// Terror protected virtual bool ShouldSoulHarvest(out Vector3 position) { position = Vector3.Zero; if (!Skills.WitchDoctor.SoulHarvest.CanCast()) { return(false); } var stacks = Skills.WitchDoctor.SoulHarvest.BuffStacks; if (stacks > 1 && Skills.WitchDoctor.SoulHarvest.TimeSinceUse > 11000 && HostileMonsters.Any(u => u.Distance <= 18f)) { return(true); } var isMaxHarvestStacks = stacks == MaxSoulHarvestStacks; if (isMaxHarvestStacks && !Sets.RaimentOfTheJadeHarvester.IsEquipped) { return(false); } position = TargetUtil.GetBestClusterPoint(); return(true); }
public TrinityPower GetBuffPower() { if (TryLaw(out var power)) { //Core.Logger.Verbose(LogCategory.Routine, $"Buff Law"); return(power); } if (!Player.IsInTown && Settings.BombardmentOOC && HostileMonsters.Any(u => u.Distance < 150f)) { //Core.Logger.Verbose(LogCategory.Routine, $"Buff Bombard Func"); // Break Steed to bombard OOC only if waiting for CoE var goodTimetoCast = !ShouldBombardWheneverPossible || !IsSteedCharging; if (goodTimetoCast && TryBombard(out power)) { return(power); } } return(null); }
public TrinityPower GetOffensivePower() { TrinityPower power; Vector3 position; if (TrySpecialPower(out power)) { return(power); } if (Core.Buffs.HasCastingShrine) { if (Skills.Monk.BlindingFlash.CanCast() && Legendary.TheLawsOfSeph.IsEquipped && Player.PrimaryResource < Player.PrimaryResourceMax - 165) { return(BlindingFlash()); } if (Skills.Monk.MysticAlly.CanCast() && Runes.Monk.AirAlly.IsActive && Player.PrimaryResource < Player.PrimaryResourceMax - 200) { return(MysticAlly()); } if (Skills.Monk.DashingStrike.CanCast() && !Skills.Monk.DashingStrike.IsLastUsed) { return(DashingStrike(CurrentTarget.Position)); } if (Skills.Monk.WaveOfLight.CanCast()) { return(WaveOfLight(CurrentTarget)); } } if (TrySecondaryPower(out power)) { return(power); } if (TryPrimaryPower(out power)) { return(power); } if (IsNoPrimary) { // Stay away from hostile units when Regen skills are on cooldown and under [50] Spirit if (Skills.Monk.BlindingFlash.IsActive && Legendary.TheLawsOfSeph.IsEquipped || Skills.Monk.MysticAlly.IsActive && Runes.Monk.AirAlly.IsActive) { var regenOnCooldown = !Skills.Monk.BlindingFlash.CanCast() && !Skills.Monk.MysticAlly.CanCast(); var needResource = Player.PrimaryResource < PrimaryEnergyReserve; if ((regenOnCooldown || needResource) && HostileMonsters.Any(u => u.Distance <= 12f)) { Core.Logger.Log(LogCategory.Routine, "Moving away - Low Spirit - Regen on Cooldown"); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 30f))); } } } return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 20f))); }
public TrinityPower GetBuffPower() { if (Settings.SpiritWalk.UseMode == UseTime.Always && !Player.IsInTown && Skills.WitchDoctor.SpiritWalk.CanCast()) { return(SpiritWalk()); } if (Skills.WitchDoctor.WallOfDeath.CanCast() && IsInCombatOrBeingAttacked) { return(WallOfDeath(TargetUtil.GetBestClusterPoint())); } if (Skills.WitchDoctor.SoulHarvest.CanCast() && HostileMonsters.Any(u => u.Distance < 16f)) { // Refresh the buff time to avoid losing 10 stacks. if (Skills.WitchDoctor.SoulHarvest.TimeSinceUse > 4500) { return(SoulHarvest()); } // Build some stacks if (Skills.WitchDoctor.SoulHarvest.BuffStacks < MaxSoulHarvestStacks) { return(SoulHarvest()); } } return(DefaultBuffPower()); }
public TrinityPower GetOffensivePower() { if (TrySpecialPower(out var power)) { return(power); } if (Core.Buffs.HasCastingShrine) { if (Skills.Monk.BlindingFlash.CanCast() && Legendary.TheLawsOfSeph.IsEquipped && Player.PrimaryResource < Player.PrimaryResourceMax - 165) { return(BlindingFlash()); } if (Skills.Monk.MysticAlly.CanCast() && Runes.Monk.AirAlly.IsActive && Player.PrimaryResource < Player.PrimaryResourceMax - 200) { return(MysticAlly()); } if (Skills.Monk.DashingStrike.CanCast() && !Skills.Monk.DashingStrike.IsLastUsed) { return(DashingStrike(CurrentTarget.Position)); } if (Skills.Monk.WaveOfLight.CanCast()) { return(WaveOfLight(CurrentTarget)); } } if (TrySecondaryPower(out power)) { return(power); } if (TryPrimaryPower(out power)) { return(power); } if (IsNoPrimary) { // Stay away from units for belt to build stacks. if (Legendary.KyoshirosSoul.IsEquipped) { var needStacks = Skills.Monk.SweepingWind.BuffStacks < 3 && Player.PrimaryResourcePct <= 0.75f; var needResource = Player.PrimaryResource < PrimaryEnergyReserve; if ((needStacks || needResource) && HostileMonsters.Any(u => u.Distance <= 12f)) { Core.Logger.Log(LogCategory.Routine, "Moving away to build dem stacks"); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 20f))); } } } // SW Stacks but no mana, or skills cooldown maybe, hang out just outside range of target. Core.Logger.Log(LogCategory.Routine, "Can't cast anything right meow."); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 20f))); }
private bool TryBombard(out TrinityPower trinityPower) { trinityPower = null; // Make sure we cast Bombardment when IronSkin and CoE is Up. // Note iron skin is gated below by Convention of Elements check, if (Player.HasBuff(SNOPower.X1_Crusader_IronSkin)) { TrinityActor target; if (ShouldBombardment(out target)) { trinityPower = Bombardment(target); return(true); } if (ShouldShieldGlare(out target)) { trinityPower = ShieldGlare(target); return(true); } if (IsInCombat && ShouldConsecration()) { trinityPower = Consecration(); return(true); } } var eliteExists = HostileMonsters.Any(u => u.IsElite && !TrinityCombat.Weighting.ShouldIgnore(u)); // Provoke with Votoyias spiker. var inProvokeRange = !eliteExists || CurrentTarget != null && CurrentTarget.IsElite && CurrentTarget.Distance < 15f; if (!ShouldWaitForConventionofElements(Skills.Crusader.Provoke, Element.Physical, 0, 1000) && Skills.Crusader.Provoke.CanCast() && inProvokeRange) { trinityPower = Provoke(); return(true); } // Wait for CoE to Cast Damage CD's var isCastWindow = !ShouldWaitForConventionofElements(Skills.Crusader.Bombardment, Element.Physical, 1500, 1000); var isTargetCloseEnough = !eliteExists || CurrentTarget != null && CurrentTarget.IsElite && CurrentTarget.Distance < 20f; if (Skills.Crusader.Bombardment.CanCast() && (ShouldBombardWheneverPossible && isTargetCloseEnough || isCastWindow)) { if (ShouldIronSkin()) { trinityPower = IronSkin(); return(true); } } return(false); }
protected override bool ShouldIronSkin() { if (!Skills.Crusader.IronSkin.CanCast()) { return(false); } if (Player.HasBuff(SNOPower.X1_Crusader_IronSkin)) { return(false); } return(HostileMonsters.Any(u => u.Distance < 80f)); }
public TrinityPower GetBuffPower() { if (ShouldHorrify()) { return(Horrify()); } if (Settings.SpiritWalk.UseMode == UseTime.Always && !Player.IsInTown && Skills.WitchDoctor.SpiritWalk.CanCast()) { return(SpiritWalk()); } var closeUnit = HostileMonsters.FirstOrDefault(u => u.Distance < 16f); if (closeUnit != null && !Player.IsInTown && !IsInCombat && Skills.WitchDoctor.SoulHarvest.CanCast()) { if (Settings.HarvestModeOOC == HarvestMode.NonStop) { if (Skills.WitchDoctor.Haunt.CanCast() && Skills.WitchDoctor.Haunt.TimeSinceUse > 1000) { return(Haunt(closeUnit)); } if (HostileMonsters.Any(u => u.Distance < 16f && u.HasDebuff(SNOPower.Witchdoctor_Haunt))) { return(SoulHarvest()); } } // Refresh the buff time to avoid losing 10 stacks. if (Skills.WitchDoctor.SoulHarvest.TimeSinceUse > 4500) { return(SoulHarvest()); } // Build some stacks if (Skills.WitchDoctor.SoulHarvest.BuffStacks < 10) { return(SoulHarvest()); } } return(DefaultBuffPower()); }
public TrinityPower GetOffensivePower() { TrinityPower power; Vector3 position; if (TrySpecialPower(out power)) { return(power); } if (Core.Buffs.HasCastingShrine) { if (Skills.Monk.BlindingFlash.CanCast() && Legendary.TheLawsOfSeph.IsEquipped && Player.PrimaryResource < Player.PrimaryResourceMax - 165) { return(BlindingFlash()); } if (Skills.Monk.MysticAlly.CanCast() && Runes.Monk.AirAlly.IsActive && Player.PrimaryResource < Player.PrimaryResourceMax - 200) { return(MysticAlly()); } if (Skills.Monk.DashingStrike.CanCast() && !Skills.Monk.DashingStrike.IsLastUsed) { return(DashingStrike(CurrentTarget.Position)); } if (Skills.Monk.LashingTailKick.CanCast()) { return(LashingTailKick(CurrentTarget)); } } // With sweeping armada try to keep distance in the sweet spot between 10-15yd if (Runes.Monk.SweepingArmada.IsActive) { var enoughTimePassed = SpellHistory.TimeSinceUse(SNOPower.Walk).TotalMilliseconds > 500; var isSoloElite = TargetUtil.ElitesInRange(25f) == 1 && !AnyUnitsInRange(25f); if (enoughTimePassed && isSoloElite && CurrentTarget.RadiusDistance <= 10f && !IsStuck) { if (Avoider.TryGetSafeSpot(out position, 12f + CurrentTarget.CollisionRadius, 30f, CurrentTarget.Position)) { Core.Logger.Log(LogCategory.Routine, $"Adjusting Distance for Sweeping Armarda RDist={CurrentTarget.RadiusDistance} Dist={ZetaDia.Me.Position.Distance(CurrentTarget.Position)}"); return(Walk(position, 2f)); } } } if (TrySecondaryPower(out power)) { return(power); } if (TryPrimaryPower(out power)) { return(power); } if (IsNoPrimary) { // Stay away from hostile units when Regen skills are on cooldown and under [50] Spirit if (Skills.Monk.BlindingFlash.IsActive && Legendary.TheLawsOfSeph.IsEquipped || Skills.Monk.MysticAlly.IsActive && Runes.Monk.AirAlly.IsActive) { var regenOnCooldown = !Skills.Monk.BlindingFlash.CanCast() && !Skills.Monk.MysticAlly.CanCast(); var needResource = Player.PrimaryResource < PrimaryEnergyReserve; if ((regenOnCooldown || needResource) && HostileMonsters.Any(u => u.Distance <= 12f)) { Core.Logger.Log(LogCategory.Routine, "Moving away - Low Spirit - Regen on Cooldown"); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 30f))); } } } return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 25f))); }
public bool AnyUnitsInRange(float range) => HostileMonsters.Any(u => u.Position.Distance(Player.Position) < range);
//public static class FireballTracker //{ // public static Dictionary<int,TrinityActor> Fireballs = new Dictionary<int, TrinityActor>(); // private static DateTime _lastUseTime; // public static bool IsFireballPending { get; private set; } // public const int FireballSnoId = (int) SNOActor.zoltunKulle_fieryBoulder_model; // public const int PendingTimeoutMs = 1000; // public static void Update() // { // var lastUseTime = SpellHistory.PowerLastUsedTime(SNOPower.Monk_LashingTailKick); // var msSinceUse = DateTime.UtcNow.Subtract(lastUseTime).TotalMilliseconds; // if (lastUseTime != _lastUseTime) // { // Core.Logger.Log($"New LTK cast, waiting for fireball"); // IsFireballPending = msSinceUse < PendingTimeoutMs; // _lastUseTime = lastUseTime; // } // if (msSinceUse > PendingTimeoutMs && IsFireballPending) // { // Core.Logger.Log($"Fireball wait timed out"); // IsFireballPending = false; // } // foreach (var actor in Core.Actors.AllRActors.Where(a => a.Type == TrinityObjectType.ClientEffect)) // { // if (actor.ActorSnoId == FireballSnoId && !Fireballs.ContainsKey(actor.AnnId)) // { // Core.Logger.Log($"New Fireball Found Delay:{msSinceUse}ms"); // IsFireballPending = false; // Fireballs.Add(actor.AnnId, actor); // } // } // foreach (var fireball in Fireballs.ToList().Where(fireball => !fireball.Value.IsValid)) // { // Fireballs.Remove(fireball.Key); // } // } //} /* Speed Farm Solo Variant tested @ GR75 * [Trinity 2.55.668] ------ Equipped Non-Set Legendaries: Items=8, Sets=1 ------ * [Trinity 2.55.668] Item: SpiritStone: Gyana Na Kashu (222169) is Equipped * [Trinity 2.55.668] Item: Belt: Kyoshiro's Soul (298136) is Equipped * [Trinity 2.55.668] Item: Boots: Rivera Dancers (197224) is Equipped * [Trinity 2.55.668] Item: Ring: Obsidian Ring of the Zodiac (212588) is Equipped * [Trinity 2.55.668] Item: Ring: Unity (212581) is Equipped * [Trinity 2.55.668] Item: Bracer: Nemesis Bracers (298121) is Equipped * [Trinity 2.55.668] Item: FistWeapon: Scarbringer (130557) is Equipped * [Trinity 2.55.668] Item: FistWeapon: Vengeful Wind (403775) is Equipped * [Trinity 2.55.668] ------ Equipped in Kanai's Cube: Items=3 ------ * [Trinity 2.55.668] Item: SpiritStone: The Laws of Seph (299454) is Equipped * [Trinity 2.55.668] Item: Ring: Ring of Royal Grandeur (298094) is Equipped * [Trinity 2.55.668] Item: Sword: In-geom (410946) is Equipped * [Trinity 2.55.668] ------ Set: Monkey King's Garb : 5/6 Equipped. ActiveBonuses=3/3 ------ * [Trinity 2.55.668] Item: Shoulder: Sunwuko's Balance (336175) is Equipped * [Trinity 2.55.668] Item: Gloves: Sunwuko's Paws (336172) is Equipped * [Trinity 2.55.668] Item: Amulet: Sunwuko's Shines (336174) is Equipped * [Trinity 2.55.668] Item: Legs: Sunwuko's Leggings (429075) is Equipped * [Trinity 2.55.668] Item: Chest: Sunwuko's Soul (429167) is Equipped * [Trinity 2.55.668] ------ Active Skills / Runes ------ * [Trinity 2.55.668] Skill: Lashing Tail Kick Rune=Sweeping Armada Type=Spender * [Trinity 2.55.668] Skill: Blinding Flash Rune=Faith in the Light Type=Other * [Trinity 2.55.668] Skill: Dashing Strike Rune=Way of the Falling Star Type=Other * [Trinity 2.55.668] Skill: Mantra of Salvation Rune=Agility Type=Other * [Trinity 2.55.668] Skill: Sweeping Wind Rune=Inner Storm Type=Spender * [Trinity 2.55.668] Skill: Epiphany Rune=Desert Shroud Type=Other * [Trinity 2.55.668] ------ Passives ------ * [Trinity 2.55.668] Passive: Exalted Soul * [Trinity 2.55.668] Passive: Beacon of Ytar * [Trinity 2.55.668] Passive: Harmony * [Trinity 2.55.668] Passive: Momentum * * [Trinity 2.55.668] ------ Equipped Non-Set Legendaries: Items=6, Sets=2 ------ * [Trinity 2.55.668] Item: SpiritStone: Gyana Na Kashu (222169) is Equipped * [Trinity 2.55.668] Item: Belt: The Witching Hour (193670) is Equipped * [Trinity 2.55.668] Item: Boots: Rivera Dancers (197224) is Equipped * [Trinity 2.55.668] Item: Bracer: Spirit Guards (430290) is Equipped * [Trinity 2.55.668] Item: FistWeapon: Crystal Fist (175939) is Equipped * [Trinity 2.55.668] Item: FistWeapon: Scarbringer (130557) is Equipped * [Trinity 2.55.668] ------ Equipped in Kanai's Cube: Items=3 ------ * [Trinity 2.55.668] Item: SpiritStone: The Laws of Seph (299454) is Equipped * [Trinity 2.55.668] Item: Ring: Ring of Royal Grandeur (298094) is Equipped * [Trinity 2.55.668] Item: Daibo: Flying Dragon (197065) is Equipped * [Trinity 2.55.668] ------ Set: Bastions of Will : 2/2 Equipped. ActiveBonuses=1/1 ------ * [Trinity 2.55.668] Item: Ring: Focus (332209) is Equipped * [Trinity 2.55.668] Item: Ring: Restraint (332210) is Equipped * [Trinity 2.55.668] ------ Set: Monkey King's Garb : 5/6 Equipped. ActiveBonuses=3/3 ------ * [Trinity 2.55.668] Item: Shoulder: Sunwuko's Balance (336175) is Equipped * [Trinity 2.55.668] Item: Gloves: Sunwuko's Paws (336172) is Equipped * [Trinity 2.55.668] Item: Amulet: Sunwuko's Shines (336174) is Equipped * [Trinity 2.55.668] Item: Legs: Sunwuko's Leggings (429075) is Equipped * [Trinity 2.55.668] Item: Chest: Sunwuko's Soul (429167) is Equipped * [Trinity 2.55.668] ------ Active Skills / Runes ------ * [Trinity 2.55.668] Skill: Fists of Thunder Rune=Quickening Type=Generator * [Trinity 2.55.668] Skill: Lashing Tail Kick Rune=Sweeping Armada Type=Spender * [Trinity 2.55.668] Skill: Blinding Flash Rune=Faith in the Light Type=Other * [Trinity 2.55.668] Skill: Dashing Strike Rune=Blinding Speed Type=Other * [Trinity 2.55.668] Skill: Mantra of Salvation Rune=Agility Type=Other * [Trinity 2.55.668] Skill: Sweeping Wind Rune=Inner Storm Type=Spender * [Trinity 2.55.668] ------ Passives ------ * [Trinity 2.55.668] Passive: Exalted Soul * [Trinity 2.55.668] Passive: Seize the Initiative * [Trinity 2.55.668] Passive: The Guardian's Path * [Trinity 2.55.668] Passive: Beacon of Ytar * [Trinity 2.55.668][Routine] Need Spirit Gaurds Buff * */ public TrinityPower GetOffensivePower() { // 853: PowerBuff0VisualEffectNone (-3243) [ PowerSnoId: ItemPassive_Unique_Ring_903_x1: 402411 ] i:1 f:0 Value=1 // 865: PowerBuff2VisualEffectNone (-3231) [ PowerSnoId: ItemPassive_Unique_Ring_922_x1: 402461 ] i:0 f:0 Value=0 // 588: BuffIconStartTick2(-3508)[PowerSnoId: ItemPassive_Unique_Gem_018_x1: 428348] i: 79817 f: 0 Value = 79817 // 863: PowerBuff1VisualEffectD (-3233) [ PowerSnoId: Monk_LashingTailKick: 111676 ] i:1 f:0 Value=1 TrinityPower power; Vector3 position; //FireballTracker.Update(); //if (FireballTracker.IsFireballPending) //{ // Core.Logger.Log("Waiting for fireball"); // return new TrinityPower(SNOPower.None); //} if (TrySpecialPower(out power)) { return(power); } if (Core.Buffs.HasCastingShrine) { if (Skills.Monk.DashingStrike.CanCast() && !Skills.Monk.DashingStrike.IsLastUsed) { return(DashingStrike(CurrentTarget.Position)); } if (Skills.Monk.LashingTailKick.CanCast()) { return(LashingTailKick(CurrentTarget)); } } if (ShouldRefreshSpiritGuardsBuff) { Core.Logger.Log(LogCategory.Routine, "Need Spirit Gaurds Buff"); if (TryPrimaryClosestTarget(out power)) { return(power); } } if (ShouldRefreshBastiansGenerator) { Core.Logger.Log(LogCategory.Routine, "Need Bastians Buff"); if (TryPrimaryClosestTarget(out power)) { return(power); } } // With sweeping armada try to keep distance in the sweet spot between 10-15yd if (Runes.Monk.SweepingArmada.IsActive) { var enoughTimePassed = SpellHistory.TimeSinceUse(SNOPower.Walk).TotalMilliseconds > 500; var isSoloElite = TargetUtil.ElitesInRange(25f) == 1 && !AnyUnitsInRange(25f); if (enoughTimePassed && isSoloElite && CurrentTarget.RadiusDistance <= 10f && !IsStuck) { if (Avoider.TryGetSafeSpot(out position, 12f + CurrentTarget.CollisionRadius, 30f, CurrentTarget.Position)) { Core.Logger.Log(LogCategory.Routine, $"Adjusting Distance for Sweeping Armarda RDist={CurrentTarget.RadiusDistance} Dist={ZetaDia.Me.Position.Distance(CurrentTarget.Position)}"); return(Walk(position, 2f)); } } } if (TrySecondaryPower(out power)) { return(power); } if (TryPrimaryPower(out power)) { return(power); } if (IsNoPrimary) { // Stay away from units for belt to build stacks. if (Legendary.KyoshirosSoul.IsEquipped) { var needStacks = Skills.Monk.SweepingWind.BuffStacks < 3 && Player.PrimaryResourcePct <= 0.75f; var needResource = Player.PrimaryResource < PrimaryEnergyReserve; if ((needStacks || needResource) && HostileMonsters.Any(u => u.Distance <= 12f)) { Core.Logger.Log(LogCategory.Routine, "Moving away to build stacks"); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 30f))); } } } // SW Stacks but no mana, or skills cooldown maybe, hang out just outside range of target. Core.Logger.Log(LogCategory.Routine, "Can't cast anything."); return(Walk(TargetUtil.GetLoiterPosition(CurrentTarget, 25f))); }
public TrinityPower GetBuffPower() { Vector3 position; if (ShouldSummonZombieDogs(out position)) { return(IsInCombat ? SummonZombieDogs(position) : SummonZombieDogs()); } if (ShouldGargantuan(out position)) { return(IsInCombat ? Gargantuan(position) : Gargantuan()); } if (Settings.SpiritWalk.UseMode == UseTime.Always && !Player.IsInTown && Skills.WitchDoctor.SpiritWalk.CanCast()) { return(SpiritWalk()); } if (ShouldSpiritWalk()) { return(SpiritWalk()); } if (ShouldFetishArmy()) { return(FetishArmy()); } if (Skills.WitchDoctor.WallOfDeath.CanCast() && IsInCombatOrBeingAttacked) { return(WallOfDeath(TargetUtil.GetBestClusterPoint())); } if (Skills.WitchDoctor.SoulHarvest.CanCast() && (!IsChannellingFirebats || Player.CurrentHealthPct < 0.4f) && HostileMonsters.Any(u => u.Distance < 16f)) { // Refresh the buff time to avoid losing 10 stacks. if (Skills.WitchDoctor.SoulHarvest.TimeSinceUse > 4500) { return(SoulHarvest()); } // Build some stacks if (Skills.WitchDoctor.SoulHarvest.BuffStacks < MaxSoulHarvestStacks) { return(SoulHarvest()); } } return(null); }
public TrinityPower GetMovementPower(Vector3 destination) { // Leap out of combat for the defensive bonuses. if (Skills.Barbarian.Leap.CanCast() && (!Player.HasBuff(SNOPower.Barbarian_Leap) || Player.CurrentHealthPct > 0.35f) && !Player.IsInTown && HostileMonsters.Any(u => u.Distance < 20f)) { return(Leap(destination)); } return(Walk(destination)); }
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); }
protected override bool ShouldTeleport(out Vector3 position) { position = Vector3.Zero; var skill = Skills.Wizard.Teleport; var affixOnPlayer = Core.Avoidance.InAvoidance(ZetaDia.Me.Position); var healthIsLow = Player.CurrentHealthPct < Settings.TeleportHealthEmergency; var archonHealthIsLow = Player.CurrentHealthPct < Settings.ArchonTeleportHealthEmergency; var anyElitesinRange = TargetUtil.AnyElitesInRange(Settings.TeleportEliteKiteRange); var anyMobsInRange = TargetUtil.AnyMobsInRangeOfPosition(Player.Position, Settings.TeleportTrashKiteRange, Settings.TeleportTrashInRangeCount); if (!skill.CanCast()) { return(false); } if (Player.IsChannelling || !Player.IsChannelling) { if (anyElitesinRange || anyMobsInRange || healthIsLow || affixOnPlayer) { Core.Logger.Log(LogCategory.Routine, $"Close Elites: {anyElitesinRange}, Mobs: {anyMobsInRange}, Health: {healthIsLow}, Affix: {affixOnPlayer}"); } return(true); } Avoider.TryGetSafeSpot(out position, Settings.TeleportKiteMinDistance, Settings.TeleportKiteMaxDistance, ZetaDia.Me.Position, node => !HostileMonsters.Any(m => m.Position.Distance(node.NavigableCenter) < 15f)); return(position != Vector3.Zero); }