Pathing is essentially fully functional now, still could use improvements here and there

This commit is contained in:
KimLS 2016-01-13 13:39:42 -08:00
parent e61e2e7f02
commit 1cb07d055e
25 changed files with 214 additions and 2548 deletions

View File

@ -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; }

View File

@ -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(&current_location[0], &ext[0], &filter, &start_ref, 0);
query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
m_nav_query->findNearestPoly(&current_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, &current_location[0], &dest_location[0], &filter, path, &npoly, 256);
m_nav_query->findPath(start_ref, end_ref, &current_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(&current_location[0], &epos[0], path, npoly,
m_nav_query->findStraightPath(&current_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 &current_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 &current = 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;
}

View File

@ -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 &current_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 &current_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;
};

View File

@ -183,7 +183,6 @@ SET(zone_headers
npc_ai.h
object.h
oriented_bounding_box.h
pathing.h
perlpacket.h
petitions.h
pets.h

View File

@ -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; }

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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"

View File

@ -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);

View 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()
{

View File

@ -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();

View File

@ -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

View File

@ -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) {

View File

@ -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();

View File

@ -1304,7 +1304,7 @@ bool Merc::Process()
return true;
// Merc AI
//AI_Process();
AI_Process();
return true;
}

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -734,7 +734,7 @@ bool NPC::Process()
}
}
//AI_Process();
AI_Process();
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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())

View File

@ -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();

View File

@ -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);
}

View File

@ -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;