diff --git a/lib/CPathfinder.cpp b/lib/CPathfinder.cpp index 0647981d1..9f4911d91 100644 --- a/lib/CPathfinder.cpp +++ b/lib/CPathfinder.cpp @@ -225,6 +225,40 @@ void CPathfinder::addTeleportExits(bool noTeleportExcludes) } } +bool CPathfinder::isLayerTransitionPossible() +{ + if((cp->layer == EPathfindingLayer::AIR || cp->layer == EPathfindingLayer::WATER) + && dp->layer != EPathfindingLayer::LAND) + { + return false; + } + else if(cp->layer == EPathfindingLayer::SAIL && dp->layer != EPathfindingLayer::LAND) + return false; + else if(cp->layer == EPathfindingLayer::SAIL && dp->layer == EPathfindingLayer::LAND) + { + if(!dt->isCoastal()) + return false; + + //tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast + if((dp->accessible != CGPathNode::ACCESSIBLE && (dp->accessible != CGPathNode::BLOCKVIS || dt->blocked)) + || dt->visitable) //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate + return false; + + useEmbarkCost = 2; + } + else if(cp->layer == EPathfindingLayer::LAND && dp->layer == EPathfindingLayer::SAIL) + { + Obj destTopVisObjID = dt->topVisitableId(); + if(dp->accessible == CGPathNode::ACCESSIBLE || destTopVisObjID < 0) //cannot enter empty water tile from land -> it has to be visitable + return false; + if(destTopVisObjID != Obj::HERO && destTopVisObjID != Obj::BOAT) //only boat or hero can be accessed from land + return false; + if(destTopVisObjID == Obj::BOAT) + useEmbarkCost = 1; + } + return true; +} + bool CPathfinder::isMovementToDestPossible() { switch (dp->layer) @@ -463,40 +497,6 @@ bool CPathfinder::canVisitObject() const return cp->layer == EPathfindingLayer::LAND || cp->layer == EPathfindingLayer::SAIL; } -bool CPathfinder::isLayerTransitionPossible() -{ - if((cp->layer == EPathfindingLayer::AIR || cp->layer == EPathfindingLayer::WATER) - && dp->layer != EPathfindingLayer::LAND) - { - return false; - } - else if(cp->layer == EPathfindingLayer::SAIL && dp->layer != EPathfindingLayer::LAND) - return false; - else if(cp->layer == EPathfindingLayer::SAIL && dp->layer == EPathfindingLayer::LAND) - { - if(!dt->isCoastal()) - return false; - - //tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast - if((dp->accessible != CGPathNode::ACCESSIBLE && (dp->accessible != CGPathNode::BLOCKVIS || dt->blocked)) - || dt->visitable) //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate - return false; - - useEmbarkCost = 2; - } - else if(cp->layer == EPathfindingLayer::LAND && dp->layer == EPathfindingLayer::SAIL) - { - Obj destTopVisObjID = dt->topVisitableId(); - if(dp->accessible == CGPathNode::ACCESSIBLE || destTopVisObjID < 0) //cannot enter empty water tile from land -> it has to be visitable - return false; - if(destTopVisObjID != Obj::HERO && destTopVisObjID != Obj::BOAT) //only boat or hero can be accessed from land - return false; - if(destTopVisObjID == Obj::BOAT) - useEmbarkCost = 1; - } - return true; -} - CGPathNode::CGPathNode() :coord(-1,-1,-1) { diff --git a/lib/CPathfinder.h b/lib/CPathfinder.h index 4a7b9f790..660e472cc 100644 --- a/lib/CPathfinder.h +++ b/lib/CPathfinder.h @@ -105,7 +105,8 @@ private: void addNeighbours(const int3 &coord); void addTeleportExits(bool noTeleportExcludes = false); - bool isMovementToDestPossible(); //checks if current move will be between sea<->land. If so, checks it legality (returns false if movement is not possible) and sets useEmbarkCost + bool isLayerTransitionPossible(); + bool isMovementToDestPossible(); bool isMovementAfterDestPossible(); int3 getSourceGuardPosition(); @@ -125,5 +126,4 @@ private: bool canVisitObject() const; - bool isLayerTransitionPossible(); };