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:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
|||||||
Reference in New Issue
Block a user