diff --git a/zone/attack.cpp b/zone/attack.cpp index 666cb19f8..a229f197e 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3693,7 +3693,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons //send an HP update if we are hurt if(GetHP() < GetMaxHP()) - SendHPUpdate(); + SendHPUpdate(!iBuffTic); // the OP_Damage actually updates the client in these cases, so we skill them } //end `if damage was done` //send damage packet... diff --git a/zone/bot.cpp b/zone/bot.cpp index e76389b24..8b3741443 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -755,7 +755,7 @@ void Bot::GenerateBaseStats() { this->Corrup = CorruptionResist; SetBotSpellID(BotSpellID); this->size = BotSize; - + this->pAggroRange = 0; this->pAssistRange = 0; this->raid_target = false; @@ -1381,18 +1381,18 @@ int32 Bot::GenerateBaseHitPoints() uint32 lm = GetClassLevelFactor(); int32 Post255; int32 NormalSTA = GetSTA(); - + if(GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->GetClientVersion() >= ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) { float SoDPost255; - + if(((NormalSTA - 255) / 2) > 0) SoDPost255 = ((NormalSTA - 255) / 2); else SoDPost255 = 0; - + int hp_factor = GetClassHPFactor(); - + if(level < 41) { new_base_hp = (5 + (GetLevel() * hp_factor / 12) + ((NormalSTA - SoDPost255) * GetLevel() * hp_factor / 3600)); @@ -1420,7 +1420,7 @@ int32 Bot::GenerateBaseHitPoints() new_base_hp = (5)+(GetLevel()*lm/10) + (((NormalSTA-Post255)*GetLevel()*lm/3000)) + ((Post255*1)*lm/6000); } this->base_hp = new_base_hp; - + return new_base_hp; } @@ -2342,7 +2342,7 @@ bool Bot::IsBotNameAvailable(char *botName, std::string* errorMessage) { if (results.RowCount()) { //Name already in use! return false; } - + return true; //We made it with a valid name! } @@ -2901,7 +2901,7 @@ bool Bot::Process() SetEndurance(GetEndurance() + CalcEnduranceRegen() + RestRegenEndurance); } - if (sendhpupdate_timer.Check()) { + if (sendhpupdate_timer.Check(false)) { SendHPUpdate(); if(HasPet()) @@ -5894,7 +5894,7 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, SkillUseTypes att // delete from group data RemoveBotFromGroup(this, g); - + //Make sure group still exists if it doesnt they were already updated in RemoveBotFromGroup g = GetGroup(); if (!g) @@ -5912,7 +5912,7 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, SkillUseTypes att g->members[j] = nullptr; } } - + // update the client group EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer; @@ -10823,7 +10823,7 @@ void Bot::CalcItemBonuses(StatBonuses* newbon) AddItemBonuses(item, newbon); } } - + // Caps if(newbon->HPRegen > CalcHPRegenCap()) newbon->HPRegen = CalcHPRegenCap(); diff --git a/zone/client.cpp b/zone/client.cpp index 7471a6a62..bdcbbbf68 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -116,7 +116,7 @@ Client::Client(EQStreamInterface* ieqs) ), //these must be listed in the order they appear in client.h position_timer(250), - hpupdate_timer(1800), + hpupdate_timer(2000), camp_timer(29000), process_timer(100), stamina_timer(40000), @@ -8631,4 +8631,4 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold, QueuePacket(outapp, false, Client::CLIENT_CONNECTED); safe_delete(outapp); -} \ No newline at end of file +} diff --git a/zone/client.h b/zone/client.h index 73bde1a69..2015a52ba 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1257,6 +1257,8 @@ public: int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false); void QuestReward(Mob* target, uint32 copper = 0, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0, uint32 itemid = 0, uint32 exp = 0, bool faction = false); + + void ResetHPUpdateTimer() { hpupdate_timer.Start(); } protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 42681340b..be2e1321f 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -129,7 +129,9 @@ bool Client::Process() { if(IsTracking() && (GetClientVersion() >= ClientVersion::SoD) && TrackingTimer.Check()) DoTracking(); - if(hpupdate_timer.Check()) + // SendHPUpdate calls hpupdate_timer.Start so it can delay this timer, so lets not reset with the check + // since the function will anyways + if(hpupdate_timer.Check(false)) SendHPUpdate(); if(mana_timer.Check()) diff --git a/zone/mob.cpp b/zone/mob.cpp index 8a224db0b..1591cc057 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1266,7 +1266,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app) } // sends hp update of this mob to people who might care -void Mob::SendHPUpdate() +void Mob::SendHPUpdate(bool skip_self) { EQApplicationPacket hp_app; Group *group; @@ -1355,8 +1355,7 @@ void Mob::SendHPUpdate() } // send to self - we need the actual hps here - if(IsClient()) - { + if(IsClient() && !skip_self) { EQApplicationPacket* hp_app2 = new EQApplicationPacket(OP_HPUpdate,sizeof(SpawnHPUpdate_Struct)); SpawnHPUpdate_Struct* ds = (SpawnHPUpdate_Struct*)hp_app2->pBuffer; ds->cur_hp = CastToClient()->GetHP() - itembonuses.HP; @@ -1365,6 +1364,7 @@ void Mob::SendHPUpdate() CastToClient()->QueuePacket(hp_app2); safe_delete(hp_app2); } + ResetHPUpdateTimer(); // delay the timer } // this one just warps the mob to the current location @@ -4205,25 +4205,25 @@ int32 Mob::GetItemStat(uint32 itemid, const char *identifier) std::string Mob::GetGlobal(const char *varname) { int qgCharid = 0; int qgNpcid = 0; - + if (this->IsNPC()) qgNpcid = this->GetNPCTypeID(); - + if (this->IsClient()) qgCharid = this->CastToClient()->CharacterID(); - + QGlobalCache *qglobals = nullptr; std::list globalMap; - + if (this->IsClient()) qglobals = this->CastToClient()->GetQGlobals(); - + if (this->IsNPC()) qglobals = this->CastToNPC()->GetQGlobals(); if(qglobals) QGlobalCache::Combine(globalMap, qglobals->GetBucket(), qgNpcid, qgCharid, zone->GetZoneID()); - + std::list::iterator iter = globalMap.begin(); while(iter != globalMap.end()) { if ((*iter).name.compare(varname) == 0) @@ -4231,7 +4231,7 @@ std::string Mob::GetGlobal(const char *varname) { ++iter; } - + return "Undefined"; } diff --git a/zone/mob.h b/zone/mob.h index 74a53346e..ded9c04dc 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -508,7 +508,8 @@ public: static void CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); void CreateHPPacket(EQApplicationPacket* app); - void SendHPUpdate(); + void SendHPUpdate(bool skip_self = false); + virtual void ResetHPUpdateTimer() {}; // does nothing //Util static uint32 RandomTimer(int min, int max); diff --git a/zone/npc.cpp b/zone/npc.cpp index 0ece7ab6c..d4a33b6d0 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -115,7 +115,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if knightattack_timer(1000), assist_timer(AIassistcheck_delay), qglobal_purge_timer(30000), - sendhpupdate_timer(1000), + sendhpupdate_timer(2000), enraged_timer(1000), taunt_timer(TauntReuseTime * 1000), m_SpawnPoint(position), @@ -650,7 +650,8 @@ bool NPC::Process() } } - if (sendhpupdate_timer.Check() && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) { + // we might actually want to reset in this check ... won't until issues arise at least :P + if (sendhpupdate_timer.Check(false) && (IsTargeted() || (IsPet() && GetOwner() && GetOwner()->IsClient()))) { if(!IsFullHP || cur_hp