/// <summary> /// Called when finished casting /// </summary> void OnAICasted() { if (Spell.AISettings.IdleTimeAfterCastMillis > 0) { CasterUnit.Idle(Spell.AISettings.IdleTimeAfterCastMillis); } }
private void ConsumeCombopoints() { if (Spell.IsFinishingMove) { CasterUnit.ModComboState(null, 0); } }
private void ResetSwingDelay() { if (Spell.HasHarmfulEffects && !Spell.IsPreventionDebuff && CasterUnit.IsInCombat) { CasterUnit.ResetSwingDelay(); } }
/// <summary> /// Trigger proc on the caster of the spell. /// </summary> /// <param name="flags">What spell caster casted ie. ProcTriggerFlags.DoneHarmfulSpell</param> /// <param name="hitFlags">Hit result of the spell</param> private void TriggerProcOnCaster(ProcTriggerFlags flags, ProcHitFlags hitFlags) { var casterAction = new SimpleUnitAction { Attacker = CasterUnit, Spell = Spell, Victim = m_hitInfoByTarget.Count > 0 ? m_hitInfoByTarget.First().Key : null, IsCritical = hitFlags.HasAnyFlag(ProcHitFlags.CriticalHit) }; var triggerer = UnitTargets.FirstOrDefault(); CasterUnit.Proc(flags, triggerer, casterAction, true, hitFlags); }
/// <summary> /// Validates targets and applies all SpellEffects /// </summary> public SpellFailedReason Impact() { if (!IsCasting) { return(SpellFailedReason.Ok); } // apply effects foreach (var handler in Handlers) { if (handler.Effect.IsPeriodic || handler.Effect.IsStrikeEffect) { // weapon ability or handled by Aura or Channel continue; } handler.Apply(); if (!IsCasting) { // the last handler cancelled the SpellCast return(SpellFailedReason.DontReport); } } if (CasterObject is Unit && Spell.IsPhysicalAbility) { // strike at everyone foreach (var target in UnitTargets) { ProcHitFlags hitFlags = CasterUnit.Strike(GetWeapon(), target, this); m_hitInfoByTarget[target] = hitFlags; } } // open Channel and spawn DynamicObject DynamicObject dynObj = null; if (Spell.DOEffect != null) { dynObj = new DynamicObject(this, Spell.DOEffect.GetRadius(CasterReference)); } if (!IsCasting) { return(SpellFailedReason.Ok); } List <MissedTarget> missedTargets = null; // create auras List <IAura> auras = null; if (m_auraApplicationInfos != null) { CreateAuras(ref missedTargets, ref auras, dynObj); } // check for missed targets if (missedTargets != null) { if (missedTargets.Count > 0) { // TODO: Flash message ontop of missed heads when impact is delayed CombatLogHandler.SendSpellMiss(this, true, missedTargets); missedTargets.Clear(); } CastMissListPool.Recycle(missedTargets); } // open channel if (Spell.IsChanneled && CasterObject != null) { Channel = SpellChannel.SpellChannelPool.Obtain(); Channel.m_cast = this; if (CasterObject is Unit) { if (dynObj != null) { CasterUnit.ChannelObject = dynObj; } else if (SelectedTarget != null) { CasterUnit.ChannelObject = SelectedTarget; if (SelectedTarget is NPC && Spell.IsTame) { ((NPC)SelectedTarget).CurrentTamer = CasterObject as Character; } } } var len = Handlers.Length; var channelEffectHandlers = SpellEffectHandlerListPool.Obtain(); //var channelEffectHandlers = new List<SpellEffectHandler>(6); for (var i = 0; i < len; i++) { var handler = Handlers[i]; if (handler.Effect.IsPeriodic) { channelEffectHandlers.Add(handler); } } Channel.Open(channelEffectHandlers, auras); } // start Auras if (auras != null) { for (var i = 0; i < auras.Count; i++) { var aura = auras[i]; aura.Start(Spell.IsChanneled ? Channel : null, false); } if (!IsChanneling) { auras.Clear(); AuraListPool.Recycle(auras); auras = null; } } // applying debuffs might cancel other Auras if (Spell.HasHarmfulEffects && !Spell.IsPreventionDebuff) { foreach (var target in Targets) { if (target is Unit && Spell.IsHarmfulFor(CasterReference, target)) { ((Unit)target).Auras.RemoveByFlag(AuraInterruptFlags.OnHostileSpellInflicted); } } } //if (CasterChar != null) //{ // CasterChar.SendSystemMessage("SpellCast (Impact): {0} ms", sw1.ElapsedTicks / 10000d); //} return(SpellFailedReason.Ok); }