mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-29 09:51:30 +00:00
Movement manager add
This commit is contained in:
parent
c677169edd
commit
2224b83ae0
@ -92,6 +92,8 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
connect(1000),
|
||||
eqs(ieqs)
|
||||
{
|
||||
//mMovementManager->AddClient(this);
|
||||
|
||||
// Live does not send datarate as of 3/11/2005
|
||||
//eqs->SetDataRate(7);
|
||||
ip = eqs->GetRemoteIP();
|
||||
|
||||
@ -82,6 +82,7 @@ SET(zone_sources
|
||||
merc.cpp
|
||||
mob.cpp
|
||||
mob_ai.cpp
|
||||
mob_movement_manager.cpp
|
||||
mod_functions.cpp
|
||||
net.cpp
|
||||
npc.cpp
|
||||
@ -204,6 +205,7 @@ SET(zone_headers
|
||||
message.h
|
||||
merc.h
|
||||
mob.h
|
||||
mob_movement_manager.h
|
||||
net.h
|
||||
npc.h
|
||||
npc_ai.h
|
||||
|
||||
@ -53,6 +53,7 @@ extern volatile bool RunLoops;
|
||||
#include "guild_mgr.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "queryserv.h"
|
||||
#include "mob_movement_manager.h"
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern EntityList entity_list;
|
||||
@ -156,7 +157,6 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f),
|
||||
last_region_type(RegionTypeUnsupported),
|
||||
m_dirtyautohaters(false),
|
||||
npc_close_scan_timer(6000),
|
||||
hp_self_update_throttle_timer(300),
|
||||
hp_other_update_throttle_timer(500),
|
||||
position_update_timer(10000),
|
||||
@ -166,6 +166,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
for (int client_filter = 0; client_filter < _FilterCount; client_filter++)
|
||||
ClientFilters[client_filter] = FilterShow;
|
||||
|
||||
mMovementManager->AddClient(this);
|
||||
character_id = 0;
|
||||
conn_state = NoPacketsReceived;
|
||||
client_data_loaded = false;
|
||||
@ -339,6 +340,8 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
mMovementManager->RemoveClient(this);
|
||||
|
||||
#ifdef BOTS
|
||||
Bot::ProcessBotOwnerRefDelete(this);
|
||||
#endif
|
||||
@ -6464,7 +6467,7 @@ void Client::LocateCorpse()
|
||||
SetHeading(CalculateHeadingToTarget(ClosestCorpse->GetX(), ClosestCorpse->GetY()));
|
||||
SetTarget(ClosestCorpse);
|
||||
SendTargetCommand(ClosestCorpse->GetID());
|
||||
SendPositionUpdate(2);
|
||||
SendPositionUpdate(true);
|
||||
}
|
||||
else if(!GetTarget())
|
||||
Message_StringID(clientMessageError, SENSE_CORPSE_NONE);
|
||||
|
||||
@ -1534,13 +1534,11 @@ private:
|
||||
Timer afk_toggle_timer;
|
||||
Timer helm_toggle_timer;
|
||||
Timer aggro_meter_timer;
|
||||
Timer npc_close_scan_timer;
|
||||
Timer hp_self_update_throttle_timer; /* This is to prevent excessive packet sending under trains/fast combat */
|
||||
Timer hp_other_update_throttle_timer; /* This is to keep clients from DOSing the server with macros that change client targets constantly */
|
||||
Timer position_update_timer; /* Timer used when client hasn't updated within a 10 second window */
|
||||
|
||||
glm::vec3 m_Proximity;
|
||||
glm::vec4 last_major_update_position;
|
||||
|
||||
void BulkSendInventoryItems();
|
||||
|
||||
|
||||
@ -4622,10 +4622,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u",
|
||||
client_scan_npc_aggro_timer.GetDuration());
|
||||
if (client_scan_npc_aggro_timer.GetDuration() > 1000) {
|
||||
|
||||
npc_close_scan_timer.Disable();
|
||||
npc_close_scan_timer.Start(500);
|
||||
|
||||
client_scan_npc_aggro_timer.Disable();
|
||||
client_scan_npc_aggro_timer.Start(500);
|
||||
|
||||
@ -4634,10 +4630,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u",
|
||||
client_scan_npc_aggro_timer.GetDuration());
|
||||
if (client_scan_npc_aggro_timer.GetDuration() < 1000) {
|
||||
|
||||
npc_close_scan_timer.Disable();
|
||||
npc_close_scan_timer.Start(6000);
|
||||
|
||||
client_scan_npc_aggro_timer.Disable();
|
||||
client_scan_npc_aggro_timer.Start(3000);
|
||||
}
|
||||
|
||||
@ -242,47 +242,6 @@ bool Client::Process() {
|
||||
}
|
||||
}
|
||||
|
||||
///* Build a close range list of NPC's */
|
||||
//if (npc_close_scan_timer.Check()) {
|
||||
// close_mobs.clear();
|
||||
//
|
||||
// /* Force spawn updates when traveled far */
|
||||
// bool force_spawn_updates = false;
|
||||
// float client_update_range = (RuleI(Range, ClientForceSpawnUpdateRange) * RuleI(Range, ClientForceSpawnUpdateRange));
|
||||
// if (DistanceSquared(last_major_update_position, m_Position) >= client_update_range) {
|
||||
// last_major_update_position = m_Position;
|
||||
// force_spawn_updates = true;
|
||||
// }
|
||||
//
|
||||
// float scan_range = (RuleI(Range, ClientNPCScan) * RuleI(Range, ClientNPCScan));
|
||||
// auto &mob_list = entity_list.GetMobList();
|
||||
// for (auto itr = mob_list.begin(); itr != mob_list.end(); ++itr) {
|
||||
// Mob* mob = itr->second;
|
||||
//
|
||||
// float distance = DistanceSquared(m_Position, mob->GetPosition());
|
||||
// if (mob->IsNPC()) {
|
||||
// if (distance <= scan_range) {
|
||||
// close_mobs.insert(std::pair<Mob *, float>(mob, distance));
|
||||
// }
|
||||
// else if ((mob->GetAggroRange() * mob->GetAggroRange()) > scan_range) {
|
||||
// close_mobs.insert(std::pair<Mob *, float>(mob, distance));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (force_spawn_updates && mob != this) {
|
||||
//
|
||||
// if (mob->is_distance_roamer) {
|
||||
// mob->SendPositionUpdateToClient(this);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (distance <= client_update_range)
|
||||
// mob->SendPositionUpdateToClient(this);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
||||
bool may_use_attacks = false;
|
||||
/*
|
||||
Things which prevent us from attacking:
|
||||
@ -460,7 +419,7 @@ bool Client::Process() {
|
||||
{
|
||||
animation = 0;
|
||||
m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w);
|
||||
SendPositionUpdate(2);
|
||||
SendPositionUpdate(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
71
zone/mob.cpp
71
zone/mob.cpp
@ -23,6 +23,7 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
#include "mob_movement_manager.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
@ -116,12 +117,12 @@ Mob::Mob(const char* in_name,
|
||||
position_update_melee_push_timer(500),
|
||||
hate_list_cleanup_timer(6000)
|
||||
{
|
||||
mMovementManager = &MobMovementManager::Get();
|
||||
mMovementManager->AddMob(this);
|
||||
|
||||
targeted = 0;
|
||||
currently_fleeing = false;
|
||||
|
||||
last_major_update_position = m_Position;
|
||||
is_distance_roamer = false;
|
||||
|
||||
AI_Init();
|
||||
SetMoving(false);
|
||||
moved = false;
|
||||
@ -448,6 +449,8 @@ Mob::Mob(const char* in_name,
|
||||
|
||||
Mob::~Mob()
|
||||
{
|
||||
mMovementManager->RemoveMob(this);
|
||||
|
||||
AI_Stop();
|
||||
if (GetPet()) {
|
||||
if (GetPet()->Charmed())
|
||||
@ -1450,59 +1453,12 @@ void Mob::StopMoving(float new_heading) {
|
||||
|
||||
/* Used for mobs standing still - this does not send a delta */
|
||||
void Mob::SendPosition() {
|
||||
//auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
//PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
|
||||
//MakeSpawnUpdateNoDelta(spu);
|
||||
//
|
||||
//entity_list.QueueCloseClients(this, app, true, 200.0f, nullptr, false);
|
||||
//
|
||||
///* When an NPC has made a large distance change - we should update all clients to prevent "ghosts" */
|
||||
//if (DistanceSquared(last_major_update_position, m_Position) >= (100 * 100)) {
|
||||
// entity_list.QueueClients(this, app, true, true);
|
||||
// last_major_update_position = m_Position;
|
||||
// is_distance_roamer = true;
|
||||
//}
|
||||
//else {
|
||||
// entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
|
||||
//}
|
||||
//
|
||||
//safe_delete(app);
|
||||
}
|
||||
|
||||
void Mob::SendPositionUpdateToClient(Client *client) {
|
||||
//auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
//PlayerPositionUpdateServer_Struct* spawn_update = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
|
||||
//
|
||||
//if(this->IsMoving())
|
||||
// MakeSpawnUpdate(spawn_update);
|
||||
//else
|
||||
// MakeSpawnUpdateNoDelta(spawn_update);
|
||||
//
|
||||
//client->QueuePacket(app, false);
|
||||
//
|
||||
//safe_delete(app);
|
||||
mMovementManager->SendPosition(this);
|
||||
}
|
||||
|
||||
/* Position updates for mobs on the move */
|
||||
void Mob::SendPositionUpdate(uint8 iSendToSelf) {
|
||||
//auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
//PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
|
||||
//MakeSpawnUpdate(spu);
|
||||
//
|
||||
//if (iSendToSelf == 2) {
|
||||
// if (IsClient()) {
|
||||
// CastToClient()->FastQueuePacket(&app, false);
|
||||
// }
|
||||
//}
|
||||
//else if (DistanceSquared(last_major_update_position, m_Position) >= (100 * 100)) {
|
||||
// entity_list.QueueClients(this, app, true, true);
|
||||
// last_major_update_position = m_Position;
|
||||
// is_distance_roamer = true;
|
||||
//}
|
||||
//else {
|
||||
// entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false);
|
||||
//}
|
||||
//safe_delete(app);
|
||||
void Mob::SendPositionUpdate(bool iSendToSelf) {
|
||||
mMovementManager->SendPositionUpdate(this, iSendToSelf);
|
||||
}
|
||||
|
||||
// this is for SendPosition()
|
||||
@ -1518,11 +1474,6 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu) {
|
||||
spu->heading = FloatToEQ12(m_Position.w);
|
||||
spu->animation = 0;
|
||||
spu->delta_heading = FloatToEQ10(0);
|
||||
spu->padding0002 = 0;
|
||||
spu->padding0006 = 7;
|
||||
spu->padding0014 = 0x7f;
|
||||
spu->padding0018 = 0x5df27;
|
||||
|
||||
}
|
||||
|
||||
// this is for SendPosUpdate()
|
||||
@ -1535,10 +1486,6 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
|
||||
spu->delta_y = FloatToEQ13(m_Delta.y);
|
||||
spu->delta_z = FloatToEQ13(m_Delta.z);
|
||||
spu->heading = FloatToEQ12(m_Position.w);
|
||||
spu->padding0002 = 0;
|
||||
spu->padding0006 = 7;
|
||||
spu->padding0014 = 0x7f;
|
||||
spu->padding0018 = 0x5df27;
|
||||
#ifdef BOTS
|
||||
if (this->IsClient() || this->IsBot())
|
||||
#else
|
||||
|
||||
11
zone/mob.h
11
zone/mob.h
@ -49,6 +49,7 @@ class Aura;
|
||||
struct AuraRecord;
|
||||
struct NewSpawn_Struct;
|
||||
struct PlayerPositionUpdateServer_Struct;
|
||||
class MobMovementManager;
|
||||
|
||||
const int COLLISION_BOX_SIZE = 8;
|
||||
|
||||
@ -164,8 +165,6 @@ public:
|
||||
inline virtual bool IsMob() const { return true; }
|
||||
inline virtual bool InZone() const { return true; }
|
||||
|
||||
bool is_distance_roamer;
|
||||
|
||||
//Somewhat sorted: needs documenting!
|
||||
|
||||
//Attack
|
||||
@ -559,8 +558,7 @@ public:
|
||||
void SetRunning(bool val) { m_is_running = val; }
|
||||
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true);
|
||||
void SetDelta(const glm::vec4& delta);
|
||||
void SendPositionUpdateToClient(Client *client);
|
||||
void SendPositionUpdate(uint8 iSendToSelf = 0);
|
||||
void SendPositionUpdate(bool iSendToSelf = false);
|
||||
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
|
||||
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);
|
||||
void SendPosition();
|
||||
@ -802,6 +800,7 @@ public:
|
||||
void SendAppearancePacket(uint32 type, uint32 value, bool WholeZone = true, bool iIgnoreSelf = false, Client *specific_target=nullptr);
|
||||
void SetAppearance(EmuAppearance app, bool iIgnoreSelf = true);
|
||||
inline EmuAppearance GetAppearance() const { return _appearance; }
|
||||
inline const int GetAnimation() const { return animation; }
|
||||
inline const uint8 GetRunAnimSpeed() const { return pRunAnimSpeed; }
|
||||
inline void SetRunAnimSpeed(int8 in) { if (pRunAnimSpeed != in) { pRunAnimSpeed = in; } }
|
||||
bool IsDestructibleObject() { return destructibleobject; }
|
||||
@ -1247,8 +1246,6 @@ protected:
|
||||
uint8 orig_level;
|
||||
uint32 npctype_id;
|
||||
glm::vec4 m_Position;
|
||||
/* Used to determine when an NPC has traversed so many units - to send a zone wide pos update */
|
||||
glm::vec4 last_major_update_position;
|
||||
|
||||
int animation; // this is really what MQ2 calls SpeedRun just packed like (int)(SpeedRun * 40.0f)
|
||||
float base_size;
|
||||
@ -1530,6 +1527,8 @@ protected:
|
||||
AuraMgr aura_mgr;
|
||||
AuraMgr trap_mgr;
|
||||
|
||||
MobMovementManager *mMovementManager;
|
||||
|
||||
private:
|
||||
void _StopSong(); //this is not what you think it is
|
||||
Mob* target;
|
||||
|
||||
259
zone/mob_movement_manager.cpp
Normal file
259
zone/mob_movement_manager.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
#include "mob_movement_manager.h"
|
||||
#include "client.h"
|
||||
#include "mob.h"
|
||||
#include "../common/timer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct MobMovementEntry
|
||||
{
|
||||
Mob *m;
|
||||
int animation;
|
||||
float heading;
|
||||
bool dirty;
|
||||
double last_sent_time;
|
||||
double last_sent_time_long_distance;
|
||||
|
||||
MobMovementEntry(Mob *m) {
|
||||
this->m = m;
|
||||
animation = 0;
|
||||
heading = m->GetHeading();
|
||||
dirty = false;
|
||||
last_sent_time = 0.0;
|
||||
last_sent_time_long_distance = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
struct MobMovementManager::Implementation
|
||||
{
|
||||
std::vector<MobMovementEntry> Entries;
|
||||
std::vector<Client*> Clients;
|
||||
};
|
||||
|
||||
MobMovementManager::MobMovementManager()
|
||||
{
|
||||
_impl.reset(new Implementation());
|
||||
}
|
||||
|
||||
MobMovementManager::~MobMovementManager()
|
||||
{
|
||||
}
|
||||
|
||||
void MobMovementManager::Process()
|
||||
{
|
||||
double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
|
||||
|
||||
for (auto &ent : _impl->Entries) {
|
||||
if (ent.dirty) {
|
||||
SendUpdate(ent.m, ent.animation, ent.heading);
|
||||
|
||||
ent.dirty = false;
|
||||
ent.last_sent_time = current_time;
|
||||
ent.last_sent_time_long_distance = current_time;
|
||||
} else if (ent.animation != 0) {
|
||||
double diff_short_range = current_time - ent.last_sent_time;
|
||||
double diff_long_range = current_time - ent.last_sent_time_long_distance;
|
||||
|
||||
if (diff_short_range >= 2.0) {
|
||||
SendUpdateShortDistance(ent.m, ent.animation, ent.heading);
|
||||
ent.last_sent_time = current_time;
|
||||
}
|
||||
|
||||
if (diff_long_range >= 6.0) {
|
||||
SendUpdateLongDistance(ent.m, ent.animation, ent.heading);
|
||||
ent.last_sent_time_long_distance = current_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MobMovementManager::AddMob(Mob *m)
|
||||
{
|
||||
_impl->Entries.push_back(MobMovementEntry(m));
|
||||
}
|
||||
|
||||
void MobMovementManager::RemoveMob(Mob *m)
|
||||
{
|
||||
auto iter = _impl->Entries.begin();
|
||||
while (iter != _impl->Entries.end()) {
|
||||
auto &ent = *iter;
|
||||
if (ent.m == m) {
|
||||
_impl->Entries.erase(iter);
|
||||
return;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void MobMovementManager::AddClient(Client *c)
|
||||
{
|
||||
_impl->Clients.push_back(c);
|
||||
}
|
||||
|
||||
void MobMovementManager::RemoveClient(Client *c)
|
||||
{
|
||||
auto iter = _impl->Clients.begin();
|
||||
while (iter != _impl->Clients.end()) {
|
||||
if (c == *iter) {
|
||||
_impl->Clients.erase(iter);
|
||||
return;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MobMovementManager::SendPosition(Mob *who)
|
||||
{
|
||||
auto iter = _impl->Entries.begin();
|
||||
while (iter != _impl->Entries.end()) {
|
||||
auto &ent = *iter;
|
||||
|
||||
if (ent.m == who) {
|
||||
auto anim = 0;
|
||||
auto heading = who->GetHeading();
|
||||
|
||||
if (ent.animation != anim || !HeadingEqual(ent.heading, heading)) {
|
||||
ent.animation = anim;
|
||||
ent.heading = heading;
|
||||
ent.dirty = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void MobMovementManager::SendPositionUpdate(Mob *who, bool send_to_self)
|
||||
{
|
||||
auto iter = _impl->Entries.begin();
|
||||
while (iter != _impl->Entries.end()) {
|
||||
auto &ent = *iter;
|
||||
|
||||
if (ent.m == who) {
|
||||
auto anim = 0;
|
||||
auto heading = who->GetHeading();
|
||||
if (who->IsMoving()) {
|
||||
if (who->IsClient()) {
|
||||
anim = who->GetAnimation();
|
||||
}
|
||||
else {
|
||||
anim = who->GetRunAnimSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
if (send_to_self && who->IsClient()) {
|
||||
SendUpdateTo(who, who->CastToClient(), anim, heading);
|
||||
}
|
||||
|
||||
if (ent.animation != anim || !HeadingEqual(ent.heading, heading)) {
|
||||
ent.animation = anim;
|
||||
ent.heading = heading;
|
||||
ent.dirty = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
bool MobMovementManager::HeadingEqual(float a, float b)
|
||||
{
|
||||
const float eps = 0.001f;
|
||||
return abs(a - b) < eps;
|
||||
}
|
||||
|
||||
void MobMovementManager::SendUpdateTo(Mob *who, Client *c, int anim, float heading)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer;
|
||||
if (anim == 0) {
|
||||
who->MakeSpawnUpdateNoDelta(spu);
|
||||
}
|
||||
else {
|
||||
who->MakeSpawnUpdate(spu);
|
||||
}
|
||||
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
|
||||
void MobMovementManager::SendUpdate(Mob *who, int anim, float heading)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer;
|
||||
if (anim == 0) {
|
||||
who->MakeSpawnUpdateNoDelta(spu);
|
||||
}
|
||||
else {
|
||||
who->MakeSpawnUpdate(spu);
|
||||
}
|
||||
|
||||
for (auto &c : _impl->Clients) {
|
||||
if (c != who) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
else if (c->IsAIControlled()) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MobMovementManager::SendUpdateShortDistance(Mob *who, int anim, float heading)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer;
|
||||
if (anim == 0) {
|
||||
who->MakeSpawnUpdateNoDelta(spu);
|
||||
}
|
||||
else {
|
||||
who->MakeSpawnUpdate(spu);
|
||||
}
|
||||
|
||||
for (auto &c : _impl->Clients) {
|
||||
if (c != who) {
|
||||
auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ());
|
||||
if (dist <= 1000.0f) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
else if (c->IsAIControlled()) {
|
||||
auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ());
|
||||
if (dist <= 1000.0f) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MobMovementManager::SendUpdateLongDistance(Mob *who, int anim, float heading)
|
||||
{
|
||||
EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer;
|
||||
if (anim == 0) {
|
||||
who->MakeSpawnUpdateNoDelta(spu);
|
||||
}
|
||||
else {
|
||||
who->MakeSpawnUpdate(spu);
|
||||
}
|
||||
|
||||
for (auto &c : _impl->Clients) {
|
||||
if (c != who) {
|
||||
auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ());
|
||||
if (dist > 1000.0f) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
else if (c->IsAIControlled()) {
|
||||
auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ());
|
||||
if (dist > 1000.0f) {
|
||||
c->QueuePacket(&outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
zone/mob_movement_manager.h
Normal file
38
zone/mob_movement_manager.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
class Mob;
|
||||
class Client;
|
||||
|
||||
class MobMovementManager
|
||||
{
|
||||
public:
|
||||
~MobMovementManager();
|
||||
void Process();
|
||||
void AddMob(Mob *m);
|
||||
void RemoveMob(Mob *m);
|
||||
void AddClient(Client *c);
|
||||
void RemoveClient(Client *c);
|
||||
|
||||
void SendPosition(Mob *who);
|
||||
void SendPositionUpdate(Mob *who, bool send_to_self);
|
||||
|
||||
static MobMovementManager &Get() {
|
||||
static MobMovementManager inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
private:
|
||||
MobMovementManager();
|
||||
MobMovementManager(const MobMovementManager&);
|
||||
MobMovementManager& operator=(const MobMovementManager&);
|
||||
|
||||
bool HeadingEqual(float a, float b);
|
||||
void SendUpdateTo(Mob *who, Client *c, int anim, float heading);
|
||||
void SendUpdate(Mob *who, int anim, float heading);
|
||||
void SendUpdateShortDistance(Mob *who, int anim, float heading);
|
||||
void SendUpdateLongDistance(Mob *who, int anim, float heading);
|
||||
|
||||
struct Implementation;
|
||||
std::unique_ptr<Implementation> _impl;
|
||||
};
|
||||
@ -1189,7 +1189,7 @@ XS(XS_Mob_SendPosUpdate) {
|
||||
iSendToSelf = (uint8) SvUV(ST(1));
|
||||
}
|
||||
|
||||
THIS->SendPositionUpdate(iSendToSelf);
|
||||
THIS->SendPositionUpdate(iSendToSelf != 0 ? true : false);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
@ -853,7 +853,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
SetHeading(CalculateHeadingToTarget(ClosestMob->GetX(), ClosestMob->GetY()));
|
||||
SetTarget(ClosestMob);
|
||||
CastToClient()->SendTargetCommand(ClosestMob->GetID());
|
||||
SendPositionUpdate(2);
|
||||
SendPositionUpdate(true);
|
||||
}
|
||||
else
|
||||
Message_StringID(clientMessageError, SENSE_NOTHING);
|
||||
|
||||
@ -463,7 +463,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
|
||||
if (IsClient())
|
||||
#endif
|
||||
{
|
||||
animation = speed / 2;
|
||||
animation = speed * 0.55f;
|
||||
}
|
||||
|
||||
//Setup Vectors
|
||||
@ -481,7 +481,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
|
||||
}
|
||||
|
||||
double time_since_last = static_cast<double>(frame_time) / 1000.0;
|
||||
double distance_moved = time_since_last * (speed + 100.0f);
|
||||
double distance_moved = time_since_last * speed * 2.275f;
|
||||
|
||||
if (distance_moved > len) {
|
||||
m_Position.x = x;
|
||||
@ -492,6 +492,10 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
|
||||
entity_list.ProcessMove(CastToNPC(), x, y, z);
|
||||
}
|
||||
|
||||
if (check_z && fix_z_timer.Check() && (!IsEngaged() || flee_mode || currently_fleeing)) {
|
||||
FixZ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@ -505,11 +509,15 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
|
||||
}
|
||||
}
|
||||
|
||||
if (check_z && fix_z_timer.Check() && !IsEngaged()) {
|
||||
FixZ();
|
||||
}
|
||||
|
||||
SetMoving(true);
|
||||
m_Delta = glm::vec4(m_Position.x - pos.x, m_Position.y - pos.y, m_Position.z - pos.z, 0.0f);
|
||||
|
||||
if (IsClient()) {
|
||||
SendPositionUpdate(1);
|
||||
SendPositionUpdate();
|
||||
CastToClient()->ResetPositionTimer();
|
||||
}
|
||||
else {
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
#include "zone_config.h"
|
||||
#include "mob_movement_manager.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <ctime>
|
||||
@ -861,6 +862,8 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
||||
|
||||
m_ucss_available = false;
|
||||
m_last_ucss_update = 0;
|
||||
|
||||
mMovementManager = &MobMovementManager::Get();
|
||||
}
|
||||
|
||||
Zone::~Zone() {
|
||||
@ -1303,6 +1306,8 @@ bool Zone::Process() {
|
||||
|
||||
if(hotzone_timer.Check()) { UpdateHotzone(); }
|
||||
|
||||
mMovementManager->Process();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -79,6 +79,7 @@ class WaterMap;
|
||||
extern EntityList entity_list;
|
||||
struct NPCType;
|
||||
struct ServerZoneIncomingClient_Struct;
|
||||
class MobMovementManager;
|
||||
|
||||
class Zone
|
||||
{
|
||||
@ -362,6 +363,8 @@ private:
|
||||
|
||||
bool m_ucss_available;
|
||||
uint32 m_last_ucss_update;
|
||||
|
||||
MobMovementManager *mMovementManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user