public static void PetCast(this PetSpellData spell, GameObject tar, [CallerMemberName] string name = "") { if (Core.Me.Pet == null) { return; } if (tar == null) { return; } if (Core.Me.Pet.IsCasting) { return; } if (spell.Cooldown != TimeSpan.Zero) { return; } if (!PetManager.CanCast(spell, tar)) { return; } PetManager.DoAction(spell.LocalizedName, tar); }
public override async Task <bool> Execute(ObservableCollection <IGambitCondition> conditions) { if (Core.Me.Pet == null) { return(false); } GameObject target = null; if (OnPet) { target = Core.Me.Pet; } if (OnTarget) { target = Core.Me.CurrentTarget; } if (OnPlayer) { target = Core.Me; } if (target == null) { return(false); } if (conditions.Any(condition => !condition.Check(target))) { return(false); } if (!PetManager.CanCast(SpellName, target)) { return(false); } if (PetManager.DoAction(SpellName, target)) { return(false); } return(await Task.FromResult(false)); }
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); }
private static async Task <bool> PetActions() { if (Target == null || !Target.CanAttack || Me.Pet == null || !EikoSettingsModel.Instance.UseBuffs || !Target.HealthCheck(false) || !Target.TimeToDeathCheck() || !PetManager.LockTimer.IsFinished) { return(false); } if (PetManager.LockTimer.WaitTime.Seconds != 2) { PetManager.LockTimer = new WaitTimer(new TimeSpan(0, 0, 0, 2)); } if (Me.Pet.CurrentTargetId != Me.CurrentTargetObjId || Me.Pet.TargetCharacter == null || PetManager.PetMode != PetMode.Obey) { PetManager.DoAction(Spells.Obey.LocalizedName, Target); } if (PetManager.PetStance != PetStance.Guard) { PetManager.DoAction(Spells.Guard.LocalizedName, Me); } if (!DreadwormTrance) { if (await Aetherpact()) { return(true); } if (await Rouse()) { return(true); } if (await Enkindle()) { return(true); } } switch (EikoSettingsModel.Instance.SelectedEikoSummon) { case EikoSummonMode.Garuda: if (EikoSettingsModel.Instance.UseContagion && Me.ClassLevel >= 40 && PetManager.CanCast(Spells.Contagion.LocalizedName, Target) && DreadwormTrance && Target.HasAura(BioAura(), true, 5000) && Target.HasAura(MiasmaAura(), true, 5000) && Spells.TriDisaster.Cooldown.TotalSeconds > 5 || Me.ClassLevel < 56) { return(PetManager.DoAction(Spells.Contagion.LocalizedName, Target)); } if (PetManager.CanCast(Spells.AerialSlash.LocalizedName, Target) && !DreadwormTrance) { return(PetManager.DoAction(Spells.AerialSlash.LocalizedName, Target)); } break; case EikoSummonMode.Titan: if (PetManager.CanCast(Spells.MountainBuster.LocalizedName, Me.Pet)) { return(PetManager.DoAction(Spells.MountainBuster.LocalizedName, Me.Pet)); } if (PetManager.CanCast(Spells.EarthenWard.LocalizedName, Me.Pet)) { return(PetManager.DoAction(Spells.EarthenWard.LocalizedName, Me.Pet)); } if (PetManager.CanCast(Spells.Landslide.LocalizedName, Target) && (Target.CanStun() || ((Character)Target).IsCasting)) { return(PetManager.DoAction(Spells.Landslide.LocalizedName, Target)); } break; case EikoSummonMode.Ifrit: if (PetManager.CanCast(Spells.CrimsonCyclone.LocalizedName, Target) && (Target.CanStun() || ((Character)Target).IsCasting)) { return(PetManager.DoAction(Spells.CrimsonCyclone.LocalizedName, Target)); } if (PetManager.CanCast(Spells.RadiantShield.LocalizedName, Me.Pet)) { return(PetManager.DoAction(Spells.RadiantShield.LocalizedName, Me.Pet)); } if (PetManager.CanCast(Spells.FlamingCrush.LocalizedName, Me.Pet)) { return(PetManager.DoAction(Spells.FlamingCrush.LocalizedName, Me.Pet)); } break; } return(false); }
private static async Task <bool> PetAction() { if (Me.HasAura(Auras.Dissipation) || Me.Pet == null || HealManager.Any(hm => hm.HasAura(Auras.FeyUnion)) || CombatHelper.GcdTimeRemaining < 10) { return(false); } var target = HealManager.FirstOrDefault(hm => hm.InCombat); switch (SuritoSettingsModel.Instance.SelectedSuritoSummon) { case SuritoSummonMode.Eos: if (SuritoSettingsModel.Instance.UseWhisperingDawn && PetManager.CanCast(Spells.WhisperingDawn.LocalizedName, Me.Pet) && HealManager.Count(hm => hm.Distance2D(Me.Pet) <= 15 && hm.CurrentHealthPercent <= SuritoSettingsModel.Instance.WhisperingDawnHpPct) >= SuritoSettingsModel.Instance.PetAoEPlayerCount) { return(PetManager.DoAction(Spells.WhisperingDawn.LocalizedName, Me.Pet)); } if (SuritoSettingsModel.Instance.UseFeyCovenant && PetManager.CanCast(Spells.FeyCovenant.LocalizedName, Me.Pet) && HealManager.Count(hm => hm.Distance2D(Me.Pet) <= 15 && hm.CurrentHealthPercent <= SuritoSettingsModel.Instance.FeyCovenantHpPct) >= SuritoSettingsModel.Instance.PetAoEPlayerCount) { return(PetManager.DoAction(Spells.FeyCovenant.LocalizedName, Me.Pet)); } if (SuritoSettingsModel.Instance.UseFeyIllumination && PetManager.CanCast(Spells.FeyIllumination.LocalizedName, Me.Pet) && HealManager.Count(hm => hm.Distance2D(Me.Pet) <= 15 && hm.CurrentHealthPercent <= SuritoSettingsModel.Instance.FeyIlluninationHpPct) >= SuritoSettingsModel.Instance.PetAoEPlayerCount) { return(PetManager.DoAction(Spells.FeyIllumination.LocalizedName, Me.Pet)); } if (SuritoSettingsModel.Instance.UseEmbrace) { target = HealManager.FirstOrDefault(hm => hm.CurrentHealthPercent <= SuritoSettingsModel.Instance.EmbraceHpPct); if (target != null && PetManager.CanCast(Spells.Embrace.LocalizedName, target)) { return(PetManager.DoAction(Spells.Embrace.LocalizedName, target)); } } break; case SuritoSummonMode.Selene: if (SuritoSettingsModel.Instance.UseEmbrace) { target = HealManager.FirstOrDefault(hm => hm.CurrentHealthPercent <= SuritoSettingsModel.Instance.EmbraceHpPct); if (target != null && PetManager.CanCast(Spells.Embrace.LocalizedName, target)) { return(PetManager.DoAction(Spells.Embrace.LocalizedName, target)); } } if (SuritoSettingsModel.Instance.UseSilentDusk) { target = HealManager.FirstOrDefault(hm => hm.CanSilence()); if (target != null && PetManager.CanCast(Spells.SilentDusk.LocalizedName, target)) { return(PetManager.DoAction(Spells.SilentDusk.LocalizedName, target)); } } if (SuritoSettingsModel.Instance.UseFeyCaress && PetManager.CanCast(Spells.FeyCaress.LocalizedName, Me.Pet) && HealManager.Count(hm => hm.Distance2D(Me.Pet) <= 20) >= SuritoSettingsModel.Instance.PetAoEPlayerCount) { return(await CleanseManager.PetCleanse()); } if (SuritoSettingsModel.Instance.UseFeyWind && PetManager.CanCast(Spells.FeyWind.LocalizedName, Me.Pet) && HealManager.Count(hm => hm.IsDps() && hm.Distance2D(Me.Pet) <= 20) >= SuritoSettingsModel.Instance.PetAoEPlayerCount) { return(PetManager.DoAction(Spells.FeyWind.LocalizedName, Me.Pet)); } break; } return(false); }
public async Task <bool> Cast(GameObject target = null) { #region Target if (target == null) { switch (CastType) { case CastType.TargetLocation: if (!Core.Player.HasTarget) { return(false); } target = Core.Player.CurrentTarget; break; case CastType.Target: if (!Core.Player.HasTarget) { return(false); } target = Core.Player.CurrentTarget; break; default: target = Core.Player; break; } } #endregion #region Recent Spell Check RecentSpell.RemoveAll(t => DateTime.UtcNow > t); if (RecentSpell.ContainsKey(target.ObjectId.ToString("X") + "-" + Name)) { return(false); } #endregion #region Bard Song Check if (Core.Player.CurrentJob == ClassJobType.Bard && SpellType == SpellType.Buff) { if (Core.Player.HasAura(135, true) || Core.Player.HasAura(137, true)) { return(false); } } #endregion #region AoE Check if (SpellType == SpellType.AoE && Ultima.UltSettings.SmartTarget) { var EnemyCount = Helpers.EnemyUnit.Count(eu => eu.Distance2D(target) - eu.CombatReach - target.CombatReach <= DataManager.GetSpellData(ID).Radius); switch (Core.Player.CurrentJob) { case ClassJobType.Arcanist: case ClassJobType.Scholar: case ClassJobType.Summoner: if (EnemyCount < 2) { return(false); } break; case ClassJobType.Archer: case ClassJobType.Bard: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Astrologian: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Conjurer: case ClassJobType.WhiteMage: if (EnemyCount < 3) { return(false); } break; case ClassJobType.DarkKnight: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Gladiator: case ClassJobType.Paladin: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Lancer: case ClassJobType.Dragoon: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Machinist: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Marauder: case ClassJobType.Warrior: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Pugilist: case ClassJobType.Monk: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Rogue: case ClassJobType.Ninja: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Thaumaturge: case ClassJobType.BlackMage: if (EnemyCount < 3) { return(false); } break; case ClassJobType.Samurai: if (EnemyCount < 3) { return(false); } break; case ClassJobType.RedMage: if (EnemyCount < 3) { return(false); } break; } } #region Cone Check if (ID == 106 || ID == 41 || ID == 70) { if (!Helpers.InView(Core.Player.Location, Core.Player.Heading, target.Location)) { return(false); } } #endregion #region Rectangle Check if (ID == 86) { if (!Core.Player.IsFacing(target)) { return(false); } } #endregion #endregion #region Pet Exception if (SpellType == SpellType.Pet) { if (Core.Player.Pet == null) { return(false); } if (PetManager.PetMode != PetMode.Obey) { if (!await Coroutine.Wait(1000, () => PetManager.DoAction("Obey", Core.Player))) { return(false); } Logging.Write(Colors.OrangeRed, @"[Ultima] Ability: Pet Obey"); } #region IsMounted Check if (Core.Player.IsMounted) { return(false); } #endregion #region CanCast if (!PetManager.CanCast(Name, target)) { return(false); } #endregion #region DoAction if (!await Coroutine.Wait(5000, () => PetManager.DoAction(Name, target))) { return(false); } #endregion Ultima.LastSpell = this; #region Recent Spell Add var key = target.ObjectId.ToString("X") + "-" + Name; var val = DateTime.UtcNow + DataManager.GetSpellData(Name).AdjustedCastTime + TimeSpan.FromSeconds(5); RecentSpell.Add(key, val); #endregion Logging.Write(Colors.OrangeRed, @"[Ultima] Ability: " + Name); return(true); } #endregion #region Card Exception if (SpellType == SpellType.Card) { if (!await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target))) { return(false); } Ultima.LastSpell = this; #region Recent Spell Add var key = target.ObjectId.ToString("X") + "-" + Name; var val = DateTime.UtcNow + DataManager.GetSpellData(3590).AdjustedCastTime + TimeSpan.FromSeconds(5); RecentSpell.Add(key, val); #endregion Logging.Write(Colors.OrangeRed, @"[Ultima] Ability: " + Name); return(true); } #endregion #region CanAttack Check if (!target.CanAttack && CastType != CastType.Self) { switch (SpellType) { case SpellType.Damage: case SpellType.DoT: case SpellType.Movement: case SpellType.Cooldown: case SpellType.Interrupt: case SpellType.Execute: case SpellType.Knockback: case SpellType.Debuff: case SpellType.Flank: case SpellType.Behind: return(false); } } #endregion #region Ninjutsu Exception if (SpellType == SpellType.Ninjutsu || SpellType == SpellType.Mudra) { #region Player 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 Check if (Core.Player.IsMounted) { return(false); } #endregion #region CanCast if (Ultima.UltSettings.QueueSpells) { if (!ActionManager.CanCastOrQueue(DataManager.GetSpellData(ID), target)) { return(false); } } else { if (!ActionManager.CanCast(ID, target)) { return(false); } } #endregion #region Wait For Animation if (Ultima.LastSpell.ID != 0 && Ultima.LastSpell.SpellType != SpellType.Ninjutsu && Ultima.LastSpell.SpellType != SpellType.Mudra) { await Coroutine.Wait(1000, () => DataManager.GetSpellData(Ultima.LastSpell.ID).Cooldown.TotalMilliseconds <= DataManager.GetSpellData(Ultima.LastSpell.ID).AdjustedCooldown.TotalMilliseconds - 1000); } #endregion #region DoAction if (!await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target))) { return(false); } #endregion #region Wait For Cast Completion await Coroutine.Wait(2000, () => !ActionManager.CanCast(ID, target)); #endregion Ultima.LastSpell = this; #region Recent Spell Add if (SpellType == SpellType.Mudra) { var key = target.ObjectId.ToString("X") + "-" + Name; var val = DateTime.UtcNow + DataManager.GetSpellData(ID).AdjustedCastTime + TimeSpan.FromSeconds(1); RecentSpell.Add(key, val); } #endregion Logging.Write(Colors.OrangeRed, @"[Ultima] Ability: " + Name); return(true); } #endregion #region HasSpell Check if (!ActionManager.HasSpell(ID)) { return(false); } #endregion #region Player Movement if (BotManager.Current.IsAutonomous) { switch (ActionManager.InSpellInRangeLOS(ID, 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 (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, @"[Ultima] Dismounting..."); ActionManager.Dismount(); await Coroutine.Sleep(1000); } } #endregion #region IsMounted Check if (Core.Player.IsMounted) { return(false); } #endregion #region CanCast Check switch (CastType) { case CastType.TargetLocation: case CastType.SelfLocation: if (!ActionManager.CanCastLocation(ID, target.Location)) { return(false); } break; default: if (Ultima.UltSettings.QueueSpells) { 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 Check if (GameSettingsManager.FaceTargetOnAction == false && CastType == CastType.Target && SpellType != SpellType.Heal && SpellType != SpellType.Defensive && !Helpers.InView(Core.Player.Location, Core.Player.Heading, target.Location)) { return(false); } #endregion #region Off-GCD Check if (GCDType == GCDType.Off) { switch (Core.Player.CurrentJob) { case ClassJobType.Arcanist: case ClassJobType.Scholar: case ClassJobType.Summoner: if (Core.Player.ClassLevel >= 38 && Core.Player.CurrentManaPercent > 40 && DataManager.GetSpellData(163).Cooldown.TotalMilliseconds <= 1000) { return(false); } break; case ClassJobType.Archer: case ClassJobType.Bard: if (DataManager.GetSpellData(97).Cooldown.TotalMilliseconds <= 700) { return(false); } break; case ClassJobType.Astrologian: if (DataManager.GetSpellData(3596).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 (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.Rogue: case ClassJobType.Ninja: if (DataManager.GetSpellData(2240).Cooldown.TotalMilliseconds <= 1000) { return(false); } break; case ClassJobType.Thaumaturge: case ClassJobType.BlackMage: if (DataManager.GetSpellData(142).Cooldown.TotalMilliseconds <= 1000) { return(false); } break; case ClassJobType.Samurai: if (DataManager.GetSpellData(8821).Cooldown.TotalMilliseconds <= 1000) { return(false); } break; case ClassJobType.RedMage: if (DataManager.GetSpellData(7503).Cooldown.TotalMilliseconds <= 1000) { return(false); } break; } } #endregion #region DoAction switch (CastType) { case CastType.TargetLocation: if (Ultima.UltSettings.RandomCastLocation) { var rndx = (target.CombatReach * _rnd.NextDouble() * GetMultiplier()); var rndz = (target.CombatReach * _rnd.NextDouble() * GetMultiplier()); var rndxz = new Vector3((float)rndx, 0f, (float)rndz); var tarloc = target.Location; var rndloc = tarloc + rndxz; if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, rndloc))) { return(false); } } else { if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, target.Location))) { return(false); } } break; case CastType.SelfLocation: if (Ultima.UltSettings.RandomCastLocation) { var rndx = ((1f * _rnd.NextDouble() + 1f) * GetMultiplier()); var rndz = ((1f * _rnd.NextDouble() + 1f) * GetMultiplier()); var rndxz = new Vector3((float)rndx, 0f, (float)rndz); var tarloc = target.Location; var rndloc = tarloc + rndxz; if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, rndloc))) { return(false); } } else { if (!await Coroutine.Wait(1000, () => ActionManager.DoActionLocation(ID, target.Location))) { return(false); } } break; default: if (!await Coroutine.Wait(1000, () => ActionManager.DoAction(ID, target))) { return(false); } break; } #endregion #region Wait For Cast Completion 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 Ultima.LastSpell = this; #region Recent Spell Add if (SpellType != SpellType.Damage && SpellType != SpellType.Heal && SpellType != SpellType.AoE && SpellType != SpellType.Behind && SpellType != SpellType.Flank) { var key = target.ObjectId.ToString("X") + "-" + Name; var val = DateTime.UtcNow + DataManager.GetSpellData(ID).AdjustedCastTime + TimeSpan.FromSeconds(5); RecentSpell.Add(key, val); } if (SpellType == SpellType.Heal) { var key = target.ObjectId.ToString("X") + "-" + Name; var val = DateTime.UtcNow + DataManager.GetSpellData(ID).AdjustedCastTime + TimeSpan.FromSeconds(3); RecentSpell.Add(key, val); } #endregion Logging.Write(Colors.OrangeRed, @"[Ultima] Ability: " + Name); return(true); }