Example #1
0
        private static bool CheckBeforeExecuteJumps()
        {
            if (!DragoonSettings.Instance.UseJumps)
            {
                return(false);
            }

            if (DragoonSettings.Instance.SafeJumpLogic)
            {
                if (!Core.Me.CurrentTarget.InView())
                {
                    return(false);
                }
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (DragoonRoutine.JumpsList.Contains(Casting.LastSpell))
            {
                return(false);
            }

            return(true);
        }
        public Composite CreateBasicCombat()
        {
            return(new PrioritySelector(ctx => Core.Player.CurrentTarget as BattleCharacter,
                                        new Decorator(ctx => ctx != null,
                                                      new PrioritySelector(
                                                          new Decorator(ctx => !RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement), new PrioritySelector(
                                                                            CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                                                                            CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => Core.Player.CombatReach + PullRange, true, "Moving to unit")
                                                                            )),
                                                          //CombatBuffs
                                                          Spell.Cast("Toad Oil", r => !Core.Me.HasAura("Toad Oil")),

                                                          //Interrupt
                                                          Spell.Cast("Flying Sardine", r => shouldFishSlap),

                                                          //Basic Combat
                                                          Spell.Cast("Triple Trident", r => Core.Me.HasAura("Tingling") && Core.Me.HasAura("Harmonized")),
                                                          Spell.Cast("Whistle", r => ActionManager.LastSpell.Name == "Tingle"),
                                                          Spell.Cast("Tingle", r => DataManager.GetSpellData(23264).Cooldown.TotalMilliseconds == 0 && Core.Me.CurrentTarget.CurrentHealthPercent > 30 && Core.Target.Distance2D(Core.Me) <= 6f),
                                                          Spell.Cast("Lucid Dreaming", r => ActionManager.HasSpell("Lucid Dreaming") && Core.Player.CurrentManaPercent < 50),
                                                          Spell.Cast("Blood Drain", r => Core.Player.CurrentManaPercent < 20),
                                                          Spell.Cast("Off-guard", r => Core.Me.CurrentTarget.CurrentHealthPercent < 50),
                                                          Spell.Cast("Bad Breath", r => ActionManager.LastSpell.Name != "Bad Breath" && Core.Me.IsFacing(Core.Target) && Core.Target.Distance2D(Core.Me) <= 8f && !Core.Target.HasAura("Poison") && Core.Me.CurrentTarget.CurrentHealthPercent > 40),
                                                          Spell.Cast("Plaincracker", r => GameObjectManager.NumberOfAttackers >= 2 && Core.Target.Distance2D(Core.Me) <= 4f),
                                                          Spell.Cast("Whistle", r => !Core.Me.HasAura("Boost") && !Core.Me.HasAura("Harmonized") && !Core.Target.HasAura("Off-guard") && ActionManager.HasSpell("Abyssal Transfixion")),
                                                          Spell.Cast("Abyssal Transfixion", r => true),
                                                          Spell.Cast("1000 Needles", r => Core.Me.CurrentTarget.CurrentHealthPercent > 75 && ActionManager.LastSpell.Name != "1000 Needles"),
                                                          Spell.Cast("Water Cannon", r => true)
                                                          ))));
        }
Example #3
0
        public static async Task <bool> Displacement()
        {
            if (!RedMageSettings.Instance.Displacement)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (!RedMageSettings.Instance.UseMelee)
            {
                return(false);
            }

            if (BlackMana > 24 && WhiteMana > 24)
            {
                return(false);
            }

            var inMeleeCombo = Casting.SpellCastHistory.Take(5).Any(s => s.Spell == Spells.Riposte ||
                                                                    s.Spell == Spells.Zwerchhau ||
                                                                    s.Spell == Spells.Redoublement);

            if (!inMeleeCombo)
            {
                return(false);
            }

            return(await Spells.Displacement.Cast(Core.Me.CurrentTarget));
        }
