Пример #1
0
        /// <summary>
        /// Calculates the damage reduction modifier for bows and casters
        /// with 'Magic Absorbing' property
        /// </summary>
        public float AbsorbMagic(Creature target, WorldObject item)
        {
            // https://asheron.fandom.com/wiki/Category:Magic_Absorbing

            // Tomes and Bows
            // The formula to determine magic absorption for Tomes and the Fetish of the Dark Idols:
            // - For a 25% maximum item: (magic absorbing %) = 25 - (0.1 * (319 - base magic defense))
            // - For a 10% maximum item: (magic absorbing %) = 10 - (0.04 * (319 - base magic defense))

            // wiki currently has what is likely a typo for the 10% formula,
            // where it has a factor of 0.4 instead of 0.04
            // with 0.4, the 10% items would not start to become effective until base magic defense 294
            // with 0.04, both formulas start to become effective at base magic defense 69

            // using an equivalent formula that produces the correct results for 10% and 25%,
            // and also produces the correct results for any %

            if (item.AbsorbMagicDamage == null)
            {
                return(1.0f);
            }

            var maxPercent = item.AbsorbMagicDamage.Value;

            var baseCap      = 319;
            var magicDefBase = target.GetCreatureSkill(Skill.MagicDefense).Base;
            var diff         = Math.Max(0, baseCap - magicDefBase);

            var percent = maxPercent - maxPercent * diff * 0.004f;

            return(Math.Min(1.0f, 1.0f - (float)percent));
        }
Пример #2
0
        /// <summary>
        /// Calculates the amount of damage a shield absorbs from magic projectile
        /// </summary>
        public float GetShieldMod(Creature target)
        {
            // ensure combat stance
            if (target.CombatMode == CombatMode.NonCombat)
            {
                return(1.0f);
            }

            // does the player have a shield equipped?
            var shield = target.GetEquippedShield();

            if (shield == null || shield.GetProperty(PropertyFloat.AbsorbMagicDamage) == null)
            {
                return(1.0f);
            }

            // is spell projectile in front of player,
            // within shield effectiveness area?
            var effectiveAngle = 180.0f;
            var angle          = target.GetAngle(this);

            if (Math.Abs(angle) > effectiveAngle / 2.0f)
            {
                return(1.0f);
            }

            // https://asheron.fandom.com/wiki/Shield
            // The formula to determine magic absorption for shields is:
            // Reduction Percent = (cap * specMod * baseSkill * 0.003f) - (cap * specMod * 0.3f)
            // Cap = Maximum reduction
            // SpecMod = 1.0 for spec, 0.8 for trained
            // BaseSkill = 100 to 433 (above 433 base shield you always achieve the maximum %)

            var shieldSkill = target.GetCreatureSkill(Skill.Shield);

            // ensure trained?
            if (shieldSkill.AdvancementClass < SkillAdvancementClass.Trained || shieldSkill.Base < 100)
            {
                return(1.0f);
            }

            var baseSkill = Math.Min(shieldSkill.Base, 433);
            var specMod   = shieldSkill.AdvancementClass == SkillAdvancementClass.Specialized ? 1.0f : 0.8f;
            var cap       = (float)(shield.GetProperty(PropertyFloat.AbsorbMagicDamage) ?? 0.0f);

            // speced, 100 skill = 0%
            // trained, 100 skill = 0%
            // speced, 200 skill = 30%
            // trained, 200 skill = 24%
            // speced, 300 skill = 60%
            // trained, 300 skill = 48%
            // speced, 433 skill = 100%
            // trained, 433 skill = 80%

            var reduction = (cap * specMod * baseSkill * 0.003f) - (cap * specMod * 0.3f);

            var shieldMod = 1.0f - reduction;

            return(shieldMod);
        }
Пример #3
0
        public uint CalculateManaUsage(Creature caster, SpellBase spell, WorldObject target = null)
        {
            var items = new List <WorldObject>();

            if ((target as Player) != null)
            {
                items = (target as Player).GetAllWieldedItems();
            }

            CreatureSkill mc = caster.GetCreatureSkill(Skill.ManaConversion);
            double        z  = mc.Current;
            double        baseManaPercent = 1;

            if (z > spell.Power)
            {
                baseManaPercent = spell.Power / z;
            }
            double preCost  = 0;
            uint   manaUsed = 0;

            if ((int)Math.Floor(baseManaPercent) == 1)
            {
                preCost  = spell.BaseMana;
                manaUsed = (uint)preCost;
            }
            else
            {
                if ((spell.School == MagicSchool.ItemEnchantment) && (spell.MetaSpellType == SpellType.Enchantment))
                {
                    int count = 1;
                    if ((target as Player) != null)
                    {
                        count = items.Count;
                    }

                    preCost = (spell.BaseMana + (spell.ManaMod * items.Count)) * baseManaPercent;
                }
                else
                {
                    preCost = spell.BaseMana * baseManaPercent;
                }
                if (preCost < 1)
                {
                    preCost = 1;
                }
                manaUsed = (uint)Physics.Common.Random.RollDice(1, (int)preCost);
            }

            return(manaUsed);
        }
Пример #4
0
        public uint CalculateManaUsage(Creature caster, Spell spell, WorldObject target = null)
        {
            var baseCost = spell.BaseMana;

            // for casting spells built into a casting implement, use the ItemManaCost
            var castItem = caster.GetEquippedWand();

            if (castItem != null && (castItem.SpellDID ?? 0) == spell.Id)
            {
                baseCost = (uint)(castItem.ItemManaCost ?? 0);
            }

            uint mana_conversion_skill = caster.GetCreatureSkill(Skill.ManaConversion).Current;
            uint difficulty            = spell.PowerMod; // modified power difficulty

            double baseManaPercent = 1.0;

            if (mana_conversion_skill > difficulty)
            {
                baseManaPercent = (double)difficulty / mana_conversion_skill;
            }

            uint preCost = 0;

            if ((spell.School == MagicSchool.ItemEnchantment) && (spell.MetaSpellType == SpellType.Enchantment))
            {
                var targetPlayer = target as Player;

                int numTargetItems = 1;
                if (targetPlayer != null)
                {
                    numTargetItems = targetPlayer.EquippedObjects.Count;
                }
                preCost = (uint)Math.Round((baseCost + (spell.ManaMod * numTargetItems)) * baseManaPercent);
            }
            else
            {
                preCost = (uint)Math.Round(baseCost * baseManaPercent);
            }

            if (preCost < 1)
            {
                preCost = 1;
            }

            uint manaUsed = ThreadSafeRandom.Next(1, preCost);

            return(manaUsed);
        }
Пример #5
0
        public uint CalculateManaUsage(Creature caster, Spell spell, WorldObject target = null)
        {
            var baseCost = spell.BaseMana;

            // for casting spells built into a casting implement, use the ItemManaCost
            var castItem = caster.GetEquippedWand();

            if (castItem != null && (castItem.SpellDID ?? 0) == spell.Id)
            {
                baseCost = (uint)(castItem.ItemManaCost ?? 0);
            }

            if ((spell.School == MagicSchool.ItemEnchantment) && (spell.MetaSpellType == SpellType.Enchantment) &&
                (spell.Category >= SpellCategory.ArmorValueRaising) && (spell.Category <= SpellCategory.AcidicResistanceLowering) && target is Player targetPlayer)
            {
                var numTargetItems = 1;
                if (targetPlayer != null)
                {
                    numTargetItems = targetPlayer.EquippedObjects.Values.Count(i => (i is Clothing || i.IsShield) && i.IsEnchantable);
                }

                baseCost += spell.ManaMod * (uint)numTargetItems;
            }
            else if ((spell.Flags & SpellFlags.FellowshipSpell) != 0)
            {
                var numFellows = 1;
                if (this is Player player && player.Fellowship != null)
                {
                    numFellows = player.Fellowship.FellowshipMembers.Count;
                }

                baseCost += spell.ManaMod * (uint)numFellows;
            }

            var manaConversion = caster.GetCreatureSkill(Skill.ManaConversion);

            if (manaConversion.AdvancementClass < SkillAdvancementClass.Trained || spell.Flags.HasFlag(SpellFlags.IgnoresManaConversion))
            {
                return(baseCost);
            }

            var difficulty = spell.PowerMod;   // modified power difficulty

            var mana_conversion_skill = (uint)Math.Round(manaConversion.Current * GetWeaponManaConversionModifier(caster));

            var manaCost = GetManaCost(difficulty, baseCost, mana_conversion_skill);

            return(manaCost);
        }
