|
@@ -72,26 +72,16 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- auto templates = handler->getTemplates(zone.getTerrainType());
|
|
|
|
- if (templates.empty())
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- //TODO: Reuse chooseRandomAppearance (eg. WoG treasure chests)
|
|
|
|
- //Assume the template with fewest terrains is the most suitable
|
|
|
|
- auto temp = *boost::min_element(templates, [](std::shared_ptr<const ObjectTemplate> lhs, std::shared_ptr<const ObjectTemplate> rhs) -> bool
|
|
|
|
|
|
+ oi.generateObject = [primaryID, secondaryID]() -> CGObjectInstance *
|
|
{
|
|
{
|
|
- return lhs->getAllowedTerrains().size() < rhs->getAllowedTerrains().size();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- oi.generateObject = [temp]() -> CGObjectInstance *
|
|
|
|
- {
|
|
|
|
- return VLC->objtypeh->getHandlerFor(temp->id, temp->subid)->create(temp);
|
|
|
|
|
|
+ return VLC->objtypeh->getHandlerFor(primaryID, secondaryID)->create();
|
|
};
|
|
};
|
|
oi.value = rmgInfo.value;
|
|
oi.value = rmgInfo.value;
|
|
oi.probability = rmgInfo.rarity;
|
|
oi.probability = rmgInfo.rarity;
|
|
- oi.templ = temp;
|
|
|
|
|
|
+ oi.setTemplates(primaryID, secondaryID, zone.getTerrainType());
|
|
oi.maxPerZone = rmgInfo.zoneLimit;
|
|
oi.maxPerZone = rmgInfo.zoneLimit;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -125,18 +115,18 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
obj->exp = generator.getConfig().prisonExperience[i];
|
|
obj->exp = generator.getConfig().prisonExperience[i];
|
|
obj->setOwner(PlayerColor::NEUTRAL);
|
|
obj->setOwner(PlayerColor::NEUTRAL);
|
|
generator.banHero(hid);
|
|
generator.banHero(hid);
|
|
- obj->appearance = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0)->getTemplates(zone.getTerrainType()).front(); //can't init template with hero subID
|
|
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PRISON, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType());
|
|
oi.value = generator.getConfig().prisonValues[i];
|
|
oi.value = generator.getConfig().prisonValues[i];
|
|
oi.probability = 30;
|
|
oi.probability = 30;
|
|
|
|
|
|
//Distribute all allowed prisons, starting from the most valuable
|
|
//Distribute all allowed prisons, starting from the most valuable
|
|
oi.maxPerZone = (std::ceil((float)prisonsLeft / (i + 1)));
|
|
oi.maxPerZone = (std::ceil((float)prisonsLeft / (i + 1)));
|
|
prisonsLeft -= oi.maxPerZone;
|
|
prisonsLeft -= oi.maxPerZone;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -183,22 +173,16 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFaction()));
|
|
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFaction()));
|
|
oi.value = static_cast<ui32>(cre->getAIValue() * cre->getGrowth() * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2)));
|
|
oi.value = static_cast<ui32>(cre->getAIValue() * cre->getGrowth() * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2)));
|
|
oi.probability = 40;
|
|
oi.probability = 40;
|
|
-
|
|
|
|
- for(const auto & tmplate : dwellingHandler->getTemplates())
|
|
|
|
|
|
+
|
|
|
|
+ oi.generateObject = [secondaryID, dwellingType]() -> CGObjectInstance *
|
|
{
|
|
{
|
|
- if(tmplate->canBePlacedAt(zone.getTerrainType()))
|
|
|
|
- {
|
|
|
|
- oi.generateObject = [tmplate, secondaryID, dwellingType]() -> CGObjectInstance *
|
|
|
|
- {
|
|
|
|
- auto * obj = VLC->objtypeh->getHandlerFor(dwellingType, secondaryID)->create(tmplate);
|
|
|
|
- obj->tempOwner = PlayerColor::NEUTRAL;
|
|
|
|
- return obj;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- oi.templ = tmplate;
|
|
|
|
- addObjectToRandomPool(oi);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ auto * obj = VLC->objtypeh->getHandlerFor(dwellingType, secondaryID)->create();
|
|
|
|
+ obj->tempOwner = PlayerColor::NEUTRAL;
|
|
|
|
+ return obj;
|
|
|
|
+ };
|
|
|
|
+ oi.setTemplates(dwellingType, secondaryID, zone.getTerrainType());
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -222,10 +206,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
obj->storedArtifact = a;
|
|
obj->storedArtifact = a;
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::SPELL_SCROLL, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::SPELL_SCROLL, 0, zone.getTerrainType());
|
|
oi.value = generator.getConfig().scrollValues[i];
|
|
oi.value = generator.getConfig().scrollValues[i];
|
|
oi.probability = 30;
|
|
oi.probability = 30;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
//pandora box with gold
|
|
//pandora box with gold
|
|
@@ -243,10 +228,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = i * generator.getConfig().pandoraMultiplierGold;
|
|
oi.value = i * generator.getConfig().pandoraMultiplierGold;
|
|
oi.probability = 5;
|
|
oi.probability = 5;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
//pandora box with experience
|
|
//pandora box with experience
|
|
@@ -264,10 +250,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = i * generator.getConfig().pandoraMultiplierExperience;
|
|
oi.value = i * generator.getConfig().pandoraMultiplierExperience;
|
|
oi.probability = 20;
|
|
oi.probability = 20;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
//pandora box with creatures
|
|
//pandora box with creatures
|
|
@@ -325,10 +312,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = static_cast<ui32>((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) / 3);
|
|
oi.value = static_cast<ui32>((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) / 3);
|
|
oi.probability = 3;
|
|
oi.probability = 3;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
//Pandora with 12 spells of certain level
|
|
//Pandora with 12 spells of certain level
|
|
@@ -357,10 +345,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = (i + 1) * generator.getConfig().pandoraMultiplierSpells; //5000 - 15000
|
|
oi.value = (i + 1) * generator.getConfig().pandoraMultiplierSpells; //5000 - 15000
|
|
oi.probability = 2;
|
|
oi.probability = 2;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
//Pandora with 15 spells of certain school
|
|
//Pandora with 15 spells of certain school
|
|
@@ -389,10 +378,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = generator.getConfig().pandoraSpellSchool;
|
|
oi.value = generator.getConfig().pandoraSpellSchool;
|
|
oi.probability = 2;
|
|
oi.probability = 2;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
}
|
|
}
|
|
|
|
|
|
// Pandora box with 60 random spells
|
|
// Pandora box with 60 random spells
|
|
@@ -420,10 +410,11 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
|
|
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
- oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
|
oi.value = generator.getConfig().pandoraSpell60;
|
|
oi.value = generator.getConfig().pandoraSpell60;
|
|
oi.probability = 2;
|
|
oi.probability = 2;
|
|
- addObjectToRandomPool(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ addObjectToRandomPool(oi);
|
|
|
|
|
|
//Seer huts with creatures or generic rewards
|
|
//Seer huts with creatures or generic rewards
|
|
|
|
|
|
@@ -483,7 +474,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
oi.probability = 3;
|
|
oi.probability = 3;
|
|
- oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
|
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) - 4000) / 3);
|
|
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) - 4000) / 3);
|
|
if (oi.value > zone.getMaxTreasureValue())
|
|
if (oi.value > zone.getMaxTreasureValue())
|
|
{
|
|
{
|
|
@@ -491,7 +482,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- possibleSeerHuts.push_back(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ possibleSeerHuts.push_back(oi);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -500,7 +492,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
{
|
|
{
|
|
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
|
|
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
|
|
|
|
|
|
- oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
|
|
|
|
|
+ oi.setTemplates(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
|
oi.value = generator.getConfig().questValues[i];
|
|
oi.value = generator.getConfig().questValues[i];
|
|
if (oi.value > zone.getMaxTreasureValue())
|
|
if (oi.value > zone.getMaxTreasureValue())
|
|
{
|
|
{
|
|
@@ -533,7 +525,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
|
|
|
|
- possibleSeerHuts.push_back(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ possibleSeerHuts.push_back(oi);
|
|
|
|
|
|
oi.generateObject = [i, randomAppearance, this, qap]() -> CGObjectInstance *
|
|
oi.generateObject = [i, randomAppearance, this, qap]() -> CGObjectInstance *
|
|
{
|
|
{
|
|
@@ -557,7 +550,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|
return obj;
|
|
return obj;
|
|
};
|
|
};
|
|
|
|
|
|
- possibleSeerHuts.push_back(oi);
|
|
|
|
|
|
+ if(!oi.templates.empty())
|
|
|
|
+ possibleSeerHuts.push_back(oi);
|
|
}
|
|
}
|
|
|
|
|
|
if (possibleSeerHuts.empty())
|
|
if (possibleSeerHuts.empty())
|
|
@@ -610,7 +604,12 @@ std::vector<ObjectInfo*> TreasurePlacer::prepareTreasurePile(const CTreasureInfo
|
|
if(!oi) //fail
|
|
if(!oi) //fail
|
|
break;
|
|
break;
|
|
|
|
|
|
- if(oi->templ->isVisitableFromTop())
|
|
|
|
|
|
+ bool visitableFromTop = true;
|
|
|
|
+ for(auto & t : oi->templates)
|
|
|
|
+ if(!t->isVisitableFromTop())
|
|
|
|
+ visitableFromTop = false;
|
|
|
|
+
|
|
|
|
+ if(visitableFromTop)
|
|
{
|
|
{
|
|
objectInfos.push_back(oi);
|
|
objectInfos.push_back(oi);
|
|
}
|
|
}
|
|
@@ -641,7 +640,10 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|
accessibleArea.add(int3());
|
|
accessibleArea.add(int3());
|
|
|
|
|
|
auto * object = oi->generateObject();
|
|
auto * object = oi->generateObject();
|
|
- object->appearance = oi->templ;
|
|
|
|
|
|
+ if(oi->templates.empty())
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ object->appearance = *RandomGeneratorUtil::nextItem(oi->templates, zone.getRand());
|
|
auto & instance = rmgObject.addInstance(*object);
|
|
auto & instance = rmgObject.addInstance(*object);
|
|
|
|
|
|
do
|
|
do
|
|
@@ -717,7 +719,12 @@ ObjectInfo * TreasurePlacer::getRandomObject(ui32 desiredValue, ui32 currentValu
|
|
if(oi.value > maxVal)
|
|
if(oi.value > maxVal)
|
|
break; //this assumes values are sorted in ascending order
|
|
break; //this assumes values are sorted in ascending order
|
|
|
|
|
|
- if(!oi.templ->isVisitableFromTop() && !allowLargeObjects)
|
|
|
|
|
|
+ bool visitableFromTop = true;
|
|
|
|
+ for(auto & t : oi.templates)
|
|
|
|
+ if(!t->isVisitableFromTop())
|
|
|
|
+ visitableFromTop = false;
|
|
|
|
+
|
|
|
|
+ if(!visitableFromTop && !allowLargeObjects)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
if(oi.value >= minValue && oi.maxPerZone > 0)
|
|
if(oi.value >= minValue && oi.maxPerZone > 0)
|
|
@@ -921,17 +928,13 @@ char TreasurePlacer::dump(const int3 & t)
|
|
return Modificator::dump(t);
|
|
return Modificator::dump(t);
|
|
}
|
|
}
|
|
|
|
|
|
-void ObjectInfo::setTemplate(si32 type, si32 subtype, TerrainId terrainType)
|
|
|
|
|
|
+void ObjectInfo::setTemplates(si32 type, si32 subtype, TerrainId terrainType)
|
|
{
|
|
{
|
|
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
|
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
|
if(!templHandler)
|
|
if(!templHandler)
|
|
return;
|
|
return;
|
|
|
|
|
|
- auto templates = templHandler->getTemplates(terrainType);
|
|
|
|
- if(templates.empty())
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- templ = templates.front();
|
|
|
|
|
|
+ templates = templHandler->getTemplates(terrainType);
|
|
}
|
|
}
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|
|
VCMI_LIB_NAMESPACE_END
|