Transcription ArgusCore : anti-clip des clotures (d21a91eb)

PathGenerator::ValidatePathAgainstCollision() appelee en fin de BuildPointPath :
valide chaque segment du chemin MMAP contre la collision vmap (isInLineOfSight,
ModelIgnoreFlags::Nothing). Le MMAP ne modelise pas les objets fins (clotures,
barrieres) -> un chemin nav-mesh valide peut les traverser. Si un segment est bloque,
on tronque le chemin (PATHFIND_INCOMPLETE) pour que l unite s arrete devant l obstacle.
Adapte a nos APIs : _sourceUnit, isInLineOfSight 8-params, log printf, halfHeight fixe.
Skippe les chemins non-MMAP (vol/nage/raccourcis).

ARBITRAGE reversible : plus realiste mais risque de sur-troncature (PNJ qui s arretent
devant une porte/rampe M2 vue comme obstacle). A surveiller : PNJ bloques en mouvement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-07-26 17:22:16 +00:00
parent 13e246f744
commit 846517c655
2 changed files with 45 additions and 0 deletions
@@ -590,6 +590,8 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
}
ValidatePathAgainstCollision();
TC_LOG_DEBUG("maps", "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", _type, pointCount, _polyLength);
}
@@ -599,6 +601,42 @@ void PathGenerator::NormalizePath()
_sourceUnit->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z);
}
void PathGenerator::ValidatePathAgainstCollision()
{
// Raccourcis en ligne droite voulus (vol, nage, repli). Seuls les chemins sol MMAP sont valides.
if (_type & PATHFIND_NOT_USING_PATH)
return;
if (_pathPoints.size() < 2)
return;
// rayon leve a hauteur de torse pour accrocher une cloture et non le sol
float const halfHeight = 1.0f;
for (uint32 i = 0; i + 1 < _pathPoints.size(); ++i)
{
G3D::Vector3 const& from = _pathPoints[i];
G3D::Vector3 const& to = _pathPoints[i + 1];
if (_sourceUnit->GetMap()->isInLineOfSight(_sourceUnit->GetPhaseShift(),
from.x, from.y, from.z + halfHeight, to.x, to.y, to.z + halfHeight,
VMAP::ModelIgnoreFlags::Nothing))
continue;
// segment bloque par une geometrie absente du navmesh (cloture) : on tronque
if (i == 0)
{
Clear();
_pathPoints.resize(2);
_pathPoints[0] = GetStartPosition();
_pathPoints[1] = GetStartPosition();
_type = PATHFIND_NOPATH;
}
else
{
_pathPoints.resize(i + 1);
SetActualEndPosition(_pathPoints.back());
_type = PathType(_type | PATHFIND_INCOMPLETE);
}
return;
}
}
void PathGenerator::BuildShortcut()
{
TC_LOG_DEBUG("maps", "++ BuildShortcut :: making shortcut\n");
+7
View File
@@ -106,6 +106,13 @@ class TC_GAME_API PathGenerator
void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; }
void NormalizePath();
// Apres la generation du chemin MMAP, valide chaque segment contre la collision vmap
// statique. Le MMAP ne modelise pas les objets fins (clotures, petites barrieres) : un
// chemin nav-mesh valide peut donc traverser une cloture. Si un segment est bloque, on
// tronque le chemin la et on marque PATHFIND_INCOMPLETE pour que l unite s arrete devant
// l obstacle au lieu de le traverser (ArgusCore d21a91eb).
void ValidatePathAgainstCollision();
void Clear()
{
_polyLength = 0;