فهرست منبع

- Fixed Border Gates logic
- VCAI may now walk onto removable objects when exploring

DJWarmonger 7 سال پیش
والد
کامیت
a9ef8fe32f
5فایلهای تغییر یافته به همراه42 افزوده شده و 13 حذف شده
  1. 21 1
      AI/VCAI/AIUtility.cpp
  2. 1 0
      AI/VCAI/AIUtility.h
  3. 6 2
      AI/VCAI/Goals.cpp
  4. 1 1
      AI/VCAI/SectorMap.cpp
  5. 13 9
      AI/VCAI/VCAI.cpp

+ 21 - 1
AI/VCAI/AIUtility.cpp

@@ -357,6 +357,26 @@ bool isSafeToVisit(HeroPtr h, crint3 tile)
 	return true; //there's no danger
 }
 
+bool isObjectRemovable(const CGObjectInstance * obj)
+{
+	//FIXME: move logic to object property!
+	switch (obj->ID)
+	{
+	case Obj::MONSTER:
+	case Obj::RESOURCE:
+	case Obj::CAMPFIRE:
+	case Obj::TREASURE_CHEST:
+	case Obj::ARTIFACT:
+	case Obj::BORDERGUARD:
+		return true;
+		break;
+	default:
+		return false;
+		break;
+	}
+
+}
+
 bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
 {
 	// TODO: Such information should be provided by pathfinder
@@ -422,7 +442,7 @@ bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should
 	if(cb->getTile(tileToHit)->topVisitableId() != Obj::BORDER_GATE)
 		return false;
 	auto gate = dynamic_cast<const CGKeys *>(cb->getTile(tileToHit)->topVisitableObj());
-	return !gate->wasMyColorVisited(ai->playerID);
+	return !gate->passableFor(ai->playerID);
 }
 bool isBlockVisitObj(const int3 & pos)
 {

+ 1 - 0
AI/VCAI/AIUtility.h

@@ -167,6 +167,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj);
 ui64 evaluateDanger(const CGObjectInstance * obj);
 ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor);
 bool isSafeToVisit(HeroPtr h, crint3 tile);
+bool isObjectRemovable(const CGObjectInstance * obj); //FIXME FIXME: move logic to object property!
 
 bool compareMovement(HeroPtr lhs, HeroPtr rhs);
 bool compareHeroStrength(HeroPtr h1, HeroPtr h2);

+ 6 - 2
AI/VCAI/Goals.cpp

@@ -673,6 +673,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
 		{
 			//FIXME: this way we'll not visit gate and activate quest :?
 			ret.push_back(sptr(Goals::FindObj(Obj::KEYMASTER, cb->getTile(tileToHit)->visitableObjects.back()->subID)));
+			return ret; //only option
 		}
 
 		auto topObj = cb->getTopObj(tileToHit);
@@ -699,13 +700,16 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
 				}
 				else
 				{
-					//TODO: we should be able to return apriopriate quest here (VCAI::striveToQuest)
+					//TODO: we should be able to return apriopriate quest here
+					//ret.push_back(ai->questToGoal());
+					//however, visiting obj for firts time will give us quest
 					logAi->debug("Quest guard blocks the way to %s", tile.toString());
 					continue; //do not access quets guard if we can't complete the quest
 				}
+				return ret; //try complete quest as the only option
 			}
 		}
-		if(isSafeToVisit(h, tileToHit)) //this makes sense only if tile is guarded, but there i no quest object
+		if(isSafeToVisit(h, tileToHit)) //this makes sense only if tile is guarded, but there is no quest object
 		{
 			ret.push_back(sptr(Goals::VisitTile(tileToHit).sethero(h)));
 		}

+ 1 - 1
AI/VCAI/SectorMap.cpp

@@ -329,7 +329,7 @@ int3 SectorMap::firstTileToGet(HeroPtr h, crint3 dst)
 			//throw cannotFulfillGoalException("Inter-sector route detection failed: not connected sectors?");
 		}
 	}
-	else
+	else //tiles are in same sector
 	{
 		return findFirstVisitableTile(h, dst);
 	}

+ 13 - 9
AI/VCAI/VCAI.cpp

@@ -2585,8 +2585,10 @@ int3 VCAI::explorationNewPoint(HeroPtr h)
 			{
 				if(isSafeToVisit(h, tile))
 				{
-					if(isBlockVisitObj(tile)) //we can't stand on that object
-						continue;
+					auto obj = cb->getTopObj(tile);
+					if (obj)
+						if(obj->blockVisit && !isObjectRemovable(obj)) //we can't stand on that object
+							continue;
 					bestTile = tile;
 					bestValue = ourValue;
 				}
@@ -2633,14 +2635,16 @@ int3 VCAI::explorationDesperate(HeroPtr h)
 				ui64 ourDanger = evaluateDanger(t, h.h);
 				if(ourDanger < lowestDanger)
 				{
-					if(!isBlockVisitObj(t))
-					{
-						if(!ourDanger) //at least one safe place found
-							return t;
+					auto obj = cb->getTopObj(t);
+					if (obj)
+						if (obj->blockVisit && !isObjectRemovable(obj)) //we can't stand on objct or remove it
+							continue;
 
-						bestTile = t;
-						lowestDanger = ourDanger;
-					}
+					if(!ourDanger) //at least one safe place found
+						return t;
+
+					bestTile = t;
+					lowestDanger = ourDanger;
 				}
 			}
 		}