Пример #6
0
        public uint CalculateManaUsage(Creature caster, SpellBase spell, WorldObject target = null)
        {
            uint mana_conversion_skill = caster.GetCreatureSkill(Skill.ManaConversion).Current;
            uint difficulty            = Math.Max(25, spell.Power); // for mana conversion only?

            double baseManaPercent = 1.0;

            if (mana_conversion_skill > difficulty)
            {
                baseManaPercent = (double)difficulty / mana_conversion_skill;
            }

            uint preCost = 0;

            if ((spell.School == MagicSchool.ItemEnchantment) && (spell.MetaSpellType == SpellType.Enchantment))
            {
                var targetPlayer = target as Player;

                int numTargetItems = 1;
                if (targetPlayer != null)
                {
                    var targetItems = targetPlayer.GetAllWieldedItems();
                    numTargetItems = targetItems.Count;
                }
                preCost = (uint)Math.Round((spell.BaseMana + (spell.ManaMod * numTargetItems)) * baseManaPercent);
            }
            else
            {
                preCost = (uint)Math.Round(spell.BaseMana * baseManaPercent);
            }

            if (preCost < 1)
            {
                preCost = 1;
            }

            uint manaUsed = Physics.Common.Random.RollDice(1, preCost);

            return(manaUsed);
        }
Пример #7
0
        public uint CalculateManaUsage(Creature caster, Spell spell, WorldObject target = null)
        {
            var baseCost = spell.BaseMana;

            // for casting spells built into a casting implement, use the ItemManaCost
            var castItem = caster.GetEquippedWand();

            if (castItem != null && (castItem.SpellDID ?? 0) == spell.Id)
            {
                baseCost = (uint)(castItem.ItemManaCost ?? 0);
            }

            uint mana_conversion_skill = (uint)Math.Round(caster.GetCreatureSkill(Skill.ManaConversion).Current *GetWeaponManaConversionModifier(caster));

            uint difficulty = spell.PowerMod;   // modified power difficulty

            double baseManaPercent = 1.0;

            if (mana_conversion_skill > difficulty)
            {
                baseManaPercent = (double)difficulty / mana_conversion_skill;
            }

            uint preCost = 0;

            if ((spell.School == MagicSchool.ItemEnchantment) && (spell.MetaSpellType == SpellType.Enchantment) &&
                (spell.Category >= SpellCategory.ArmorValueRaising) && (spell.Category <= SpellCategory.AcidicResistanceLowering) && target is Player targetPlayer)
            {
                int numTargetItems = 1;
                if (targetPlayer != null)
                {
                    numTargetItems = targetPlayer.EquippedObjects.Values.Count(i => (i is Clothing || i.IsShield) && i.IsEnchantable);
                }

                preCost = (uint)Math.Round((baseCost + (spell.ManaMod * numTargetItems)) * baseManaPercent);
            }
            else if ((spell.Flags & SpellFlags.FellowshipSpell) != 0)
            {
                int numFellows = 1;
                var player     = this as Player;
                if (player != null && player.Fellowship != null)
                {
                    numFellows = player.Fellowship.FellowshipMembers.Count;
                }

                preCost = (uint)Math.Round((baseCost + (spell.ManaMod * numFellows)) * baseManaPercent);
            }
            else
            {
                preCost = (uint)Math.Round(baseCost * baseManaPercent);
            }

            if (preCost < 1)
            {
                preCost = 1;
            }

            uint manaUsed = ThreadSafeRandom.Next(1, preCost);

            return(manaUsed);
        }
