1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

CPathfinder: update teleport code and use TurnInfo for whirlpools

This commit is contained in:
ArseniyShestakov
2015-11-16 19:14:18 +03:00
parent 0949283cb9
commit 8f72d73241
2 changed files with 29 additions and 30 deletions

View File

@@ -203,36 +203,16 @@ void CPathfinder::addNeighbours(const int3 & coord)
vstd::concatenate(neighbours, tiles);
}
void CPathfinder::addTeleportExits(bool noTeleportExcludes)
void CPathfinder::addTeleportExits()
{
neighbours.clear();
if(!isSourceVisitableObj())
return;
auto isAllowedTeleportEntrance = [&](const CGTeleport * obj) -> bool
const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(ctObj);
if(isAllowedTeleportEntrance(objTeleport))
{
if(!gs->isTeleportEntrancePassable(obj, hero->tempOwner))
return false;
if(noTeleportExcludes)
return true;
auto whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
if(whirlpool)
{
if(addTeleportWhirlpool(whirlpool))
return true;
}
else if(addTeleportTwoWay(obj) || addTeleportOneWay(obj) || addTeleportOneWayRandom(obj))
return true;
return false;
};
const CGTeleport * sTileTeleport = dynamic_cast<const CGTeleport *>(ctObj);
if(isAllowedTeleportEntrance(sTileTeleport))
{
for(auto objId : gs->getTeleportChannelExits(sTileTeleport->channel, hero->tempOwner))
for(auto objId : gs->getTeleportChannelExits(objTeleport->channel, hero->tempOwner))
{
auto obj = getObj(objId);
if(dynamic_cast<const CGWhirlpool *>(obj))
@@ -401,18 +381,19 @@ bool CPathfinder::isMovementAfterDestPossible() const
/// TODO: Investigate what kind of limitation is possible to apply on movement from visitable tiles
/// Likely in many cases we don't need to add visitable tile to queue when hero don't fly
case CGPathNode::VISIT:
{
/// For now we only add visitable tile into queue when it's teleporter that allow transit
/// Movement from visitable tile when hero is standing on it is possible into any layer
if(CGTeleport::isTeleport(dtObj))
const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(dtObj);
if(isAllowedTeleportEntrance(objTeleport))
{
/// For now we'll always allow transit over teleporters
/// Transit over whirlpools only allowed when hero protected
auto whirlpool = dynamic_cast<const CGWhirlpool *>(dtObj);
if(!whirlpool || options.useTeleportWhirlpool)
return true;
}
break;
}
case CGPathNode::NORMAL:
return true;
@@ -635,6 +616,23 @@ bool CPathfinder::canMoveBetween(const int3 & a, const int3 & b) const
return gs->checkForVisitableDir(a, b);
}
bool CPathfinder::isAllowedTeleportEntrance(const CGTeleport * obj) const
{
if(!obj || !gs->isTeleportEntrancePassable(obj, hero->tempOwner))
return false;
auto whirlpool = dynamic_cast<const CGWhirlpool *>(obj);
if(whirlpool)
{
if(addTeleportWhirlpool(whirlpool))
return true;
}
else if(addTeleportTwoWay(obj) || addTeleportOneWay(obj) || addTeleportOneWayRandom(obj))
return true;
return false;
}
bool CPathfinder::addTeleportTwoWay(const CGTeleport * obj) const
{
return options.useTeleportTwoWay && gs->isTeleportChannelBidirectional(obj->channel, hero->tempOwner);
@@ -664,7 +662,7 @@ bool CPathfinder::addTeleportOneWayRandom(const CGTeleport * obj) const
bool CPathfinder::addTeleportWhirlpool(const CGWhirlpool * obj) const
{
return options.useTeleportWhirlpool && obj;
return options.useTeleportWhirlpool && hlp->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION) && obj;
}
TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)

View File

@@ -166,7 +166,7 @@ private:
CGPathNode::ENodeAction destAction;
void addNeighbours(const int3 & coord);
void addTeleportExits(bool noTeleportExcludes = false);
void addTeleportExits();
bool isLayerTransitionPossible() const;
bool isMovementToDestPossible() const;
@@ -184,6 +184,7 @@ private:
CGPathNode::EAccessibility evaluateAccessibility(const int3 & pos, 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)
bool isAllowedTeleportEntrance(const CGTeleport * obj) const;
bool addTeleportTwoWay(const CGTeleport * obj) const;
bool addTeleportOneWay(const CGTeleport * obj) const;
bool addTeleportOneWayRandom(const CGTeleport * obj) const;