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); vstd::concatenate(neighbours, tiles);
} }
void CPathfinder::addTeleportExits(bool noTeleportExcludes) void CPathfinder::addTeleportExits()
{ {
neighbours.clear(); neighbours.clear();
if(!isSourceVisitableObj()) if(!isSourceVisitableObj())
return; return;
auto isAllowedTeleportEntrance = [&](const CGTeleport * obj) -> bool const CGTeleport * objTeleport = dynamic_cast<const CGTeleport *>(ctObj);
if(isAllowedTeleportEntrance(objTeleport))
{ {
if(!gs->isTeleportEntrancePassable(obj, hero->tempOwner)) for(auto objId : gs->getTeleportChannelExits(objTeleport->channel, 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))
{ {
auto obj = getObj(objId); auto obj = getObj(objId);
if(dynamic_cast<const CGWhirlpool *>(obj)) 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 /// 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 /// Likely in many cases we don't need to add visitable tile to queue when hero don't fly
case CGPathNode::VISIT: case CGPathNode::VISIT:
{
/// For now we only add visitable tile into queue when it's teleporter that allow transit /// 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 /// 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 /// For now we'll always allow transit over teleporters
/// Transit over whirlpools only allowed when hero protected /// Transit over whirlpools only allowed when hero protected
auto whirlpool = dynamic_cast<const CGWhirlpool *>(dtObj); return true;
if(!whirlpool || options.useTeleportWhirlpool)
return true;
} }
break; break;
}
case CGPathNode::NORMAL: case CGPathNode::NORMAL:
return true; return true;
@@ -635,6 +616,23 @@ bool CPathfinder::canMoveBetween(const int3 & a, const int3 & b) const
return gs->checkForVisitableDir(a, b); 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 bool CPathfinder::addTeleportTwoWay(const CGTeleport * obj) const
{ {
return options.useTeleportTwoWay && gs->isTeleportChannelBidirectional(obj->channel, hero->tempOwner); 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 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) TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)

View File

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