mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-14 20:12:26 +00:00
Pathing stuck detection, and logic to go with it
This commit is contained in:
parent
0ba9b3fedc
commit
c52ff4249a
@ -5737,17 +5737,11 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
glm::vec3 Start(GetX(), GetY(), GetZ() + (GetSize() < 6.0 ? 6 : GetSize()) * HEAD_POSITION);
|
||||
glm::vec3 End(target->GetX(), target->GetY(), target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION);
|
||||
|
||||
auto pathlist = zone->pathing->FindRoute(Start, End);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
auto pathlist = zone->pathing->FindRoute(Start, End, partial, error);
|
||||
|
||||
if (pathlist.empty())
|
||||
{
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
//the client seems to have issues with packets larger than this
|
||||
if (pathlist.size() > 36)
|
||||
if (pathlist.empty() || error || partial)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
|
||||
@ -445,7 +445,7 @@ Mob::Mob(const char* in_name,
|
||||
AssistAggro = false;
|
||||
npc_assist_cap = 0;
|
||||
|
||||
PathRecalcTimer.reset(new Timer(2000));
|
||||
PathRecalcTimer.reset(new Timer(1500));
|
||||
PathingLoopCount = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
IPathfinder() { }
|
||||
virtual ~IPathfinder() { }
|
||||
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end) = 0;
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error) = 0;
|
||||
virtual glm::vec3 GetRandomLocation() = 0;
|
||||
virtual void DebugCommand(Client *c, const Seperator *sep) = 0;
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
const int MaxNavmeshNodes = 4092;
|
||||
|
||||
struct PathfinderNavmesh::Implementation
|
||||
{
|
||||
dtNavMesh *nav_mesh;
|
||||
@ -31,9 +33,13 @@ PathfinderNavmesh::~PathfinderNavmesh()
|
||||
Clear();
|
||||
}
|
||||
|
||||
IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end)
|
||||
IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error)
|
||||
{
|
||||
partial = false;
|
||||
error = false;
|
||||
|
||||
if (!m_impl->nav_mesh) {
|
||||
error = true;
|
||||
IPath Route;
|
||||
Route.push_back(end);
|
||||
return Route;
|
||||
@ -41,7 +47,7 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
|
||||
|
||||
if (!m_impl->query) {
|
||||
m_impl->query = dtAllocNavMeshQuery();
|
||||
m_impl->query->init(m_impl->nav_mesh, 32768);
|
||||
m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes);
|
||||
}
|
||||
|
||||
glm::vec3 current_location(start.x, start.z, start.y);
|
||||
@ -68,6 +74,7 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
|
||||
m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
|
||||
|
||||
if (!start_ref || !end_ref) {
|
||||
error = true;
|
||||
IPath Route;
|
||||
Route.push_back(end);
|
||||
return Route;
|
||||
@ -81,6 +88,7 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
|
||||
glm::vec3 epos = dest_location;
|
||||
if (path[npoly - 1] != end_ref) {
|
||||
m_impl->query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
|
||||
partial = true;
|
||||
}
|
||||
|
||||
float straight_path[2048 * 3];
|
||||
@ -93,7 +101,8 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl
|
||||
straight_path, straight_path_flags,
|
||||
straight_path_polys, &n_straight_polys, 2048, DT_STRAIGHTPATH_AREA_CROSSINGS);
|
||||
|
||||
if (status & DT_OUT_OF_NODES) {
|
||||
if (dtStatusFailed(status)) {
|
||||
error = true;
|
||||
IPath Route;
|
||||
Route.push_back(end);
|
||||
return Route;
|
||||
@ -135,7 +144,7 @@ glm::vec3 PathfinderNavmesh::GetRandomLocation()
|
||||
|
||||
if (!m_impl->query) {
|
||||
m_impl->query = dtAllocNavMeshQuery();
|
||||
m_impl->query->init(m_impl->nav_mesh, 32768);
|
||||
m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes);
|
||||
}
|
||||
|
||||
dtQueryFilter filter;
|
||||
@ -280,11 +289,14 @@ void PathfinderNavmesh::Load(const std::string &path)
|
||||
}
|
||||
}
|
||||
|
||||
void PathfinderNavmesh::ShowPath(Client * c, const glm::vec3 & start, const glm::vec3 & end)
|
||||
void PathfinderNavmesh::ShowPath(Client * c, const glm::vec3 &start, const glm::vec3 &end)
|
||||
{
|
||||
auto path = FindRoute(start, end);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
auto path = FindRoute(start, end, partial, error);
|
||||
std::vector<FindPerson_Point> points;
|
||||
|
||||
if (!partial && !error) {
|
||||
FindPerson_Point p;
|
||||
for (auto &node : path)
|
||||
{
|
||||
@ -296,6 +308,7 @@ void PathfinderNavmesh::ShowPath(Client * c, const glm::vec3 & start, const glm:
|
||||
points.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->SendPathPacket(points);
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ public:
|
||||
PathfinderNavmesh(const std::string &path);
|
||||
virtual ~PathfinderNavmesh();
|
||||
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end);
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error);
|
||||
virtual glm::vec3 GetRandomLocation();
|
||||
virtual void DebugCommand(Client *c, const Seperator *sep);
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#include "pathfinder_null.h"
|
||||
|
||||
IPathfinder::IPath PathfinderNull::FindRoute(const glm::vec3 &start, const glm::vec3 &end)
|
||||
IPathfinder::IPath PathfinderNull::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error)
|
||||
{
|
||||
error = false;
|
||||
partial = false;
|
||||
IPath ret;
|
||||
ret.push_back(start);
|
||||
ret.push_back(end);
|
||||
|
||||
@ -8,7 +8,7 @@ public:
|
||||
PathfinderNull() { }
|
||||
virtual ~PathfinderNull() { }
|
||||
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end);
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error);
|
||||
virtual glm::vec3 GetRandomLocation();
|
||||
virtual void DebugCommand(Client *c, const Seperator *sep) { }
|
||||
};
|
||||
@ -114,17 +114,21 @@ PathfinderWaypoint::~PathfinderWaypoint()
|
||||
{
|
||||
}
|
||||
|
||||
IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const glm::vec3 &end)
|
||||
IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error)
|
||||
{
|
||||
partial = false;
|
||||
error = false;
|
||||
std::vector<RTreeValue> result_start_n;
|
||||
m_impl->Tree.query(boost::geometry::index::nearest(Point(start.x, start.y, start.z), 1), std::back_inserter(result_start_n));
|
||||
if (result_start_n.size() == 0) {
|
||||
error = true;
|
||||
return IPath();
|
||||
}
|
||||
|
||||
std::vector<RTreeValue> result_end_n;
|
||||
m_impl->Tree.query(boost::geometry::index::nearest(Point(end.x, end.y, end.z), 1), std::back_inserter(result_end_n));
|
||||
if (result_end_n.size() == 0) {
|
||||
error = true;
|
||||
return IPath();
|
||||
}
|
||||
|
||||
@ -179,6 +183,7 @@ IPathfinder::IPath PathfinderWaypoint::FindRoute(const glm::vec3 &start, const g
|
||||
return Route;
|
||||
}
|
||||
|
||||
error = true;
|
||||
IPath Route;
|
||||
Route.push_front(start);
|
||||
Route.push_back(glm::vec3(nearest_start.first.get<0>(), nearest_start.first.get<1>(), nearest_start.first.get<2>()));
|
||||
@ -395,7 +400,9 @@ void PathfinderWaypoint::ShowNodes()
|
||||
|
||||
void PathfinderWaypoint::ShowPath(Client *c, const glm::vec3 &start, const glm::vec3 &end)
|
||||
{
|
||||
auto path = FindRoute(start, end);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
auto path = FindRoute(start, end, partial, error);
|
||||
std::vector<FindPerson_Point> points;
|
||||
|
||||
FindPerson_Point p;
|
||||
|
||||
@ -11,7 +11,7 @@ public:
|
||||
PathfinderWaypoint(const std::string &path);
|
||||
virtual ~PathfinderWaypoint();
|
||||
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end);
|
||||
virtual IPath FindRoute(const glm::vec3 &start, const glm::vec3 &end, bool &partial, bool &error);
|
||||
virtual glm::vec3 GetRandomLocation();
|
||||
virtual void DebugCommand(Client *c, const Seperator *sep);
|
||||
|
||||
|
||||
@ -39,14 +39,22 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
}
|
||||
|
||||
if (Route.empty()) {
|
||||
Route = zone->pathing->FindRoute(From, To);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
Route = zone->pathing->FindRoute(From, To, partial, error);
|
||||
AdjustRoute(Route, flymode, GetModelOffset());
|
||||
|
||||
PathingDestination = To;
|
||||
WaypointChanged = true;
|
||||
NodeReached = false;
|
||||
if (Route.empty()) {
|
||||
return From;
|
||||
if (partial && Route.size() <= 2) {
|
||||
//We are stuck
|
||||
Route.clear();
|
||||
Teleport(To);
|
||||
return To;
|
||||
}
|
||||
else if (error || Route.empty()) {
|
||||
return To;
|
||||
}
|
||||
else {
|
||||
return (*Route.begin()).pos;
|
||||
@ -57,15 +65,21 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
bool SameDestination = DistanceSquared(To, PathingDestination) < 100.0f;
|
||||
if (!SameDestination) {
|
||||
//We had a route but our target position moved too much
|
||||
Route = zone->pathing->FindRoute(From, To);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
Route = zone->pathing->FindRoute(From, To, partial, error);
|
||||
AdjustRoute(Route, flymode, GetModelOffset());
|
||||
|
||||
PathingDestination = To;
|
||||
WaypointChanged = true;
|
||||
NodeReached = false;
|
||||
|
||||
if (Route.empty()) {
|
||||
return From;
|
||||
if (partial && Route.size() <= 2) {
|
||||
Route.clear();
|
||||
Teleport(To);
|
||||
return To;
|
||||
} else if (error || Route.empty()) {
|
||||
return To;
|
||||
}
|
||||
else {
|
||||
return (*Route.begin()).pos;
|
||||
@ -118,13 +132,21 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
Route.pop_front();
|
||||
|
||||
if (Route.empty()) {
|
||||
Route = zone->pathing->FindRoute(From, To);
|
||||
bool partial = false;
|
||||
bool error = false;
|
||||
Route = zone->pathing->FindRoute(From, To, partial, error);
|
||||
AdjustRoute(Route, flymode, GetModelOffset());
|
||||
PathingDestination = To;
|
||||
WaypointChanged = true;
|
||||
|
||||
if (Route.empty()) {
|
||||
return From;
|
||||
if (partial && Route.size() <= 2) {
|
||||
//We are stuck
|
||||
Route.clear();
|
||||
Teleport(To);
|
||||
return To;
|
||||
}
|
||||
else if (error || Route.empty()) {
|
||||
return To;
|
||||
}
|
||||
else {
|
||||
return (*Route.begin()).pos;
|
||||
@ -161,6 +183,8 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa
|
||||
return (*Route.begin()).pos;
|
||||
}
|
||||
}
|
||||
|
||||
return To;
|
||||
}
|
||||
|
||||
void CullPoints(std::vector<FindPerson_Point> &points) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user