Ver código fonte

CPathfinder: move guard checks into functions

ArseniyShestakov 10 anos atrás
pai
commit
1beacf2260
2 arquivos alterados com 46 adições e 14 exclusões
  1. 41 14
      lib/CGameState.cpp
  2. 5 0
      lib/CGameState.h

+ 41 - 14
lib/CGameState.cpp

@@ -3360,12 +3360,50 @@ void CPathfinder::getTeleportExits(bool noTeleportExcludes)
 	}
 }
 
+int3 CPathfinder::getSourceGuardPosition()
+{
+	return gs->map->guardingCreaturePositions[cp->coord.x][cp->coord.y][cp->coord.z];
+}
+
+bool CPathfinder::isSourceGuarded()
+{
+	//TODO: find out why exactly source can't be guarded if hero on it. Why this quirk was nessesaary in first place? Map where hero start on guarded tile?
+	if(getSourceGuardPosition() != int3(-1, -1, -1)
+		&& cp->coord != hero->getPosition(false))
+	{
+		//special case -> hero embarked a boat standing on a guarded tile -> we must allow to move away from that tile
+		if(cp->accessible != CGPathNode::VISITABLE
+		   || !cp->theNodeBefore->land
+		   || ct->topVisitableId() != Obj::BOAT)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool CPathfinder::isDestinationGuarded()
+{
+	if(gs->map->guardingCreaturePositions[dp->coord.x][dp->coord.y][dp->coord.z].valid()
+		&& dp->accessible == CGPathNode::BLOCKVIS)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+bool CPathfinder::isDestinationGuardian()
+{
+	return getSourceGuardPosition() == dp->coord;
+}
+
 void CPathfinder::calculatePaths()
 {
 	bool flying = hero->hasBonusOfType(Bonus::FLYING_MOVEMENT);
 	int maxMovePointsLand = hero->maxMovePoints(true);
 	int maxMovePointsWater = hero->maxMovePoints(false);
-	int3 src = hero->getPosition(false);
 
 	auto maxMovePoints = [&](CGPathNode *cp) -> int
 	{
@@ -3395,9 +3433,6 @@ void CPathfinder::calculatePaths()
 		cp = mq.front();
 		mq.pop_front();
 
-		const int3 sourceGuardPosition = gs->map->guardingCreaturePositions[cp->coord.x][cp->coord.y][cp->coord.z];
-		bool guardedSource = (sourceGuardPosition != int3(-1, -1, -1) && cp->coord != src);
-
 		int movement = cp->moveRemains, turn = cp->turns;
 		if(!movement)
 		{
@@ -3412,7 +3447,6 @@ void CPathfinder::calculatePaths()
 			dp = getNode(neighbour);
 			dt = &gs->map->getTile(neighbour);
 			useEmbarkCost = 0; //0 - usual movement; 1 - embark; 2 - disembark
-			const bool destIsGuardian = sourceGuardPosition == neighbour;
 
 			if(!isMovementPossible())
 				continue;
@@ -3435,23 +3469,16 @@ void CPathfinder::calculatePaths()
 				remains = moveAtNextTile - cost;
 			}
 
-			//special case -> hero embarked a boat standing on a guarded tile -> we must allow to move away from that tile
-			if(cp->accessible == CGPathNode::VISITABLE && guardedSource && cp->theNodeBefore->land && ct->topVisitableId() == Obj::BOAT)
-				guardedSource = false;
-
 			if((dp->turns==0xff		//we haven't been here before
 				|| dp->turns > turnAtNextTile
 				|| (dp->turns >= turnAtNextTile  &&  dp->moveRemains < remains)) //this route is faster
-				&& (!guardedSource || destIsGuardian)) // Can step into tile of guard
+				&& (!isSourceGuarded() || isDestinationGuardian())) // Can step into tile of guard
 			{
 				assert(dp != cp->theNodeBefore); //two tiles can't point to each other
 				dp->moveRemains = remains;
 				dp->turns = turnAtNextTile;
 				dp->theNodeBefore = cp;
 
-				const bool guardedDst = gs->map->guardingCreaturePositions[dp->coord.x][dp->coord.y][dp->coord.z].valid()
-										&& dp->accessible == CGPathNode::BLOCKVIS;
-
 				auto checkDestinationTile = [&]() -> bool
 				{
 					if(dp->accessible == CGPathNode::ACCESSIBLE)
@@ -3462,7 +3489,7 @@ void CPathfinder::calculatePaths()
 						return true; // For now we'll walways allos transit for teleports
 					if(useEmbarkCost && allowEmbarkAndDisembark)
 						return true;
-					if(guardedDst && !guardedSource)
+					if(isDestinationGuarded() && !isSourceGuarded())
 						return true; // Can step into a hostile tile once
 
 					return false;

+ 5 - 0
lib/CGameState.h

@@ -307,6 +307,11 @@ private:
 	void initializeGraph();
 	bool isMovementPossible(); //checks if current move will be between sea<->land. If so, checks it legality (returns false if movement is not possible) and sets useEmbarkCost
 
+	int3 getSourceGuardPosition();
+	bool isSourceGuarded();
+	bool isDestinationGuarded();
+	bool isDestinationGuardian();
+
 	void getNeighbours(const int3 &coord);
 	void getTeleportExits(bool noTeleportExcludes = false);