Пример #8
0
        /// <summary>
        /// Method used for handling player targeted spell casts
        /// </summary>
        public void CreatePlayerSpell(ObjectGuid guidTarget, uint spellId)
        {
            Player         player         = CurrentLandblock.GetObject(Guid) as Player;
            WorldObject    target         = CurrentLandblock.GetObject(guidTarget);
            TargetCategory targetCategory = TargetCategory.WorldObject;

            if (target == null)
            {
                target         = GetWieldedItem(guidTarget);
                targetCategory = TargetCategory.Wielded;
            }
            if (target == null)
            {
                target         = GetInventoryItem(guidTarget);
                targetCategory = TargetCategory.Inventory;
            }
            if (target == null)
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.TargetNotAcquired));
                targetCategory = TargetCategory.UnDef;
                return;
            }

            SpellTable spellTable = DatManager.PortalDat.SpellTable;

            if (!spellTable.Spells.ContainsKey(spellId))
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicInvalidSpellType));
                return;
            }

            SpellBase spell = spellTable.Spells[spellId];

            if (IsInvalidTarget(spell, target))
            {
                player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, $"{spell.Name} cannot be cast on {target.Name}."));
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None));
                return;
            }

            Database.Models.World.Spell spellStatMod = DatabaseManager.World.GetCachedSpell(spellId);
            if (spellStatMod == null)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{spell.Name} spell not implemented, yet!", ChatMessageType.System));
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicInvalidSpellType));
                return;
            }

            if (player.IsBusy == true)
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YoureTooBusy));
                return;
            }
            else
            {
                player.IsBusy = true;
            }

            uint targetEffect = spell.TargetEffect;

            // Grab player's skill level in the spell's Magic School
            var magicSkill = player.GetCreatureSkill(spell.School).Current;

            if (targetCategory == TargetCategory.WorldObject)
            {
                if (guidTarget != Guid)
                {
                    float distanceTo = Location.Distance2D(target.Location);

                    if (distanceTo > spell.BaseRangeConstant + magicSkill * spell.BaseRangeMod)
                    {
                        player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.MagicTargetOutOfRange),
                                                           new GameMessageSystemChat($"{target.Name} is out of range!", ChatMessageType.Magic));
                        player.IsBusy = false;
                        return;
                    }
                }
            }

            // Ensure that a harmful spell isn't being cast on a player target that doesn't have the same PK status
            if (target.WeenieClassId == 1 && player.PlayerKillerStatus != ACE.Entity.Enum.PlayerKillerStatus.NPK)
            {
                bool isSpellHarmful = IsSpellHarmful(spell);
                if (player.PlayerKillerStatus != target.PlayerKillerStatus && isSpellHarmful)
                {
                    player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.InvalidPkStatus));
                    player.IsBusy = false;
                    return;
                }
            }

            float scale   = SpellAttributes(player.Session.Account, spellId, out float castingDelay, out MotionCommand windUpMotion, out MotionCommand spellGesture);
            var   formula = SpellTable.GetSpellFormula(spellTable, spellId, player.Session.Account);

            bool spellCastSuccess = false || ((Physics.Common.Random.RollDice(0.0f, 1.0f) > (1.0f - SkillCheck.GetMagicSkillChance((int)magicSkill, (int)spell.Power))) &&
                                              (magicSkill >= (int)spell.Power - 50) && (magicSkill > 0));

            // Calculating mana usage
            #region
            CreatureSkill mc = player.GetCreatureSkill(Skill.ManaConversion);
            double        z  = mc.Current;
            double        baseManaPercent = 1;
            if (z > spell.Power)
            {
                baseManaPercent = spell.Power / z;
            }
            double preCost;
            uint   manaUsed;
            if ((int)Math.Floor(baseManaPercent) == 1)
            {
                preCost  = spell.BaseMana;
                manaUsed = (uint)preCost;
            }
            else
            {
                preCost = spell.BaseMana * baseManaPercent;
                if (preCost < 1)
                {
                    preCost = 1;
                }
                manaUsed = (uint)Physics.Common.Random.RollDice(1, (int)preCost);
            }
            if (spell.MetaSpellType == SpellType.Transfer)
            {
                uint vitalChange, casterVitalChange;
                vitalChange = (uint)(player.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source) * spellStatMod.Proportion);
                if (spellStatMod.TransferCap != 0)
                {
                    if (vitalChange > spellStatMod.TransferCap)
                    {
                        vitalChange = (uint)spellStatMod.TransferCap;
                    }
                }
                casterVitalChange = (uint)(vitalChange * (1.0f - spellStatMod.LossPercent));
                vitalChange       = (uint)(casterVitalChange / (1.0f - spellStatMod.LossPercent));

                if (spellStatMod.Source == (int)PropertyAttribute2nd.Mana && (vitalChange + 10 + manaUsed) > player.Mana.Current)
                {
                    ActionChain resourceCheckChain = new ActionChain();

                    resourceCheckChain.AddAction(this, () =>
                    {
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                    });

                    resourceCheckChain.AddDelaySeconds(2.0f);
                    resourceCheckChain.AddAction(this, () =>
                    {
                        player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                        player.IsBusy = false;
                    });

                    resourceCheckChain.EnqueueChain();

                    return;
                }
                else if ((vitalChange + 10) > player.GetCurrentCreatureVital((PropertyAttribute2nd)spellStatMod.Source))
                {
                    ActionChain resourceCheckChain = new ActionChain();

                    resourceCheckChain.AddAction(this, () =>
                    {
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                    });

                    resourceCheckChain.AddDelaySeconds(2.0f);
                    resourceCheckChain.AddAction(this, () => player.IsBusy = false);
                    resourceCheckChain.EnqueueChain();

                    return;
                }
            }
            else if (manaUsed > player.Mana.Current)
            {
                ActionChain resourceCheckChain = new ActionChain();

                resourceCheckChain.AddAction(this, () =>
                {
                    CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f));
                });

                resourceCheckChain.AddDelaySeconds(2.0f);
                resourceCheckChain.AddAction(this, () =>
                {
                    player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.YouDontHaveEnoughManaToCast));
                    player.IsBusy = false;
                });

                resourceCheckChain.EnqueueChain();

                return;
            }
            else
            {
                player.UpdateVital(player.Mana, player.Mana.Current - manaUsed);
            }
            #endregion

            ActionChain spellChain = new ActionChain();

            uint fastCast = (spell.Bitfield >> 14) & 0x1u;
            if (fastCast != 1)
            {
                spellChain.AddAction(this, () =>
                {
                    var motionWindUp = new UniversalMotion(MotionStance.Spellcasting);
                    motionWindUp.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                    motionWindUp.MovementData.ForwardCommand = (uint)windUpMotion;
                    motionWindUp.MovementData.ForwardSpeed   = 2;
                    DoMotion(motionWindUp);
                });
            }

            spellChain.AddAction(this, () =>
            {
                CurrentLandblock.EnqueueBroadcast(Location, new GameMessageCreatureMessage(SpellComponentsTable.GetSpellWords(DatManager.PortalDat.SpellComponentsTable,
                                                                                                                              formula), Name, Guid.Full, ChatMessageType.Magic));
            });

            spellChain.AddAction(this, () =>
            {
                var motionCastSpell = new UniversalMotion(MotionStance.Spellcasting);
                motionCastSpell.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionCastSpell.MovementData.ForwardCommand = (uint)spellGesture;
                motionCastSpell.MovementData.ForwardSpeed   = 2;
                DoMotion(motionCastSpell);
            });

            if (fastCast == 1)
            {
                spellChain.AddDelaySeconds(castingDelay * 0.26f);
            }
            else
            {
                spellChain.AddDelaySeconds(castingDelay);
            }

            if (spellCastSuccess == false)
            {
                spellChain.AddAction(this, () => CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, ACE.Entity.Enum.PlayScript.Fizzle, 0.5f)));
            }
            else
            {
                spellChain.AddAction(this, () =>
                {
                    bool targetDeath;
                    string message;

                    switch (spell.School)
                    {
                    case MagicSchool.WarMagic:
                        WarMagic(target, spell, spellStatMod);
                        break;

                    case MagicSchool.VoidMagic:
                        VoidMagic(target, spell, spellStatMod);
                        break;

                    case MagicSchool.CreatureEnchantment:
                        if (IsSpellHarmful(spell))
                        {
                            // Retrieve player's skill level in the Magic School
                            var playerMagicSkill = player.GetCreatureSkill(spell.School).Current;

                            // Retrieve target's Magic Defense Skill
                            Creature creature           = (Creature)target;
                            var targetMagicDefenseSkill = creature.GetCreatureSkill(Skill.MagicDefense).Current;

                            if (MagicDefenseCheck(playerMagicSkill, targetMagicDefenseSkill))
                            {
                                CurrentLandblock.EnqueueBroadcastSound(player, Sound.ResistSpell);
                                player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{creature.Name} resists {spell.Name}", ChatMessageType.Magic));
                                break;
                            }
                        }
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        message = CreatureMagic(target, spell, spellStatMod);
                        if (message != "")
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        break;

                    case MagicSchool.LifeMagic:
                        if (spell.MetaSpellType != SpellType.LifeProjectile)
                        {
                            if (IsSpellHarmful(spell))
                            {
                                // Retrieve player's skill level in the Magic School
                                var playerMagicSkill = player.GetCreatureSkill(spell.School).Current;

                                // Retrieve target's Magic Defense Skill
                                Creature creature           = (Creature)target;
                                var targetMagicDefenseSkill = creature.GetCreatureSkill(Skill.MagicDefense).Current;

                                if (MagicDefenseCheck(playerMagicSkill, targetMagicDefenseSkill))
                                {
                                    CurrentLandblock.EnqueueBroadcastSound(player, Sound.ResistSpell);
                                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"{creature.Name} resists {spell.Name}", ChatMessageType.Magic));
                                    break;
                                }
                            }
                        }
                        CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        targetDeath = LifeMagic(target, spell, spellStatMod, out message);
                        if (message != null)
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        if (targetDeath == true)
                        {
                            Creature creatureTarget = (Creature)target;
                            creatureTarget.Die();
                            Strings.DeathMessages.TryGetValue(DamageType.Base, out var messages);
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(string.Format(messages[0], target.Name), ChatMessageType.Broadcast));
                            player.EarnXP((long)target.XpOverride);
                        }
                        break;

                    case MagicSchool.ItemEnchantment:
                        if (guidTarget == Guid)
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(Guid, (PlayScript)spell.CasterEffect, scale));
                        }
                        else
                        {
                            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageScript(target.Guid, (PlayScript)spell.TargetEffect, scale));
                        }
                        message = ItemMagic(target, spell, spellStatMod);
                        if (message != "")
                        {
                            player.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Magic));
                        }
                        break;

                    default:
                        break;
                    }
                });
            }

            spellChain.AddAction(this, () =>
            {
                var motionReturnToCastStance = new UniversalMotion(MotionStance.Spellcasting);
                motionReturnToCastStance.MovementData.CurrentStyle   = (ushort)((uint)MotionStance.Spellcasting & 0xFFFF);
                motionReturnToCastStance.MovementData.ForwardCommand = (uint)MotionCommand.Invalid;
                DoMotion(motionReturnToCastStance);
            });

            spellChain.AddDelaySeconds(1.0f);

            spellChain.AddAction(this, () =>
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.None));
                player.IsBusy = false;
            });

            spellChain.EnqueueChain();

            return;
        }