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

CPathfinder: handle event object properly everywhere

Also add forgoted check for AdvmapInterface to avoid possible crash.
This commit is contained in:
ArseniyShestakov 2015-11-17 07:09:01 +03:00
parent e9636a8d37
commit ab9680a7d9
3 changed files with 27 additions and 8 deletions

View File

@ -1545,7 +1545,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
case CGPathNode::VISIT:
case CGPathNode::BLOCKING_VISIT:
if(objAtTile->ID == Obj::HERO)
if(objAtTile && objAtTile->ID == Obj::HERO)
{
if(selection == objAtTile)
CCS->curh->changeGraphic(ECursor::ADVENTURE, 2);

View File

@ -352,13 +352,13 @@ bool CPathfinder::isMovementToDestPossible() const
if(cp->layer == ELayer::LAND)
{
if(!dtObj)
if(!isDestVisitableObj())
return false;
if(dtObj->ID != Obj::BOAT && dtObj->ID != Obj::HERO)
return false;
}
else if(dtObj && dtObj->ID == Obj::BOAT)
else if(isDestVisitableObj() && dtObj->ID == Obj::BOAT)
{
/// Hero in boat can't visit empty boats
return false;
@ -441,7 +441,7 @@ CGPathNode::ENodeAction CPathfinder::getDestAction() const
/// don't break - next case shared for both land and sail layers
case ELayer::SAIL:
if(dtObj)
if(isDestVisitableObj())
{
auto objRel = getPlayerRelations(dtObj->tempOwner, hero->tempOwner);
@ -495,8 +495,7 @@ bool CPathfinder::isSourceInitialPosition() const
bool CPathfinder::isSourceVisitableObj() const
{
/// Hero can't visit objects while walking on water or flying
return ctObj != nullptr && (cp->layer == ELayer::LAND || cp->layer == ELayer::SAIL);
return isVisitableObj(ctObj, cp->layer);
}
bool CPathfinder::isSourceGuarded() const
@ -505,7 +504,7 @@ bool CPathfinder::isSourceGuarded() const
/// It's possible at least in these cases:
/// - Map start with hero on guarded tile
/// - Dimention door used
/// TODO: check what happen when there is several guards
/// TODO: check what happen when there is several guards
if(guardingCreaturePosition(cp->coord) != int3(-1, -1, -1) && !isSourceInitialPosition())
{
return true;
@ -514,6 +513,11 @@ bool CPathfinder::isSourceGuarded() const
return false;
}
bool CPathfinder::isDestVisitableObj() const
{
return isVisitableObj(dtObj, dp->layer);
}
bool CPathfinder::isDestinationGuarded(const bool ignoreAccessibility) const
{
/// isDestinationGuarded is exception needed for garrisons.
@ -600,7 +604,7 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const int3 & pos,
{
return CGPathNode::BLOCKVIS;
}
else if(obj->ID != Obj::EVENT) //pathfinder should ignore placed events
else if(canSeeObj(obj))
{
return CGPathNode::VISITABLE;
}
@ -633,6 +637,18 @@ CGPathNode::EAccessibility CPathfinder::evaluateAccessibility(const int3 & pos,
return CGPathNode::ACCESSIBLE;
}
bool CPathfinder::isVisitableObj(const CGObjectInstance * obj, const ELayer layer) const
{
/// Hero can't visit objects while walking on water or flying
return canSeeObj(obj) && (layer == ELayer::LAND || layer == ELayer::SAIL);
}
bool CPathfinder::canSeeObj(const CGObjectInstance * obj) const
{
/// Pathfinder should ignore placed events
return obj != nullptr && obj->ID != Obj::EVENT;
}
bool CPathfinder::canMoveBetween(const int3 & a, const int3 & b) const
{
return gs->checkForVisitableDir(a, b);

View File

@ -188,12 +188,15 @@ private:
bool isSourceInitialPosition() const;
bool isSourceVisitableObj() const;
bool isSourceGuarded() const;
bool isDestVisitableObj() const;
bool isDestinationGuarded(const bool ignoreAccessibility = true) const;
bool isDestinationGuardian() const;
void initializeGraph();
CGPathNode::EAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile * tinfo, const ELayer layer) const;
bool isVisitableObj(const CGObjectInstance * obj, const ELayer layer) const;
bool canSeeObj(const CGObjectInstance * obj) 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;