mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
fix(Core/Spells): Fixed work of sobering spells and other improvements for drunk system (#18390)
* fix(Core/Spells): Fix sobering spells and possible uint8 overflow/underflow in SPELL_EFFECT_INEBRIATE handler. * fix(Core/Spells): Improvements for SPELL_AURA_MOD_FAKE_INEBRIATE handling
This commit is contained in:
@@ -957,7 +957,7 @@ void Player::HandleSobering()
|
||||
SetDrunkValue(drunk);
|
||||
}
|
||||
|
||||
DrunkenState Player::GetDrunkenstateByValue(uint8 value)
|
||||
/*static*/ DrunkenState Player::GetDrunkenstateByValue(uint8 value)
|
||||
{
|
||||
if (value >= 90)
|
||||
return DRUNKEN_SMASHED;
|
||||
@@ -970,27 +970,17 @@ DrunkenState Player::GetDrunkenstateByValue(uint8 value)
|
||||
|
||||
void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/)
|
||||
{
|
||||
bool isSobering = newDrunkValue < GetDrunkValue();
|
||||
newDrunkValue = std::min<uint8>(newDrunkValue, 100);
|
||||
if (newDrunkValue == GetDrunkValue())
|
||||
return;
|
||||
|
||||
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<int32>(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);
|
||||
|
||||
uint32 newDrunkenState = Player::GetDrunkenstateByValue(newDrunkValue);
|
||||
SetByteValue(PLAYER_BYTES_3, 1, newDrunkValue);
|
||||
UpdateObjectVisibility(false);
|
||||
|
||||
if (!isSobering)
|
||||
m_drunkTimer = 0; // reset sobering timer
|
||||
SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, newDrunkValue);
|
||||
UpdateInvisibilityDrunkDetect();
|
||||
|
||||
m_drunkTimer = 0; // reset sobering timer
|
||||
|
||||
if (newDrunkenState == oldDrunkenState)
|
||||
return;
|
||||
@@ -1003,6 +993,24 @@ 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<int32>(drunkValue, fakeDrunkValue);
|
||||
|
||||
if (maxDrunkValue != 0)
|
||||
{
|
||||
m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK);
|
||||
m_invisibilityDetect.SetValue(INVISIBILITY_DRUNK, maxDrunkValue);
|
||||
}
|
||||
else
|
||||
m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK);
|
||||
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
{
|
||||
uint32 ressSpellId = 0;
|
||||
|
||||
Reference in New Issue
Block a user