public TrinityPower GetOffensivePower()
        {
            TrinityActor target   = CurrentTarget;
            Vector3      position = Vector3.Zero;

            if (CurrentTarget != null && (!CurrentTarget.IsBoss || (CurrentTarget.IsElite && CurrentTarget.EliteType == EliteTypes.Minion)))
            {
                target = TargetUtil.BestRangedAoeUnit(50) ?? CurrentTarget;
            }

            if (!Core.Buffs.HasBuff(445266) && Player.PrimaryResource > 36)
            {
                return(new TrinityPower(Skills.DemonHunter.Impale));
            }

            position = MathEx.CalculatePointFrom(target.Position, ZetaDia.Me.Position, 15);
            if ((target.Distance > 15 || ((Legendary.ElusiveRing.IsEquipped || Legendary.ElusiveRing.IsEquippedInCube) && Skills.DemonHunter.Vault.TimeSinceUse > 6000)) && Core.Grids.CanRayWalk(Player.Position, position))
            {
                return(Vault(position));
            }


            if (Skills.DemonHunter.Impale.CanCast())
            {
                return(new TrinityPower(Skills.DemonHunter.Impale, Player.CurrentHealthPct < 0.45 ? 30f : 15f, target.AcdId));
            }

            return(null);
        }
        protected override bool ShouldArchonDisintegrationWave(out TrinityActor target)
        {
            target = null;

            if (!Skills.Wizard.ArchonDisintegrationWave.CanCast())
            {
                return(false);
            }

            target = CurrentTarget;
            if (target.IsTreasureGoblin && target.Distance < Settings.DisintegrationWaveRange && target.IsInLineOfSight)
            {
                return(true);
            }

            target = TargetUtil.BestRangedAoeUnit(Settings.DisintegrationWaveMinClusterRadius, Settings.DisintegrationWaveRange, ClusterSize);
            if (target != null && target.IsInLineOfSight)
            {
                return(true);
            }

            return(target != null);
        }
        public TrinityPower GetOffensivePower()
        {
            // 锁定奥拉什
            TrinityActor target;
            Vector3      position = Vector3.Zero;

            if (IsArchonActive)
            {
                target = TargetUtil.BestRangedAoeUnit(75, 75) ?? CurrentTarget;


                if (Skills.Wizard.ArchonTeleport.CanCast())
                {
                    if (!Core.Buffs.HasInvulnerableShrine && Skills.Wizard.Archon.TimeSinceUse > 19000)
                    {
                        Core.Avoidance.Avoider.TryGetSafeSpot(out position, 30, 50, Player.Position);
                    }

                    if (!Core.Buffs.HasInvulnerableShrine && Core.Avoidance.InAvoidance(Core.Player.Position))
                    {
                        Core.Avoidance.Avoider.TryGetSafeSpot(out position, 25, 45, target.Position);

                        if (position == Vector3.Zero)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 15, 40, Player.Position);
                        }
                    }

                    if ((!Core.Buffs.HasInvulnerableShrine && (Player.CurrentHealthPct >= 1 && Player.ShieldHitpoints < Player.CurrentHealth) && Skills.Wizard.ArchonTeleport.TimeSinceUse > 3000) ||
                        (!Core.Buffs.HasInvulnerableShrine && Player.CurrentHealthPct < 1 && Skills.Wizard.ArchonTeleport.TimeSinceUse > 1500) ||
                        TargetUtil.AnyElitesInRange(10))
                    {
                        Core.Avoidance.Avoider.TryGetSafeSpot(out position, 30, 45, target.Position);
                    }

                    if (target.IsBoss && target.Distance < 30)
                    {
                        Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, target.Position);
                    }

                    if (position != Vector3.Zero)
                    {
                        return(Teleport(position));
                    }
                }

                if (Skills.Wizard.ArchonDisintegrationWave.CanCast())
                {
                    return(ArchonDisintegrationWave(target));
                }

                return(Walk(Avoider.SafeSpot));
            }


            target = TargetUtil.BestRangedAoeUnit(50) ?? CurrentTarget;


            if (Skills.Wizard.Archon.CanCast())
            {
                if (!HasTalRashaStacks)
                {
                    if (TalRashaStacks == 2 && Skills.Wizard.ArcaneTorrent.TimeSinceUse < 6000)
                    {
                        if (Skills.Wizard.Blizzard.TimeSinceUse < 6000)
                        {
                            return(BlackHole(target));
                        }
                        if (Skills.Wizard.BlackHole.TimeSinceUse < 6000)
                        {
                            return(Blizzard(target));
                        }
                    }
                }
                else
                {
                    return(Archon());
                }
            }

            var blizzard = Skills.Wizard.Blizzard;

            if (blizzard.CanCast() && blizzard.TimeSinceUse > 6000)
            {
                return(Blizzard(target));
            }

            var blackhole = Skills.Wizard.BlackHole;

            if ((blackhole.CanCast() && blackhole.TimeSinceUse > 6000))
            {
                return(BlackHole(target));
            }

            if (TalRashaStacks >= 2)
            {
                return(ArcaneTorrent(target));
            }

            return(Walk(Avoider.SafeSpot));
        }
