From a7c45d8ec8f1d6c042e96b9981fe7ab8855b1cad Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 27 Nov 2023 23:17:25 +0200 Subject: [PATCH 1/5] Remove assert - confirmed to be legal scenario --- client/HeroMovementController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/HeroMovementController.cpp b/client/HeroMovementController.cpp index 81a625d12..6b1152f60 100644 --- a/client/HeroMovementController.cpp +++ b/client/HeroMovementController.cpp @@ -100,7 +100,8 @@ void HeroMovementController::showTeleportDialog(const CGHeroInstance * hero, Tel } } - assert(0); // exit not found? How? + // may happen when hero has path but does not moves alongside it + // for example, while standing on teleporter set path that does not leads throught teleporter and press space LOCPLINT->cb->selectionMade(-1, askID); return; } From faead7739a485e642a72097bf64314d74772cc3f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 27 Nov 2023 23:18:48 +0200 Subject: [PATCH 2/5] Do not allow U-turns while flying. Works fine, but poor representation in UI --- lib/pathfinder/CPathfinder.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pathfinder/CPathfinder.cpp b/lib/pathfinder/CPathfinder.cpp index 61cf7aa48..5430548f1 100644 --- a/lib/pathfinder/CPathfinder.cpp +++ b/lib/pathfinder/CPathfinder.cpp @@ -136,6 +136,9 @@ void CPathfinder::calculatePaths() if(neighbour->locked) continue; + if (source.node->theNodeBefore && source.node->theNodeBefore->coord == neighbour->coord ) + continue; // block U-turns + if(!hlp->isLayerAvailable(neighbour->layer)) continue; From 8cbc2c01ad3031e63f76a85b7dcbdcc302ab5fcc Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 27 Nov 2023 23:19:19 +0200 Subject: [PATCH 3/5] Do not allow moving through most of visitable objects --- lib/pathfinder/CPathfinder.cpp | 38 ++++++++++++++++++++++++++++++++-- lib/pathfinder/CPathfinder.h | 1 + 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/pathfinder/CPathfinder.cpp b/lib/pathfinder/CPathfinder.cpp index 5430548f1..a713b5bdc 100644 --- a/lib/pathfinder/CPathfinder.cpp +++ b/lib/pathfinder/CPathfinder.cpp @@ -24,11 +24,45 @@ VCMI_LIB_NAMESPACE_BEGIN +bool CPathfinderHelper::canMoveFromNode(const PathNodeInfo & source) const +{ + // we can always make the first step, even when standing on object + if(source.node->theNodeBefore == nullptr) + return true; + + if (!source.nodeObject) + return true; + + if (!source.isNodeObjectVisitable()) + return true; + + // we can always move from visitable object if hero has teleported here (e.g. went through monolith) + if (source.node->isTeleportAction()) + return true; + + // we can go through garrisons + if (source.nodeObject->ID == MapObjectID::GARRISON || source.nodeObject->ID == MapObjectID::GARRISON2) + return true; + + // or through border gate (if we stand on it then we already have the key) + if (source.nodeObject->ID == MapObjectID::BORDER_GATE) + return true; + + // or "through" boat, but only if this is embarking + if (source.nodeObject->ID == MapObjectID::BOAT && source.node->action == EPathNodeAction::EMBARK) + return true; + + return false; +} + std::vector CPathfinderHelper::getNeighbourTiles(const PathNodeInfo & source) const { std::vector neighbourTiles; - neighbourTiles.reserve(8); + if (!canMoveFromNode(source)) + return neighbourTiles; + + neighbourTiles.reserve(8); getNeighbours( *source.tile, source.node->coord, @@ -38,7 +72,7 @@ std::vector CPathfinderHelper::getNeighbourTiles(const PathNodeInfo & sour if(source.isNodeObjectVisitable()) { - vstd::erase_if(neighbourTiles, [&](const int3 & tile) -> bool + vstd::erase_if(neighbourTiles, [&](const int3 & tile) -> bool { return !canMoveBetween(tile, source.nodeObject->visitablePos()); }); diff --git a/lib/pathfinder/CPathfinder.h b/lib/pathfinder/CPathfinder.h index af12ca56a..4203c8ba1 100644 --- a/lib/pathfinder/CPathfinder.h +++ b/lib/pathfinder/CPathfinder.h @@ -79,6 +79,7 @@ public: virtual ~CPathfinderHelper(); void initializePatrol(); bool isHeroPatrolLocked() const; + bool canMoveFromNode(const PathNodeInfo & source) const; bool isPatrolMovementAllowed(const int3 & dst) const; void updateTurnInfo(const int turn = 0); bool isLayerAvailable(const EPathfindingLayer & layer) const; From 37d81e916e6715ac83a223f2e7741c65b227bf11 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 28 Nov 2023 19:31:38 +0200 Subject: [PATCH 4/5] Fix creature appearance on hota maps --- lib/mapObjects/CGCreature.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/mapObjects/CGCreature.cpp b/lib/mapObjects/CGCreature.cpp index ca661dc8e..f76915582 100644 --- a/lib/mapObjects/CGCreature.cpp +++ b/lib/mapObjects/CGCreature.cpp @@ -215,12 +215,8 @@ void CGCreature::pickRandomObject(CRandomGenerator & rand) subID = VLC->creh->pickRandomMonster(rand, 7); break; } - - if (ID != MapObjectID::MONSTER) - { - ID = MapObjectID::MONSTER; - setType(ID, subID); - } + ID = MapObjectID::MONSTER; + setType(ID, subID); } void CGCreature::initObj(CRandomGenerator & rand) From a7d6068bf6ec7214b3e1d10533b1b68933058e2b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 28 Nov 2023 19:32:03 +0200 Subject: [PATCH 5/5] Do not ignore block-visit objects when computing guardian locations --- lib/mapping/CMap.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index 92893cdbf..c825899e2 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -348,13 +348,8 @@ int3 CMap::guardingCreaturePosition (int3 pos) const { for (CGObjectInstance* obj : posTile.visitableObjects) { - if(obj->isBlockedVisitable()) - { - if (obj->ID == Obj::MONSTER) // Monster - return pos; - else - return int3(-1, -1, -1); //blockvis objects are not guarded by neighbouring creatures - } + if (obj->ID == Obj::MONSTER) + return pos; } }