aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Movement/PathGenerator.cpp84
-rw-r--r--src/server/game/Movement/PathGenerator.h5
2 files changed, 48 insertions, 41 deletions
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 66b93de4820..d995ff7c7f6 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -27,22 +27,22 @@
#include "Metric.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 %u", _sourceUnit->GetGUID().GetCounter());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::PathGenerator for %u", _source->GetGUID().GetCounter());
- uint32 mapId = _sourceUnit->GetMapId();
+ uint32 mapId = _source->GetMapId();
if (DisableMgr::IsPathfindingEnabled(mapId))
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId);
- _navMeshQuery = mmap->GetNavMeshQuery(mapId, _sourceUnit->GetInstanceId());
+ _navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetInstanceId());
}
CreateFilter();
@@ -50,13 +50,13 @@ PathGenerator::PathGenerator(Unit const* owner) :
PathGenerator::~PathGenerator()
{
- TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::~PathGenerator() for %u", _sourceUnit->GetGUID().GetCounter());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::~PathGenerator() for %u", _source->GetGUID().GetCounter());
}
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;
@@ -72,11 +72,12 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
_forceDestination = forceDest;
_straightLine = straightLine;
- TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::CalculatePath() for %u", _sourceUnit->GetGUID().GetCounter());
+ TC_LOG_DEBUG("maps.mmaps", "++ PathGenerator::CalculatePath() for %u", _source->GetGUID().GetCounter());
// 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();
@@ -175,15 +176,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->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr, _sourceUnit->GetCollisionHeight());
+ ZLiquidStatus status = _source->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr, _source->GetCollisionHeight());
// One of the points is not in the water, cancel movement.
if (status == LIQUID_MAP_NO_WATER)
{
@@ -206,20 +207,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->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
+ if (_source->GetBaseMap()->IsUnderWater(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)
@@ -275,7 +280,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;
}
@@ -399,7 +404,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);
@@ -468,7 +473,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", "%u's Path Build failed: 0 length path", _sourceUnit->GetGUID().GetCounter());
+ TC_LOG_ERROR("maps.mmaps", "%u's Path Build failed: 0 length path", _source->GetGUID().GetCounter());
BuildShortcut();
_type = PATHFIND_NOPATH;
return;
@@ -603,7 +608,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()
@@ -629,9 +634,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
@@ -655,21 +660,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->GetBaseMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data, _sourceUnit->GetCollisionHeight());
+ ZLiquidStatus liquidStatus = _source->GetBaseMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data, _source->GetCollisionHeight());
if (liquidStatus == LIQUID_MAP_NO_WATER)
return NAV_GROUND;
@@ -855,7 +861,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);
@@ -959,7 +965,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
@@ -971,8 +977,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(x, y, z, _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight, _sourceUnit->GetPhaseMask(), 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(x, y, z, _pathPoints[i - 1].x, _pathPoints[i - 1].y, _pathPoints[i - 1].z + collisionHeight, _source->GetPhaseMask(), 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);
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index f3a53e41435..ce82da1f1c0 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -25,6 +25,7 @@
#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,7 +54,7 @@ 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
@@ -94,7 +95,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