Bläddra i källkod

A number of fixes for wander / SectorMap.

DjWarmonger 10 år sedan
förälder
incheckning
6cfc89dc7c
1 ändrade filer med 17 tillägg och 4 borttagningar
  1. 17 4
      AI/VCAI/VCAI.cpp

+ 17 - 4
AI/VCAI/VCAI.cpp

@@ -835,8 +835,12 @@ void VCAI::makeTurnInternal()
 bool VCAI::goVisitObj(const CGObjectInstance * obj, HeroPtr h)
 {
 	int3 dst = obj->visitablePos();
+	SectorMap sm(h);
 	logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getObjectName() % strFromInt3(dst);
-	return moveHeroToTile(dst, h);
+	int3 pos = sm.firstTileToGet(h, dst);
+	if (!pos.valid()) //rare case when we are already standing on one of potential objects
+		return false;
+	return moveHeroToTile(pos, h);
 }
 
 void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
@@ -1242,7 +1246,8 @@ void VCAI::buildStructure(const CGTownInstance * t)
 bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm)
 {
 	const int3 pos = obj->visitablePos();
-	if (canReachTile(h.get(), sm.firstTileToGet(h, obj->visitablePos())) &&
+	const int3 targetPos = sm.firstTileToGet(h, pos);
+	if (canReachTile(h.get(), targetPos) &&
 			!obj->wasVisited(playerID) &&
 			(cb->getPlayerRelations(ai->playerID, obj->tempOwner) == PlayerRelations::ENEMIES || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
 			isSafeToVisit(h, pos) &&
@@ -1324,14 +1329,22 @@ void VCAI::wander(HeroPtr h)
 		validateVisitableObjs();
 		std::vector <ObjectIdRef> dests, tmp;
 
+		SectorMap sm(h);
+
 		range::copy(reservedHeroesMap[h], std::back_inserter(tmp)); //also visit our reserved objects - but they are not prioritized to avoid running back and forth
 		for (auto obj : tmp)
 		{
-			if (isAccessibleForHero (obj->visitablePos(), h)) //even nearby objects could be blocked by other heroes :(
-				dests.push_back(obj); //can't use lambda for member function :(
+			int3 pos = sm.firstTileToGet(h, obj->visitablePos());
+			if (pos.valid())
+				if (isAccessibleForHero (pos, h)) //even nearby objects could be blocked by other heroes :(
+					dests.push_back(obj); //can't use lambda for member function :(
 		}
 
 		range::copy(getPossibleDestinations(h), std::back_inserter(dests));
+		erase_if(dests, [&](ObjectIdRef obj) -> bool
+		{
+			return !isSafeToVisit(h, sm.firstTileToGet(h, obj->visitablePos()));
+		});
 
 		if(!dests.size())
 		{