diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp index 55de3c6af..1d2782d44 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp @@ -809,7 +809,7 @@ ExchangeCandidate HeroChainCalculationTask::calculateExchange( if(carrierParentNode->turns < otherParentNode->turns) { - int moveRemains = exchangeActor->hero->maxMovePoints(carrierParentNode->layer); + int moveRemains = exchangeActor->maxMovePoints(carrierParentNode->layer); float waitingCost = otherParentNode->turns - carrierParentNode->turns - 1 + carrierParentNode->moveRemains / (float)moveRemains; diff --git a/AI/Nullkiller/Pathfinding/Actors.cpp b/AI/Nullkiller/Pathfinding/Actors.cpp index 2bdc7cc85..e10a7e6d5 100644 --- a/AI/Nullkiller/Pathfinding/Actors.cpp +++ b/AI/Nullkiller/Pathfinding/Actors.cpp @@ -45,10 +45,11 @@ ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t initialTurn = 0; armyValue = hero->getArmyStrength(); heroFightingStrength = hero->getFightingStrength(); + tiCache.reset(new TurnInfo(hero)); } ChainActor::ChainActor(const ChainActor * carrier, const ChainActor * other, const CCreatureSet * heroArmy) - :hero(carrier->hero), heroRole(carrier->heroRole), isMovable(true), creatureSet(heroArmy), chainMask(carrier->chainMask | other->chainMask), + :hero(carrier->hero), tiCache(carrier->tiCache), heroRole(carrier->heroRole), isMovable(true), creatureSet(heroArmy), chainMask(carrier->chainMask | other->chainMask), baseActor(this), carrierParent(carrier), otherParent(other), heroFightingStrength(carrier->heroFightingStrength), actorExchangeCount(carrier->actorExchangeCount + other->actorExchangeCount), armyCost(carrier->armyCost + other->armyCost), actorAction() { @@ -65,6 +66,16 @@ ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatu armyValue = creatureSet->getArmyStrength(); } +int ChainActor::maxMovePoints(CGPathNode::ELayer layer) +{ +#if AI_TRACE_LEVEL > 0 + if(!hero) + throw std::exception("Asking movement points for static actor"); +#endif + + return hero->maxMovePointsCached(layer, tiCache.get()); +} + std::string ChainActor::toString() const { return hero->name; @@ -120,6 +131,7 @@ void ChainActor::setBaseActor(HeroActor * base) heroFightingStrength = base->heroFightingStrength; armyCost = base->armyCost; actorAction = base->actorAction; + tiCache = base->tiCache; } void HeroActor::setupSpecialActors() diff --git a/AI/Nullkiller/Pathfinding/Actors.h b/AI/Nullkiller/Pathfinding/Actors.h index 5ccae7b37..ff2618df2 100644 --- a/AI/Nullkiller/Pathfinding/Actors.h +++ b/AI/Nullkiller/Pathfinding/Actors.h @@ -73,6 +73,7 @@ public: float heroFightingStrength; uint8_t actorExchangeCount; TResources armyCost; + std::shared_ptr tiCache; ChainActor(){} @@ -80,6 +81,7 @@ public: ExchangeResult tryExchangeNoLock(const ChainActor * other) const { return tryExchangeNoLock(this, other); } void setBaseActor(HeroActor * base); virtual const CGObjectInstance * getActorObject() const { return hero; } + int maxMovePoints(CGPathNode::ELayer layer); protected: virtual ExchangeResult tryExchangeNoLock(const ChainActor * specialActor, const ChainActor * other) const; diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index da2824240..97306a3dd 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -290,10 +290,13 @@ bool CCreature::isItNativeTerrain(ETerrainType::EETerrainType terrain) const ETerrainType::EETerrainType CCreature::getNativeTerrain() const { + const std::string cachingStringBlocksRetaliation = "type_NO_TERRAIN_PENALTY"; + static const auto selectorBlocksRetaliation = Selector::type()(Bonus::NO_TERRAIN_PENALTY); + //this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses //and in the CGHeroInstance::getNativeTerrain() to setup mevement bonuses or/and penalties. - return hasBonusOfType(Bonus::NO_TERRAIN_PENALTY) ? - ETerrainType::ANY_TERRAIN + return hasBonus(selectorBlocksRetaliation, selectorBlocksRetaliation) + ? ETerrainType::ANY_TERRAIN : (ETerrainType::EETerrainType)(*VLC->townh)[faction]->nativeTerrain; }