mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
CPathfinder: separate teleporter exits and neighbour tile code
This way code that handle real neighbour tiles is more readable and teleport exits don't have to go via all checks they ignore anyway.
This commit is contained in:
parent
f15065fdc5
commit
13c2b5e2d8
@ -3300,13 +3300,33 @@ void CPathfinder::initializeGraph()
|
||||
}
|
||||
}
|
||||
|
||||
void CPathfinder::getNeighbours(const int3 &coord, bool noTeleportExcludes)
|
||||
void CPathfinder::getNeighbours(const int3 &coord)
|
||||
{
|
||||
neighbours.clear();
|
||||
ct = &gs->map->getTile(coord);
|
||||
// Will be needed for usage outside of calculatePaths
|
||||
// if(!cp)
|
||||
// cp = getNode(coord);
|
||||
|
||||
std::vector<int3> tiles;
|
||||
gs->getNeighbours(*ct, coord, tiles, boost::logic::indeterminate, !cp->land);
|
||||
sTileObj = ct->topVisitableObj(coord == CGHeroInstance::convertPosition(hero->pos, false));
|
||||
if(sTileObj)
|
||||
{
|
||||
for(int3 tile: tiles)
|
||||
{
|
||||
if(canMoveBetween(tile, sTileObj->visitablePos()))
|
||||
neighbours.push_back(tile);
|
||||
}
|
||||
}
|
||||
else
|
||||
vstd::concatenate(neighbours, tiles);
|
||||
}
|
||||
|
||||
void CPathfinder::getTeleportExits(bool noTeleportExcludes)
|
||||
{
|
||||
assert(sTileObj);
|
||||
|
||||
neighbours.clear();
|
||||
auto isAllowedTeleportEntrance = [&](const CGTeleport * obj) -> bool
|
||||
{
|
||||
@ -3328,7 +3348,6 @@ void CPathfinder::getNeighbours(const int3 &coord, bool noTeleportExcludes)
|
||||
return false;
|
||||
};
|
||||
|
||||
sTileObj = ct->topVisitableObj(coord == CGHeroInstance::convertPosition(hero->pos, false));
|
||||
sTileTeleport = dynamic_cast<const CGTeleport *>(sTileObj);
|
||||
if(isAllowedTeleportEntrance(sTileTeleport))
|
||||
{
|
||||
@ -3339,19 +3358,6 @@ void CPathfinder::getNeighbours(const int3 &coord, bool noTeleportExcludes)
|
||||
neighbours.push_back(obj->visitablePos());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int3> neighbour_tiles;
|
||||
gs->getNeighbours(*ct, coord, neighbour_tiles, boost::logic::indeterminate, !cp->land);
|
||||
if(sTileObj)
|
||||
{
|
||||
for(int3 neighbour_tile: neighbour_tiles)
|
||||
{
|
||||
if(canMoveBetween(neighbour_tile, sTileObj->visitablePos()))
|
||||
neighbours.push_back(neighbour_tile);
|
||||
}
|
||||
}
|
||||
else
|
||||
vstd::concatenate(neighbours, neighbour_tiles);
|
||||
}
|
||||
|
||||
void CPathfinder::calculatePaths()
|
||||
@ -3406,13 +3412,11 @@ void CPathfinder::calculatePaths()
|
||||
dp = getNode(neighbour);
|
||||
dt = &gs->map->getTile(neighbour);
|
||||
destTopVisObjID = dt->topVisitableId();
|
||||
|
||||
useEmbarkCost = 0; //0 - usual movement; 1 - embark; 2 - disembark
|
||||
const bool destIsGuardian = sourceGuardPosition == neighbour;
|
||||
|
||||
dTileTeleport = dynamic_cast<const CGTeleport*>(dt->topVisitableObj());
|
||||
if(!goodForLandSeaTransition()
|
||||
|| (!canMoveBetween(cp->coord, dp->coord) && !CGTeleport::isConnected(sTileTeleport, dTileTeleport))
|
||||
|| !canMoveBetween(cp->coord, dp->coord)
|
||||
|| dp->accessible == CGPathNode::BLOCKED)
|
||||
{
|
||||
continue;
|
||||
@ -3423,10 +3427,6 @@ void CPathfinder::calculatePaths()
|
||||
guardedSource = false;
|
||||
|
||||
int cost = gs->getMovementCost(hero, cp->coord, dp->coord, flying, movement);
|
||||
//special case -> moving from src Subterranean gate to dest gate -> it's free
|
||||
if(CGTeleport::isConnected(sTileTeleport, dTileTeleport))
|
||||
cost = 0;
|
||||
|
||||
int remains = movement - cost;
|
||||
if(useEmbarkCost)
|
||||
{
|
||||
@ -3467,10 +3467,6 @@ void CPathfinder::calculatePaths()
|
||||
return true; // For now we'll walways allos transit for teleports
|
||||
if(useEmbarkCost && allowEmbarkAndDisembark)
|
||||
return true;
|
||||
if(gs->isTeleportEntrancePassable(dTileTeleport, hero->tempOwner))
|
||||
return true; // Always add entry teleport with non-dummy channel
|
||||
if(CGTeleport::isConnected(sTileTeleport, dTileTeleport))
|
||||
return true; // Always add exit points of teleport
|
||||
if(guardedDst && !guardedSource)
|
||||
return true; // Can step into a hostile tile once
|
||||
|
||||
@ -3481,6 +3477,23 @@ void CPathfinder::calculatePaths()
|
||||
mq.push_back(dp);
|
||||
}
|
||||
} //neighbours loop
|
||||
|
||||
//just add all passable teleport exits
|
||||
if(sTileObj)
|
||||
{
|
||||
getTeleportExits();
|
||||
for(auto & neighbour : neighbours)
|
||||
{
|
||||
dp = getNode(neighbour);
|
||||
if (dp->turns == 0xff)
|
||||
{
|
||||
dp->moveRemains = movement;
|
||||
dp->turns = turn;
|
||||
dp->theNodeBefore = cp;
|
||||
mq.push_back(dp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} //queue loop
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,8 @@ private:
|
||||
void initializeGraph();
|
||||
bool goodForLandSeaTransition(); //checks if current move will be between sea<->land. If so, checks it legality (returns false if movement is not possible) and sets useEmbarkCost
|
||||
|
||||
void getNeighbours(const int3 &coord, bool noTeleportExcludes = false);
|
||||
void getNeighbours(const int3 &coord);
|
||||
void getTeleportExits(bool noTeleportExcludes = false);
|
||||
|
||||
CGPathNode::EAccessibility evaluateAccessibility(const TerrainTile *tinfo) const;
|
||||
bool canMoveBetween(const int3 &a, const int3 &b) const; //checks only for visitable objects that may make moving between tiles impossible, not other conditions (like tiles itself accessibility)
|
||||
|
Loading…
Reference in New Issue
Block a user