Преглед изворни кода

Nullkiller: fix crash when buy army through pathfinder

Andrii Danylchenko пре 4 година
родитељ
комит
3dc76cfe35

+ 9 - 1
AI/Nullkiller/Analyzers/ArmyManager.cpp

@@ -188,9 +188,17 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
 }
 
 ui64 ArmyManager::howManyReinforcementsCanBuy(const CCreatureSet * h, const CGDwelling * t) const
+{
+	return howManyReinforcementsCanBuy(h, t, cb->getResourceAmount());
+}
+
+ui64 ArmyManager::howManyReinforcementsCanBuy(
+	const CCreatureSet * h,
+	const CGDwelling * t,
+	const TResources & availableResources) const
 {
 	ui64 aivalue = 0;
-	auto army = getArmyAvailableToBuy(h, t);
+	auto army = getArmyAvailableToBuy(h, t, availableResources);
 
 	for(const creInfo & ci : army)
 	{

+ 8 - 0
AI/Nullkiller/Analyzers/ArmyManager.h

@@ -43,6 +43,10 @@ class DLL_EXPORT IArmyManager //: public: IAbstractManager
 public:
 	virtual void update() = 0;
 	virtual ui64 howManyReinforcementsCanBuy(const CCreatureSet * target, const CGDwelling * source) const = 0;
+	virtual	ui64 howManyReinforcementsCanBuy(
+		const CCreatureSet * h,
+		const CGDwelling * t,
+		const TResources & availableResources) const = 0;
 	virtual ui64 howManyReinforcementsCanGet(const CGHeroInstance * hero, const CCreatureSet * source) const = 0;
 	virtual ui64 howManyReinforcementsCanGet(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const = 0;
 	virtual std::vector<SlotInfo> getBestArmy(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const = 0;
@@ -71,6 +75,10 @@ public:
 	ArmyManager(CPlayerSpecificInfoCallback * CB, const Nullkiller * ai): cb(CB), ai(ai) {}
 	void update() override;
 	ui64 howManyReinforcementsCanBuy(const CCreatureSet * target, const CGDwelling * source) const override;
+	ui64 howManyReinforcementsCanBuy(
+		const CCreatureSet * h,
+		const CGDwelling * t,
+		const TResources & availableResources) const override;
 	ui64 howManyReinforcementsCanGet(const CGHeroInstance * hero, const CCreatureSet * source) const override;
 	ui64 howManyReinforcementsCanGet(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const override;
 	std::vector<SlotInfo> getBestArmy(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const override;

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

@@ -11,7 +11,7 @@
 #pragma once
 
 #define PATHFINDER_TRACE_LEVEL 0
-#define AI_TRACE_LEVEL 0
+#define AI_TRACE_LEVEL 1
 #define SCOUT_TURN_DISTANCE_LIMIT 3
 
 #include "../../../lib/CPathfinder.h"

+ 7 - 2
AI/Nullkiller/Pathfinding/Actors.cpp

@@ -198,10 +198,12 @@ bool HeroExchangeMap::canExchange(const ChainActor * other)
 				return;
 			}
 
+			TResources availableResources = resources - actor->armyCost - other->armyCost;
+
 			auto upgradeInfo = ai->armyManager->calculateCreateresUpgrade(
 				actor->creatureSet, 
 				other->getActorObject(),
-				resources - actor->armyCost - other->armyCost);
+				availableResources);
 
 			uint64_t reinforcment = upgradeInfo.upgradeValue;
 			
@@ -211,7 +213,10 @@ bool HeroExchangeMap::canExchange(const ChainActor * other)
 			auto obj = other->getActorObject();
 			if(obj && obj->ID == Obj::TOWN)
 			{
-				reinforcment += ai->armyManager->howManyReinforcementsCanBuy(actor->creatureSet, ai->cb->getTown(obj->id));
+				reinforcment += ai->armyManager->howManyReinforcementsCanBuy(
+					actor->creatureSet,
+					ai->cb->getTown(obj->id),
+					availableResources - upgradeInfo.upgradeCost);
 			}
 
 #if PATHFINDER_TRACE_LEVEL >= 2