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:
commit
be9c7f2099
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user