aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Movement/PathGenerator.cpp88
-rw-r--r--src/server/game/Movement/PathGenerator.h8
2 files changed, 51 insertions, 45 deletions
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index d6fda8eeedb..c1e6482bd0b 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -28,22 +28,22 @@
#include "PhasingHandler.h"
////////////////// PathGenerator //////////////////
-PathGenerator::PathGenerator(Unit const* owner) :
+PathGenerator::PathGenerator(WorldObject const* owner) :
_polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
_forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), _straightLine(false),
- _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(nullptr),
+ _endPosition(G3D::Vector3::zero()), _source(owner), _navMesh(nullptr),
_navMeshQuery(nullptr)
{
memset(_pathPolyRefs, 0, sizeof(_pathPolyRefs));
- TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::PathGenerator for %s", _sourceUnit->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::PathGenerator for %s", _source->GetGUID().ToString().c_str());
- uint32 mapId = PhasingHandler::GetTerrainMapId(_sourceUnit->GetPhaseShift(), _sourceUnit->GetMap(), _sourceUnit->GetPositionX(), _sourceUnit->GetPositionY());
- if (DisableMgr::IsPathfindingEnabled(_sourceUnit->GetMapId()))
+ uint32 mapId = PhasingHandler::GetTerrainMapId(_source->GetPhaseShift(), _source->GetMap(), _source->GetPositionX(), _source->GetPositionY());
+ if (DisableMgr::IsPathfindingEnabled(_source->GetMapId()))
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId);
- _navMeshQuery = mmap->GetNavMeshQuery(mapId, _sourceUnit->GetInstanceId());
+ _navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetInstanceId());
}
CreateFilter();
@@ -51,13 +51,13 @@ PathGenerator::PathGenerator(Unit const* owner) :
PathGenerator::~PathGenerator()
{
- TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::~PathGenerator() for %s", _sourceUnit->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::~PathGenerator() for %s", _source->GetGUID().ToString().c_str());
}
bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest, bool straightLine)
{
float x, y, z;
- _sourceUnit->GetPosition(x, y, z);
+ _source->GetPosition(x, y, z);
if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z))
return false;
@@ -73,11 +73,12 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
_forceDestination = forceDest;
_straightLine = straightLine;
- TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::CalculatePath() for %s", _sourceUnit->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::CalculatePath() for %s", _source->GetGUID().ToString().c_str());
// make sure navMesh works - we can run on map w/o mmap
// check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?)
- if (!_navMesh || !_navMeshQuery || _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING) ||
+ Unit const* _sourceUnit = _source->ToUnit();
+ if (!_navMesh || !_navMeshQuery || (_sourceUnit && _sourceUnit->HasUnitState(UNIT_STATE_IGNORE_PATHFINDING)) ||
!HaveTile(start) || !HaveTile(dest))
{
BuildShortcut();
@@ -176,15 +177,15 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
{
TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)");
BuildShortcut();
- bool path = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanFly();
+ bool path = _source->GetTypeId() == TYPEID_UNIT && _source->ToCreature()->CanFly();
- bool waterPath = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanSwim();
+ bool waterPath = _source->GetTypeId() == TYPEID_UNIT && _source->ToCreature()->CanSwim();
if (waterPath)
{
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
for (uint32 i = 0; i < _pathPoints.size(); ++i)
{
- ZLiquidStatus status = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, map_liquidHeaderTypeFlags::AllLiquids, nullptr, _sourceUnit->GetCollisionHeight());
+ ZLiquidStatus status = _source->GetMap()->GetLiquidStatus(_source->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, map_liquidHeaderTypeFlags::AllLiquids, nullptr, _source->GetCollisionHeight());
// One of the points is not in the water, cancel movement.
if (status == LIQUID_MAP_NO_WATER)
{
@@ -207,20 +208,24 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
bool buildShotrcut = false;
G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
- if (_sourceUnit->GetMap()->IsUnderWater(_sourceUnit->GetPhaseShift(), p.x, p.y, p.z))
+ if (_source->GetMap()->IsUnderWater(_source->GetPhaseShift(), p.x, p.y, p.z))
{
TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: underWater case");
- if (_sourceUnit->CanSwim())
- buildShotrcut = true;
+ if (Unit const* _sourceUnit = _source->ToUnit())
+ if (_sourceUnit->CanSwim())
+ buildShotrcut = true;
}
else
{
TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: flying case");
- if (_sourceUnit->CanFly())
- buildShotrcut = true;
- // Allow to build a shortcut if the unit is falling and it's trying to move downwards towards a target (i.e. charging)
- else if (_sourceUnit->IsFalling() && endPos.z < startPos.z)
- buildShotrcut = true;
+ if (Unit const* _sourceUnit = _source->ToUnit())
+ {
+ if (_sourceUnit->CanFly())
+ buildShotrcut = true;
+ // Allow to build a shortcut if the unit is falling and it's trying to move downwards towards a target (i.e. charging)
+ else if (_sourceUnit->IsFalling() && endPos.z < startPos.z)
+ buildShotrcut = true;
+ }
}
if (buildShotrcut)
@@ -276,7 +281,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
TC_LOG_ERROR("maps.mmaps", "Invalid poly ref in BuildPolyPath. _polyLength: %u, pathStartIndex: %u,"
" startPos: %s, endPos: %s, mapid: %u",
_polyLength, pathStartIndex, startPos.toString().c_str(), endPos.toString().c_str(),
- _sourceUnit->GetMapId());
+ _source->GetMapId());
break;
}
@@ -400,7 +405,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// this is probably an error state, but we'll leave it
// and hopefully recover on the next Update
// we still need to copy our preffix
- TC_LOG_ERROR("maps.mmaps", "Path Build failed\n%s", _sourceUnit->GetDebugInfo().c_str());
+ TC_LOG_ERROR("maps.mmaps", "Path Build failed\n%s", _source->GetDebugInfo().c_str());
}
TC_LOG_DEBUG("maps.mmaps", "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u", _polyLength, prefixPolyLength, suffixPolyLength);
@@ -469,7 +474,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
if (!_polyLength || dtStatusFailed(dtResult))
{
// only happens if we passed bad data to findPath(), or navmesh is messed up
- TC_LOG_ERROR("maps.mmaps", "%s's Path Build failed: 0 length path", _sourceUnit->GetGUID().ToString().c_str());
+ TC_LOG_ERROR("maps.mmaps", "%s's Path Build failed: 0 length path", _source->GetGUID().ToString().c_str());
BuildShortcut();
_type = PATHFIND_NOPATH;
return;
@@ -604,7 +609,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
void PathGenerator::NormalizePath()
{
for (uint32 i = 0; i < _pathPoints.size(); ++i)
- _sourceUnit->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z);
+ _source->UpdateAllowedPositionZ(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z);
}
void PathGenerator::BuildShortcut()
@@ -630,9 +635,9 @@ void PathGenerator::CreateFilter()
uint16 includeFlags = 0;
uint16 excludeFlags = 0;
- if (_sourceUnit->GetTypeId() == TYPEID_UNIT)
+ if (_source->GetTypeId() == TYPEID_UNIT)
{
- Creature* creature = (Creature*)_sourceUnit;
+ Creature* creature = (Creature*)_source;
if (creature->CanWalk())
includeFlags |= NAV_GROUND; // walk
@@ -656,21 +661,22 @@ void PathGenerator::UpdateFilter()
{
// allow creatures to cheat and use different movement types if they are moved
// forcefully into terrain they can't normally move in
- if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater())
- {
- uint16 includedFlags = _filter.getIncludeFlags();
- includedFlags |= GetNavTerrain(_sourceUnit->GetPositionX(),
- _sourceUnit->GetPositionY(),
- _sourceUnit->GetPositionZ());
+ if (Unit const* _sourceUnit = _source->ToUnit())
+ if (_sourceUnit->IsInWater() || _sourceUnit->IsUnderWater())
+ {
+ uint16 includedFlags = _filter.getIncludeFlags();
+ includedFlags |= GetNavTerrain(_source->GetPositionX(),
+ _source->GetPositionY(),
+ _source->GetPositionZ());
- _filter.setIncludeFlags(includedFlags);
- }
+ _filter.setIncludeFlags(includedFlags);
+ }
}
NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z)
{
LiquidData data;
- ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->GetLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, map_liquidHeaderTypeFlags::AllLiquids, &data, _sourceUnit->GetCollisionHeight());
+ ZLiquidStatus liquidStatus = _source->GetMap()->GetLiquidStatus(_source->GetPhaseShift(), x, y, z, map_liquidHeaderTypeFlags::AllLiquids, &data, _source->GetCollisionHeight());
if (liquidStatus == LIQUID_MAP_NO_WATER)
return NAV_GROUND;
@@ -857,7 +863,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
npolys = FixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited);
if (dtStatusFailed(_navMeshQuery->getPolyHeight(polys[0], result, &result[1])))
- TC_LOG_DEBUG("maps.mmaps", "Cannot find height at position X: %f Y: %f Z: %f for %s", result[2], result[0], result[1], _sourceUnit->GetDebugInfo().c_str());
+ TC_LOG_DEBUG("maps.mmaps", "Cannot find height at position X: %f Y: %f Z: %f for %s", result[2], result[0], result[1], _source->GetDebugInfo().c_str());
result[1] += 0.5f;
dtVcopy(iterPos, result);
@@ -961,7 +967,7 @@ void PathGenerator::ShortenPathUntilDist(G3D::Vector3 const& target, float dist)
return;
size_t i = _pathPoints.size()-1;
- float x, y, z, collisionHeight = _sourceUnit->GetCollisionHeight();
+ float x, y, z, collisionHeight = _source->GetCollisionHeight();
// find the first i s.t.:
// - _pathPoints[i] is still too close
// - _pathPoints[i-1] is too far away
@@ -973,8 +979,8 @@ void PathGenerator::ShortenPathUntilDist(G3D::Vector3 const& target, float dist)
break; // bingo!
// check if the shortened path is still in LoS with the target
- _sourceUnit->GetHitSpherePointFor({ _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight }, x, y, z);
- if (!_sourceUnit->GetMap()->isInLineOfSight(_sourceUnit->GetPhaseShift(), x, y, z, _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::Nothing))
+ _source->GetHitSpherePointFor({ _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight }, x, y, z);
+ if (!_source->GetMap()->isInLineOfSight(_source->GetPhaseShift(), x, y, z, _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::Nothing))
{
// whenver we find a point that is not in LoS anymore, simply use last valid path
_pathPoints.resize(i + 1);
@@ -997,7 +1003,7 @@ void PathGenerator::ShortenPathUntilDist(G3D::Vector3 const& target, float dist)
_pathPoints.resize(i+1);
}
-bool PathGenerator::IsInvalidDestinationZ(Unit const* target) const
+bool PathGenerator::IsInvalidDestinationZ(WorldObject const* target) const
{
return (target->GetPositionZ() - GetActualEndPosition().z) > 5.0f;
}
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index 3a9c260684f..c2d850a421d 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -24,7 +24,7 @@
#include "MoveSplineInitArgs.h"
#include <G3D/Vector3.h>
-class Unit;
+class WorldObject;
// 74*4.0f=296y number_of_points*interval = max_path_len
// this is way more than actual evade range
@@ -53,13 +53,13 @@ enum PathType
class TC_GAME_API PathGenerator
{
public:
- explicit PathGenerator(Unit const* owner);
+ explicit PathGenerator(WorldObject const* owner);
~PathGenerator();
// Calculate the path from owner to given destination
// return: true if new path was calculated, false otherwise (no change needed)
bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false, bool straightLine = false);
- bool IsInvalidDestinationZ(Unit const* target) const;
+ bool IsInvalidDestinationZ(WorldObject const* target) const;
// option setters - use optional
void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
@@ -94,7 +94,7 @@ class TC_GAME_API PathGenerator
G3D::Vector3 _endPosition; // {x, y, z} of the destination
G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination
- Unit const* const _sourceUnit; // the unit that is moving
+ WorldObject const* const _source; // the object that is moving
dtNavMesh const* _navMesh; // the nav mesh
dtNavMeshQuery const* _navMeshQuery; // the nav mesh query used to find the path