Core/Auras: Implemented SPELL_AURA_ADD_PCT_MODIFIER_BY_SPELL_LABEL and SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL

Port From (https://github.com/TrinityCore/TrinityCore/commit/ba4fa060d765a35507f1a73287504c3f2e440fdb)
This commit is contained in:
hondacrx
2021-10-17 09:11:00 -04:00
parent 68c4407840
commit 0b64c4a02e
8 changed files with 517 additions and 360 deletions
@@ -239,8 +239,8 @@ namespace Framework.Constants
ArenaPreparation = 215, ArenaPreparation = 215,
HasteSpells = 216, HasteSpells = 216,
ModMeleeHaste2 = 217, ModMeleeHaste2 = 217,
AddPctModifierBySpellLabel = 218, //NYI AddPctModifierBySpellLabel = 218,
AddFlatModifierBySpellLabel = 219, //NYI AddFlatModifierBySpellLabel = 219,
ModAbilitySchoolMask = 220, //NYI ModAbilitySchoolMask = 220, //NYI
ModDetaunt = 221, ModDetaunt = 221,
RemoveTransmogCost = 222, RemoveTransmogCost = 222,
@@ -400,6 +400,8 @@ namespace Framework.Constants
{ {
Flat = 0, // SPELL_AURA_ADD_FLAT_MODIFIER Flat = 0, // SPELL_AURA_ADD_FLAT_MODIFIER
Pct = 1, // SPELL_AURA_ADD_PCT_MODIFIER Pct = 1, // SPELL_AURA_ADD_PCT_MODIFIER
LabelFlat = 2, // SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL
LabelPct = 3, // SPELL_AURA_ADD_PCT_MODIFIER_BY_SPELL_LABEL
End End
} }
+100 -11
View File
@@ -1083,7 +1083,7 @@ namespace Game.Entities
skillStatusData.State = SkillState.Changed; skillStatusData.State = SkillState.Changed;
} }
} }
else if(currVal != 0 && newVal == 0) // Deactivate skill line else if (currVal != 0 && newVal == 0) // Deactivate skill line
{ {
//remove enchantments needing this skill //remove enchantments needing this skill
UpdateSkillEnchantments(id, currVal, 0); UpdateSkillEnchantments(id, currVal, 0);
@@ -2665,6 +2665,10 @@ namespace Game.Entities
m_spellMods[(int)mod.op][(int)mod.type].Remove(mod); m_spellMods[(int)mod.op][(int)mod.type].Remove(mod);
// Now, send spellmodifier packet // Now, send spellmodifier packet
switch (mod.type)
{
case SpellModType.Flat:
case SpellModType.Pct:
if (!IsLoading()) if (!IsLoading())
{ {
ServerOpcodes opcode = (mod.type == SpellModType.Flat ? ServerOpcodes.SetFlatSpellModifier : ServerOpcodes.SetPctSpellModifier); ServerOpcodes opcode = (mod.type == SpellModType.Flat ? ServerOpcodes.SetFlatSpellModifier : ServerOpcodes.SetPctSpellModifier);
@@ -2677,21 +2681,21 @@ namespace Game.Entities
for (int eff = 0; eff < 128; ++eff) for (int eff = 0; eff < 128; ++eff)
{ {
FlagArray128 mask = new(); FlagArray128 mask = new();
mask[eff / 32] = 1u << (eff %32); mask[eff / 32] = 1u << (eff % 32);
if (mod.mask & mask) if ((mod as SpellModifierByClassMask).mask & mask)
{ {
SpellModifierData modData = new(); SpellModifierData modData = new();
if (mod.type == SpellModType.Flat) if (mod.type == SpellModType.Flat)
{ {
modData.ModifierValue = 0.0f; modData.ModifierValue = 0.0f;
foreach (var spell in m_spellMods[(int)mod.op][(int)SpellModType.Flat]) foreach (SpellModifierByClassMask spell in m_spellMods[(int)mod.op][(int)SpellModType.Flat])
if (spell.mask & mask) if (spell.mask & mask)
modData.ModifierValue += spell.value; modData.ModifierValue += spell.value;
} }
else else
{ {
modData.ModifierValue = 1.0f; modData.ModifierValue = 1.0f;
foreach (var spell in m_spellMods[(int)mod.op][(int)SpellModType.Pct]) foreach (SpellModifierByClassMask spell in m_spellMods[(int)mod.op][(int)SpellModType.Pct])
if (spell.mask & mask) if (spell.mask & mask)
modData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, spell.value); modData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, spell.value);
} }
@@ -2705,6 +2709,32 @@ namespace Game.Entities
SendPacket(packet); SendPacket(packet);
} }
break;
case SpellModType.LabelFlat:
if (apply)
{
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SpellFlatModByLabel), (mod as SpellFlatModifierByLabel).value);
}
else
{
int firstIndex = m_activePlayerData.SpellFlatModByLabel.FindIndex((mod as SpellFlatModifierByLabel).value);
if (firstIndex >= 0)
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SpellFlatModByLabel), firstIndex);
}
break;
case SpellModType.LabelPct:
if (apply)
{
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SpellPctModByLabel), (mod as SpellPctModifierByLabel).value);
}
else
{
int firstIndex = m_activePlayerData.SpellPctModByLabel.FindIndex((mod as SpellPctModifierByLabel).value);
if (firstIndex >= 0)
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SpellPctModByLabel), firstIndex);
}
break;
}
} }
public void ApplySpellMod(SpellInfo spellInfo, SpellModOp op, ref int basevalue, Spell spell = null) public void ApplySpellMod(SpellInfo spellInfo, SpellModOp op, ref int basevalue, Spell spell = null)
@@ -2752,7 +2782,7 @@ namespace Game.Entities
case SpellModOp.ChangeCastTime: case SpellModOp.ChangeCastTime:
{ {
SpellModifier modInstantSpell = null; SpellModifier modInstantSpell = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Pct]) foreach (SpellModifierByClassMask mod in m_spellMods[(int)op][(int)SpellModType.Pct])
{ {
if (!IsAffectedBySpellmod(spellInfo, mod, spell)) if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue; continue;
@@ -2764,6 +2794,21 @@ namespace Game.Entities
} }
} }
if (modInstantSpell == null)
{
foreach (SpellPctModifierByLabel mod in m_spellMods[(int)op][(int)SpellModType.LabelPct])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
if (baseValue.CompareTo(10000) < 0 && mod.value.ModifierValue <= -1.0f)
{
modInstantSpell = mod;
break;
}
}
}
if (modInstantSpell != null) if (modInstantSpell != null)
{ {
ApplyModToSpell(modInstantSpell, spell); ApplyModToSpell(modInstantSpell, spell);
@@ -2776,7 +2821,7 @@ namespace Game.Entities
case SpellModOp.CritChance: case SpellModOp.CritChance:
{ {
SpellModifier modCritical = null; SpellModifier modCritical = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Flat]) foreach (SpellModifierByClassMask mod in m_spellMods[(int)op][(int)SpellModType.Flat])
{ {
if (!IsAffectedBySpellmod(spellInfo, mod, spell)) if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue; continue;
@@ -2788,6 +2833,21 @@ namespace Game.Entities
} }
} }
if (modCritical == null)
{
foreach (SpellFlatModifierByLabel mod in m_spellMods[(int)op][(int)SpellModType.LabelFlat])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
if (mod.value.ModifierValue >= 100)
{
modCritical = mod;
break;
}
}
}
if (modCritical != null) if (modCritical != null)
{ {
ApplyModToSpell(modCritical, spell); ApplyModToSpell(modCritical, spell);
@@ -2800,7 +2860,7 @@ namespace Game.Entities
break; break;
} }
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Flat]) foreach (SpellModifierByClassMask mod in m_spellMods[(int)op][(int)SpellModType.Flat])
{ {
if (!IsAffectedBySpellmod(spellInfo, mod, spell)) if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue; continue;
@@ -2809,7 +2869,16 @@ namespace Game.Entities
ApplyModToSpell(mod, spell); ApplyModToSpell(mod, spell);
} }
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Pct]) foreach (SpellFlatModifierByLabel mod in m_spellMods[(int)op][(int)SpellModType.LabelFlat])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
flat += mod.value.ModifierValue;
ApplyModToSpell(mod, spell);
}
foreach (SpellModifierByClassMask mod in m_spellMods[(int)op][(int)SpellModType.Pct])
{ {
if (!IsAffectedBySpellmod(spellInfo, mod, spell)) if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue; continue;
@@ -2828,6 +2897,26 @@ namespace Game.Entities
pct *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value); pct *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value);
ApplyModToSpell(mod, spell); ApplyModToSpell(mod, spell);
} }
foreach (SpellPctModifierByLabel mod in m_spellMods[(int)op][(int)SpellModType.LabelPct])
{
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
// skip percent mods for null basevalue (most important for spell mods with charges)
if (baseValue + (dynamic)flat == 0)
continue;
// special case (skip > 10sec spell casts for instant cast setting)
if (op == SpellModOp.ChangeCastTime)
{
if (baseValue.CompareTo(10000) > 0 && mod.value.ModifierValue <= -1.0f)
continue;
}
pct *= mod.value.ModifierValue;
ApplyModToSpell(mod, spell);
}
} }
bool IsAffectedBySpellmod(SpellInfo spellInfo, SpellModifier mod, Spell spell) bool IsAffectedBySpellmod(SpellInfo spellInfo, SpellModifier mod, Spell spell)
@@ -2883,13 +2972,13 @@ namespace Game.Entities
pctData.ClassIndex = j; pctData.ClassIndex = j;
pctData.ModifierValue = 1.0f; pctData.ModifierValue = 1.0f;
foreach (SpellModifier mod in m_spellMods[i][(int)SpellModType.Flat]) foreach (SpellModifierByClassMask mod in m_spellMods[i][(int)SpellModType.Flat])
{ {
if (mod.mask & mask) if (mod.mask & mask)
flatData.ModifierValue += mod.value; flatData.ModifierValue += mod.value;
} }
foreach (SpellModifier mod in m_spellMods[i][(int)SpellModType.Pct]) foreach (SpellModifierByClassMask mod in m_spellMods[i][(int)SpellModType.Pct])
{ {
if (mod.mask & mask) if (mod.mask & mask)
pctData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value); pctData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value);
+35 -6
View File
@@ -259,14 +259,43 @@ namespace Game.Spells
case AuraType.AddPctModifier: case AuraType.AddPctModifier:
if (m_spellmod == null) if (m_spellmod == null)
{ {
m_spellmod = new SpellModifier(GetBase()); SpellModifierByClassMask spellmod = new SpellModifierByClassMask(GetBase());
m_spellmod.op = (SpellModOp)GetMiscValue(); spellmod.op = (SpellModOp)GetMiscValue();
m_spellmod.type = GetAuraType() == AuraType.AddPctModifier ? SpellModType.Pct : SpellModType.Flat; spellmod.type = GetAuraType() == AuraType.AddPctModifier ? SpellModType.Pct : SpellModType.Flat;
m_spellmod.spellId = GetId(); spellmod.spellId = GetId();
m_spellmod.mask = GetSpellEffectInfo().SpellClassMask; spellmod.mask = GetSpellEffectInfo().SpellClassMask;
m_spellmod = spellmod;
} }
m_spellmod.value = GetAmount(); (m_spellmod as SpellModifierByClassMask).value = GetAmount();
break;
case AuraType.AddFlatModifierBySpellLabel:
if (m_spellmod == null)
{
SpellFlatModifierByLabel spellmod = new SpellFlatModifierByLabel(GetBase());
spellmod.op = (SpellModOp)GetMiscValue();
spellmod.type = SpellModType.LabelFlat;
spellmod.spellId = GetId();
spellmod.value.ModIndex = GetMiscValue();
spellmod.value.LabelID = GetMiscValueB();
m_spellmod = spellmod;
}
(m_spellmod as SpellFlatModifierByLabel).value.ModifierValue = GetAmount();
break;
case AuraType.AddPctModifierBySpellLabel:
if (m_spellmod == null)
{
SpellPctModifierByLabel spellmod = new SpellPctModifierByLabel(GetBase());
spellmod.op = (SpellModOp)GetMiscValue();
spellmod.type = SpellModType.LabelPct;
spellmod.spellId = GetId();
spellmod.value.ModIndex = GetMiscValue();
spellmod.value.LabelID = GetMiscValueB();
m_spellmod = spellmod;
}
(m_spellmod as SpellPctModifierByLabel).value.ModifierValue = 1.0f + MathFunctions.CalculatePct(1.0f, GetAmount());
break; break;
default: default:
break; break;
+26 -4
View File
@@ -8129,20 +8129,42 @@ namespace Game.Spells
{ {
op = SpellModOp.HealingAndDamage; op = SpellModOp.HealingAndDamage;
type = SpellModType.Flat; type = SpellModType.Flat;
value = 0;
mask = new FlagArray128();
spellId = 0; spellId = 0;
ownerAura = _ownerAura; ownerAura = _ownerAura;
} }
public SpellModOp op { get; set; } public SpellModOp op { get; set; }
public SpellModType type { get; set; } public SpellModType type { get; set; }
public int value { get; set; }
public FlagArray128 mask { get; set; }
public uint spellId { get; set; } public uint spellId { get; set; }
public Aura ownerAura { get; set; } public Aura ownerAura { get; set; }
} }
public class SpellModifierByClassMask : SpellModifier
{
public SpellModifierByClassMask(Aura _ownerAura) : base(_ownerAura)
{
value = 0;
mask = new FlagArray128();
}
public int value;
public FlagArray128 mask;
}
public class SpellFlatModifierByLabel : SpellModifier
{
public SpellFlatModByLabel value = new();
public SpellFlatModifierByLabel(Aura _ownerAura) : base(_ownerAura) { }
}
class SpellPctModifierByLabel : SpellModifier
{
public SpellPctModByLabel value = new();
public SpellPctModifierByLabel(Aura _ownerAura) : base(_ownerAura) { }
}
public class WorldObjectSpellTargetCheck : ICheck<WorldObject> public class WorldObjectSpellTargetCheck : ICheck<WorldObject>
{ {
internal WorldObject _caster; internal WorldObject _caster;
+14 -1
View File
@@ -660,9 +660,22 @@ namespace Game.Spells
if (affectSpell == null) if (affectSpell == null)
return false; return false;
switch (mod.type)
{
case SpellModType.Flat:
case SpellModType.Pct:
// TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods // TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods
// TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected // TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected
return affectSpell.SpellFamilyName == SpellFamilyName && mod.mask & SpellFamilyFlags; return affectSpell.SpellFamilyName == SpellFamilyName && (mod as SpellModifierByClassMask).mask & SpellFamilyFlags;
case SpellModType.LabelFlat:
return HasLabel((uint)(mod as SpellFlatModifierByLabel).value.LabelID);
case SpellModType.LabelPct:
return HasLabel((uint)(mod as SpellPctModifierByLabel).value.LabelID);
default:
break;
}
return false;
} }
public bool CanPierceImmuneAura(SpellInfo auraSpellInfo) public bool CanPierceImmuneAura(SpellInfo auraSpellInfo)
+2 -1
View File
@@ -1421,7 +1421,8 @@ namespace Game.Entities
if (!spellEffectInfo.IsAura()) if (!spellEffectInfo.IsAura())
continue; continue;
if (spellEffectInfo.ApplyAuraName == AuraType.AddPctModifier || spellEffectInfo.ApplyAuraName == AuraType.AddFlatModifier) if (spellEffectInfo.ApplyAuraName == AuraType.AddPctModifier || spellEffectInfo.ApplyAuraName == AuraType.AddFlatModifier
|| spellEffectInfo.ApplyAuraName == AuraType.AddPctModifierBySpellLabel || spellEffectInfo.ApplyAuraName == AuraType.AddFlatModifierBySpellLabel)
{ {
found = true; found = true;
break; break;
+7 -6
View File
@@ -598,13 +598,14 @@ namespace Scripts.Spells.Druid
{ {
if (spellMod == null) if (spellMod == null)
{ {
spellMod = new SpellModifier(GetAura()); SpellModifierByClassMask mod = new(GetAura());
spellMod.op = SpellModOp.PeriodicHealingAndDamage; mod.op = SpellModOp.PeriodicHealingAndDamage;
spellMod.type = SpellModType.Flat; mod.type = SpellModType.Flat;
spellMod.spellId = GetId(); mod.spellId = GetId();
spellMod.mask = aurEff.GetSpellEffectInfo().SpellClassMask; mod.mask = aurEff.GetSpellEffectInfo().SpellClassMask;
spellMod = mod;
} }
spellMod.value = aurEff.GetAmount() / 7; (spellMod as SpellModifierByClassMask).value = aurEff.GetAmount() / 7;
} }
public override void Register() public override void Register()