예제 #1
0
        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);
        }
예제 #2
0
        protected virtual bool ShouldLandOfTheDead()
        {
            if (!Skills.Necromancer.LandOfTheDead.CanCast())
            {
                return(false);
            }

            if (Player.IsInTown)
            {
                return(false);
            }

            if (!TargetUtil.AnyMobsInRange(60f))
            {
                return(false);
            }

            return(true);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        /// <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));
        }
예제 #9
0
        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);
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        /// <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));
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
        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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
        }
예제 #23
0
        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);
        }
예제 #24
0
        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());
        }
예제 #25
0
        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);
        }
예제 #26
0
        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);
        }
예제 #27
0
        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);
        }
예제 #28
0
        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);
        }
예제 #29
0
        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);
        }
예제 #30
0
        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);
        }