فهرست منبع

- Extensive use of SectorMap. AI will not eagerly pick guarded and blocked treasures.
- Fixed usage of boats, added Boat building as a part of Explore goal. This resolves #2151

DjWarmonger 10 سال پیش
والد
کامیت
b2a75551c8
4فایلهای تغییر یافته به همراه63 افزوده شده و 7 حذف شده
  1. 3 1
      AI/VCAI/AIUtility.cpp
  2. 54 1
      AI/VCAI/Goals.cpp
  3. 5 4
      AI/VCAI/VCAI.cpp
  4. 1 1
      AI/VCAI/VCAI.h

+ 3 - 1
AI/VCAI/AIUtility.cpp

@@ -359,6 +359,8 @@ int3 whereToExplore(HeroPtr h)
 	int radius = h->getSightRadious();
 	int3 hpos = h->visitablePos();
 
+	SectorMap sm(h);
+
 	//look for nearby objs -> visit them if they're close enouh
 	const int DIST_LIMIT = 3;
 	std::vector<const CGObjectInstance *> nearbyVisitableObjs;
@@ -372,7 +374,7 @@ int3 whereToExplore(HeroPtr h)
 				CGPath p;
 				ai->myCb->getPathsInfo(h.get())->getPath(op, p);
 				if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
-					if (ai->isGoodForVisit(obj, h))
+					if (ai->isGoodForVisit(obj, h, sm))
 						nearbyVisitableObjs.push_back(obj);
 			}
 		}

+ 54 - 1
AI/VCAI/Goals.cpp

@@ -624,6 +624,58 @@ TGoalVec Explore::getAllPossibleSubgoals()
 			}
 		}
 	}
+
+	//if there are any boats, pathfinder will use them. If not, try to build one
+	/*
+	TODO: this should be optional if no better ways are available.
+	On the other hand you wnat to build boat before looking for exploration point - preferably make boat building another goal
+	*/
+	bool boatsAvailable = false;
+
+	for (const CGObjectInstance *obj : ai->visitableObjs)
+	{
+		if (obj->ID == Obj::BOAT)
+		{
+			auto pos = obj->visitablePos();
+			if ((hero.h && ai->isAccessibleForHero(pos, hero)) || (!hero.h && ai->isAccessible(pos)))
+			{
+					boatsAvailable = true;
+			}
+		}
+	}
+	if (!boatsAvailable) //build one
+	{
+		std::vector<const CGObjectInstance *> shipyards;
+		for (const CGTownInstance *t : cb->getTownsInfo())
+		{
+			if (t->hasBuilt(BuildingID::SHIPYARD))
+				shipyards.push_back(t);
+		}
+
+		for (const CGObjectInstance *obj : ai->getFlaggedObjects())
+		{
+			if (obj->ID != Obj::TOWN) //towns were handled in the previous loop
+				if (const IShipyard *shipyard = IShipyard::castFrom(obj))
+					shipyards.push_back(obj);
+	}
+
+		for (auto shipyard : shipyards)
+		{
+			auto pos = shipyard->visitablePos();
+			if ((hero.h && ai->isAccessibleForHero(pos, hero)) || (!hero.h && ai->isAccessible(pos)))
+			{
+				TResources shipCost;
+				auto s = IShipyard::castFrom(shipyard);
+				s->getBoatCost(shipCost);
+				if (cb->getResourceAmount().canAfford(shipCost))
+				{
+					int3 ret = s->bestLocation();
+					cb->buildBoat(s); //TODO: move actions elsewhere
+				}
+			}
+		}
+	}
+
 	for (auto h : heroes)
 	{
 		SectorMap sm(h);
@@ -1067,10 +1119,11 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
 	}
 	for(auto h : cb->getHeroesInfo())
 	{
+		SectorMap sm(h);
 		for (auto obj : objs)
 		{ //find safe dwelling
 			auto pos = obj->visitablePos();
-			if (ai->isGoodForVisit(obj, h))
+			if (ai->isGoodForVisit(obj, h, sm))
 				ret.push_back (sptr (Goals::VisitTile(pos).sethero(h)));
 		}
 	}

+ 5 - 4
AI/VCAI/VCAI.cpp

@@ -1239,10 +1239,10 @@ void VCAI::buildStructure(const CGTownInstance * t)
 		return;
 }
 
-bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h)
+bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm)
 {
 	const int3 pos = obj->visitablePos();
-	if (isAccessibleForHero(obj->visitablePos(), h) &&
+	if (canReachTile(h.get(), sm.firstTileToGet(h, obj->visitablePos())) &&
 			!obj->wasVisited(playerID) &&
 			(cb->getPlayerRelations(ai->playerID, obj->tempOwner) == PlayerRelations::ENEMIES || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
 			isSafeToVisit(h, pos) &&
@@ -1266,9 +1266,10 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
 {
 	validateVisitableObjs();
 	std::vector<const CGObjectInstance *> possibleDestinations;
+	SectorMap sm(h);
 	for(const CGObjectInstance *obj : visitableObjs)
 	{
-		if (isGoodForVisit(obj, h))
+		if (isGoodForVisit(obj, h, sm))
 		{
 			possibleDestinations.push_back(obj);
 		}
@@ -3117,7 +3118,7 @@ For ship construction etc, another function (goal?) is needed
 							shipyards.push_back(t);
 					}
 
-					for(const CGObjectInstance *obj : ai->visitableObjs)
+					for(const CGObjectInstance *obj : ai->getFlaggedObjects())
 					{
 						if(obj->ID != Obj::TOWN) //towns were handled in the previous loop
 							if(const IShipyard *shipyard = IShipyard::castFrom(obj))

+ 1 - 1
AI/VCAI/VCAI.h

@@ -267,7 +267,7 @@ public:
 	void striveToQuest (const QuestInfo &q);
 
 	void recruitHero(const CGTownInstance * t, bool throwing = false);
-	bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h);
+	bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm);
 	std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);
 	void buildStructure(const CGTownInstance * t);
 	//void recruitCreatures(const CGTownInstance * t);