1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Unban artifacts if RMG fails to place Seer Hut (unlikely)

This commit is contained in:
Tomasz Zieliński 2024-01-16 17:15:35 +01:00
parent 0273d9c36b
commit 71844d4d92
5 changed files with 44 additions and 10 deletions

View File

@ -509,6 +509,11 @@ void CMapGenerator::banQuestArt(const ArtifactID & id)
map->getMap(this).allowedArtifact.erase(id);
}
void CMapGenerator::unbanQuestArt(const ArtifactID & id)
{
map->getMap(this).allowedArtifact.insert(id);
}
Zone * CMapGenerator::getZoneWater() const
{
for(auto & z : map->getZones())

View File

@ -65,6 +65,7 @@ public:
const std::vector<ArtifactID> & getAllPossibleQuestArtifacts() const;
const std::vector<HeroTypeID> getAllPossibleHeroes() const;
void banQuestArt(const ArtifactID & id);
void unbanQuestArt(const ArtifactID & id);
Zone * getZoneWater() const;
void addWaterTreasuresInfo();

View File

@ -40,11 +40,18 @@ void QuestArtifactPlacer::addQuestArtZone(std::shared_ptr<Zone> otherZone)
void QuestArtifactPlacer::addQuestArtifact(const ArtifactID& id)
{
logGlobal->info("Need to place quest artifact %s", VLC->artifacts()->getById(id)->getNameTranslated());
RecursiveLock lock(externalAccessMutex);
logGlobal->info("Need to place quest artifact artifact %s", VLC->artifacts()->getById(id)->getNameTranslated());
questArtifactsToPlace.emplace_back(id);
}
void QuestArtifactPlacer::removeQuestArtifact(const ArtifactID& id)
{
logGlobal->info("Will not try to place quest artifact %s", VLC->artifacts()->getById(id)->getNameTranslated());
RecursiveLock lock(externalAccessMutex);
vstd::erase_if_present(questArtifactsToPlace, id);
}
void QuestArtifactPlacer::rememberPotentialArtifactToReplace(CGObjectInstance* obj)
{
RecursiveLock lock(externalAccessMutex);
@ -143,10 +150,11 @@ ArtifactID QuestArtifactPlacer::drawRandomArtifact()
}
}
void QuestArtifactPlacer::addRandomArtifact(ArtifactID artid)
void QuestArtifactPlacer::addRandomArtifact(const ArtifactID & artid)
{
RecursiveLock lock(externalAccessMutex);
questArtifacts.push_back(artid);
generator.unbanQuestArt(artid);
}
VCMI_LIB_NAMESPACE_END

View File

@ -29,14 +29,15 @@ public:
void findZonesForQuestArts();
void addQuestArtifact(const ArtifactID& id);
void removeQuestArtifact(const ArtifactID& id);
void rememberPotentialArtifactToReplace(CGObjectInstance* obj);
std::vector<CGObjectInstance*> getPossibleArtifactsToReplace() const;
void placeQuestArtifacts(CRandomGenerator & rand);
void dropReplacedArtifact(CGObjectInstance* obj);
size_t getMaxQuestArtifactCount() const;
ArtifactID drawRandomArtifact();
void addRandomArtifact(ArtifactID artid);
[[nodiscard]] ArtifactID drawRandomArtifact();
void addRandomArtifact(const ArtifactID & artid);
protected:

View File

@ -474,7 +474,8 @@ void TreasurePlacer::addAllPossibleObjects()
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, qap]() -> CGObjectInstance *
// FIXME: Remove duplicated code for gold, exp and creaure reward
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, qap, &oi]() -> CGObjectInstance *
{
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
@ -485,9 +486,15 @@ void TreasurePlacer::addAllPossibleObjects()
obj->configuration.info.push_back(reward);
ArtifactID artid = qap->drawRandomArtifact();
oi.destroyObject = [artid, qap]()
{
// Artifact can be used again
qap->addRandomArtifact(artid);
qap->removeQuestArtifact(artid);
};
obj->quest->mission.artifacts.push_back(artid);
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
qap->addQuestArtifact(artid);
return obj;
};
@ -521,7 +528,7 @@ void TreasurePlacer::addAllPossibleObjects()
oi.probability = 10;
oi.maxPerZone = 1;
oi.generateObject = [i, randomAppearance, this, qap]() -> CGObjectInstance *
oi.generateObject = [i, randomAppearance, this, qap, &oi]() -> CGObjectInstance *
{
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
@ -532,9 +539,15 @@ void TreasurePlacer::addAllPossibleObjects()
obj->configuration.info.push_back(reward);
ArtifactID artid = qap->drawRandomArtifact();
oi.destroyObject = [artid, qap]()
{
// Artifact can be used again
qap->addRandomArtifact(artid);
qap->removeQuestArtifact(artid);
};
obj->quest->mission.artifacts.push_back(artid);
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
qap->addQuestArtifact(artid);
return obj;
};
@ -542,7 +555,7 @@ void TreasurePlacer::addAllPossibleObjects()
if(!oi.templates.empty())
possibleSeerHuts.push_back(oi);
oi.generateObject = [i, randomAppearance, this, qap]() -> CGObjectInstance *
oi.generateObject = [i, randomAppearance, this, qap, &oi]() -> CGObjectInstance *
{
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
@ -553,9 +566,15 @@ void TreasurePlacer::addAllPossibleObjects()
obj->configuration.info.push_back(reward);
ArtifactID artid = qap->drawRandomArtifact();
oi.destroyObject = [artid, qap]()
{
// Artifact can be used again
qap->addRandomArtifact(artid);
qap->removeQuestArtifact(artid);
};
obj->quest->mission.artifacts.push_back(artid);
zone.getModificator<QuestArtifactPlacer>()->addQuestArtifact(artid);
qap->addQuestArtifact(artid);
return obj;
};