Ver Fonte

NKAI: fix casting FLY several times during path calculation

Andrii Danylchenko há 1 ano atrás
pai
commit
1db43a509e

+ 14 - 2
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -137,6 +137,18 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer
 	return sum > 1 ? result / sum : result;
 }
 
+uint64_t getResourcesGoldReward(TResources & res)
+{
+	int nonGoldResources = res[EGameResID::GEMS]
+		+ res[EGameResID::SULFUR]
+		+ res[EGameResID::WOOD]
+		+ res[EGameResID::ORE]
+		+ res[EGameResID::CRYSTAL]
+		+ res[EGameResID::MERCURY];
+
+	return res[EGameResID::GOLD] + 100 * nonGoldResources;
+}
+
 uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero)
 {
 	auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance);
@@ -491,7 +503,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons
 			//Evaluate resources used for construction. Gold is evaluated separately.
 			if (it->resType != EGameResID::GOLD)
 			{
-				sum += 0.1f * getResourceRequirementStrength(it->resType);
+				sum += 0.1f * it->resVal * getResourceRequirementStrength(it->resType);
 			}
 		}
 		return sum;
@@ -662,7 +674,7 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG
 	case Obj::WAGON:
 		return 100;
 	case Obj::CREATURE_BANK:
-		return getCreatureBankResources(target, hero)[EGameResID::GOLD];
+		return getResourcesGoldReward(getCreatureBankResources(target, hero));
 	case Obj::CRYPT:
 	case Obj::DERELICT_SHIP:
 		return 3000;

+ 6 - 0
AI/Nullkiller/Pathfinding/AINodeStorage.cpp

@@ -234,6 +234,7 @@ void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPath
 		heroNode.specialAction.reset();
 		heroNode.armyLoss = 0;
 		heroNode.chainOther = nullptr;
+		heroNode.dayFlags = DayFlags::NONE;
 		heroNode.update(coord, layer, accessibility);
 	}
 }
@@ -295,6 +296,11 @@ void AINodeStorage::commit(
 	{
 		commitedTiles.insert(destination->coord);
 	}
+
+	if(destination->turns == source->turns)
+	{
+		destination->dayFlags = source->dayFlags;
+	}
 }
 
 std::vector<CGPathNode *> AINodeStorage::calculateNeighbours(

+ 9 - 1
AI/Nullkiller/Pathfinding/AINodeStorage.h

@@ -41,11 +41,19 @@ namespace AIPathfinding
 	const int CHAIN_MAX_DEPTH = 4;
 }
 
+enum DayFlags : ui8
+{
+	NONE = 0,
+	FLY_CASTED = 1,
+	WATER_WALK_CASTED = 2
+};
+
 struct AIPathNode : public CGPathNode
 {
 	uint64_t danger;
 	uint64_t armyLoss;
-	int32_t manaCost;
+	int16_t manaCost;
+	DayFlags dayFlags;
 	const AIPathNode * chainOther;
 	std::shared_ptr<const SpecialAction> specialAction;
 	const ChainActor * actor;

+ 8 - 7
AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp

@@ -22,18 +22,18 @@ namespace NKAI
 
 namespace AIPathfinding
 {
-	AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero)
-		:spellToCast(spellToCast), hero(hero)
+	AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd)
+		:spellToCast(spellToCast), hero(hero), flagsToAdd(flagsToAdd)
 	{
 		manaCost = hero->getSpellCost(spellToCast.toSpell());
 	}
 
 	WaterWalkingAction::WaterWalkingAction(const CGHeroInstance * hero)
-		:AdventureCastAction(SpellID::WATER_WALK, hero)
+		:AdventureCastAction(SpellID::WATER_WALK, hero, DayFlags::WATER_WALK_CASTED)
 	{ }
 
 	AirWalkingAction::AirWalkingAction(const CGHeroInstance * hero)
-		: AdventureCastAction(SpellID::FLY, hero)
+		: AdventureCastAction(SpellID::FLY, hero, DayFlags::FLY_CASTED)
 	{
 	}
 
@@ -41,11 +41,12 @@ namespace AIPathfinding
 		const CGHeroInstance * hero,
 		CDestinationNodeInfo & destination,
 		const PathNodeInfo & source,
-		AIPathNode * dstMode,
+		AIPathNode * dstNode,
 		const AIPathNode * srcNode) const
 	{
-		dstMode->manaCost = srcNode->manaCost + manaCost;
-		dstMode->theNodeBefore = source.node;
+		dstNode->manaCost = srcNode->manaCost + manaCost;
+		dstNode->theNodeBefore = source.node;
+		dstNode->dayFlags = static_cast<DayFlags>(dstNode->dayFlags | flagsToAdd);
 	}
 
 	void AdventureCastAction::execute(const CGHeroInstance * hero) const

+ 2 - 1
AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.h

@@ -24,9 +24,10 @@ namespace AIPathfinding
 		SpellID spellToCast;
 		const CGHeroInstance * hero;
 		int manaCost;
+		DayFlags flagsToAdd;
 
 	public:
-		AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero);
+		AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd = DayFlags::NONE);
 
 		virtual void execute(const CGHeroInstance * hero) const override;
 

+ 12 - 0
AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp

@@ -61,6 +61,12 @@ namespace AIPathfinding
 
 		if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::WATER)
 		{
+			if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::WATER_WALK_CASTED)
+			{
+				destination.blocked = false;
+				return;
+			}
+
 			auto action = waterWalkingActions.find(nodeStorage->getHero(source.node));
 
 			if(action != waterWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL))
@@ -73,6 +79,12 @@ namespace AIPathfinding
 
 		if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::AIR)
 		{
+			if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::FLY_CASTED)
+			{
+				destination.blocked = false;
+				return;
+			}
+
 			auto action = airWalkingActions.find(nodeStorage->getHero(source.node));
 
 			if(action != airWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL))