/// <summary> /// This will find a safe place to stand in both Kiting and Avoidance situations /// </summary> /// <param name="isStuck"></param> /// <param name="stuckAttempts"></param> /// <param name="dangerPoint"></param> /// <param name="shouldKite"></param> /// <param name="avoidDeath"></param> /// <returns></returns> internal static Vector3 FindSafeZone(bool isStuck, int stuckAttempts, Vector3 dangerPoint, bool shouldKite = false, IEnumerable <TrinityCacheObject> monsterList = null, bool avoidDeath = false) { if (!isStuck) { if (shouldKite && DateTime.UtcNow.Subtract(lastFoundSafeSpot).TotalMilliseconds <= 1500 && lastSafeZonePosition != Vector3.Zero) { return(lastSafeZonePosition); } else if (DateTime.UtcNow.Subtract(lastFoundSafeSpot).TotalMilliseconds <= 800 && lastSafeZonePosition != Vector3.Zero) { return(lastSafeZonePosition); } hasEmergencyTeleportUp = ( // Leap is available (!PlayerStatus.IsIncapacitated && CombatBase.CanCast(SNOPower.Barbarian_Leap)) || // Whirlwind is available (!PlayerStatus.IsIncapacitated && CombatBase.CanCast(SNOPower.Barbarian_Whirlwind) && ((PlayerStatus.PrimaryResource >= 10 && !PlayerStatus.WaitingForReserveEnergy) || PlayerStatus.PrimaryResource >= Trinity.MinEnergyReserve)) || // Tempest rush is available (!PlayerStatus.IsIncapacitated && CombatBase.CanCast(SNOPower.Monk_TempestRush) && ((PlayerStatus.PrimaryResource >= 20 && !PlayerStatus.WaitingForReserveEnergy) || PlayerStatus.PrimaryResource >= Trinity.MinEnergyReserve)) || // Teleport is available (!PlayerStatus.IsIncapacitated && CombatBase.CanCast(SNOPower.Wizard_Teleport) && PlayerStatus.PrimaryResource >= 15) || // Archon Teleport is available (!PlayerStatus.IsIncapacitated && CombatBase.CanCast(SNOPower.Wizard_Archon_Teleport)) ); // Wizards can look for bee stings in range and try a wave of force to dispel them if (!shouldKite && PlayerStatus.ActorClass == ActorClass.Wizard && Hotbar.Contains(SNOPower.Wizard_WaveOfForce) && PlayerStatus.PrimaryResource >= 25 && DateTime.UtcNow.Subtract(CacheData.AbilityLastUsed[SNOPower.Wizard_WaveOfForce]).TotalMilliseconds >= CombatBase.GetSNOPowerUseDelay(SNOPower.Wizard_WaveOfForce) && !PlayerStatus.IsIncapacitated && CacheData.TimeBoundAvoidance.Count(u => u.ActorSNO == 5212 && u.Position.Distance(PlayerStatus.Position) <= 15f) >= 2 && ( //HotbarSkills.PassiveSkills.Contains(SNOPower.Wizard_Passive_CriticalMass) || PowerManager.CanCast(SNOPower.Wizard_WaveOfForce))) { ZetaDia.Me.UsePower(SNOPower.Wizard_WaveOfForce, Vector3.Zero, PlayerStatus.WorldDynamicID, -1); } } float highestWeight = 0f; if (monsterList == null) { monsterList = new List <TrinityCacheObject>(); } //Vector3 vBestLocation = FindSafeZone(dangerPoint, shouldKite, isStuck, monsterList, avoidDeath); Vector3 vBestLocation = MainFindSafeZone(dangerPoint, shouldKite, isStuck, monsterList, avoidDeath); highestWeight = 1; // Loop through distance-range steps if (highestWeight <= 0) { return(vBestLocation); } lastFoundSafeSpot = DateTime.UtcNow; lastSafeZonePosition = vBestLocation; return(vBestLocation); }
/// <summary> /// This will find a safe place to stand in both Kiting and Avoidance situations /// </summary> /// <param name="isStuck"></param> /// <param name="stuckAttempts"></param> /// <param name="dangerPoint"></param> /// <param name="shouldKite"></param> /// <param name="avoidDeath"></param> /// <returns></returns> internal static Vector3 FindSafeZone(bool isStuck, int stuckAttempts, Vector3 dangerPoint, bool shouldKite = false, IEnumerable <TrinityCacheObject> monsterList = null, bool avoidDeath = false) { // Handle The Butcher's Lair var butcherFloorPanels = CacheData.TimeBoundAvoidance.Where(aoe => DataDictionary.ButcherFloorPanels.Contains(aoe.ActorSNO)).ToList(); if (butcherFloorPanels.Any()) { foreach (var safePoint in DataDictionary.ButcherPanelPositions.OrderBy(p => p.Value.Distance2DSqr(Trinity.Player.Position))) { // Floor panel with fire animation was added to cache if (butcherFloorPanels.Any(p => p.ActorSNO == safePoint.Key && p.Position.Distance2DSqr(safePoint.Value) <= 15f * 15f)) { continue; } // floor panel position is in Butcher animation avoidance (charging, chain hook) if (CacheData.TimeBoundAvoidance.Any(aoe => aoe.Position.Distance2D(safePoint.Value) < aoe.Radius)) { continue; } // no avoidance object in cache, this point is safe return(safePoint.Value); } // Don't fall back to regular avoidance return(Vector3.Zero); } if (!isStuck) { if (shouldKite && DateTime.UtcNow.Subtract(lastFoundSafeSpot).TotalMilliseconds <= 1500 && lastSafeZonePosition != Vector3.Zero) { return(lastSafeZonePosition); } if (DateTime.UtcNow.Subtract(lastFoundSafeSpot).TotalMilliseconds <= 800 && lastSafeZonePosition != Vector3.Zero) { return(lastSafeZonePosition); } hasEmergencyTeleportUp = (!Player.IsIncapacitated && ( // Leap is available (CombatBase.CanCast(SNOPower.Barbarian_Leap)) || // Whirlwind is available (CombatBase.CanCast(SNOPower.Barbarian_Whirlwind) && ((Player.PrimaryResource >= 10 && !CombatBase.IsWaitingForSpecial) || Player.PrimaryResource >= Trinity.MinEnergyReserve)) || // Tempest rush is available (CombatBase.CanCast(SNOPower.Monk_TempestRush) && ((Player.PrimaryResource >= 20 && !CombatBase.IsWaitingForSpecial) || Player.PrimaryResource >= Trinity.MinEnergyReserve)) || // Teleport is available (CombatBase.CanCast(SNOPower.Wizard_Teleport) && Player.PrimaryResource >= 15) || // Archon Teleport is available (CombatBase.CanCast(SNOPower.Wizard_Archon_Teleport)) )); // Wizards can look for bee stings in range and try a wave of force to dispel them if (!shouldKite && Player.ActorClass == ActorClass.Wizard && CombatBase.CanCast(SNOPower.Wizard_WaveOfForce) && !Player.IsIncapacitated && CacheData.TimeBoundAvoidance.Count(u => u.ActorSNO == 5212 && u.Position.Distance(Player.Position) <= 15f) >= 2 && ( //HotbarSkills.PassiveSkills.Contains(SNOPower.Wizard_Passive_CriticalMass) || PowerManager.CanCast(SNOPower.Wizard_WaveOfForce))) { ZetaDia.Me.UsePower(SNOPower.Wizard_WaveOfForce, Vector3.Zero, Player.WorldDynamicID, -1); } } float highestWeight = 0f; if (monsterList == null) { monsterList = new List <TrinityCacheObject>(); } //Vector3 vBestLocation = FindSafeZone(dangerPoint, shouldKite, isStuck, monsterList, avoidDeath); Vector3 vBestLocation = MainFindSafeZone(dangerPoint, shouldKite, isStuck, monsterList, avoidDeath); highestWeight = 1; // Loop through distance-range steps if (highestWeight <= 0) { return(vBestLocation); } lastFoundSafeSpot = DateTime.UtcNow; lastSafeZonePosition = vBestLocation; return(vBestLocation); }
/// <summary> /// Performs basic checks to see if we have and can cast a power (hotbar, power manager). Checks use timer for Wiz, DH, Monk /// </summary> public bool CanCast(CombatBase.CanCastFlags flags = CombatBase.CanCastFlags.All) { return(CombatBase.CanCast(SNOPower, flags)); }
/// <summary> /// Check if skill can and should be cast /// </summary> public bool CanCast() { return(CombatBase.CanCast(this)); }