Example #4
0
        public static async Task <bool> CorpsACorps()
        {
            if (!RedMageSettings.Instance.CorpsACorps)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (!RedMageSettings.Instance.UseMelee)
            {
                return(false);
            }

            if (BlackMana < 80 || WhiteMana < 80)
            {
                return(false);
            }

            else
            {
                return(await Spells.CorpsACorps.Cast(Core.Me.CurrentTarget));
            }
        }
 public Composite CreateBasicPull()
 {
     return(new PrioritySelector(ctx => Core.Player.CurrentTarget as BattleCharacter,
                                 new Decorator(ctx => ctx != null, new PrioritySelector(
                                                   new Decorator(ctx => !RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement), new PrioritySelector(
                                                                     CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                                                                     CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => Core.Player.CombatReach + PullRange + (ctx as GameObject).CombatReach, true, "Moving to unit")
                                                                     )),
                                                   Spell.PullCast(r => "Sticky Tongue", r => ActionManager.LastSpell.Name != "Sticky Tongue" && Core.Target.Distance2D(Core.Me) >= 5f),
                                                   Spell.PullCast(r => "Water Cannon", r => ActionManager.LastSpell.Name != "Water Cannon" && !ActionManager.HasSpell("Sticky Tongue"))
                                                   ))));
 }
Example #6
0
        public static async Task <bool> Jump()
        {
            if (!DragoonSettings.Instance.Jump)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            return(await Spells.Jump.Cast(Core.Me.CurrentTarget));
        }
Example #7
0
        private async Task CastPomanderAbility(SpellData spell)
        {
            if (!RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement | CapabilityFlags.Facing))
            {
                if (!ActionManager.CanCast(spell, Poi.Current.BattleCharacter) || Poi.Current.BattleCharacter.Distance2D() > (float)spell.Range + Poi.Current.BattleCharacter.CombatReach)
                {
                    await CommonTasks.MoveAndStop(new MoveToParameters(Core.Target.Location, $"Moving to {Poi.Current.Name} to cast {spell.Name}"),
                                                  (float)spell.Range + Poi.Current.BattleCharacter.CombatReach, true);
                }

                Poi.Current.BattleCharacter.Face2D();
            }

            ActionManager.DoAction(spell, Poi.Current.BattleCharacter);
            await Coroutine.Yield();
        }
Example #8
0
        public static async Task <bool> MirageDive()
        {
            if (!DragoonSettings.Instance.MirageDive)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (!Core.Me.HasAura(Auras.DiveReady))
            {
                return(false);
            }

            // Neko: 2 things that can help. Don't mirage dive unless in Blood of the Dragon, also, don't mirage dive if at 2 eyes.

            if (ActionResourceManager.Dragoon.DragonGaze == 2)
            {
                return(false);
            }

            if (Spells.VorpalThrust.Cooldown.TotalMilliseconds < 750)
            {
                return(false);
            }

            if (await Spells.MirageDive.Cast(Core.Me.CurrentTarget))
            {
                Utilities.Routines.Dragoon.MirageDives++;

                if (DragoonSettings.Instance.Geirskogul)
                {
                    if (Spells.Geirskogul.Cooldown.TotalMilliseconds < 1000)
                    {
                        await Coroutine.Wait(3000, () => ActionManager.CanCast(Spells.Geirskogul.Id, Core.Me.CurrentTarget));

                        return(await Spells.Geirskogul.Cast(Core.Me.CurrentTarget));
                    }
                }
            }

            return(false);
        }
