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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ TSubgoal BuildThis::whatToDoToAchieve()
|
||||
|
||||
// find town if not set
|
||||
if(!town && hero)
|
||||
town = hero->visitedTown;
|
||||
town = hero->getVisitedTown();
|
||||
|
||||
if(!town)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user