From f395ee05088857fb3bcba5b62693b30cc22a3d16 Mon Sep 17 00:00:00 2001 From: Clayton Dunwell Date: Tue, 19 Sep 2023 10:16:12 -0400 Subject: [PATCH] [Bug Fix] Invis vs. Undead/Animal Breaks Charm for Pets (#3587) * IVU & IVA break charm pets #2212 * fix typing * fix tab spacing * Formatting * Formatting for CalcInvisibleLevel --------- Co-authored-by: Akkadius --- zone/mob.cpp | 70 ++++++++++++++++++++++++++-------------------------- zone/mob.h | 2 ++ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index 7884d4255..09cdee6b9 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -593,42 +593,49 @@ void Mob::CalcSeeInvisibleLevel() see_invis = std::max({ spellbonuses.SeeInvis, itembonuses.SeeInvis, aabonuses.SeeInvis, innate_see_invis }); } -void Mob::CalcInvisibleLevel() -{ - bool is_invisible = invisible; +bool Mob::HasAnInvisibilityEffect() { + return invisible || hidden || improved_hidden || invisible_animals || invisible_undead; +} - invisible = std::max({ spellbonuses.invisibility, nobuff_invisible }); - invisible_undead = spellbonuses.invisibility_verse_undead; - invisible_animals = spellbonuses.invisibility_verse_animal; - - if (!is_invisible && invisible) { - SetInvisible(Invisibility::Invisible, true); - return; - } - - if (is_invisible && !invisible) { - SetInvisible(invisible, true); - return; +void Mob::BreakCharmPetIfConditionsMet() { + auto pet = GetPet(); + if (pet && pet->GetPetType() == petCharmed && HasAnInvisibilityEffect()) { + if (RuleB(Pets, LivelikeBreakCharmOnInvis) || IsInvisible(pet)) { + pet->BuffFadeByEffect(SE_Charm); + } + LogRules( + "Pets:LivelikeBreakCharmOnInvis for [{}] invisible [{}] hidden [{}] improved_hidden (shroud of stealth) [{}] invisible_animals [{}] invisible_undead [{}]", + GetCleanName(), + invisible, + hidden, + improved_hidden, + invisible_animals, + invisible_undead + ); } } -void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc) +void Mob::CalcInvisibleLevel() { - /* - If you set an NPC to invisible you will only be able to see it on - your client if your see invisible level is greater than equal to the invisible level. - Note, the clients spell file must match the servers see invisible level on the spell. - */ + bool was_invisible = invisible; + invisible = std::max({spellbonuses.invisibility, nobuff_invisible}); + invisible_undead = spellbonuses.invisibility_verse_undead; + invisible_animals = spellbonuses.invisibility_verse_animal; + + if (was_invisible != invisible) { + SetInvisible(invisible, true); + return; + } + + BreakCharmPetIfConditionsMet(); +} + +void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc) { if (state == Invisibility::Visible) { SendAppearancePacket(AT_Invis, Invisibility::Visible); ZeroInvisibleVars(InvisType::T_INVISIBLE); - } - else { - /* - if your setting invisible from a script, or escape/fading memories effect then - we use the internal invis variable which allows invisible without a buff on mob. - */ + } else { if (!set_on_bonus_calc) { nobuff_invisible = state; CalcInvisibleLevel(); @@ -636,14 +643,7 @@ void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc) SendAppearancePacket(AT_Invis, invisible); } - // Invis and hide breaks charms - auto pet = GetPet(); - if (pet && pet->GetPetType() == petCharmed && (invisible || hidden || improved_hidden || invisible_animals || invisible_undead)) { - if (RuleB(Pets, LivelikeBreakCharmOnInvis) || IsInvisible(pet)) { - pet->BuffFadeByEffect(SE_Charm); - } - LogRules("Pets:LivelikeBreakCharmOnInvis for [{}] | Invis [{}] - Hidden [{}] - Shroud of Stealth [{}] - IVA [{}] - IVU [{}]", GetCleanName(), invisible, hidden, improved_hidden, invisible_animals, invisible_undead); - } + BreakCharmPetIfConditionsMet(); } void Mob::ZeroInvisibleVars(uint8 invisible_type) diff --git a/zone/mob.h b/zone/mob.h index c18a8eec5..bcd989049 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -269,6 +269,8 @@ public: return; } + bool HasAnInvisibilityEffect(); + void BreakCharmPetIfConditionsMet(); //Invisible bool IsInvisible(Mob* other = 0) const; void SetInvisible(uint8 state, bool set_on_bonus_calc = false);