Prechádzať zdrojové kódy

Fix performance issue related to TurnInfo construction

Andrii Danylchenko 3 rokov pred
rodič
commit
31c9d6e28d

+ 1 - 1
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;
 

+ 13 - 1
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()

+ 2 - 0
AI/Nullkiller/Pathfinding/Actors.h

@@ -73,6 +73,7 @@ public:
 	float heroFightingStrength;
 	uint8_t actorExchangeCount;
 	TResources armyCost;
+	std::shared_ptr<TurnInfo> 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;

+ 5 - 2
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;
 }