[Position Updates] Bulk updates when player has moved far enough - eliminates client ghosting on rez/gates/summon as well as npc ghosting

This commit is contained in:
Akkadius 2017-08-22 02:13:56 -05:00
parent bb2d8f6a4d
commit 808654743c
5 changed files with 33 additions and 5 deletions

View File

@ -564,6 +564,7 @@ RULE_INT(Range, SpellMessages, 75)
RULE_INT(Range, SongMessages, 75)
RULE_INT(Range, MobPositionUpdates, 600)
RULE_INT(Range, ClientPositionUpdates, 300)
RULE_INT(Range, ClientForceSpawnUpdateRange, 1000)
RULE_INT(Range, CriticalDamage, 80)
RULE_INT(Range, ClientNPCScan, 300)
RULE_CATEGORY_END()

View File

@ -1489,7 +1489,9 @@ private:
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::vec3 m_Proximity;
glm::vec4 last_major_update_position;
void BulkSendInventoryItems();

View File

@ -243,15 +243,21 @@ bool Client::Process() {
/* Build a close range list of NPC's */
if (npc_close_scan_timer.Check()) {
close_mobs.clear();
auto &mob_list = entity_list.GetMobList();
float scan_range = (RuleI(Range, ClientNPCScan) * RuleI(Range, ClientNPCScan));
float client_update_range = (RuleI(Range, MobPositionUpdates) * RuleI(Range, MobPositionUpdates));
/* 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) {
@ -261,6 +267,10 @@ bool Client::Process() {
close_mobs.insert(std::pair<Mob *, float>(mob, distance));
}
}
if (force_spawn_updates && mob != this && distance <= client_update_range)
mob->SendPositionUpdateToClient(this);
}
}

View File

@ -1455,6 +1455,20 @@ void Mob::SendPosition() {
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);
}
/* Position updates for mobs on the move */
void Mob::SendPositionUpdate(uint8 iSendToSelf) {
auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));

View File

@ -543,6 +543,7 @@ public:
virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true);
void SetDelta(const glm::vec4& delta);
void SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; }
void SendPositionUpdateToClient(Client *client);
void SendPositionUpdate(uint8 iSendToSelf = 0);
void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu);
void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu);