1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

CPathfinder: move guard checks into functions

This commit is contained in:
ArseniyShestakov 2015-10-12 08:13:10 +03:00
parent cd7c5acbc4
commit 1beacf2260
2 changed files with 46 additions and 14 deletions

View File

@ -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;

View File

@ -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);