Beispiel #4
0
        public TrinityPower GetOffensivePower()
        {
            TrinityPower power;
            var          target   = CurrentTarget;
            Vector3      position = Vector3.Zero;

            if (Skills.Wizard.ArchonTeleport.CanCast() || Skills.Wizard.Teleport.CanCast())
            {
                if (!Core.Buffs.HasInvulnerableShrine && Core.Avoidance.InAvoidance(Core.Player.Position))
                {
                    Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, Player.Position);

                    if (position == Vector3.Zero)
                    {
                        Core.Avoidance.Avoider.TryGetSafeSpot(out position, 15, 50, Player.Position);
                    }
                }
                if (!Core.Buffs.HasInvulnerableShrine)
                {
                    if (IsArchonActive)
                    {
                        if (TargetUtil.AnyElitesInRange(10) && Skills.Wizard.ArchonTeleport.TimeSinceUse > 2000)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, CurrentTarget.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 20, 50, CurrentTarget.Position);
                            }
                        }
                        if (TargetUtil.AnyMobsInRange(15, 3) && Skills.Wizard.ArchonTeleport.TimeSinceUse > 3000)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, CurrentTarget.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 20, 50, CurrentTarget.Position);
                            }
                        }
                        if (Player.CurrentHealthPct < 1 && Skills.Wizard.ArchonTeleport.TimeSinceUse > 2000)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, Player.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 15, 50, Player.Position);
                            }
                        }
                    }
                    if (!IsArchonActive)
                    {
                        if (TargetUtil.AnyElitesInRange(10) && Skills.Wizard.Teleport.TimeSinceUse > 1200)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, CurrentTarget.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 20, 50, CurrentTarget.Position);
                            }
                        }

                        if (TargetUtil.AnyMobsInRange(15, 3) && Skills.Wizard.Teleport.TimeSinceUse > 1200)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, CurrentTarget.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 20, 50, CurrentTarget.Position);
                            }
                        }
                        if (Player.CurrentHealthPct < 1 && Skills.Wizard.Teleport.TimeSinceUse > 1200)
                        {
                            Core.Avoidance.Avoider.TryGetSafeSpot(out position, 35, 50, Player.Position);

                            if (position == Vector3.Zero)
                            {
                                Core.Avoidance.Avoider.TryGetSafeSpot(out position, 15, 50, Player.Position);
                            }
                        }
                    }
                }

                if (target.IsBoss && target.Distance < 25 && (Skills.Wizard.ArchonTeleport.TimeSinceUse > 2000 || Skills.Wizard.Teleport.TimeSinceUse > 2000))
                {
                    Core.Avoidance.Avoider.TryGetSafeSpot(out position, 40, 50, CurrentTarget.Position);
                }

                if (position != Vector3.Zero && !TrinityGrid.Instance.IsIntersectedByFlags(ZetaDia.Me.Position, position, AvoidanceFlags.Combat, AvoidanceFlags.CriticalAvoidance))
                {
                    return(Teleport(position));
                }
            }

            if (!IsArchonActive)
            {
                if (Player.CurrentHealthPct <= 0.7f && Skills.Wizard.Archon.CanCast())
                {
                    Core.Logger.Log(LogCategory.Spells, $"Emergency Archon, LOW ON HP {Player.CurrentHealthPct}%!");
                    return(Archon());
                }
                if (Legendary.ConventionOfElements.IsEquipped)
                {
                    if (Skills.Wizard.Archon.CanCast())
                    {
                        if (Core.Buffs.ConventionElement == Element.Fire && TalRashaStacks >= 3)
                        {
                            Core.Logger.Log(LogCategory.Spells, $"Archon conditions met (TalRasha {TalRashaStacks} stacks && We are on {Core.Buffs.ConventionElement}!)");
                            return(Archon());
                        }

                        if (Core.Buffs.ConventionElement == Element.Fire && TalRashaStacks >= 2)
                        {
                            Core.Logger.Log(LogCategory.Spells, $"Archon conditions met (TalRasha {TalRashaStacks} stacks && We are on {Core.Buffs.ConventionElement}!)");
                            return(Archon());
                        }
                    }
                }
                if (!Legendary.ConventionOfElements.IsEquipped)
                {
                    if (Skills.Wizard.Archon.CanCast() && TalRashaStacks >= 2)
                    {
                        Core.Logger.Log(LogCategory.Spells, $"Archon conditions met (TalRasha {TalRashaStacks} stacks!)");
                        return(Archon());
                    }
                }
            }

            if (IsArchonActive)
            {
                target = null;
                var targetElite = TargetUtil.BestEliteInRange(75);
                var targett     = TargetUtil.BestRangedAoeUnit(30, 75, Settings.ClusterSize, true, true);
                var targettt    = TargetUtil.GetBestClusterUnit(30, 75, true, true, false, true) ?? CurrentTarget;
                if (targetElite != null)
                {
                    Core.Logger.Log(LogCategory.Targetting, $"Ladies first!");
                    return(ArchonDisintegrationWave(targetElite));
                }
                else if (targett != null)
                {
                    Core.Logger.Log(LogCategory.Targetting, $"Good hunts are second!");
                    return(ArchonDisintegrationWave(targett));
                }
                else
                {
                    Core.Logger.Log(LogCategory.Targetting, $"Archon Disintegration: Pew Pew Pew!");
                    return(ArchonDisintegrationWave(targettt));
                }
            }

            var lastBlackHolePosition = Vector3.Zero;

            power = null;
            if (Skills.Wizard.BlackHole.CanCast() && Core.Player.PrimaryResource > 18)
            {
                if (Skills.Wizard.BlackHole.CurrentRune == Runes.Wizard.Spellsteal || Skills.Wizard.BlackHole.CurrentRune == Runes.Wizard.AbsoluteZero)
                {
                    if (TargetUtil.NumMobsInRangeOfPosition(target.Position, 15) > Skills.Wizard.BlackHole.BuffStacks)
                    {
                        lastBlackHolePosition = target.Position;
                        {
                            Core.Logger.Log(LogCategory.Targetting, $"Placing BlackHole: Good place for stacks!");
                            return(BlackHole(target));
                        }
                    }
                }

                if (target.Position.Distance2D(lastBlackHolePosition) > 10)
                {
                    lastBlackHolePosition = target.Position;
                    {
                        Core.Logger.Log(LogCategory.Targetting, $"Placing BlackHole: The bomb has been planted!");
                        return(BlackHole(target));
                    }
                }

                if (Skills.Wizard.BlackHole.TimeSinceUse > 2000)
                {
                    lastBlackHolePosition = target.Position;
                    {
                        Core.Logger.Log(LogCategory.Targetting, $"Placing BlackHole: Well placed.");
                        return(BlackHole(target));
                    }
                }
            }

            if (TrySecondaryPower(out power))
            {
                Core.Logger.Log(LogCategory.Targetting, $"OffensivePower SecondaryPower");
                return(power);
            }

            if (TryPrimaryPower(out power))
            {
                Core.Logger.Log(LogCategory.Targetting, $"OffensivePower PrimaryPower");
                return(power);
            }
            return(Walk(CurrentTarget.Position));
        }
        protected override bool ShouldArchonTeleport(out Vector3 position)
        {
            position = Vector3.Zero;
            var skill              = Skills.Wizard.ArchonTeleport;
            var affixOnPlayer      = Core.Avoidance.InAvoidance(ZetaDia.Me.Position);
            var isShrine           = TrinityCombat.Targeting.CurrentTarget.Type == TrinityObjectType.Shrine;
            var isProgressionGlobe = TrinityCombat.Targeting.CurrentTarget.Type == TrinityObjectType.ProgressionGlobe;
            var isHealthGlobe      = TrinityCombat.Targeting.CurrentTarget.Type == TrinityObjectType.HealthGlobe;

            //Teleport Activations
            var archonHealthIsLow = IsArchonActive && Player.CurrentHealthPct < Settings.ArchonTeleportHealthEmergency;
            var anyElitesinRange  = TargetUtil.AnyElitesInRange(Settings.TeleportEliteKiteRange);
            var anyMobsInRange    = TargetUtil.AnyMobsInRangeOfPosition(Player.Position, Settings.TeleportTrashKiteRange, Settings.TeleportTrashInRangeCount);

            //Teleport Delays
            var archonHealthIsLowDelay = Skills.Wizard.Teleport.TimeSinceUse > Settings.ArchonTeleportHealthDelay;
            var archonTeleportDelay    = (TalRashaStacks == 4 && Skills.Wizard.Teleport.TimeSinceUse > Settings.Archon4StackDelay) || (TalRashaStacks <4 && Skills.Wizard.Teleport.TimeSinceUse> Settings.Archon1StackDelay);

            if (!skill.CanCast())
            {
                return(false);
            }

            if (CurrentTarget.Distance < 50 && isShrine || isProgressionGlobe || (isHealthGlobe && archonHealthIsLow))
            {
                //Core.Logger.Log($"Teleporting to Priority Target");
                position = CurrentTarget.Position;
                return(true);
            }

            if ((Player.IsChannelling || !Player.IsChannelling))
            {
                if (affixOnPlayer || (archonHealthIsLow && archonHealthIsLowDelay && anyMobsInRange))
                {
                    //Core.Logger.Log($"Teleport for Survival! Affix: {affixOnPlayer}, Health: {archonHealthIsLow}");
                    Avoider.TryGetSafeSpot(out position, Settings.TeleportKiteMinDistance, Settings.TeleportKiteMaxDistance, ZetaDia.Me.Position, node => !HostileMonsters.Any(m => m.Position.Distance(node.NavigableCenter) < 15f));
                    return(true);
                }

                if (Skills.Wizard.Archon.TimeSinceUse > 19500)
                {
                    //Core.Logger.Log($"Teleport! Archon is about to drop!!!");
                    Avoider.TryGetSafeSpot(out position, Settings.TeleportKiteMinDistance, Settings.TeleportKiteMaxDistance, ZetaDia.Me.Position, node => !HostileMonsters.Any(m => m.Position.Distance(node.NavigableCenter) < 15f));
                    return(true);
                }

                if (CurrentTarget.IsElite && anyElitesinRange && archonTeleportDelay)
                {
                    //Core.Logger.Log($"Teleport! Elite too close: {CurrentTarget.Distance} Setting: {Settings.TeleportEliteKiteRange}");
                    Avoider.TryGetSafeSpot(out position, 40, Settings.TeleportKiteMaxDistance, TrinityCombat.Targeting.CurrentTarget.Position, node => !HostileMonsters.Any(m => m.Position.Distance(node.NavigableCenter) < 15f));
                    return(true);
                }

                var target = TargetUtil.BestRangedAoeUnit(10, 50, ClusterSize);
                if (target != null && target.Distance < 30f)
                {
                    //Core.Logger.Log($"Teleport! Trash Target too close: {CurrentTarget.Distance}");
                    Avoider.TryGetSafeSpot(out position, 40, Settings.TeleportKiteMaxDistance, target.Position, node => !HostileMonsters.Any(m => m.Position.Distance(node.NavigableCenter) < 15f));
                    return(true);
                }
            }

            return(position != Vector3.Zero);
        }