فهرست منبع

- Possible fix for #1769
- Fixed all possible (even unexpected) crashes when AI looses active hero

DjWarmonger 11 سال پیش
والد
کامیت
6658e173f1
3فایلهای تغییر یافته به همراه12 افزوده شده و 10 حذف شده
  1. 3 2
      AI/VCAI/AIUtility.cpp
  2. 1 1
      AI/VCAI/AIUtility.h
  3. 8 7
      AI/VCAI/VCAI.cpp

+ 3 - 2
AI/VCAI/AIUtility.cpp

@@ -344,11 +344,12 @@ bool isReachable(const CGObjectInstance *obj)
 	return cb->getPathInfo(obj->visitablePos())->turns < 255;
 }
 
-bool canBeEmbarkmentPoint(const TerrainTile *t)
+bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater)
 {
 	//tile must be free of with unoccupied boat
 	return !t->blocked
-        || (t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::BOAT);
+        || (!fromWater && t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::BOAT);
+	//do not try to board when in water sector
 }
 
 int3 whereToExplore(HeroPtr h)

+ 1 - 1
AI/VCAI/AIUtility.h

@@ -183,7 +183,7 @@ int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp);
 int howManyTilesWillBeDiscovered(int radious, int3 pos, crint3 dir);
 void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out);
 
-bool canBeEmbarkmentPoint(const TerrainTile *t);
+bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
 bool isBlockedBorderGate(int3 tileToHit);
 bool isReachable(const CGObjectInstance *obj);
 bool isCloser(const CGObjectInstance *lhs, const CGObjectInstance *rhs);

+ 8 - 7
AI/VCAI/VCAI.cpp

@@ -1681,12 +1681,13 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
 		}
 		ret = !i;
 	}
-	if (auto visitedObject = frontOrNull(cb->getVisitableObjs(h->visitablePos()))) //we stand on something interesting
+	if (h)
 	{
-		if (visitedObject != *h)
-			performObjectInteraction (visitedObject, h);
-		//BNLOG("Hero %s moved from %s to %s at %s", h->name % startHpos % visitedObject->hoverName % h->visitablePos());
-		//throw goalFulfilledException (CGoal(GET_OBJ).setobjid(visitedObject->id));
+		if (auto visitedObject = frontOrNull(cb->getVisitableObjs(h->visitablePos()))) //we stand on something interesting
+		{
+			if (visitedObject != *h)
+				performObjectInteraction (visitedObject, h);
+		}
 	}
 	if(h) //we could have lost hero after last move
 	{
@@ -1704,8 +1705,8 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
 			erase_if_present (lockedHeroes, h); //hero seemingly is confused
 			throw cannotFulfillGoalException("Invalid path found!"); //FIXME: should never happen
 		}
+		logAi->debugStream() << boost::format("Hero %s moved from %s to %s. Returning %d.") % h->name % startHpos % h->visitablePos() % ret;
 	}
-    logAi->debugStream() << boost::format("Hero %s moved from %s to %s. Returning %d.") % h->name % startHpos % h->visitablePos() % ret;
 	return ret;
 }
 void VCAI::tryRealize(Goals::Explore & g)
@@ -2725,7 +2726,7 @@ void SectorMap::exploreNewSector(crint3 pos, int num, CCallback * cbp)
 							//parent[neighPos] = curPos;
 						}
 						const TerrainTile *nt = cbp->getTile(neighPos, false);
-						if(nt && nt->isWater() != s.water && canBeEmbarkmentPoint(nt))
+						if(nt && nt->isWater() != s.water && canBeEmbarkmentPoint(nt, s.water))
 						{
 							s.embarkmentPoints.push_back(neighPos);
 						}