mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-29 18:11:28 +00:00
Pathing is essentially fully functional now, still could use improvements here and there
This commit is contained in:
parent
e61e2e7f02
commit
1cb07d055e
@ -63,7 +63,7 @@ public:
|
||||
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
|
||||
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
|
||||
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
|
||||
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
|
||||
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += (uint32)n; }
|
||||
|
||||
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
|
||||
uint8 ReadUInt8(uint32 Offset) const { uint8 value = *(uint8 *)(pBuffer + Offset); return value; }
|
||||
|
||||
@ -1,13 +1,34 @@
|
||||
#include "pathfind.h"
|
||||
#include "random.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <DetourNavMeshQuery.h>
|
||||
|
||||
const uint32_t nav_mesh_file_version = 1;
|
||||
const float max_dest_drift = 10.0f;
|
||||
const float at_waypoint_eps = 1.0f;
|
||||
EQEmu::Random path_rng;
|
||||
|
||||
float vec_dist(const glm::vec3 &a, const glm::vec3 &b) {
|
||||
float dist_x = a.x - b.x;
|
||||
float dist_y = a.y - b.y;
|
||||
float dist_z = a.z - b.z;
|
||||
return sqrt((dist_x * dist_x) + (dist_y * dist_y) + (dist_z * dist_z));
|
||||
}
|
||||
|
||||
PathfindingManager::PathfindingManager()
|
||||
{
|
||||
m_nav_mesh = nullptr;
|
||||
m_nav_query = nullptr;
|
||||
m_filter.setIncludeFlags(NavigationPolyFlagAll);
|
||||
m_filter.setAreaCost(NavigationAreaFlagNormal, 1.0f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagWater, 2.5f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagLava, 2.5f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagPvP, 1.0f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagSlime, 1.0f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagIce, 1.0f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagVWater, 2.5f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagGeneralArea, 1.0f);
|
||||
m_filter.setAreaCost(NavigationAreaFlagPortal, 1.0f);
|
||||
}
|
||||
|
||||
PathfindingManager::~PathfindingManager()
|
||||
@ -17,6 +38,8 @@ PathfindingManager::~PathfindingManager()
|
||||
|
||||
void PathfindingManager::Load(const std::string &zone_name)
|
||||
{
|
||||
Clear();
|
||||
|
||||
std::string filename = MAP_DIR + std::string("/") + zone_name + ".nav";
|
||||
FILE *f = fopen(filename.c_str(), "rb");
|
||||
if (f) {
|
||||
@ -109,6 +132,11 @@ void PathfindingManager::Clear()
|
||||
dtFreeNavMesh(m_nav_mesh);
|
||||
m_nav_mesh = nullptr;
|
||||
}
|
||||
|
||||
if (m_nav_query) {
|
||||
dtFreeNavMeshQuery(m_nav_query);
|
||||
m_nav_query = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const glm::vec3 &dest_loc)
|
||||
@ -117,8 +145,10 @@ PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const g
|
||||
glm::vec3 dest_location(dest_loc.x, dest_loc.z, dest_loc.y);
|
||||
|
||||
PathfindingRoute ret;
|
||||
ret.m_dest = dest_location;
|
||||
|
||||
ret.m_dest = dest_loc;
|
||||
ret.m_current_node = 0;
|
||||
ret.m_active = true;
|
||||
|
||||
if (!m_nav_mesh) {
|
||||
PathfindingNode src;
|
||||
@ -134,30 +164,19 @@ PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const g
|
||||
return ret;
|
||||
}
|
||||
|
||||
glm::vec3 ext(5.0f, 5.0f, 5.0f);
|
||||
dtQueryFilter filter;
|
||||
filter.setIncludeFlags(NavigationPolyFlagAll);
|
||||
filter.setAreaCost(NavigationAreaFlagNormal, 1.0f);
|
||||
filter.setAreaCost(NavigationAreaFlagWater, 2.5f);
|
||||
filter.setAreaCost(NavigationAreaFlagLava, 2.5f);
|
||||
filter.setAreaCost(NavigationAreaFlagPvP, 1.0f);
|
||||
filter.setAreaCost(NavigationAreaFlagSlime, 1.0f);
|
||||
filter.setAreaCost(NavigationAreaFlagIce, 1.0f);
|
||||
filter.setAreaCost(NavigationAreaFlagVWater, 2.5f);
|
||||
filter.setAreaCost(NavigationAreaFlagGeneralArea, 1.0f);
|
||||
filter.setAreaCost(NavigationAreaFlagPortal, 1.0f);
|
||||
if (!m_nav_query) {
|
||||
m_nav_query = dtAllocNavMeshQuery();
|
||||
m_nav_query->init(m_nav_mesh, 4092);
|
||||
}
|
||||
|
||||
dtNavMeshQuery *query = dtAllocNavMeshQuery();
|
||||
query->init(m_nav_mesh, 4092);
|
||||
dtPolyRef start_ref;
|
||||
dtPolyRef end_ref;
|
||||
glm::vec3 ext(10.0f, 10.0f, 10.0f);
|
||||
|
||||
query->findNearestPoly(¤t_location[0], &ext[0], &filter, &start_ref, 0);
|
||||
query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
|
||||
m_nav_query->findNearestPoly(¤t_location[0], &ext[0], &m_filter, &start_ref, 0);
|
||||
m_nav_query->findNearestPoly(&dest_location[0], &ext[0], &m_filter, &end_ref, 0);
|
||||
|
||||
if (!start_ref || !end_ref) {
|
||||
dtFreeNavMeshQuery(query);
|
||||
|
||||
PathfindingNode src;
|
||||
src.flag = NavigationPolyFlagNormal;
|
||||
src.position = current_location;
|
||||
@ -173,23 +192,21 @@ PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const g
|
||||
|
||||
int npoly = 0;
|
||||
dtPolyRef path[256] = { 0 };
|
||||
query->findPath(start_ref, end_ref, ¤t_location[0], &dest_location[0], &filter, path, &npoly, 256);
|
||||
m_nav_query->findPath(start_ref, end_ref, ¤t_location[0], &dest_location[0], &m_filter, path, &npoly, 256);
|
||||
|
||||
if (npoly) {
|
||||
glm::vec3 epos = dest_location;
|
||||
if (path[npoly - 1] != end_ref)
|
||||
query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
|
||||
m_nav_query->closestPointOnPoly(path[npoly - 1], &dest_location[0], &epos[0], 0);
|
||||
|
||||
float straight_path[256 * 3];
|
||||
unsigned char straight_path_flags[256];
|
||||
int n_straight_polys;
|
||||
dtPolyRef straight_path_polys[256];
|
||||
query->findStraightPath(¤t_location[0], &epos[0], path, npoly,
|
||||
m_nav_query->findStraightPath(¤t_location[0], &epos[0], path, npoly,
|
||||
straight_path, straight_path_flags,
|
||||
straight_path_polys, &n_straight_polys, 256, DT_STRAIGHTPATH_ALL_CROSSINGS);
|
||||
|
||||
dtFreeNavMeshQuery(query);
|
||||
|
||||
if (n_straight_polys) {
|
||||
ret.m_nodes.reserve(n_straight_polys);
|
||||
for (int i = 0; i < n_straight_polys; ++i)
|
||||
@ -222,17 +239,52 @@ PathfindingRoute PathfindingManager::FindRoute(const glm::vec3 &src_loc, const g
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PathfindingManager::GetRandomPoint(const glm::vec3 &start, float radius, glm::vec3 &pos)
|
||||
{
|
||||
if(!m_nav_mesh)
|
||||
return false;
|
||||
|
||||
if (!m_nav_query) {
|
||||
m_nav_query = dtAllocNavMeshQuery();
|
||||
m_nav_query->init(m_nav_mesh, 4092);
|
||||
}
|
||||
|
||||
glm::vec3 ext(10.0f, 10.0f, 10.0f);
|
||||
dtPolyRef start_ref;
|
||||
m_nav_query->findNearestPoly(&start[0], &ext[0], &m_filter, &start_ref, 0);
|
||||
if (!start_ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dtPolyRef random_ref;
|
||||
glm::vec3 pt;
|
||||
|
||||
dtStatus status = m_nav_query->findRandomPointAroundCircle(start_ref, &start[0], radius,
|
||||
&m_filter, []() -> float { return (float)path_rng.Real(0.0, 1.0); }, &random_ref, &pt[0]);
|
||||
|
||||
if (dtStatusSucceed(status))
|
||||
{
|
||||
pos.x = pt.x;
|
||||
pos.z = pt.y;
|
||||
pos.y = pt.z;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PathfindingRoute::PathfindingRoute()
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
PathfindingRoute::~PathfindingRoute()
|
||||
{
|
||||
}
|
||||
|
||||
bool PathfindingRoute::Valid(const glm::vec3 &dest)
|
||||
bool PathfindingRoute::DestinationValid(const glm::vec3 &dest)
|
||||
{
|
||||
auto dist = (dest - m_dest).length();
|
||||
auto dist = vec_dist(dest, m_dest);
|
||||
if (dist <= max_dest_drift) {
|
||||
return true;
|
||||
}
|
||||
@ -240,11 +292,29 @@ bool PathfindingRoute::Valid(const glm::vec3 &dest)
|
||||
return false;
|
||||
}
|
||||
|
||||
void PathfindingRoute::CalcCurrentNode()
|
||||
void PathfindingRoute::CalcCurrentNode(const glm::vec3 ¤t_pos, bool &wp_changed)
|
||||
{
|
||||
//if we're at last node then we dont need to do anything.
|
||||
wp_changed = false;
|
||||
if (m_active) {
|
||||
//if we're at last node then we dont need to do anything.
|
||||
if (m_nodes.size() - 1 == m_current_node) {
|
||||
return;
|
||||
}
|
||||
|
||||
//else need to see if we're at current_node
|
||||
//if so then we advance to the next node and return it
|
||||
//else just return the current node
|
||||
auto ¤t = GetCurrentNode();
|
||||
auto dist = vec_dist(current.position, current_pos);
|
||||
if (dist < at_waypoint_eps) {
|
||||
m_current_node++;
|
||||
wp_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short PathfindingRoute::GetPreviousNodeFlag()
|
||||
{
|
||||
if(m_current_node == 0)
|
||||
return 0;
|
||||
|
||||
return m_nodes[m_current_node - 1].flag;
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <DetourNavMesh.h>
|
||||
#include <DetourNavMeshQuery.h>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
enum NavigationAreaFlags
|
||||
@ -48,15 +49,18 @@ public:
|
||||
PathfindingRoute();
|
||||
~PathfindingRoute();
|
||||
|
||||
bool Valid(const glm::vec3 &dest);
|
||||
void CalcCurrentNode();
|
||||
bool Active() const { return m_active; }
|
||||
bool PathfindingRoute::DestinationValid(const glm::vec3 &dest);
|
||||
void CalcCurrentNode(const glm::vec3 ¤t_pos, bool &wp_changed);
|
||||
const PathfindingNode& GetCurrentNode() { return m_nodes[m_current_node]; }
|
||||
unsigned short GetPreviousNodeFlag();
|
||||
const std::vector<PathfindingNode>& GetNodes() const { return m_nodes; }
|
||||
std::vector<PathfindingNode>& GetNodesEdit() { return m_nodes; }
|
||||
private:
|
||||
glm::vec3 m_dest;
|
||||
std::vector<PathfindingNode> m_nodes;
|
||||
int m_current_node;
|
||||
bool m_active;
|
||||
|
||||
friend class PathfindingManager;
|
||||
};
|
||||
@ -72,6 +76,9 @@ public:
|
||||
|
||||
//Expects locations in EQEmu internal format eg what #loc returns not what /loc returns.
|
||||
PathfindingRoute FindRoute(const glm::vec3 ¤t_location, const glm::vec3 &dest_location);
|
||||
bool GetRandomPoint(const glm::vec3 &start, float radius, glm::vec3 &pos);
|
||||
private:
|
||||
dtNavMesh *m_nav_mesh;
|
||||
dtNavMeshQuery *m_nav_query;
|
||||
dtQueryFilter m_filter;
|
||||
};
|
||||
|
||||
@ -183,7 +183,6 @@ SET(zone_headers
|
||||
npc_ai.h
|
||||
object.h
|
||||
oriented_bounding_box.h
|
||||
pathing.h
|
||||
perlpacket.h
|
||||
petitions.h
|
||||
pets.h
|
||||
|
||||
@ -1256,7 +1256,7 @@ public:
|
||||
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
|
||||
|
||||
void SetNextInvSnapshot(uint32 interval_in_min) {
|
||||
m_epp.last_invsnapshot_time = time(nullptr);
|
||||
m_epp.last_invsnapshot_time = (uint32)time(nullptr);
|
||||
m_epp.next_invsnapshot_time = m_epp.last_invsnapshot_time + (interval_in_min * 60);
|
||||
}
|
||||
uint32 GetLastInvSnapshotTime() { return m_epp.last_invsnapshot_time; }
|
||||
|
||||
@ -5630,7 +5630,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
glm::vec3 dest(target->GetX(), target->GetY(), target->GetZ());
|
||||
auto route = zone->pathing_new.FindRoute(glm::vec3(GetX(), GetY(), GetZ()), dest);
|
||||
auto route = zone->pathing.FindRoute(glm::vec3(GetX(), GetY(), GetZ()), dest);
|
||||
CreatePathFromRoute(dest, route);
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,8 +236,8 @@ bool Client::Process() {
|
||||
CheckMercSuspendTimer();
|
||||
}
|
||||
|
||||
//if(IsAIControlled())
|
||||
//AI_Process();
|
||||
if(IsAIControlled())
|
||||
AI_Process();
|
||||
|
||||
// Don't reset the bindwound timer so we can check it in BindWound as well.
|
||||
if (bindwound_timer.Check(false) && bindwound_target != 0) {
|
||||
|
||||
@ -58,7 +58,6 @@
|
||||
#include "command.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "map.h"
|
||||
#include "pathing.h"
|
||||
#include "qglobals.h"
|
||||
#include "queryserv.h"
|
||||
#include "quest_parser_collection.h"
|
||||
|
||||
@ -1930,52 +1930,6 @@ XS(XS__repopzone)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__ConnectNodeToNode);
|
||||
XS(XS__ConnectNodeToNode)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 4)
|
||||
Perl_croak(aTHX_ "Usage: ConnectNodeToNode(node1, node2, teleport, doorid)");
|
||||
|
||||
int node1 = (int)SvIV(ST(0));
|
||||
int node2 = (int)SvIV(ST(1));
|
||||
int teleport = (int)SvIV(ST(2));
|
||||
int doorid = (int)SvIV(ST(3));
|
||||
|
||||
quest_manager.ConnectNodeToNode(node1, node2, teleport, doorid);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__AddNode);
|
||||
XS(XS__AddNode)
|
||||
{
|
||||
dXSARGS;
|
||||
//void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id);
|
||||
if (items < 3 || items > 5)
|
||||
Perl_croak(aTHX_ "Usage: AddNode(x, y, z, [best_z], [requested_id])");
|
||||
|
||||
int x = (int)SvIV(ST(0));
|
||||
int y = (int)SvIV(ST(1));
|
||||
int z = (int)SvIV(ST(2));
|
||||
int best_z = 0;
|
||||
int requested_id = 0;
|
||||
|
||||
if (items == 4)
|
||||
{
|
||||
best_z = (int)SvIV(ST(3));
|
||||
}
|
||||
else if (items == 5)
|
||||
{
|
||||
best_z = (int)SvIV(ST(3));
|
||||
requested_id = (int)SvIV(ST(4));
|
||||
}
|
||||
|
||||
quest_manager.AddNode(x, y, z, best_z, requested_id);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__npcrace);
|
||||
XS(XS__npcrace)
|
||||
{
|
||||
@ -3818,8 +3772,6 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file);
|
||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||
newXS(strcpy(buf, "ConnectNodeToNode"), XS__ConnectNodeToNode, file);
|
||||
newXS(strcpy(buf, "AddNode"), XS__AddNode, file);
|
||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||
newXS(strcpy(buf, "respawn"), XS__respawn, file);
|
||||
newXS(strcpy(buf, "resume"), XS__resume, file);
|
||||
|
||||
@ -2691,26 +2691,6 @@ void EntityList::ListPlayerCorpses(Client *client)
|
||||
client->Message(0, "%d player corpses listed.", x);
|
||||
}
|
||||
|
||||
void EntityList::FindPathsToAllNPCs()
|
||||
{
|
||||
if (!zone->pathing)
|
||||
return;
|
||||
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
glm::vec3 Node0 = zone->pathing->GetPathNodeCoordinates(0, false);
|
||||
glm::vec3 Dest(it->second->GetX(), it->second->GetY(), it->second->GetZ());
|
||||
std::deque<int> Route = zone->pathing->FindRoute(Node0, Dest);
|
||||
if (Route.size() == 0)
|
||||
printf("Unable to find a route to %s\n", it->second->GetName());
|
||||
else
|
||||
printf("Found a route to %s\n", it->second->GetName());
|
||||
++it;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// returns the number of corpses deleted. A negative number indicates an error code.
|
||||
int32 EntityList::DeleteNPCCorpses()
|
||||
{
|
||||
|
||||
@ -350,7 +350,6 @@ public:
|
||||
void ListNPCs(Client* client, const char* arg1 = 0, const char* arg2 = 0, uint8 searchtype = 0);
|
||||
void ListNPCCorpses(Client* client);
|
||||
void ListPlayerCorpses(Client* client);
|
||||
void FindPathsToAllNPCs();
|
||||
int32 DeleteNPCCorpses();
|
||||
int32 DeletePlayerCorpses();
|
||||
void WriteEntityIDs();
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "../common/rulesys.h"
|
||||
|
||||
#include "map.h"
|
||||
#include "pathing.h"
|
||||
#include "zone.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
@ -46,7 +45,7 @@ void Mob::CheckFlee() {
|
||||
|
||||
//see if were possibly hurt enough
|
||||
float ratio = GetHPRatio();
|
||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
||||
float fleeratio = (float)GetSpecialAbility(FLEE_PERCENT);
|
||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
||||
|
||||
if(ratio >= fleeratio)
|
||||
@ -106,7 +105,7 @@ void Mob::ProcessFlee()
|
||||
}
|
||||
|
||||
//see if we are still dying, if so, do nothing
|
||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
||||
float fleeratio = (float)GetSpecialAbility(FLEE_PERCENT);
|
||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
||||
if (GetHPRatio() < fleeratio)
|
||||
return;
|
||||
@ -125,28 +124,11 @@ void Mob::ProcessFlee()
|
||||
|
||||
void Mob::CalculateNewFearpoint()
|
||||
{
|
||||
if(RuleB(Pathing, Fear) && zone->pathing)
|
||||
{
|
||||
int Node = zone->pathing->GetRandomPathNode();
|
||||
|
||||
glm::vec3 Loc = zone->pathing->GetPathNodeCoordinates(Node);
|
||||
|
||||
++Loc.z;
|
||||
|
||||
glm::vec3 CurrentPosition(GetX(), GetY(), GetZ());
|
||||
|
||||
std::deque<int> Route = zone->pathing->FindRoute(CurrentPosition, Loc);
|
||||
|
||||
if(Route.size() > 0)
|
||||
{
|
||||
m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z);
|
||||
currently_fleeing = true;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Out(Logs::Detail, Logs::None, "No path found to selected node. Falling through to old fear point selection.");
|
||||
glm::vec3 pos;
|
||||
if (zone->pathing.GetRandomPoint(glm::vec3(GetX(), GetY(), GetZ()), 500.0f, pos)) {
|
||||
currently_fleeing = true;
|
||||
m_FearWalkTarget = pos;
|
||||
return;
|
||||
}
|
||||
|
||||
int loop = 0;
|
||||
@ -168,6 +150,7 @@ void Mob::CalculateNewFearpoint()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currently_fleeing)
|
||||
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
||||
else //Break fear
|
||||
|
||||
@ -1049,12 +1049,12 @@ void Lua_Client::IncrementAA(int aa) {
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points) {
|
||||
Lua_Safe_Call_Bool();
|
||||
self->GrantAlternateAdvancementAbility(aa_id, points);
|
||||
return self->GrantAlternateAdvancementAbility(aa_id, points);
|
||||
}
|
||||
|
||||
bool Lua_Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
|
||||
Lua_Safe_Call_Bool();
|
||||
self->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
return self->GrantAlternateAdvancementAbility(aa_id, points, ignore_cost);
|
||||
}
|
||||
|
||||
void Lua_Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z) {
|
||||
|
||||
@ -873,7 +873,7 @@ bool Map::LoadV2(FILE *f) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 face_count = indices.size() / 3;
|
||||
uint32 face_count = (uint32)indices.size() / 3;
|
||||
|
||||
if (imp) {
|
||||
imp->rm->release();
|
||||
|
||||
@ -1304,7 +1304,7 @@ bool Merc::Process()
|
||||
return true;
|
||||
|
||||
// Merc AI
|
||||
//AI_Process();
|
||||
AI_Process();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
15
zone/mob.cpp
15
zone/mob.cpp
@ -415,15 +415,8 @@ Mob::Mob(const char* in_name,
|
||||
m_TargetRing = glm::vec3();
|
||||
|
||||
flymode = FlyMode3;
|
||||
// Pathing
|
||||
PathingLOSState = UnknownLOS;
|
||||
PathingLoopCount = 0;
|
||||
PathingLastNodeVisited = -1;
|
||||
PathingLOSCheckTimer = new Timer(RuleI(Pathing, LOSCheckFrequency));
|
||||
PathingRouteUpdateTimerShort = new Timer(RuleI(Pathing, RouteUpdateFrequencyShort));
|
||||
PathingRouteUpdateTimerLong = new Timer(RuleI(Pathing, RouteUpdateFrequencyLong));
|
||||
|
||||
DistractedFromGrid = false;
|
||||
PathingTraversedNodes = 0;
|
||||
hate_list.SetHateOwner(this);
|
||||
|
||||
m_AllowBeneficial = false;
|
||||
@ -469,9 +462,6 @@ Mob::~Mob()
|
||||
entity_list.DestroyTempPets(this);
|
||||
}
|
||||
entity_list.UnMarkNPC(GetID());
|
||||
safe_delete(PathingLOSCheckTimer);
|
||||
safe_delete(PathingRouteUpdateTimerShort);
|
||||
safe_delete(PathingRouteUpdateTimerLong);
|
||||
UninitializeBuffSlots();
|
||||
}
|
||||
|
||||
@ -1564,8 +1554,7 @@ void Mob::ShowBuffList(Client* client) {
|
||||
}
|
||||
|
||||
void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) {
|
||||
|
||||
Route.clear();
|
||||
m_pathing_route = PathfindingRoute();
|
||||
|
||||
if(IsNPC()) {
|
||||
entity_list.ProcessMove(CastToNPC(), x, y, z);
|
||||
|
||||
21
zone/mob.h
21
zone/mob.h
@ -18,10 +18,10 @@
|
||||
#ifndef MOB_H
|
||||
#define MOB_H
|
||||
|
||||
#include "../common/pathfind.h"
|
||||
#include "common.h"
|
||||
#include "entity.h"
|
||||
#include "hate_list.h"
|
||||
#include "pathing.h"
|
||||
#include "position.h"
|
||||
#include "aa_ability.h"
|
||||
#include "aa.h"
|
||||
@ -473,7 +473,7 @@ public:
|
||||
int GetBaseRunspeed() const { return base_runspeed; }
|
||||
int GetBaseWalkspeed() const { return base_walkspeed; }
|
||||
int GetBaseFearSpeed() const { return base_fearspeed; }
|
||||
float GetMovespeed() const { return IsRunning() ? GetRunspeed() : GetWalkspeed(); }
|
||||
float GetMovespeed() const { return IsRunning() ? (float)GetRunspeed() : (float)GetWalkspeed(); }
|
||||
bool IsRunning() const { return m_is_running; }
|
||||
void SetRunning(bool val) { m_is_running = val; }
|
||||
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true);
|
||||
@ -1141,8 +1141,8 @@ protected:
|
||||
virtual int16 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
|
||||
void CalculateNewFearpoint();
|
||||
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
|
||||
void PrintRoute();
|
||||
glm::vec3 UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange);
|
||||
void TrySnapToMap();
|
||||
|
||||
virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0);
|
||||
int16 GetSympatheticSpellProcRate(uint16 spell_id);
|
||||
@ -1313,19 +1313,8 @@ protected:
|
||||
glm::vec3 m_FearWalkTarget;
|
||||
bool currently_fleeing;
|
||||
|
||||
// Pathing
|
||||
//
|
||||
glm::vec3 PathingDestination;
|
||||
glm::vec3 PathingLastPosition;
|
||||
int PathingLoopCount;
|
||||
int PathingLastNodeVisited;
|
||||
std::deque<int> Route;
|
||||
LOSType PathingLOSState;
|
||||
Timer *PathingLOSCheckTimer;
|
||||
Timer *PathingRouteUpdateTimerShort;
|
||||
Timer *PathingRouteUpdateTimerLong;
|
||||
PathfindingRoute m_pathing_route;
|
||||
bool DistractedFromGrid;
|
||||
int PathingTraversedNodes;
|
||||
|
||||
uint32 pDontHealMeBefore;
|
||||
uint32 pDontBuffMeBefore;
|
||||
|
||||
107
zone/mob_ai.cpp
107
zone/mob_ai.cpp
@ -586,10 +586,6 @@ void Client::AI_Stop() {
|
||||
|
||||
// only call this on a zone shutdown event
|
||||
void Mob::AI_ShutDown() {
|
||||
safe_delete(PathingLOSCheckTimer);
|
||||
safe_delete(PathingRouteUpdateTimerShort);
|
||||
safe_delete(PathingRouteUpdateTimerLong);
|
||||
|
||||
attack_timer.Disable();
|
||||
attack_dw_timer.Disable();
|
||||
ranged_timer.Disable();
|
||||
@ -787,20 +783,12 @@ void Client::AI_Process()
|
||||
// Calculate a new point to run to
|
||||
CalculateNewFearpoint();
|
||||
}
|
||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
speed, WaypointChanged, NodeReached);
|
||||
bool WaypointChanged;
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
speed, WaypointChanged);
|
||||
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
||||
}
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -869,19 +857,12 @@ void Client::AI_Process()
|
||||
animation = newspeed;
|
||||
newspeed *= 2;
|
||||
SetCurrentSpeed(newspeed);
|
||||
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), newspeed);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||
GetRunspeed(), WaypointChanged, NodeReached);
|
||||
|
||||
bool WaypointChanged;
|
||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||
GetRunspeed(), WaypointChanged);
|
||||
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, newspeed);
|
||||
}
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, newspeed);
|
||||
}
|
||||
}
|
||||
else if(IsMoving())
|
||||
@ -980,22 +961,13 @@ void Mob::AI_Process() {
|
||||
// Calculate a new point to run to
|
||||
CalculateNewFearpoint();
|
||||
}
|
||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
||||
{
|
||||
CalculateNewPosition2(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, GetFearSpeed(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
bool WaypointChanged;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
GetFearSpeed(), WaypointChanged, NodeReached);
|
||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
||||
GetFearSpeed(), WaypointChanged);
|
||||
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetFearSpeed());
|
||||
}
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetFearSpeed());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1299,20 +1271,13 @@ void Mob::AI_Process() {
|
||||
{
|
||||
if(!IsRooted()) {
|
||||
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
|
||||
if(!RuleB(Pathing, Aggro) || !zone->pathing)
|
||||
CalculateNewPosition2(target->GetX(), target->GetY(), target->GetZ(), GetRunspeed());
|
||||
else
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
|
||||
GetRunspeed(), WaypointChanged, NodeReached);
|
||||
bool WaypointChanged;
|
||||
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
glm::vec3 Goal = UpdatePath(target->GetX(), target->GetY(), target->GetZ(),
|
||||
GetRunspeed(), WaypointChanged);
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
||||
}
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
||||
|
||||
}
|
||||
else if(IsMoving()) {
|
||||
@ -1588,18 +1553,15 @@ void NPC::AI_DoMovement() {
|
||||
}
|
||||
if (doMove)
|
||||
{ // not at waypoint yet or at 0 pause WP, so keep moving
|
||||
if(!RuleB(Pathing, AggroReturnToGrid) || !zone->pathing || (DistractedFromGrid == 0))
|
||||
if(DistractedFromGrid == 0)
|
||||
CalculateNewPosition2(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, true);
|
||||
else
|
||||
{
|
||||
bool WaypointChanged;
|
||||
bool NodeReached;
|
||||
glm::vec3 Goal = UpdatePath(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, WaypointChanged, NodeReached);
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
if(NodeReached)
|
||||
glm::vec3 Goal = UpdatePath(m_CurrentWayPoint.x, m_CurrentWayPoint.y, m_CurrentWayPoint.z, walksp, WaypointChanged);
|
||||
if (WaypointChanged) {
|
||||
entity_list.OpenDoorsNear(CastToNPC());
|
||||
}
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, walksp, true);
|
||||
}
|
||||
@ -1625,26 +1587,19 @@ void NPC::AI_DoMovement() {
|
||||
else if (IsGuarding())
|
||||
{
|
||||
bool CP2Moved;
|
||||
if(!RuleB(Pathing, Guard) || !zone->pathing)
|
||||
CP2Moved = CalculateNewPosition2(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp);
|
||||
else
|
||||
if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)))
|
||||
{
|
||||
if(!((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)))
|
||||
{
|
||||
bool WaypointChanged, NodeReached;
|
||||
glm::vec3 Goal = UpdatePath(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp, WaypointChanged, NodeReached);
|
||||
if(WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
if(NodeReached)
|
||||
entity_list.OpenDoorsNear(CastToNPC());
|
||||
|
||||
CP2Moved = CalculateNewPosition2(Goal.x, Goal.y, Goal.z, walksp);
|
||||
bool WaypointChanged;
|
||||
glm::vec3 Goal = UpdatePath(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z, walksp, WaypointChanged);
|
||||
if (WaypointChanged) {
|
||||
entity_list.OpenDoorsNear(CastToNPC());
|
||||
}
|
||||
else
|
||||
CP2Moved = false;
|
||||
|
||||
CP2Moved = CalculateNewPosition2(Goal.x, Goal.y, Goal.z, walksp);
|
||||
}
|
||||
else
|
||||
CP2Moved = false;
|
||||
|
||||
if (!CP2Moved)
|
||||
{
|
||||
if(moved) {
|
||||
|
||||
@ -734,7 +734,7 @@ bool NPC::Process()
|
||||
}
|
||||
}
|
||||
|
||||
//AI_Process();
|
||||
AI_Process();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
2263
zone/pathing.cpp
2263
zone/pathing.cpp
File diff suppressed because it is too large
Load Diff
@ -74,10 +74,8 @@ public:
|
||||
void OpenDoors(int Node1, int Node2, Mob* ForWho);
|
||||
|
||||
PathNode* FindPathNodeByCoordinates(float x, float y, float z);
|
||||
void ShowPathNodeNeighbours(Client *c);
|
||||
int GetRandomPathNode();
|
||||
|
||||
void NodeInfo(Client *c);
|
||||
int32 AddNode(float x, float y, float z, float best_z, int32 requested_id = 0); //return -1 on failure, else returns the id of this node
|
||||
bool DeleteNode(Client *c);
|
||||
bool DeleteNode(int32 id); //returns true on success, false on failure, tries to delete a node from this map
|
||||
|
||||
@ -670,79 +670,6 @@ void QuestManager::repopzone() {
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::ConnectNodeToNode(int node1, int node2, int teleport, int doorid) {
|
||||
if (!node1 || !node2)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::ConnectNodeToNode called without node1 or node2. Probably syntax error in quest file.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!teleport)
|
||||
{
|
||||
teleport = 0;
|
||||
}
|
||||
else if (teleport == 1 || teleport == -1)
|
||||
{
|
||||
teleport = -1;
|
||||
}
|
||||
|
||||
if (!doorid)
|
||||
{
|
||||
doorid = 0;
|
||||
}
|
||||
|
||||
if (!zone->pathing)
|
||||
{
|
||||
// if no pathing bits available, make them available.
|
||||
zone->pathing = new PathManager();
|
||||
}
|
||||
|
||||
if (zone->pathing)
|
||||
{
|
||||
zone->pathing->ConnectNodeToNode(node1, node2, teleport, doorid);
|
||||
Log.Out(Logs::Moderate, Logs::Quests, "QuestManager::ConnectNodeToNode connecting node %i to node %i.", node1, node2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::AddNode(float x, float y, float z, float best_z, int32 requested_id)
|
||||
{
|
||||
if (!x || !y || !z)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Quests, "QuestManager::AddNode called without x, y, z. Probably syntax error in quest file.");
|
||||
}
|
||||
|
||||
if (!best_z || best_z == 0)
|
||||
{
|
||||
if (zone->zonemap)
|
||||
{
|
||||
glm::vec3 loc(x, y, z);
|
||||
best_z = zone->zonemap->FindBestZ(loc, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
best_z = z;
|
||||
}
|
||||
}
|
||||
|
||||
if (!requested_id)
|
||||
{
|
||||
requested_id = 0;
|
||||
}
|
||||
|
||||
if (!zone->pathing)
|
||||
{
|
||||
// if no pathing bits available, make them available.
|
||||
zone->pathing = new PathManager();
|
||||
}
|
||||
|
||||
if (zone->pathing)
|
||||
{
|
||||
zone->pathing->AddNode(x, y, z, best_z, requested_id);
|
||||
Log.Out(Logs::Moderate, Logs::Quests, "QuestManager::AddNode adding node at (%i, %i, %i).", x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::settarget(const char *type, int target_id) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (!owner || !owner->IsNPC())
|
||||
|
||||
@ -87,8 +87,6 @@ public:
|
||||
void depopall(int npc_type = 0);
|
||||
void depopzone(bool StartSpawnTimer = true);
|
||||
void repopzone();
|
||||
void ConnectNodeToNode(int node1, int node2, int teleport, int doorid);
|
||||
void AddNode(float x, float y, float z, float best_z, int32 requested_id);
|
||||
void settarget(const char *type, int target_id);
|
||||
void follow(int entity_id, int distance);
|
||||
void sfollow();
|
||||
|
||||
@ -42,7 +42,6 @@
|
||||
#include "net.h"
|
||||
#include "npc.h"
|
||||
#include "object.h"
|
||||
#include "pathing.h"
|
||||
#include "petitions.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "spawn2.h"
|
||||
@ -102,8 +101,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
}
|
||||
zone->zonemap = Map::LoadMapFile(zone->map_name);
|
||||
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
|
||||
zone->pathing = PathManager::LoadPathFile(zone->map_name);
|
||||
zone->pathing_new.Load(zone->map_name);
|
||||
zone->pathing.Load(zone->map_name);
|
||||
|
||||
char tmp[10];
|
||||
if (database.GetVariable("loglevel",tmp, 9)) {
|
||||
@ -756,7 +754,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
pers_instance = false;
|
||||
zonemap = nullptr;
|
||||
watermap = nullptr;
|
||||
pathing = nullptr;
|
||||
qGlobals = nullptr;
|
||||
default_ruleset = 0;
|
||||
|
||||
@ -845,7 +842,6 @@ Zone::~Zone() {
|
||||
spawn2_list.Clear();
|
||||
safe_delete(zonemap);
|
||||
safe_delete(watermap);
|
||||
safe_delete(pathing);
|
||||
if (worldserver.Connected()) {
|
||||
worldserver.SetZoneData(0);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "../common/random.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/pathfind.h"
|
||||
#include "map.h"
|
||||
#include "qglobals.h"
|
||||
#include "spawn2.h"
|
||||
#include "spawngroup.h"
|
||||
@ -212,8 +213,7 @@ public:
|
||||
|
||||
Map* zonemap;
|
||||
WaterMap* watermap;
|
||||
PathManager *pathing;
|
||||
PathfindingManager pathing_new;
|
||||
PathfindingManager pathing;
|
||||
NewZone_Struct newzone_data;
|
||||
|
||||
SpawnConditionManager spawn_conditions;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user