public AvoidanceValue() { Type = AvoidanceType.None; Health = 0.00d; Radius = 0.00d; Weight = 1; }
public CacheAvoidance(AvoidanceType type, int snoid, int raguid, int acdguid, Vector3 position, string name = "") : base(snoid, raguid, acdguid, position, name) { AvoidanceType = type; AvoidanceValue = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)type]; targetType = TargetType.Avoidance; }
public int Weight; //How "Deadly" #endregion Fields #region Constructors public AvoidanceValue(AvoidanceType type, double hp, double radius, int weight) { Type = type; Health = hp; Radius = radius; Weight = weight; }
public int Weight; //How "Deadly" public AvoidanceValue(AvoidanceType type, double hp, double radius, int weight) { Type = type; Health = hp; Radius = radius; Weight = weight; }
public AvoidanceValue() { Type = AvoidanceType.None; Health = 0.00d; Radius = 0.00d; Weight = 1; RemovalSeconds = -1; }
public CacheAvoidance(CacheObject parent, AvoidanceType type, Ray R, double speed) : base(parent) { this.AvoidanceType=type; this.ray_=R; this.Speed=speed; this.projectile_startPosition=base.Position; }
public AvoidanceValue(AvoidanceType type, double hp, double radius, int weight, int secondsRemove = -1) { Type = type; Health = hp; Radius = radius; Weight = weight; RemovalSeconds = secondsRemove; }
public int Weight; //How "Deadly" #endregion Fields #region Constructors public AvoidanceValue(AvoidanceType type, double hp, double radius, int weight, int secondsRemove=-1) { Type = type; Health = hp; Radius = radius; Weight = weight; RemovalSeconds=secondsRemove; }
public CacheAvoidance(CacheObject parent, AvoidanceType avoidancetype) : base(parent) { this.AvoidanceType=avoidancetype; //Special avoidances that require additional loops before removal if ((AvoidanceType.TreeSpore|AvoidanceType.GrotesqueExplosion).HasFlag(this.AvoidanceType)) this.RefreshRemovalCounter=30; }
public CacheAvoidance(CacheObject parent, AvoidanceType type, Ray R, double speed) : base(parent) { AvoidanceType = type; AvoidanceValue = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)type]; ray_ = R; Speed = speed; projectile_startPosition = base.Position; }
public CourseCorrection(GameObject gameObject, float radiusOffset) { this.gameObject = gameObject; this.origin = gameObject.GetComponent <Rigidbody>().transform.position; this.radiusOffset = radiusOffset; this.avoidanceType = AvoidanceType.Unknown; this.vehicleType = Vehicle.Type.None; this.obstacleType = Obstacle.Type.None; this.weaponType = Weapon.Type.None; }
public CacheAvoidance(CacheObject parent, AvoidanceType avoidancetype) : base(parent) { AvoidanceType = avoidancetype; AvoidanceValue = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)avoidancetype]; RefreshRemovalCounter = AvoidanceValue.RemovalSeconds; //Special avoidances that require additional loops before removal (note: the loops are checked every 150ms, but obstacles are checked twice!) //if (AvoidanceType.HasFlag(AvoidanceType.TreeSpore) && SNOID == 6578) // RefreshRemovalCounter = 75; //else if (AvoidanceType.HasFlag(AvoidanceType.GrotesqueExplosion)) // RefreshRemovalCounter = 25; //else if (AvoidanceType.HasFlag(AvoidanceType.DemonicForge)) // RefreshRemovalCounter = 10; }
internal static bool IgnoringAvoidanceType(AvoidanceType thisAvoidance) { if (!FunkyBaseExtension.Settings.Avoidance.AttemptAvoidanceMovements) { return(true); } double dThisHealthAvoid = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; if (dThisHealthAvoid == 0d) { return(true); } return(false); }
///<summary> ///Tests the given avoidance type to see if it should be ignored either due to a buff or if health is greater than the avoidance HP. ///</summary> internal static bool IgnoreAvoidance(AvoidanceType thisAvoidance) { double dThisHealthAvoid = Bot.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; if (!Bot.Character.Data.CriticalAvoidance) { //Not Critical Avoidance, should we be in total ignorance because of a buff? // Monks with Serenity up ignore all AOE's if (Bot.Character.Class.AC == ActorClass.Monk && Bot.Character.Class.HotBar.HotbarPowers.Contains(SNOPower.Monk_Serenity) && Bot.Character.Class.HotBar.HasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune return(true); } // Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud //else if (Bot.Character_.Class.AC==ActorClass.WitchDoctor // &&Bot.Character_.Class.HotBar.HotbarPowers.Contains(SNOPower.Witchdoctor_SpiritWalk) // &&(!Bot.Character_.Class.HotBar.HasBuff(SNOPower.Witchdoctor_SpiritWalk)&&Bot.Character_.Class.Abilities[SNOPower.Witchdoctor_SpiritWalk].AbilityUseTimer())||Bot.Character_.Class.HotBar.HasBuff(SNOPower.Witchdoctor_SpiritWalk)) //{ // switch (thisAvoidance) // { // case AvoidanceType.Frozen: // case AvoidanceType.ArcaneSentry: // case AvoidanceType.Dececrator: // case AvoidanceType.PlagueCloud: // return true; // } //} if (Bot.Character.Class.AC == ActorClass.Barbarian && Bot.Character.Class.HotBar.HotbarPowers.Contains(SNOPower.Barbarian_WrathOfTheBerserker) && Bot.Character.Class.HotBar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return(true); } } } //Only procedee if health percent is necessary for avoidance! return(dThisHealthAvoid < Bot.Character.Data.dCurrentHealthPct); }
public static bool IsPlayerImmune(AvoidanceType avoidanceType) { // Item based immunity switch (avoidanceType) { case AvoidanceType.PoisonTree: case AvoidanceType.PlagueCloud: case AvoidanceType.PoisonEnchanted: case AvoidanceType.PlagueHand: if (Legendary.MarasKaleidoscope.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because MarasKaleidoscope is equipped", avoidanceType); return true; } break; case AvoidanceType.AzmoFireball: case AvoidanceType.DiabloRingOfFire: case AvoidanceType.DiabloMeteor: case AvoidanceType.ButcherFloorPanel: case AvoidanceType.Mortar: case AvoidanceType.MageFire: case AvoidanceType.MoltenTrail: case AvoidanceType.MoltenBall: case AvoidanceType.ShamanFire: if (Legendary.TheStarOfAzkaranth.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TheStarofAzkaranth is equipped", avoidanceType); return true; } break; case AvoidanceType.FrozenPulse: case AvoidanceType.IceBall: case AvoidanceType.IceTrail: // Ignore if both items are equipped if (Legendary.TalismanOfAranoch.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TalismanofAranoch is equipped", avoidanceType); return true; } break; case AvoidanceType.Orbiter: case AvoidanceType.Thunderstorm: if (Legendary.XephirianAmulet.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because XephirianAmulet is equipped", avoidanceType); return true; } break; case AvoidanceType.Arcane: if (Legendary.CountessJuliasCameo.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because CountessJuliasCameo is equipped", avoidanceType); return true; } break; } // Set based immunity if (Sets.BlackthornesBattlegear.IsMaxBonusActive) { var blackthornsImmunity = new HashSet<AvoidanceType> { AvoidanceType.Desecrator, AvoidanceType.MoltenBall, AvoidanceType.MoltenCore, AvoidanceType.MoltenTrail, AvoidanceType.PlagueHand }; if (blackthornsImmunity.Contains(avoidanceType)) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because BlackthornesBattlegear is equipped", avoidanceType); return true; } } return false; }
public static float GetAvoidanceRadius(AvoidanceType type, float defaultValue) { switch (type) { case AvoidanceType.Arcane: return Trinity.Settings.Combat.AvoidanceRadius.Arcane; case AvoidanceType.AzmodanBody: return Trinity.Settings.Combat.AvoidanceRadius.AzmoBodies; case AvoidanceType.AzmoFireball: return Trinity.Settings.Combat.AvoidanceRadius.AzmoFireBall; case AvoidanceType.AzmodanPool: return Trinity.Settings.Combat.AvoidanceRadius.AzmoPools; case AvoidanceType.BeastCharge: return 1; case AvoidanceType.BeeWasp: return Trinity.Settings.Combat.AvoidanceRadius.BeesWasps; case AvoidanceType.Belial: return Trinity.Settings.Combat.AvoidanceRadius.Belial; case AvoidanceType.ButcherFloorPanel: return Trinity.Settings.Combat.AvoidanceRadius.ButcherFloorPanel; case AvoidanceType.Desecrator: return Trinity.Settings.Combat.AvoidanceRadius.Desecrator; case AvoidanceType.DiabloMeteor: return Trinity.Settings.Combat.AvoidanceRadius.DiabloMeteor; case AvoidanceType.DiabloPrison: return Trinity.Settings.Combat.AvoidanceRadius.DiabloPrison; case AvoidanceType.DiabloRingOfFire: return Trinity.Settings.Combat.AvoidanceRadius.DiabloRingOfFire; case AvoidanceType.FireChains: return 1; case AvoidanceType.FrozenPulse: return Trinity.Settings.Combat.AvoidanceRadius.FrozenPulse; case AvoidanceType.GhomGas: return Trinity.Settings.Combat.AvoidanceRadius.GhomGas; case AvoidanceType.Grotesque: return Trinity.Settings.Combat.AvoidanceRadius.Grotesque; case AvoidanceType.IceBall: return Trinity.Settings.Combat.AvoidanceRadius.IceBalls; case AvoidanceType.IceTrail: return Trinity.Settings.Combat.AvoidanceRadius.IceTrail; case AvoidanceType.Orbiter: return Trinity.Settings.Combat.AvoidanceRadius.Orbiter; case AvoidanceType.MageFire: return Trinity.Settings.Combat.AvoidanceRadius.MageFire; case AvoidanceType.MaghdaProjectille: return Trinity.Settings.Combat.AvoidanceRadius.MaghdaProjectille; case AvoidanceType.MoltenCore: return Trinity.Settings.Combat.AvoidanceRadius.MoltenCore; case AvoidanceType.MoltenTrail: return Trinity.Settings.Combat.AvoidanceRadius.MoltenTrail; case AvoidanceType.Mortar: return defaultValue; case AvoidanceType.MoltenBall: return Trinity.Settings.Combat.AvoidanceRadius.MoltenBall; case AvoidanceType.PlagueCloud: return Trinity.Settings.Combat.AvoidanceRadius.PlagueCloud; case AvoidanceType.PlagueHand: return Trinity.Settings.Combat.AvoidanceRadius.PlagueHands; case AvoidanceType.PoisonTree: return Trinity.Settings.Combat.AvoidanceRadius.PoisonTree; case AvoidanceType.PoisonEnchanted: return Trinity.Settings.Combat.AvoidanceRadius.PoisonEnchanted; case AvoidanceType.ShamanFire: return Trinity.Settings.Combat.AvoidanceRadius.ShamanFire; case AvoidanceType.Thunderstorm: return Trinity.Settings.Combat.AvoidanceRadius.Thunderstorm; case AvoidanceType.Wormhole: return Trinity.Settings.Combat.AvoidanceRadius.Wormhole; case AvoidanceType.ZoltBubble: return Trinity.Settings.Combat.AvoidanceRadius.ZoltBubble; case AvoidanceType.ZoltTwister: return Trinity.Settings.Combat.AvoidanceRadius.ZoltTwister; default: { //Logger.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Radius Switch! {0}", type.ToString()); return defaultValue; } } }
private static bool RefreshAvoidance() { try { CurrentCacheObject.Animation = c_diaObject.CommonData.CurrentAnimation; } catch (Exception ex) { Logger.LogDebug(LogCategory.CacheManagement, "Error reading CurrentAnimation for AoE sno:{0} raGuid:{1} name:{2} ex:{3}", CurrentCacheObject.ActorSNO, CurrentCacheObject.RActorGuid, CurrentCacheObject.InternalName, ex.Message); } float customRadius; if (DataDictionary.DefaultAvoidanceCustomRadius.TryGetValue(CurrentCacheObject.ActorSNO, out customRadius) || DataDictionary.DefaultAvoidanceAnimationCustomRadius.TryGetValue((int)CurrentCacheObject.Animation, out customRadius)) { CurrentCacheObject.Radius = customRadius; } double minAvoidanceHealth = GetAvoidanceHealth(CurrentCacheObject.ActorSNO); double minAvoidanceRadius = GetAvoidanceRadius(CurrentCacheObject.ActorSNO, CurrentCacheObject.Radius + 5); // Add Navigation cell weights to path around avoidance MainGridProvider.AddCellWeightingObstacle(CurrentCacheObject.ActorSNO, (float)minAvoidanceRadius); AvoidanceType avoidanceType = AvoidanceManager.GetAvoidanceType(CurrentCacheObject.ActorSNO); // Beast Charge should set aoe position as players current position! var avoidAtPlayerPosition = DataDictionary.AvoidAnimationAtPlayer.Contains((int)CurrentCacheObject.Animation); if (avoidAtPlayerPosition) { CurrentCacheObject.Position = Player.Position; } // Monks with Serenity up ignore all AOE's if (Player.ActorClass == ActorClass.Monk && Hotbar.Contains(SNOPower.Monk_Serenity) && GetHasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune minAvoidanceHealth *= V.F("Monk.Avoidance.Serenity"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a Monk with Serenity"); } // Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud if (Player.ActorClass == ActorClass.Witchdoctor && Hotbar.Contains(SNOPower.Witchdoctor_SpiritWalk) && GetHasBuff(SNOPower.Witchdoctor_SpiritWalk)) { if (avoidanceType == AvoidanceType.IceBall || avoidanceType == AvoidanceType.Arcane || avoidanceType == AvoidanceType.Desecrator || avoidanceType == AvoidanceType.PlagueCloud) { // Ignore ICE/Arcane/Desc/PlagueCloud altogether with spirit walk up or available minAvoidanceHealth *= V.F("WitchDoctor.Avoidance.SpiritWalk"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a WitchDoctor with Spirit Walk"); } } // Remove ice balls if the barbarian has wrath of the berserker up, and reduce health from most other SNO avoidances if (Player.ActorClass == ActorClass.Barbarian && Settings.Combat.Barbarian.IgnoreAvoidanceInWOTB && Hotbar.Contains(SNOPower.Barbarian_WrathOfTheBerserker) && GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (avoidanceType) { case AvoidanceType.IceBall: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.IceBall"); break; case AvoidanceType.Arcane: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Arcane"); break; case AvoidanceType.Desecrator: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Desecrator"); break; case AvoidanceType.Belial: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.Belial"); break; case AvoidanceType.PoisonTree: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.PoisonTree"); break; case AvoidanceType.BeastCharge: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.BeastCharge"); break; case AvoidanceType.MoltenCore: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.MoltenCore"); break; default: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Other"); break; } } // Item based immunity switch (avoidanceType) { case AvoidanceType.PoisonTree: case AvoidanceType.PlagueCloud: case AvoidanceType.PoisonEnchanted: case AvoidanceType.PlagueHand: if (Legendary.MarasKaleidoscope.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because MarasKaleidoscope is equipped", avoidanceType); minAvoidanceHealth = 0; } break; case AvoidanceType.AzmoFireball: case AvoidanceType.DiabloRingOfFire: case AvoidanceType.DiabloMeteor: case AvoidanceType.ButcherFloorPanel: case AvoidanceType.Mortar: case AvoidanceType.MageFire: case AvoidanceType.MoltenTrail: case AvoidanceType.MoltenBall: case AvoidanceType.ShamanFire: if (Legendary.TheStarOfAzkaranth.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TheStarofAzkaranth is equipped", avoidanceType); minAvoidanceHealth = 0; } break; case AvoidanceType.FrozenPulse: case AvoidanceType.IceBall: case AvoidanceType.IceTrail: // Ignore if both items are equipped if (Legendary.TalismanOfAranoch.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TalismanofAranoch is equipped", avoidanceType); minAvoidanceHealth = 0; } break; case AvoidanceType.Orbiter: case AvoidanceType.Thunderstorm: if (Legendary.XephirianAmulet.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because XephirianAmulet is equipped", avoidanceType); minAvoidanceHealth = 0; } break; case AvoidanceType.Arcane: if (Legendary.CountessJuliasCameo.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because CountessJuliasCameo is equipped", avoidanceType); minAvoidanceHealth = 0; } break; } // Set based immunity if (Sets.BlackthornesBattlegear.IsMaxBonusActive) { var blackthornsImmunity = new HashSet <AvoidanceType> { AvoidanceType.Desecrator, AvoidanceType.MoltenBall, AvoidanceType.MoltenCore, AvoidanceType.MoltenTrail, AvoidanceType.PlagueHand }; if (blackthornsImmunity.Contains(avoidanceType)) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because BlackthornesBattlegear is equipped", avoidanceType); minAvoidanceHealth = 0; } } if (minAvoidanceHealth == 0) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance! Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); return(false); } //Logger.LogDebug(LogCategory.Avoidance, "{0} Distance={1:0} {2}! {3} ({4})", // (avoidanceType == AvoidanceType.None) ? CurrentCacheObject.Animation.ToString() : avoidanceType.ToString(), // CurrentCacheObject.Distance, // minAvoidanceHealth >= Player.CurrentHealthPct ? "Adding" : "Ignoring", // CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO); // Add it to the list of known avoidance objects, *IF* our health is lower than this avoidance health limit if (minAvoidanceHealth >= Player.CurrentHealthPct) { float avoidanceRadius = (float)GetAvoidanceRadius(CurrentCacheObject.ActorSNO, CurrentCacheObject.Radius); TimeSpan aoeExpiration; DataDictionary.AvoidanceSpawnerDuration.TryGetValue(CurrentCacheObject.ActorSNO, out aoeExpiration); CacheData.TimeBoundAvoidance.Add(new CacheObstacleObject(CurrentCacheObject.Position, avoidanceRadius, CurrentCacheObject.ActorSNO, CurrentCacheObject.InternalName) { Expires = DateTime.UtcNow.Add(aoeExpiration), ObjectType = TrinityObjectType.Avoidance, Rotation = CurrentCacheObject.Rotation }); // Is this one under our feet? If so flag it up so we can find an avoidance spot if (CurrentCacheObject.Distance <= minAvoidanceRadius) { _currentAvoidance = CurrentCacheObject; _currentAvoidance.AvoidanceRadius = avoidanceRadius; _currentAvoidance.AvoidanceHealth = minAvoidanceHealth; _currentAvoidanceName = CurrentCacheObject.InternalName; _standingInAvoidance = true; // Note if this is a travelling projectile or not so we can constantly update our safe points if (DataDictionary.AvoidanceProjectiles.Contains(CurrentCacheObject.ActorSNO)) { Logger.Log(TrinityLogLevel.Verbose, LogCategory.Avoidance, "Is standing in avoidance for projectile Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); } else { Logger.Log(TrinityLogLevel.Verbose, LogCategory.Avoidance, "Is standing in avoidance Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); } } } return(true); }
public static AvoidanceDefinition GetAvoidanceData(AvoidanceType type) { return(AvoidanceDataByType.ContainsKey(type) ? AvoidanceDataByType[type] : null); }
private static bool RefreshAvoidance(bool AddToCache) { AddToCache = true; try { CurrentCacheObject.Animation = CurrentCacheObject.Object.CommonData.CurrentAnimation; } catch (Exception ex) { Logger.LogDebug(LogCategory.CacheManagement, "Error reading CurrentAnimation for AoE sno:{0} raGuid:{1} name:{2} ex:{3}", CurrentCacheObject.ActorSNO, CurrentCacheObject.RActorGuid, CurrentCacheObject.InternalName, ex.Message); } float customRadius; if (DataDictionary.DefaultAvoidanceCustomRadius.TryGetValue(CurrentCacheObject.ActorSNO, out customRadius)) { CurrentCacheObject.Radius = customRadius; } double minAvoidanceHealth = GetAvoidanceHealth(CurrentCacheObject.ActorSNO); double minAvoidanceRadius = GetAvoidanceRadius(CurrentCacheObject.ActorSNO, CurrentCacheObject.Radius); // Are we allowed to path around avoidance? if (Settings.Combat.Misc.AvoidanceNavigation) { MainGridProvider.AddCellWeightingObstacle(CurrentCacheObject.ActorSNO, (float)minAvoidanceRadius); } AvoidanceType avoidanceType = AvoidanceManager.GetAvoidanceType(CurrentCacheObject.ActorSNO); // Beast Charge should set aoe position as players current position! if (avoidanceType == AvoidanceType.BeastCharge) { CurrentCacheObject.Position = Trinity.Player.Position; } // Monks with Serenity up ignore all AOE's if (Player.ActorClass == ActorClass.Monk && Hotbar.Contains(SNOPower.Monk_Serenity) && GetHasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune minAvoidanceHealth *= V.F("Monk.Avoidance.Serenity"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a Monk with Serenity"); } // Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud if (Player.ActorClass == ActorClass.Witchdoctor && Hotbar.Contains(SNOPower.Witchdoctor_SpiritWalk) && GetHasBuff(SNOPower.Witchdoctor_SpiritWalk)) { if (avoidanceType == AvoidanceType.IceBall || avoidanceType == AvoidanceType.Arcane || avoidanceType == AvoidanceType.Desecrator || avoidanceType == AvoidanceType.PlagueCloud) { // Ignore ICE/Arcane/Desc/PlagueCloud altogether with spirit walk up or available minAvoidanceHealth *= V.F("WitchDoctor.Avoidance.SpiritWalk"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a WitchDoctor with Spirit Walk"); } } // Remove ice balls if the barbarian has wrath of the berserker up, and reduce health from most other SNO avoidances if (Player.ActorClass == ActorClass.Barbarian && Settings.Combat.Barbarian.IgnoreAvoidanceInWOTB && Hotbar.Contains(SNOPower.Barbarian_WrathOfTheBerserker) && GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (avoidanceType) { case AvoidanceType.IceBall: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.IceBall"); break; case AvoidanceType.Arcane: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Arcane"); break; case AvoidanceType.Desecrator: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Desecrator"); break; case AvoidanceType.Belial: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.Belial"); break; case AvoidanceType.PoisonTree: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.PoisonTree"); break; case AvoidanceType.BeastCharge: minAvoidanceHealth = V.F("Barbarian.Avoidance.WOTB.BeastCharge"); break; default: minAvoidanceHealth *= V.F("Barbarian.Avoidance.WOTB.Other"); break; } } if (minAvoidanceHealth == 0) { AddToCache = false; Logger.Log(TrinityLogLevel.Verbose, LogCategory.Avoidance, "Ignoring Avoidance! Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); return(AddToCache); } // Add it to the list of known avoidance objects, *IF* our health is lower than this avoidance health limit if (minAvoidanceHealth >= Player.CurrentHealthPct) { float avoidanceRadius = (float)GetAvoidanceRadius(CurrentCacheObject.ActorSNO, CurrentCacheObject.Radius); TimeSpan aoeExpiration; DataDictionary.AvoidanceSpawnerDuration.TryGetValue(CurrentCacheObject.ActorSNO, out aoeExpiration); CacheData.TimeBoundAvoidance.Add(new CacheObstacleObject(CurrentCacheObject.Position, avoidanceRadius, CurrentCacheObject.ActorSNO, CurrentCacheObject.InternalName) { Expires = DateTime.UtcNow.Add(aoeExpiration), ObjectType = GObjectType.Avoidance, Rotation = CurrentCacheObject.Rotation }); // Is this one under our feet? If so flag it up so we can find an avoidance spot if (CurrentCacheObject.Distance <= minAvoidanceRadius) { _standingInAvoidance = true; // Note if this is a travelling projectile or not so we can constantly update our safe points if (DataDictionary.AvoidanceProjectiles.Contains(CurrentCacheObject.ActorSNO)) { _isAvoidingProjectiles = true; Logger.Log(TrinityLogLevel.Verbose, LogCategory.Avoidance, "Is standing in avoidance for projectile Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); } else { Logger.Log(TrinityLogLevel.Verbose, LogCategory.Avoidance, "Is standing in avoidance Name={0} SNO={1} radius={2:0} health={3:0.00} dist={4:0}", CurrentCacheObject.InternalName, CurrentCacheObject.ActorSNO, minAvoidanceRadius, minAvoidanceHealth, CurrentCacheObject.Distance); } } } return(AddToCache); }
///<summary> ///Adds/Updates CacheObjects inside collection by Iteration of RactorList ///This is the method that caches all live data about an object! ///</summary> internal static bool UpdateCacheObjectCollection() { HashSet <int> hashDoneThisRactor = new HashSet <int>(); using (ZetaDia.Memory.AcquireFrame(true)) { if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || !ZetaDia.Me.IsValid) { return(false); } foreach (Actor thisActor in ZetaDia.Actors.RActorList) { int tmp_raGUID; DiaObject thisObj; if (!thisActor.IsValid) { continue; } //Convert to DiaObject thisObj = (DiaObject)thisActor; tmp_raGUID = thisObj.RActorGuid; // See if we've already checked this ractor, this loop if (hashDoneThisRactor.Contains(tmp_raGUID)) { continue; } hashDoneThisRactor.Add(tmp_raGUID); //Update RactorGUID and check blacklisting.. if (BlacklistCache.IsRAGUIDBlacklisted(tmp_raGUID)) { continue; } CacheObject tmp_CachedObj; if (!Objects.TryGetValue(tmp_raGUID, out tmp_CachedObj)) { Vector3 tmp_position; int tmp_acdguid; int tmp_SNOID; #region SNO //Lookup SNO try { tmp_SNOID = thisObj.ActorSNO; } catch (NullReferenceException) { //Logger.DBLog.InfoFormat("Failure to get SNO from object! RaGUID: {0}", tmp_raGUID); continue; } #endregion //check our SNO blacklist if (BlacklistCache.IsSNOIDBlacklisted(tmp_SNOID) && !CacheIDLookup.hashSummonedPets.Contains(tmp_SNOID)) { continue; } #region Position try { tmp_position = thisObj.Position; } catch (NullReferenceException) { //Logger.DBLog.InfoFormat("Failure to get position vector for RAGUID {0}", tmp_raGUID); continue; } #endregion #region AcdGUID try { tmp_acdguid = thisObj.ACDGuid; } catch (NullReferenceException) { //Logger.DBLog.InfoFormat("Failure to get ACDGUID for RAGUID {0}", tmp_raGUID); continue; } #endregion tmp_CachedObj = new CacheObject(tmp_SNOID, tmp_raGUID, tmp_acdguid, tmp_position); } else { //Reset unseen var tmp_CachedObj.LoopsUnseen = 0; } //Validate try { if (thisObj.CommonData == null || thisObj.CommonData.ACDGuid != thisObj.ACDGuid) { continue; } } catch (NullReferenceException) { continue; } //Check if this object is a summoned unit by a player... #region SummonedUnits if (tmp_CachedObj.IsSummonedPet) { // Get the summoned-by info, cached if possible if (!tmp_CachedObj.SummonerID.HasValue) { try { tmp_CachedObj.SummonerID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.SummonedByACDID); } catch (Exception ex) { //Logger.DBLog.InfoFormat("[Funky] Safely handled exception getting summoned-by info [" + tmp_CachedObj.SNOID.ToString(CultureInfo.InvariantCulture) + "]"); //Logger.DBLog.DebugFormat(ex.ToString()); continue; } } //See if this summoned unit was summoned by the bot. if (Bot.Character.Data.iMyDynamicID == tmp_CachedObj.SummonerID.Value) { //Now modify the player data pets count.. if (Bot.Character.Class.AC == ActorClass.Monk) { Bot.Character.Data.PetData.MysticAlly++; } else if (Bot.Character.Class.AC == ActorClass.DemonHunter) { if (CacheIDLookup.hashDHPets.Contains(tmp_CachedObj.SNOID)) { Bot.Character.Data.PetData.DemonHunterPet++; } else if (CacheIDLookup.hashDHSpikeTraps.Contains(tmp_CachedObj.SNOID) && tmp_CachedObj.CentreDistance <= 50f) { Bot.Character.Data.PetData.DemonHunterSpikeTraps++; } } else if (Bot.Character.Class.AC == ActorClass.Witchdoctor) { if (CacheIDLookup.hashZombie.Contains(tmp_CachedObj.SNOID)) { Bot.Character.Data.PetData.ZombieDogs++; } else if (CacheIDLookup.hashGargantuan.Contains(tmp_CachedObj.SNOID)) { Bot.Character.Data.PetData.Gargantuan++; } } else if (Bot.Character.Class.AC == ActorClass.Wizard) { //only count when range is within 45f (so we can summon a new one) if (CacheIDLookup.hashWizHydras.Contains(tmp_CachedObj.SNOID) && tmp_CachedObj.CentreDistance <= 45f) { Bot.Character.Data.PetData.WizardHydra++; } } } //We return regardless if it was summoned by us or not since this object is not anything we want to deal with.. tmp_CachedObj.NeedsRemoved = true; continue; } #endregion //Update any SNO Data. #region SNO_Cache_Update if (tmp_CachedObj.ref_DiaObject == null || tmp_CachedObj.ContainsNullValues()) { if (!tmp_CachedObj.UpdateData(thisObj, tmp_CachedObj.RAGUID)) { continue; } } else if (!tmp_CachedObj.IsFinalized) { //Finalize this data by recreating it and updating the Sno cache with a new finalized entry, this also clears our all Sno cache dictionaries since we no longer need them! cacheSnoCollection.FinalizeEntry(tmp_CachedObj.SNOID); } #endregion //Special Cache for Interactable Server Objects if (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.ServerInteractable)) { if (!Bot.Game.Profile.InteractableObjectCache.ContainsKey(tmp_CachedObj.RAGUID)) { Bot.Game.Profile.InteractableObjectCache.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); } //Do not add to main cache! continue; } //Objects with static positions already cached don't need to be updated here. if (!tmp_CachedObj.NeedsUpdate) { continue; } //Obstacles -- (Not an actual object we add to targeting.) if (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.Avoidance) || tmp_CachedObj.IsObstacle || tmp_CachedObj.HandleAsAvoidanceObject) { #region Obstacles CacheObstacle thisObstacle; //Do we have this cached? if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacle)) { AvoidanceType AvoidanceType = AvoidanceType.None; if (tmp_CachedObj.IsAvoidance) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingSNOID(tmp_CachedObj.SNOID); if (AvoidanceType == AvoidanceType.None) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingName(tmp_CachedObj.InternalName); if (AvoidanceType == AvoidanceType.None) { continue; } } } if (tmp_CachedObj.IsAvoidance && tmp_CachedObj.IsProjectileAvoidance) { //Ranged Projectiles require more than simple bounding points.. so we create it as avoidance zone to cache it with properties. //Check for intersection.. try { ActorMovement thisMovement = thisObj.Movement; Vector2 Direction = thisMovement.DirectionVector; Ray R = new Ray(tmp_CachedObj.Position, Direction.ToVector3()); double Speed; //Lookup Cached Speed, or add new entry. if (!dictProjectileSpeed.TryGetValue(tmp_CachedObj.SNOID, out Speed)) { Speed = thisMovement.DesiredSpeed; dictProjectileSpeed.Add(tmp_CachedObj.SNOID, Speed); } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType, R, Speed); Obstacles.Add(thisObstacle); } catch { Logger.Write(LogLevel.Cache, "Failed to create projectile avoidance with rotation and speed. {0}", tmp_CachedObj.InternalName); } } else if (tmp_CachedObj.IsAvoidance) { //Poison Gas Can Be Friendly... if (AvoidanceType == AvoidanceType.PoisonGas) { int TeamID = 0; try { TeamID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.TeamID); } catch { Logger.Write(LogLevel.Cache, "Failed to retrieve TeamID attribute for object {0}", thisObstacle.InternalName); } //ID of 1 means its non-hostile! (-1?) 2?? //if (TeamID==1||TeamID==-1) if (TeamID != 10) { //Logger.Write(LogLevel.None, "Ignoring Avoidance {0} due to Friendly TeamID match!", tmp_CachedObj.InternalName); BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Permanent); continue; } } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType); Obstacles.Add(thisObstacle); } else { //Obstacles. thisObstacle = new CacheServerObject(tmp_CachedObj); Obstacles.Add(thisObstacle); } } continue; #endregion } if (tmp_CachedObj.ObjectShouldBeRecreated) { //Specific updates if (tmp_CachedObj.Actortype.Value == ActorType.Item) { tmp_CachedObj = new CacheItem(tmp_CachedObj); } else if (tmp_CachedObj.Actortype.Value == ActorType.Monster) { tmp_CachedObj = new CacheUnit(tmp_CachedObj); } else if (tmp_CachedObj.Actortype.Value == ActorType.Gizmo) { if (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.Interactables)) { tmp_CachedObj = new CacheInteractable(tmp_CachedObj); } else { tmp_CachedObj = new CacheDestructable(tmp_CachedObj); } } //Update Properties tmp_CachedObj.UpdateProperties(); } if (!tmp_CachedObj.UpdateData()) { if (!tmp_CachedObj.IsStillValid()) { tmp_CachedObj.NeedsRemoved = true; } continue; } //Obstacle cache if (tmp_CachedObj.Obstacletype.Value != ObstacleType.None && (CheckTargetTypeFlag(tmp_CachedObj.targetType.Value, TargetType.ServerObjects))) { CacheObstacle thisObstacleObj; if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacleObj)) { CacheServerObject newobj = new CacheServerObject(tmp_CachedObj); Obstacles.Add(tmp_CachedObj.RAGUID, newobj); //Add nearby objects to our collection (used in navblock/obstaclecheck methods to reduce queries) if (CacheIDLookup.hashSNONavigationObstacles.Contains(newobj.SNOID)) { Navigation.MGP.AddCellWeightingObstacle(newobj.SNOID, newobj.Radius); } } else { if (thisObstacleObj.targetType.Value == TargetType.Unit) { //Since units position requires updating, we update using the CacheObject thisObstacleObj.Position = tmp_CachedObj.Position; Obstacles[tmp_CachedObj.RAGUID] = thisObstacleObj; } } } //cache it if (Objects.ContainsKey(tmp_CachedObj.RAGUID)) { Objects[tmp_CachedObj.RAGUID] = tmp_CachedObj; } else { Objects.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); } } //End of Loop } // End of Framelock //Tally up unseen objects. var UnseenObjects = Objects.Keys.Where(O => !hashDoneThisRactor.Contains(O)).ToList(); if (UnseenObjects.Any()) { for (int i = 0; i < UnseenObjects.Count(); i++) { Objects[UnseenObjects[i]].LoopsUnseen++; } } //Trim our collection every 5th refresh. UpdateLoopCounter++; if (UpdateLoopCounter > 4) { UpdateLoopCounter = 0; //Now flag any objects not seen for 5 loops. Gold/Globe only 1 loop. foreach (var item in Objects.Values.Where(CO => (CO.LoopsUnseen >= 5 || //5 loops max.. (CO.targetType.HasValue && (CheckTargetTypeFlag(CO.targetType.Value, TargetType.Gold | TargetType.Globe)) && CO.LoopsUnseen > 0)))) //gold/globe only 1 loop! { item.NeedsRemoved = true; } } return(true); }
public double UpdateWeight(out int monstercount, out int avoidcount, ref List <int> UsedRAGUIDs, bool ResetIndex = false) { monstercount = 0; avoidcount = 0; if (ResetIndex) { LastIndexUsed = 0; } OccupiedObjects.Clear(); Vector3 sectorCenter = this.Center; //Get the Diagonal Length between start and end, multiply by 2.5 since each point represents an area of 5f than Divide the total by 2 for the radius range. double range = GridPoint.GetDistanceBetweenPoints(this.StartPoint, this.CornerPoint); int TotalGridPoints = this.ContainedPoints.Count; this.ThisWeight = 0d; //We use 2D Distance and subtract the obstacles radius IEnumerable <CacheObstacle> obstaclesContained = ObjectCache.Obstacles.Values .Where(obs => Math.Max(0f, sectorCenter.Distance2D(obs.Position) - obs.Radius) <= range); double maxaverage = ObjectCache.Objects.MaximumHitPointAverage; if (obstaclesContained.Any()) { //reset weight this.ThisWeight = 0; //copy SectorPoints //GridPoint[] SectorPoints=new GridPoint[this.ContainedPoints.Count]; //this.ContainedPoints.CopyTo(SectorPoints); List <GridPoint> NonNavPoints = new List <GridPoint>(); foreach (CacheObstacle item in obstaclesContained) { OccupiedObjects.Add(item.RAGUID); if (item is CacheServerObject) { //Monsters should add 10% of its weight //if (item.Obstacletype.Value==ObstacleType.Monster) //{ // if (Bot.Settings.Fleeing.EnableFleeingBehavior&& Bot.Targeting.Environment.FleeTrigeringRAGUIDs.Contains(item.RAGUID)) // { // } //} if (item.Obstacletype.Value == ObstacleType.ServerObject) { //give +1 to weight this.ThisWeight++; } } else if (item is CacheAvoidance) { if (!UsedRAGUIDs.Contains(item.RAGUID)) { AvoidanceType thisAvoidanceType = ((CacheAvoidance)item).AvoidanceType; if (AvoidanceCache.IgnoringAvoidanceType(thisAvoidanceType)) { continue; } AvoidanceValue AV = Bot.Settings.Avoidance.Avoidances[(int)thisAvoidanceType]; avoidcount++; float BaseWeight = AV.Weight; //if ((AvoidanceType.ArcaneSentry|AvoidanceType.Dececrator|AvoidanceType.MoltenCore|AvoidanceType.TreeSpore).HasFlag(thisAvoidanceType)) // BaseWeight=1f; //else // BaseWeight=0.5f; this.ThisWeight += (BaseWeight / Bot.Character.Data.dCurrentHealthPct); UsedRAGUIDs.Add(item.RAGUID); } } } ////Now add a base score for non-nav points. (25 being 100% non-navigable) //int PointMultiplier=(25/TotalGridPoints); //int RemainingPoints=SectorPoints.Length; //this.ThisWeight+=25-(RemainingPoints*PointMultiplier); //Logger.DBLog.InfoFormat("Weight assigned to this sector {0}. \r\n" //+"Total Points {1} with {2} Remaining points Valid!", this.ThisWeight, this.ContainedPoints.Count, SectorPoints.Length); } return(this.ThisWeight); //(Total Points / Non-Navigable Points Ratio) }
internal static bool IgnoringAvoidanceType(AvoidanceType thisAvoidance) { if (!FunkyBaseExtension.Settings.Avoidance.AttemptAvoidanceMovements) return true; double dThisHealthAvoid = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; if (dThisHealthAvoid == 0d) return true; return false; }
///<summary> ///Tests the given avoidance type to see if it should be ignored either due to a buff or if health is greater than the avoidance HP. ///</summary> internal static bool IgnoreAvoidance(AvoidanceType thisAvoidance) { double dThisHealthAvoid; if (!AvoidancesHealth.TryGetValue(thisAvoidance, out dThisHealthAvoid)) return true; if (!Combat.CriticalAvoidance) {//Not Critical Avoidance, should we be in total ignorance because of a buff? // Monks with Serenity up ignore all AOE's if (Class.AC==ActorClass.Monk&&Class.HotbarPowers.Contains(SNOPower.Monk_Serenity)&&Class.HasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune return true; }// Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud else if (Class.AC==ActorClass.WitchDoctor &&Class.HotbarPowers.Contains(SNOPower.Witchdoctor_SpiritWalk) &&(!Class.HasBuff(SNOPower.Witchdoctor_SpiritWalk)&&Class.AbilityUseTimer(SNOPower.Witchdoctor_SpiritWalk))||Class.HasBuff(SNOPower.Witchdoctor_SpiritWalk)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return true; } } else if (Class.AC==ActorClass.Barbarian&&Class.HotbarPowers.Contains(SNOPower.Barbarian_WrathOfTheBerserker)&&Class.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return true; } } } //Only procedee if health percent is necessary for avoidance! return dThisHealthAvoid<Character.dCurrentHealthPct; }
internal static bool IgnoringAvoidanceType(AvoidanceType thisAvoidance) { if (!Bot.SettingsFunky.AttemptAvoidanceMovements) return true; double dThisHealthAvoid; if (!AvoidancesHealth.TryGetValue(thisAvoidance, out dThisHealthAvoid)) return true; else if (dThisHealthAvoid==0d) return true; return false; }
public static bool IsAvoidanceTypeProjectile(AvoidanceType type) { return (type == AvoidanceType.BeeProjectile || type == AvoidanceType.ShamanFireBall || type == AvoidanceType.AzmodanFireball); }
public static bool IsAvoidanceTypeProjectile(AvoidanceType type) { return(type == AvoidanceType.BeeProjectile || type == AvoidanceType.ShamanFireBall || type == AvoidanceType.AzmodanFireball); }
public static float GetAvoidanceHealth(AvoidanceType type, float defaultValue) { // Monks with Serenity up ignore all AOE's if (Trinity.Player.ActorClass == ActorClass.Monk && Trinity.Hotbar.Contains(SNOPower.Monk_Serenity) && Trinity.GetHasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune defaultValue *= V.F("Monk.Avoidance.Serenity"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a Monk with Serenity"); } // Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud if (Trinity.Player.ActorClass == ActorClass.Witchdoctor && Trinity.Hotbar.Contains(SNOPower.Witchdoctor_SpiritWalk) && Trinity.GetHasBuff(SNOPower.Witchdoctor_SpiritWalk)) { if (type == AvoidanceType.IceBall || type == AvoidanceType.Arcane || type == AvoidanceType.Desecrator || type == AvoidanceType.PlagueCloud) { // Ignore ICE/Arcane/Desc/PlagueCloud altogether with spirit walk up or available defaultValue *= V.F("WitchDoctor.Avoidance.SpiritWalk"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a WitchDoctor with Spirit Walk"); } } // Remove ice balls if the barbarian has wrath of the berserker up, and reduce health from most other SNO avoidances if (Trinity.Player.ActorClass == ActorClass.Barbarian && Trinity.Settings.Combat.Barbarian.IgnoreAvoidanceInWOTB && Trinity.Hotbar.Contains(SNOPower.Barbarian_WrathOfTheBerserker) && Trinity.GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (type) { case AvoidanceType.IceBall: defaultValue *= V.F("Barbarian.Avoidance.WOTB.IceBall"); break; case AvoidanceType.Arcane: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Arcane"); break; case AvoidanceType.Desecrator: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Desecrator"); break; case AvoidanceType.Belial: defaultValue = V.F("Barbarian.Avoidance.WOTB.Belial"); break; case AvoidanceType.PoisonTree: defaultValue = V.F("Barbarian.Avoidance.WOTB.PoisonTree"); break; case AvoidanceType.BeastCharge: defaultValue = V.F("Barbarian.Avoidance.WOTB.BeastCharge"); break; case AvoidanceType.MoltenCore: defaultValue = V.F("Barbarian.Avoidance.WOTB.MoltenCore"); break; default: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Other"); break; } } IAvoidanceHealth avoidanceHealth = null; switch (Trinity.Player.ActorClass) { case ActorClass.Barbarian: avoidanceHealth = Trinity.Settings.Combat.Barbarian; break; case ActorClass.Crusader: avoidanceHealth = Trinity.Settings.Combat.Crusader; break; case ActorClass.Monk: avoidanceHealth = Trinity.Settings.Combat.Monk; break; case ActorClass.Wizard: avoidanceHealth = Trinity.Settings.Combat.Wizard; break; case ActorClass.Witchdoctor: avoidanceHealth = Trinity.Settings.Combat.WitchDoctor; break; case ActorClass.DemonHunter: avoidanceHealth = Trinity.Settings.Combat.DemonHunter; break; } if (avoidanceHealth != null) { switch (type) { case AvoidanceType.Arcane: return(avoidanceHealth.AvoidArcaneHealth); case AvoidanceType.AzmoFireball: return(avoidanceHealth.AvoidAzmoFireBallHealth); case AvoidanceType.AzmodanBody: return(avoidanceHealth.AvoidAzmoBodiesHealth); case AvoidanceType.AzmodanPool: return(avoidanceHealth.AvoidAzmoPoolsHealth); case AvoidanceType.BeastCharge: return(1); case AvoidanceType.BeeWasp: return(avoidanceHealth.AvoidBeesWaspsHealth); case AvoidanceType.Belial: return(avoidanceHealth.AvoidBelialHealth); case AvoidanceType.ButcherFloorPanel: return(avoidanceHealth.AvoidButcherFloorPanelHealth); case AvoidanceType.Desecrator: return(avoidanceHealth.AvoidDesecratorHealth); case AvoidanceType.DiabloMeteor: return(avoidanceHealth.AvoidDiabloMeteorHealth); case AvoidanceType.DiabloPrison: return(avoidanceHealth.AvoidDiabloPrisonHealth); case AvoidanceType.DiabloRingOfFire: return(avoidanceHealth.AvoidDiabloRingOfFireHealth); case AvoidanceType.FireChains: return(0.8f); case AvoidanceType.FrozenPulse: return(avoidanceHealth.AvoidFrozenPulseHealth); case AvoidanceType.GhomGas: return(avoidanceHealth.AvoidGhomGasHealth); case AvoidanceType.Grotesque: return(avoidanceHealth.AvoidGrotesqueHealth); case AvoidanceType.IceBall: return(avoidanceHealth.AvoidIceBallsHealth); case AvoidanceType.IceTrail: return(avoidanceHealth.AvoidIceTrailHealth); case AvoidanceType.Orbiter: return(avoidanceHealth.AvoidOrbiterHealth); case AvoidanceType.MageFire: return(avoidanceHealth.AvoidMageFireHealth); case AvoidanceType.MaghdaProjectille: return(avoidanceHealth.AvoidMaghdaProjectilleHealth); case AvoidanceType.MoltenBall: return(avoidanceHealth.AvoidMoltenBallHealth); case AvoidanceType.MoltenCore: return(avoidanceHealth.AvoidMoltenCoreHealth); case AvoidanceType.MoltenTrail: return(avoidanceHealth.AvoidMoltenTrailHealth); case AvoidanceType.Mortar: return(0.25f); case AvoidanceType.PlagueCloud: return(avoidanceHealth.AvoidPlagueCloudHealth); case AvoidanceType.PlagueHand: return(avoidanceHealth.AvoidPlagueHandsHealth); case AvoidanceType.PoisonEnchanted: return(avoidanceHealth.AvoidPoisonEnchantedHealth); case AvoidanceType.PoisonTree: return(avoidanceHealth.AvoidPoisonTreeHealth); case AvoidanceType.ShamanFire: return(avoidanceHealth.AvoidShamanFireHealth); case AvoidanceType.Thunderstorm: return(avoidanceHealth.AvoidThunderstormHealth); case AvoidanceType.Wormhole: return(avoidanceHealth.AvoidWormholeHealth); case AvoidanceType.ZoltBubble: return(avoidanceHealth.AvoidZoltBubbleHealth); case AvoidanceType.ZoltTwister: return(avoidanceHealth.AvoidZoltTwisterHealth); default: { //Logger.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Health Switch! {0}", type.ToString()); return(defaultValue); } } } return(defaultValue); }
///<summary> ///Tests the given avoidance type to see if it should be ignored either due to a buff or if health is greater than the avoidance HP. ///</summary> internal static bool IgnoreAvoidance(AvoidanceType thisAvoidance) { //Pylon Shield? if (Hotbar.HasBuff(SNOPower.Pages_Buff_Invulnerable)) { return(true); } //Countess Julias Cameo (Arcane Immunity) if (Equipment.ImmuneToArcane && thisAvoidance == AvoidanceType.ArcaneSentry) { return(true); } //Maras Kaleidoscope (Poison Immunity) if (Equipment.ImmuneToPoison && (thisAvoidance == AvoidanceType.PlagueCloud || thisAvoidance == AvoidanceType.PlagueHand || thisAvoidance == AvoidanceType.PoisonGas)) { return(true); } //Talisman of Aranoch if (Equipment.ImmuneToCold && (thisAvoidance == AvoidanceType.FrozenPulse || thisAvoidance == AvoidanceType.MalthaelDeathFog)) { return(true); } //Special Blackthorne's Set Bonus Check! if (Equipment.ImmuneToDescratorMoltenPlaguedAvoidances) { switch (thisAvoidance) { case AvoidanceType.Dececrator: case AvoidanceType.MoltenCore: case AvoidanceType.MoltenTrail: case AvoidanceType.PlagueCloud: case AvoidanceType.PlagueHand: return(true); } } double dThisHealthAvoid = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; //if (!FunkyGame.Hero.CriticalAvoidance) //{ //Not Critical Avoidance, should we be in total ignorance because of a buff? // Monks with Serenity up ignore all AOE's if (FunkyGame.CurrentActorClass == ActorClass.Monk) { // Monks with serenity are immune if (Hotbar.HasPower(SNOPower.Monk_Serenity) && Hotbar.HasBuff(SNOPower.Monk_Serenity)) { return(true); } //Epiphany ignore frozen. if (Hotbar.HasPower(SNOPower.X1_Monk_Epiphany) && Hotbar.HasBuff(SNOPower.X1_Monk_Epiphany) && thisAvoidance == AvoidanceType.Frozen) { return(true); } } //Crusader Akarats Champion -- Ignore Frozen! if (FunkyGame.CurrentActorClass == ActorClass.Crusader && Hotbar.HasPower(SNOPower.X1_Crusader_AkaratsChampion) && Hotbar.HasBuff(SNOPower.X1_Crusader_AkaratsChampion) && thisAvoidance == AvoidanceType.Frozen) { return(true); } if (FunkyGame.CurrentActorClass == ActorClass.Barbarian && Hotbar.HasPower(SNOPower.Barbarian_WrathOfTheBerserker) && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return(true); } } //} //Only procedee if health percent is necessary for avoidance! return(dThisHealthAvoid < FunkyGame.Hero.dCurrentHealthPct); }
public static bool IsPlayerImmune(AvoidanceType avoidanceType) { if (CacheData.Buffs.HasInvulnerableShrine) { return(true); } if (CacheData.BuffsCache.Instance.HasBuff(SNOPower.Barbarian_IgnorePain)) { switch (avoidanceType) { case AvoidanceType.IceBall: return(true); } } // Item based immunity switch (avoidanceType) { case AvoidanceType.PoisonTree: case AvoidanceType.PlagueCloud: case AvoidanceType.PoisonEnchanted: case AvoidanceType.PlagueHand: if (Legendary.MarasKaleidoscope.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because MarasKaleidoscope is equipped", avoidanceType); return(true); } break; case AvoidanceType.AzmoFireball: case AvoidanceType.DiabloRingOfFire: case AvoidanceType.DiabloMeteor: case AvoidanceType.ButcherFloorPanel: case AvoidanceType.Mortar: case AvoidanceType.MageFire: case AvoidanceType.MoltenTrail: case AvoidanceType.MoltenBall: case AvoidanceType.ShamanFire: if (Legendary.TheStarOfAzkaranth.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TheStarofAzkaranth is equipped", avoidanceType); return(true); } break; case AvoidanceType.FrozenPulse: case AvoidanceType.IceBall: case AvoidanceType.IceTrail: // Ignore if both items are equipped if (Legendary.TalismanOfAranoch.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because TalismanofAranoch is equipped", avoidanceType); return(true); } break; case AvoidanceType.Orbiter: case AvoidanceType.Thunderstorm: if (Legendary.XephirianAmulet.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because XephirianAmulet is equipped", avoidanceType); return(true); } break; case AvoidanceType.Arcane: if (Legendary.CountessJuliasCameo.IsEquipped) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because CountessJuliasCameo is equipped", avoidanceType); return(true); } break; } // Set based immunity if (Sets.BlackthornesBattlegear.IsMaxBonusActive) { var blackthornsImmunity = new HashSet <AvoidanceType> { AvoidanceType.Desecrator, AvoidanceType.MoltenBall, AvoidanceType.MoltenCore, AvoidanceType.MoltenTrail, AvoidanceType.PlagueHand }; if (blackthornsImmunity.Contains(avoidanceType)) { Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring Avoidance {0} because BlackthornesBattlegear is equipped", avoidanceType); return(true); } } return(false); }
public static float GetAvoidanceHealth(AvoidanceType type, float defaultValue) { //TODO : Make mapping between Type and Config LoadAvoidanceDictionary(false); IAvoidanceHealth avoidanceHealth = null; switch (GilesTrinity.PlayerStatus.ActorClass) { case ActorClass.Barbarian: avoidanceHealth = GilesTrinity.Settings.Combat.Barbarian; break; case ActorClass.Monk: avoidanceHealth = GilesTrinity.Settings.Combat.Monk; break; case ActorClass.Wizard: avoidanceHealth = GilesTrinity.Settings.Combat.Wizard; break; case ActorClass.WitchDoctor: avoidanceHealth = GilesTrinity.Settings.Combat.WitchDoctor; break; case ActorClass.DemonHunter: avoidanceHealth = GilesTrinity.Settings.Combat.DemonHunter; break; } if (avoidanceHealth != null) { switch (type) { case AvoidanceType.Arcane: return(avoidanceHealth.AvoidArcaneHealth); case AvoidanceType.AzmodanBody: return(avoidanceHealth.AvoidAzmoBodiesHealth); case AvoidanceType.AzmoFireball: return(avoidanceHealth.AvoidAzmoFireBallHealth); case AvoidanceType.AzmodanPool: return(avoidanceHealth.AvoidAzmoPoolsHealth); case AvoidanceType.BeeWasp: return(avoidanceHealth.AvoidBeesWaspsHealth); case AvoidanceType.Belial: return(avoidanceHealth.AvoidBelialHealth); case AvoidanceType.ButcherFloorPanel: return(avoidanceHealth.AvoidButcherFloorPanelHealth); case AvoidanceType.Desecrator: return(avoidanceHealth.AvoidDesecratorHealth); case AvoidanceType.DiabloMeteor: return(avoidanceHealth.AvoidDiabloMeteorHealth); case AvoidanceType.DiabloPrison: return(avoidanceHealth.AvoidDiabloPrisonHealth); case AvoidanceType.DiabloRingOfFire: return(avoidanceHealth.AvoidDiabloRingOfFireHealth); case AvoidanceType.GhomGas: return(avoidanceHealth.AvoidGhomGasHealth); case AvoidanceType.IceBall: return(avoidanceHealth.AvoidIceBallsHealth); case AvoidanceType.IceTrail: return(avoidanceHealth.AvoidIceTrailHealth); case AvoidanceType.MageFire: return(avoidanceHealth.AvoidMageFireHealth); case AvoidanceType.MaghdaProjectille: return(avoidanceHealth.AvoidMaghdaProjectilleHealth); case AvoidanceType.MoltenBall: return(avoidanceHealth.AvoidMoltenBallHealth); case AvoidanceType.MoltenCore: return(avoidanceHealth.AvoidMoltenCoreHealth); case AvoidanceType.MoltenTrail: return(avoidanceHealth.AvoidMoltenTrailHealth); case AvoidanceType.PlagueCloud: return(avoidanceHealth.AvoidPlagueCloudHealth); case AvoidanceType.PlagueHand: return(avoidanceHealth.AvoidPlagueHandsHealth); case AvoidanceType.PoisonTree: return(avoidanceHealth.AvoidPoisonTreeHealth); case AvoidanceType.SuccubusStar: return(avoidanceHealth.AvoidSuccubusStarHealth); case AvoidanceType.ShamanFire: return(avoidanceHealth.AvoidShamanFireHealth); case AvoidanceType.ZoltBubble: return(avoidanceHealth.AvoidZoltBubbleHealth); case AvoidanceType.ZoltTwister: return(avoidanceHealth.AvoidZoltTwisterHealth); default: { DbHelper.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Health Switch! {0}", type.ToString()); return(defaultValue); } } } return(defaultValue); }
///<summary> ///Updates SNO Cache Values ///</summary> public virtual bool UpdateData(DiaObject thisObj, int raguid) { bool failureDuringUpdate = false; if (InternalName == null) { try { InternalName = thisObj.Name; } catch { Logger.Write(LogLevel.Cache, "Failure to get internal name on object, SNO {0}", SNOID); return(false); } } if (!Actortype.HasValue) { #region ActorType try { Actortype = thisObj.ActorType; } catch { Logger.Write(LogLevel.Cache, "Failure to get actorType for object, SNO: {0}", SNOID); return(false); } #endregion } //Ignored actor types.. if (BlacklistCache.IgnoredActorTypes.Contains(Actortype.Value)) //||!LootBehaviorEnabled&&this.Actortype.Value==ActorType.Item) { BlacklistCache.IgnoreThisObject(this, raguid); return(false); } if (!targetType.HasValue) { #region EvaluateTargetType try { //Evaluate Target Type.. // See if it's an avoidance first from the SNO if (IsAvoidance || IsObstacle) { targetType = TargetType.None; if (IsAvoidance) { if (IsProjectileAvoidance) { Obstacletype = ObstacleType.MovingAvoidance; } else { Obstacletype = ObstacleType.StaticAvoidance; } AvoidanceType AT = AvoidanceCache.FindAvoidanceUsingSNOID(SNOID); //Check if avoidance is enabled or if the avoidance type is set to 0 if (!Bot.Settings.Avoidance.AttemptAvoidanceMovements || AT != AvoidanceType.None && AvoidanceCache.IgnoringAvoidanceType(AT)) { BlacklistCache.AddObjectToBlacklist(raguid, BlacklistType.Temporary); return(false); } // Avoidance isn't disabled, so set this object type to avoidance targetType = TargetType.Avoidance; } else { Obstacletype = ObstacleType.ServerObject; } } else { // Calculate the object type of this object if (Actortype.Value == ActorType.Monster || CacheIDLookup.hashActorSNOForceTargetUnit.Contains(SNOID)) { targetType = TargetType.Unit; Obstacletype = ObstacleType.Monster; if (CacheIDLookup.hashActorSNOForceTargetUnit.Contains(SNOID)) { //Fill in monster data? Actortype = ActorType.Monster; } } else if (Actortype.Value == ActorType.Item || CacheIDLookup.hashForceSNOToItemList.Contains(SNOID)) { string testname = InternalName.ToLower(); //Check if this item is gold/globe.. if (testname.StartsWith("gold")) { targetType = TargetType.Gold; } else if (testname.StartsWith("healthglobe")) { targetType = TargetType.Globe; } else if (testname.StartsWith("console_powerglobe")) { targetType = TargetType.PowerGlobe; } else { targetType = TargetType.Item; } //Gold/Globe? } else if (Actortype.Value == ActorType.Gizmo) { GizmoType thisGizmoType; try { thisGizmoType = thisObj.ActorInfo.GizmoType; } catch { Logger.Write(LogLevel.Cache, "Failure to get actor Gizmo Type!"); return(false); } if (thisGizmoType == GizmoType.DestroyableObject || thisGizmoType == GizmoType.BreakableChest) { targetType = TargetType.Destructible; } else if (thisGizmoType == GizmoType.PowerUp || thisGizmoType == GizmoType.HealingWell || thisGizmoType == GizmoType.PoolOfReflection) { targetType = TargetType.Shrine; } else if (thisGizmoType == GizmoType.Chest) { targetType = TargetType.Container; } else if (thisGizmoType == GizmoType.BreakableDoor) { targetType = TargetType.Barricade; } else if (thisGizmoType == GizmoType.Door) { targetType = TargetType.Door; } else if (thisGizmoType == GizmoType.Waypoint || thisGizmoType == GizmoType.Portal || thisGizmoType == GizmoType.DungeonPortal || thisGizmoType == GizmoType.BossPortal) { //Special Interactive Object -- Add to special cache! targetType = TargetType.ServerInteractable; } else if (thisGizmoType == GizmoType.Switch) { targetType = TargetType.CursedShrine; } else { //All other gizmos should be ignored! BlacklistCache.IgnoreThisObject(this, raguid); return(false); } if (targetType.HasValue) { if (targetType.Value == TargetType.Destructible || targetType.Value == TargetType.Barricade || targetType.Value == TargetType.Door) { Obstacletype = ObstacleType.Destructable; } else if (targetType.Value == TargetType.Shrine || IsChestContainer) { Obstacletype = ObstacleType.ServerObject; } } if (!Gizmotype.HasValue) { Gizmotype = thisGizmoType; } } else if (CacheIDLookup.hashSNOInteractWhitelist.Contains(SNOID)) { targetType = TargetType.Interactable; } else if (Actortype.Value == ActorType.ServerProp) { string TestString = InternalName.ToLower(); //Server props with Base in name are the destructibles "remains" which is considered an obstacle! if (TestString.Contains("base") || TestString.Contains("fence")) { //Add this to the obstacle navigation cache if (!IsObstacle) { CacheIDLookup.hashSNONavigationObstacles.Add(SNOID); } Obstacletype = ObstacleType.ServerObject; //Use unknown since we lookup SNO ID for server prop related objects. targetType = TargetType.None; } else if (TestString.StartsWith("monsteraffix_")) { AvoidanceType T = AvoidanceCache.FindAvoidanceUsingName(TestString); if (T == AvoidanceType.Wall) { //Add this to the obstacle navigation cache if (!IsObstacle) { CacheIDLookup.hashSNONavigationObstacles.Add(SNOID); } Obstacletype = ObstacleType.ServerObject; //Use unknown since we lookup SNO ID for server prop related objects. targetType = TargetType.None; } //else if (Bot.AvoidancesHealth.ContainsKey(T)) //{ // Logger.DBLog.InfoFormat("Found Avoidance not recongized by SNO! Name {0} SNO {1}", TestString, this.SNOID); // CacheIDLookup.hashAvoidanceSNOList.Add(this.SNOID); // this.targetType=TargetType.Avoidance; //} else { //Blacklist all other monster affixes BlacklistCache.IgnoreThisObject(this, raguid); return(false); } } else { BlacklistCache.IgnoreThisObject(this, raguid); return(false); } } else { //Misc?? Ignore it! BlacklistCache.IgnoreThisObject(this, raguid); return(false); } } } catch { Logger.Write(LogLevel.Cache, "Failure to get actorType for object, SNO: {0}", SNOID); return(false); } #endregion } if (!Obstacletype.HasValue) { Obstacletype = ObstacleType.None; } if (ObjectCache.CheckTargetTypeFlag(targetType.Value, TargetType.Unit)) { SNORecordMonster monsterInfo; try { monsterInfo = thisObj.CommonData.MonsterInfo; } catch { Logger.Write(LogLevel.Cache, "Safely Handled MonsterInfo Exception for Object {0}", InternalName); return(false); } if (!Monstertype.HasValue || ShouldRefreshMonsterType) { #region MonsterType try { Monstertype = monsterInfo.MonsterType; } catch { Logger.Write(LogLevel.Cache, "Failure to get MonsterType for SNO: {0}", SNOID); failureDuringUpdate = true; } #endregion } if (!Monstersize.HasValue) { #region MonsterSize try { Monstersize = monsterInfo.MonsterSize; } catch { Logger.Write(LogLevel.Cache, "Failure to get MonsterSize for SNO: {0}", SNOID); failureDuringUpdate = true; } #endregion } } if (Actortype.HasValue && targetType.HasValue && (Actortype.Value != ActorType.Item && targetType.Value != TargetType.Avoidance && targetType.Value != TargetType.ServerInteractable)) { //Validate sphere info Sphere sphereInfo = thisObj.CollisionSphere; if (!CollisionRadius.HasValue) { #region CollisionRadius try { CollisionRadius = sphereInfo.Radius; } catch { Logger.Write(LogLevel.Cache, "Failure to get CollisionRadius for SNO: {0}", SNOID); failureDuringUpdate = true; } #endregion if (CacheIDLookup.dictFixedCollisionRadius.ContainsKey(SNOID)) { //Override The Default Collision Sphere Value CollisionRadius = CacheIDLookup.dictFixedCollisionRadius[SNOID]; } } if (!ActorSphereRadius.HasValue) { #region ActorSphereRadius try { ActorSphereRadius = thisObj.ActorInfo.Sphere.Radius; } catch { Logger.Write(LogLevel.Cache, "Safely handled getting attribute Sphere radius for gizmo {0}", InternalName); failureDuringUpdate = true; } #endregion } #region GizmoProperties if (ObjectCache.CheckTargetTypeFlag(targetType.Value, TargetType.Destructible | TargetType.Interactable)) { //No Loot if (!DropsNoLoot.HasValue) { #region DropsNoLoot try { DropsNoLoot = thisObj.CommonData.GetAttribute <float>(ActorAttributeType.DropsNoLoot) <= 0; } catch { Logger.Write(LogLevel.Cache, "Safely handled reading DropsNoLoot for gizmo {0}", InternalName); failureDuringUpdate = true; } #endregion } //No XP if (!GrantsNoXP.HasValue) { #region GrantsNoXP try { GrantsNoXP = thisObj.CommonData.GetAttribute <float>(ActorAttributeType.GrantsNoXP) <= 0; } catch { Logger.Write(LogLevel.Cache, "Safely handled reading GrantsNoXp for gizmo {0}", InternalName); failureDuringUpdate = true; } #endregion } //Barricade flag if (!IsBarricade.HasValue) { #region Barricade try { IsBarricade = ((DiaGizmo)thisObj).IsBarricade; } catch { Logger.Write(LogLevel.Cache, "Safely handled getting attribute IsBarricade for gizmo {0}", InternalName); failureDuringUpdate = true; } #endregion } } #endregion } return(!failureDuringUpdate); }
public AvoidanceEntry(int snoID, AvoidanceType objectType, string internalname = "") : base(snoID) { InternalName=internalname; _objectType = objectType; }
///<summary> ///Tests the given avoidance type to see if it should be ignored either due to a buff or if health is greater than the avoidance HP. ///</summary> internal static bool IgnoreAvoidance(AvoidanceType thisAvoidance) { //Pylon Shield? if (Hotbar.HasBuff(SNOPower.Pages_Buff_Invulnerable)) return true; //Countess Julias Cameo (Arcane Immunity) if (Equipment.ImmuneToArcane && thisAvoidance == AvoidanceType.ArcaneSentry) return true; //Maras Kaleidoscope (Poison Immunity) if (Equipment.ImmuneToPoison && (thisAvoidance == AvoidanceType.PlagueCloud || thisAvoidance == AvoidanceType.PlagueHand || thisAvoidance == AvoidanceType.PoisonGas)) return true; //Talisman of Aranoch if (Equipment.ImmuneToCold && (thisAvoidance == AvoidanceType.FrozenPulse || thisAvoidance == AvoidanceType.MalthaelDeathFog)) return true; //Special Blackthorne's Set Bonus Check! if (Equipment.ImmuneToDescratorMoltenPlaguedAvoidances) { switch (thisAvoidance) { case AvoidanceType.Dececrator: case AvoidanceType.MoltenCore: case AvoidanceType.MoltenTrail: case AvoidanceType.PlagueCloud: case AvoidanceType.PlagueHand: return true; } } double dThisHealthAvoid = FunkyBaseExtension.Settings.Avoidance.Avoidances[(int)thisAvoidance].Health; //if (!FunkyGame.Hero.CriticalAvoidance) //{ //Not Critical Avoidance, should we be in total ignorance because of a buff? // Monks with Serenity up ignore all AOE's if (FunkyGame.CurrentActorClass == ActorClass.Monk) { // Monks with serenity are immune if (Hotbar.HasPower(SNOPower.Monk_Serenity) && Hotbar.HasBuff(SNOPower.Monk_Serenity)) return true; //Epiphany ignore frozen. if (Hotbar.HasPower(SNOPower.X1_Monk_Epiphany) && Hotbar.HasBuff(SNOPower.X1_Monk_Epiphany) && thisAvoidance == AvoidanceType.Frozen) return true; } //Crusader Akarats Champion -- Ignore Frozen! if (FunkyGame.CurrentActorClass == ActorClass.Crusader && Hotbar.HasPower(SNOPower.X1_Crusader_AkaratsChampion) && Hotbar.HasBuff(SNOPower.X1_Crusader_AkaratsChampion) && thisAvoidance == AvoidanceType.Frozen) return true; if (FunkyGame.CurrentActorClass == ActorClass.Barbarian && Hotbar.HasPower(SNOPower.Barbarian_WrathOfTheBerserker) && Hotbar.HasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (thisAvoidance) { case AvoidanceType.Frozen: case AvoidanceType.ArcaneSentry: case AvoidanceType.Dececrator: case AvoidanceType.PlagueCloud: return true; } } //} //Only procedee if health percent is necessary for avoidance! return dThisHealthAvoid < FunkyGame.Hero.dCurrentHealthPct; }
public static float GetAvoidanceRadius(AvoidanceType type, float defaultValue) { switch (type) { case AvoidanceType.Arcane: return(Trinity.Settings.Combat.AvoidanceRadius.Arcane); case AvoidanceType.AzmodanBody: return(Trinity.Settings.Combat.AvoidanceRadius.AzmoBodies); case AvoidanceType.AzmoFireball: return(Trinity.Settings.Combat.AvoidanceRadius.AzmoFireBall); case AvoidanceType.AzmodanPool: return(Trinity.Settings.Combat.AvoidanceRadius.AzmoPools); case AvoidanceType.BeastCharge: return(1); case AvoidanceType.BeeWasp: return(Trinity.Settings.Combat.AvoidanceRadius.BeesWasps); case AvoidanceType.Belial: return(Trinity.Settings.Combat.AvoidanceRadius.Belial); case AvoidanceType.ButcherFloorPanel: return(Trinity.Settings.Combat.AvoidanceRadius.ButcherFloorPanel); case AvoidanceType.Desecrator: return(Trinity.Settings.Combat.AvoidanceRadius.Desecrator); case AvoidanceType.DiabloMeteor: return(Trinity.Settings.Combat.AvoidanceRadius.DiabloMeteor); case AvoidanceType.DiabloPrison: return(Trinity.Settings.Combat.AvoidanceRadius.DiabloPrison); case AvoidanceType.DiabloRingOfFire: return(Trinity.Settings.Combat.AvoidanceRadius.DiabloRingOfFire); case AvoidanceType.FireChains: return(1); case AvoidanceType.FrozenPulse: return(Trinity.Settings.Combat.AvoidanceRadius.FrozenPulse); case AvoidanceType.GhomGas: return(Trinity.Settings.Combat.AvoidanceRadius.GhomGas); case AvoidanceType.Grotesque: return(Trinity.Settings.Combat.AvoidanceRadius.Grotesque); case AvoidanceType.IceBall: return(Trinity.Settings.Combat.AvoidanceRadius.IceBalls); case AvoidanceType.IceTrail: return(Trinity.Settings.Combat.AvoidanceRadius.IceTrail); case AvoidanceType.Orbiter: return(Trinity.Settings.Combat.AvoidanceRadius.Orbiter); case AvoidanceType.MageFire: return(Trinity.Settings.Combat.AvoidanceRadius.MageFire); case AvoidanceType.MaghdaProjectille: return(Trinity.Settings.Combat.AvoidanceRadius.MaghdaProjectille); case AvoidanceType.MoltenCore: return(Trinity.Settings.Combat.AvoidanceRadius.MoltenCore); case AvoidanceType.MoltenTrail: return(Trinity.Settings.Combat.AvoidanceRadius.MoltenTrail); case AvoidanceType.Mortar: return(defaultValue); case AvoidanceType.MoltenBall: return(Trinity.Settings.Combat.AvoidanceRadius.MoltenBall); case AvoidanceType.PlagueCloud: return(Trinity.Settings.Combat.AvoidanceRadius.PlagueCloud); case AvoidanceType.PlagueHand: return(Trinity.Settings.Combat.AvoidanceRadius.PlagueHands); case AvoidanceType.PoisonTree: return(Trinity.Settings.Combat.AvoidanceRadius.PoisonTree); case AvoidanceType.PoisonEnchanted: return(Trinity.Settings.Combat.AvoidanceRadius.PoisonEnchanted); case AvoidanceType.ShamanFire: return(Trinity.Settings.Combat.AvoidanceRadius.ShamanFire); case AvoidanceType.Thunderstorm: return(Trinity.Settings.Combat.AvoidanceRadius.Thunderstorm); case AvoidanceType.Wormhole: return(Trinity.Settings.Combat.AvoidanceRadius.Wormhole); case AvoidanceType.ZoltBubble: return(Trinity.Settings.Combat.AvoidanceRadius.ZoltBubble); case AvoidanceType.ZoltTwister: return(Trinity.Settings.Combat.AvoidanceRadius.ZoltTwister); default: { //Logger.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Radius Switch! {0}", type.ToString()); return(defaultValue); } } }
public AvoidanceSettingsEntry GetDefinitionSettings(AvoidanceType type) { return(EntriesByType.ContainsKey(type) ? EntriesByType[type] : null); }
// ///<summary> ///Adds/Updates CacheObjects inside collection by Iteration of RactorList ///This is the method that caches all live data about an object! ///</summary> internal static bool UpdateCacheObjectCollection() { //Update Character (just incase it wasnt called before..) FunkyGame.Hero.Update(false, true); Obstacles.AttemptToClearEntries(); HashSet <int> hashDoneThisRactor = new HashSet <int>(); using (ZetaDia.Memory.AcquireFrame(true)) { if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || !ZetaDia.Me.IsValid) { return(false); } foreach (Actor thisActor in ZetaDia.Actors.RActorList) { int tmp_raGUID; DiaObject thisObj; if (!thisActor.IsValid) { continue; } //Convert to DiaObject thisObj = (DiaObject)thisActor; tmp_raGUID = thisObj.RActorGuid; // See if we've already checked this ractor, this loop if (hashDoneThisRactor.Contains(tmp_raGUID)) { continue; } hashDoneThisRactor.Add(tmp_raGUID); //Update RactorGUID and check blacklisting.. if (BlacklistCache.IsRAGUIDBlacklisted(tmp_raGUID)) { continue; } CacheObject tmp_CachedObj; if (!Objects.TryGetValue(tmp_raGUID, out tmp_CachedObj)) { ActorType Actortype; Vector3 tmp_position; int tmp_acdguid; int tmp_SNOID; #region SNO //Lookup SNO try { tmp_SNOID = thisObj.ActorSNO; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting SNO for {0}", tmp_raGUID); //Logger.DBLog.InfoFormat("Failure to get SNO from object! RaGUID: {0}", tmp_raGUID); continue; } #endregion //check our SNO blacklist (exclude pets?) if (BlacklistCache.IsSNOIDBlacklisted(tmp_SNOID)) { continue; } #region Position try { tmp_position = thisObj.Position; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting Position for {0}", tmp_SNOID); continue; } #endregion #region AcdGUID try { tmp_acdguid = thisObj.ACDGuid; } catch (Exception ex) { Logger.Write(LogLevel.Cache, "Safely handled getting ACDGuid for {0}", tmp_SNOID); continue; } #endregion tmp_CachedObj = new CacheObject(tmp_SNOID, tmp_raGUID, tmp_acdguid, tmp_position); } else { //Reset unseen var tmp_CachedObj.LoopsUnseen = 0; } ////Validate (ignore special object SNO Ids) //if (!CacheIDLookup.hashSNOSkipCommonDataCheck.Contains(tmp_CachedObj.SNOID)) //{ // try // { // if (thisObj.CommonData == null) // { // Logger.Write(LogLevel.Cache, "CommonData is no longer valid! {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } // if (thisObj.CommonData.ACDGuid != thisObj.ACDGuid) // { // Logger.Write(LogLevel.Cache, "ACDGuid Mismatched! {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } // } // catch (Exception ex) // { // //Logger.Write(LogLevel.Cache, "Object is no longer valid! (Exception) SNOID {0}", tmp_CachedObj.DebugStringSimple); // //BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Temporary); // continue; // } //} //Update any SNO Data. #region SNO_Cache_Update if (tmp_CachedObj.ref_DiaObject == null || tmp_CachedObj.ContainsNullValues()) { if (!tmp_CachedObj.UpdateData(thisObj, tmp_CachedObj.RAGUID)) { continue; } } else if (!tmp_CachedObj.IsFinalized) { //Finalize this data by recreating it and updating the Sno cache with a new finalized entry, this also clears our all Sno cache dictionaries since we no longer need them! cacheSnoCollection.FinalizeEntry(tmp_CachedObj.SNOID); } #endregion //Check if this object is a summoned unit by a player... #region SummonedUnits if (tmp_CachedObj.IsSummonedPet && CacheIDLookup.hashSNOSkipCommonDataCheck.Contains(tmp_CachedObj.SNOID)) { PetTypes PetType = (PetTypes)TheCache.ObjectIDCache.UnitPetEntries[tmp_CachedObj.SNOID].ObjectType; if (PetType == PetTypes.WIZARD_ArcaneOrbs) { FunkyGame.Targeting.Cache.Environment.HeroPets.WizardArcaneOrbs++; tmp_CachedObj.NeedsRemoved = true; continue; } } #endregion //Special Cache for Interactable Server Objects if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.ServerInteractable)) { if (!InteractableObjectCache.ContainsKey(tmp_CachedObj.RAGUID)) { InteractableObjectCache.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); //Adventure Mode -- Rifting we add Exit to LOS movement! //if (FunkyGame.AdventureMode && FunkyGame.Bounty.IsInRiftWorld && FunkyBaseExtension.Settings.AdventureMode.EnableAdventuringMode) //{ // if (tmp_CachedObj.InternalName.Contains("Exit")) // { // int index = FunkyGame.Bounty.CurrentBountyMapMarkers.Count; // FunkyGame.Bounty.CurrentBountyMapMarkers.Add(index, new BountyCache.BountyMapMarker(tmp_CachedObj.Position, FunkyGame.Hero.CurrentWorldDynamicID, index)); // } //} } //Whymsdal Portal! if (tmp_CachedObj.SNOID == 405590) { GoblinBehavior.Portal = tmp_CachedObj; } else if (tmp_CachedObj.SNOID == 393030) { GoblinBehavior.Portal = tmp_CachedObj; } //Do not add to main cache! continue; } //Objects with static positions already cached don't need to be updated here. if (!tmp_CachedObj.NeedsUpdate) { continue; } //Obstacles -- (Not an actual object we add to targeting.) if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.Avoidance) || tmp_CachedObj.IsObstacle || tmp_CachedObj.HandleAsAvoidanceObject) { #region Obstacles CacheObstacle thisObstacle; //Do we have this cached? if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacle)) { AvoidanceType AvoidanceType = AvoidanceType.None; if (tmp_CachedObj.IsAvoidance) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingSNOID(tmp_CachedObj.SNOID); if (AvoidanceType == AvoidanceType.None) { AvoidanceType = AvoidanceCache.FindAvoidanceUsingName(tmp_CachedObj.InternalName); if (AvoidanceType == AvoidanceType.None) { continue; } } } if (tmp_CachedObj.IsAvoidance && tmp_CachedObj.IsProjectileAvoidance) { //Ranged Projectiles require more than simple bounding points.. so we create it as avoidance zone to cache it with properties. //Check for intersection.. try { ActorMovement thisMovement = thisObj.Movement; Vector2 Direction = thisMovement.DirectionVector; Ray R = new Ray(tmp_CachedObj.Position, Direction.ToVector3()); double Speed; //Lookup Cached Speed, or add new entry. if (!dictProjectileSpeed.TryGetValue(tmp_CachedObj.SNOID, out Speed)) { Speed = thisMovement.DesiredSpeed; dictProjectileSpeed.Add(tmp_CachedObj.SNOID, Speed); } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType, R, Speed); Obstacles.Add(thisObstacle); } catch { Logger.Write(LogLevel.Cache, "Failed to create projectile avoidance with rotation and speed. {0}", tmp_CachedObj.InternalName); } } else if (tmp_CachedObj.IsAvoidance) { //Poison Gas Can Be Friendly... if (AvoidanceType == AvoidanceType.PoisonGas) { int TeamID = 0; try { TeamID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.TeamID); } catch { Logger.Write(LogLevel.Cache, "Failed to retrieve TeamID attribute for object {0}", tmp_CachedObj.InternalName); } //ID of 1 means its non-hostile! (-1?) 2?? //if (TeamID==1||TeamID==-1) if (TeamID != 10) { //Logger.Write(LogLevel.None, "Ignoring Avoidance {0} due to Friendly TeamID match!", tmp_CachedObj.InternalName); BlacklistCache.AddObjectToBlacklist(tmp_CachedObj.RAGUID, BlacklistType.Permanent); continue; } } thisObstacle = new CacheAvoidance(tmp_CachedObj, AvoidanceType); Obstacles.Add(thisObstacle); } else { //Obstacles. thisObstacle = new CacheServerObject(tmp_CachedObj); Obstacles.Add(thisObstacle); } } continue; #endregion } if (tmp_CachedObj.ObjectShouldBeRecreated) { //This is where we create the real object after its done with SNO Update. //Specific updates if (tmp_CachedObj.Actortype.Value == ActorType.Item) { tmp_CachedObj = new CacheItem(tmp_CachedObj); } else if (tmp_CachedObj.Actortype.Value == ActorType.Monster) { if (!tmp_CachedObj.IsSummonedPet) { tmp_CachedObj = new CacheUnit(tmp_CachedObj); } else { PetTypes PetType = (PetTypes)TheCache.ObjectIDCache.UnitPetEntries[tmp_CachedObj.SNOID].ObjectType; #region Summoner ID Check // Get the summoned-by info, cached if possible if (!tmp_CachedObj.SummonerID.HasValue) { try { tmp_CachedObj.SummonerID = thisObj.CommonData.GetAttribute <int>(ActorAttributeType.SummonedByACDID); } catch (Exception ex) { //Logger.DBLog.InfoFormat("[Funky] Safely handled exception getting summoned-by info [" + tmp_CachedObj.SNOID.ToString(CultureInfo.InvariantCulture) + "]"); //Logger.DBLog.DebugFormat(ex.ToString()); continue; } } if (FunkyGame.Hero.iMyDynamicID != tmp_CachedObj.SummonerID.Value) { BlacklistCache.IgnoreThisObject(tmp_CachedObj, false, false); tmp_CachedObj.NeedsRemoved = true; continue; } #endregion tmp_CachedObj = new CachePet(tmp_CachedObj, PetType); } } else if (tmp_CachedObj.Actortype.Value == ActorType.Gizmo) { if (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.Interactables)) { tmp_CachedObj = new CacheInteractable(tmp_CachedObj); } else { tmp_CachedObj = new CacheDestructable(tmp_CachedObj); } } //Update Properties (currently only for units) try { tmp_CachedObj.UpdateProperties(); } catch { Logger.Write(LogLevel.Cache, "Failed to update properties for {0}", tmp_CachedObj.DebugStringSimple); } } if (!tmp_CachedObj.UpdateData()) { //Logger.Write(LogLevel.Cache, "Update Failed for {0}", tmp_CachedObj.DebugStringSimple); if (!tmp_CachedObj.IsStillValid()) { tmp_CachedObj.NeedsRemoved = true; } continue; } //Obstacle cache if (tmp_CachedObj.Obstacletype.Value != ObstacleType.None && (CheckFlag(tmp_CachedObj.targetType.Value, TargetType.ServerObjects))) { CacheObstacle thisObstacleObj; if (!Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacleObj)) { CacheServerObject newobj = new CacheServerObject(tmp_CachedObj); Obstacles.Add(tmp_CachedObj.RAGUID, newobj); //Add nearby objects to our collection (used in navblock/obstaclecheck methods to reduce queries) if (CacheIDLookup.hashSNONavigationObstacles.Contains(newobj.SNOID)) { Navigation.Navigation.MGP.AddCellWeightingObstacle(newobj.SNOID, newobj.Radius); } } else { if (thisObstacleObj.targetType.Value == TargetType.Unit) { //Since units position requires updating, we update using the CacheObject thisObstacleObj.Position = tmp_CachedObj.Position; Obstacles[tmp_CachedObj.RAGUID] = thisObstacleObj; } } } //cache it if (Objects.ContainsKey(tmp_CachedObj.RAGUID)) { Objects[tmp_CachedObj.RAGUID] = tmp_CachedObj; } else { Objects.Add(tmp_CachedObj.RAGUID, tmp_CachedObj); } } //End of Loop } // End of Framelock //Tally up unseen objects. var UnseenObjects = Objects.Keys.Where(O => !hashDoneThisRactor.Contains(O)).ToList(); if (UnseenObjects.Any()) { for (int i = 0; i < UnseenObjects.Count(); i++) { Objects[UnseenObjects[i]].LoopsUnseen++; } } //Trim our collection every 5th refresh. UpdateLoopCounter++; if (UpdateLoopCounter > 4) { UpdateLoopCounter = 0; //Now flag any objects not seen for 5 loops. Gold/Globe only 1 loop. foreach (var item in Objects.Values.Where(CO => (CO.LoopsUnseen >= 5 || //5 loops max.. (CO.targetType.HasValue && (CheckFlag(CO.targetType.Value, TargetType.Gold | TargetType.Globe)) && CO.LoopsUnseen > 0)))) //gold/globe only 1 loop! { item.NeedsRemoved = true; } } CheckForCacheRemoval(); _lastUpdatedCacheCollection = DateTime.Now; return(true); }
public CacheAvoidanceEntry(int snoID, AvoidanceType objectType, string internalname = "") : base(snoID) { InternalName = internalname; _objectType = objectType; }
public static float GetAvoidanceRadius(AvoidanceType type, float defaultValue) { LoadAvoidanceDictionary(false); //TODO : Make mapping between Type and Config switch (type) { case AvoidanceType.Arcane: return(GilesTrinity.Settings.Combat.AvoidanceRadius.Arcane); case AvoidanceType.AzmodanBody: return(GilesTrinity.Settings.Combat.AvoidanceRadius.AzmoBodies); case AvoidanceType.AzmoFireball: return(GilesTrinity.Settings.Combat.AvoidanceRadius.AzmoFireBall); case AvoidanceType.AzmodanPool: return(GilesTrinity.Settings.Combat.AvoidanceRadius.AzmoPools); case AvoidanceType.BeeWasp: return(GilesTrinity.Settings.Combat.AvoidanceRadius.BeesWasps); case AvoidanceType.Belial: return(GilesTrinity.Settings.Combat.AvoidanceRadius.Belial); case AvoidanceType.ButcherFloorPanel: return(GilesTrinity.Settings.Combat.AvoidanceRadius.ButcherFloorPanel); case AvoidanceType.Desecrator: return(GilesTrinity.Settings.Combat.AvoidanceRadius.Desecrator); case AvoidanceType.DiabloMeteor: return(GilesTrinity.Settings.Combat.AvoidanceRadius.DiabloMeteor); case AvoidanceType.DiabloPrison: return(GilesTrinity.Settings.Combat.AvoidanceRadius.DiabloPrison); case AvoidanceType.DiabloRingOfFire: return(GilesTrinity.Settings.Combat.AvoidanceRadius.DiabloRingOfFire); case AvoidanceType.GhomGas: return(GilesTrinity.Settings.Combat.AvoidanceRadius.GhomGas); case AvoidanceType.IceBall: return(GilesTrinity.Settings.Combat.AvoidanceRadius.IceBalls); case AvoidanceType.IceTrail: return(GilesTrinity.Settings.Combat.AvoidanceRadius.IceTrail); case AvoidanceType.MageFire: return(GilesTrinity.Settings.Combat.AvoidanceRadius.MageFire); case AvoidanceType.MaghdaProjectille: return(GilesTrinity.Settings.Combat.AvoidanceRadius.MaghdaProjectille); case AvoidanceType.MoltenCore: return(GilesTrinity.Settings.Combat.AvoidanceRadius.MoltenCore); case AvoidanceType.MoltenTrail: return(GilesTrinity.Settings.Combat.AvoidanceRadius.MoltenTrail); case AvoidanceType.MoltenBall: return(GilesTrinity.Settings.Combat.AvoidanceRadius.MoltenBall); case AvoidanceType.PlagueCloud: return(GilesTrinity.Settings.Combat.AvoidanceRadius.PlagueCloud); case AvoidanceType.PlagueHand: return(GilesTrinity.Settings.Combat.AvoidanceRadius.PlagueHands); case AvoidanceType.PoisonTree: return(GilesTrinity.Settings.Combat.AvoidanceRadius.PoisonTree); case AvoidanceType.SuccubusStar: return(GilesTrinity.Settings.Combat.AvoidanceRadius.SuccubusStar); case AvoidanceType.ShamanFire: return(GilesTrinity.Settings.Combat.AvoidanceRadius.ShamanFire); case AvoidanceType.ZoltBubble: return(GilesTrinity.Settings.Combat.AvoidanceRadius.ZoltBubble); case AvoidanceType.ZoltTwister: return(GilesTrinity.Settings.Combat.AvoidanceRadius.ZoltTwister); default: { DbHelper.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Radius Switch! {0}", type.ToString()); return(defaultValue); } } }
public static float GetAvoidanceHealth(AvoidanceType type, float defaultValue) { // Monks with Serenity up ignore all AOE's if (Trinity.Player.ActorClass == ActorClass.Monk && Trinity.Hotbar.Contains(SNOPower.Monk_Serenity) && Trinity.GetHasBuff(SNOPower.Monk_Serenity)) { // Monks with serenity are immune defaultValue *= V.F("Monk.Avoidance.Serenity"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a Monk with Serenity"); } // Witch doctors with spirit walk available and not currently Spirit Walking will subtly ignore ice balls, arcane, desecrator & plague cloud if (Trinity.Player.ActorClass == ActorClass.Witchdoctor && Trinity.Hotbar.Contains(SNOPower.Witchdoctor_SpiritWalk) && Trinity.GetHasBuff(SNOPower.Witchdoctor_SpiritWalk)) { if (type == AvoidanceType.IceBall || type == AvoidanceType.Arcane || type == AvoidanceType.Desecrator || type == AvoidanceType.PlagueCloud) { // Ignore ICE/Arcane/Desc/PlagueCloud altogether with spirit walk up or available defaultValue *= V.F("WitchDoctor.Avoidance.SpiritWalk"); Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Ignoring avoidance as a WitchDoctor with Spirit Walk"); } } // Remove ice balls if the barbarian has wrath of the berserker up, and reduce health from most other SNO avoidances if (Trinity.Player.ActorClass == ActorClass.Barbarian && Trinity.Settings.Combat.Barbarian.IgnoreAvoidanceInWOTB && Trinity.Hotbar.Contains(SNOPower.Barbarian_WrathOfTheBerserker) && Trinity.GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) { switch (type) { case AvoidanceType.IceBall: defaultValue *= V.F("Barbarian.Avoidance.WOTB.IceBall"); break; case AvoidanceType.Arcane: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Arcane"); break; case AvoidanceType.Desecrator: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Desecrator"); break; case AvoidanceType.Belial: defaultValue = V.F("Barbarian.Avoidance.WOTB.Belial"); break; case AvoidanceType.PoisonTree: defaultValue = V.F("Barbarian.Avoidance.WOTB.PoisonTree"); break; case AvoidanceType.BeastCharge: defaultValue = V.F("Barbarian.Avoidance.WOTB.BeastCharge"); break; case AvoidanceType.MoltenCore: defaultValue = V.F("Barbarian.Avoidance.WOTB.MoltenCore"); break; default: defaultValue *= V.F("Barbarian.Avoidance.WOTB.Other"); break; } } IAvoidanceHealth avoidanceHealth = null; switch (Trinity.Player.ActorClass) { case ActorClass.Barbarian: avoidanceHealth = Trinity.Settings.Combat.Barbarian; break; case ActorClass.Crusader: avoidanceHealth = Trinity.Settings.Combat.Crusader; break; case ActorClass.Monk: avoidanceHealth = Trinity.Settings.Combat.Monk; break; case ActorClass.Wizard: avoidanceHealth = Trinity.Settings.Combat.Wizard; break; case ActorClass.Witchdoctor: avoidanceHealth = Trinity.Settings.Combat.WitchDoctor; break; case ActorClass.DemonHunter: avoidanceHealth = Trinity.Settings.Combat.DemonHunter; break; } if (avoidanceHealth != null) { switch (type) { case AvoidanceType.Arcane: return avoidanceHealth.AvoidArcaneHealth; case AvoidanceType.AzmoFireball: return avoidanceHealth.AvoidAzmoFireBallHealth; case AvoidanceType.AzmodanBody: return avoidanceHealth.AvoidAzmoBodiesHealth; case AvoidanceType.AzmodanPool: return avoidanceHealth.AvoidAzmoPoolsHealth; case AvoidanceType.BeastCharge: return 1; case AvoidanceType.BeeWasp: return avoidanceHealth.AvoidBeesWaspsHealth; case AvoidanceType.Belial: return avoidanceHealth.AvoidBelialHealth; case AvoidanceType.ButcherFloorPanel: return avoidanceHealth.AvoidButcherFloorPanelHealth; case AvoidanceType.Desecrator: return avoidanceHealth.AvoidDesecratorHealth; case AvoidanceType.DiabloMeteor: return avoidanceHealth.AvoidDiabloMeteorHealth; case AvoidanceType.DiabloPrison: return avoidanceHealth.AvoidDiabloPrisonHealth; case AvoidanceType.DiabloRingOfFire: return avoidanceHealth.AvoidDiabloRingOfFireHealth; case AvoidanceType.FireChains: return 0.8f; case AvoidanceType.FrozenPulse: return avoidanceHealth.AvoidFrozenPulseHealth; case AvoidanceType.GhomGas: return avoidanceHealth.AvoidGhomGasHealth; case AvoidanceType.Grotesque: return avoidanceHealth.AvoidGrotesqueHealth; case AvoidanceType.IceBall: return avoidanceHealth.AvoidIceBallsHealth; case AvoidanceType.IceTrail: return avoidanceHealth.AvoidIceTrailHealth; case AvoidanceType.Orbiter: return avoidanceHealth.AvoidOrbiterHealth; case AvoidanceType.MageFire: return avoidanceHealth.AvoidMageFireHealth; case AvoidanceType.MaghdaProjectille: return avoidanceHealth.AvoidMaghdaProjectilleHealth; case AvoidanceType.MoltenBall: return avoidanceHealth.AvoidMoltenBallHealth; case AvoidanceType.MoltenCore: return avoidanceHealth.AvoidMoltenCoreHealth; case AvoidanceType.MoltenTrail: return avoidanceHealth.AvoidMoltenTrailHealth; case AvoidanceType.Mortar: return 0.25f; case AvoidanceType.PlagueCloud: return avoidanceHealth.AvoidPlagueCloudHealth; case AvoidanceType.PlagueHand: return avoidanceHealth.AvoidPlagueHandsHealth; case AvoidanceType.PoisonEnchanted: return avoidanceHealth.AvoidPoisonEnchantedHealth; case AvoidanceType.PoisonTree: return avoidanceHealth.AvoidPoisonTreeHealth; case AvoidanceType.ShamanFire: return avoidanceHealth.AvoidShamanFireHealth; case AvoidanceType.Thunderstorm: return avoidanceHealth.AvoidThunderstormHealth; case AvoidanceType.Wormhole: return avoidanceHealth.AvoidWormholeHealth; case AvoidanceType.ZoltBubble: return avoidanceHealth.AvoidZoltBubbleHealth; case AvoidanceType.ZoltTwister: return avoidanceHealth.AvoidZoltTwisterHealth; default: { //Logger.Log(TrinityLogLevel.Error, LogCategory.Avoidance, "Unknown Avoidance type in Health Switch! {0}", type.ToString()); return defaultValue; } } } return defaultValue; }