/// <summary> /// called after normal spell cast is completed and effect has to be started /// </summary> public virtual void FinishSpellCast(GameLiving target) { if (Caster is GamePlayer && ((GamePlayer)Caster).IsOnHorse && !HasPositiveEffect) ((GamePlayer)Caster).IsOnHorse = false; //[Stryve]: Do not break stealth if spell never breaks stealth. if ((Caster is GamePlayer) && UnstealthCasterOnFinish ) ((GamePlayer)Caster).Stealth(false); if (Caster is GamePlayer && !HasPositiveEffect) { if (Caster.AttackWeapon != null && Caster.AttackWeapon is GameInventoryItem) { (Caster.AttackWeapon as GameInventoryItem).OnSpellCast(Caster, target, Spell); } } // messages if (Spell.InstrumentRequirement == 0 && Spell.ClientEffect != 0 && Spell.CastTime > 0) { MessageToCaster("You cast a " + m_spell.Name + " spell!", eChatType.CT_Spell); foreach (GamePlayer player in m_caster.GetPlayersInRadius(WorldMgr.INFO_DISTANCE)) { if (player != m_caster) player.MessageFromArea(m_caster, m_caster.GetName(0, true) + " casts a spell!", eChatType.CT_Spell, eChatLoc.CL_SystemWindow); } } if (m_spell.Pulse != 0 && m_spell.Frequency > 0) { CancelAllPulsingSpells(Caster); PulsingSpellEffect pulseeffect = new PulsingSpellEffect(this); pulseeffect.Start(); // show animation on caster for positive spells, negative shows on every StartSpell if (m_spell.Target == "Self" || m_spell.Target == "Group") SendEffectAnimation(Caster, 0, false, 1); if (m_spell.Target == "Pet") SendEffectAnimation(target, 0, false,1); } StartSpell(target); // and action //Dinberg: This is where I moved the warlock part (previously found in gameplayer) to prevent //cancelling before the spell was fired. if (m_spell.SpellType != "Powerless" && m_spell.SpellType != "Range" && m_spell.SpellType != "Uninterruptable") { GameSpellEffect effect = SpellHandler.FindEffectOnTarget(m_caster, "Powerless"); if (effect == null) effect = SpellHandler.FindEffectOnTarget(m_caster, "Range"); if (effect == null) effect = SpellHandler.FindEffectOnTarget(m_caster, "Uninterruptable"); //if we found an effect, cancel it! if (effect != null) effect.Cancel(false); } //the quick cast is unallowed whenever you miss the spell //set the time when casting to can not quickcast during a minimum time if (m_caster is GamePlayer) { QuickCastEffect quickcast = m_caster.EffectList.GetOfType<QuickCastEffect>(); if (quickcast != null && Spell.CastTime > 0) { m_caster.TempProperties.setProperty(GamePlayer.QUICK_CAST_CHANGE_TICK, m_caster.CurrentRegion.Time); ((GamePlayer)m_caster).DisableSkill(SkillBase.GetAbility(Abilities.Quickcast), QuickCastAbilityHandler.DISABLE_DURATION); quickcast.Cancel(false); } } if (m_ability != null) m_caster.DisableSkill(m_ability.Ability, (m_spell.RecastDelay == 0 ? 3000 : m_spell.RecastDelay)); // disable spells with recasttimer (Disables group of same type with same delay) if (m_spell.RecastDelay > 0 && m_startReuseTimer) { if (m_caster is GamePlayer) { ICollection<Tuple<Skill, int>> toDisable = new List<Tuple<Skill, int>>(); GamePlayer gp_caster = m_caster as GamePlayer; foreach (var skills in gp_caster.GetAllUsableSkills()) if (skills.Item1 is Spell && (((Spell)skills.Item1).ID == m_spell.ID || ( ((Spell)skills.Item1).SharedTimerGroup != 0 && ( ((Spell)skills.Item1).SharedTimerGroup == m_spell.SharedTimerGroup) ) )) toDisable.Add(new Tuple<Skill, int>((Spell)skills.Item1, m_spell.RecastDelay)); foreach (var sl in gp_caster.GetAllUsableListSpells()) foreach(var sp in sl.Item2) if (sp is Spell && ( ((Spell)sp).ID == m_spell.ID || ( ((Spell)sp).SharedTimerGroup != 0 && ( ((Spell)sp).SharedTimerGroup == m_spell.SharedTimerGroup) ) )) toDisable.Add(new Tuple<Skill, int>((Spell)sp, m_spell.RecastDelay)); m_caster.DisableSkill(toDisable); } else if (m_caster is GameNPC) m_caster.DisableSkill(m_spell, m_spell.RecastDelay); } GameEventMgr.Notify(GameLivingEvent.CastFinished, m_caster, new CastingEventArgs(this, target, m_lastAttackData)); }
/// <summary> /// called after normal spell cast is completed and effect has to be started /// </summary> public virtual void FinishSpellCast(GameLiving target) { //turn into wraith if (m_caster is GamePlayer && ((m_caster as GamePlayer).CharacterClass.ID == (int)eCharacterClass.Bainshee) && (m_caster as GamePlayer).InWraithForm == false && !HasPositiveEffect) { (m_caster as GamePlayer).InWraithForm = true; } if (Caster is GamePlayer && ((GamePlayer)Caster).IsOnHorse && !HasPositiveEffect) ((GamePlayer)Caster).IsOnHorse = false; //[Stryve]: Do not break stealth if spell never breaks stealth. if ((Caster is GamePlayer) && UnstealthCasterOnFinish ) ((GamePlayer)Caster).Stealth(false); if (Caster is GamePlayer && !HasPositiveEffect) { if (Caster.AttackWeapon != null && Caster.AttackWeapon is GameInventoryItem) { (Caster.AttackWeapon as GameInventoryItem).OnSpellCast(Caster, target, Spell); } } // messages if (Spell.InstrumentRequirement == 0 && Spell.ClientEffect != 0 && Spell.CastTime > 0) { MessageToCaster("You cast a " + m_spell.Name + " spell!", eChatType.CT_Spell); foreach (GamePlayer player in m_caster.GetPlayersInRadius(WorldMgr.INFO_DISTANCE)) { if (player != m_caster) player.Out.SendMessage(m_caster.GetName(0, true) + " casts a spell!", eChatType.CT_Spell, eChatLoc.CL_SystemWindow); } } if (m_spell.Pulse != 0 && m_spell.Frequency > 0) { CancelAllPulsingSpells(Caster); PulsingSpellEffect pulseeffect = new PulsingSpellEffect(this); pulseeffect.Start(); // show animation on caster for positive spells, negative shows on every StartSpell if (m_spell.Target == "Self" || m_spell.Target == "Group") SendEffectAnimation(Caster, 0, false, 1); if (m_spell.Target == "Pet") SendEffectAnimation(target, 0, false,1); } StartSpell(target); // and action //Dinberg: This is where I moved the warlock part (previously found in gameplayer) to prevent //cancelling before the spell was fired. if (m_spell.SpellType != "Powerless" && m_spell.SpellType != "Range" && m_spell.SpellType != "Uninterruptable") { GameSpellEffect effect = SpellHandler.FindEffectOnTarget(m_caster, "Powerless"); if (effect == null) effect = SpellHandler.FindEffectOnTarget(m_caster, "Range"); if (effect == null) effect = SpellHandler.FindEffectOnTarget(m_caster, "Uninterruptable"); //if we found an effect, cancel it! if (effect != null) effect.Cancel(false); } //Subspells if (m_spell.SubSpellID > 0 && Spell.SpellType != "Archery" && Spell.SpellType != "Bomber" && Spell.SpellType != "SummonAnimistFnF" && Spell.SpellType != "SummonAnimistPet" && Spell.SpellType != "Grapple") { Spell spell = SkillBase.GetSpellByID(m_spell.SubSpellID); //we need subspell ID to be 0, we don't want spells linking off the subspell if (target != null && spell != null && spell.SubSpellID == 0) { ISpellHandler spellhandler = ScriptMgr.CreateSpellHandler(m_caster, spell, SkillBase.GetSpellLine(GlobalSpellsLines.Reserved_Spells)); spellhandler.StartSpell(target); } } //the quick cast is unallowed whenever you miss the spell //set the time when casting to can not quickcast during a minimum time if (m_caster is GamePlayer) { QuickCastEffect quickcast = m_caster.EffectList.GetOfType<QuickCastEffect>(); if (quickcast != null && Spell.CastTime > 0) { m_caster.TempProperties.setProperty(GamePlayer.QUICK_CAST_CHANGE_TICK, m_caster.CurrentRegion.Time); ((GamePlayer)m_caster).DisableSkill(SkillBase.GetAbility(Abilities.Quickcast), QuickCastAbilityHandler.DISABLE_DURATION); quickcast.Cancel(false); } } if (m_ability != null) m_caster.DisableSkill(m_ability.Ability, (m_spell.RecastDelay == 0 ? 3 : m_spell.RecastDelay)); // disable spells with recasttimer (Disables group of same type with same delay) if (m_spell.RecastDelay > 0 && m_startReuseTimer) { if (m_caster is GamePlayer) { GamePlayer gp_caster = m_caster as GamePlayer; foreach (SpellLine spellline in gp_caster.GetSpellLines()) foreach (Spell sp in SkillBase.GetSpellList(spellline.KeyName)) if (sp == m_spell || (sp.SharedTimerGroup != 0 && (sp.SharedTimerGroup == m_spell.SharedTimerGroup))) m_caster.DisableSkill(sp, sp.RecastDelay); } else if (m_caster is GameNPC) m_caster.DisableSkill(m_spell, m_spell.RecastDelay); } GameEventMgr.Notify(GameLivingEvent.CastFinished, m_caster, new CastingEventArgs(this, target, m_lastAttackData)); }