1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Remove ConstTransitivePtr from hero and town instances

This commit is contained in:
Ivan Savenko
2025-03-09 21:51:33 +00:00
parent 62234fcf92
commit 417ea6451a
57 changed files with 436 additions and 390 deletions

View File

@@ -904,19 +904,19 @@ void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h
switch(obj->ID)
{
case Obj::TOWN:
if(h->visitedTown) //we are inside, not just attacking
if(h->getVisitedTown()) //we are inside, not just attacking
{
makePossibleUpgrades(h.get());
std::unique_lock lockGuard(nullkiller->aiStateMutex);
if(!h->visitedTown->garrisonHero || !nullkiller->isHeroLocked(h->visitedTown->garrisonHero))
moveCreaturesToHero(h->visitedTown);
if(!h->getVisitedTown()->getGarrisonHero() || !nullkiller->isHeroLocked(h->getVisitedTown()->getGarrisonHero()))
moveCreaturesToHero(h->getVisitedTown());
if(nullkiller->heroManager->getHeroRole(h) == HeroRole::MAIN && !h->hasSpellbook()
&& nullkiller->getFreeGold() >= GameConstants::SPELLBOOK_GOLD_COST)
{
if(h->visitedTown->hasBuilt(BuildingID::MAGES_GUILD_1))
if(h->getVisitedTown()->hasBuilt(BuildingID::MAGES_GUILD_1))
cb->buyArtifact(h.get(), ArtifactID::SPELLBOOK);
}
}
@@ -929,9 +929,9 @@ void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h
void AIGateway::moveCreaturesToHero(const CGTownInstance * t)
{
if(t->visitingHero && t->armedGarrison() && t->visitingHero->tempOwner == t->tempOwner)
if(t->getVisitingHero() && t->armedGarrison() && t->getVisitingHero()->tempOwner == t->tempOwner)
{
pickBestCreatures(t->visitingHero, t->getUpperArmy());
pickBestCreatures(t->getVisitingHero(), t->getUpperArmy());
}
}
@@ -1282,10 +1282,10 @@ void AIGateway::addVisitableObj(const CGObjectInstance * obj)
bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
{
if(h->inTownGarrison && h->visitedTown)
if(h->isGarrisoned() && h->getVisitedTown())
{
cb->swapGarrisonHero(h->visitedTown);
moveCreaturesToHero(h->visitedTown);
cb->swapGarrisonHero(h->getVisitedTown());
moveCreaturesToHero(h->getVisitedTown());
}
//TODO: consider if blockVisit objects change something in our checks: AIUtility::isBlockVisitObj()
@@ -1596,7 +1596,7 @@ void AIGateway::endTurn()
void AIGateway::buildArmyIn(const CGTownInstance * t)
{
makePossibleUpgrades(t->visitingHero);
makePossibleUpgrades(t->getVisitingHero());
makePossibleUpgrades(t);
recruitCreatures(t, t->getUpperArmy());
moveCreaturesToHero(t);

View File

@@ -767,7 +767,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
bool townHasFreeTavern(const CGTownInstance * town)
{
if(!town->hasBuilt(BuildingID::TAVERN)) return false;
if(!town->visitingHero) return true;
if(!town->getVisitingHero()) return true;
bool canMoveVisitingHeroToGarrison = !town->getUpperArmy()->stacksCount();
@@ -778,9 +778,9 @@ uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCr
{
auto armyStrength = heroArmy->getArmyStrength(fortLevel);
if(hero && hero->commander && hero->commander->alive)
if(hero && hero->getCommander() && hero->getCommander()->alive)
{
armyStrength += 100 * hero->commander->level;
armyStrength += 100 * hero->getCommander()->level;
}
return armyStrength;

View File

@@ -93,8 +93,8 @@ void DangerHitMapAnalyzer::updateHitMap()
{
auto town = dynamic_cast<const CGTownInstance *>(obj);
if(town->garrisonHero)
heroes[town->garrisonHero->tempOwner][town->garrisonHero] = HeroRole::MAIN;
if(town->getGarrisonHero())
heroes[town->getGarrisonHero()->tempOwner][town->getGarrisonHero()] = HeroRole::MAIN;
}
}

View File

@@ -293,7 +293,7 @@ const CGHeroInstance * HeroManager::findWeakHeroToDismiss(uint64_t armyLimit, co
|| existingHero->getArmyStrength() >armyLimit
|| getHeroRole(existingHero) == HeroRole::MAIN
|| existingHero->movementPointsRemaining()
|| (townToSpare != nullptr && existingHero->visitedTown == townToSpare)
|| (townToSpare != nullptr && existingHero->getVisitedTown() == townToSpare)
|| existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1))
{
continue;

View File

@@ -109,30 +109,30 @@ void handleCounterAttack(
bool handleGarrisonHeroFromPreviousTurn(const CGTownInstance * town, Goals::TGoalVec & tasks, const Nullkiller * ai)
{
if(ai->isHeroLocked(town->garrisonHero.get()))
if(ai->isHeroLocked(town->getGarrisonHero()))
{
logAi->trace(
"Hero %s in garrison of town %s is supposed to defend the town",
town->garrisonHero->getNameTranslated(),
town->getGarrisonHero()->getNameTranslated(),
town->getNameTranslated());
return true;
}
if(!town->visitingHero)
if(!town->getVisitingHero())
{
if(ai->cb->getHeroCount(ai->playerID, false) < GameConstants::MAX_HEROES_PER_PLAYER)
{
logAi->trace(
"Extracting hero %s from garrison of town %s",
town->garrisonHero->getNameTranslated(),
town->getGarrisonHero()->getNameTranslated(),
town->getNameTranslated());
tasks.push_back(Goals::sptr(Goals::ExchangeSwapTownHeroes(town, nullptr).setpriority(5)));
return false;
}
else if(ai->heroManager->getHeroRole(town->garrisonHero.get()) == HeroRole::MAIN)
else if(ai->heroManager->getHeroRole(town->getGarrisonHero()) == HeroRole::MAIN)
{
auto armyDismissLimit = 1000;
auto heroToDismiss = ai->heroManager->findWeakHeroToDismiss(armyDismissLimit);
@@ -160,7 +160,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
threats.push_back(threatNode.fastestDanger); // no guarantee that fastest danger will be there
if (town->garrisonHero && handleGarrisonHeroFromPreviousTurn(town, tasks, ai))
if (town->getGarrisonHero() && handleGarrisonHeroFromPreviousTurn(town, tasks, ai))
{
return;
}
@@ -233,16 +233,16 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
path.toString());
#endif
auto townDefenseStrength = town->garrisonHero
? town->garrisonHero->getTotalStrength()
: (town->visitingHero ? town->visitingHero->getTotalStrength() : town->getUpperArmy()->getArmyStrength());
auto townDefenseStrength = town->getGarrisonHero()
? town->getGarrisonHero()->getTotalStrength()
: (town->getVisitingHero() ? town->getVisitingHero()->getTotalStrength() : town->getUpperArmy()->getArmyStrength());
if(town->visitingHero && path.targetHero == town->visitingHero.get())
if(town->getVisitingHero() && path.targetHero == town->getVisitingHero())
{
if(path.getHeroStrength() < townDefenseStrength)
continue;
}
else if(town->garrisonHero && path.targetHero == town->garrisonHero.get())
else if(town->getGarrisonHero() && path.targetHero == town->getGarrisonHero())
{
if(path.getHeroStrength() < townDefenseStrength)
continue;
@@ -271,7 +271,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
continue;
}
if(path.targetHero == town->visitingHero.get() && path.exchangeCount == 1)
if(path.targetHero == town->getVisitingHero() && path.exchangeCount == 1)
{
#if NKAI_TRACE_LEVEL >= 1
logAi->trace("Put %s to garrison of town %s",
@@ -280,7 +280,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
#endif
// dismiss creatures we are not able to pick to be able to hide in garrison
if(town->garrisonHero
if(town->getGarrisonHero()
|| town->getUpperArmy()->stacksCount() == 0
|| path.targetHero->canBeMergedWith(*town)
|| (town->getUpperArmy()->getArmyStrength() < 500 && town->fortLevel() >= CGTownInstance::CITADEL))
@@ -288,25 +288,25 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
tasks.push_back(
Goals::sptr(Composition()
.addNext(DefendTown(town, threat, path.targetHero))
.addNext(ExchangeSwapTownHeroes(town, town->visitingHero.get(), HeroLockedReason::DEFENCE))));
.addNext(ExchangeSwapTownHeroes(town, town->getVisitingHero(), HeroLockedReason::DEFENCE))));
}
continue;
}
// main without army and visiting scout with army, very specific case
if(town->visitingHero && town->getUpperArmy()->stacksCount() == 0
&& path.targetHero != town->visitingHero.get() && path.exchangeCount == 1 && path.turn() == 0
&& ai->heroManager->evaluateHero(path.targetHero) > ai->heroManager->evaluateHero(town->visitingHero.get())
&& 10 * path.targetHero->getTotalStrength() < town->visitingHero->getTotalStrength())
if(town->getVisitingHero() && town->getUpperArmy()->stacksCount() == 0
&& path.targetHero != town->getVisitingHero() && path.exchangeCount == 1 && path.turn() == 0
&& ai->heroManager->evaluateHero(path.targetHero) > ai->heroManager->evaluateHero(town->getVisitingHero())
&& 10 * path.targetHero->getTotalStrength() < town->getVisitingHero()->getTotalStrength())
{
path.heroArmy = town->visitingHero.get();
path.heroArmy = town->getVisitingHero();
tasks.push_back(
Goals::sptr(Composition()
.addNext(DefendTown(town, threat, path))
.addNextSequence({
sptr(ExchangeSwapTownHeroes(town, town->visitingHero.get())),
sptr(ExchangeSwapTownHeroes(town, town->getVisitingHero())),
sptr(ExecuteHeroChain(path, town)),
sptr(ExchangeSwapTownHeroes(town, path.targetHero, HeroLockedReason::DEFENCE))
})));
@@ -350,22 +350,22 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
composition.addNext(DefendTown(town, threat, path));
TGoalVec sequence;
if(town->garrisonHero && path.targetHero == town->garrisonHero.get() && path.exchangeCount == 1)
if(town->getGarrisonHero() && path.targetHero == town->getGarrisonHero() && path.exchangeCount == 1)
{
composition.addNext(ExchangeSwapTownHeroes(town, town->garrisonHero.get(), HeroLockedReason::DEFENCE));
composition.addNext(ExchangeSwapTownHeroes(town, town->getGarrisonHero(), HeroLockedReason::DEFENCE));
tasks.push_back(Goals::sptr(composition));
#if NKAI_TRACE_LEVEL >= 1
logAi->trace("Locking hero %s in garrison of %s",
town->garrisonHero.get()->getObjectName(),
town->getGarrisonHero()->getObjectName(),
town->getObjectName());
#endif
continue;
}
else if(town->visitingHero && path.targetHero != town->visitingHero && !path.containsHero(town->visitingHero))
else if(town->getVisitingHero() && path.targetHero != town->getVisitingHero() && !path.containsHero(town->getVisitingHero()))
{
if(town->garrisonHero && town->garrisonHero != path.targetHero)
if(town->getGarrisonHero() && town->getGarrisonHero() != path.targetHero)
{
#if NKAI_TRACE_LEVEL >= 1
logAi->trace("Cancel moving %s to defend town %s as the town has garrison hero",
@@ -376,7 +376,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
}
else if(path.turn() == 0)
{
sequence.push_back(sptr(ExchangeSwapTownHeroes(town, town->visitingHero.get())));
sequence.push_back(sptr(ExchangeSwapTownHeroes(town, town->getVisitingHero())));
}
}
@@ -425,7 +425,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & threat, const CGTownInstance * town, const Nullkiller * ai) const
{
if (threat.turn > 0 || town->garrisonHero || town->visitingHero)
if (threat.turn > 0 || town->getGarrisonHero() || town->getVisitingHero())
return;
if(town->hasBuilt(BuildingID::TAVERN)
@@ -461,25 +461,25 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
bool needSwap = false;
const CGHeroInstance * heroToDismiss = nullptr;
if(town->visitingHero)
if(town->getVisitingHero())
{
if(!town->garrisonHero)
if(!town->getGarrisonHero())
needSwap = true;
else
{
if(town->visitingHero->getArmyStrength() < town->garrisonHero->getArmyStrength())
if(town->getVisitingHero()->getArmyStrength() < town->getGarrisonHero()->getArmyStrength())
{
if(town->visitingHero->getArmyStrength() >= hero->getArmyStrength())
if(town->getVisitingHero()->getArmyStrength() >= hero->getArmyStrength())
continue;
heroToDismiss = town->visitingHero.get();
heroToDismiss = town->getVisitingHero();
}
else if(town->garrisonHero->getArmyStrength() >= hero->getArmyStrength())
else if(town->getGarrisonHero()->getArmyStrength() >= hero->getArmyStrength())
continue;
else
{
needSwap = true;
heroToDismiss = town->garrisonHero.get();
heroToDismiss = town->getGarrisonHero();
}
}
@@ -499,7 +499,7 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
Goals::Composition recruitHeroComposition;
if(needSwap)
sequence.push_back(sptr(ExchangeSwapTownHeroes(town, town->visitingHero.get())));
sequence.push_back(sptr(ExchangeSwapTownHeroes(town, town->getVisitingHero())));
if(heroToDismiss)
sequence.push_back(sptr(DismissHero(heroToDismiss)));

View File

@@ -167,21 +167,21 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const Nullkiller * ai, con
composition.addNext(heroExchange);
if(hero->inTownGarrison && path.turn() == 0)
if(hero->isGarrisoned() && path.turn() == 0)
{
auto lockReason = ai->getHeroLockedReason(hero);
if(path.targetHero->visitedTown == hero->visitedTown)
if(path.targetHero->getVisitedTown() == hero->getVisitedTown())
{
composition.addNextSequence({
sptr(ExchangeSwapTownHeroes(hero->visitedTown, hero, lockReason))});
sptr(ExchangeSwapTownHeroes(hero->getVisitedTown(), hero, lockReason))});
}
else
{
composition.addNextSequence({
sptr(ExchangeSwapTownHeroes(hero->visitedTown)),
sptr(ExchangeSwapTownHeroes(hero->getVisitedTown())),
sptr(exchangePath),
sptr(ExchangeSwapTownHeroes(hero->visitedTown, hero, lockReason))});
sptr(ExchangeSwapTownHeroes(hero->getVisitedTown(), hero, lockReason))});
}
}
else
@@ -262,7 +262,7 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const Nullkiller * ai, const CGT
continue;
}
if(upgrader->visitingHero && (upgrader->visitingHero.get() != path.targetHero || path.exchangeCount == 1))
if(upgrader->getVisitingHero() && (upgrader->getVisitingHero() != path.targetHero || path.exchangeCount == 1))
{
#if NKAI_TRACE_LEVEL >= 2
logAi->trace("Ignore path. Town has visiting hero.");
@@ -289,7 +289,7 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const Nullkiller * ai, const CGT
auto upgrade = ai->armyManager->calculateCreaturesUpgrade(path.heroArmy, upgrader, availableResources);
if(!upgrader->garrisonHero
if(!upgrader->getGarrisonHero()
&& (
hasMainAround
|| ai->heroManager->getHeroRole(path.targetHero) == HeroRole::MAIN))

View File

@@ -68,7 +68,7 @@ Goals::TGoalVec RecruitHeroBehavior::decompose(const Nullkiller * ai) const
closestThreat = std::min(closestThreat, threat.turn);
}
//Don't hire a hero where there already is one present
if (town->visitingHero && town->garrisonHero)
if (town->getVisitingHero() && town->getGarrisonHero())
continue;
float visitability = 0;
for (auto checkHero : ourHeroes)
@@ -98,7 +98,7 @@ Goals::TGoalVec RecruitHeroBehavior::decompose(const Nullkiller * ai) const
for(auto hero : availableHeroes)
{
if ((town->visitingHero || town->garrisonHero)
if ((town->getVisitingHero() || town->getGarrisonHero())
&& closestThreat < 1
&& hero->getArmyCost() < GameConstants::HERO_GOLD_COST / 3.0)
continue;

View File

@@ -32,7 +32,7 @@ const AIPath getShortestPath(const CGTownInstance * town, const std::vector<AIPa
{
auto shortestPath = *vstd::minElementByFun(paths, [town](const AIPath & path) -> float
{
if(town->garrisonHero && path.targetHero == town->garrisonHero.get())
if(town->getGarrisonHero() && path.targetHero == town->getGarrisonHero())
return 1;
return path.movementCost();
@@ -53,7 +53,7 @@ const CGHeroInstance * getNearestHero(const Nullkiller * ai, const CGTownInstanc
if(shortestPath.nodes.size() > 1
|| shortestPath.turn() != 0
|| shortestPath.targetHero->visitablePos().dist2dSQ(town->visitablePos()) > 4
|| (town->garrisonHero && shortestPath.targetHero == town->garrisonHero.get()))
|| (town->getGarrisonHero() && shortestPath.targetHero == town->getGarrisonHero()))
return nullptr;
return shortestPath.targetHero;
@@ -64,7 +64,7 @@ bool needToRecruitHero(const Nullkiller * ai, const CGTownInstance * startupTown
if(!ai->heroManager->canRecruitHero(startupTown))
return false;
if(!startupTown->garrisonHero && !startupTown->visitingHero)
if(!startupTown->getGarrisonHero() && !startupTown->getVisitingHero())
return true;
int treasureSourcesCount = 0;
@@ -122,8 +122,8 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
{
startupTown = *vstd::maxElementByFun(towns, [ai](const CGTownInstance * town) -> float
{
if(town->garrisonHero)
return ai->heroManager->evaluateHero(town->garrisonHero.get());
if(town->getGarrisonHero())
return ai->heroManager->evaluateHero(town->getGarrisonHero());
auto closestHero = getNearestHero(ai, town);
@@ -147,7 +147,7 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
if(closestHero)
{
if(!startupTown->visitingHero)
if(!startupTown->getVisitingHero())
{
if(ai->armyManager->howManyReinforcementsCanGet(startupTown->getUpperArmy(), startupTown->getUpperArmy(), closestHero, TerrainId::NONE) > 200)
{
@@ -163,12 +163,12 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
}
else
{
auto visitingHero = startupTown->visitingHero.get();
auto visitingHero = startupTown->getVisitingHero();
auto visitingHeroScore = ai->heroManager->evaluateHero(visitingHero);
if(startupTown->garrisonHero)
if(startupTown->getGarrisonHero())
{
auto garrisonHero = startupTown->garrisonHero.get();
auto garrisonHero = startupTown->getGarrisonHero();
auto garrisonHeroScore = ai->heroManager->evaluateHero(garrisonHero);
if(visitingHeroScore > garrisonHeroScore
@@ -187,7 +187,7 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
else if(canRecruitHero)
{
auto canPickTownArmy = startupTown->stacksCount() == 0
|| ai->armyManager->howManyReinforcementsCanGet(startupTown->visitingHero, startupTown) > 0;
|| ai->armyManager->howManyReinforcementsCanGet(startupTown->getVisitingHero(), startupTown) > 0;
if(canPickTownArmy)
{
@@ -197,16 +197,16 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
}
}
if(tasks.empty() && canRecruitHero && !startupTown->visitingHero)
if(tasks.empty() && canRecruitHero && !startupTown->getVisitingHero())
{
tasks.push_back(Goals::sptr(Goals::RecruitHero(startupTown)));
}
if(tasks.empty() && !startupTown->visitingHero)
if(tasks.empty() && !startupTown->getVisitingHero())
{
for(auto town : towns)
{
if(!town->visitingHero && needToRecruitHero(ai, town))
if(!town->getVisitingHero() && needToRecruitHero(ai, town))
{
tasks.push_back(Goals::sptr(Goals::RecruitHero(town)));
@@ -219,10 +219,10 @@ Goals::TGoalVec StartupBehavior::decompose(const Nullkiller * ai) const
{
for(const CGTownInstance * town : towns)
{
if(town->garrisonHero
&& town->garrisonHero->movementPointsRemaining()
&& !town->visitingHero
&& ai->getHeroLockedReason(town->garrisonHero) != HeroLockedReason::DEFENCE)
if(town->getGarrisonHero()
&& town->getGarrisonHero()->movementPointsRemaining()
&& !town->getVisitingHero()
&& ai->getHeroLockedReason(town->getGarrisonHero()) != HeroLockedReason::DEFENCE)
{
tasks.push_back(Goals::sptr(ExchangeSwapTownHeroes(town, nullptr).setpriority(MIN_PRIORITY)));
}

View File

@@ -43,7 +43,7 @@ Goals::TGoalVec StayAtTownBehavior::decompose(const Nullkiller * ai) const
for(auto & path : paths)
{
if(town->visitingHero && town->visitingHero.get() != path.targetHero)
if(town->getVisitingHero() && town->getVisitingHero() != path.targetHero)
continue;
if(!path.getFirstBlockedAction() && path.exchangeCount <= 1)

View File

@@ -47,16 +47,16 @@ ui64 FuzzyHelper::evaluateDanger(const int3 & tile, const CGHeroInstance * visit
{
auto hero = dynamic_cast<const CGHeroInstance *>(dangerousObject);
if(hero->visitedTown && !hero->visitedTown->garrisonHero)
if(hero->getVisitedTown() && !hero->getVisitedTown()->getGarrisonHero())
{
objectDanger += evaluateDanger(hero->visitedTown.get());
objectDanger += evaluateDanger(hero->getVisitedTown());
}
objectDanger *= ai->heroManager->getFightingStrengthCached(hero);
}
if (objWithID<Obj::TOWN>(dangerousObject))
{
auto town = dynamic_cast<const CGTownInstance*>(dangerousObject);
auto hero = town->garrisonHero;
auto hero = town->getGarrisonHero();
if (hero)
objectDanger *= ai->heroManager->getFightingStrengthCached(hero);
@@ -121,7 +121,7 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
const CGTownInstance * town = dynamic_cast<const CGTownInstance *>(obj);
auto danger = town->getUpperArmy()->getArmyStrength();
if(danger || town->visitingHero)
if(danger || town->getVisitingHero())
{
auto fortLevel = town->fortLevel();

View File

@@ -44,17 +44,17 @@ void AdventureSpellCast::accept(AIGateway * ai)
{
ai->selectedObject = town->id;
if(town->visitingHero && town->tempOwner == ai->playerID && !town->getUpperArmy()->stacksCount())
if(town->getVisitingHero() && town->tempOwner == ai->playerID && !town->getUpperArmy()->stacksCount())
{
ai->myCb->swapGarrisonHero(town);
}
if(town->visitingHero)
throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->getNameTranslated());
if(town->getVisitingHero())
throw cannotFulfillGoalException("The town is already occupied by " + town->getVisitingHero()->getNameTranslated());
}
if (hero->inTownGarrison)
ai->myCb->swapGarrisonHero(hero->visitedTown);
if (hero->isGarrisoned())
ai->myCb->swapGarrisonHero(hero->getVisitedTown());
auto wait = cb->waitTillRealize;

View File

@@ -97,9 +97,9 @@ void BuyArmy::accept(AIGateway * ai)
throw cannotFulfillGoalException("No creatures to buy.");
}
if(town->visitingHero && !town->garrisonHero)
if(town->getVisitingHero() && !town->getGarrisonHero())
{
ai->moveHeroToTile(town->visitablePos(), town->visitingHero.get());
ai->moveHeroToTile(town->visitablePos(), town->getVisitingHero());
}
}

View File

@@ -19,7 +19,7 @@ namespace NKAI
using namespace Goals;
ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(
const CGTownInstance * town,
const CGTownInstance * town,
const CGHeroInstance * garrisonHero,
HeroLockedReason lockingReason)
:ElementarGoal(Goals::EXCHANGE_SWAP_TOWN_HEROES), town(town), garrisonHero(garrisonHero), lockingReason(lockingReason)
@@ -30,11 +30,11 @@ std::vector<ObjectInstanceID> ExchangeSwapTownHeroes::getAffectedObjects() const
{
std::vector<ObjectInstanceID> affectedObjects = { town->id };
if(town->garrisonHero)
affectedObjects.push_back(town->garrisonHero->id);
if(town->getGarrisonHero())
affectedObjects.push_back(town->getGarrisonHero()->id);
if(town->visitingHero)
affectedObjects.push_back(town->visitingHero->id);
if(town->getVisitingHero())
affectedObjects.push_back(town->getVisitingHero()->id);
return affectedObjects;
}
@@ -42,8 +42,8 @@ std::vector<ObjectInstanceID> ExchangeSwapTownHeroes::getAffectedObjects() const
bool ExchangeSwapTownHeroes::isObjectAffected(ObjectInstanceID id) const
{
return town->id == id
|| (town->visitingHero && town->visitingHero->id == id)
|| (town->garrisonHero && town->garrisonHero->id == id);
|| (town->getVisitingHero() && town->getVisitingHero()->id == id)
|| (town->getGarrisonHero() && town->getGarrisonHero()->id == id);
}
std::string ExchangeSwapTownHeroes::toString() const
@@ -58,39 +58,39 @@ bool ExchangeSwapTownHeroes::operator==(const ExchangeSwapTownHeroes & other) co
void ExchangeSwapTownHeroes::accept(AIGateway * ai)
{
if(!garrisonHero)
if(!getGarrisonHero())
{
auto currentGarrisonHero = town->garrisonHero;
auto currentGarrisonHero = town->getGarrisonHero();
if(!currentGarrisonHero)
throw cannotFulfillGoalException("Invalid configuration. There is no hero in town garrison.");
cb->swapGarrisonHero(town);
if(currentGarrisonHero.get() != town->visitingHero.get())
if(currentGarrisonHero != town->getVisitingHero())
{
logAi->error("VisitingHero is empty, expected %s", currentGarrisonHero->getNameTranslated());
return;
}
ai->buildArmyIn(town);
ai->nullkiller->unlockHero(currentGarrisonHero.get());
ai->nullkiller->unlockHero(currentGarrisonHero);
logAi->debug("Extracted hero %s from garrison of %s", currentGarrisonHero->getNameTranslated(), town->getNameTranslated());
return;
}
if(town->visitingHero && town->visitingHero.get() != garrisonHero)
if(town->getVisitingHero() && town->getVisitingHero() != getGarrisonHero())
cb->swapGarrisonHero(town);
ai->makePossibleUpgrades(town);
ai->moveHeroToTile(town->visitablePos(), garrisonHero);
ai->moveHeroToTile(town->visitablePos(), getGarrisonHero());
auto upperArmy = town->getUpperArmy();
if(!town->garrisonHero)
if(!town->getGarrisonHero())
{
if (!garrisonHero->canBeMergedWith(*town))
if (!getGarrisonHero()->canBeMergedWith(*town))
{
while (upperArmy->stacksCount() != 0)
{
@@ -103,16 +103,16 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
if(lockingReason != HeroLockedReason::NOT_LOCKED)
{
ai->nullkiller->lockHero(garrisonHero, lockingReason);
ai->nullkiller->lockHero(getGarrisonHero(), lockingReason);
}
if(town->visitingHero && town->visitingHero != garrisonHero)
if(town->getVisitingHero() && town->getVisitingHero() != getGarrisonHero())
{
ai->nullkiller->unlockHero(town->visitingHero.get());
ai->makePossibleUpgrades(town->visitingHero);
ai->nullkiller->unlockHero(town->getVisitingHero());
ai->makePossibleUpgrades(town->getVisitingHero());
}
logAi->debug("Put hero %s to garrison of %s", garrisonHero->getNameTranslated(), town->getNameTranslated());
logAi->debug("Put hero %s to garrison of %s", getGarrisonHero()->getNameTranslated(), town->getNameTranslated());
}
}

View File

@@ -59,12 +59,12 @@ void RecruitHero::accept(AIGateway * ai)
if(!heroToHire)
throw cannotFulfillGoalException("No hero to hire!");
if(t->visitingHero)
if(t->getVisitingHero())
{
cb->swapGarrisonHero(t);
}
if(t->visitingHero)
if(t->getVisitingHero())
throw cannotFulfillGoalException("Town " + t->nodeName() + " is occupied. Cannot recruit hero!");
cb->recruitHero(t, heroToHire);

View File

@@ -958,7 +958,7 @@ void AINodeStorage::setHeroes(std::map<const CGHeroInstance *, HeroRole> heroes)
{
// do not allow our own heroes in garrison to act on map
if(hero.first->getOwner() == ai->playerID
&& hero.first->inTownGarrison
&& hero.first->isGarrisoned()
&& (ai->isHeroLocked(hero.first) || ai->heroManager->heroCapReached(false)))
{
continue;
@@ -987,9 +987,9 @@ void AINodeStorage::setTownsAndDwellings(
{
uint64_t mask = FirstActorMask << actors.size();
// TODO: investigate logix of second condition || ai->nullkiller->getHeroLockedReason(town->garrisonHero) != HeroLockedReason::DEFENCE
// TODO: investigate logix of second condition || ai->nullkiller->getHeroLockedReason(town->getGarrisonHero()) != HeroLockedReason::DEFENCE
// check defence imrove
if(!town->garrisonHero)
if(!town->getGarrisonHero())
{
actors.push_back(std::make_shared<TownGarrisonActor>(town, mask));
}
@@ -1185,19 +1185,19 @@ void AINodeStorage::calculateTownPortal(
{
for(const CGTownInstance * targetTown : towns)
{
if(targetTown->visitingHero
if(targetTown->getVisitingHero()
&& targetTown->getUpperArmy()->stacksCount()
&& maskMap.find(targetTown->visitingHero.get()) != maskMap.end())
&& maskMap.find(targetTown->getVisitingHero()) != maskMap.end())
{
auto basicMask = maskMap.at(targetTown->visitingHero.get());
auto basicMask = maskMap.at(targetTown->getVisitingHero());
bool sameActorInTown = actor->chainMask == basicMask;
if(!sameActorInTown)
continue;
}
if (targetTown->visitingHero
&& (targetTown->visitingHero.get()->getFactionID() != actor->hero->getFactionID()
if (targetTown->getVisitingHero()
&& (targetTown->getVisitingHero()->getFactionID() != actor->hero->getFactionID()
|| targetTown->getUpperArmy()->stacksCount()))
continue;

View File

@@ -20,13 +20,13 @@ namespace AIPathfinding
{
void BuyArmyAction::execute(AIGateway * ai, const CGHeroInstance * hero) const
{
if(!hero->visitedTown)
if(!hero->getVisitedTown())
{
throw cannotFulfillGoalException(
hero->getNameTranslated() + " being at " + hero->visitablePos().toString() + " has no town to recruit creatures.");
}
ai->recruitCreatures(hero->visitedTown, hero);
ai->recruitCreatures(hero->getVisitedTown(), hero);
}
std::string BuyArmyAction::toString() const

View File

@@ -39,8 +39,8 @@ TSubgoal AdventureSpellCast::whatToDoToAchieve()
if(hero->mana < hero->getSpellCost(spell))
throw cannotFulfillGoalException("Hero has not enough mana to cast " + spell->getNameTranslated());
if(spellID == SpellID::TOWN_PORTAL && town && town->visitingHero)
throw cannotFulfillGoalException("The town is already occupied by " + town->visitingHero->getNameTranslated());
if(spellID == SpellID::TOWN_PORTAL && town && town->getVisitingHero())
throw cannotFulfillGoalException("The town is already occupied by " + town->getVisitingHero()->getNameTranslated());
return iAmElementar();
}

View File

@@ -32,7 +32,7 @@ TSubgoal BuildThis::whatToDoToAchieve()
// find town if not set
if(!town && hero)
town = hero->visitedTown;
town = hero->getVisitedTown();
if(!town)
{

View File

@@ -56,14 +56,14 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
if(waysToVisit.size())
{
//grab army from town
if(!t->visitingHero && ai->ah->howManyReinforcementsCanGet(hero.get(), t))
if(!t->getVisitingHero() && ai->ah->howManyReinforcementsCanGet(hero.get(), t))
{
if(!vstd::contains(ai->townVisitsThisWeek[hero], t))
vstd::concatenate(ret, waysToVisit);
}
//buy army in town
if (!t->visitingHero || t->visitingHero == hero.get(true))
if (!t->getVisitingHero() || t->getVisitingHero() == hero.get(true))
{
std::vector<int> values = {
value,

View File

@@ -75,9 +75,9 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
if(count >= this->value)
{
if(t->visitingHero)
if(t->getVisitingHero())
{
solutions.push_back(sptr(VisitObj(t->id.getNum()).sethero(t->visitingHero.get())));
solutions.push_back(sptr(VisitObj(t->id.getNum()).sethero(t->getVisitingHero())));
}
else
{

View File

@@ -83,9 +83,9 @@ TSubgoal Win::whatToDoToAchieve()
if(auto h = ai->getHeroWithGrail())
{
//hero is in a town that can host Grail
if(h->visitedTown && !vstd::contains(h->visitedTown->forbiddenBuildings, BuildingID::GRAIL))
if(h->getVisitedTown() && !vstd::contains(h->getVisitedTown()->forbiddenBuildings, BuildingID::GRAIL))
{
const CGTownInstance * t = h->visitedTown;
const CGTownInstance * t = h->getVisitedTown();
return sptr(BuildThis(BuildingID::GRAIL, t).setpriority(10));
}
else

View File

@@ -267,7 +267,7 @@ void AINodeStorage::calculateTownPortalTeleportations(
for(const CGTownInstance * targetTown : towns)
{
if(targetTown->visitingHero)
if(targetTown->getVisitingHero())
continue;
auto nodeOptional = getOrCreateNode(targetTown->visitablePos(), EPathfindingLayer::LAND, srcNode->chainMask | CAST_CHAIN);

View File

@@ -486,8 +486,8 @@ void VCAI::playerBonusChanged(const Bonus & bonus, bool gain)
void VCAI::heroCreated(const CGHeroInstance * h)
{
LOG_TRACE(logAi);
if(h->visitedTown)
townVisitsThisWeek[HeroPtr(h)].insert(h->visitedTown);
if(h->getVisitedTown())
townVisitsThisWeek[HeroPtr(h)].insert(h->getVisitedTown());
NET_EVENT_HANDLER;
}
@@ -1073,12 +1073,12 @@ void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
{
case Obj::TOWN:
moveCreaturesToHero(dynamic_cast<const CGTownInstance *>(obj));
if(h->visitedTown) //we are inside, not just attacking
if(h->getVisitedTown()) //we are inside, not just attacking
{
townVisitsThisWeek[h].insert(h->visitedTown);
townVisitsThisWeek[h].insert(h->getVisitedTown());
if(!h->hasSpellbook() && ah->freeGold() >= GameConstants::SPELLBOOK_GOLD_COST)
{
if(h->visitedTown->hasBuilt(BuildingID::MAGES_GUILD_1))
if(h->getVisitedTown()->hasBuilt(BuildingID::MAGES_GUILD_1))
cb->buyArtifact(h.get(), ArtifactID::SPELLBOOK);
}
}
@@ -1089,9 +1089,9 @@ void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
void VCAI::moveCreaturesToHero(const CGTownInstance * t)
{
if(t->visitingHero && t->armedGarrison() && t->visitingHero->tempOwner == t->tempOwner)
if(t->getVisitingHero() && t->armedGarrison() && t->getVisitingHero()->tempOwner == t->tempOwner)
{
pickBestCreatures(t->visitingHero, t);
pickBestCreatures(t->getVisitingHero(), t);
}
}
@@ -1363,10 +1363,10 @@ void VCAI::wander(HeroPtr h)
{
auto visitTownIfAny = [this](HeroPtr h) -> bool
{
if (h->visitedTown)
if (h->getVisitedTown())
{
townVisitsThisWeek[h].insert(h->visitedTown);
buildArmyIn(h->visitedTown);
townVisitsThisWeek[h].insert(h->getVisitedTown());
buildArmyIn(h->getVisitedTown());
return true;
}
return false;
@@ -1434,7 +1434,7 @@ void VCAI::wander(HeroPtr h)
std::vector<const CGTownInstance *> townsNotReachable;
for(const CGTownInstance * t : cb->getTownsInfo())
{
if(!t->visitingHero && !vstd::contains(townVisitsThisWeek[h], t))
if(!t->getVisitingHero() && !vstd::contains(townVisitsThisWeek[h], t))
{
if(isAccessibleForHero(t->visitablePos(), h))
townsReachable.push_back(t);
@@ -2251,7 +2251,7 @@ void VCAI::tryRealize(Goals::AbstractGoal & g)
const CGTownInstance * VCAI::findTownWithTavern() const
{
for(const CGTownInstance * t : cb->getTownsInfo())
if(t->hasBuilt(BuildingID::TAVERN) && !t->visitingHero)
if(t->hasBuilt(BuildingID::TAVERN) && !t->getVisitingHero())
return t;
return nullptr;
@@ -2455,7 +2455,7 @@ void VCAI::performTypicalActions()
void VCAI::buildArmyIn(const CGTownInstance * t)
{
makePossibleUpgrades(t->visitingHero);
makePossibleUpgrades(t->getVisitingHero());
makePossibleUpgrades(t);
recruitCreatures(t, t->getUpperArmy());
moveCreaturesToHero(t);