From 8fa76b91542fe8617a05cc29b548b3220a4218e2 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Aug 2019 03:27:33 -0500 Subject: [PATCH] Optimizations to movement updates to eliminate ghosting possibilities in larger zones --- changelog.txt | 3 +++ zone/client.cpp | 1 + zone/client.h | 1 + zone/client_packet.cpp | 35 +++++++++++++++++++++++++++++++---- zone/client_process.cpp | 5 +++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6b9d00a80..3f69bf570 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 8/6/2019 == +Akkadius: Optimizations to movement updates to eliminate ghosting possibilities in larger zones + == 7/22/2019 == Uleat: Added script 'vcxproj_dependencies.py' - a script to help determine conflicting project dependencies (alpha-stage) diff --git a/zone/client.cpp b/zone/client.cpp index 57f6ba865..ac696247a 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -136,6 +136,7 @@ Client::Client(EQStreamInterface* ieqs) forget_timer(0), autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000), client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000), + client_zone_wide_full_position_update_timer(5 * 60 * 1000), tribute_timer(Tribute_duration), proximity_timer(ClientProximity_interval), TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000), diff --git a/zone/client.h b/zone/client.h index 0272fb21b..7b37c2b47 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1517,6 +1517,7 @@ private: Timer forget_timer; // our 2 min everybody forgets you timer Timer autosave_timer; Timer client_scan_npc_aggro_timer; + Timer client_zone_wide_full_position_update_timer; Timer tribute_timer; Timer proximity_timer; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f0eb00d13..2dc5cdbf9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -60,6 +60,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "water_map.h" #include "worldserver.h" #include "zone.h" +#include "mob_movement_manager.h" #ifdef BOTS #include "bot.h" @@ -4466,16 +4467,16 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { /* Handle client aggro scanning timers NPCs */ is_client_moving = (ppu->y_pos == m_Position.y && ppu->x_pos == m_Position.x) ? false : true; - + if (is_client_moving) { 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) { client_scan_npc_aggro_timer.Disable(); client_scan_npc_aggro_timer.Start(500); - } - } else { + } + else { 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) { @@ -4483,7 +4484,33 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { client_scan_npc_aggro_timer.Start(3000); } } - + + /** + * On a normal basis we limit mob movement updates based on distance + * This ensures we send a periodic full zone update to a client that has started + * moving after 5 or so minutes + */ + if (is_client_moving && client_zone_wide_full_position_update_timer.Check()) { + Log(Logs::Detail, Logs::Normal, "[%s] Client Zone Wide Position Update NPCs", GetCleanName()); + + auto &mob_movement_manager = MobMovementManager::Get(); + auto &mob_list = entity_list.GetMobList(); + + for (auto &it : mob_list) { + Mob *entity = it.second; + if (!entity->IsNPC()) { + continue; + } + + float distance_from_client_to_ignore = zone->GetMaxMovementUpdateRange() - 100; + if (CalculateDistance(entity->GetX(), entity->GetY(), entity->GetZ()) <= distance_from_client_to_ignore) { + continue; + } + + mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, this); + } + } + float new_heading = EQ12toFloat(ppu->heading); int32 new_animation = ppu->animation; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 5c750f03a..244f36580 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -592,8 +592,8 @@ bool Client::Process() { // only if client is not feigned if (zone->CanDoCombat() && ret && !GetFeigned() && client_scan_npc_aggro_timer.Check()) { int npc_scan_count = 0; - for (auto it = close_mobs.begin(); it != close_mobs.end(); ++it) { - Mob *mob = it->first; + for (auto & close_mob : close_mobs) { + Mob *mob = close_mob.first; if (!mob) continue; @@ -604,6 +604,7 @@ bool Client::Process() { if (mob->CheckWillAggro(this) && !mob->CheckAggro(this)) { mob->AddToHateList(this, 25); } + npc_scan_count++; } Log(Logs::General, Logs::Aggro, "Checking Reverse Aggro (client->npc) scanned_npcs (%i)", npc_scan_count);