Example #9
0
        public static async Task <bool> Execute()
        {
            if (!DragoonSettings.Instance.UseJumps)
            {
                return(false);
            }

            if (DragoonSettings.Instance.SafeJumpLogic)
            {
                if (!Core.Me.CurrentTarget.InView())
                {
                    return(false);
                }
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (Utilities.Routines.Dragoon.Jumps.Contains(Casting.LastSpell))
            {
                return(false);
            }

            if (Core.Me.ClassLevel >= 54 && Combat.CombatTime.Elapsed.Seconds < 20 && ActionResourceManager.Dragoon.Timer.Seconds == 0)
            {
                return(false);
            }

            if (await Jump())
            {
                return(true);
            }
            if (await Stardiver())
            {
                return(true);
            }
            if (await SpineshatterDive())
            {
                return(true);
            }
            return(await DragonfireDive());
        }
Example #10
0
        public static async Task <bool> DragonfireDive()
        {
            if (!DragoonSettings.Instance.DragonfireDive)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (Spells.VorpalThrust.Cooldown.TotalMilliseconds < 1250)
            {
                return(false);
            }

            return(await Spells.DragonfireDive.Cast(Core.Me.CurrentTarget));
        }
Example #11
0
        /***************************************************************************
        *                                Single Target
        * *************************************************************************/
        public static async Task <bool> HighJump()
        {
            if (!DragoonSettings.Instance.UseHighJump)
            {
                return(false);
            }


            if (!CheckBeforeExecuteJumps())
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            return(await DragoonRoutine.HighJump.Cast(Core.Me.CurrentTarget));
        }
Example #12
0
        public static async Task <bool> ShoulderTackle()
        {
            // Off GCD

            if (!MonkSettings.Instance.UseShoulderTackle)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (Core.Me.CurrentTarget.Distance(Core.Me) < 10)
            {
                return(false);
            }

            return(await Spells.ShoulderTackle.Cast(Core.Me.CurrentTarget));
        }
Example #13
0
        public static async Task <bool> RepellingShot()
        {
            if (!BardSettings.Instance.RepellingShot)
            {
                return(false);
            }

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return(false);
            }

            if (BardSettings.Instance.RepellingShotOnlyWhenTargeted)
            {
                var repellingShotTarget = Combat.Enemies.FirstOrDefault(r => r.Distance(Core.Me) <= 5 + r.CombatReach &&
                                                                        r.InView() &&
                                                                        ActionManager.CanCast(Spells.RepellingShot.Id, r));

                if (repellingShotTarget == null)
                {
                    return(false);
                }

                return(await Spells.RepellingShot.Cast(repellingShotTarget));
            }
            else
            {
                if (Core.Me.CurrentTarget == null)
                {
                    return(false);
                }

                if (Core.Me.CurrentTarget.Distance(Core.Me) > 5 + Core.Me.CurrentTarget.CombatReach)
                {
                    return(false);
                }

                return(await Spells.RepellingShot.Cast(Core.Me.CurrentTarget));
            }
        }
Example #14
0
        public static void NavigateToUnitLos(GameObject unit, float distance)
        {
            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement))
            {
                return;
            }

            if (unit == null)
            {
                return;
            }

            if (!MovementManager.IsMoving && !unit.InView())
            {
                Core.Me.Face(Core.Me.CurrentTarget);
            }

            if (AvoidanceManager.Avoids.Any(r => r.IsPointInAvoid(unit.Location)))
            {
                return;
            }

            if (unit.Distance(Core.Me) > distance)
            {
                Navigator.MoveTo(new MoveToParameters(unit.Location));
            }

            if (Core.Me.Distance(Core.Me.CurrentTarget.Location) <= distance && unit.InView() && unit.InLineOfSight())
            {
                if (MovementManager.IsMoving)
                {
                    Navigator.PlayerMover.MoveStop();
                }
            }
            else
            {
                Navigator.MoveTo(new MoveToParameters(unit.Location));
            }
        }
