BFA Update (still lots of testing to do tho)
This commit is contained in:
@@ -37,7 +37,7 @@ namespace Game.Spells
|
||||
auraBase = abase;
|
||||
m_spellInfo = abase.GetSpellInfo();
|
||||
_effectInfo = abase.GetSpellEffectInfo(effindex);
|
||||
m_baseAmount = baseAmount.HasValue ? baseAmount.Value : abase.GetSpellEffectInfo(effindex).BasePoints;
|
||||
m_baseAmount = baseAmount.HasValue ? baseAmount.Value : _effectInfo.CalcBaseValue(caster, abase.GetAuraType() == AuraObjectType.Unit ? abase.GetOwner().ToUnit() : null, abase.GetCastItemLevel());
|
||||
m_donePct = 1.0f;
|
||||
m_effIndex = (byte)effindex;
|
||||
m_canBeRecalculated = true;
|
||||
@@ -78,7 +78,7 @@ namespace Game.Spells
|
||||
if (!m_spellInfo.HasAttribute(SpellAttr8.MasterySpecialization) || MathFunctions.fuzzyEq(GetSpellEffectInfo().BonusCoefficient, 0.0f))
|
||||
amount = GetSpellEffectInfo().CalcValue(caster, m_baseAmount, GetBase().GetOwner().ToUnit(), GetBase().GetCastItemLevel());
|
||||
else if (caster != null && caster.IsTypeId(TypeId.Player))
|
||||
amount = (int)(caster.GetFloatValue(PlayerFields.Mastery) * GetSpellEffectInfo().BonusCoefficient);
|
||||
amount = (int)(caster.GetFloatValue(ActivePlayerFields.Mastery) * GetSpellEffectInfo().BonusCoefficient);
|
||||
|
||||
// check item enchant aura cast
|
||||
if (amount == 0 && caster != null)
|
||||
@@ -1088,7 +1088,7 @@ namespace Game.Spells
|
||||
{
|
||||
// apply glow vision
|
||||
if (target.IsTypeId(TypeId.Player))
|
||||
target.SetByteFlag(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.InvisibilityGlow);
|
||||
target.SetByteFlag(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.InvisibilityGlow);
|
||||
|
||||
target.m_invisibility.AddFlag(type);
|
||||
target.m_invisibility.AddValue(type, GetAmount());
|
||||
@@ -1100,7 +1100,7 @@ namespace Game.Spells
|
||||
// if not have different invisibility auras.
|
||||
// remove glow vision
|
||||
if (target.IsTypeId(TypeId.Player))
|
||||
target.RemoveByteFlag(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.InvisibilityGlow);
|
||||
target.RemoveByteFlag(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.InvisibilityGlow);
|
||||
|
||||
target.m_invisibility.DelFlag(type);
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ namespace Game.Spells
|
||||
target.m_stealth.AddValue(type, GetAmount());
|
||||
target.SetStandFlags(UnitStandFlags.Creep);
|
||||
if (target.IsTypeId(TypeId.Player))
|
||||
target.SetByteFlag(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.Stealth);
|
||||
target.SetByteFlag(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.Stealth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1185,7 +1185,7 @@ namespace Game.Spells
|
||||
|
||||
target.RemoveStandFlags(UnitStandFlags.Creep);
|
||||
if (target.IsTypeId(TypeId.Player))
|
||||
target.RemoveByteFlag(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.Stealth);
|
||||
target.RemoveByteFlag(ActivePlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, PlayerFieldByte2Flags.Stealth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1623,7 +1623,7 @@ namespace Game.Spells
|
||||
else
|
||||
{
|
||||
uint model_id = 0;
|
||||
uint modelid = ObjectManager.ChooseDisplayId(ci);
|
||||
uint modelid = ObjectManager.ChooseDisplayId(ci).CreatureDisplayID;
|
||||
if (modelid != 0)
|
||||
model_id = modelid; // Will use the default model here
|
||||
|
||||
@@ -1670,10 +1670,10 @@ namespace Game.Spells
|
||||
CreatureTemplate ci = Global.ObjectMgr.GetCreatureTemplate((uint)cr_id);
|
||||
if (ci != null)
|
||||
{
|
||||
uint displayID = ObjectManager.ChooseDisplayId(ci);
|
||||
Global.ObjectMgr.GetCreatureModelRandomGender(ref displayID);
|
||||
CreatureModel model = ObjectManager.ChooseDisplayId(ci);
|
||||
Global.ObjectMgr.GetCreatureModelRandomGender(ref model, ci);
|
||||
|
||||
target.SetUInt32Value(UnitFields.MountDisplayId, displayID);
|
||||
target.SetUInt32Value(UnitFields.MountDisplayId, model.CreatureDisplayID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2025,9 +2025,9 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
target.SetFlag(PlayerFields.TrackCreatures, 1 << (GetMiscValue() - 1));
|
||||
target.SetFlag(ActivePlayerFields.TrackCreatures, 1 << (GetMiscValue() - 1));
|
||||
else
|
||||
target.RemoveFlag(PlayerFields.TrackCreatures, 1 << (GetMiscValue() - 1));
|
||||
target.RemoveFlag(ActivePlayerFields.TrackCreatures, 1 << (GetMiscValue() - 1));
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.TrackResources)]
|
||||
@@ -2042,9 +2042,9 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
target.SetFlag(PlayerFields.TrackResources, 1 << (GetMiscValue() - 1));
|
||||
target.SetFlag(ActivePlayerFields.TrackResources, 1 << (GetMiscValue() - 1));
|
||||
else
|
||||
target.RemoveFlag(PlayerFields.TrackResources, 1 << (GetMiscValue() - 1));
|
||||
target.RemoveFlag(ActivePlayerFields.TrackResources, 1 << (GetMiscValue() - 1));
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.TrackStealthed)]
|
||||
@@ -2064,7 +2064,7 @@ namespace Game.Spells
|
||||
if (target.HasAuraType(GetAuraType()))
|
||||
return;
|
||||
}
|
||||
target.ApplyModFlag(PlayerFields.LocalFlags, PlayerLocalFlags.TrackStealthed, apply);
|
||||
target.ApplyModFlag(ActivePlayerFields.LocalFlags, PlayerLocalFlags.TrackStealthed, apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ModStalked)]
|
||||
@@ -2189,8 +2189,9 @@ namespace Game.Spells
|
||||
|
||||
if (displayId == 0)
|
||||
{
|
||||
displayId = ObjectManager.ChooseDisplayId(creatureInfo);
|
||||
Global.ObjectMgr.GetCreatureModelRandomGender(ref displayId);
|
||||
CreatureModel model = ObjectManager.ChooseDisplayId(creatureInfo);
|
||||
Global.ObjectMgr.GetCreatureModelRandomGender(ref model, creatureInfo);
|
||||
displayId = model.CreatureDisplayID;
|
||||
}
|
||||
|
||||
//some spell has one aura of mount and one of vehicle
|
||||
@@ -2880,20 +2881,14 @@ namespace Game.Spells
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
for (byte x = (byte)SpellSchools.Normal; x < (byte)SpellSchools.Max; x++)
|
||||
{
|
||||
if (Convert.ToBoolean(GetMiscValue() & (1 << x)))
|
||||
{
|
||||
target.HandleStatModifier((UnitMods.ResistanceStart + x), UnitModifierType.TotalValue, GetAmount(), apply);
|
||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||
target.ApplyResistanceBuffModsMod((SpellSchools)x, GetAmount() > 0, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
target.HandleStatModifier(UnitMods.ResistanceStart + x, UnitModifierType.TotalValue, GetAmount(), apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ModBaseResistancePct)]
|
||||
void HandleAuraModBaseResistancePCT(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag((AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat)))
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
@@ -2918,7 +2913,7 @@ namespace Game.Spells
|
||||
[AuraEffectHandler(AuraType.ModResistancePct)]
|
||||
void HandleModResistancePercent(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag((AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat)))
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
@@ -2931,21 +2926,9 @@ namespace Game.Spells
|
||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||
{
|
||||
if (spellGroupVal != 0)
|
||||
{
|
||||
target.HandleStatModifier((UnitMods.ResistanceStart + i), UnitModifierType.TotalPCT, (float)spellGroupVal, !apply);
|
||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||
{
|
||||
target.ApplyResistanceBuffModsPercentMod((SpellSchools)i, true, spellGroupVal, !apply);
|
||||
target.ApplyResistanceBuffModsPercentMod((SpellSchools)i, false, spellGroupVal, !apply);
|
||||
}
|
||||
target.HandleStatModifier(UnitMods.ResistanceStart + i, UnitModifierType.TotalPCT, (float)spellGroupVal, !apply);
|
||||
|
||||
}
|
||||
target.HandleStatModifier((UnitMods.ResistanceStart + i), UnitModifierType.TotalPCT, GetAmount(), apply);
|
||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||
{
|
||||
target.ApplyResistanceBuffModsPercentMod((SpellSchools)i, true, GetAmount(), apply);
|
||||
target.ApplyResistanceBuffModsPercentMod((SpellSchools)i, false, GetAmount(), apply);
|
||||
}
|
||||
target.HandleStatModifier(UnitMods.ResistanceStart + i, UnitModifierType.TotalPCT, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2953,7 +2936,7 @@ namespace Game.Spells
|
||||
[AuraEffectHandler(AuraType.ModBaseResistance)]
|
||||
void HandleModBaseResistance(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag((AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat)))
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
@@ -2985,11 +2968,11 @@ namespace Game.Spells
|
||||
|
||||
// show armor penetration
|
||||
if (target.IsTypeId(TypeId.Player) && Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
||||
target.ApplyModUInt32Value(PlayerFields.ModTargetPhysicalResistance, GetAmount(), apply);
|
||||
target.ApplyModUInt32Value(ActivePlayerFields.ModTargetPhysicalResistance, GetAmount(), apply);
|
||||
|
||||
// show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
|
||||
if (target.IsTypeId(TypeId.Player) && ((SpellSchoolMask)GetMiscValue() & SpellSchoolMask.Spell) == SpellSchoolMask.Spell)
|
||||
target.ApplyModUInt32Value(PlayerFields.ModTargetResistance, GetAmount(), apply);
|
||||
target.ApplyModUInt32Value(ActivePlayerFields.ModTargetResistance, GetAmount(), apply);
|
||||
}
|
||||
|
||||
/********************************/
|
||||
@@ -3277,7 +3260,7 @@ namespace Game.Spells
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
target.ApplyModSignedFloatValue(PlayerFields.OverrideSpellPowerByApPct, m_amount, apply);
|
||||
target.ApplyModSignedFloatValue(ActivePlayerFields.OverrideSpellPowerByApPct, m_amount, apply);
|
||||
target.UpdateSpellDamageAndHealingBonus();
|
||||
}
|
||||
|
||||
@@ -3291,7 +3274,7 @@ namespace Game.Spells
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
target.ApplyModSignedFloatValue(PlayerFields.OverrideApBySpellPowerPercent, m_amount, apply);
|
||||
target.ApplyModSignedFloatValue(ActivePlayerFields.OverrideApBySpellPowerPercent, m_amount, apply);
|
||||
target.UpdateAttackPowerAndDamage();
|
||||
target.UpdateAttackPowerAndDamage(true);
|
||||
}
|
||||
@@ -3305,7 +3288,7 @@ namespace Game.Spells
|
||||
Player target = aurApp.GetTarget().ToPlayer();
|
||||
if (target)
|
||||
{
|
||||
target.SetStatFloatValue(PlayerFields.VersatilityBonus, target.GetTotalAuraModifier(AuraType.ModVersatility));
|
||||
target.SetStatFloatValue(ActivePlayerFields.VersatilityBonus, target.GetTotalAuraModifier(AuraType.ModVersatility));
|
||||
target.UpdateHealingDonePercentMod();
|
||||
target.UpdateVersatilityDamageDone();
|
||||
}
|
||||
@@ -3951,7 +3934,7 @@ namespace Game.Spells
|
||||
// This information for client side use only
|
||||
if (target.IsTypeId(TypeId.Player))
|
||||
{
|
||||
PlayerFields baseField = GetAmount() >= 0 ? PlayerFields.ModDamageDonePos : PlayerFields.ModDamageDoneNeg;
|
||||
ActivePlayerFields baseField = GetAmount() >= 0 ? ActivePlayerFields.ModDamageDonePos : ActivePlayerFields.ModDamageDoneNeg;
|
||||
for (int i = 0; i < (int)SpellSchools.Max; ++i)
|
||||
{
|
||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||
@@ -3996,9 +3979,9 @@ namespace Game.Spells
|
||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||
{
|
||||
if (spellGroupVal != 0)
|
||||
target.ApplyPercentModFloatValue(PlayerFields.ModDamageDonePct + i, spellGroupVal, !apply);
|
||||
target.ApplyPercentModFloatValue(ActivePlayerFields.ModDamageDonePct + i, spellGroupVal, !apply);
|
||||
|
||||
target.ApplyPercentModFloatValue(PlayerFields.ModDamageDonePct + i, GetAmount(), apply);
|
||||
target.ApplyPercentModFloatValue(ActivePlayerFields.ModDamageDonePct + i, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4095,9 +4078,9 @@ namespace Game.Spells
|
||||
mask |= effect.SpellClassMask;
|
||||
}
|
||||
|
||||
target.SetUInt32Value(PlayerFields.NoReagentCost1, mask[0]);
|
||||
target.SetUInt32Value(PlayerFields.NoReagentCost1 + 1, mask[1]);
|
||||
target.SetUInt32Value(PlayerFields.NoReagentCost1 + 2, mask[2]);
|
||||
target.SetUInt32Value(ActivePlayerFields.NoReagentCost, mask[0]);
|
||||
target.SetUInt32Value(ActivePlayerFields.NoReagentCost + 1, mask[1]);
|
||||
target.SetUInt32Value(ActivePlayerFields.NoReagentCost + 2, mask[2]);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.RetainComboPoints)]
|
||||
@@ -4730,7 +4713,7 @@ namespace Game.Spells
|
||||
|
||||
if (apply)
|
||||
{
|
||||
target.SetUInt16Value(PlayerFields.FieldBytes3, PlayerFieldOffsets.FieldBytes3OffsetOverrideSpellsIdUint16Offset, (ushort)overrideId);
|
||||
target.SetUInt16Value(ActivePlayerFields.Bytes3, PlayerFieldOffsets.FieldBytes3OffsetOverrideSpellsIdUint16Offset, (ushort)overrideId);
|
||||
OverrideSpellDataRecord overrideSpells = CliDB.OverrideSpellDataStorage.LookupByKey(overrideId);
|
||||
if (overrideSpells != null)
|
||||
{
|
||||
@@ -4744,7 +4727,7 @@ namespace Game.Spells
|
||||
}
|
||||
else
|
||||
{
|
||||
target.SetUInt16Value(PlayerFields.FieldBytes3, PlayerFieldOffsets.FieldBytes3OffsetOverrideSpellsIdUint16Offset, 0);
|
||||
target.SetUInt16Value(ActivePlayerFields.Bytes3, PlayerFieldOffsets.FieldBytes3OffsetOverrideSpellsIdUint16Offset, 0);
|
||||
OverrideSpellDataRecord overrideSpells = CliDB.OverrideSpellDataStorage.LookupByKey(overrideId);
|
||||
if (overrideSpells != null)
|
||||
{
|
||||
@@ -4796,9 +4779,9 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
aurApp.GetTarget().RemoveByteFlag(PlayerFields.LocalFlags, 0, PlayerLocalFlags.ReleaseTimer);
|
||||
aurApp.GetTarget().RemoveByteFlag(ActivePlayerFields.LocalFlags, 0, PlayerLocalFlags.ReleaseTimer);
|
||||
else if (!aurApp.GetTarget().GetMap().Instanceable())
|
||||
aurApp.GetTarget().SetByteFlag(PlayerFields.LocalFlags, 0, PlayerLocalFlags.ReleaseTimer);
|
||||
aurApp.GetTarget().SetByteFlag(ActivePlayerFields.LocalFlags, 0, PlayerLocalFlags.ReleaseTimer);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.Mastery)]
|
||||
@@ -5377,8 +5360,10 @@ namespace Game.Spells
|
||||
if (crit)
|
||||
damage = caster.SpellCriticalDamageBonus(m_spellInfo, damage, target);
|
||||
|
||||
uint dmg = damage;
|
||||
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
||||
caster.ApplyResilience(target, ref damage);
|
||||
caster.ApplyResilience(target, ref dmg);
|
||||
damage = dmg;
|
||||
|
||||
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
||||
caster.CalcAbsorbResist(damageInfo);
|
||||
@@ -5403,7 +5388,7 @@ namespace Game.Spells
|
||||
if (overkill < 0)
|
||||
overkill = 0;
|
||||
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, damage, dmg, (uint)overkill, absorb, resist, 0.0f, crit);
|
||||
|
||||
caster.DealDamage(target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), true);
|
||||
|
||||
@@ -5465,8 +5450,10 @@ namespace Game.Spells
|
||||
if (crit)
|
||||
damage = caster.SpellCriticalDamageBonus(m_spellInfo, damage, target);
|
||||
|
||||
uint dmg = damage;
|
||||
if (!GetSpellInfo().HasAttribute(SpellAttr4.FixedDamage))
|
||||
caster.ApplyResilience(target, ref damage);
|
||||
caster.ApplyResilience(target, ref dmg);
|
||||
damage = dmg;
|
||||
|
||||
DamageInfo damageInfo = new DamageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask(), DamageEffectType.DOT, WeaponAttackType.BaseAttack);
|
||||
caster.CalcAbsorbResist(damageInfo);
|
||||
@@ -5477,6 +5464,7 @@ namespace Game.Spells
|
||||
// SendSpellNonMeleeDamageLog expects non-absorbed/non-resisted damage
|
||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(caster, target, GetId(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().GetSchoolMask(), GetBase().GetCastGUID());
|
||||
log.damage = damage;
|
||||
log.originalDamage = dmg;
|
||||
log.absorb = absorb;
|
||||
log.resist = resist;
|
||||
log.periodicLog = true;
|
||||
@@ -5627,7 +5615,7 @@ namespace Game.Spells
|
||||
caster.CalcHealAbsorb(healInfo);
|
||||
caster.DealHeal(healInfo);
|
||||
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, heal, (int)(heal - healInfo.GetEffectiveHeal()), healInfo.GetAbsorb(), 0, 0.0f, crit);
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, heal, (uint)damage, heal - healInfo.GetEffectiveHeal(), healInfo.GetAbsorb(), 0, 0.0f, crit);
|
||||
target.SendPeriodicAuraLog(pInfo);
|
||||
|
||||
target.getHostileRefManager().threatAssist(caster, healInfo.GetEffectiveHeal() * 0.5f, GetSpellInfo());
|
||||
@@ -5667,7 +5655,7 @@ namespace Game.Spells
|
||||
int drainedAmount = -target.ModifyPower(powerType, -drainAmount);
|
||||
float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
|
||||
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)drainedAmount, 0, 0, 0, gainMultiplier, false);
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)drainedAmount, (uint)drainAmount, 0, 0, 0, gainMultiplier, false);
|
||||
|
||||
int gainAmount = (int)(drainedAmount * gainMultiplier);
|
||||
int gainedAmount = 0;
|
||||
@@ -5719,7 +5707,7 @@ namespace Game.Spells
|
||||
// ignore negative values (can be result apply spellmods to aura damage
|
||||
int amount = Math.Max(m_amount, 0) * target.GetMaxPower(powerType) / 100;
|
||||
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)amount, 0, 0, 0, 0.0f, false);
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)amount, (uint)amount, 0, 0, 0, 0.0f, false);
|
||||
|
||||
int gain = target.ModifyPower(powerType, amount);
|
||||
|
||||
@@ -5748,7 +5736,7 @@ namespace Game.Spells
|
||||
// ignore negative values (can be result apply spellmods to aura damage
|
||||
int amount = Math.Max(m_amount, 0);
|
||||
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)amount, 0, 0, 0, 0.0f, false);
|
||||
SpellPeriodicAuraLogInfo pInfo = new SpellPeriodicAuraLogInfo(this, (uint)amount, (uint)amount, 0, 0, 0, 0.0f, false);
|
||||
int gain = target.ModifyPower(powerType, amount);
|
||||
|
||||
if (caster != null)
|
||||
@@ -5962,9 +5950,9 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
aurApp.GetTarget().SetFlag(PlayerFields.LocalFlags, PlayerLocalFlags.CanUseObjectsMounted);
|
||||
aurApp.GetTarget().SetFlag(ActivePlayerFields.LocalFlags, PlayerLocalFlags.CanUseObjectsMounted);
|
||||
else if (!aurApp.GetTarget().HasAuraType(AuraType.AllowUsingGameobjectsWhileMounted))
|
||||
aurApp.GetTarget().RemoveFlag(PlayerFields.LocalFlags, PlayerLocalFlags.CanUseObjectsMounted);
|
||||
aurApp.GetTarget().RemoveFlag(ActivePlayerFields.LocalFlags, PlayerLocalFlags.CanUseObjectsMounted);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.PlayScene)]
|
||||
|
||||
+62
-111
@@ -41,7 +41,7 @@ namespace Game.Spells
|
||||
{
|
||||
m_spellInfo = info;
|
||||
m_caster = (info.HasAttribute(SpellAttr6.CastByCharmer) && caster.GetCharmerOrOwner() != null ? caster.GetCharmerOrOwner() : caster);
|
||||
m_spellValue = new SpellValue(caster.GetMap().GetDifficultyID(), m_spellInfo);
|
||||
m_spellValue = new SpellValue(caster.GetMap().GetDifficultyID(), m_spellInfo, caster);
|
||||
m_preGeneratedPath = new PathGenerator(m_caster);
|
||||
m_castItemLevel = -1;
|
||||
_effects = info.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID());
|
||||
@@ -278,29 +278,6 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_auraScaleMask != 0)
|
||||
{
|
||||
bool checkLvl = !m_UniqueTargetInfo.Empty();
|
||||
for (var i = 0; i < m_UniqueTargetInfo.Count; ++i)
|
||||
{
|
||||
var ihit = m_UniqueTargetInfo[i];
|
||||
// remove targets which did not pass min level check
|
||||
if (m_auraScaleMask != 0 && ihit.effectMask == m_auraScaleMask)
|
||||
{
|
||||
// Do not check for selfcast
|
||||
if (!ihit.scaleAura && ihit.targetGUID != m_caster.GetGUID())
|
||||
{
|
||||
m_UniqueTargetInfo.Remove(ihit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkLvl && m_UniqueTargetInfo.Empty())
|
||||
{
|
||||
SendCastResult(SpellCastResult.Lowlevel);
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_targets.HasDst())
|
||||
@@ -982,6 +959,9 @@ namespace Game.Spells
|
||||
if (m_caster.IsTypeId(TypeId.Unit) && m_caster.ToCreature().IsVehicle())
|
||||
target = m_caster.GetVehicleKit().GetPassenger((sbyte)(targetType.GetTarget() - Targets.UnitPassenger0));
|
||||
break;
|
||||
case Targets.UnitOwnCritter:
|
||||
target = ObjectAccessor.GetCreatureOrPetOrVehicle(m_caster, m_caster.GetCritterGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1481,7 +1461,7 @@ namespace Game.Spells
|
||||
if (unitTarget != null)
|
||||
{
|
||||
uint deficit = (uint)(unitTarget.GetMaxHealth() - unitTarget.GetHealth());
|
||||
if ((deficit > maxHPDeficit || found == null) && target.IsWithinDist(unitTarget, jumpRadius) && target.IsWithinLOSInMap(unitTarget))
|
||||
if ((deficit > maxHPDeficit || found == null) && target.IsWithinDist(unitTarget, jumpRadius) && target.IsWithinLOSInMap(unitTarget, ModelIgnoreFlags.M2))
|
||||
{
|
||||
found = obj;
|
||||
maxHPDeficit = deficit;
|
||||
@@ -1496,10 +1476,10 @@ namespace Game.Spells
|
||||
{
|
||||
if (found == null)
|
||||
{
|
||||
if ((!isBouncingFar || target.IsWithinDist(obj, jumpRadius)) && target.IsWithinLOSInMap(obj))
|
||||
if ((!isBouncingFar || target.IsWithinDist(obj, jumpRadius)) && target.IsWithinLOSInMap(obj, ModelIgnoreFlags.M2))
|
||||
found = obj;
|
||||
}
|
||||
else if (target.GetDistanceOrder(obj, found) && target.IsWithinLOSInMap(obj))
|
||||
else if (target.GetDistanceOrder(obj, found) && target.IsWithinLOSInMap(obj, ModelIgnoreFlags.M2))
|
||||
found = obj;
|
||||
}
|
||||
}
|
||||
@@ -1565,7 +1545,6 @@ namespace Game.Spells
|
||||
// For other spells trigger procflags are set in Spell.DoAllEffectOnTarget
|
||||
// Because spell positivity is dependant on target
|
||||
}
|
||||
m_hitMask = ProcFlagsHit.None;
|
||||
|
||||
// Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
|
||||
if (m_spellInfo.SpellFamilyName == SpellFamilyNames.Hunter && (m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x18u) || // Freezing and Frost Trap, Freezing Arrow
|
||||
@@ -1625,13 +1604,6 @@ namespace Game.Spells
|
||||
if (targetGUID == ihit.targetGUID) // Found in list
|
||||
{
|
||||
ihit.effectMask |= effectMask; // Immune effects removed from mask
|
||||
ihit.scaleAura = false;
|
||||
if (m_auraScaleMask != 0 && ihit.effectMask == m_auraScaleMask && m_caster != target)
|
||||
{
|
||||
SpellInfo auraSpell = Global.SpellMgr.GetSpellInfo(Global.SpellMgr.GetFirstSpellInChain(m_spellInfo.Id));
|
||||
if (target.GetLevelForTarget(m_caster) + 10 >= auraSpell.SpellLevel)
|
||||
ihit.scaleAura = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1646,13 +1618,6 @@ namespace Game.Spells
|
||||
targetInfo.alive = target.IsAlive();
|
||||
targetInfo.damage = 0;
|
||||
targetInfo.crit = false;
|
||||
targetInfo.scaleAura = false;
|
||||
if (m_auraScaleMask != 0 && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
|
||||
{
|
||||
SpellInfo auraSpell = Global.SpellMgr.GetSpellInfo(Global.SpellMgr.GetFirstSpellInChain(m_spellInfo.Id));
|
||||
if (target.GetLevelForTarget(m_caster) + 10 >= auraSpell.SpellLevel)
|
||||
targetInfo.scaleAura = true;
|
||||
}
|
||||
|
||||
// Calculate hit result
|
||||
if (m_originalCaster != null)
|
||||
@@ -1896,7 +1861,7 @@ namespace Game.Spells
|
||||
// if target is flagged for pvp also flag caster if a player
|
||||
if (unit.IsPvP() && m_caster.IsTypeId(TypeId.Player))
|
||||
enablePvP = true; // Decide on PvP flagging now, but act on it later.
|
||||
SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target.scaleAura);
|
||||
SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask);
|
||||
if (missInfo2 != SpellMissInfo.None)
|
||||
{
|
||||
if (missInfo2 != SpellMissInfo.Miss)
|
||||
@@ -2088,7 +2053,7 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
SpellMissInfo DoSpellHitOnUnit(Unit unit, uint effectMask, bool scaleAura)
|
||||
SpellMissInfo DoSpellHitOnUnit(Unit unit, uint effectMask)
|
||||
{
|
||||
if (unit == null || effectMask == 0)
|
||||
return SpellMissInfo.Evade;
|
||||
@@ -2175,35 +2140,18 @@ namespace Game.Spells
|
||||
|
||||
if (aura_effmask != 0)
|
||||
{
|
||||
// Select rank for aura with level requirements only in specific cases
|
||||
// Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
|
||||
SpellInfo aurSpellInfo = m_spellInfo;
|
||||
int[] basePoints = new int[SpellConst.MaxEffects];
|
||||
if (scaleAura)
|
||||
{
|
||||
aurSpellInfo = m_spellInfo.GetAuraRankForLevel(unitTarget.getLevel());
|
||||
Cypher.Assert(aurSpellInfo != null);
|
||||
foreach (SpellEffectInfo effect in aurSpellInfo.GetEffectsForDifficulty(0))
|
||||
{
|
||||
if (effect == null)
|
||||
continue;
|
||||
|
||||
basePoints[effect.EffectIndex] = effect.BasePoints;
|
||||
SpellEffectInfo myEffect = GetEffect(effect.EffectIndex);
|
||||
if (myEffect != null && myEffect.Effect != effect.Effect)
|
||||
{
|
||||
aurSpellInfo = m_spellInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_originalCaster != null)
|
||||
{
|
||||
int[] basePoints = new int[SpellConst.MaxEffects];
|
||||
foreach (SpellEffectInfo auraSpellEffect in GetEffects())
|
||||
if (auraSpellEffect != null)
|
||||
basePoints[auraSpellEffect.EffectIndex] = (m_spellValue.CustomBasePointsMask & (1 << (int)auraSpellEffect.EffectIndex)) != 0 ?
|
||||
m_spellValue.EffectBasePoints[auraSpellEffect.EffectIndex] : auraSpellEffect.CalcBaseValue(m_originalCaster, unit, m_castItemLevel);
|
||||
|
||||
bool refresh = false;
|
||||
bool resetPeriodicTimer = !_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.DontResetPeriodicTimer);
|
||||
m_spellAura = Aura.TryRefreshStackOrCreate(aurSpellInfo, m_castId, (byte)effectMask, unit,
|
||||
m_originalCaster, out refresh, (aurSpellInfo == m_spellInfo) ? m_spellValue.EffectBasePoints : basePoints, m_CastItem, ObjectGuid.Empty, resetPeriodicTimer, ObjectGuid.Empty, m_castItemLevel);
|
||||
m_spellAura = Aura.TryRefreshStackOrCreate(m_spellInfo, m_castId, (byte)effectMask, unit,
|
||||
m_originalCaster, out refresh, basePoints, m_CastItem, ObjectGuid.Empty, resetPeriodicTimer, ObjectGuid.Empty, m_castItemLevel);
|
||||
if (m_spellAura != null)
|
||||
{
|
||||
// Set aura stack amount to desired value
|
||||
@@ -2217,7 +2165,7 @@ namespace Game.Spells
|
||||
|
||||
// Now Reduce spell duration using data received at spell hit
|
||||
int duration = m_spellAura.GetMaxDuration();
|
||||
float diminishMod = unit.ApplyDiminishingToDuration(aurSpellInfo, ref duration, m_originalCaster, diminishLevel);
|
||||
float diminishMod = unit.ApplyDiminishingToDuration(m_spellInfo, ref duration, m_originalCaster, diminishLevel);
|
||||
|
||||
// unit is immune to aura if it was diminished to 0 duration
|
||||
if (diminishMod == 0.0f)
|
||||
@@ -2239,13 +2187,13 @@ namespace Game.Spells
|
||||
if (aurApp != null)
|
||||
positive = aurApp.IsPositive();
|
||||
|
||||
duration = m_originalCaster.ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
|
||||
duration = m_originalCaster.ModSpellDuration(m_spellInfo, unit, duration, positive, effectMask);
|
||||
|
||||
if (duration > 0)
|
||||
{
|
||||
// Haste modifies duration of channeled spells
|
||||
if (m_spellInfo.IsChanneled())
|
||||
m_originalCaster.ModSpellDurationTime(aurSpellInfo, ref duration, this);
|
||||
m_originalCaster.ModSpellDurationTime(m_spellInfo, ref duration, this);
|
||||
else if (m_spellInfo.HasAttribute(SpellAttr5.HasteAffectDuration))
|
||||
{
|
||||
int origDuration = duration;
|
||||
@@ -2404,6 +2352,9 @@ namespace Game.Spells
|
||||
Player modOwner = m_caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(m_spellInfo.Id, SpellModOp.Range, ref range, this);
|
||||
|
||||
// add little tolerance level
|
||||
range += Math.Min(3.0f, range * 0.1f); // 10% but no more than 3.0f
|
||||
}
|
||||
|
||||
foreach (var ihit in m_UniqueTargetInfo)
|
||||
@@ -2464,27 +2415,6 @@ namespace Game.Spells
|
||||
|
||||
InitExplicitTargets(targets);
|
||||
|
||||
// Fill aura scaling information
|
||||
if (m_caster.IsControlledByPlayer() && !m_spellInfo.IsPassive() && m_spellInfo.SpellLevel != 0 && !m_spellInfo.IsChanneled() && !Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreAuraScaling))
|
||||
{
|
||||
foreach (SpellEffectInfo effect in GetEffects())
|
||||
{
|
||||
if (effect != null && effect.Effect == SpellEffectName.ApplyAura)
|
||||
{
|
||||
// Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
|
||||
if (m_spellInfo.IsPositiveEffect(effect.EffectIndex))
|
||||
{
|
||||
m_auraScaleMask |= (byte)(1 << (int)effect.EffectIndex);
|
||||
if (m_spellValue.EffectBasePoints[effect.EffectIndex] != effect.BasePoints)
|
||||
{
|
||||
m_auraScaleMask = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_spellState = SpellState.Preparing;
|
||||
|
||||
if (triggeredByAura != null)
|
||||
@@ -2991,8 +2921,14 @@ namespace Game.Spells
|
||||
// process immediate effects (items, ground, etc.) also initialize some variables
|
||||
_handle_immediate_phase();
|
||||
|
||||
foreach (var ihit in m_UniqueTargetInfo)
|
||||
DoAllEffectOnTarget(ihit);
|
||||
// consider spell hit for some spells without target, so they may proc on finish phase correctly
|
||||
if (m_UniqueTargetInfo.Empty())
|
||||
m_hitMask = ProcFlagsHit.Normal;
|
||||
else
|
||||
{
|
||||
foreach (var ihit in m_UniqueTargetInfo)
|
||||
DoAllEffectOnTarget(ihit);
|
||||
}
|
||||
|
||||
foreach (var ihit in m_UniqueGOTargetInfo)
|
||||
DoAllEffectOnTarget(ihit);
|
||||
@@ -3848,7 +3784,7 @@ namespace Game.Spells
|
||||
{
|
||||
case ItemSubClassWeapon.Thrown:
|
||||
ammoDisplayID = Global.DB2Mgr.GetItemDisplayId(itemId, m_caster.GetVirtualItemAppearanceMod(i));
|
||||
ammoInventoryType = itemEntry.inventoryType;
|
||||
ammoInventoryType = (InventoryType)itemEntry.inventoryType;
|
||||
break;
|
||||
case ItemSubClassWeapon.Bow:
|
||||
case ItemSubClassWeapon.Crossbow:
|
||||
@@ -4632,7 +4568,7 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
if (!m_spellInfo.HasAttribute(SpellAttr2.CanTargetNotInLos) && !Global.DisableMgr.IsDisabledFor(DisableType.Spell, m_spellInfo.Id, null, DisableFlags.SpellLOS)
|
||||
&& !unitTarget.IsWithinLOSInMap(losTarget))
|
||||
&& !unitTarget.IsWithinLOSInMap(losTarget, ModelIgnoreFlags.M2))
|
||||
return SpellCastResult.LineOfSight;
|
||||
}
|
||||
}
|
||||
@@ -4645,7 +4581,7 @@ namespace Game.Spells
|
||||
m_targets.GetDstPos().GetPosition(out x, out y, out z);
|
||||
|
||||
if (!m_spellInfo.HasAttribute(SpellAttr2.CanTargetNotInLos) && !Global.DisableMgr.IsDisabledFor(DisableType.Spell, m_spellInfo.Id, null, DisableFlags.SpellLOS)
|
||||
&& !m_caster.IsWithinLOS(x, y, z))
|
||||
&& !m_caster.IsWithinLOS(x, y, z, ModelIgnoreFlags.M2))
|
||||
return SpellCastResult.LineOfSight;
|
||||
}
|
||||
|
||||
@@ -4936,6 +4872,9 @@ namespace Game.Spells
|
||||
if (target == null)
|
||||
return SpellCastResult.DontReport;
|
||||
|
||||
// first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
|
||||
if (!target.IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
|
||||
return SpellCastResult.LineOfSight;
|
||||
|
||||
float objSize = target.GetObjectSize();
|
||||
float range = m_spellInfo.GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
|
||||
@@ -5677,6 +5616,10 @@ namespace Game.Spells
|
||||
|
||||
(float minRange, float maxRange) = GetMinMaxRange(strict);
|
||||
|
||||
// dont check max_range to strictly after cast
|
||||
if (m_spellInfo.RangeEntry != null && m_spellInfo.RangeEntry.Flags != SpellRangeFlag.Melee && !strict)
|
||||
maxRange += Math.Min(3.0f, maxRange * 0.1f); // 10% but no more than 3.0f
|
||||
|
||||
// get square values for sqr distance checks
|
||||
minRange *= minRange;
|
||||
maxRange *= maxRange;
|
||||
@@ -6457,8 +6400,9 @@ namespace Game.Spells
|
||||
return true;
|
||||
|
||||
// @todo shit below shouldn't be here, but it's temporary
|
||||
//Check targets for LOS visibility
|
||||
if (losPosition != null)
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ());
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ(), ModelIgnoreFlags.M2);
|
||||
else
|
||||
{
|
||||
// Get GO cast coordinates if original caster . GO
|
||||
@@ -6467,7 +6411,7 @@ namespace Game.Spells
|
||||
caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster))
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6675,7 +6619,7 @@ namespace Game.Spells
|
||||
|
||||
skillId = SharedConst.SkillByLockType((LockType)lockInfo.Index[j]);
|
||||
|
||||
if (skillId != SkillType.None || lockInfo.Index[j] == (uint)LockType.Picklock)
|
||||
if (skillId != SkillType.None || lockInfo.Index[j] == (uint)LockType.Lockpicking)
|
||||
{
|
||||
reqSkillValue = lockInfo.Skill[j];
|
||||
|
||||
@@ -6683,7 +6627,7 @@ namespace Game.Spells
|
||||
skillValue = 0;
|
||||
if (!m_CastItem && m_caster.IsTypeId(TypeId.Player))
|
||||
skillValue = m_caster.ToPlayer().GetSkillValue(skillId);
|
||||
else if (lockInfo.Index[j] == (uint)LockType.Picklock)
|
||||
else if (lockInfo.Index[j] == (uint)LockType.Lockpicking)
|
||||
skillValue = (int)m_caster.getLevel() * 5;
|
||||
|
||||
// skill bonus provided by casting spell (mostly item spells)
|
||||
@@ -6710,9 +6654,8 @@ namespace Game.Spells
|
||||
{
|
||||
if (mod < SpellValueMod.End)
|
||||
{
|
||||
SpellEffectInfo effect = GetEffect((uint)mod);
|
||||
if (effect != null)
|
||||
m_spellValue.EffectBasePoints[(int)mod] = effect.CalcBaseValue(value);
|
||||
m_spellValue.EffectBasePoints[(int)mod] = value;
|
||||
m_spellValue.CustomBasePointsMask |= 1u << (int)mod;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7088,11 +7031,19 @@ namespace Game.Spells
|
||||
|
||||
int CalculateDamage(uint i, Unit target)
|
||||
{
|
||||
return m_caster.CalculateSpellDamage(target, m_spellInfo, i, m_spellValue.EffectBasePoints[i], m_castItemLevel);
|
||||
int? basePoint = null;
|
||||
if ((m_spellValue.CustomBasePointsMask & (1 << (int)i)) != 0)
|
||||
basePoint = m_spellValue.EffectBasePoints[i];
|
||||
|
||||
return m_caster.CalculateSpellDamage(target, m_spellInfo, i, basePoint, m_castItemLevel);
|
||||
}
|
||||
int CalculateDamage(uint i, Unit target, out float variance)
|
||||
{
|
||||
return m_caster.CalculateSpellDamage(target, m_spellInfo, i, out variance, m_spellValue.EffectBasePoints[i], m_castItemLevel);
|
||||
int? basePoint = null;
|
||||
if ((m_spellValue.CustomBasePointsMask & (1 << (int)i)) != 0)
|
||||
basePoint = m_spellValue.EffectBasePoints[i];
|
||||
|
||||
return m_caster.CalculateSpellDamage(target, m_spellInfo, i, out variance, basePoint, m_castItemLevel);
|
||||
}
|
||||
public SpellState getState()
|
||||
{
|
||||
@@ -7331,7 +7282,6 @@ namespace Game.Spells
|
||||
SpellEffectInfo[] _effects = new SpellEffectInfo[SpellConst.MaxEffects];
|
||||
|
||||
bool m_skipCheck;
|
||||
byte m_auraScaleMask;
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -7504,7 +7454,6 @@ namespace Game.Spells
|
||||
public bool processed;
|
||||
public bool alive;
|
||||
public bool crit;
|
||||
public bool scaleAura;
|
||||
}
|
||||
|
||||
public class GOTargetInfo
|
||||
@@ -7523,20 +7472,22 @@ namespace Game.Spells
|
||||
|
||||
public class SpellValue
|
||||
{
|
||||
public SpellValue(Difficulty difficulty, SpellInfo proto)
|
||||
public SpellValue(Difficulty difficulty, SpellInfo proto, Unit caster)
|
||||
{
|
||||
var effects = proto.GetEffectsForDifficulty(difficulty);
|
||||
Cypher.Assert(effects.Length <= SpellConst.MaxEffects);
|
||||
foreach (SpellEffectInfo effect in effects)
|
||||
if (effect != null)
|
||||
EffectBasePoints[effect.EffectIndex] = effect.BasePoints;
|
||||
EffectBasePoints[effect.EffectIndex] = effect.CalcBaseValue(caster, null, -1);
|
||||
|
||||
CustomBasePointsMask = 0;
|
||||
MaxAffectedTargets = proto.MaxAffectedTargets;
|
||||
RadiusMod = 1.0f;
|
||||
AuraStackAmount = 1;
|
||||
}
|
||||
|
||||
public int[] EffectBasePoints = new int[SpellConst.MaxEffects];
|
||||
public uint CustomBasePointsMask;
|
||||
public uint MaxAffectedTargets;
|
||||
public float RadiusMod;
|
||||
public byte AuraStackAmount;
|
||||
|
||||
@@ -134,7 +134,8 @@ namespace Game.Spells
|
||||
m_caster.CalcAbsorbResist(damageInfo);
|
||||
|
||||
SpellNonMeleeDamage log = new SpellNonMeleeDamage(m_caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellInfo.GetSchoolMask(), m_castId);
|
||||
log.damage = (uint)damage;
|
||||
log.damage = damageInfo.GetDamage();
|
||||
log.originalDamage = (uint)damage;
|
||||
log.absorb = damageInfo.GetAbsorb();
|
||||
log.resist = damageInfo.GetResist();
|
||||
|
||||
@@ -2102,7 +2103,7 @@ namespace Game.Spells
|
||||
if (!unitTarget.IsTypeId(TypeId.Player))
|
||||
return;
|
||||
|
||||
if (damage < 0)
|
||||
if (damage < 1)
|
||||
return;
|
||||
|
||||
uint skillid = (uint)effectInfo.MiscValue;
|
||||
@@ -2114,7 +2115,7 @@ namespace Game.Spells
|
||||
if (tier == null)
|
||||
return;
|
||||
ushort skillval = unitTarget.ToPlayer().GetPureSkillValue((SkillType)skillid);
|
||||
unitTarget.ToPlayer().SetSkill(skillid, (uint)effectInfo.CalcValue(), Math.Max(skillval, (ushort)1), tier.Value[damage - 1]);
|
||||
unitTarget.ToPlayer().SetSkill(skillid, (uint)damage, Math.Max(skillval, (ushort)1), tier.Value[damage - 1]);
|
||||
}
|
||||
|
||||
[SpellEffectHandler(SpellEffectName.PlayMovie)]
|
||||
@@ -4068,12 +4069,41 @@ namespace Game.Spells
|
||||
creature.RemoveFlag(UnitFields.Flags, UnitFlags.Skinnable);
|
||||
creature.SetFlag(ObjectFields.DynamicFlags, UnitDynFlags.Lootable);
|
||||
|
||||
uint reqValue = (uint)(targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5);
|
||||
if (skill == SkillType.Skinning)
|
||||
{
|
||||
int reqValue;
|
||||
if (targetLevel <= 10)
|
||||
reqValue = 1;
|
||||
else if (targetLevel < 20)
|
||||
reqValue = (targetLevel - 10) * 10;
|
||||
else if (targetLevel <= 73)
|
||||
reqValue = targetLevel * 5;
|
||||
else if (targetLevel < 80)
|
||||
reqValue = targetLevel * 10 - 365;
|
||||
else if (targetLevel <= 84)
|
||||
reqValue = targetLevel * 5 + 35;
|
||||
else if (targetLevel <= 87)
|
||||
reqValue = targetLevel * 15 - 805;
|
||||
else if (targetLevel <= 92)
|
||||
reqValue = (targetLevel - 62) * 20;
|
||||
else if (targetLevel <= 104)
|
||||
reqValue = targetLevel * 5 + 175;
|
||||
else if (targetLevel <= 107)
|
||||
reqValue = targetLevel * 15 - 905;
|
||||
else if (targetLevel <= 112)
|
||||
reqValue = (targetLevel - 72) * 20;
|
||||
else if (targetLevel <= 122)
|
||||
reqValue = (targetLevel - 32) * 10;
|
||||
else
|
||||
reqValue = 900;
|
||||
|
||||
uint skillValue = m_caster.ToPlayer().GetPureSkillValue(skill);
|
||||
// TODO: Specialize skillid for each expansion
|
||||
// new db field?
|
||||
// tied to one of existing expansion fields in creature_template?
|
||||
|
||||
// Double chances for elites
|
||||
m_caster.ToPlayer().UpdateGatherSkill(skill, skillValue, reqValue, (uint)(creature.isElite() ? 2 : 1));
|
||||
// Double chances for elites
|
||||
m_caster.ToPlayer().UpdateGatherSkill(skill, (uint)damage, (uint)reqValue, (uint)(creature.isElite() ? 2 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
[SpellEffectHandler(SpellEffectName.Charge)]
|
||||
|
||||
@@ -953,7 +953,7 @@ namespace Game.Spells
|
||||
public bool OnHold;
|
||||
}
|
||||
|
||||
struct ChargeEntry
|
||||
public struct ChargeEntry
|
||||
{
|
||||
public ChargeEntry(DateTime startTime, TimeSpan rechargeTime)
|
||||
{
|
||||
|
||||
+209
-141
@@ -107,7 +107,7 @@ namespace Game.Spells
|
||||
if (_options != null)
|
||||
{
|
||||
SpellProcsPerMinuteRecord _ppm = CliDB.SpellProcsPerMinuteStorage.LookupByKey(_options.SpellProcsPerMinuteID);
|
||||
ProcFlags = (ProcFlags)_options.ProcTypeMask;
|
||||
ProcFlags = (ProcFlags)_options.ProcTypeMask[0];
|
||||
ProcChance = _options.ProcChance;
|
||||
ProcCharges = _options.ProcCharges;
|
||||
ProcCooldown = _options.ProcCategoryRecovery;
|
||||
@@ -892,10 +892,34 @@ namespace Game.Spells
|
||||
// continent limitation (virtual continent)
|
||||
if (HasAttribute(SpellAttr4.CastOnlyInOutland))
|
||||
{
|
||||
uint v_map = Global.DB2Mgr.GetVirtualMapForMapAndZone(map_id, zone_id);
|
||||
var map = CliDB.MapStorage.LookupByKey(v_map);
|
||||
if (map == null || map.ExpansionID < 1 || !map.IsContinent())
|
||||
uint mountFlags = 0;
|
||||
if (player && player.HasAuraType(AuraType.MountRestrictions))
|
||||
{
|
||||
foreach (AuraEffect auraEffect in player.GetAuraEffectsByType(AuraType.MountRestrictions))
|
||||
mountFlags |= (uint)auraEffect.GetMiscValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
AreaTableRecord areaTable = CliDB.AreaTableStorage.LookupByKey(area_id);
|
||||
if (areaTable != null)
|
||||
mountFlags = areaTable.MountFlags;
|
||||
}
|
||||
if (!Convert.ToBoolean(mountFlags & (uint)AreaMountFlags.FlyingAllowed))
|
||||
return SpellCastResult.IncorrectArea;
|
||||
|
||||
if (player)
|
||||
{
|
||||
uint mapToCheck = map_id;
|
||||
MapRecord mapEntry1 = CliDB.MapStorage.LookupByKey(map_id);
|
||||
if (mapEntry1 != null)
|
||||
mapToCheck = (uint)mapEntry1.CosmeticParentMapID;
|
||||
if ((mapToCheck == 1116 || mapToCheck == 1464) && !player.HasSpell(191645)) // Draenor Pathfinder
|
||||
return SpellCastResult.IncorrectArea;
|
||||
else if (mapToCheck == 1220 && !player.HasSpell(233368)) // Broken Isles Pathfinder
|
||||
return SpellCastResult.IncorrectArea;
|
||||
else if ((mapToCheck == 1642 || mapToCheck == 1643) && !player.HasSpell(278833)) // Battle for Azeroth Pathfinder
|
||||
return SpellCastResult.IncorrectArea;
|
||||
}
|
||||
}
|
||||
|
||||
var mapEntry = CliDB.MapStorage.LookupByKey(map_id);
|
||||
@@ -2905,9 +2929,9 @@ namespace Game.Spells
|
||||
if (!caster.IsTypeId(TypeId.Player))
|
||||
return 0.0f;
|
||||
|
||||
float crit = caster.GetFloatValue(PlayerFields.CritPercentage);
|
||||
float rangedCrit = caster.GetFloatValue(PlayerFields.RangedCritPercentage);
|
||||
float spellCrit = caster.GetFloatValue(PlayerFields.SpellCritPercentage1);
|
||||
float crit = caster.GetFloatValue(ActivePlayerFields.CritPercentage);
|
||||
float rangedCrit = caster.GetFloatValue(ActivePlayerFields.RangedCritPercentage);
|
||||
float spellCrit = caster.GetFloatValue(ActivePlayerFields.SpellCritPercentage1);
|
||||
|
||||
switch (mod.Param)
|
||||
{
|
||||
@@ -3733,7 +3757,6 @@ namespace Game.Spells
|
||||
Effect = (SpellEffectName)_effect.Effect;
|
||||
ApplyAuraName = (AuraType)_effect.EffectAura;
|
||||
ApplyAuraPeriod = _effect.EffectAuraPeriod;
|
||||
DieSides = (int)_effect.EffectDieSides;
|
||||
RealPointsPerLevel = _effect.EffectRealPointsPerLevel;
|
||||
BasePoints = (int)_effect.EffectBasePoints;
|
||||
PointsPerResource = _effect.EffectPointsPerResource;
|
||||
@@ -3828,10 +3851,57 @@ namespace Game.Spells
|
||||
{
|
||||
variance = 0.0f;
|
||||
float basePointsPerLevel = RealPointsPerLevel;
|
||||
int basePoints = bp.HasValue ? bp.Value : BasePoints;
|
||||
// TODO: this needs to be a float, not rounded
|
||||
int basePoints = CalcBaseValue(caster, target, itemLevel);
|
||||
float value = bp.HasValue ? bp.Value : BasePoints;
|
||||
float comboDamage = PointsPerResource;
|
||||
|
||||
if (Scaling.Variance != 0)
|
||||
{
|
||||
float delta = Math.Abs(Scaling.Variance * 0.5f);
|
||||
float valueVariance = RandomHelper.FRand(-delta, delta);
|
||||
value += basePoints * valueVariance;
|
||||
variance = valueVariance;
|
||||
}
|
||||
|
||||
// base amount modification based on spell lvl vs caster lvl
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
if (Scaling.ResourceCoefficient != 0)
|
||||
comboDamage = Scaling.ResourceCoefficient * value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetScalingExpectedStat() == ExpectedStatType.None)
|
||||
{
|
||||
int level = caster ? (int)caster.getLevel() : 0;
|
||||
if (level > (int)_spellInfo.MaxLevel && _spellInfo.MaxLevel > 0)
|
||||
level = (int)_spellInfo.MaxLevel;
|
||||
level -= (int)_spellInfo.BaseLevel;
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
value += level * basePointsPerLevel;
|
||||
}
|
||||
}
|
||||
// random damage
|
||||
if (caster)
|
||||
{
|
||||
// bonus amount from combo points
|
||||
if (caster.m_playerMovingMe && comboDamage != 0)
|
||||
{
|
||||
uint comboPoints = caster.m_playerMovingMe.GetComboPoints();
|
||||
if (comboPoints != 0)
|
||||
value += comboDamage * comboPoints;
|
||||
}
|
||||
|
||||
value = caster.ApplyEffectModifiers(_spellInfo, EffectIndex, value);
|
||||
}
|
||||
|
||||
return (int)Math.Round(value);
|
||||
}
|
||||
|
||||
public int CalcBaseValue(Unit caster, Unit target, int itemLevel)
|
||||
{
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
uint level = _spellInfo.SpellLevel;
|
||||
@@ -3855,153 +3925,57 @@ namespace Game.Spells
|
||||
if (_spellInfo.Scaling._Class == 0)
|
||||
return 0;
|
||||
|
||||
if (_spellInfo.Scaling.ScalesFromItemLevel == 0)
|
||||
uint effectiveItemLevel = itemLevel != -1 ? (uint)itemLevel : 1u;
|
||||
if (_spellInfo.Scaling.ScalesFromItemLevel != 0 || _spellInfo.HasAttribute(SpellAttr11.ScalesWithItemLevel))
|
||||
{
|
||||
if (!_spellInfo.HasAttribute(SpellAttr11.ScalesWithItemLevel))
|
||||
tempValue = CliDB.GetSpellScalingColumnForClass(CliDB.SpellScalingGameTable.GetRow(level), _spellInfo.Scaling._Class);
|
||||
else
|
||||
if (_spellInfo.Scaling.ScalesFromItemLevel != 0)
|
||||
effectiveItemLevel = _spellInfo.Scaling.ScalesFromItemLevel;
|
||||
|
||||
if (_spellInfo.Scaling._Class == -8)
|
||||
{
|
||||
uint effectiveItemLevel = (uint)(itemLevel != -1 ? itemLevel : 1);
|
||||
tempValue = ItemEnchantment.GetRandomPropertyPoints(effectiveItemLevel, ItemQuality.Rare, InventoryType.Chest, 0);
|
||||
if (IsAura() && ApplyAuraName == AuraType.ModRating)
|
||||
{
|
||||
GtCombatRatingsMultByILvlRecord ratingMult = CliDB.CombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel);
|
||||
if (ratingMult != null)
|
||||
tempValue *= ratingMult.ArmorMultiplier;
|
||||
}
|
||||
RandPropPointsRecord randPropPoints = CliDB.RandPropPointsStorage.LookupByKey(effectiveItemLevel);
|
||||
if (randPropPoints == null)
|
||||
randPropPoints = CliDB.RandPropPointsStorage.LookupByKey(CliDB.RandPropPointsStorage.Count - 1);
|
||||
|
||||
tempValue = randPropPoints.DamageReplaceStat;
|
||||
}
|
||||
else
|
||||
tempValue = ItemEnchantment.GetRandomPropertyPoints(effectiveItemLevel, ItemQuality.Rare, InventoryType.Chest, 0);
|
||||
}
|
||||
else
|
||||
tempValue = ItemEnchantment.GetRandomPropertyPoints(_spellInfo.Scaling.ScalesFromItemLevel, ItemQuality.Rare, InventoryType.Chest, 0);
|
||||
tempValue = CliDB.GetSpellScalingColumnForClass(CliDB.SpellScalingGameTable.GetRow(level), _spellInfo.Scaling._Class);
|
||||
|
||||
if (_spellInfo.Scaling._Class == -7)
|
||||
{
|
||||
// todo: get inventorytype here
|
||||
GtCombatRatingsMultByILvlRecord ratingMult = CliDB.CombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel);
|
||||
if (ratingMult != null)
|
||||
tempValue *= ratingMult.ArmorMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
tempValue *= Scaling.Coefficient;
|
||||
if (tempValue != 0.0f && tempValue < 1.0f)
|
||||
tempValue = 1.0f;
|
||||
|
||||
if (Scaling.Variance != 0f)
|
||||
{
|
||||
float delta = Math.Abs(Scaling.Variance * 0.5f);
|
||||
float valueVariance = RandomHelper.FRand(-delta, delta);
|
||||
tempValue += tempValue * valueVariance;
|
||||
|
||||
variance = valueVariance;
|
||||
}
|
||||
|
||||
basePoints = (int)Math.Round(tempValue);
|
||||
|
||||
if (Scaling.ResourceCoefficient != 0f)
|
||||
comboDamage = Scaling.ResourceCoefficient * tempValue;
|
||||
return (int)Math.Round(tempValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (caster != null)
|
||||
float tempValue = BasePoints;
|
||||
ExpectedStatType stat = GetScalingExpectedStat();
|
||||
if (stat != ExpectedStatType.None)
|
||||
{
|
||||
int level = (int)caster.getLevel();
|
||||
if (level > _spellInfo.MaxLevel && _spellInfo.MaxLevel > 0)
|
||||
level = (int)_spellInfo.MaxLevel;
|
||||
else if (level < _spellInfo.BaseLevel)
|
||||
level = (int)_spellInfo.BaseLevel;
|
||||
if (_spellInfo.HasAttribute(SpellAttr0.LevelDamageCalculation))
|
||||
stat = ExpectedStatType.CreatureAutoAttackDps;
|
||||
|
||||
level -= (int)_spellInfo.SpellLevel;
|
||||
basePoints += (int)(level * basePointsPerLevel);
|
||||
// TODO - add expansion and content tuning id args?
|
||||
uint level = caster ? caster.getLevel() : 1;
|
||||
tempValue = Global.DB2Mgr.EvaluateExpectedStat(stat, level, -2, 0, Class.None) * BasePoints / 100.0f;
|
||||
}
|
||||
|
||||
// roll in a range <1;EffectDieSides> as of patch 3.3.3
|
||||
int randomPoints = DieSides;
|
||||
switch (randomPoints)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
basePoints += 1;
|
||||
break; // range 1..1
|
||||
default:
|
||||
{
|
||||
// range can have positive (1..rand) and negative (rand..1) values, so order its for irand
|
||||
int randvalue = (randomPoints >= 1) ? RandomHelper.IRand(1, randomPoints) : RandomHelper.IRand(randomPoints, 1);
|
||||
|
||||
basePoints += randvalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int)Math.Round(tempValue);
|
||||
}
|
||||
|
||||
float value = (float)basePoints;
|
||||
|
||||
// random damage
|
||||
if (caster != null)
|
||||
{
|
||||
// bonus amount from combo points
|
||||
if (caster.m_playerMovingMe != null && comboDamage != 0)
|
||||
{
|
||||
byte comboPoints = caster.m_playerMovingMe.GetComboPoints();
|
||||
if (comboPoints != 0)
|
||||
value += comboDamage * comboPoints;
|
||||
}
|
||||
|
||||
value = caster.ApplyEffectModifiers(_spellInfo, EffectIndex, value);
|
||||
|
||||
if (!caster.IsControlledByPlayer() && _spellInfo.SpellLevel != 0 && _spellInfo.SpellLevel != caster.getLevel() &&
|
||||
basePointsPerLevel == 0 && _spellInfo.HasAttribute(SpellAttr0.LevelDamageCalculation))
|
||||
{
|
||||
bool canEffectScale = false;
|
||||
switch (Effect)
|
||||
{
|
||||
case SpellEffectName.SchoolDamage:
|
||||
case SpellEffectName.Dummy:
|
||||
case SpellEffectName.PowerDrain:
|
||||
case SpellEffectName.HealthLeech:
|
||||
case SpellEffectName.Heal:
|
||||
case SpellEffectName.WeaponDamage:
|
||||
case SpellEffectName.PowerBurn:
|
||||
case SpellEffectName.ScriptEffect:
|
||||
case SpellEffectName.NormalizedWeaponDmg:
|
||||
case SpellEffectName.ForceCastWithValue:
|
||||
case SpellEffectName.TriggerSpellWithValue:
|
||||
case SpellEffectName.TriggerMissileSpellWithValue:
|
||||
canEffectScale = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ApplyAuraName)
|
||||
{
|
||||
case AuraType.PeriodicDamage:
|
||||
case AuraType.Dummy:
|
||||
case AuraType.PeriodicHeal:
|
||||
case AuraType.DamageShield:
|
||||
case AuraType.ProcTriggerDamage:
|
||||
case AuraType.PeriodicLeech:
|
||||
case AuraType.PeriodicManaLeech:
|
||||
case AuraType.SchoolAbsorb:
|
||||
case AuraType.PeriodicTriggerSpellWithValue:
|
||||
canEffectScale = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (canEffectScale)
|
||||
{
|
||||
GtNpcManaCostScalerRecord spellScaler = CliDB.NpcManaCostScalerGameTable.GetRow(_spellInfo.SpellLevel);
|
||||
GtNpcManaCostScalerRecord casterScaler = CliDB.NpcManaCostScalerGameTable.GetRow(caster.getLevel());
|
||||
if (spellScaler != null && casterScaler != null)
|
||||
value *= casterScaler.Scaler / spellScaler.Scaler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
public int CalcBaseValue(int value)
|
||||
{
|
||||
if (DieSides == 0)
|
||||
return value;
|
||||
else
|
||||
return value - 1;
|
||||
}
|
||||
|
||||
public float CalcValueMultiplier(Unit caster, Spell spell = null)
|
||||
@@ -4098,6 +4072,94 @@ namespace Game.Spells
|
||||
return _data[(int)Effect].UsedTargetObjectType;
|
||||
}
|
||||
|
||||
ExpectedStatType GetScalingExpectedStat()
|
||||
{
|
||||
switch (Effect)
|
||||
{
|
||||
case SpellEffectName.SchoolDamage:
|
||||
case SpellEffectName.EnvironmentalDamage:
|
||||
case SpellEffectName.HealthLeech:
|
||||
case SpellEffectName.WeaponDamageNoschool:
|
||||
case SpellEffectName.WeaponDamage:
|
||||
return ExpectedStatType.CreatureSpellDamage;
|
||||
case SpellEffectName.Heal:
|
||||
case SpellEffectName.HealMechanical:
|
||||
return ExpectedStatType.PlayerHealth;
|
||||
case SpellEffectName.Energize:
|
||||
case SpellEffectName.PowerBurn:
|
||||
if (MiscValue == 0)
|
||||
return ExpectedStatType.PlayerMana;
|
||||
return ExpectedStatType.None;
|
||||
case SpellEffectName.PowerDrain:
|
||||
return ExpectedStatType.PlayerMana;
|
||||
case SpellEffectName.ApplyAura:
|
||||
case SpellEffectName.PersistentAreaAura:
|
||||
case SpellEffectName.ApplyAreaAuraParty:
|
||||
case SpellEffectName.ApplyAreaAuraRaid:
|
||||
case SpellEffectName.ApplyAreaAuraPet:
|
||||
case SpellEffectName.ApplyAreaAuraFriend:
|
||||
case SpellEffectName.ApplyAreaAuraEnemy:
|
||||
case SpellEffectName.ApplyAreaAuraOwner:
|
||||
case SpellEffectName.ApllyAuraOnPet:
|
||||
case SpellEffectName.Unk202:
|
||||
switch (ApplyAuraName)
|
||||
{
|
||||
case AuraType.PeriodicDamage:
|
||||
case AuraType.ModDamageDone:
|
||||
case AuraType.DamageShield:
|
||||
case AuraType.ProcTriggerDamage:
|
||||
case AuraType.PeriodicLeech:
|
||||
case AuraType.ModDamageDoneCreature:
|
||||
case AuraType.PeriodicHealthFunnel:
|
||||
case AuraType.ModMeleeAttackPowerVersus:
|
||||
case AuraType.ModRangedAttackPowerVersus:
|
||||
case AuraType.ModFlatSpellDamageVersus:
|
||||
return ExpectedStatType.CreatureSpellDamage;
|
||||
case AuraType.PeriodicHeal:
|
||||
case AuraType.ModDamageTaken:
|
||||
case AuraType.ModIncreaseHealth:
|
||||
case AuraType.SchoolAbsorb:
|
||||
case AuraType.ModRegen:
|
||||
case AuraType.ManaShield:
|
||||
case AuraType.ModHealing:
|
||||
case AuraType.ModHealingDone:
|
||||
case AuraType.ModHealthRegenInCombat:
|
||||
case AuraType.ModMaxHealth:
|
||||
case AuraType.ModIncreaseHealth2:
|
||||
case AuraType.SchoolHealAbsorb:
|
||||
return ExpectedStatType.PlayerHealth;
|
||||
case AuraType.PeriodicManaLeech:
|
||||
return ExpectedStatType.PlayerMana;
|
||||
case AuraType.ModStat:
|
||||
case AuraType.ModAttackPower:
|
||||
case AuraType.ModRangedAttackPower:
|
||||
return ExpectedStatType.PlayerPrimaryStat;
|
||||
case AuraType.ModRating:
|
||||
return ExpectedStatType.PlayerSecondaryStat;
|
||||
case AuraType.ModResistance:
|
||||
case AuraType.ModBaseResistance:
|
||||
case AuraType.ModTargetResistance:
|
||||
case AuraType.ModBonusArmor:
|
||||
return ExpectedStatType.ArmorConstant;
|
||||
case AuraType.PeriodicEnergize:
|
||||
case AuraType.ModIncreaseEnergy:
|
||||
case AuraType.ModPowerCostSchool:
|
||||
case AuraType.ModPowerRegen:
|
||||
case AuraType.PowerBurn:
|
||||
case AuraType.ModMaxPower:
|
||||
if (MiscValue == 0)
|
||||
return ExpectedStatType.PlayerMana;
|
||||
return ExpectedStatType.None;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ExpectedStatType.None;
|
||||
}
|
||||
|
||||
public ImmunityInfo GetImmunityInfo() { return _immunityInfo; }
|
||||
|
||||
public class StaticData
|
||||
@@ -4370,7 +4432,13 @@ namespace Game.Spells
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 252 SPELL_EFFECT_252
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 253 SPELL_EFFECT_GIVE_HONOR
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 254 SPELL_EFFECT_254
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit) // 255 SPELL_EFFECT_LEARN_TRANSMOG_SET
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 255 SPELL_EFFECT_LEARN_TRANSMOG_SET
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 256 SPELL_EFFECT_256
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 257 SPELL_EFFECT_257
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 258 SPELL_EFFECT_MODIFY_KEYSTONE
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 259 SPELL_EFFECT_RESPEC_AZERITE_EMPOWERED_ITEM
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 260 SPELL_EFFECT_SUMMON_STABLED_PET
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 261 SPELL_EFFECT_SCRAP_ITEM
|
||||
};
|
||||
|
||||
#region Fields
|
||||
@@ -4380,7 +4448,6 @@ namespace Game.Spells
|
||||
public SpellEffectName Effect;
|
||||
public AuraType ApplyAuraName;
|
||||
public uint ApplyAuraPeriod;
|
||||
public int DieSides;
|
||||
public float RealPointsPerLevel;
|
||||
public int BasePoints;
|
||||
public float PointsPerResource;
|
||||
@@ -4741,8 +4808,9 @@ namespace Game.Spells
|
||||
new StaticData(SpellTargetObjectTypes.None, SpellTargetReferenceTypes.None, SpellTargetSelectionCategories.Nyi, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 145
|
||||
new StaticData(SpellTargetObjectTypes.None, SpellTargetReferenceTypes.None, SpellTargetSelectionCategories.Nyi, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 146
|
||||
new StaticData(SpellTargetObjectTypes.None, SpellTargetReferenceTypes.None, SpellTargetSelectionCategories.Nyi, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 147
|
||||
new StaticData(SpellTargetObjectTypes.None, SpellTargetReferenceTypes.None, SpellTargetSelectionCategories.Nyi, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 148)
|
||||
new StaticData(SpellTargetObjectTypes.Dest, SpellTargetReferenceTypes.Caster, SpellTargetSelectionCategories.Default, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.Random), // 149)
|
||||
new StaticData(SpellTargetObjectTypes.None, SpellTargetReferenceTypes.None, SpellTargetSelectionCategories.Nyi, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 148
|
||||
new StaticData(SpellTargetObjectTypes.Dest, SpellTargetReferenceTypes.Caster, SpellTargetSelectionCategories.Default, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.Random), // 149
|
||||
new StaticData(SpellTargetObjectTypes.Unit, SpellTargetReferenceTypes.Caster, SpellTargetSelectionCategories.Default, SpellTargetCheckTypes.Default, SpellTargetDirectionTypes.None), // 150
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1356,14 +1356,30 @@ namespace Game.Entities
|
||||
procEntry.SpellPhaseMask = ProcFlagsSpellPhase.Hit;
|
||||
procEntry.HitMask = ProcFlagsHit.None; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
|
||||
|
||||
// Reflect auras should only proc off reflects
|
||||
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
|
||||
{
|
||||
if (effect != null && (effect.IsAura(AuraType.ReflectSpells) || effect.IsAura(AuraType.ReflectSpellsSchool)))
|
||||
if (effect == null || !effect.IsAura())
|
||||
continue;
|
||||
|
||||
switch (effect.ApplyAuraName)
|
||||
{
|
||||
procEntry.HitMask = ProcFlagsHit.Reflect;
|
||||
break;
|
||||
// Reflect auras should only proc off reflects
|
||||
case AuraType.ReflectSpells:
|
||||
case AuraType.ReflectSpellsSchool:
|
||||
procEntry.HitMask = ProcFlagsHit.Reflect;
|
||||
break;
|
||||
// Only drop charge on crit
|
||||
case AuraType.ModWeaponCritPercent:
|
||||
procEntry.HitMask = ProcFlagsHit.Critical;
|
||||
break;
|
||||
// Only drop charge on block
|
||||
case AuraType.ModBlockPercent:
|
||||
procEntry.HitMask = ProcFlagsHit.Block;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
procEntry.AttributesMask = 0;
|
||||
@@ -1633,7 +1649,7 @@ namespace Game.Entities
|
||||
if (skillLine.SkillLine != creatureFamily.SkillLine[j])
|
||||
continue;
|
||||
|
||||
if (skillLine.AcquireMethod != AbilytyLearnType.OnSkillLearn)
|
||||
if (skillLine.AcquireMethod != AbilityLearnType.OnSkillLearn)
|
||||
continue;
|
||||
|
||||
SpellInfo spell = GetSpellInfo(skillLine.Spell);
|
||||
@@ -1783,7 +1799,7 @@ namespace Game.Entities
|
||||
spellArea.questEndStatus = result.Read<uint>(4);
|
||||
spellArea.questEnd = result.Read<uint>(5);
|
||||
spellArea.auraSpell = result.Read<int>(6);
|
||||
spellArea.raceMask = result.Read<uint>(7);
|
||||
spellArea.raceMask = result.Read<ulong>(7);
|
||||
spellArea.gender = (Gender)result.Read<uint>(8);
|
||||
spellArea.flags = (SpellAreaFlag)result.Read<byte>(9);
|
||||
|
||||
@@ -1971,7 +1987,7 @@ namespace Game.Entities
|
||||
effectsBySpell[effect.SpellID][effect.DifficultyID][effect.EffectIndex] = effect;
|
||||
}
|
||||
|
||||
foreach (var spell in CliDB.SpellStorage.Values)
|
||||
foreach (var spell in CliDB.SpellNameStorage.Values)
|
||||
loadData[spell.Id] = new SpellInfoLoadHelper();
|
||||
|
||||
foreach (SpellAuraOptionsRecord auraOptions in CliDB.SpellAuraOptionsStorage.Values)
|
||||
@@ -2068,13 +2084,13 @@ namespace Game.Entities
|
||||
visualsBySpell[visual.SpellID].Add(visual.DifficultyID, visual);
|
||||
}
|
||||
|
||||
foreach (var spellEntry in CliDB.SpellStorage.Values)
|
||||
foreach (var spellEntry in CliDB.SpellNameStorage.Values)
|
||||
{
|
||||
loadData[spellEntry.Id].Entry = spellEntry;
|
||||
mSpellInfoMap[spellEntry.Id] = new SpellInfo(loadData[spellEntry.Id], effectsBySpell.LookupByKey(spellEntry.Id), visualsBySpell.LookupByKey(spellEntry.Id));
|
||||
}
|
||||
|
||||
CliDB.SpellStorage.Clear();
|
||||
CliDB.SpellNameStorage.Clear();
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo store in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
@@ -2483,6 +2499,8 @@ namespace Game.Entities
|
||||
break;
|
||||
case 50661:// Weakened Resolve
|
||||
case 68979:// Unleashed Souls
|
||||
case 48714:// Compelled
|
||||
case 7853: // The Art of Being a Water Terror: Force Cast on Player
|
||||
spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(13); // 50000yd
|
||||
break;
|
||||
// VIOLET HOLD SPELLS
|
||||
@@ -2903,7 +2921,7 @@ namespace Game.Entities
|
||||
if (skillLine.SkillLine != cFamily.SkillLine[0] && skillLine.SkillLine != cFamily.SkillLine[1])
|
||||
continue;
|
||||
|
||||
if (skillLine.AcquireMethod != AbilytyLearnType.OnSkillLearn)
|
||||
if (skillLine.AcquireMethod != AbilityLearnType.OnSkillLearn)
|
||||
continue;
|
||||
|
||||
Global.SpellMgr.PetFamilySpellsStorage.Add(cFamily.Id, spellInfo.Id);
|
||||
@@ -2998,6 +3016,15 @@ namespace Game.Entities
|
||||
case AuraType.ProcTriggerSpellWithValue:
|
||||
case AuraType.ModSpellDamageFromCaster:
|
||||
case AuraType.AbilityIgnoreAurastate:
|
||||
case AuraType.ModInvisibility:
|
||||
case AuraType.ForceReaction:
|
||||
case AuraType.ModTaunt:
|
||||
case AuraType.ModDetaunt:
|
||||
case AuraType.ModDamagePercentDone:
|
||||
case AuraType.ModAttackPowerPct:
|
||||
case AuraType.ModHitChance:
|
||||
case AuraType.ModWeaponCritPercent:
|
||||
case AuraType.ModBlockPercent:
|
||||
case AuraType.ModRoot2:
|
||||
return true;
|
||||
}
|
||||
@@ -3014,6 +3041,7 @@ namespace Game.Entities
|
||||
case AuraType.ModRoot:
|
||||
case AuraType.ModStun:
|
||||
case AuraType.Transform:
|
||||
case AuraType.ModInvisibility:
|
||||
case AuraType.SpellMagnet:
|
||||
case AuraType.SchoolAbsorb:
|
||||
case AuraType.ModRoot2:
|
||||
@@ -3033,6 +3061,7 @@ namespace Game.Entities
|
||||
case AuraType.ModRoot2:
|
||||
case AuraType.ModStun:
|
||||
case AuraType.Transform:
|
||||
case AuraType.ModInvisibility:
|
||||
return ProcFlagsSpellType.Damage;
|
||||
default:
|
||||
return ProcFlagsSpellType.MaskAll;
|
||||
@@ -3117,7 +3146,7 @@ namespace Game.Entities
|
||||
|
||||
public bool IsProfessionSkill(uint skill)
|
||||
{
|
||||
return IsPrimaryProfessionSkill(skill) || skill == (uint)SkillType.Fishing || skill == (uint)SkillType.Cooking || skill == (uint)SkillType.FirstAid;
|
||||
return IsPrimaryProfessionSkill(skill) || skill == (uint)SkillType.Fishing || skill == (uint)SkillType.Cooking;
|
||||
}
|
||||
|
||||
public bool IsPartOfSkillLine(SkillType skillId, uint spellId)
|
||||
@@ -3209,7 +3238,7 @@ namespace Game.Entities
|
||||
|
||||
public class SpellInfoLoadHelper
|
||||
{
|
||||
public SpellRecord Entry;
|
||||
public SpellNameRecord Entry;
|
||||
|
||||
public SpellAuraOptionsRecord AuraOptions;
|
||||
public SpellAuraRestrictionsRecord AuraRestrictions;
|
||||
@@ -3263,7 +3292,7 @@ namespace Game.Entities
|
||||
public uint questStart; // quest start (quest must be active or rewarded for spell apply)
|
||||
public uint questEnd; // quest end (quest must not be rewarded for spell apply)
|
||||
public int auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case
|
||||
public uint raceMask; // can be applied only to races
|
||||
public ulong raceMask; // can be applied only to races
|
||||
public Gender gender; // can be applied only to gender
|
||||
public uint questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
|
||||
public uint questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
|
||||
|
||||
Reference in New Issue
Block a user