From 89deb60d43cb4aa1c51214db9ad423b65f94f522 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sat, 12 Feb 2022 15:51:27 +0100 Subject: [PATCH] fix(Core/Spells): Flasks should not be overridden by elixirs. (#10301) * fix(Core/Spells): Flasks should not be overridden by elixirs. --- src/server/game/Entities/Player/Player.cpp | 8 ++++ src/server/game/Spells/SpellInfo.cpp | 47 ++++++++++++++++++++++ src/server/game/Spells/SpellInfo.h | 2 + src/server/game/Spells/SpellMgr.h | 9 ++++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5a535413c..1bc0833cf 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7279,7 +7279,15 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 } if (HasSpellCooldown(spellInfo->Id)) + { continue; + } + + if (!spellInfo->CheckElixirStacking(this)) + { + Spell::SendCastResult(this, spellInfo, cast_count, SPELL_FAILED_AURA_BOUNCED); + continue; + } Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE); spell->m_CastItem = item; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 05a97eed7..e251e8207 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -2844,3 +2844,50 @@ void SpellInfo::_UnloadImplicitTargetConditionLists() delete cur; } } + +bool SpellInfo::CheckElixirStacking(Unit const* caster) const +{ + if (!caster) + { + return true; + } + + // xinef: check spell group + uint32 groupId = sSpellMgr->GetSpellGroup(Id); + if (groupId != SPELL_GROUP_GUARDIAN_AND_BATTLE_ELIXIRS) + { + return true; + } + + SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(Id); + for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!Effects[i].IsAura()) + { + continue; + } + + Unit::AuraApplicationMap const& Auras = caster->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = Auras.begin(); itr != Auras.end(); ++itr) + { + // xinef: aura is not groupped or in different group + uint32 auraGroup = sSpellMgr->GetSpellGroup(itr->first); + if (auraGroup != groupId) + { + continue; + } + + // Cannot apply guardian/battle elixir if flask is present + if (sFlag == SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE || sFlag == SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN) + { + SpellGroupSpecialFlags sAuraFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->first); + if ((sAuraFlag & SPELL_GROUP_SPECIAL_FLAG_FLASK) == SPELL_GROUP_SPECIAL_FLAG_FLASK) + { + return false; + } + } + } + } + + return true; +} diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 7f85461e4..4dfcef8ac 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -535,6 +535,8 @@ public: // unloading helpers void _UnloadImplicitTargetConditionLists(); + bool CheckElixirStacking(Unit const* caster) const; + private: std::array& _GetEffects() { return Effects; } SpellEffectInfo& _GetEffect(SpellEffIndex index) { ASSERT(index < Effects.size()); return Effects[index]; } diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 49e521a6a..52201a013 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -340,7 +340,9 @@ enum SpellGroupSpecialFlags SPELL_GROUP_SPECIAL_FLAG_PRIORITY4 = 0x800, SPELL_GROUP_SPECIAL_FLAG_SAME_SPELL_CHECK = 0x1000, SPELL_GROUP_SPECIAL_FLAG_SKIP_STRONGER_SAME_SPELL = 0x2000, - SPELL_GROUP_SPECIAL_FLAG_MAX = 0x4000 + SPELL_GROUP_SPECIAL_FLAG_MAX = 0x4000, + + SPELL_GROUP_SPECIAL_FLAG_FLASK = SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE | SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN }; enum SpellGroupStackFlags @@ -358,6 +360,11 @@ enum SpellGroupStackFlags SPELL_GROUP_STACK_FLAG_FORCED_WEAKEST = 0x200, }; +enum SpellGroupIDs +{ + SPELL_GROUP_GUARDIAN_AND_BATTLE_ELIXIRS = 1 +}; + struct SpellStackInfo { uint32 groupId;