diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c68f2edf32cd7..8bdbf14311798 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -959,7 +959,7 @@ void Player::HandleSobering() SetDrunkValue(drunk); } -DrunkenState Player::GetDrunkenstateByValue(uint8 value) +/*static*/ DrunkenState Player::GetDrunkenstateByValue(uint8 value) { if (value >= 90) return DRUNKEN_SMASHED; @@ -972,27 +972,17 @@ DrunkenState Player::GetDrunkenstateByValue(uint8 value) void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/) { - bool isSobering = newDrunkValue < GetDrunkValue(); - uint32 oldDrunkenState = Player::GetDrunkenstateByValue(GetDrunkValue()); - if (newDrunkValue > 100) - newDrunkValue = 100; - - // select drunk percent or total SPELL_AURA_MOD_FAKE_INEBRIATE amount, whichever is higher for visibility updates - int32 drunkPercent = std::max(newDrunkValue, GetTotalAuraModifier(SPELL_AURA_MOD_FAKE_INEBRIATE)); - if (drunkPercent) - { - m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK); - m_invisibilityDetect.SetValue(INVISIBILITY_DRUNK, drunkPercent); - } - else if (!HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE) && !newDrunkValue) - m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK); + newDrunkValue = std::min(newDrunkValue, 100); + if (newDrunkValue == GetDrunkValue()) + return; + uint32 oldDrunkenState = Player::GetDrunkenstateByValue(GetDrunkValue()); uint32 newDrunkenState = Player::GetDrunkenstateByValue(newDrunkValue); + SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, newDrunkValue); - UpdateObjectVisibility(); + UpdateInvisibilityDrunkDetect(); - if (!isSobering) - m_drunkTimer = 0; // reset sobering timer + m_drunkTimer = 0; // reset sobering timer if (newDrunkenState == oldDrunkenState) return; @@ -1005,6 +995,25 @@ void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/) SendMessageToSet(data.Write(), true); } +void Player::UpdateInvisibilityDrunkDetect() +{ + // select drunk percent or total SPELL_AURA_MOD_FAKE_INEBRIATE amount, whichever is higher for visibility updates + uint8 drunkValue = GetDrunkValue(); + int32 fakeDrunkValue = GetFakeDrunkValue(); + int32 maxDrunkValue = std::max(drunkValue, fakeDrunkValue); + + if (maxDrunkValue != 0) + { + m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK); + m_invisibilityDetect.SetValue(INVISIBILITY_DRUNK, maxDrunkValue); + } + else + m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK); + + if (IsInWorld()) + UpdateObjectVisibility(); +} + void Player::Update(uint32 p_time) { if (!IsInWorld()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 3d5f7fd4361a7..870eb868da705 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1815,6 +1815,8 @@ class TC_GAME_API Player : public Unit, public GridObject void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0); uint8 GetDrunkValue() const { return GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION); } + int32 GetFakeDrunkValue() const { return GetInt32Value(PLAYER_FAKE_INEBRIATION); } + void UpdateInvisibilityDrunkDetect(); static DrunkenState GetDrunkenstateByValue(uint8 value); uint32 GetDeathTimer() const { return m_deathTimer; } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b7372fdb23b4f..a40e18f013133 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -363,7 +363,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb &AuraEffect::HandleUnused, //302 0 spells in 3.3.5 &AuraEffect::HandleNoImmediateEffect, //303 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus - &AuraEffect::HandleAuraModFakeInebriation, //304 SPELL_AURA_MOD_DRUNK + &AuraEffect::HandleAuraModFakeInebriation, //304 SPELL_AURA_MOD_FAKE_INEBRIATE &AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED &AuraEffect::HandleUnused, //306 0 spells in 3.3.5 &AuraEffect::HandleUnused, //307 0 spells in 3.3.5 @@ -4927,41 +4927,12 @@ void AuraEffect::HandleAuraModFakeInebriation(AuraApplication const* aurApp, uin if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)) return; - Unit* target = aurApp->GetTarget(); - - if (apply) - { - target->m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK); - target->m_invisibilityDetect.AddValue(INVISIBILITY_DRUNK, GetAmount()); - - if (target->GetTypeId() == TYPEID_PLAYER) - { - int32 oldval = target->ToPlayer()->GetInt32Value(PLAYER_FAKE_INEBRIATION); - target->ToPlayer()->SetInt32Value(PLAYER_FAKE_INEBRIATION, oldval + GetAmount()); - } - } - else - { - bool removeDetect = !target->HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE); - - target->m_invisibilityDetect.AddValue(INVISIBILITY_DRUNK, -GetAmount()); - - if (target->GetTypeId() == TYPEID_PLAYER) - { - int32 oldval = target->ToPlayer()->GetInt32Value(PLAYER_FAKE_INEBRIATION); - target->ToPlayer()->SetInt32Value(PLAYER_FAKE_INEBRIATION, oldval - GetAmount()); - - if (removeDetect) - removeDetect = !target->ToPlayer()->GetDrunkValue(); - } - - if (removeDetect) - target->m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK); - } + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) + return; - // call functions which may have additional effects after changing state of unit - if (target->IsInWorld()) - target->UpdateObjectVisibility(); + target->ApplyModInt32Value(PLAYER_FAKE_INEBRIATION, GetAmount(), apply); + target->UpdateInvisibilityDrunkDetect(); } void AuraEffect::HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 mode, bool apply) const