mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-21 20:56:23 +00:00
fix(Core/CreatureAI): revert NPC repositioning and path system (temporarily) (#4274)
This commit is contained in:
@@ -60,13 +60,12 @@ bool FleeingMovementGenerator<T>::_getPoint(T* owner, float& x, float& y, float&
|
||||
if (!owner)
|
||||
return false;
|
||||
|
||||
const Map* _map = owner->GetBaseMap();
|
||||
|
||||
x = owner->GetPositionX();
|
||||
y = owner->GetPositionY();
|
||||
z = owner->GetPositionZ();
|
||||
|
||||
float temp_x, temp_y, angle;
|
||||
const Map* _map = owner->GetBaseMap();
|
||||
// primitive path-finding
|
||||
for (uint8 i = 0; i < 18; ++i)
|
||||
{
|
||||
@@ -152,20 +151,37 @@ bool FleeingMovementGenerator<T>::_getPoint(T* owner, float& x, float& y, float&
|
||||
|
||||
temp_x = x + distance * cos(angle);
|
||||
temp_y = y + distance * sin(angle);
|
||||
float temp_z = z;
|
||||
|
||||
if (_map->CanReachPositionAndGetCoords(owner, temp_x, temp_y, temp_z, true, 3.0f, M_PI/4))
|
||||
acore::NormalizeMapCoord(temp_x);
|
||||
acore::NormalizeMapCoord(temp_y);
|
||||
if (owner->IsWithinLOS(temp_x, temp_y, z))
|
||||
{
|
||||
if (!(temp_z - z) || distance / fabs(temp_z - z) > 1.0f)
|
||||
bool is_water_now = _map->IsInWater(x, y, z);
|
||||
|
||||
if (is_water_now && _map->IsInWater(temp_x, temp_y, z))
|
||||
{
|
||||
float temp_z_left = _map->GetHeight(owner->GetPhaseMask(), temp_x + 1.0f * cos(angle + static_cast<float>(M_PI / 2)), temp_y + 1.0f * sin(angle + static_cast<float>(M_PI / 2)), z, true);
|
||||
float temp_z_right = _map->GetHeight(owner->GetPhaseMask(), temp_x + 1.0f * cos(angle - static_cast<float>(M_PI / 2)), temp_y + 1.0f * sin(angle - static_cast<float>(M_PI / 2)), z, true);
|
||||
if (fabs(temp_z_left - temp_z) < 1.2f && fabs(temp_z_right - temp_z) < 1.2f)
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
return true;
|
||||
}
|
||||
float new_z = _map->GetHeight(owner->GetPhaseMask(), temp_x, temp_y, z, true);
|
||||
|
||||
if (new_z <= INVALID_HEIGHT || fabs(z - new_z) > 3.0f)
|
||||
continue;
|
||||
|
||||
bool is_water_next = _map->IsInWater(temp_x, temp_y, new_z);
|
||||
|
||||
if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
|
||||
continue;
|
||||
|
||||
if (!(new_z - z) || distance / fabs(new_z - z) > 1.0f)
|
||||
{
|
||||
float new_z_left = _map->GetHeight(owner->GetPhaseMask(), temp_x + 1.0f * cos(angle + static_cast<float>(M_PI / 2)), temp_y + 1.0f * sin(angle + static_cast<float>(M_PI / 2)), z, true);
|
||||
float new_z_right = _map->GetHeight(owner->GetPhaseMask(), temp_x + 1.0f * cos(angle - static_cast<float>(M_PI / 2)), temp_y + 1.0f * sin(angle - static_cast<float>(M_PI / 2)), z, true);
|
||||
if (fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
|
||||
{
|
||||
// use new values
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
z = temp_z;
|
||||
z = new_z;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _PATH_GENERATOR_H
|
||||
@@ -11,152 +22,139 @@
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "MoveSplineInitArgs.h"
|
||||
#include <G3D/Vector3.h>
|
||||
#include "MMapFactory.h"
|
||||
#include "MMapManager.h"
|
||||
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
|
||||
// 74*4.0f=296y number_of_points*interval = max_path_len
|
||||
// 74*4.0f=296y number_of_points*interval = max_path_len
|
||||
// this is way more than actual evade range
|
||||
// I think we can safely cut those down even more
|
||||
#define MAX_PATH_LENGTH 74
|
||||
#define MAX_POINT_PATH_LENGTH 74
|
||||
#define MAX_PATH_LENGTH 74
|
||||
#define MAX_POINT_PATH_LENGTH 74
|
||||
|
||||
#define SMOOTH_PATH_STEP_SIZE 4.0f
|
||||
#define SMOOTH_PATH_SLOP 0.3f
|
||||
#define SMOOTH_PATH_STEP_SIZE 4.0f
|
||||
#define SMOOTH_PATH_SLOP 0.3f
|
||||
#define ALLOWED_DIST_FROM_POLY 2.5f
|
||||
#define ADDED_Z_FOR_POLY_LOOKUP 0.3f
|
||||
#define DISALLOW_TIME_AFTER_FAIL 3 // secs
|
||||
#define MAX_FIXABLE_Z_ERROR 7.0f
|
||||
|
||||
#define VERTEX_SIZE 3
|
||||
#define INVALID_POLYREF 0
|
||||
|
||||
enum PathType
|
||||
{
|
||||
PATHFIND_BLANK = 0x00, // path not built yet
|
||||
PATHFIND_NORMAL = 0x01, // normal path
|
||||
PATHFIND_SHORTCUT = 0x02, // travel through obstacles, terrain, air, etc (old behavior)
|
||||
PATHFIND_INCOMPLETE = 0x04, // we have partial path to follow - getting closer to target
|
||||
PATHFIND_NOPATH = 0x08, // no valid path at all or error in generating one
|
||||
PATHFIND_NOT_USING_PATH = 0x10, // used when we are either flying/swiming or on map w/o mmaps
|
||||
PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length
|
||||
PATHFIND_FARFROMPOLY_START = 0x40, // start position is far from the mmap poligon
|
||||
PATHFIND_FARFROMPOLY_END = 0x80, // end positions is far from the mmap poligon
|
||||
PATHFIND_FARFROMPOLY = PATHFIND_FARFROMPOLY_START | PATHFIND_FARFROMPOLY_END, // start or end positions are far from the mmap poligon
|
||||
PATHFIND_BLANK = 0x00, // path not built yet
|
||||
PATHFIND_NORMAL = 0x01, // normal path
|
||||
PATHFIND_SHORTCUT = 0x02, // travel through obstacles, terrain, air, etc (old behavior)
|
||||
PATHFIND_INCOMPLETE = 0x04, // we have partial path to follow - getting closer to target
|
||||
PATHFIND_NOPATH = 0x08, // no valid path at all or error in generating one
|
||||
PATHFIND_NOT_USING_PATH = 0x10, // used when we are either flying/swiming or on map w/o mmaps
|
||||
PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length
|
||||
};
|
||||
|
||||
class PathGenerator
|
||||
{
|
||||
public:
|
||||
explicit PathGenerator(WorldObject const* owner);
|
||||
~PathGenerator();
|
||||
public:
|
||||
explicit PathGenerator(Unit 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 IsInvalidDestinationZ(Unit const* target) const;
|
||||
// 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);
|
||||
|
||||
// option setters - use optional
|
||||
void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
|
||||
void SetPathLengthLimit(float distance) { _pointPathLimit = std::min<uint32>(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }
|
||||
void SetUseRaycast(bool useRaycast) { _useRaycast = useRaycast; }
|
||||
// option setters - use optional
|
||||
void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
|
||||
void SetPathLengthLimit(float distance) { _pointPathLimit = std::min<uint32>(uint32(distance / SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }
|
||||
|
||||
// result getters
|
||||
G3D::Vector3 const& GetStartPosition() const { return _startPosition; }
|
||||
G3D::Vector3 const& GetEndPosition() const { return _endPosition; }
|
||||
G3D::Vector3 const& GetActualEndPosition() const { return _actualEndPosition; }
|
||||
// result getters
|
||||
G3D::Vector3 const& GetStartPosition() const { return _startPosition; }
|
||||
G3D::Vector3 const& GetEndPosition() const { return _endPosition; }
|
||||
G3D::Vector3 const& GetActualEndPosition() const { return _actualEndPosition; }
|
||||
|
||||
Movement::PointsArray const& GetPath() const { return _pathPoints; }
|
||||
Movement::PointsArray const& GetPath() const { return _pathPoints; }
|
||||
|
||||
PathType GetPathType() const { return _type; }
|
||||
|
||||
// shortens the path until the destination is the specified distance from the target point
|
||||
void ShortenPathUntilDist(G3D::Vector3 const& point, float dist);
|
||||
|
||||
float getPathLength() const
|
||||
PathType GetPathType() const { return _type; }
|
||||
float getPathLength() const
|
||||
{
|
||||
float len = 0.0f;
|
||||
float dx, dy, dz;
|
||||
uint32 size = _pathPoints.size();
|
||||
if (size)
|
||||
{
|
||||
float len = 0.0f;
|
||||
float dx, dy, dz;
|
||||
uint32 size = _pathPoints.size();
|
||||
if (size)
|
||||
{
|
||||
dx = _pathPoints[0].x - _startPosition.x;
|
||||
dy = _pathPoints[0].y - _startPosition.y;
|
||||
dz = _pathPoints[0].z - _startPosition.z;
|
||||
len += sqrt( dx * dx + dy * dy + dz * dz );
|
||||
}
|
||||
else
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
for (uint32 i = 1; i < size; ++i)
|
||||
{
|
||||
dx = _pathPoints[i].x - _pathPoints[i - 1].x;
|
||||
dy = _pathPoints[i].y - _pathPoints[i - 1].y;
|
||||
dz = _pathPoints[i].z - _pathPoints[i - 1].z;
|
||||
len += sqrt( dx * dx + dy * dy + dz * dz );
|
||||
}
|
||||
dx = _pathPoints[0].x - _startPosition.x;
|
||||
dy = _pathPoints[0].y - _startPosition.y;
|
||||
dz = _pathPoints[0].z - _startPosition.z;
|
||||
len += sqrt( dx * dx + dy * dy + dz * dz );
|
||||
}
|
||||
else
|
||||
return len;
|
||||
}
|
||||
|
||||
private:
|
||||
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references
|
||||
uint32 _polyLength; // number of polygons in the path
|
||||
|
||||
Movement::PointsArray _pathPoints; // our actual (x,y,z) path to the target
|
||||
PathType _type; // tells what kind of path this is
|
||||
|
||||
bool _useStraightPath; // type of path will be generated
|
||||
bool _forceDestination; // when set, we will always arrive at given point
|
||||
uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH)
|
||||
bool _useRaycast; // use raycast if true for a straight line path
|
||||
|
||||
G3D::Vector3 _startPosition; // {x, y, z} of current location
|
||||
G3D::Vector3 _endPosition; // {x, y, z} of the destination
|
||||
G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination
|
||||
|
||||
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
|
||||
|
||||
dtQueryFilter _filter; // use single filter for all movements, update it when needed
|
||||
|
||||
void SetStartPosition(G3D::Vector3 const& point) { _startPosition = point; }
|
||||
void SetEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; _endPosition = point; }
|
||||
void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; }
|
||||
void NormalizePath();
|
||||
|
||||
void Clear()
|
||||
for (uint32 i = 1; i < size; ++i)
|
||||
{
|
||||
_polyLength = 0;
|
||||
_pathPoints.clear();
|
||||
dx = _pathPoints[i].x - _pathPoints[i - 1].x;
|
||||
dy = _pathPoints[i].y - _pathPoints[i - 1].y;
|
||||
dz = _pathPoints[i].z - _pathPoints[i - 1].z;
|
||||
len += sqrt( dx * dx + dy * dy + dz * dz );
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const;
|
||||
float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const;
|
||||
bool InRangeYZX(float const* v1, float const* v2, float r, float h) const;
|
||||
private:
|
||||
|
||||
dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = nullptr) const;
|
||||
dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const;
|
||||
bool HaveTile(G3D::Vector3 const& p) const;
|
||||
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references
|
||||
uint32 _polyLength; // number of polygons in the path
|
||||
|
||||
void BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos);
|
||||
void BuildPointPath(float const* startPoint, float const* endPoint);
|
||||
void BuildShortcut();
|
||||
Movement::PointsArray _pathPoints; // our actual (x,y,z) path to the target
|
||||
PathType _type; // tells what kind of path this is
|
||||
|
||||
NavTerrain GetNavTerrain(float x, float y, float z);
|
||||
void CreateFilter();
|
||||
void UpdateFilter();
|
||||
bool _useStraightPath; // type of path will be generated
|
||||
bool _forceDestination; // when set, we will always arrive at given point
|
||||
uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH)
|
||||
|
||||
// smooth path aux functions
|
||||
uint32 FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited);
|
||||
bool GetSteerTarget(float const* startPos, float const* endPos, float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos,
|
||||
unsigned char& steerPosFlag, dtPolyRef& steerPosRef);
|
||||
dtStatus FindSmoothPath(float const* startPos, float const* endPos,
|
||||
dtPolyRef const* polyPath, uint32 polyPathSize,
|
||||
float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize);
|
||||
G3D::Vector3 _startPosition; // {x, y, z} of current location
|
||||
G3D::Vector3 _endPosition; // {x, y, z} of the destination
|
||||
G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination
|
||||
|
||||
void AddFarFromPolyFlags(bool startFarFromPoly, bool endFarFromPoly);
|
||||
Unit const* const _sourceUnit; // the unit that is moving
|
||||
dtNavMesh const* _navMesh; // the nav mesh
|
||||
dtNavMeshQuery const* _navMeshQuery; // the nav mesh query used to find the path
|
||||
|
||||
dtQueryFilter _filter; // use single filter for all movements, update it when needed
|
||||
|
||||
void SetStartPosition(G3D::Vector3 const& point) { _startPosition = point; }
|
||||
void SetEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; _endPosition = point; }
|
||||
void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
_polyLength = 0;
|
||||
_pathPoints.clear();
|
||||
}
|
||||
|
||||
bool InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const;
|
||||
float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const;
|
||||
bool InRangeYZX(float const* v1, float const* v2, float r, float h) const;
|
||||
|
||||
dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = nullptr) const;
|
||||
dtPolyRef GetPolyByLocation(float* Point, float* Distance) const;
|
||||
bool HaveTile(G3D::Vector3 const& p) const;
|
||||
|
||||
void BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, ACE_RW_Thread_Mutex& lock);
|
||||
void BuildPointPath(float const* startPoint, float const* endPoint);
|
||||
void BuildShortcut();
|
||||
|
||||
NavTerrain GetNavTerrain(float x, float y, float z);
|
||||
void CreateFilter();
|
||||
void UpdateFilter();
|
||||
|
||||
// smooth path aux functions
|
||||
uint32 FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited);
|
||||
bool GetSteerTarget(float const* startPos, float const* endPos, float minTargetDist, dtPolyRef const* path, uint32 pathSize, float* steerPos,
|
||||
unsigned char& steerPosFlag, dtPolyRef& steerPosRef);
|
||||
dtStatus FindSmoothPath(float const* startPos, float const* endPos,
|
||||
dtPolyRef const* polyPath, uint32 polyPathSize,
|
||||
float* smoothPath, int* smoothPathSize, uint32 smoothPathMaxSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user