Core/Spells: Load entire proc flags array from db2
Port From (https://github.com/TrinityCore/TrinityCore/commit/3844c79adb749432b0f41b9b1aecde7287b9f765)
This commit is contained in:
@@ -2507,6 +2507,15 @@ namespace Framework.Constants
|
||||
MeleeBasedTriggerMask = (DoneMeleeAutoAttack | TakenMeleeAutoAttack | DoneSpellMeleeDmgClass | TakenSpellMeleeDmgClass |
|
||||
DoneRangedAutoAttack | TakenRangedAutoAttack | DoneSpellRangedDmgClass | TakenSpellRangedDmgClass)
|
||||
}
|
||||
|
||||
public enum ProcFlags2
|
||||
{
|
||||
None = 0x00,
|
||||
TargetDies = 0x01,
|
||||
Knockback = 0x02,
|
||||
CastSuccessful = 0x04
|
||||
}
|
||||
|
||||
public enum ProcFlagsSpellPhase
|
||||
{
|
||||
None = 0x0,
|
||||
|
||||
@@ -19,104 +19,119 @@ using System;
|
||||
|
||||
namespace Framework.Dynamic
|
||||
{
|
||||
public class FlagArray128
|
||||
public class FlagsArray<T> where T : struct
|
||||
{
|
||||
public FlagArray128(params uint[] parts)
|
||||
protected dynamic[] _storage;
|
||||
|
||||
public FlagsArray(uint length)
|
||||
{
|
||||
_values = new uint[4];
|
||||
for (var i = 0; i < parts.Length; ++i)
|
||||
_values[i] = parts[i];
|
||||
_storage = new dynamic[length];
|
||||
}
|
||||
|
||||
public FlagArray128(int[] parts)
|
||||
public FlagsArray(params T[] parts)
|
||||
{
|
||||
_values = new uint[4];
|
||||
_storage = new dynamic[parts.Length];
|
||||
for (var i = 0; i < parts.Length; ++i)
|
||||
_values[i] = (uint)parts[i];
|
||||
_storage[i] = parts[i];
|
||||
}
|
||||
|
||||
public FlagsArray(T[] parts, uint length)
|
||||
{
|
||||
_storage = new dynamic[length];
|
||||
for (var i = 0; i < length && i < parts.Length; ++i)
|
||||
_storage[i] = parts[i];
|
||||
}
|
||||
|
||||
public static bool operator <(FlagsArray<T> left, FlagsArray<T> right)
|
||||
{
|
||||
for (var i = left._storage.Length; i > 0; --i)
|
||||
{
|
||||
if ((dynamic)left._storage[i - 1] < right._storage[i - 1])
|
||||
return true;
|
||||
else if ((dynamic)left._storage[i - 1] > right._storage[i - 1])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool operator >(FlagsArray<T> left, FlagsArray<T> right)
|
||||
{
|
||||
for (var i = left._storage.Length; i > 0; --i)
|
||||
{
|
||||
if ((dynamic)left._storage[i - 1] > right._storage[i - 1])
|
||||
return true;
|
||||
else if ((dynamic)left._storage[i - 1] < right._storage[i - 1])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static FlagArray128 operator &(FlagsArray<T> left, FlagsArray<T> right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._storage.Length; ++i)
|
||||
fl[i] = left._storage[i] & right._storage[i];
|
||||
return fl;
|
||||
}
|
||||
public static FlagArray128 operator |(FlagsArray<T> left, FlagsArray<T> right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._storage.Length; ++i)
|
||||
fl[i] = left._storage[i] | right._storage[i];
|
||||
return fl;
|
||||
}
|
||||
public static FlagArray128 operator ^(FlagsArray<T> left, FlagsArray<T> right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._storage.Length; ++i)
|
||||
fl[i] = left._storage[i] ^ right._storage[i];
|
||||
return fl;
|
||||
}
|
||||
|
||||
public static implicit operator bool(FlagsArray<T> left)
|
||||
{
|
||||
for (var i = 0; i < left._storage.Length; ++i)
|
||||
if (left._storage[i] != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public T this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _storage[i];
|
||||
}
|
||||
set
|
||||
{
|
||||
_storage[i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FlagArray128 : FlagsArray<uint>
|
||||
{
|
||||
public FlagArray128(params uint[] parts) : base(parts, 4) { }
|
||||
|
||||
public bool IsEqual(params uint[] parts)
|
||||
{
|
||||
for (var i = 0; i < _values.Length; ++i)
|
||||
if (_values[i] == parts[i])
|
||||
for (var i = 0; i < _storage.Length; ++i)
|
||||
if (_storage[i] == parts[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HasFlag(params uint[] parts)
|
||||
{
|
||||
return (_storage[0] & parts[0] || _storage[1] & parts[1] || _storage[2] & parts[2] || _storage[3] & parts[3]);
|
||||
}
|
||||
|
||||
public void Set(params uint[] parts)
|
||||
{
|
||||
for (var i = 0; i < parts.Length; ++i)
|
||||
_values[i] = parts[i];
|
||||
_storage[i] = parts[i];
|
||||
}
|
||||
|
||||
public static bool operator <(FlagArray128 left, FlagArray128 right)
|
||||
{
|
||||
for (var i = left._values.Length; i > 0; --i)
|
||||
{
|
||||
if (left._values[i - 1] < right._values[i - 1])
|
||||
return true;
|
||||
else if (left._values[i - 1] > right._values[i - 1])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool operator >(FlagArray128 left, FlagArray128 right)
|
||||
{
|
||||
for (var i = left._values.Length; i > 0; --i)
|
||||
{
|
||||
if (left._values[i - 1] > right._values[i - 1])
|
||||
return true;
|
||||
else if (left._values[i - 1] < right._values[i - 1])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static FlagArray128 operator &(FlagArray128 left, FlagArray128 right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._values.Length; ++i)
|
||||
fl[i] = left._values[i] & right._values[i];
|
||||
return fl;
|
||||
}
|
||||
public static FlagArray128 operator |(FlagArray128 left, FlagArray128 right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._values.Length; ++i)
|
||||
fl[i] = left._values[i] | right._values[i];
|
||||
return fl;
|
||||
}
|
||||
public static FlagArray128 operator ^(FlagArray128 left, FlagArray128 right)
|
||||
{
|
||||
FlagArray128 fl = new();
|
||||
for (var i = 0; i < left._values.Length; ++i)
|
||||
fl[i] = left._values[i] ^ right._values[i];
|
||||
return fl;
|
||||
}
|
||||
|
||||
public static implicit operator bool (FlagArray128 left)
|
||||
{
|
||||
for (var i = 0; i < left._values.Length; ++i)
|
||||
if (left._values[i] != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public uint this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _values[i];
|
||||
}
|
||||
set
|
||||
{
|
||||
_values[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
uint[] _values { get; set; }
|
||||
}
|
||||
|
||||
public class FlaggedArray<T> where T : struct
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Game.DataStorage
|
||||
}
|
||||
else if (type == typeof(FlagArray128))
|
||||
{
|
||||
f.SetValue(obj, new FlagArray128(ReadArray<int>(result, dbIndex, 4)));
|
||||
f.SetValue(obj, new FlagArray128(ReadArray<uint>(result, dbIndex, 4)));
|
||||
dbIndex += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Game.Entities
|
||||
InterruptNonMeleeSpells(false);
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnteringCombat);
|
||||
ProcSkillsAndAuras(this, null, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
ProcSkillsAndAuras(this, null, new ProcFlagsInit(ProcFlags.EnterCombat), new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
|
||||
public virtual void AtExitCombat()
|
||||
@@ -793,14 +793,14 @@ namespace Game.Entities
|
||||
// proc only once for victim
|
||||
Unit owner = attacker.GetOwner();
|
||||
if (owner != null)
|
||||
ProcSkillsAndAuras(owner, victim, ProcFlags.Kill, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
ProcSkillsAndAuras(owner, victim, new ProcFlagsInit(ProcFlags.Kill), new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
|
||||
if (!victim.IsCritter())
|
||||
ProcSkillsAndAuras(attacker, victim, ProcFlags.Kill, ProcFlags.Killed, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
ProcSkillsAndAuras(attacker, victim, new ProcFlagsInit(ProcFlags.Kill), new ProcFlagsInit(ProcFlags.Killed), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
|
||||
// Proc auras on death - must be before aura/combat remove
|
||||
ProcSkillsAndAuras(victim, victim, ProcFlags.None, ProcFlags.Death, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
ProcSkillsAndAuras(victim, victim, new ProcFlagsInit(ProcFlags.None), new ProcFlagsInit(ProcFlags.Death), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
|
||||
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
|
||||
// and before Spirit of Redemption as it also removes auras
|
||||
@@ -1026,8 +1026,8 @@ namespace Game.Entities
|
||||
damageInfo.TargetState = 0;
|
||||
|
||||
damageInfo.AttackType = attackType;
|
||||
damageInfo.ProcAttacker = ProcFlags.None;
|
||||
damageInfo.ProcVictim = ProcFlags.None;
|
||||
damageInfo.ProcAttacker = new ProcFlagsInit();
|
||||
damageInfo.ProcVictim = new ProcFlagsInit();
|
||||
damageInfo.CleanDamage = 0;
|
||||
damageInfo.HitOutCome = MeleeHitOutcome.Evade;
|
||||
|
||||
@@ -1041,12 +1041,12 @@ namespace Game.Entities
|
||||
switch (attackType)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
damageInfo.ProcAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneMainHandAttack;
|
||||
damageInfo.ProcVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
damageInfo.ProcAttacker = new ProcFlagsInit(ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneMainHandAttack);
|
||||
damageInfo.ProcVictim = new ProcFlagsInit(ProcFlags.TakenMeleeAutoAttack);
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
damageInfo.ProcAttacker = ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneOffHandAttack;
|
||||
damageInfo.ProcVictim = ProcFlags.TakenMeleeAutoAttack;
|
||||
damageInfo.ProcAttacker = new ProcFlagsInit(ProcFlags.DoneMeleeAutoAttack | ProcFlags.DoneOffHandAttack);
|
||||
damageInfo.ProcVictim = new ProcFlagsInit(ProcFlags.TakenMeleeAutoAttack);
|
||||
damageInfo.HitInfo = HitInfo.OffHand;
|
||||
break;
|
||||
default:
|
||||
@@ -1185,7 +1185,7 @@ namespace Game.Entities
|
||||
// Calculate absorb resist
|
||||
if (damageInfo.Damage > 0)
|
||||
{
|
||||
damageInfo.ProcVictim |= ProcFlags.TakenDamage;
|
||||
damageInfo.ProcVictim.Or(ProcFlags.TakenDamage);
|
||||
// Calculate absorb & resists
|
||||
DamageInfo dmgInfo = new(damageInfo);
|
||||
CalcAbsorbResist(dmgInfo);
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Game.Entities
|
||||
|
||||
public class ProcEventInfo
|
||||
{
|
||||
public ProcEventInfo(Unit actor, Unit actionTarget, Unit procTarget, ProcFlags typeMask, ProcFlagsSpellType spellTypeMask,
|
||||
public ProcEventInfo(Unit actor, Unit actionTarget, Unit procTarget, ProcFlagsInit typeMask, ProcFlagsSpellType spellTypeMask,
|
||||
ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
{
|
||||
_actor = actor;
|
||||
@@ -181,7 +181,7 @@ namespace Game.Entities
|
||||
public Unit GetActionTarget() { return _actionTarget; }
|
||||
public Unit GetProcTarget() { return _procTarget; }
|
||||
|
||||
public ProcFlags GetTypeMask() { return _typeMask; }
|
||||
public ProcFlagsInit GetTypeMask() { return _typeMask; }
|
||||
public ProcFlagsSpellType GetSpellTypeMask() { return _spellTypeMask; }
|
||||
public ProcFlagsSpellPhase GetSpellPhaseMask() { return _spellPhaseMask; }
|
||||
public ProcFlagsHit GetHitMask() { return _hitMask; }
|
||||
@@ -217,7 +217,7 @@ namespace Game.Entities
|
||||
Unit _actor;
|
||||
Unit _actionTarget;
|
||||
Unit _procTarget;
|
||||
ProcFlags _typeMask;
|
||||
ProcFlagsInit _typeMask;
|
||||
ProcFlagsSpellType _spellTypeMask;
|
||||
ProcFlagsSpellPhase _spellPhaseMask;
|
||||
ProcFlagsHit _hitMask;
|
||||
@@ -444,8 +444,8 @@ namespace Game.Entities
|
||||
|
||||
// Helper
|
||||
public WeaponAttackType AttackType { get; set; }
|
||||
public ProcFlags ProcAttacker { get; set; }
|
||||
public ProcFlags ProcVictim { get; set; }
|
||||
public ProcFlagsInit ProcAttacker { get; set; }
|
||||
public ProcFlagsInit ProcVictim { get; set; }
|
||||
public uint CleanDamage { get; set; } // Used only for rage calculation
|
||||
public MeleeHitOutcome HitOutCome { get; set; } // TODO: remove this field (need use TargetState)
|
||||
}
|
||||
|
||||
@@ -1419,28 +1419,28 @@ namespace Game.Entities
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ProcSkillsAndAuras(Unit actor, Unit actionTarget, ProcFlags typeMaskActor, ProcFlags typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
|
||||
public static void ProcSkillsAndAuras(Unit actor, Unit actionTarget, ProcFlagsInit typeMaskActor, ProcFlagsInit typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
{
|
||||
WeaponAttackType attType = damageInfo != null ? damageInfo.GetAttackType() : WeaponAttackType.BaseAttack;
|
||||
if (typeMaskActor != 0 && actor != null)
|
||||
if (typeMaskActor && actor != null)
|
||||
actor.ProcSkillsAndReactives(false, actionTarget, typeMaskActor, hitMask, attType);
|
||||
|
||||
if (typeMaskActionTarget != 0 && actionTarget)
|
||||
if (typeMaskActionTarget && actionTarget)
|
||||
actionTarget.ProcSkillsAndReactives(true, actor, typeMaskActionTarget, hitMask, attType);
|
||||
|
||||
if (actor != null)
|
||||
actor.TriggerAurasProcOnEvent(null, null, actionTarget, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
|
||||
}
|
||||
|
||||
void ProcSkillsAndReactives(bool isVictim, Unit procTarget, ProcFlags typeMask, ProcFlagsHit hitMask, WeaponAttackType attType)
|
||||
void ProcSkillsAndReactives(bool isVictim, Unit procTarget, ProcFlagsInit typeMask, ProcFlagsHit hitMask, WeaponAttackType attType)
|
||||
{
|
||||
// Player is loaded now - do not allow passive spell casts to proc
|
||||
if (IsPlayer() && ToPlayer().GetSession().PlayerLoading())
|
||||
return;
|
||||
|
||||
// For melee/ranged based attack need update skills and set some Aura states if victim present
|
||||
if (typeMask.HasAnyFlag(ProcFlags.MeleeBasedTriggerMask) && procTarget)
|
||||
if (typeMask.HasFlag(ProcFlags.MeleeBasedTriggerMask) && procTarget)
|
||||
{
|
||||
// If exist crit/parry/dodge/block need update aura state (for victim and attacker)
|
||||
if (hitMask.HasAnyFlag(ProcFlagsHit.Critical | ProcFlagsHit.Parry | ProcFlagsHit.Dodge | ProcFlagsHit.Block))
|
||||
@@ -1508,12 +1508,12 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerAurasProcOnEvent(List<AuraApplication> myProcAuras, List<AuraApplication> targetProcAuras, Unit actionTarget, ProcFlags typeMaskActor, ProcFlags typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
void TriggerAurasProcOnEvent(List<AuraApplication> myProcAuras, List<AuraApplication> targetProcAuras, Unit actionTarget, ProcFlagsInit typeMaskActor, ProcFlagsInit typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
|
||||
{
|
||||
// prepare data for self trigger
|
||||
ProcEventInfo myProcEventInfo = new(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
|
||||
List<Tuple<uint, AuraApplication>> myAurasTriggeringProc = new();
|
||||
if (typeMaskActor != 0)
|
||||
if (typeMaskActor)
|
||||
{
|
||||
GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo);
|
||||
|
||||
@@ -1537,12 +1537,12 @@ namespace Game.Entities
|
||||
// prepare data for target trigger
|
||||
ProcEventInfo targetProcEventInfo = new(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
|
||||
List<Tuple<uint, AuraApplication>> targetAurasTriggeringProc = new();
|
||||
if (typeMaskActionTarget != 0 && actionTarget)
|
||||
if (typeMaskActionTarget && actionTarget)
|
||||
actionTarget.GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo);
|
||||
|
||||
TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc);
|
||||
|
||||
if (typeMaskActionTarget != 0 && actionTarget)
|
||||
if (typeMaskActionTarget && actionTarget)
|
||||
actionTarget.TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc);
|
||||
}
|
||||
|
||||
|
||||
@@ -3513,7 +3513,7 @@ namespace Game.Entities
|
||||
caster.SendSpellNonMeleeDamageLog(log);
|
||||
|
||||
// break 'Fear' and similar auras
|
||||
ProcSkillsAndAuras(damageInfo.GetAttacker(), caster, ProcFlags.None, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.Hit, ProcFlagsHit.None, null, damageInfo, null);
|
||||
ProcSkillsAndAuras(damageInfo.GetAttacker(), caster, new ProcFlagsInit(ProcFlags.None), new ProcFlagsInit(ProcFlags.TakenSpellMagicDmgClassNeg), ProcFlagsSpellType.Damage, ProcFlagsSpellPhase.Hit, ProcFlagsHit.None, null, damageInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ using Game.Maps;
|
||||
using Game.Movement;
|
||||
using Game.Networking;
|
||||
using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -205,7 +206,7 @@ namespace Game
|
||||
if (opcode == ClientOpcodes.MoveJump)
|
||||
{
|
||||
plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.Jump); // Mind Control
|
||||
Unit.ProcSkillsAndAuras(plrMover, null, ProcFlags.Jump, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
Unit.ProcSkillsAndAuras(plrMover, null, new ProcFlagsInit(ProcFlags.Jump), new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ using Game.Entities;
|
||||
using Game.Groups;
|
||||
using Game.Networking.Packets;
|
||||
using Game.Scenarios;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@@ -367,7 +368,7 @@ namespace Game.Maps
|
||||
var playerList = instance.GetPlayers();
|
||||
foreach (var player in playerList)
|
||||
if (player.IsAlive())
|
||||
Unit.ProcSkillsAndAuras(player, null, ProcFlags.EncounterStart, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
Unit.ProcSkillsAndAuras(player, null, new ProcFlagsInit(ProcFlags.EncounterStart), new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
break;
|
||||
}
|
||||
case EncounterState.Fail:
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Game.Spells
|
||||
case AuraType.Transform:
|
||||
case AuraType.ModRoot2:
|
||||
m_canBeRecalculated = false;
|
||||
if (m_spellInfo.ProcFlags == 0)
|
||||
if (!m_spellInfo.ProcFlags)
|
||||
break;
|
||||
amount = (int)(GetBase().GetUnitOwner().CountPctFromMaxHealth(10));
|
||||
break;
|
||||
@@ -5065,14 +5065,14 @@ namespace Game.Spells
|
||||
Unit.DealDamageMods(caster, target, ref damage, ref absorb);
|
||||
|
||||
// Set trigger flag
|
||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||
ProcFlagsInit procAttacker = new ProcFlagsInit(ProcFlags.DonePeriodic);
|
||||
ProcFlagsInit procVictim = new ProcFlagsInit(ProcFlags.TakenPeriodic);
|
||||
ProcFlagsHit hitMask = damageInfo.GetHitMask();
|
||||
|
||||
if (damage != 0)
|
||||
{
|
||||
hitMask |= crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
||||
procVictim |= ProcFlags.TakenDamage;
|
||||
procVictim.Or(ProcFlags.TakenDamage);
|
||||
}
|
||||
|
||||
int overkill = (int)(damage - target.GetHealth());
|
||||
@@ -5156,14 +5156,14 @@ namespace Game.Spells
|
||||
log.HitInfo |= HitInfo.CriticalHit;
|
||||
|
||||
// Set trigger flag
|
||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||
ProcFlagsInit procAttacker = new ProcFlagsInit(ProcFlags.DonePeriodic);
|
||||
ProcFlagsInit procVictim = new ProcFlagsInit(ProcFlags.TakenPeriodic);
|
||||
ProcFlagsHit hitMask = damageInfo.GetHitMask();
|
||||
|
||||
if (damage != 0)
|
||||
{
|
||||
hitMask |= crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
||||
procVictim |= ProcFlags.TakenDamage;
|
||||
procVictim.Or(ProcFlags.TakenDamage);
|
||||
}
|
||||
|
||||
int new_damage = (int)Unit.DealDamage(caster, target, damage, cleanDamage, DamageEffectType.DOT, GetSpellInfo().GetSchoolMask(), GetSpellInfo(), false);
|
||||
@@ -5182,7 +5182,7 @@ namespace Game.Spells
|
||||
caster.HealBySpell(healInfo);
|
||||
|
||||
caster.GetThreatManager().ForwardThreatForAssistingMe(caster, healInfo.GetEffectiveHeal() * 0.5f, GetSpellInfo());
|
||||
Unit.ProcSkillsAndAuras(caster, caster, ProcFlags.DonePeriodic, ProcFlags.TakenPeriodic, ProcFlagsSpellType.Heal, ProcFlagsSpellPhase.Hit, hitMask, null, null, healInfo);
|
||||
Unit.ProcSkillsAndAuras(caster, caster, new ProcFlagsInit(ProcFlags.DonePeriodic), new ProcFlagsInit(ProcFlags.TakenPeriodic), ProcFlagsSpellType.Heal, ProcFlagsSpellPhase.Hit, hitMask, null, null, healInfo);
|
||||
|
||||
caster.SendSpellNonMeleeDamageLog(log);
|
||||
}
|
||||
@@ -5214,7 +5214,7 @@ namespace Game.Spells
|
||||
|
||||
HealInfo healInfo = new(caster, target, damage, GetSpellInfo(), GetSpellInfo().GetSchoolMask());
|
||||
caster.HealBySpell(healInfo);
|
||||
Unit.ProcSkillsAndAuras(caster, target, ProcFlags.DonePeriodic, ProcFlags.TakenPeriodic, ProcFlagsSpellType.Heal, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Normal, null, null, healInfo);
|
||||
Unit.ProcSkillsAndAuras(caster, target, new ProcFlagsInit(ProcFlags.DonePeriodic), new ProcFlagsInit(ProcFlags.TakenPeriodic), ProcFlagsSpellType.Heal, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Normal, null, null, healInfo);
|
||||
}
|
||||
|
||||
void HandlePeriodicHealAurasTick(Unit target, Unit caster)
|
||||
@@ -5271,8 +5271,8 @@ namespace Game.Spells
|
||||
if (GetAuraType() == AuraType.ObsModHealth)
|
||||
return;
|
||||
|
||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||
ProcFlagsInit procAttacker = new ProcFlagsInit(ProcFlags.DonePeriodic);
|
||||
ProcFlagsInit procVictim = new ProcFlagsInit(ProcFlags.TakenPeriodic);
|
||||
ProcFlagsHit hitMask = crit ? ProcFlagsHit.Critical : ProcFlagsHit.Normal;
|
||||
// ignore item heals
|
||||
if (GetBase().GetCastItemGUID().IsEmpty())
|
||||
@@ -5426,13 +5426,13 @@ namespace Game.Spells
|
||||
Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
|
||||
|
||||
// Set trigger flag
|
||||
ProcFlags procAttacker = ProcFlags.DonePeriodic;
|
||||
ProcFlags procVictim = ProcFlags.TakenPeriodic;
|
||||
ProcFlagsInit procAttacker = new ProcFlagsInit(ProcFlags.DonePeriodic);
|
||||
ProcFlagsInit procVictim = new ProcFlagsInit(ProcFlags.TakenPeriodic);
|
||||
ProcFlagsHit hitMask = Unit.CreateProcHitMask(damageInfo, SpellMissInfo.None);
|
||||
ProcFlagsSpellType spellTypeMask = ProcFlagsSpellType.NoDmgHeal;
|
||||
if (damageInfo.damage != 0)
|
||||
{
|
||||
procVictim |= ProcFlags.TakenDamage;
|
||||
procVictim.Or(ProcFlags.TakenDamage);
|
||||
spellTypeMask |= ProcFlagsSpellType.Damage;
|
||||
}
|
||||
|
||||
|
||||
+78
-46
@@ -1698,29 +1698,29 @@ namespace Game.Spells
|
||||
// Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_hitMask)
|
||||
//==========================================================================================
|
||||
|
||||
m_procVictim = m_procAttacker = 0;
|
||||
m_procVictim = m_procAttacker = new ProcFlagsInit();
|
||||
// Get data for type of attack and fill base info for trigger
|
||||
switch (m_spellInfo.DmgClass)
|
||||
{
|
||||
case SpellDmgClass.Melee:
|
||||
m_procAttacker = ProcFlags.DoneSpellMeleeDmgClass;
|
||||
m_procAttacker = new ProcFlagsInit(ProcFlags.DoneSpellMeleeDmgClass);
|
||||
if (m_attackType == WeaponAttackType.OffAttack)
|
||||
m_procAttacker |= ProcFlags.DoneOffHandAttack;
|
||||
m_procAttacker.Or(ProcFlags.DoneOffHandAttack);
|
||||
else
|
||||
m_procAttacker |= ProcFlags.DoneMainHandAttack;
|
||||
m_procVictim = ProcFlags.TakenSpellMeleeDmgClass;
|
||||
m_procAttacker.Or(ProcFlags.DoneMainHandAttack);
|
||||
m_procVictim = new ProcFlagsInit(ProcFlags.TakenSpellMeleeDmgClass);
|
||||
break;
|
||||
case SpellDmgClass.Ranged:
|
||||
// Auto attack
|
||||
if (m_spellInfo.HasAttribute(SpellAttr2.AutorepeatFlag))
|
||||
{
|
||||
m_procAttacker = ProcFlags.DoneRangedAutoAttack;
|
||||
m_procVictim = ProcFlags.TakenRangedAutoAttack;
|
||||
m_procAttacker = new ProcFlagsInit(ProcFlags.DoneRangedAutoAttack);
|
||||
m_procVictim = new ProcFlagsInit(ProcFlags.TakenRangedAutoAttack);
|
||||
}
|
||||
else // Ranged spell attack
|
||||
{
|
||||
m_procAttacker = ProcFlags.DoneSpellRangedDmgClass;
|
||||
m_procVictim = ProcFlags.TakenSpellRangedDmgClass;
|
||||
m_procAttacker = new ProcFlagsInit(ProcFlags.DoneSpellRangedDmgClass);
|
||||
m_procVictim = new ProcFlagsInit(ProcFlags.TakenSpellRangedDmgClass);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1728,8 +1728,8 @@ namespace Game.Spells
|
||||
Convert.ToBoolean(m_spellInfo.EquippedItemSubClassMask & (1 << (int)ItemSubClassWeapon.Wand))
|
||||
&& m_spellInfo.HasAttribute(SpellAttr2.AutorepeatFlag)) // Wands auto attack
|
||||
{
|
||||
m_procAttacker = ProcFlags.DoneRangedAutoAttack;
|
||||
m_procVictim = ProcFlags.TakenRangedAutoAttack;
|
||||
m_procAttacker = new ProcFlagsInit(ProcFlags.DoneRangedAutoAttack);
|
||||
m_procVictim = new ProcFlagsInit(ProcFlags.TakenRangedAutoAttack);
|
||||
}
|
||||
break;
|
||||
// For other spells trigger procflags are set in Spell::TargetInfo::DoDamageAndTriggers
|
||||
@@ -1741,18 +1741,18 @@ namespace Game.Spells
|
||||
m_spellInfo.Id == 57879 || // Snake Trap - done this way to avoid double proc
|
||||
m_spellInfo.SpellFamilyFlags[2].HasAnyFlag(0x00024000u))) // Explosive and Immolation Trap
|
||||
{
|
||||
m_procAttacker |= ProcFlags.DoneTrapActivation;
|
||||
m_procAttacker.Or(ProcFlags.DoneTrapActivation);
|
||||
|
||||
// also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set)
|
||||
m_procAttacker |= ProcFlags.DoneSpellMagicDmgClassNeg;
|
||||
m_procVictim |= ProcFlags.TakenSpellMagicDmgClassNeg;
|
||||
m_procAttacker.Or(ProcFlags.DoneSpellMagicDmgClassNeg);
|
||||
m_procVictim.Or(ProcFlags.TakenSpellMagicDmgClassNeg);
|
||||
}
|
||||
|
||||
// Hellfire Effect - trigger as DOT
|
||||
if (m_spellInfo.SpellFamilyName == SpellFamilyNames.Warlock && m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00000040u))
|
||||
{
|
||||
m_procAttacker = ProcFlags.DonePeriodic;
|
||||
m_procVictim = ProcFlags.TakenPeriodic;
|
||||
m_procAttacker = new ProcFlagsInit(ProcFlags.DonePeriodic);
|
||||
m_procVictim = new ProcFlagsInit(ProcFlags.TakenPeriodic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2882,13 +2882,13 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
// Handle procs on cast
|
||||
ProcFlags procAttacker = m_procAttacker;
|
||||
if (procAttacker == 0)
|
||||
ProcFlagsInit procAttacker = m_procAttacker;
|
||||
if (!procAttacker)
|
||||
{
|
||||
if (m_spellInfo.DmgClass == SpellDmgClass.Magic)
|
||||
procAttacker = IsPositive() ? ProcFlags.DoneSpellMagicDmgClassPos : ProcFlags.DoneSpellMagicDmgClassNeg;
|
||||
procAttacker = new ProcFlagsInit(IsPositive() ? ProcFlags.DoneSpellMagicDmgClassPos : ProcFlags.DoneSpellMagicDmgClassNeg);
|
||||
else
|
||||
procAttacker = IsPositive() ? ProcFlags.DoneSpellNoneDmgClassPos : ProcFlags.DoneSpellNoneDmgClassNeg;
|
||||
procAttacker = new ProcFlagsInit(IsPositive() ? ProcFlags.DoneSpellNoneDmgClassPos : ProcFlags.DoneSpellNoneDmgClassNeg);
|
||||
}
|
||||
|
||||
ProcFlagsHit hitMask = m_hitMask;
|
||||
@@ -2898,7 +2898,7 @@ namespace Game.Spells
|
||||
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreAuraInterruptFlags) && !m_spellInfo.HasAttribute(SpellAttr2.IgnoreActionAuraInterruptFlags))
|
||||
m_originalCaster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ActionDelayed);
|
||||
|
||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
|
||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
|
||||
|
||||
// Call CreatureAI hook OnSuccessfulSpellCast
|
||||
Creature caster = m_originalCaster.ToCreature();
|
||||
@@ -3144,16 +3144,16 @@ namespace Game.Spells
|
||||
if (!m_originalCaster)
|
||||
return;
|
||||
|
||||
ProcFlags procAttacker = m_procAttacker;
|
||||
if (procAttacker == 0)
|
||||
ProcFlagsInit procAttacker = m_procAttacker;
|
||||
if (!procAttacker)
|
||||
{
|
||||
if (m_spellInfo.DmgClass == SpellDmgClass.Magic)
|
||||
procAttacker = IsPositive() ? ProcFlags.DoneSpellMagicDmgClassPos : ProcFlags.DoneSpellMagicDmgClassNeg;
|
||||
procAttacker = new ProcFlagsInit(IsPositive() ? ProcFlags.DoneSpellMagicDmgClassPos : ProcFlags.DoneSpellMagicDmgClassNeg);
|
||||
else
|
||||
procAttacker = IsPositive() ? ProcFlags.DoneSpellNoneDmgClassPos : ProcFlags.DoneSpellNoneDmgClassNeg;
|
||||
procAttacker = new ProcFlagsInit(IsPositive() ? ProcFlags.DoneSpellNoneDmgClassPos : ProcFlags.DoneSpellNoneDmgClassNeg);
|
||||
}
|
||||
|
||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Finish, m_hitMask, this, null, null);
|
||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Finish, m_hitMask, this, null, null);
|
||||
}
|
||||
|
||||
void SendSpellCooldown()
|
||||
@@ -7047,7 +7047,7 @@ namespace Game.Spells
|
||||
{
|
||||
return m_originalCaster != null ? m_originalCaster : m_caster.ToUnit();
|
||||
}
|
||||
|
||||
|
||||
bool IsValidDeadOrAliveTarget(Unit target)
|
||||
{
|
||||
if (target.IsAlive())
|
||||
@@ -7865,8 +7865,8 @@ namespace Game.Spells
|
||||
// ******************************************
|
||||
// Spell trigger system
|
||||
// ******************************************
|
||||
internal ProcFlags m_procAttacker; // Attacker trigger flags
|
||||
internal ProcFlags m_procVictim; // Victim trigger flags
|
||||
internal ProcFlagsInit m_procAttacker; // Attacker trigger flags
|
||||
internal ProcFlagsInit m_procVictim; // Victim trigger flags
|
||||
internal ProcFlagsHit m_hitMask;
|
||||
|
||||
// *****************************************
|
||||
@@ -8028,7 +8028,7 @@ namespace Game.Spells
|
||||
TransportGUID.Clear();
|
||||
TransportOffset.Relocate(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public SpellDestination(WorldObject wObj) : this()
|
||||
{
|
||||
TransportGUID = wObj.GetTransGUID();
|
||||
@@ -8190,8 +8190,8 @@ namespace Game.Spells
|
||||
if (caster != null)
|
||||
{
|
||||
// Fill base trigger info
|
||||
ProcFlags procAttacker = spell.m_procAttacker;
|
||||
ProcFlags procVictim = spell.m_procVictim;
|
||||
ProcFlagsInit procAttacker = spell.m_procAttacker;
|
||||
ProcFlagsInit procVictim = spell.m_procVictim;
|
||||
ProcFlagsSpellType procSpellType = ProcFlagsSpellType.None;
|
||||
ProcFlagsHit hitMask = ProcFlagsHit.None;
|
||||
|
||||
@@ -8200,7 +8200,7 @@ namespace Game.Spells
|
||||
(spell.CanExecuteTriggersOnHit(EffectMask) || MissCondition == SpellMissInfo.Immune || MissCondition == SpellMissInfo.Immune2);
|
||||
|
||||
// Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now
|
||||
if (canEffectTrigger && procAttacker == 0 && procVictim == 0)
|
||||
if (canEffectTrigger && !procAttacker && !procVictim)
|
||||
{
|
||||
bool positive = true;
|
||||
if (spell.m_damage > 0)
|
||||
@@ -8226,25 +8226,25 @@ namespace Game.Spells
|
||||
case SpellDmgClass.Magic:
|
||||
if (positive)
|
||||
{
|
||||
procAttacker |= ProcFlags.DoneSpellMagicDmgClassPos;
|
||||
procVictim |= ProcFlags.TakenSpellMagicDmgClassPos;
|
||||
procAttacker.Or(ProcFlags.DoneSpellMagicDmgClassPos);
|
||||
procVictim.Or(ProcFlags.TakenSpellMagicDmgClassPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
procAttacker |= ProcFlags.DoneSpellMagicDmgClassNeg;
|
||||
procVictim |= ProcFlags.TakenSpellMagicDmgClassNeg;
|
||||
procAttacker.Or(ProcFlags.DoneSpellMagicDmgClassNeg);
|
||||
procVictim.Or(ProcFlags.TakenSpellMagicDmgClassNeg);
|
||||
}
|
||||
break;
|
||||
case SpellDmgClass.None:
|
||||
if (positive)
|
||||
{
|
||||
procAttacker |= ProcFlags.DoneSpellNoneDmgClassPos;
|
||||
procVictim |= ProcFlags.TakenSpellNoneDmgClassPos;
|
||||
procAttacker.Or(ProcFlags.DoneSpellNoneDmgClassPos);
|
||||
procVictim.Or(ProcFlags.TakenSpellNoneDmgClassPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
procAttacker |= ProcFlags.DoneSpellNoneDmgClassNeg;
|
||||
procVictim |= ProcFlags.TakenSpellNoneDmgClassNeg;
|
||||
procAttacker.Or(ProcFlags.DoneSpellNoneDmgClassNeg);
|
||||
procVictim.Or(ProcFlags.TakenSpellNoneDmgClassNeg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -8297,7 +8297,7 @@ namespace Game.Spells
|
||||
Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
|
||||
|
||||
hitMask |= Unit.CreateProcHitMask(damageInfo, MissCondition);
|
||||
procVictim |= ProcFlags.TakenDamage;
|
||||
procVictim.Or(ProcFlags.TakenDamage);
|
||||
|
||||
spell.m_damage = (int)damageInfo.damage;
|
||||
|
||||
@@ -8482,7 +8482,7 @@ namespace Game.Spells
|
||||
spell.CallScriptAfterHitHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SpellValue
|
||||
{
|
||||
public SpellValue(SpellInfo proto, WorldObject caster)
|
||||
@@ -8934,7 +8934,7 @@ namespace Game.Spells
|
||||
ProcFlagsSpellPhase spellPhaseMask = ProcFlagsSpellPhase.None;
|
||||
ProcFlagsHit hitMask = ProcFlagsHit.Reflect;
|
||||
|
||||
Unit.ProcSkillsAndAuras(caster, _victim, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, null, null, null);
|
||||
Unit.ProcSkillsAndAuras(caster, _victim, new ProcFlagsInit(typeMaskActor), new ProcFlagsInit(typeMaskActionTarget), spellTypeMask, spellPhaseMask, hitMask, null, null, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8988,7 +8988,7 @@ namespace Game.Spells
|
||||
Targets = targets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CastSpellExtraArgs
|
||||
{
|
||||
public TriggerCastFlags TriggerFlags;
|
||||
@@ -9061,7 +9061,7 @@ namespace Game.Spells
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CastSpellExtraArgs SetTriggeringAura(AuraEffect triggeringAura)
|
||||
{
|
||||
TriggeringAura = triggeringAura;
|
||||
@@ -9106,6 +9106,38 @@ namespace Game.Spells
|
||||
public List<SpellLogEffectGenericVictimParams> GenericVictimTargets = new();
|
||||
public List<SpellLogEffectTradeSkillItemParams> TradeSkillTargets = new();
|
||||
public List<SpellLogEffectFeedPetParams> FeedPetTargets = new();
|
||||
}
|
||||
|
||||
public class ProcFlagsInit : FlagsArray<int>
|
||||
{
|
||||
public ProcFlagsInit(ProcFlags procFlags = 0, ProcFlags2 procFlags2 = 0) : base(2)
|
||||
{
|
||||
_storage[0] = (int)procFlags;
|
||||
_storage[1] = (int)procFlags2;
|
||||
}
|
||||
|
||||
public ProcFlagsInit(params int[] flags) : base(flags) { }
|
||||
|
||||
public ProcFlagsInit Or(ProcFlags procFlags)
|
||||
{
|
||||
_storage[0] |= (int)procFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProcFlagsInit Or(ProcFlags2 procFlags2)
|
||||
{
|
||||
_storage[1] |= (int)procFlags2;
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool HasFlag(ProcFlags procFlags)
|
||||
{
|
||||
return (_storage[0] & procFlags) != 0;
|
||||
}
|
||||
|
||||
public bool HasFlag(ProcFlags2 procFlags)
|
||||
{
|
||||
return (_storage[1] & procFlags) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2627,9 +2627,9 @@ namespace Game.Spells
|
||||
duration = unitTarget.ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1u << (int)effectInfo.EffectIndex);
|
||||
unitTarget.GetSpellHistory().LockSpellSchool(curSpellInfo.GetSchoolMask(), TimeSpan.FromMilliseconds(duration));
|
||||
if (m_spellInfo.DmgClass == SpellDmgClass.Magic)
|
||||
Unit.ProcSkillsAndAuras(unitCaster, unitTarget, ProcFlags.DoneSpellMagicDmgClassNeg, ProcFlags.TakenSpellMagicDmgClassNeg, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Interrupt, null, null, null);
|
||||
Unit.ProcSkillsAndAuras(unitCaster, unitTarget, new ProcFlagsInit(ProcFlags.DoneSpellMagicDmgClassNeg), new ProcFlagsInit(ProcFlags.TakenSpellMagicDmgClassNeg), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Interrupt, null, null, null);
|
||||
else if (m_spellInfo.DmgClass == SpellDmgClass.Melee)
|
||||
Unit.ProcSkillsAndAuras(unitCaster, unitTarget, ProcFlags.DoneSpellMeleeDmgClass, ProcFlags.TakenSpellMeleeDmgClass, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Interrupt, null, null, null);
|
||||
Unit.ProcSkillsAndAuras(unitCaster, unitTarget, new ProcFlagsInit(ProcFlags.DoneSpellMeleeDmgClass), new ProcFlagsInit(ProcFlags.TakenSpellMeleeDmgClass), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Hit, ProcFlagsHit.Interrupt, null, null, null);
|
||||
}
|
||||
SendSpellInterruptLog(unitTarget, curSpellInfo.Id);
|
||||
unitTarget.InterruptSpell(i, false);
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Game.Spells
|
||||
SpellAuraOptionsRecord _options = data.AuraOptions;
|
||||
if (_options != null)
|
||||
{
|
||||
ProcFlags = (ProcFlags)_options.ProcTypeMask[0];
|
||||
ProcFlags = new ProcFlagsInit(_options.ProcTypeMask);
|
||||
ProcChance = _options.ProcChance;
|
||||
ProcCharges = (uint)_options.ProcCharges;
|
||||
ProcCooldown = _options.ProcCategoryRecovery;
|
||||
@@ -3948,7 +3948,7 @@ namespace Game.Spells
|
||||
public SpellAuraInterruptFlags2 AuraInterruptFlags2 { get; set; }
|
||||
public SpellAuraInterruptFlags ChannelInterruptFlags { get; set; }
|
||||
public SpellAuraInterruptFlags2 ChannelInterruptFlags2 { get; set; }
|
||||
public ProcFlags ProcFlags { get; set; }
|
||||
public ProcFlagsInit ProcFlags { get; set; }
|
||||
public uint ProcChance { get; set; }
|
||||
public uint ProcCharges { get; set; }
|
||||
public uint ProcCooldown { get; set; }
|
||||
|
||||
@@ -459,7 +459,7 @@ namespace Game.Entities
|
||||
public static bool CanSpellTriggerProcOnEvent(SpellProcEntry procEntry, ProcEventInfo eventInfo)
|
||||
{
|
||||
// proc type doesn't match
|
||||
if ((eventInfo.GetTypeMask() & procEntry.ProcFlags) == 0)
|
||||
if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags))
|
||||
return false;
|
||||
|
||||
// check XP or honor target requirement
|
||||
@@ -484,7 +484,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// always trigger for these types
|
||||
if (eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.Killed | ProcFlags.Kill | ProcFlags.Death))
|
||||
if (eventInfo.GetTypeMask().HasFlag(ProcFlags.Killed | ProcFlags.Kill | ProcFlags.Death))
|
||||
return true;
|
||||
|
||||
// check school mask (if set) for other trigger types
|
||||
@@ -1293,8 +1293,8 @@ namespace Game.Entities
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
SQLResult result = DB.World.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, SpellFamilyMask3, " +
|
||||
//7 8 9 10 11 12 13 14 15 16
|
||||
"ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
|
||||
//7 8 9 10 11 12 13 14 15 16 17
|
||||
"ProcFlags, ProcFlags2, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, DisableEffectsMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc");
|
||||
|
||||
uint count = 0;
|
||||
if (!result.IsEmpty())
|
||||
@@ -1331,16 +1331,16 @@ namespace Game.Entities
|
||||
baseProcEntry.SchoolMask = (SpellSchoolMask)result.Read<uint>(1);
|
||||
baseProcEntry.SpellFamilyName = (SpellFamilyNames)result.Read<uint>(2);
|
||||
baseProcEntry.SpellFamilyMask = new FlagArray128(result.Read<uint>(3), result.Read<uint>(4), result.Read<uint>(5), result.Read<uint>(6));
|
||||
baseProcEntry.ProcFlags = (ProcFlags)result.Read<uint>(7);
|
||||
baseProcEntry.SpellTypeMask = (ProcFlagsSpellType)result.Read<uint>(8);
|
||||
baseProcEntry.SpellPhaseMask = (ProcFlagsSpellPhase)result.Read<uint>(9);
|
||||
baseProcEntry.HitMask = (ProcFlagsHit)result.Read<uint>(10);
|
||||
baseProcEntry.AttributesMask = (ProcAttributes)result.Read<uint>(11);
|
||||
baseProcEntry.DisableEffectsMask = result.Read<uint>(12);
|
||||
baseProcEntry.ProcsPerMinute = result.Read<float>(13);
|
||||
baseProcEntry.Chance = result.Read<float>(14);
|
||||
baseProcEntry.Cooldown = result.Read<uint>(15);
|
||||
baseProcEntry.Charges = result.Read<uint>(16);
|
||||
baseProcEntry.ProcFlags = new ProcFlagsInit(result.Read<int>(7), result.Read<int>(8), 2);
|
||||
baseProcEntry.SpellTypeMask = (ProcFlagsSpellType)result.Read<uint>(9);
|
||||
baseProcEntry.SpellPhaseMask = (ProcFlagsSpellPhase)result.Read<uint>(10);
|
||||
baseProcEntry.HitMask = (ProcFlagsHit)result.Read<uint>(11);
|
||||
baseProcEntry.AttributesMask = (ProcAttributes)result.Read<uint>(12);
|
||||
baseProcEntry.DisableEffectsMask = result.Read<uint>(13);
|
||||
baseProcEntry.ProcsPerMinute = result.Read<float>(14);
|
||||
baseProcEntry.Chance = result.Read<float>(15);
|
||||
baseProcEntry.Cooldown = result.Read<uint>(16);
|
||||
baseProcEntry.Charges = result.Read<uint>(17);
|
||||
|
||||
while (spellInfo != null)
|
||||
{
|
||||
@@ -1352,7 +1352,7 @@ namespace Game.Entities
|
||||
SpellProcEntry procEntry = baseProcEntry;
|
||||
|
||||
// take defaults from dbcs
|
||||
if (procEntry.ProcFlags == 0)
|
||||
if (!procEntry.ProcFlags)
|
||||
procEntry.ProcFlags = spellInfo.ProcFlags;
|
||||
if (procEntry.Charges == 0)
|
||||
procEntry.Charges = spellInfo.ProcCharges;
|
||||
@@ -1376,21 +1376,21 @@ namespace Game.Entities
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has negative value in `ProcsPerMinute` field", spellInfo.Id);
|
||||
procEntry.ProcsPerMinute = 0;
|
||||
}
|
||||
if (procEntry.ProcFlags == 0)
|
||||
if (!procEntry.ProcFlags)
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} doesn't have `ProcFlags` value defined, proc will not be triggered", spellInfo.Id);
|
||||
if (Convert.ToBoolean(procEntry.SpellTypeMask & ~ProcFlagsSpellType.MaskAll))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has wrong `SpellTypeMask` set: {1}", spellInfo.Id, procEntry.SpellTypeMask);
|
||||
if (procEntry.SpellTypeMask != 0 && !Convert.ToBoolean(procEntry.ProcFlags & (ProcFlags.SpellMask)))
|
||||
if (procEntry.SpellTypeMask != 0 && !procEntry.ProcFlags.HasFlag(ProcFlags.SpellMask))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has `SpellTypeMask` value defined, but it won't be used for defined `ProcFlags` value", spellInfo.Id);
|
||||
if (procEntry.SpellPhaseMask == 0 && Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.ReqSpellPhaseMask))
|
||||
if (procEntry.SpellPhaseMask == 0 && procEntry.ProcFlags.HasFlag(ProcFlags.ReqSpellPhaseMask))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} doesn't have `SpellPhaseMask` value defined, but it's required for defined `ProcFlags` value, proc will not be triggered", spellInfo.Id);
|
||||
if (Convert.ToBoolean(procEntry.SpellPhaseMask & ~ProcFlagsSpellPhase.MaskAll))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has wrong `SpellPhaseMask` set: {1}", spellInfo.Id, procEntry.SpellPhaseMask);
|
||||
if (procEntry.SpellPhaseMask != 0 && !Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.ReqSpellPhaseMask))
|
||||
if (procEntry.SpellPhaseMask != 0 && !procEntry.ProcFlags.HasFlag(ProcFlags.ReqSpellPhaseMask))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has `SpellPhaseMask` value defined, but it won't be used for defined `ProcFlags` value", spellInfo.Id);
|
||||
if (Convert.ToBoolean(procEntry.HitMask & ~ProcFlagsHit.MaskAll))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has wrong `HitMask` set: {1}", spellInfo.Id, procEntry.HitMask);
|
||||
if (procEntry.HitMask != 0 && !(Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.TakenHitMask) || (Convert.ToBoolean(procEntry.ProcFlags & ProcFlags.DoneHitMask) && (procEntry.SpellPhaseMask == 0 || Convert.ToBoolean(procEntry.SpellPhaseMask & (ProcFlagsSpellPhase.Hit | ProcFlagsSpellPhase.Finish))))))
|
||||
if (procEntry.HitMask != 0 && !(procEntry.ProcFlags.HasFlag(ProcFlags.TakenHitMask) || (procEntry.ProcFlags.HasFlag(ProcFlags.DoneHitMask) && (procEntry.SpellPhaseMask == 0 || Convert.ToBoolean(procEntry.SpellPhaseMask & (ProcFlagsSpellPhase.Hit | ProcFlagsSpellPhase.Finish))))))
|
||||
Log.outError(LogFilter.Sql, "`spell_proc` table entry for spellId {0} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellInfo.Id);
|
||||
foreach (var spellEffectInfo in spellInfo.GetEffects())
|
||||
if ((procEntry.DisableEffectsMask & (1u << (int)spellEffectInfo.EffectIndex)) != 0 && !spellEffectInfo.IsAura())
|
||||
@@ -1448,7 +1448,7 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
// Nothing to do if no flags set
|
||||
if (spellInfo.ProcFlags == 0)
|
||||
if (!spellInfo.ProcFlags)
|
||||
continue;
|
||||
|
||||
bool addTriggerFlag = false;
|
||||
@@ -1476,7 +1476,7 @@ namespace Game.Entities
|
||||
|
||||
// many proc auras with taken procFlag mask don't have attribute "can proc with triggered"
|
||||
// they should proc nevertheless (example mage armor spells with judgement)
|
||||
if (!addTriggerFlag && spellInfo.ProcFlags.HasAnyFlag(ProcFlags.TakenHitMask))
|
||||
if (!addTriggerFlag && spellInfo.ProcFlags.HasFlag(ProcFlags.TakenHitMask))
|
||||
{
|
||||
switch (auraName)
|
||||
{
|
||||
@@ -1496,7 +1496,7 @@ namespace Game.Entities
|
||||
{
|
||||
if (spellEffectInfo.IsAura())
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"Spell Id {spellInfo.Id} has DBC ProcFlags {spellInfo.ProcFlags}, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.");
|
||||
Log.outError(LogFilter.Sql, $"Spell Id {spellInfo.Id} has DBC ProcFlags 0x{spellInfo.ProcFlags[0]:X} 0x{spellInfo.ProcFlags[1]:X}, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1552,7 +1552,7 @@ namespace Game.Entities
|
||||
|
||||
procEntry.AttributesMask = 0;
|
||||
procEntry.DisableEffectsMask = nonProcMask;
|
||||
if (spellInfo.ProcFlags.HasAnyFlag(ProcFlags.Kill))
|
||||
if (spellInfo.ProcFlags.HasFlag(ProcFlags.Kill))
|
||||
procEntry.AttributesMask |= ProcAttributes.ReqExpOrHonor;
|
||||
if (addTriggerFlag)
|
||||
procEntry.AttributesMask |= ProcAttributes.TriggeredCanProc;
|
||||
@@ -2467,13 +2467,13 @@ namespace Game.Entities
|
||||
"ExcludeCasterAuraState, ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, CastingTimeIndex, " +
|
||||
//35 36 37 38 39 40 41
|
||||
"RecoveryTime, CategoryRecoveryTime, StartRecoveryCategory, StartRecoveryTime, InterruptFlags, AuraInterruptFlags1, AuraInterruptFlags2, " +
|
||||
//42 43 44 45 46 47 48 49 50 51
|
||||
"ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " +
|
||||
//52 53 54 55 56 57 58 59 60
|
||||
//42 43 44 45 46 47 48 49 50 51 52
|
||||
"ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcFlags2, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " +
|
||||
//53 54 55 56 57 58 59 60 61
|
||||
"DurationIndex, RangeIndex, Speed, LaunchDelay, StackAmount, EquippedItemClass, EquippedItemSubClassMask, EquippedItemInventoryTypeMask, ContentTuningId, " +
|
||||
//61 62 63 64 65 66 67 68 69 70
|
||||
//62 63 64 65 66 67 68 69 70 71
|
||||
"SpellName, ConeAngle, ConeWidth, MaxTargetLevel, MaxAffectedTargets, SpellFamilyName, SpellFamilyFlags1, SpellFamilyFlags2, SpellFamilyFlags3, SpellFamilyFlags4, " +
|
||||
//71 72 73 74 75
|
||||
//72 73 74 75 76
|
||||
"DmgClass, PreventionType, AreaGroupId, SchoolMask, ChargeCategoryId FROM serverside_spell");
|
||||
|
||||
if (!spellsResult.IsEmpty())
|
||||
@@ -2488,7 +2488,7 @@ namespace Game.Entities
|
||||
continue;
|
||||
}
|
||||
|
||||
mServersideSpellNames.Add(new(spellId, spellsResult.Read<string>(61)));
|
||||
mServersideSpellNames.Add(new(spellId, spellsResult.Read<string>(62)));
|
||||
|
||||
SpellInfo spellInfo = new(mServersideSpellNames.Last().Name, difficulty, spellEffects[(spellId, difficulty)]);
|
||||
spellInfo.CategoryId = spellsResult.Read<uint>(2);
|
||||
@@ -2533,34 +2533,34 @@ namespace Game.Entities
|
||||
spellInfo.AuraInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read<uint>(41);
|
||||
spellInfo.ChannelInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read<uint>(42);
|
||||
spellInfo.ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read<uint>(43);
|
||||
spellInfo.ProcFlags = (ProcFlags)spellsResult.Read<uint>(44);
|
||||
spellInfo.ProcChance = spellsResult.Read<uint>(45);
|
||||
spellInfo.ProcCharges = spellsResult.Read<uint>(46);
|
||||
spellInfo.ProcCooldown = spellsResult.Read<uint>(47);
|
||||
spellInfo.ProcBasePPM = spellsResult.Read<float>(48);
|
||||
spellInfo.MaxLevel = spellsResult.Read<uint>(49);
|
||||
spellInfo.BaseLevel = spellsResult.Read<uint>(50);
|
||||
spellInfo.SpellLevel = spellsResult.Read<uint>(51);
|
||||
spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(spellsResult.Read<uint>(52));
|
||||
spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(spellsResult.Read<uint>(53));
|
||||
spellInfo.Speed = spellsResult.Read<float>(54);
|
||||
spellInfo.LaunchDelay = spellsResult.Read<float>(55);
|
||||
spellInfo.StackAmount = spellsResult.Read<uint>(56);
|
||||
spellInfo.EquippedItemClass = (ItemClass)spellsResult.Read<int>(57);
|
||||
spellInfo.EquippedItemSubClassMask = spellsResult.Read<int>(58);
|
||||
spellInfo.EquippedItemInventoryTypeMask = spellsResult.Read<int>(59);
|
||||
spellInfo.ContentTuningId = spellsResult.Read<uint>(60);
|
||||
spellInfo.ConeAngle = spellsResult.Read<float>(62);
|
||||
spellInfo.Width = spellsResult.Read<float>(63);
|
||||
spellInfo.MaxTargetLevel = spellsResult.Read<uint>(64);
|
||||
spellInfo.MaxAffectedTargets = spellsResult.Read<uint>(65);
|
||||
spellInfo.SpellFamilyName = (SpellFamilyNames)spellsResult.Read<uint>(66);
|
||||
spellInfo.SpellFamilyFlags = new FlagArray128(spellsResult.Read<uint>(67), spellsResult.Read<uint>(68), spellsResult.Read<uint>(69), spellsResult.Read<uint>(70));
|
||||
spellInfo.DmgClass = (SpellDmgClass)spellsResult.Read<uint>(71);
|
||||
spellInfo.PreventionType = (SpellPreventionType)spellsResult.Read<uint>(72);
|
||||
spellInfo.RequiredAreasID = spellsResult.Read<int>(73);
|
||||
spellInfo.SchoolMask = (SpellSchoolMask)spellsResult.Read<uint>(74);
|
||||
spellInfo.ChargeCategoryId = spellsResult.Read<uint>(75);
|
||||
spellInfo.ProcFlags = new ProcFlagsInit(spellsResult.Read<int>(44), spellsResult.Read<int>(45));
|
||||
spellInfo.ProcChance = spellsResult.Read<uint>(46);
|
||||
spellInfo.ProcCharges = spellsResult.Read<uint>(47);
|
||||
spellInfo.ProcCooldown = spellsResult.Read<uint>(48);
|
||||
spellInfo.ProcBasePPM = spellsResult.Read<float>(49);
|
||||
spellInfo.MaxLevel = spellsResult.Read<uint>(50);
|
||||
spellInfo.BaseLevel = spellsResult.Read<uint>(51);
|
||||
spellInfo.SpellLevel = spellsResult.Read<uint>(52);
|
||||
spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(spellsResult.Read<uint>(53));
|
||||
spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(spellsResult.Read<uint>(54));
|
||||
spellInfo.Speed = spellsResult.Read<float>(55);
|
||||
spellInfo.LaunchDelay = spellsResult.Read<float>(56);
|
||||
spellInfo.StackAmount = spellsResult.Read<uint>(57);
|
||||
spellInfo.EquippedItemClass = (ItemClass)spellsResult.Read<int>(58);
|
||||
spellInfo.EquippedItemSubClassMask = spellsResult.Read<int>(59);
|
||||
spellInfo.EquippedItemInventoryTypeMask = spellsResult.Read<int>(60);
|
||||
spellInfo.ContentTuningId = spellsResult.Read<uint>(61);
|
||||
spellInfo.ConeAngle = spellsResult.Read<float>(63);
|
||||
spellInfo.Width = spellsResult.Read<float>(64);
|
||||
spellInfo.MaxTargetLevel = spellsResult.Read<uint>(65);
|
||||
spellInfo.MaxAffectedTargets = spellsResult.Read<uint>(66);
|
||||
spellInfo.SpellFamilyName = (SpellFamilyNames)spellsResult.Read<uint>(67);
|
||||
spellInfo.SpellFamilyFlags = new FlagArray128(spellsResult.Read<uint>(68), spellsResult.Read<uint>(69), spellsResult.Read<uint>(70), spellsResult.Read<uint>(71));
|
||||
spellInfo.DmgClass = (SpellDmgClass)spellsResult.Read<uint>(72);
|
||||
spellInfo.PreventionType = (SpellPreventionType)spellsResult.Read<uint>(73);
|
||||
spellInfo.RequiredAreasID = spellsResult.Read<int>(74);
|
||||
spellInfo.SchoolMask = (SpellSchoolMask)spellsResult.Read<uint>(75);
|
||||
spellInfo.ChargeCategoryId = spellsResult.Read<uint>(76);
|
||||
|
||||
mSpellInfoMap.Add(spellId, spellInfo);
|
||||
|
||||
@@ -4373,7 +4373,7 @@ namespace Game.Entities
|
||||
|
||||
// disable proc for magnet auras, they're handled differently
|
||||
if (spellInfo.HasAura(AuraType.SpellMagnet))
|
||||
spellInfo.ProcFlags = 0;
|
||||
spellInfo.ProcFlags = new ProcFlagsInit();
|
||||
|
||||
// due to the way spell system works, unit would change orientation in Spell::_cast
|
||||
if (spellInfo.HasAura(AuraType.ControlVehicle))
|
||||
@@ -4826,7 +4826,7 @@ namespace Game.Entities
|
||||
public SpellSchoolMask SchoolMask { get; set; } // if nonzero - bitmask for matching proc condition based on spell's school
|
||||
public SpellFamilyNames SpellFamilyName { get; set; } // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName
|
||||
public FlagArray128 SpellFamilyMask { get; set; } = new FlagArray128(); // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags
|
||||
public ProcFlags ProcFlags { get; set; } // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags
|
||||
public ProcFlagsInit ProcFlags { get; set; } // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags
|
||||
public ProcFlagsSpellType SpellTypeMask { get; set; } // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType
|
||||
public ProcFlagsSpellPhase SpellPhaseMask { get; set; } // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase
|
||||
public ProcFlagsHit HitMask { get; set; } // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit
|
||||
|
||||
@@ -1498,7 +1498,7 @@ namespace Scripts.Spells.Items
|
||||
|
||||
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
|
||||
{
|
||||
if (eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.DoneRangedAutoAttack | ProcFlags.DoneSpellRangedDmgClass))
|
||||
if (eventInfo.GetTypeMask().HasFlag(ProcFlags.DoneRangedAutoAttack | ProcFlags.DoneSpellRangedDmgClass))
|
||||
{
|
||||
// in that case, do not cast heal spell
|
||||
PreventDefaultAction();
|
||||
|
||||
Reference in New Issue
Block a user