From 5c75a68715edc6e242b2b5dc02f8c4c49e1cdd0b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 14 Jul 2017 14:23:35 -0500 Subject: [PATCH] HP Update tuning - HP Updates are now forced when a client is targeted --- zone/client.cpp | 4 ++-- zone/client.h | 4 ++-- zone/mob.cpp | 62 ++++++++++++++++++++++++++++--------------------- zone/mob.h | 2 +- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 0bcbb4ec2..bc784d415 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -119,7 +119,6 @@ Client::Client(EQStreamInterface* ieqs) 0, 0 ), - //these must be listed in the order they appear in client.h position_timer(250), hpupdate_timer(2000), camp_timer(29000), @@ -159,7 +158,8 @@ Client::Client(EQStreamInterface* ieqs) last_region_type(RegionTypeUnsupported), m_dirtyautohaters(false), npc_close_scan_timer(6000), - hp_self_update_throttle_timer(500) + hp_self_update_throttle_timer(300), + hp_other_update_throttle_timer(500) { for(int cf=0; cf < _FilterCount; cf++) diff --git a/zone/client.h b/zone/client.h index ff617f009..d88769ee1 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1485,8 +1485,8 @@ private: Timer helm_toggle_timer; Timer aggro_meter_timer; Timer npc_close_scan_timer; - Timer hp_self_update_throttle_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 */ glm::vec3 m_Proximity; void BulkSendInventoryItems(); diff --git a/zone/mob.cpp b/zone/mob.cpp index 68f55626b..0a4a84746 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1302,49 +1302,50 @@ void Mob::CreateHPPacket(EQApplicationPacket* app) } // sends hp update of this mob to people who might care -void Mob::SendHPUpdate(bool skip_self) +void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/) { /* If our HP is different from last HP update call - let's update ourself */ - if (IsClient() && cur_hp != last_hp) { - /* This is to prevent excessive packet sending under trains/fast combat */ - if (this->CastToClient()->hp_self_update_throttle_timer.Check()) { - Log(Logs::General, Logs::HP_Update, - "Mob::SendHPUpdate :: Update HP of self (%s) HP: %i last: %i skip_self: %s", - this->GetCleanName(), - cur_hp, - last_hp, - (skip_self ? "true" : "false") - ); + if (IsClient()) { + if (cur_hp != last_hp || force_update_all) { + /* This is to prevent excessive packet sending under trains/fast combat */ + if (this->CastToClient()->hp_self_update_throttle_timer.Check() || force_update_all) { + Log(Logs::General, Logs::HP_Update, + "Mob::SendHPUpdate :: Update HP of self (%s) HP: %i last: %i skip_self: %s", + this->GetCleanName(), + cur_hp, + last_hp, + (skip_self ? "true" : "false") + ); - if (!skip_self || this->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::UF) { - auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); - SpawnHPUpdate_Struct* hp_packet_client = (SpawnHPUpdate_Struct*)client_packet->pBuffer; + if (!skip_self || this->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) { + auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); + SpawnHPUpdate_Struct* hp_packet_client = (SpawnHPUpdate_Struct*)client_packet->pBuffer; - hp_packet_client->cur_hp = CastToClient()->GetHP() - itembonuses.HP; - hp_packet_client->spawn_id = GetID(); - hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; + hp_packet_client->cur_hp = CastToClient()->GetHP() - itembonuses.HP; + hp_packet_client->spawn_id = GetID(); + hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; - CastToClient()->QueuePacket(client_packet); + CastToClient()->QueuePacket(client_packet); - safe_delete(client_packet); + safe_delete(client_packet); - ResetHPUpdateTimer(); + ResetHPUpdateTimer(); + } + + /* Used to check if HP has changed to update self next round */ + last_hp = cur_hp; } } } - /* Used to check if HP has changed to update self next round */ - last_hp = cur_hp; - int8 current_hp_percent = (max_hp == 0 ? 0 : static_cast(cur_hp * 100 / max_hp)); Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: SendHPUpdate %s HP is %i last %i", this->GetCleanName(), current_hp_percent, last_hp_percent); - if (current_hp_percent == last_hp_percent) { + if (current_hp_percent == last_hp_percent && !force_update_all) { Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: Same HP - skipping update"); ResetHPUpdateTimer(); - return; } else { @@ -1362,7 +1363,7 @@ void Mob::SendHPUpdate(bool skip_self) CreateHPPacket(&hp_packet); - /* Update those who have use targeted */ + /* Update those who have us targeted */ entity_list.QueueClientsByTarget(this, &hp_packet, false, 0, false, true, EQEmu::versions::bit_AllClients); /* Update those who have us on x-target */ @@ -3407,9 +3408,13 @@ int Mob::GetHaste() } void Mob::SetTarget(Mob* mob) { - if (target == mob) return; + + if (target == mob) + return; + target = mob; entity_list.UpdateHoTT(this); + if(IsNPC()) parse->EventNPC(EVENT_TARGET_CHANGE, CastToNPC(), mob, "", 0); else if (IsClient()) @@ -3417,6 +3422,9 @@ void Mob::SetTarget(Mob* mob) { if(IsPet() && GetOwner() && GetOwner()->IsClient()) GetOwner()->CastToClient()->UpdateXTargetType(MyPetTarget, mob); + + if (this->IsClient() && this->GetTarget() && this->CastToClient()->hp_other_update_throttle_timer.Check()) + this->GetTarget()->SendHPUpdate(false, true); } float Mob::FindGroundZ(float new_x, float new_y, float z_offset) diff --git a/zone/mob.h b/zone/mob.h index 5292aff00..319a28649 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -583,7 +583,7 @@ public: static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); void CreateHPPacket(EQApplicationPacket* app); - void SendHPUpdate(bool skip_self = false); + void SendHPUpdate(bool skip_self = false, bool force_update_all = false); virtual void ResetHPUpdateTimer() {}; // does nothing //Util