Răsfoiți Sursa

More consitent code.

DjWarmonger 10 ani în urmă
părinte
comite
768b1ca289
3 a modificat fișierele cu 30 adăugiri și 8 ștergeri
  1. 23 4
      AI/VCAI/Goals.cpp
  2. 5 4
      AI/VCAI/Goals.h
  3. 2 0
      AI/VCAI/VCAI.cpp

+ 23 - 4
AI/VCAI/Goals.cpp

@@ -971,11 +971,30 @@ TGoalVec Conquer::getAllPossibleSubgoals()
 			if (conquerable(obj))
 				ourObjs.push_back(obj);
 		}
-		for (auto obj : ourObjs) //double loop, performance risk?
+		for (auto obj : ourObjs)
 		{
-			auto t = sm.firstTileToGet(h, obj->visitablePos()); //we assume that no more than one tile on the way is guarded
-			if (ai->isTileNotReserved(h, t))
-				ret.push_back (sptr(Goals::ClearWayTo(obj->visitablePos(), h).setisAbstract(true)));
+			int3 dest = obj->visitablePos();
+			auto t = sm.firstTileToGet(h, dest); //we assume that no more than one tile on the way is guarded
+			if (t.valid()) //we know any path at all
+			{
+				if (ai->isTileNotReserved(h, t)) //no other hero wants to conquer that tile
+				{
+					if (isSafeToVisit(h, dest))
+					{
+						if (dest != t) //there is something blocking our way
+							ret.push_back(sptr(Goals::ClearWayTo(dest, h).setisAbstract(true)));
+						else
+						{
+							if (obj->ID.num == Obj::HERO) //enemy hero may move to other position
+								ret.push_back(sptr(Goals::VisitHero(obj->id.getNum()).sethero(h).setisAbstract(true)));
+							else //just visit that tile
+								ret.push_back(sptr(Goals::VisitTile(dest).sethero(h).setisAbstract(true)));
+						}
+					}
+					else //we need to get army in order to conquer that place
+						ret.push_back(sptr(Goals::GatherArmy(evaluateDanger(dest, h) * SAFE_ATTACK_CONSTANT).sethero(h).setisAbstract(true)));
+				}
+			}
 		}
 	}
 	if (!objs.empty() && ai->canRecruitAnyHero()) //probably no point to recruit hero if we see no objects to capture

+ 5 - 4
AI/VCAI/Goals.h

@@ -134,6 +134,7 @@ public:
 		isAbstract = false;
 		value = 0;
 		aid = -1;
+		objid = -1;
 		resID = -1;
 		tile = int3(-1, -1, -1);
 		town = nullptr;
@@ -300,7 +301,7 @@ public:
 	VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid; priority = 4;};
 	TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
 	TSubgoal whatToDoToAchieve() override;
-	//bool operator== (VisitHero &g) {return g.objid == objid;}
+	bool operator== (VisitHero &g) { return g.goalType == goalType && g.objid == objid; }
 	bool fulfillsMe (TSubgoal goal) override;
 	std::string completeMessage() const override;
 };
@@ -322,7 +323,7 @@ public:
 	VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile; priority = 5;};
 	TGoalVec getAllPossibleSubgoals() override;
 	TSubgoal whatToDoToAchieve() override;
-	//bool operator== (VisitTile &g) {return g.tile == tile;}
+	bool operator== (VisitTile &g) { return g.goalType == goalType && g.tile == tile; }
 	std::string completeMessage() const override;
 }; 
 class ClearWayTo : public CGoal<ClearWayTo>
@@ -334,7 +335,7 @@ public:
 	ClearWayTo(int3 Tile, HeroPtr h) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; hero = h; priority = 5;};
 	TGoalVec getAllPossibleSubgoals() override;
 	TSubgoal whatToDoToAchieve() override;
-	bool operator== (ClearWayTo &g) {return g.tile == tile;}
+	bool operator== (ClearWayTo &g) { return g.goalType == goalType && g.tile == tile; }
 };
 class DigAtTile : public CGoal<DigAtTile>
 	//elementar with hero on tile
@@ -345,7 +346,7 @@ public:
 	DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile; priority = 20;};
 	TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
 	TSubgoal whatToDoToAchieve() override;
-	bool operator== (DigAtTile &g) {return g.tile == tile;}
+	bool operator== (DigAtTile &g) { g.goalType == goalType && g.tile == tile; }
 };
 
 class CIssueCommand : public CGoal<CIssueCommand>

+ 2 - 0
AI/VCAI/VCAI.cpp

@@ -1932,6 +1932,8 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
 	if(h) //we could have lost hero after last move
 	{
 		completeGoal (sptr(Goals::VisitTile(dst).sethero(h))); //we stepped on some tile, anyway
+		completeGoal (sptr(Goals::ClearWayTo(dst).sethero(h)));
+
 		if (!ret) //reserve object we are heading towards
 		{
 			auto obj = frontOrNull(cb->getVisitableObjs(dst));