From 3c3c84b736cfabcf53cfc234a3114cac97a181f4 Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Wed, 9 Oct 2024 00:25:13 -0400 Subject: [PATCH] Core/Players: Fixed spells being unintentionally removed by talent swaps when they are learned from more than one spell (affects balance druid Celesial Alignment and Incarnation) Port From (https://github.com/TrinityCore/TrinityCore/commit/2c6ddcce3d6374a82214bb0ddb9d7432351982c9) --- Source/Game/Entities/Player/Player.Spells.cs | 12 ++++++++++++ Source/Game/Spells/Spell.cs | 1 + Source/Game/Spells/SpellManager.cs | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index 368eefe95..0f009b2f8 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -2331,6 +2331,18 @@ namespace Game.Entities foreach (var spellNode in spell_bounds) { + bool hasOtherSpellTeachingThis = Global.SpellMgr.GetSpellLearnedBySpellMapBounds(spellNode.Spell).Any(learnNode => + { + if (learnNode.SourceSpell == spellId) + return false; + if (!learnNode.Active) + return false; + return HasSpell(learnNode.SourceSpell); + }); + + if (hasOtherSpellTeachingThis) + continue; + RemoveSpell(spellNode.Spell, disabled); if (spellNode.OverridesSpell != 0) RemoveOverrideSpell(spellNode.OverridesSpell, spellNode.Spell); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 1ed053151..1c2a9d7a7 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -8708,6 +8708,7 @@ namespace Game.Spells public class SpellLearnSpellNode { + public uint SourceSpell; public uint Spell; public uint OverridesSpell; public bool Active; // show in spellbook or not diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index ddc336146..1424a276f 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -289,6 +289,11 @@ namespace Game.Entities return false; } + public List GetSpellLearnedBySpellMapBounds(uint learnedSpellId) + { + return mSpellLearnedBySpells.LookupByKey(learnedSpellId); + } + public SpellTargetPosition GetSpellTargetPosition(uint spell_id, uint effIndex) { return mSpellTargetPositions.LookupByKey(new KeyValuePair(spell_id, effIndex)); @@ -849,6 +854,7 @@ namespace Game.Entities { uint oldMSTime = Time.GetMSTime(); + mSpellLearnedBySpells.Clear(); mSpellLearnSpells.Clear(); // 0 1 2 @@ -864,6 +870,7 @@ namespace Game.Entities uint spell_id = result.Read(0); var node = new SpellLearnSpellNode(); + node.SourceSpell = spell_id; node.Spell = result.Read(1); node.OverridesSpell = 0; node.Active = result.Read(2); @@ -904,6 +911,7 @@ namespace Game.Entities if (spellEffectInfo.Effect == SpellEffectName.LearnSpell) { var dbc_node = new SpellLearnSpellNode(); + dbc_node.SourceSpell = entry.Id; dbc_node.Spell = spellEffectInfo.TriggerSpell; dbc_node.Active = true; // all dbc based learned spells is active (show in spell book or hide by client itself) dbc_node.OverridesSpell = 0; @@ -976,6 +984,7 @@ namespace Game.Entities continue; SpellLearnSpellNode dbcLearnNode = new(); + dbcLearnNode.SourceSpell = spellLearnSpell.SpellID; dbcLearnNode.Spell = spellLearnSpell.LearnSpellID; dbcLearnNode.OverridesSpell = spellLearnSpell.OverridesSpellID; dbcLearnNode.Active = true; @@ -985,6 +994,9 @@ namespace Game.Entities ++dbc_count; } + foreach (var (_, learnedSpellNode) in mSpellLearnSpells) + mSpellLearnedBySpells.Add(learnedSpellNode.Spell, learnedSpellNode); + Log.outInfo(LogFilter.ServerLoading, "Loaded {0} spell learn spells, {1} found in Spell.dbc in {2} ms", count, dbc_count, Time.GetMSTimeDiffToNow(oldMSTime)); } @@ -2222,7 +2234,7 @@ namespace Game.Entities case AuraType.AddPctModifierBySpellLabel: case AuraType.AddFlatModifierBySpellLabel: Cypher.Assert(effect.EffectMiscValue[0] < (int)SpellModOp.Max, $"MAX_SPELLMOD must be at least {effect.EffectMiscValue[0] + 1}"); - if (effect.EffectMiscValue[0] >= (int)SpellModOp.Max) + if (effect.EffectMiscValue[0] >= (int)SpellModOp.Max) Log.outError(LogFilter.ServerLoading, $"Invalid spell modifier type {effect.EffectMiscValue[0]} found on spell {effect.SpellID} effect index {effect.EffectIndex}, consider increasing MAX_SPELLMOD"); break; default: @@ -4903,6 +4915,7 @@ namespace Game.Entities MultiMap mSpellReq = new(); Dictionary mSpellLearnSkills = new(); MultiMap mSpellLearnSpells = new(); + MultiMap mSpellLearnedBySpells = new(); Dictionary, SpellTargetPosition> mSpellTargetPositions = new(); MultiMap mSpellSpellGroup = new(); MultiMap mSpellGroupSpell = new();