diff --git a/client/windows/CAdvmapInterface.cpp b/client/windows/CAdvmapInterface.cpp index c0a208631..e48daf709 100644 --- a/client/windows/CAdvmapInterface.cpp +++ b/client/windows/CAdvmapInterface.cpp @@ -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); diff --git a/lib/CPathfinder.cpp b/lib/CPathfinder.cpp index ab2146796..49cb006f8 100644 --- a/lib/CPathfinder.cpp +++ b/lib/CPathfinder.cpp @@ -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); diff --git a/lib/CPathfinder.h b/lib/CPathfinder.h index f035383af..143502eab 100644 --- a/lib/CPathfinder.h +++ b/lib/CPathfinder.h @@ -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;