1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

CPathfinder: patrol support using getTilesInRange

For now we use getTilesInRange which isn't really correct for patrol, but good enough for first version.
This commit is contained in:
ArseniyShestakov
2015-11-28 20:34:50 +03:00
parent 56c6785bd0
commit 6bb205b15b
3 changed files with 56 additions and 4 deletions

View File

@ -37,7 +37,7 @@ CPathfinder::PathfinderOptions::PathfinderOptions()
}
CPathfinder::CPathfinder(CPathsInfo & _out, CGameState * _gs, const CGHeroInstance * _hero)
: CGameInfoCallback(_gs, boost::optional<PlayerColor>()), out(_out), hero(_hero), FoW(getPlayerTeam(hero->tempOwner)->fogOfWarMap)
: CGameInfoCallback(_gs, boost::optional<PlayerColor>()), out(_out), hero(_hero), FoW(getPlayerTeam(hero->tempOwner)->fogOfWarMap), patrolTiles({})
{
assert(hero);
assert(hero == getHero(hero->id));
@ -52,6 +52,7 @@ CPathfinder::CPathfinder(CPathsInfo & _out, CGameState * _gs, const CGHeroInstan
hlp = make_unique<CPathfinderHelper>(hero, options);
initializePatrol();
initializeGraph();
neighbourTiles.reserve(8);
neighbours.reserve(16);
@ -95,8 +96,10 @@ void CPathfinder::calculatePaths()
CGPathNode * initialNode = out.getNode(out.hpos, hero->boat ? ELayer::SAIL : ELayer::LAND);
initialNode->turns = 0;
initialNode->moveRemains = hero->movement;
pq.push(initialNode);
if(isHeroPatrolLocked())
return;
pq.push(initialNode);
while(!pq.empty())
{
cp = pq.top();
@ -119,6 +122,9 @@ void CPathfinder::calculatePaths()
addNeighbours();
for(auto & neighbour : neighbours)
{
if(!isPatrolMovementAllowed(neighbour))
continue;
dt = &gs->map->getTile(neighbour);
dtObj = dt->topVisitableObj();
for(ELayer i = ELayer::LAND; i <= ELayer::AIR; i.advance(1))
@ -215,7 +221,9 @@ void CPathfinder::addNeighbours()
void CPathfinder::addTeleportExits()
{
neighbours.clear();
if(!isSourceVisitableObj())
/// For now we disable teleports usage for patrol movement
/// VCAI not aware about patrol and may stuck while attempt to use teleport
if(!isSourceVisitableObj() || patrolState == PATROL_RADIUS)
return;
const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(ctObj);
@ -256,6 +264,22 @@ void CPathfinder::addTeleportExits()
}
}
bool CPathfinder::isHeroPatrolLocked() const
{
return patrolState == PATROL_LOCKED;
}
bool CPathfinder::isPatrolMovementAllowed(const int3 & dst) const
{
if(patrolState == PATROL_RADIUS)
{
if(!vstd::contains(patrolTiles, dst))
return false;
}
return true;
}
bool CPathfinder::isLayerTransitionPossible(const ELayer destLayer) const
{
/// No layer transition allowed when previous node action is BATTLE
@ -564,6 +588,23 @@ bool CPathfinder::isDestinationGuardian() const
return gs->guardingCreaturePosition(cp->coord) == dp->coord;
}
void CPathfinder::initializePatrol()
{
auto state = PATROL_NONE;
if(hero->patrol.patrolling && !getPlayer(hero->tempOwner)->human)
{
if(hero->patrol.patrolRadious)
{
state = PATROL_RADIUS;
gs->getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadious);
}
else
state = PATROL_LOCKED;
}
patrolState = state;
}
void CPathfinder::initializeGraph()
{
auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo)