1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-23 21:29:13 +02:00

Merge pull request #3239 from IvanSavenko/pathfinder_fixes

Pathfinder fixes
This commit is contained in:
Ivan Savenko 2023-12-02 12:20:44 +02:00 committed by GitHub
commit be9c7f2099
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 16 deletions

View File

@ -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); LOCPLINT->cb->selectionMade(-1, askID);
return; return;
} }

View File

@ -215,12 +215,8 @@ void CGCreature::pickRandomObject(CRandomGenerator & rand)
subID = VLC->creh->pickRandomMonster(rand, 7); subID = VLC->creh->pickRandomMonster(rand, 7);
break; break;
} }
ID = MapObjectID::MONSTER;
if (ID != MapObjectID::MONSTER) setType(ID, subID);
{
ID = MapObjectID::MONSTER;
setType(ID, subID);
}
} }
void CGCreature::initObj(CRandomGenerator & rand) void CGCreature::initObj(CRandomGenerator & rand)

View File

@ -348,13 +348,8 @@ int3 CMap::guardingCreaturePosition (int3 pos) const
{ {
for (CGObjectInstance* obj : posTile.visitableObjects) for (CGObjectInstance* obj : posTile.visitableObjects)
{ {
if(obj->isBlockedVisitable()) if (obj->ID == Obj::MONSTER)
{ return pos;
if (obj->ID == Obj::MONSTER) // Monster
return pos;
else
return int3(-1, -1, -1); //blockvis objects are not guarded by neighbouring creatures
}
} }
} }

View File

@ -24,11 +24,45 @@
VCMI_LIB_NAMESPACE_BEGIN 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<int3> CPathfinderHelper::getNeighbourTiles(const PathNodeInfo & source) const std::vector<int3> CPathfinderHelper::getNeighbourTiles(const PathNodeInfo & source) const
{ {
std::vector<int3> neighbourTiles; std::vector<int3> neighbourTiles;
neighbourTiles.reserve(8);
if (!canMoveFromNode(source))
return neighbourTiles;
neighbourTiles.reserve(8);
getNeighbours( getNeighbours(
*source.tile, *source.tile,
source.node->coord, source.node->coord,
@ -38,7 +72,7 @@ std::vector<int3> CPathfinderHelper::getNeighbourTiles(const PathNodeInfo & sour
if(source.isNodeObjectVisitable()) 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()); return !canMoveBetween(tile, source.nodeObject->visitablePos());
}); });
@ -136,6 +170,9 @@ void CPathfinder::calculatePaths()
if(neighbour->locked) if(neighbour->locked)
continue; continue;
if (source.node->theNodeBefore && source.node->theNodeBefore->coord == neighbour->coord )
continue; // block U-turns
if(!hlp->isLayerAvailable(neighbour->layer)) if(!hlp->isLayerAvailable(neighbour->layer))
continue; continue;

View File

@ -79,6 +79,7 @@ public:
virtual ~CPathfinderHelper(); virtual ~CPathfinderHelper();
void initializePatrol(); void initializePatrol();
bool isHeroPatrolLocked() const; bool isHeroPatrolLocked() const;
bool canMoveFromNode(const PathNodeInfo & source) const;
bool isPatrolMovementAllowed(const int3 & dst) const; bool isPatrolMovementAllowed(const int3 & dst) const;
void updateTurnInfo(const int turn = 0); void updateTurnInfo(const int turn = 0);
bool isLayerAvailable(const EPathfindingLayer & layer) const; bool isLayerAvailable(const EPathfindingLayer & layer) const;