internal Spell(Unit caster, SpellInfo info, SpellCastingOptions options) { Logging.LogSpell($"Created new spell, current count: {++SpellAliveCount}"); spellManager = caster.World.SpellManager; spellCastFlags = options.SpellFlags; casterMovementFlags = options.MovementFlags ?? caster.MovementInfo.Flags; SchoolMask = info.SchoolMask; CastTime = CastTimeLeft = EffectDamage = EffectHealing = 0; Caster = OriginalCaster = caster; SpellInfo = info; if (spellCastFlags.HasTargetFlag(SpellCastFlags.TriggeredByAura)) { spellCastFlags |= SpellCastFlags.IgnoreTargetCheck | SpellCastFlags.IgnoreRangeCheck; } if (info.HasAttribute(SpellExtraAttributes.CanCastWhileCasting)) { spellCastFlags |= SpellCastFlags.IgnoreCastInProgress | SpellCastFlags.CastDirectly; } if (info.HasAttribute(SpellExtraAttributes.IgnoreGcd)) { spellCastFlags |= SpellCastFlags.IgnoreGcd; } CanReflect = SpellInfo.DamageClass == SpellDamageClass.Magic && !SpellInfo.HasAttribute(SpellAttributes.CantBeReflected) && !SpellInfo.HasAttribute(SpellAttributes.UnaffectedByInvulnerability) && !SpellInfo.IsPassive() && !SpellInfo.IsPositive; ExplicitTargets = options.Targets ?? new SpellExplicitTargets(); ImplicitTargets = new SpellImplicitTargets(this); spellManager.Add(this); }
private SpellCastResult ValidateCast() { if (spellCastFlags.HasTargetFlag(SpellCastFlags.TriggeredByAura)) { return(SpellCastResult.Success); } if (Caster.HasState(UnitControlState.Stunned) && !SpellInfo.HasAttribute(SpellExtraAttributes.UsableWhileStunned)) { return(SpellCastResult.Stunned); } if (Caster.HasState(UnitControlState.Confused) && !SpellInfo.HasAttribute(SpellExtraAttributes.UsableWhileConfused)) { return(SpellCastResult.Confused); } if (Caster.HasState(UnitControlState.Fleeing) && !SpellInfo.HasAttribute(SpellExtraAttributes.UsableWhileFeared)) { return(SpellCastResult.Fleeing); } if (SpellInfo.PreventionType != 0) { if (SpellInfo.PreventionType.HasTargetFlag(SpellPreventionType.Pacify) && Caster.HasFlag(UnitFlags.Pacified)) { return(SpellCastResult.Silenced); } if (SpellInfo.PreventionType.HasTargetFlag(SpellPreventionType.Silence) && Caster.HasFlag(UnitFlags.Silenced)) { return(SpellCastResult.Pacified); } } // check death state if (!Caster.IsAlive && !SpellInfo.IsPassive() && !SpellInfo.HasAttribute(SpellAttributes.CastableWhileDead)) { return(SpellCastResult.CasterDead); } // check cooldowns to prevent cheating if (!SpellInfo.IsPassive() && !Caster.SpellHistory.IsReady(SpellInfo)) { return(SpellCastResult.NotReady); } // check global cooldown if (!spellCastFlags.HasTargetFlag(SpellCastFlags.IgnoreGcd) && Caster.SpellHistory.HasGlobalCooldown) { return(SpellCastResult.NotReady); } // check if already casting if (Caster.SpellCast.IsCasting && !SpellInfo.HasAttribute(SpellExtraAttributes.CanCastWhileCasting)) { return(SpellCastResult.NotReady); } SpellCastResult castResult = ValidateRange(); if (castResult != SpellCastResult.Success) { return(castResult); } if (!spellCastFlags.HasTargetFlag(SpellCastFlags.IgnoreTargetCheck)) { castResult = SpellInfo.CheckExplicitTarget(Caster, ExplicitTargets.Target); if (castResult != SpellCastResult.Success) { return(castResult); } if (ExplicitTargets.Target != null) { castResult = SpellInfo.CheckTarget(Caster, ExplicitTargets.Target, this, false); if (castResult != SpellCastResult.Success) { return(castResult); } } } return(SpellCastResult.Success); }