Przeglądaj źródła

Nullkiller: cancel heavy decomposition on shipyards

Andrii Danylchenko 4 lat temu
rodzic
commit
1aa81530cb

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

@@ -108,7 +108,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
 		// army bonuses will change and object bonuses are temporary
 		if(bonus->source != Bonus::ARMY || bonus->source != Bonus::OBJECT)
 		{
-			newArmyInstance.addNewBonus(bonus);
+			newArmyInstance.addNewBonus(std::make_shared<Bonus>(*bonus));
 		}
 	}
 

+ 2 - 1
AI/Nullkiller/Behaviors/CaptureObjectsBehavior.cpp

@@ -146,7 +146,8 @@ Goals::TGoalVec CaptureObjectsBehavior::decompose() const
 {
 	Goals::TGoalVec tasks;
 
-	auto captureObjects = [&](const std::vector<const CGObjectInstance*> & objs) -> void{
+	auto captureObjects = [&](const std::vector<const CGObjectInstance*> & objs) -> void
+	{
 		if(objs.empty())
 		{
 			return;

+ 2 - 0
AI/Nullkiller/CMakeLists.txt

@@ -29,6 +29,7 @@ set(VCAI_SRCS
 		Goals/BuyArmy.cpp
 		Goals/AdventureSpellCast.cpp
 		Goals/Trade.cpp
+		Goals/CaptureObject.cpp
 		Goals/RecruitHero.cpp
 		Goals/DigAtTile.cpp
 		Goals/ExecuteHeroChain.cpp
@@ -89,6 +90,7 @@ set(VCAI_HEADERS
 		Goals/BuyArmy.h
 		Goals/AdventureSpellCast.h
 		Goals/Trade.h
+		Goals/CaptureObject.h
 		Goals/RecruitHero.h
 		Goals/DigAtTile.h
 		Goals/ExecuteHeroChain.h

+ 16 - 1
AI/Nullkiller/Engine/DeepDecomposer.cpp

@@ -139,6 +139,21 @@ Goals::TSubgoal DeepDecomposer::unwrapComposition(Goals::TSubgoal goal)
 	return goal->goalType == Goals::COMPOSITION ? goal->decompose().back() : goal;
 }
 
+bool isEquivalentGoals(TSubgoal goal1, TSubgoal goal2)
+{
+	if(goal1 == goal2) return true;
+
+	if(goal1->goalType == Goals::CAPTURE_OBJECT && goal2->goalType == Goals::CAPTURE_OBJECT)
+	{
+		auto o1 = cb->getObj(ObjectInstanceID(goal1->objid));
+		auto o2 = cb->getObj(ObjectInstanceID(goal2->objid));
+
+		return o1->ID == Obj::SHIPYARD && o1->ID == o2->ID;
+	}
+
+	return false;
+}
+
 bool DeepDecomposer::isCompositionLoop(TSubgoal goal)
 {
 	auto goalsToTest = goal->goalType == Goals::COMPOSITION ? goal->decompose() : TGoalVec{goal};
@@ -149,7 +164,7 @@ bool DeepDecomposer::isCompositionLoop(TSubgoal goal)
 		{
 			auto parent = unwrapComposition(goals[i].back());
 
-			if(parent == goalToTest)
+			if(isEquivalentGoals(parent, goalToTest))
 			{
 				return true;
 			}

+ 2 - 1
AI/Nullkiller/Goals/AbstractGoal.h

@@ -66,7 +66,8 @@ namespace Goals
 		UNLOCK_CLUSTER,
 		HERO_EXCHANGE,
 		ARMY_UPGRADE,
-		DEFEND_TOWN
+		DEFEND_TOWN,
+		CAPTURE_OBJECT
 	};
 
 	class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>

+ 40 - 0
AI/Nullkiller/Goals/CaptureObject.cpp

@@ -0,0 +1,40 @@
+/*
+* CaptureObject.cpp, part of VCMI engine
+*
+* Authors: listed in file AUTHORS in main folder
+*
+* License: GNU General Public License v2.0 or later
+* Full text of license available in license.txt file, in main folder
+*
+*/
+#include "../StdInc.h"
+#include "CaptureObject.h"
+#include "../../../lib/mapObjects/CGTownInstance.h"
+#include "../VCAI.h"
+#include "../Engine/Nullkiller.h"
+#include "../Behaviors/CaptureObjectsBehavior.h"
+
+
+extern boost::thread_specific_ptr<CCallback> cb;
+
+using namespace Goals;
+
+bool CaptureObject::operator==(const CaptureObject & other) const
+{
+	return objid == other.objid;
+}
+
+uint64_t CaptureObject::getHash() const
+{
+	return objid;
+}
+
+std::string CaptureObject::toString() const
+{
+	return "Capture " + name + " at " + tile.toString();
+}
+
+TGoalVec CaptureObject::decompose() const
+{
+	return CaptureObjectsBehavior(cb->getObj(ObjectInstanceID(objid))).decompose();
+}

+ 40 - 0
AI/Nullkiller/Goals/CaptureObject.h

@@ -0,0 +1,40 @@
+/*
+* CaptureObject.h, part of VCMI engine
+*
+* Authors: listed in file AUTHORS in main folder
+*
+* License: GNU General Public License v2.0 or later
+* Full text of license available in license.txt file, in main folder
+*
+*/
+#pragma once
+
+#include "CGoal.h"
+
+struct HeroPtr;
+class VCAI;
+class FuzzyHelper;
+
+namespace Goals
+{
+	class DLL_EXPORT CaptureObject : public CGoal<CaptureObject>
+	{
+	private:
+		std::string name;
+
+	public:
+		CaptureObject(const CGObjectInstance * obj)
+			: CGoal(Goals::CAPTURE_OBJECT)
+		{
+			objid = obj->id.getNum();
+			tile = obj->visitablePos();
+			name = obj->getObjectName();
+		}
+
+		virtual bool operator==(const CaptureObject & other) const override;
+		virtual Goals::TGoalVec decompose() const override;
+		virtual std::string toString() const override;
+		virtual bool hasHash() const override { return true; }
+		virtual uint64_t getHash() 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
 #define MAIN_TURN_DISTANCE_LIMIT 5
 

+ 2 - 2
AI/Nullkiller/Pathfinding/Actions/BoatActions.cpp

@@ -11,7 +11,7 @@
 #include "StdInc.h"
 #include "../../VCAI.h"
 #include "../../Goals/AdventureSpellCast.h"
-#include "../../Behaviors/CaptureObjectsBehavior.h"
+#include "../../Goals/CaptureObject.h"
 #include "../../Goals/BuildBoat.h"
 #include "../../../../lib/mapping/CMap.h"
 #include "../../../../lib/mapObjects/MapObjects.h"
@@ -31,7 +31,7 @@ namespace AIPathfinding
 	{
 		if(cb->getPlayerRelations(ai->playerID, shipyard->o->tempOwner) == PlayerRelations::ENEMIES)
 		{
-			return Goals::sptr(Goals::CaptureObjectsBehavior(shipyard->o));
+			return Goals::sptr(Goals::CaptureObject(shipyard->o));
 		}
 		
 		return sptr(Goals::Invalid());