Example #15
0
        public async Task <bool> Cast(GameObject target = null, bool checkGCDType = true)
        {
            #region Target

            if (target == null)
            {
                switch (CastType)
                {
                case CastType.Target:
                case CastType.TargetLocation:
                    if (!Core.Player.HasTarget)
                    {
                        return(false);
                    }
                    target = Core.Player.CurrentTarget;
                    break;

                default:
                    target = Core.Player;
                    break;
                }
            }

            #endregion

            #region RecentSpell

            RecentSpell.RemoveAll(t => DateTime.UtcNow > t);
            if (RecentSpell.ContainsKey(target.ObjectId.ToString("X") + "-" + Name))
            {
                return(false);
            }

            #endregion

            #region CapabilityManager

            if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Movement | CapabilityFlags.Facing))
            {
                return(false);
            }

            #endregion

            #region Cooldown

            if (ShinraEx.Settings.CooldownMode == CooldownModes.Disabled)
            {
                if ((SpellType == SpellType.Buff || SpellType == SpellType.Cooldown) && Cooldown(true) > 2500)
                {
                    return(false);
                }
            }

            #endregion

            #region AoE

            if (SpellType == SpellType.AoE && ShinraEx.Settings.RotationMode != Modes.Multi)
            {
                if (RoutineManager.IsAnyDisallowed(CapabilityFlags.Aoe))
                {
                    return(false);
                }

                var enemyCount =
                    Helpers.Enemies.Count(eu => eu.Distance2D(target) - eu.CombatReach - target.CombatReach <=
                                          DataManager.GetSpellData(ID).Radius);

                if (ShinraEx.Settings.CustomAoE)
                {
                    if (enemyCount < ShinraEx.Settings.CustomAoECount)
                    {
                        return(false);
                    }
                }
                else
                {
                    switch (Core.Player.CurrentJob)
                    {
                    case ClassJobType.Arcanist:
                    case ClassJobType.Summoner:
                        if (enemyCount < 2)
                        {
                            return(false);
                        }
                        break;

                    default:
                        if (enemyCount < 3)
                        {
                            return(false);
                        }
                        break;
                    }
                }
            }

            #endregion

            #region Directional

            switch (ID)
            {
            // Cone
            case 41:
            case 70:
            case 106:
            case 7483:
            case 7488:
            {
                if (!Helpers.InView(Core.Player.Location, Core.Player.Heading, target.Location))
                {
                    return(false);
                }
                break;
            }

            // Line
            case 86:
            case 7496:
            {
                if (!Core.Player.IsFacing(target))
                {
                    return(false);
                }
                break;
            }
            }

            #endregion

            #region Pet

            switch (SpellType)
            {
            case SpellType.Pet when Core.Player.Pet == null:
            case SpellType.Pet when PetManager.PetMode != PetMode.Obey:
            case SpellType.Pet when Core.Player.IsMounted:
            case SpellType.Pet when !PetManager.CanCast(Name, target):
            case SpellType.Pet when !await Coroutine.Wait(5000, () => PetManager.DoAction(Name, target)):
                return(false);

            case SpellType.Pet:
            {
                ShinraEx.LastSpell = this;

                #region AddRecent

                var key = target.ObjectId.ToString("X") + "-" + Name;
                var val = DateTime.UtcNow + TimeSpan.FromSeconds(3);
                RecentSpell.Add(key, val);

                #endregion

                Logging.Write(Colors.GreenYellow, $@"[ShinraEx] Casting >>> {Name}");
                return(true);
            }

            case SpellType.Card when Core.Player.IsMounted:
            case SpellType.Card when !ActionManager.CanCast(ID, target) || RecentSpell.ContainsKey("Card"):
            case SpellType.Card when !await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target)):
                return(false);

            case SpellType.Card:
            {
                ShinraEx.LastSpell = this;

                #region AddRecent

                var val = DateTime.UtcNow + TimeSpan.FromSeconds(.5);

                if (ID == 3593)
                {
                    val += TimeSpan.FromSeconds(2);
                }
                RecentSpell.Add("Card", val);

                #endregion

                Logging.Write(Colors.GreenYellow, $@"[ShinraEx] Casting >>> {Name}");
                return(true);
            }
            }

            #endregion

            #region Card

            if (ShinraEx.Settings.AstrologianCardOnly && Core.Player.CurrentJob == ClassJobType.Astrologian)
            {
                return(false);
            }

            #endregion

            #region Ninjutsu

            if (SpellType == SpellType.Ninjutsu || SpellType == SpellType.Mudra)
            {
                #region Movement

                if (BotManager.Current.IsAutonomous)
                {
                    switch (ActionManager.InSpellInRangeLOS(2247, target))
                    {
                    case SpellRangeCheck.ErrorNotInLineOfSight:
                        await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                        return(false);

                    case SpellRangeCheck.ErrorNotInRange:
                        await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                        return(false);

                    case SpellRangeCheck.ErrorNotInFront:
                        if (!target.InLineOfSight())
                        {
                            await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                            return(false);
                        }

                        target.Face();
                        return(false);

                    case SpellRangeCheck.Success:
                        if (MovementManager.IsMoving)
                        {
                            Navigator.PlayerMover.MoveStop();
                        }
                        break;
                    }
                }

                #endregion

                #region IsMounted

                if (Core.Player.IsMounted)
                {
                    return(false);
                }

                #endregion

                #region CanCast

                if (ShinraEx.Settings.QueueSpells &&
                    !ActionManager.CanCastOrQueue(DataManager.GetSpellData(ID), target) ||
                    !ActionManager.CanCast(ID, target))
                {
                    return(false);
                }

                #endregion

                #region DoAction

                if (!await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target)))
                {
                    return(false);
                }

                #endregion

                #region Wait

                await Coroutine.Wait(2000, () => !ActionManager.CanCast(ID, target));

                #endregion

                ShinraEx.LastSpell = this;

                #region AddRecent

                if (SpellType == SpellType.Mudra)
                {
                    var key = target.ObjectId.ToString("X") + "-" + Name;
                    var val = DateTime.UtcNow + TimeSpan.FromSeconds(1);
                    RecentSpell.Add(key, val);
                }

                #endregion

                Logging.Write(Colors.GreenYellow, $@"[ShinraEx] Casting >>> {Name}");
                return(true);
            }

            #endregion

            #region CanAttack

            var bc = target as BattleCharacter;

            if (!target.CanAttack && CastType != CastType.Self && CastType != CastType.SelfLocation &&
                (bc == null || !bc.IsFate))
            {
                switch (SpellType)
                {
                case SpellType.Damage:
                case SpellType.DoT:
                case SpellType.Cooldown:
                    return(false);
                }
            }

            #endregion

            #region HasSpell

            if (!ActionManager.HasSpell(ID))
            {
                return(false);
            }

            #endregion

            #region Movement

            if (BotManager.Current.IsAutonomous)
            {
                switch (ActionManager.InSpellInRangeLOS(ID, target))
                {
                case SpellRangeCheck.ErrorNotInLineOfSight:
                    await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                    Helpers.Debug($"LineOfSight >>> {Name}");
                    return(false);

                case SpellRangeCheck.ErrorNotInRange:
                    await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                    Helpers.Debug($"Range >>> {Name}");
                    return(false);

                case SpellRangeCheck.ErrorNotInFront:
                    if (!target.InLineOfSight())
                    {
                        await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                        Helpers.Debug($"Facing >>> {Name}");
                        return(false);
                    }

                    target.Face();
                    return(false);

                case SpellRangeCheck.Success:
                    if (CastType == CastType.TargetLocation && Core.Player.Distance2D(target) +
                        Core.Player.CombatReach +
                        target.CombatReach > 25)
                    {
                        await CommonTasks.MoveAndStop(new MoveToParameters(target.Location), 0f);

                        await Coroutine.Wait(1000,
                                             () => Core.Player.Distance2D(target) + Core.Player.CombatReach + target.CombatReach <=
                                             25);

                        return(false);
                    }

                    Navigator.PlayerMover.MoveStop();
                    break;
                }

                if (Core.Player.HasTarget && !MovementManager.IsMoving && Core.Player.IsMounted)
                {
                    Logging.Write(Colors.Yellow, @"[ShinraEx] Dismounting...");
                    ActionManager.Dismount();
                    await Coroutine.Sleep(1000);
                }
            }

            #endregion

            #region IsMounted

            if (Core.Player.IsMounted)
            {
                return(false);
            }

            #endregion

            #region StopCasting

            if (SpellType == SpellType.Heal)
            {
                if (Core.Player.IsCasting && !Helpers.HealingSpells.Contains(Core.Player.SpellCastInfo.Name))
                {
                    var stopCasting = false;
                    switch (Core.Player.CurrentJob)
                    {
                    case ClassJobType.Astrologian:
                        stopCasting = ShinraEx.Settings.AstrologianInterruptDamage;
                        break;

                    case ClassJobType.Scholar:
                        stopCasting = ShinraEx.Settings.ScholarInterruptDamage;
                        break;

                    case ClassJobType.WhiteMage:
                        stopCasting = ShinraEx.Settings.WhiteMageInterruptDamage;
                        break;
                    }

                    if (stopCasting)
                    {
                        Helpers.Debug($@"Trying to cast {Name}");
                        Logging.Write(Colors.Yellow, $@"[ShinraEx] Interrupting >>> {Core.Player.SpellCastInfo.Name}");
                        ActionManager.StopCasting();
                        await Coroutine.Wait(500, () => !Core.Player.IsCasting);
                    }
                }
            }

            #endregion

            #region CanCast

            switch (CastType)
            {
            case CastType.TargetLocation:
            case CastType.SelfLocation:
                if (!ActionManager.CanCastLocation(ID, target.Location) || Core.Player.IsCasting)
                {
                    return(false);
                }
                break;

            default:
                if (ShinraEx.Settings.QueueSpells && GCDType == GCDType.On)
                {
                    if (!ActionManager.CanCastOrQueue(DataManager.GetSpellData(ID), target))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!ActionManager.CanCast(ID, target))
                    {
                        return(false);
                    }
                }

                break;
            }

            if (MovementManager.IsMoving && DataManager.GetSpellData(ID).AdjustedCastTime.TotalMilliseconds > 0)
            {
                if (!BotManager.Current.IsAutonomous)
                {
                    return(false);
                }
                Navigator.PlayerMover.MoveStop();
            }

            #endregion

            #region InView

            if (GameSettingsManager.FaceTargetOnAction == false && CastType == CastType.Target &&
                SpellType != SpellType.Heal &&
                SpellType != SpellType.Buff &&
                !Helpers.InView(Core.Player.Location, Core.Player.Heading, target.Location))
            {
                return(false);
            }

            #endregion

            #region GCD

            if (GCDType == GCDType.Off && checkGCDType)
            {
                switch (Core.Player.CurrentJob)
                {
                case ClassJobType.Arcanist:
                case ClassJobType.Scholar:
                case ClassJobType.Summoner:
                    if (DataManager.GetSpellData(163).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Archer:
                case ClassJobType.Bard:
                    if (DataManager.GetSpellData(97).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Astrologian:
                    if (DataManager.GetSpellData(3594).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Conjurer:
                case ClassJobType.WhiteMage:
                    if (DataManager.GetSpellData(119).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.DarkKnight:
                    if (DataManager.GetSpellData(3617).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Gladiator:
                case ClassJobType.Paladin:
                    if (DataManager.GetSpellData(9).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Lancer:
                case ClassJobType.Dragoon:
                    if (ID == 8801 || ID == 8802)
                    {
                        if (DataManager.GetSpellData(75).Cooldown.TotalMilliseconds < 1500)
                        {
                            return(false);
                        }
                        else if (DataManager.GetSpellData(75).Cooldown.TotalMilliseconds < 1000)
                        {
                            return(false);
                        }
                    }

                    break;

                case ClassJobType.Machinist:
                    if (DataManager.GetSpellData(2866).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Marauder:
                case ClassJobType.Warrior:
                    if (DataManager.GetSpellData(31).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Pugilist:
                case ClassJobType.Monk:
                    if (DataManager.GetSpellData(53).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.RedMage:
                    if (DataManager.GetSpellData(7504).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Rogue:
                case ClassJobType.Ninja:
                    if (DataManager.GetSpellData(2240).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Samurai:
                    if (DataManager.GetSpellData(7477).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;

                case ClassJobType.Thaumaturge:
                case ClassJobType.BlackMage:
                    if (DataManager.GetSpellData(142).Cooldown.TotalMilliseconds < 1000)
                    {
                        return(false);
                    }
                    break;
                }
            }

            #endregion

            #region DoAction

            switch (CastType)
            {
            case CastType.TargetLocation:
                if (ShinraEx.Settings.RandomCastLocations)
                {
                    var randX       = target.CombatReach * _rand.NextDouble() * GetMultiplier();
                    var randZ       = target.CombatReach * _rand.NextDouble() * GetMultiplier();
                    var randXYZ     = new Vector3((float)randX, 0f, (float)randZ);
                    var newLocation = target.Location + randXYZ;

                    if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, newLocation)))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, target.Location)))
                    {
                        return(false);
                    }
                }

                break;

            case CastType.SelfLocation:
                if (ShinraEx.Settings.RandomCastLocations)
                {
                    var randX       = (1f * _rand.NextDouble() + 1f) * GetMultiplier();
                    var randZ       = (1f * _rand.NextDouble() + 1f) * GetMultiplier();
                    var randXYZ     = new Vector3((float)randX, 0f, (float)randZ);
                    var newLocation = target.Location + randXYZ;

                    if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, newLocation)))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, target.Location)))
                    {
                        return(false);
                    }
                }

                break;

            default:
                if (SpellType == SpellType.PVP)
                {
                    if (!await Coroutine.Wait(1000, () => ActionManager.DoPvPCombo(Combo, target)))
                    {
                        return(false);
                    }
                    Logging.Write(Colors.Orange, $@"DoAction Combo {Combo} 0x{target.ObjectId:X}");
                }
                else
                {
                    if (!await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target)))
                    {
                        return(false);
                    }
                }

                break;
            }

            #endregion

            #region Wait

            switch (CastType)
            {
            case CastType.SelfLocation:
            case CastType.TargetLocation:
                await Coroutine.Wait(3000, () => !ActionManager.CanCastLocation(ID, target.Location));

                break;

            default:
                await Coroutine.Wait(3000, () => !ActionManager.CanCast(ID, target));

                break;
            }

            #endregion

            ShinraEx.LastSpell = this;
            Logging.Write(Colors.GreenYellow,
                          $@"[ShinraEx] Casting >>> {Name}{(SpellType == SpellType.PVP ? " Combo" : "")}");

            #region AddRecent

            if (SpellType != SpellType.Damage && SpellType != SpellType.AoE && SpellType != SpellType.Heal &&
                SpellType != SpellType.PVP &&
                await CastComplete(this))
            {
                var key = target.ObjectId.ToString("X") + "-" + Name;
                var val = DateTime.UtcNow + DataManager.GetSpellData(ID).AdjustedCastTime + TimeSpan.FromSeconds(3);
                RecentSpell.Add(key, val);
            }

            if (SpellType == SpellType.Damage || SpellType == SpellType.DoT)
            {
                if (!Helpers.OpenerFinished && !RecentSpell.ContainsKey("Opener") && await CastComplete(this, true))
                {
                    var val = DateTime.UtcNow + DataManager.GetSpellData(ID).AdjustedCastTime + TimeSpan.FromSeconds(3);
                    RecentSpell.Add("Opener", val);
                }
            }

            #endregion

            return(true);
        }
        public static async Task <bool> CastAura(this SpellData spell, GameObject target, uint aura, bool useRefreshTime = false, int refreshTime = 0, bool needAura = true, [CallerMemberName] string caller = null, [CallerLineNumber] int sourceLineNumber = 0, [CallerFilePath] string sourceFilePath = null)
        {
            if (BaseSettings.Instance.DebugCastingCallerMemberName)
            {
                Logger.WriteInfo($@"[CastAura] [{sourceLineNumber}] {caller}");

                if (BaseSettings.Instance.DebugCastingCallerMemberNameIncludePath)
                {
                    Logger.WriteInfo($@"[Path] {sourceFilePath}");
                }
            }

            if (!GameSettingsManager.FaceTargetOnAction && BaseSettings.Instance.AssumeFaceTargetOnAction)
            {
                GameSettingsManager.FaceTargetOnAction = true;
            }

            if (BotManager.Current.IsAutonomous && !GameSettingsManager.FaceTargetOnAction && !RoutineManager.IsAnyDisallowed(CapabilityFlags.Facing) && !MovementManager.IsMoving)
            {
                Core.Me.Face(target);
            }

            return(await DoAction(spell, target, aura, needAura, useRefreshTime, refreshTime));
        }