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:
@@ -239,8 +239,8 @@ namespace Framework.Constants
|
||||
ArenaPreparation = 215,
|
||||
HasteSpells = 216,
|
||||
ModMeleeHaste2 = 217,
|
||||
AddPctModifierBySpellLabel = 218, //NYI
|
||||
AddFlatModifierBySpellLabel = 219, //NYI
|
||||
AddPctModifierBySpellLabel = 218,
|
||||
AddFlatModifierBySpellLabel = 219,
|
||||
ModAbilitySchoolMask = 220, //NYI
|
||||
ModDetaunt = 221,
|
||||
RemoveTransmogCost = 222,
|
||||
|
||||
@@ -400,6 +400,8 @@ namespace Framework.Constants
|
||||
{
|
||||
Flat = 0, // SPELL_AURA_ADD_FLAT_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
|
||||
}
|
||||
|
||||
|
||||
@@ -2665,6 +2665,10 @@ namespace Game.Entities
|
||||
m_spellMods[(int)mod.op][(int)mod.type].Remove(mod);
|
||||
|
||||
// Now, send spellmodifier packet
|
||||
switch (mod.type)
|
||||
{
|
||||
case SpellModType.Flat:
|
||||
case SpellModType.Pct:
|
||||
if (!IsLoading())
|
||||
{
|
||||
ServerOpcodes opcode = (mod.type == SpellModType.Flat ? ServerOpcodes.SetFlatSpellModifier : ServerOpcodes.SetPctSpellModifier);
|
||||
@@ -2678,20 +2682,20 @@ namespace Game.Entities
|
||||
{
|
||||
FlagArray128 mask = new();
|
||||
mask[eff / 32] = 1u << (eff % 32);
|
||||
if (mod.mask & mask)
|
||||
if ((mod as SpellModifierByClassMask).mask & mask)
|
||||
{
|
||||
SpellModifierData modData = new();
|
||||
if (mod.type == SpellModType.Flat)
|
||||
{
|
||||
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)
|
||||
modData.ModifierValue += spell.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
modData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, spell.value);
|
||||
}
|
||||
@@ -2705,6 +2709,32 @@ namespace Game.Entities
|
||||
|
||||
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)
|
||||
@@ -2752,7 +2782,7 @@ namespace Game.Entities
|
||||
case SpellModOp.ChangeCastTime:
|
||||
{
|
||||
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))
|
||||
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)
|
||||
{
|
||||
ApplyModToSpell(modInstantSpell, spell);
|
||||
@@ -2776,7 +2821,7 @@ namespace Game.Entities
|
||||
case SpellModOp.CritChance:
|
||||
{
|
||||
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))
|
||||
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)
|
||||
{
|
||||
ApplyModToSpell(modCritical, spell);
|
||||
@@ -2800,7 +2860,7 @@ namespace Game.Entities
|
||||
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))
|
||||
continue;
|
||||
@@ -2809,7 +2869,16 @@ namespace Game.Entities
|
||||
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))
|
||||
continue;
|
||||
@@ -2828,6 +2897,26 @@ namespace Game.Entities
|
||||
pct *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value);
|
||||
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)
|
||||
@@ -2883,13 +2972,13 @@ namespace Game.Entities
|
||||
pctData.ClassIndex = j;
|
||||
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)
|
||||
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)
|
||||
pctData.ModifierValue *= 1.0f + MathFunctions.CalculatePct(1.0f, mod.value);
|
||||
|
||||
@@ -259,14 +259,43 @@ namespace Game.Spells
|
||||
case AuraType.AddPctModifier:
|
||||
if (m_spellmod == null)
|
||||
{
|
||||
m_spellmod = new SpellModifier(GetBase());
|
||||
m_spellmod.op = (SpellModOp)GetMiscValue();
|
||||
SpellModifierByClassMask spellmod = new SpellModifierByClassMask(GetBase());
|
||||
spellmod.op = (SpellModOp)GetMiscValue();
|
||||
|
||||
m_spellmod.type = GetAuraType() == AuraType.AddPctModifier ? SpellModType.Pct : SpellModType.Flat;
|
||||
m_spellmod.spellId = GetId();
|
||||
m_spellmod.mask = GetSpellEffectInfo().SpellClassMask;
|
||||
spellmod.type = GetAuraType() == AuraType.AddPctModifier ? SpellModType.Pct : SpellModType.Flat;
|
||||
spellmod.spellId = GetId();
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -8129,20 +8129,42 @@ namespace Game.Spells
|
||||
{
|
||||
op = SpellModOp.HealingAndDamage;
|
||||
type = SpellModType.Flat;
|
||||
value = 0;
|
||||
mask = new FlagArray128();
|
||||
spellId = 0;
|
||||
ownerAura = _ownerAura;
|
||||
}
|
||||
|
||||
public SpellModOp op { get; set; }
|
||||
public SpellModType type { get; set; }
|
||||
public int value { get; set; }
|
||||
public FlagArray128 mask { get; set; }
|
||||
public uint spellId { 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>
|
||||
{
|
||||
internal WorldObject _caster;
|
||||
|
||||
@@ -660,9 +660,22 @@ namespace Game.Spells
|
||||
if (affectSpell == null)
|
||||
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
|
||||
// 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)
|
||||
|
||||
@@ -1421,7 +1421,8 @@ namespace Game.Entities
|
||||
if (!spellEffectInfo.IsAura())
|
||||
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;
|
||||
break;
|
||||
|
||||
@@ -598,13 +598,14 @@ namespace Scripts.Spells.Druid
|
||||
{
|
||||
if (spellMod == null)
|
||||
{
|
||||
spellMod = new SpellModifier(GetAura());
|
||||
spellMod.op = SpellModOp.PeriodicHealingAndDamage;
|
||||
spellMod.type = SpellModType.Flat;
|
||||
spellMod.spellId = GetId();
|
||||
spellMod.mask = aurEff.GetSpellEffectInfo().SpellClassMask;
|
||||
SpellModifierByClassMask mod = new(GetAura());
|
||||
mod.op = SpellModOp.PeriodicHealingAndDamage;
|
||||
mod.type = SpellModType.Flat;
|
||||
mod.spellId = GetId();
|
||||
mod.mask = aurEff.GetSpellEffectInfo().SpellClassMask;
|
||||
spellMod = mod;
|
||||
}
|
||||
spellMod.value = aurEff.GetAmount() / 7;
|
||||
(spellMod as SpellModifierByClassMask).value = aurEff.GetAmount() / 7;
|
||||
}
|
||||
|
||||
public override void Register()
|
||||
|
||||
Reference in New Issue
Block a user