Browse Source

CPathfinder: change cost calculation sequence for embark / disembark

With old embark cost calculation pathfinder may end up thinking that hero can embark/disembark while have less movement points than base movement cost is. Now hero would be only able to embark / disembark if we have enough movement points to step on that tile. This rule is also valid for situation when hero have Admiral's Hat as in H3 even if hero don't have embark penalty he still use move points for embark and disembark.

Problem was found as it's was causing infitite loop in AI. Server of course rejected attempt to embark with less than 100 movement points while pathfinder tell AI that it's can still embark with 93 movement points.
ArseniyShestakov 9 years ago
parent
commit
bf9ac7318a
2 changed files with 12 additions and 10 deletions
  1. 11 9
      lib/CPathfinder.cpp
  2. 1 1
      server/CGameHandler.cpp

+ 11 - 9
lib/CPathfinder.cpp

@@ -150,22 +150,24 @@ void CPathfinder::calculatePaths()
 					continue;
 
 				destAction = getDestAction();
-				int cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, movement, hlp->getTurnInfo());
-				int remains = movement - cost;
-				if(destAction == CGPathNode::EMBARK || destAction == CGPathNode::DISEMBARK)
-				{
-					remains = hero->movementPointsAfterEmbark(movement, cost, destAction - 1, hlp->getTurnInfo());
-					cost = movement - remains;
-				}
-				int turnAtNextTile = turn;
+				int turnAtNextTile = turn, moveAtNextTile = movement;
+				int cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, moveAtNextTile, hlp->getTurnInfo());
+				int remains = moveAtNextTile - cost;
 				if(remains < 0)
 				{
 					//occurs rarely, when hero with low movepoints tries to leave the road
 					hlp->updateTurnInfo(++turnAtNextTile);
-					int moveAtNextTile = hlp->getMaxMovePoints(i);
+					moveAtNextTile = hlp->getMaxMovePoints(i);
 					cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, moveAtNextTile, hlp->getTurnInfo()); //cost must be updated, movement points changed :(
 					remains = moveAtNextTile - cost;
 				}
+				if(destAction == CGPathNode::EMBARK || destAction == CGPathNode::DISEMBARK)
+				{
+					/// FREE_SHIP_BOARDING bonus only remove additional penalty
+					/// land <-> sail transition still cost movement points as normal movement
+					remains = hero->movementPointsAfterEmbark(moveAtNextTile, cost, destAction - 1, hlp->getTurnInfo());
+					cost = moveAtNextTile - remains;
+				}
 
 				if(isBetterWay(remains, turnAtNextTile) &&
 					((cp->turns == turnAtNextTile && remains) || passOneTurnLimitCheck()))

+ 1 - 1
server/CGameHandler.cpp

@@ -1875,7 +1875,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 teleporting, bo
 	{
 		tmh.movePoints = h->movementPointsAfterEmbark(h->movement, cost, false, ti);
 		return doMove(TryMoveHero::EMBARK, IGNORE_GUARDS, DONT_VISIT_DEST, LEAVING_TILE);
-		//attack guards on embarking? In H3 creatures on water had no zone of control at all
+		// In H3 embark ignore guards
 	}
 
 	if(disembarking)