protected virtual bool ShouldDiamondSkin() { if (!Skills.Wizard.DiamondSkin.CanCast()) { return(false); } if (Player.CurrentHealthPct > 0.8) { return(false); } if (!TargetUtil.AnyMobsInRange(25f)) { return(false); } return(true); }
protected virtual bool ShouldLandOfTheDead() { if (!Skills.Necromancer.LandOfTheDead.CanCast()) { return(false); } if (Player.IsInTown) { return(false); } if (!TargetUtil.AnyMobsInRange(60f)) { return(false); } return(true); }
protected virtual bool ShouldConsecration() { if (!Skills.Crusader.Consecration.CanCast()) { return(false); } if (Player.HasBuff(SNOPower.X1_Crusader_Consecration)) { return(false); } if (!TargetUtil.AnyMobsInRange(20f)) { return(false); } return(true); }
protected virtual bool ShouldProvoke() { if (!Skills.Crusader.Provoke.CanCast()) { return(false); } if (Player.HasBuff(SNOPower.X1_Crusader_Provoke)) { return(false); } if (!TargetUtil.AnyMobsInRange(15f)) { return(false); } return(true); }
protected virtual bool ShouldCondemn() { if (!Skills.Crusader.Condemn.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(14f)) { return(false); } if (Legendary.FrydehrsWrath.IsEquipped && Player.PrimaryResource < 40) { return(false); } return(true); }
/// <summary> /// When Companion should be cast /// </summary> private static bool CompanionCondition(SkillMeta meta) { meta.CastFlags = CanCastFlags.NoTimer; // Use Spider Slow on 4 or more trash mobs in an area or on Unique/Elite/Champion if (Runes.DemonHunter.SpiderCompanion.IsActive && TargetUtil.ClusterExists(25f, 4) && TargetUtil.EliteOrTrashInRange(25f)) { return(true); } //Use Bat when Hatred is Needed if (Runes.DemonHunter.BatCompanion.IsActive && Player.PrimaryResourceMissing >= 60) { return(true); } // Use Boar Taunt on 3 or more trash mobs in an area or on Unique/Elite/Champion if (Runes.DemonHunter.BoarCompanion.IsActive && ((TargetUtil.ClusterExists(20f, 4) && TargetUtil.EliteOrTrashInRange(20f)) || (CurrentTarget.IsBossOrEliteRareUnique && CurrentTarget.Distance <= 20f))) { return(true); } // Ferrets used for picking up Health Globes when low on Health if (Runes.DemonHunter.FerretCompanion.IsActive && Trinity.ObjectCache.Any(o => o.Type == TrinityObjectType.HealthGlobe && o.Distance < 60f) && Player.CurrentHealthPct < EmergencyHealthPotionLimit) { return(true); } // Use Wolf Howl on Unique/Elite/Champion - Would help for farming trash, but trash farming should not need this - Used on Elites to reduce Deaths per hour if (Runes.DemonHunter.WolfCompanion.IsActive && (TargetUtil.AnyElitesInRange(100f) || TargetUtil.AnyMobsInRange(40, 8))) { return(true); } // Companion off CD if (Settings.Combat.DemonHunter.CompanionOffCooldown && TargetUtil.AnyMobsInRange(60)) { return(true); } return(false); }
/// <summary> /// Only cast in combat and the target is a unit /// </summary> public TrinityPower GetOffensivePower() { TrinityPower power; if (IsChannellingFirebats && Player.CurrentHealthPct > 0.5f && TargetUtil.AnyMobsInRange(FireBatsRange)) return Firebats(); if (TrySpecialPower(out power)) return power; if (TrySecondaryPower(out power)) return power; if (TryPrimaryPower(out power)) return power; if (IsNoPrimary) return Walk(CurrentTarget); return null; }
/// <summary> /// Checks for all necessary buffs and combat conditions for starting Archon /// </summary> /// <returns></returns> private static bool ShouldStartArchon() { bool canCastArchon = ( CheckAbilityAndBuff(SNOPower.Wizard_MagicWeapon) && (!Hotbar.Contains(SNOPower.Wizard_Familiar) || IsFamiliarActive) && CheckAbilityAndBuff(SNOPower.Wizard_EnergyArmor) && CheckAbilityAndBuff(SNOPower.Wizard_IceArmor) && CheckAbilityAndBuff(SNOPower.Wizard_StormArmor) ); var elitesOnly = Settings.Combat.Wizard.ArchonElitesOnly && TargetUtil.AnyElitesInRange(Settings.Combat.Wizard.ArchonEliteDistance); var trashInRange = !Settings.Combat.Wizard.ArchonElitesOnly && TargetUtil.AnyMobsInRange(Settings.Combat.Wizard.ArchonMobDistance, Settings.Combat.Wizard.ArchonMobCount); // With Chantodos set wait until max stacks before using archon if (Sets.ChantodosResolve.IsFullyEquipped && CacheData.Buffs.HasBuff(SNOPower.P3_ItemPassive_Unique_Ring_021) && CacheData.Buffs.GetBuff(SNOPower.P3_ItemPassive_Unique_Ring_021).StackCount < 20) { return(false); } return(canCastArchon && (elitesOnly || trashInRange || CurrentTarget.IsBoss)); }
protected virtual bool ShouldStrafe(out Vector3 position) { // Note: This is for casting while not moving. // Routine GetMovermentPower() may cast for movement // (Its called directly by our IPlayerMover) position = Vector3.Zero; if (!Skills.DemonHunter.Strafe.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(50f)) { return(false); } position = TargetUtil.GetZigZagTarget(CurrentTarget.Position, 20f, true); return(position != Vector3.Zero); }
/// <summary> /// When Shadow Power should be cast /// </summary> private static bool ShadowPowerCondition(SkillMeta meta) { // Buff Already Active if (GetHasBuff(SNOPower.DemonHunter_ShadowPower)) { return(false); } // Not Enough Discipline if (Player.SecondaryResource < 14) { return(false); } // Used Recently if (TimeSincePowerUse(SNOPower.DemonHunter_ShadowPower) < 4500) { return(false); } // Low Health if (Player.CurrentHealthPct <= Trinity.PlayerEmergencyHealthPotionLimit && Player.SecondaryResource >= 14) { return(true); } // Defensive Cast if (Player.IsRooted || TargetUtil.AnyMobsInRange(15)) { return(true); } // Spam Setting if (Settings.Combat.DemonHunter.SpamShadowPower) { return(true); } return(false); }
/// <summary> /// When Evasive fire should be cast /// </summary> /// <param name="meta"></param> /// <returns></returns> private static bool EvasiveFireCondition(SkillMeta meta) { if (Skills.DemonHunter.Multishot.IsActive || Skills.DemonHunter.Strafe.IsActive) { // Still generates resource when hitting nothing. if (CurrentTarget.IsBoss && !ShouldRefreshBastiansGeneratorBuff) { meta.CastRange = Skills.DemonHunter.Multishot.IsActive ? 80f : 40f; } meta.TargetUnitSelector = ret => TargetUtil.GetClosestUnit(); } if (Legendary.YangsRecurve.IsEquipped && Legendary.DeadMansLegacy.IsEquipped) { // Only use when we have to, it deals basically no damage, just generates resource and bastians buff. return((Player.PrimaryResourcePct < 0.5 || ShouldRefreshBastiansGeneratorBuff) && TargetUtil.AnyMobsInRange(80f)); } return(TargetUtil.AnyMobsInRange(80f)); }
protected virtual bool ShouldBlessedHammer(out TrinityActor target) { target = null; if (!Skills.Crusader.BlessedHammer.CanCast()) { return(false); } if (Player.PrimaryResource <= PrimaryEnergyReserve) { return(false); } if (!TargetUtil.AnyMobsInRange(10f)) { return(false); } target = TargetUtil.GetBestClusterUnit() ?? CurrentTarget; return(target != null); }
protected virtual bool ShouldCallOfTheAncients() { if (!Skills.Barbarian.CallOfTheAncients.CanCast()) { return(false); } if (Core.Player.Summons.AncientCount < 3) { if (Sets.ImmortalKingsCall.IsFirstBonusActive) { return(true); } if (TargetUtil.AnyMobsInRange(30f)) { return(true); } } return(false); }
protected override bool ShouldEvasiveFire(out TrinityActor target) { target = null; if (!Skills.DemonHunter.EvasiveFire.CanCast()) { return(false); } if (!ShouldRefreshBastiansGenerator && Player.PrimaryResource > PrimaryEnergyReserve) { return(false); } if (!TargetUtil.AnyMobsInRange(60f)) { return(false); } target = TargetUtil.GetBestClusterUnit() ?? CurrentTarget; return(target != null); }
protected virtual bool ShouldCaltrops() { if (!Skills.DemonHunter.Caltrops.CanCast()) { return(false); } if (Player.SecondaryResource < SecondaryEnergyReserve) { return(false); } if (Runes.DemonHunter.BaitTheTrap.IsActive) { if (Player.HasBuff(SNOPower.DemonHunter_Caltrops, 3)) { return(false); } if (Skills.DemonHunter.Caltrops.TimeSinceUse < 2000) { return(false); } } else { if (!TargetUtil.AnyMobsInRange(16f)) { return(false); } if (Skills.DemonHunter.Caltrops.TimeSinceUse < 6000) { return(false); } } return(true); }
protected virtual bool ShouldLashingTailKick(out TrinityActor target) { target = null; if (!Skills.Monk.LashingTailKick.CanCast()) { return(false); } if (Player.PrimaryResource < PrimaryEnergyReserve) { return(false); } if (!TargetUtil.AnyMobsInRange(60f)) { return(false); } target = TargetUtil.GetBestClusterUnit(); return(target != null); }
protected override bool ShouldTeleport(out Vector3 position) { position = Vector3.Zero; if (!CanTeleport) { return(false); } // Jump into cluster for archon combust if (!IsArchonActive && Skills.Wizard.Archon.CanCast() && TalRashaStacks >= 2 && Runes.Wizard.Combustion.IsActive) { Core.Logger.Log(LogCategory.Routine, "Teleport to Archon Combust"); position = TargetUtil.GetBestClusterPoint(); return(position != Vector3.Zero); } // Jump away from monsters but within cast range if (Avoider.TryGetSafeSpot(out position, 15f, 50f, Player.Position, n => n.AvoidanceFlags.HasFlag(AvoidanceFlags.Monster) && Core.Grids.CanRayCast(n.NavigableCenter, CurrentTarget.Position))) { Core.Logger.Log(LogCategory.Routine, "Teleport to Safespot (ShouldTeleport)"); return(true); } // Try a different approach. var target = TargetUtil.GetBestClusterUnit(); position = TargetUtil.GetLoiterPosition(target, 30f); if (position != Vector3.Zero && target != null && TargetUtil.AnyMobsInRange(20f, 3) || TargetUtil.AnyElitesInRange(20f)) { Core.Logger.Log(LogCategory.Routine, "Teleport to LoiterPosition (ShouldTeleport)"); return(true); } return(false); }
protected override bool ShouldCycloneStrike() { if (!Skills.Monk.CycloneStrike.CanCast()) { return(false); } if (Player.PrimaryResource < PrimaryEnergyReserve) { return(false); } if (Skills.Monk.CycloneStrike.TimeSinceUse < Settings.CycloneStrikeDelay) { return(false); } var targetIsCloseElite = CurrentTarget.IsElite && CurrentTarget.Distance < CycloneStrikeRange; //Checks for elites first var plentyOfTargetsToPull = TargetUtil.IsPercentUnitsWithinBand(15f, CycloneStrikeRange, 0.25); //Checks percentage within band var anyTargetsInRange = TargetUtil.AnyMobsInRange(CycloneStrikeRange, Settings.CycloneStrikeMinMobs); //Checks minimum mobs in range return(targetIsCloseElite || plentyOfTargetsToPull || anyTargetsInRange); }
protected override bool ShouldFuriousCharge(out Vector3 position) { position = Vector3.Zero; var skill = Skills.Barbarian.FuriousCharge; if (!skill.CanCast()) { return(false); } if (!AllowedToUse(Settings.FuriousCharge, Skills.Barbarian.FuriousCharge)) { return(false); } if (!TargetUtil.AnyMobsInRange(60f) && !IsNoPrimary) { return(false); } position = TargetUtil.GetBestClusterPoint(); return(position != Vector3.Zero); }
protected override bool ShouldBreathOfHeaven() { if (!Skills.Monk.BreathOfHeaven.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(20)) { return(false); } if (Settings.SpamBreathHeaven) { return(true); } var needSpiritBuff = Runes.Monk.InfusedWithLight.IsActive && (Player.PrimaryResourcePct < 0.5f || !HasShenLongBuff); var needDamage = Runes.Monk.BlazingWrath.IsActive && TargetUtil.AnyMobsInRange(20); var needHealing = Player.CurrentHealthPct <= 0.6f; return(needSpiritBuff || needHealing || needDamage); }
protected virtual bool ShouldBreathOfHeaven() { if (!Skills.Monk.BreathOfHeaven.CanCast()) { return(false); } if (Core.Buffs.HasBuff(SNOPower.Monk_BreathOfHeaven)) { return(false); } if (!TargetUtil.AnyMobsInRange(20)) { return(false); } var needSpiritBuff = Runes.Monk.InfusedWithLight.IsActive && Player.PrimaryResourcePct < 0.5f; var needDamage = Runes.Monk.BlazingWrath.IsActive && TargetUtil.AnyMobsInRange(20); var needHealing = Player.CurrentHealthPct <= 0.6f; return(needSpiritBuff || needHealing || needDamage); }
protected override bool ShouldFuriousCharge(out Vector3 position) { position = Vector3.Zero; TrinityActor target = null; if (!Skills.Barbarian.FuriousCharge.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(60f)) { return(false); } if (Legendary.AncientParthanDefenders.IsEquipped) { position = TargetUtil.FreezePiercePoint(60f, true); } position = TargetUtil.GetBestPiercePoint(60f); return(position != Vector3.Zero); }
protected virtual bool ShouldSevenSidedStrike(out TrinityActor target) { target = null; if (!Skills.Monk.SevenSidedStrike.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(45f)) { return(false); } if (Player.PrimaryResource < PrimaryEnergyReserve) { return(false); } if (Skills.Monk.ExplodingPalm.IsActive && !WeightedUnits.Any(u => u.IsUnit && u.Distance < 35f && u.HasDebuff(SNOPower.Monk_ExplodingPalm))) { return(false); } var isElitesInRange = TargetUtil.AnyElitesInRange(15, 1); var isSpamRelatedItems = Legendary.Madstone.IsEquipped || Sets.UlianasStratagem.IsMaxBonusActive; var isLowHealth = Player.CurrentHealthPct < 0.55f; var isLargerCluster = TargetUtil.ClusterExists(20f, 20f, LargeClusterSize); if (isElitesInRange || isSpamRelatedItems || isLowHealth || isLargerCluster) { target = TargetUtil.GetBestClusterUnit(); return(target != null); } return(false); }
protected override bool ShouldArchon() { if (!AllowedToUse(Settings.Archon, Skills.Wizard.Archon)) { return(false); } if (!TargetUtil.AnyMobsInRange(30f)) { return(false); } if (IsFirebirdsMeteorReviveUsed && Player.CurrentHealthPct < EmergencyHealthPct) { return(true); } if (Sets.ChantodosResolve.IsFullyEquipped && ChantodosStacks < 20) { return(false); } return(base.ShouldArchon()); }
protected virtual bool ShouldSmokeScreen() { if (!Skills.DemonHunter.SmokeScreen.CanCast()) { return(false); } if (Player.HasBuff(SNOPower.DemonHunter_SmokeScreen)) { return(false); } if (Player.CurrentHealthPct <= 0.75 || Player.IsRooted || Player.IsIncapacitated) { return(true); } if (TargetUtil.AnyMobsInRange(15)) { return(true); } return(false); }
protected override bool ShouldBlindingFlash() { if (!Skills.Monk.BlindingFlash.CanCast()) { return(false); } if (!TargetUtil.AnyMobsInRange(20f)) { return(false); } if (Player.CurrentHealthPct < 0.5f) { return(true); } if (Legendary.TheLawsOfSeph.IsEquipped) { return(Player.PrimaryResource < Player.PrimaryResourceMax - 165); } return(true); }
protected override bool ShouldEpiphany() { if (!Skills.Monk.Epiphany.CanCast()) { return(false); } if (HasInstantCooldowns && !Skills.Monk.Epiphany.IsLastUsed) { return(true); } if (!AllowedToUse(Settings.Epiphany, Skills.Monk.Epiphany)) { return(false); } if (!TargetUtil.AnyMobsInRange(60f)) { return(false); } return(true); }
protected override bool ShouldIronSkin() { if (!Skills.Crusader.IronSkin.CanCast()) { return(false); } if (Settings.SpamIronSkin) { return(true); } if (Player.HasBuff(SNOPower.X1_Crusader_IronSkin)) { return(false); } if (!TargetUtil.AnyMobsInRange(20f)) { return(false); } return(true); }
protected override bool ShouldCondemn() { if (!Skills.Crusader.Condemn.CanCast()) { return(false); } if (Legendary.FrydehrsWrath.IsEquipped && Player.PrimaryResource < 40) { return(false); } if (Settings.SpamCondemn) { return(true); } if (!TargetUtil.AnyMobsInRange(30f)) { return(false); } return(true); }
protected virtual bool ShouldMysticAlly() { if (!Skills.Monk.MysticAlly.CanCast()) { return(false); } if (Core.Buffs.HasBuff(SNOPower.X1_Monk_MysticAlly_v2)) { return(false); } if (Runes.Monk.AirAlly.IsActive && Player.PrimaryResource > 150) { return(false); } if (!TargetUtil.AnyMobsInRange(30f)) { return(false); } return(true); }