Beispiel #1
0
        /// <summary>
        /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para />
        /// The actor of the ActionChain is the item being used.<para />
        /// The item does not exist in the players possession.<para />
        /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para />
        /// When this is called, it should be assumed that the player is within range.
        /// </summary>
        public override void ActOnUse(Player player)
        {
            ActionChain sancTimer = new ActionChain();

            sancTimer.AddAction(player, () =>
            {
                CurrentLandblock.EnqueueBroadcastMotion(player, sanctuary);
                CurrentLandblock.EnqueueBroadcastSound(player, Sound.LifestoneOn, 1);
            });
            sancTimer.AddDelaySeconds(DatManager.PortalDat.ReadFromDat <MotionTable>(player.MotionTableId).GetAnimationLength(MotionCommand.Sanctuary));
            sancTimer.AddAction(player, () =>
            {
                if (player.IsWithinUseRadiusOf(this))
                {
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat(GetProperty(PropertyString.UseMessage), ChatMessageType.Magic));
                    player.Sanctuary = player.Location;
                }
                // Unsure if there was a fail message...
                //else
                //{
                //    var serverMessage = "You wandered too far to attune with the Lifestone!";
                //    player.Session.Network.EnqueueSend(new GameMessageSystemChat(serverMessage, ChatMessageType.Magic));
                //}

                player.SendUseDoneEvent();
            });
            sancTimer.EnqueueChain();
        }
Beispiel #2
0
        public override void HandleActionOnUse(ObjectGuid playerId)
        {
            ActionChain chain = new ActionChain();

            CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) =>
            {
                Player player = wo as Player;
                if (player == null)
                {
                    return;
                }

                ////if (playerDistanceTo >= 2500)
                ////{
                ////    var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037);
                ////    player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent);
                ////    return;
                ////}

                if (!player.IsWithinUseRadiusOf(this))
                {
                    player.DoMoveTo(this);
                }
                else
                {
                    ActionChain checkDoorChain = new ActionChain();

                    checkDoorChain.AddAction(this, () =>
                    {
                        if (!IsLocked)
                        {
                            if (!IsOpen)
                            {
                                Open(playerId);
                            }
                            else
                            {
                                Close(playerId);
                            }

                            // Create Door auto close timer
                            ActionChain autoCloseTimer = new ActionChain();
                            autoCloseTimer.AddDelaySeconds(ResetInterval);
                            autoCloseTimer.AddAction(this, () => Reset());
                            autoCloseTimer.EnqueueChain();
                        }
                        else
                        {
                            CurrentLandblock.EnqueueBroadcastSound(this, Sound.OpenFailDueToLock);
                        }

                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(sendUseDoneEvent);
                    });

                    checkDoorChain.EnqueueChain();
                }
            });
            chain.EnqueueChain();
        }
Beispiel #3
0
        public override void ActOnUse(ObjectGuid playerId)
        {
            Player player = CurrentLandblock.GetObject(playerId) as Player;

            if (player == null)
            {
                return;
            }

            ////if (playerDistanceTo >= 2500)
            ////{
            ////    var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037);
            ////    player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent);
            ////    return;
            ////}

            if (!player.IsWithinUseRadiusOf(this) && Viewer != player.Guid.Full)
            {
                player.DoMoveTo(this);
            }
            else
            {
                if (!(IsLocked ?? false))
                {
                    if (!(IsOpen ?? false))
                    {
                        var turnToMotion = new UniversalMotion(MotionStance.Standing, Location, Guid);
                        turnToMotion.MovementTypes = MovementTypes.TurnToObject;

                        ActionChain turnToTimer = new ActionChain();
                        turnToTimer.AddAction(this, () => player.CurrentLandblock.EnqueueBroadcastMotion(player, turnToMotion));;
                        turnToTimer.AddDelaySeconds(1);
                        turnToTimer.AddAction(this, () => Open(player));
                        turnToTimer.EnqueueChain();

                        return;
                    }
                    else
                    {
                        if (Viewer == player.Guid.Full)
                        {
                            Close(player);
                        }
                        // else error msg?
                    }
                }
                else
                {
                    CurrentLandblock.EnqueueBroadcastSound(this, Sound.OpenFailDueToLock);
                }
                player.SendUseDoneEvent();
            }
        }
Beispiel #4
0
        public void TakeDamage(WorldObject source, DamageType damageType, float _amount, BodyPart bodyPart, bool crit = false)
        {
            if (Invincible ?? false)
            {
                return;
            }

            var amount  = (uint)Math.Round(_amount);
            var percent = (float)amount / Health.MaxValue;

            // update health
            Health.Current = (uint)Math.Max(0, (int)Health.Current - amount);
            if (Health.Current == 0)
            {
                HandleActionDie();
                return;
            }

            var damageLocation = (DamageLocation)BodyParts.Indices[bodyPart];

            // send network messages
            Session.Network.EnqueueSend(new GameMessagePrivateUpdateAttribute2ndLevel(this, Vital.Health, Health.Current));

            var creature = source as Creature;
            var hotspot  = source as Hotspot;

            if (creature != null)
            {
                var hitSound = new GameMessageSound(Guid, GetHitSound(source, bodyPart), 1.0f);
                var splatter = new GameMessageScript(Guid, (PlayScript)Enum.Parse(typeof(PlayScript), "Splatter" + GetSplatterHeight() + creature.GetSplatterDir(this)));
                var text     = new GameEventDefenderNotification(Session, creature.Name, damageType, percent, amount, damageLocation, crit, AttackConditions.None);
                Session.Network.EnqueueSend(text, hitSound, splatter);
            }
            else if (hotspot != null)
            {
                if (!string.IsNullOrWhiteSpace(hotspot.ActivationTalkString))
                {
                    Session.Network.EnqueueSend(new GameMessageSystemChat(hotspot.ActivationTalkString.Replace("%i", amount.ToString()), ChatMessageType.Craft));
                }
                if (!(hotspot.Visibility ?? false))
                {
                    CurrentLandblock.EnqueueBroadcastSound(hotspot, Sound.TriggerActivated);
                }
            }

            if (percent >= 0.1f)
            {
                var wound = new GameMessageSound(Guid, Sound.Wound1, 1.0f);
                Session.Network.EnqueueSend(wound);
            }
        }
Beispiel #5
0
        //private static readonly MotionState motionStateOpen = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.On));
        //private static readonly MotionState motionStateClosed = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.Off));

        /// <summary>
        /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para />
        /// The actor of the ActionChain is the item being used.<para />
        /// The item does not exist in the players possession.<para />
        /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para />
        /// When this is called, it should be assumed that the player is within range.
        /// </summary>
        public override void ActOnUse(WorldObject worldObject)
        {
            if (worldObject is Player)
            {
                var player = worldObject as Player;
                ////if (playerDistanceTo >= 2500)
                ////{
                ////    var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037);
                ////    player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent);
                ////    return;
                ////}

                if (!(IsLocked ?? false))
                {
                    if (!(IsOpen ?? false))
                    {
                        var turnToMotion = new UniversalMotion(MotionStance.Standing, Location, Guid);
                        turnToMotion.MovementTypes = MovementTypes.TurnToObject;

                        ActionChain turnToTimer = new ActionChain();
                        turnToTimer.AddAction(this, () => player.CurrentLandblock?.EnqueueBroadcastMotion(player, turnToMotion));
                        turnToTimer.AddDelaySeconds(1);
                        turnToTimer.AddAction(this, () => Open(player));
                        turnToTimer.EnqueueChain();

                        return;
                    }

                    if (Viewer == player.Guid.Full)
                    {
                        Close(player);
                    }

                    // else error msg?
                }
                else
                {
                    player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, $"The {Name} is locked!"));
                    CurrentLandblock?.EnqueueBroadcastSound(this, Sound.OpenFailDueToLock);
                }

                player.SendUseDoneEvent();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Used for unlocking a door via a key
        /// </summary>
        public UnlockDoorResults UnlockDoor(string keyCode)
        {
            if (IsOpen ?? false)
            {
                return(UnlockDoorResults.DoorOpen);
            }

            if (keyCode == LockCode)
            {
                if (!IsLocked ?? false)
                {
                    return(UnlockDoorResults.AlreadyUnlocked);
                }

                IsLocked = false;
                CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessagePublicUpdatePropertyBool(Sequences, Guid, PropertyBool.Locked, IsLocked ?? false));
                CurrentLandblock.EnqueueBroadcastSound(this, Sound.LockSuccess);
                return(UnlockDoorResults.UnlockSuccess);
            }

            return(UnlockDoorResults.IncorrectKey);
        }
Beispiel #7
0
        /// <summary>
        /// Used for unlocking a door via lockpick, so contains a skill check
        /// player.Skills[Skill.Lockpick].ActiveValue should be sent for the skill check
        /// </summary>
        public UnlockDoorResults UnlockDoor(uint playerLockpickSkillLvl)
        {
            if (ResistLockpick == 0)
            {
                return(UnlockDoorResults.CannotBePicked);
            }

            if (playerLockpickSkillLvl >= ResistLockpick)
            {
                if (!IsLocked ?? false)
                {
                    return(UnlockDoorResults.AlreadyUnlocked);
                }

                IsLocked = false;
                CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessagePublicUpdatePropertyBool(Sequences, Guid, PropertyBool.Locked, IsLocked ?? false));
                CurrentLandblock.EnqueueBroadcastSound(this, Sound.LockSuccess);
                return(UnlockDoorResults.UnlockSuccess);
            }

            return(UnlockDoorResults.PickLockFailed);
        }
Beispiel #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;
        }