Core/Spell: fixed SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT to actually check effects

Port From (https://github.com/TrinityCore/TrinityCore/commit/52e00746cf4a8f1b5455210dfe1baed0f342f2c4)
This commit is contained in:
hondacrx
2020-05-12 23:38:57 -04:00
parent a528aed6fe
commit d8104a0032
2 changed files with 132 additions and 27 deletions
+2 -2
View File
@@ -4366,7 +4366,7 @@ namespace Game.Entities
{ {
// Check if the Aura Effect has a the Same Effect Stack Rule and if so, use the highest amount of that SpellGroup // Check if the Aura Effect has a the Same Effect Stack Rule and if so, use the highest amount of that SpellGroup
// If the Aura Effect does not have this Stack Rule, it returns false so we can add to the multiplier as usual // If the Aura Effect does not have this Stack Rule, it returns false so we can add to the multiplier as usual
if (!Global.SpellMgr.AddSameEffectStackRuleSpellGroups(aurEff.GetSpellInfo(), aurEff.GetAmount(), sameEffectSpellGroup)) if (!Global.SpellMgr.AddSameEffectStackRuleSpellGroups(aurEff.GetSpellInfo(), auratype, aurEff.GetAmount(), sameEffectSpellGroup))
modifier += aurEff.GetAmount(); modifier += aurEff.GetAmount();
} }
} }
@@ -4398,7 +4398,7 @@ namespace Game.Entities
{ {
// Check if the Aura Effect has a the Same Effect Stack Rule and if so, use the highest amount of that SpellGroup // Check if the Aura Effect has a the Same Effect Stack Rule and if so, use the highest amount of that SpellGroup
// If the Aura Effect does not have this Stack Rule, it returns false so we can add to the multiplier as usual // If the Aura Effect does not have this Stack Rule, it returns false so we can add to the multiplier as usual
if (!Global.SpellMgr.AddSameEffectStackRuleSpellGroups(aurEff.GetSpellInfo(), aurEff.GetAmount(), sameEffectSpellGroup)) if (!Global.SpellMgr.AddSameEffectStackRuleSpellGroups(aurEff.GetSpellInfo(), auratype, aurEff.GetAmount(), sameEffectSpellGroup))
MathFunctions.AddPct(ref multiplier, aurEff.GetAmount()); MathFunctions.AddPct(ref multiplier, aurEff.GetAmount());
} }
} }
+121 -16
View File
@@ -360,20 +360,22 @@ namespace Game.Entities
} }
} }
public bool AddSameEffectStackRuleSpellGroups(SpellInfo spellInfo, int amount, Dictionary<SpellGroup, int> groups) public bool AddSameEffectStackRuleSpellGroups(SpellInfo spellInfo, AuraType auraType, int amount, Dictionary<SpellGroup, int> groups)
{ {
uint spellId = spellInfo.GetFirstRankSpell().Id; uint spellId = spellInfo.GetFirstRankSpell().Id;
var spellGroup = GetSpellSpellGroupMapBounds(spellId); var spellGroupList = GetSpellSpellGroupMapBounds(spellId);
// Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one // Find group with SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT if it belongs to one
foreach (var group in spellGroup) foreach (var group in spellGroupList)
{ {
var found = mSpellGroupStack.FirstOrDefault(p => p.Key == group); var found = mSpellSameEffectStack.LookupByKey(group);
if (found.Key != SpellGroup.None) if (found != null)
{
if (found.Value == SpellGroupStackRule.ExclusiveSameEffect)
{ {
// check auraTypes
if (!found.Any(p => p == auraType))
continue;
// Put the highest amount in the map // Put the highest amount in the map
if (groups.FirstOrDefault(p => p.Key == group).Key == SpellGroup.None) if (!groups.ContainsKey(group))
groups.Add(group, amount); groups.Add(group, amount);
else else
{ {
@@ -382,11 +384,10 @@ namespace Game.Entities
if (Math.Abs(curr_amount) < Math.Abs(amount)) if (Math.Abs(curr_amount) < Math.Abs(amount))
groups[group] = amount; groups[group] = amount;
} }
// return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group // return because a spell should be in only one SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group per auraType
return true; return true;
} }
} }
}
// Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false // Not in a SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT group, so return false
return false; return false;
} }
@@ -1114,6 +1115,9 @@ namespace Game.Entities
uint oldMSTime = Time.GetMSTime(); uint oldMSTime = Time.GetMSTime();
mSpellGroupStack.Clear(); // need for reload case mSpellGroupStack.Clear(); // need for reload case
mSpellSameEffectStack.Clear();
List<SpellGroup> sameEffectGroups = new List<SpellGroup>();
// 0 1 // 0 1
SQLResult result = DB.World.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules"); SQLResult result = DB.World.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
@@ -1126,28 +1130,128 @@ namespace Game.Entities
uint count = 0; uint count = 0;
do do
{ {
uint group_id = result.Read<uint>(0); SpellGroup group_id = (SpellGroup)result.Read<uint>(0);
byte stack_rule = result.Read<byte>(1); SpellGroupStackRule stack_rule = (SpellGroupStackRule)result.Read<byte>(1);
if (stack_rule >= (byte)SpellGroupStackRule.Max) if (stack_rule >= SpellGroupStackRule.Max)
{ {
Log.outError(LogFilter.Sql, "SpellGroupStackRule {0} listed in `spell_group_stack_rules` does not exist", stack_rule); Log.outError(LogFilter.Sql, "SpellGroupStackRule {0} listed in `spell_group_stack_rules` does not exist", stack_rule);
continue; continue;
} }
var spellGroup = GetSpellGroupSpellMapBounds((SpellGroup)group_id); var spellGroup = GetSpellGroupSpellMapBounds(group_id);
if (spellGroup == null) if (spellGroup == null)
{ {
Log.outError(LogFilter.Sql, "SpellGroup id {0} listed in `spell_group_stack_rules` does not exist", group_id); Log.outError(LogFilter.Sql, "SpellGroup id {0} listed in `spell_group_stack_rules` does not exist", group_id);
continue; continue;
} }
mSpellGroupStack[(SpellGroup)group_id] = (SpellGroupStackRule)stack_rule; mSpellGroupStack.Add(group_id, stack_rule);
// different container for same effect stack rules, need to check effect types
if (stack_rule == SpellGroupStackRule.ExclusiveSameEffect)
sameEffectGroups.Add(group_id);
++count; ++count;
} while (result.NextRow()); } while (result.NextRow());
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} spell group stack rules in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} spell group stack rules in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
count = 0;
oldMSTime = Time.GetMSTime();
Log.outInfo(LogFilter.ServerLoading, "Parsing SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules...");
foreach (SpellGroup group_id in sameEffectGroups)
{
GetSetOfSpellsInSpellGroup(group_id, out var spellIds);
List<AuraType> auraTypes = new List<AuraType>();
// we have to 'guess' what effect this group corresponds to
{
List<AuraType> frequencyContainer = new List<AuraType>();
// only waylay for the moment (shared group)
AuraType[] SubGroups =
{
AuraType.ModMeleeHaste,
AuraType.ModMeleeRangedHaste,
AuraType.ModRangedHaste
};
foreach (uint spellId in spellIds)
{
SpellInfo spellInfo = GetSpellInfo(spellId);
foreach (SpellEffectInfo effectInfo in spellInfo.GetEffectsForDifficulty(Difficulty.None))
{
if (!effectInfo.IsAura())
continue;
AuraType auraName = effectInfo.ApplyAuraName;
if (SubGroups.Contains(auraName))
{
// count as first aura
auraName = SubGroups[0];
}
frequencyContainer.Add(auraName);
}
}
AuraType auraType = 0;
int auraTypeCount = 0;
foreach (AuraType auraName in frequencyContainer)
{
int currentCount = frequencyContainer.Count(p => p == auraName);
if (currentCount > auraTypeCount)
{
auraType = auraName;
auraTypeCount = currentCount;
}
}
if (auraType == SubGroups[0])
{
auraTypes.AddRange(SubGroups);
break;
}
if (auraTypes.Empty())
auraTypes.Add(auraType);
}
// re-check spells against guessed group
foreach (uint spellId in spellIds)
{
SpellInfo spellInfo = GetSpellInfo(spellId);
bool found = false;
while (spellInfo != null)
{
foreach (AuraType auraType in auraTypes)
{
if (spellInfo.HasAura(Difficulty.None, auraType))
{
found = true;
break;
}
}
if (found)
break;
spellInfo = spellInfo.GetNextRankSpell();
}
// not found either, log error
if (!found)
Log.outError(LogFilter.Sql, $"SpellId {spellId} listed in `spell_group` with stack rule 3 does not share aura assigned for group {group_id}");
}
mSpellSameEffectStack[group_id] = auraTypes;
++count;
}
Log.outInfo(LogFilter.ServerLoading, $"Parsed {count} SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT stack rules in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
} }
public void LoadSpellProcs() public void LoadSpellProcs()
@@ -3411,6 +3515,7 @@ namespace Game.Entities
MultiMap<uint, SpellGroup> mSpellSpellGroup = new MultiMap<uint, SpellGroup>(); MultiMap<uint, SpellGroup> mSpellSpellGroup = new MultiMap<uint, SpellGroup>();
MultiMap<SpellGroup, int> mSpellGroupSpell = new MultiMap<SpellGroup, int>(); MultiMap<SpellGroup, int> mSpellGroupSpell = new MultiMap<SpellGroup, int>();
Dictionary<SpellGroup, SpellGroupStackRule> mSpellGroupStack = new Dictionary<SpellGroup, SpellGroupStackRule>(); Dictionary<SpellGroup, SpellGroupStackRule> mSpellGroupStack = new Dictionary<SpellGroup, SpellGroupStackRule>();
MultiMap<SpellGroup, AuraType> mSpellSameEffectStack = new MultiMap<SpellGroup, AuraType>();
Dictionary<uint, SpellProcEntry> mSpellProcMap = new Dictionary<uint, SpellProcEntry>(); Dictionary<uint, SpellProcEntry> mSpellProcMap = new Dictionary<uint, SpellProcEntry>();
Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new Dictionary<uint, SpellThreatEntry>(); Dictionary<uint, SpellThreatEntry> mSpellThreatMap = new Dictionary<uint, SpellThreatEntry>();
Dictionary<uint, PetAura> mSpellPetAuraMap = new Dictionary<uint, PetAura>(); Dictionary<uint, PetAura> mSpellPetAuraMap = new Dictionary<uint, PetAura>();