Browse Source

nullkiller&herochain stabilisation

Andrii Danylchenko 4 years ago
parent
commit
87f1079c60

+ 2 - 2
AI/Nullkiller/AIhelper.cpp

@@ -148,9 +148,9 @@ std::vector<AIPath> AIhelper::getPathsToTile(const HeroPtr & hero, const int3 &
 	return pathfindingManager->getPathsToTile(hero, tile);
 }
 
-void AIhelper::updatePaths(std::vector<HeroPtr> heroes)
+void AIhelper::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
 {
-	pathfindingManager->updatePaths(heroes);
+	pathfindingManager->updatePaths(heroes, useHeroChain);
 }
 
 void AIhelper::updatePaths(const HeroPtr & hero)

+ 1 - 1
AI/Nullkiller/AIhelper.h

@@ -60,7 +60,7 @@ public:
 	Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const override;
 	Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const override;
 	std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
-	void updatePaths(std::vector<HeroPtr> heroes) override;
+	void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false) override;
 	void updatePaths(const HeroPtr & hero) override;
 
 	STRONG_INLINE

+ 5 - 1
AI/Nullkiller/Engine/Nullkiller.cpp

@@ -26,6 +26,8 @@ Goals::TSubgoal Nullkiller::choseBestTask(Goals::TGoalVec tasks)
 
 Goals::TSubgoal Nullkiller::choseBestTask(Behavior & behavior)
 {
+	logAi->debug("Checking behavior %s", behavior.toString());
+
 	auto tasks = behavior.getTasks();
 
 	if(tasks.empty())
@@ -51,7 +53,7 @@ void Nullkiller::makeTurn()
 {
 	while(true)
 	{
-		ai->ah->updatePaths(ai->getMyHeroes());
+		ai->ah->updatePaths(ai->getMyHeroes(), true);
 
 		Goals::TGoalVec bestTasks = {
 			choseBestTask(CaptureObjectsBehavior()),
@@ -71,6 +73,8 @@ void Nullkiller::makeTurn()
 
 		try
 		{
+			activeHero = bestTask->hero;
+
 			bestTask->accept(ai.get());
 		}
 		catch(goalFulfilledException &)

+ 2 - 0
AI/Nullkiller/Engine/Nullkiller.h

@@ -8,10 +8,12 @@ class Nullkiller
 {
 private:
 	std::unique_ptr<PriorityEvaluator> priorityEvaluator;
+	HeroPtr activeHero;
 
 public:
 	Nullkiller();
 	void makeTurn();
+	bool isActive(const CGHeroInstance * hero) const { return activeHero.h == hero; }
 
 private:
 	Goals::TSubgoal choseBestTask(Behavior & behavior);

+ 9 - 1
AI/Nullkiller/VCAI.cpp

@@ -323,6 +323,13 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
 		{
 			logAi->debug("Heroes owned by different players. Do not exchange army or artifacts.");
 		}
+		else if(nullkiller)
+		{
+			if(nullkiller->isActive(firstHero))
+				transferFrom2to1(secondHero, firstHero);
+			else
+				transferFrom2to1(firstHero, secondHero);
+		}
 		else if(goalpriority1 > goalpriority2)
 		{
 			transferFrom2to1(firstHero, secondHero);
@@ -1172,7 +1179,8 @@ void VCAI::pickBestCreatures(const CArmedInstance * destinationArmy, const CArme
 			{
 				if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != destinationArmy)) //it's a searched creature not in dst SLOT
 				{
-					if(!(armyPtr->needsLastStack() && armyPtr->stacksCount() == 1)) //can't take away last creature without split
+					if(!armyPtr->needsLastStack() || armyPtr->stacksCount() != 1 
+						|| armyPtr == destinationArmy || 0 < destinationArmy->getStackCount(SlotID(i))) //can't take away last creature without split
 					{
 						cb->mergeOrSwapStacks(armyPtr, destinationArmy, SlotID(j), SlotID(i));
 					}