public OUR_Set <T> Remove(T value, Guid tag, long timestamp) { var elementToRemove = Adds.FirstOrDefault(a => Equals(a.Value, value) && a.Tag == tag); if (elementToRemove is null || elementToRemove?.Timestamp > timestamp) { return(this); } return(new(Adds, Removes.Add(new OUR_SetElement <T>(value, tag, timestamp)))); }
public OUR_SetWithVC <T> Remove(T value, Guid tag, VectorClock vectorClock) { var elementToRemove = Adds.FirstOrDefault(a => Equals(a.Value, value) && a.Tag == tag); if (elementToRemove is null || elementToRemove?.VectorClock > vectorClock) { return(this); } return(new(Adds, Removes.Add(new OUR_SetWithVCElement <T>(value, tag, vectorClock)))); }
public OUR_SetWithVC <T> Add(T value, Guid tag, VectorClock vectorClock) { var existingElement = Adds.FirstOrDefault(a => a.Value.Id == value.Id && a.Tag == tag); if (existingElement is not null) { return(Update(value, tag, vectorClock)); } return(new(Adds.Add(new OUR_SetWithVCElement <T>(value, tag, vectorClock)), Removes)); }
public OUR_Set <T> Add(T value, Guid tag, long timestamp) { var existingElement = Adds.FirstOrDefault(a => a.Value.Id == value.Id && a.Tag == tag); if (existingElement is not null) { return(Update(value, tag, timestamp)); } return(new(Adds.Add(new OUR_SetElement <T>(value, tag, timestamp)), Removes)); }
public P_Set <T> Add(T value) { var add = Adds.FirstOrDefault(e => e.Id == value.Id); var remove = Removes.FirstOrDefault(e => e.Id == value.Id); if (add is not null || remove is not null) { return(this); } return(new(Adds.Add(value), Removes)); }
public OUR_SetWithVC <T> Update(T value, Guid tag, VectorClock vectorClock) { var elementToUpdate = Adds.FirstOrDefault(a => a.Value.Id == value.Id && a.Tag == tag); if (elementToUpdate is null || elementToUpdate?.VectorClock > vectorClock) { return(this); } var adds = Adds.Remove(elementToUpdate); adds = adds.Add(new OUR_SetWithVCElement <T>(value, tag, vectorClock)); return(new(adds, Removes)); }
public OUR_Set <T> Update(T value, Guid tag, long timestamp) { var elementToUpdate = Adds.FirstOrDefault(a => a.Value.Id == value.Id && a.Tag == tag); if (elementToUpdate is null || elementToUpdate?.Timestamp > timestamp) { return(this); } var adds = Adds.Remove(elementToUpdate); adds = adds.Add(new OUR_SetElement <T>(value, tag, timestamp)); return(new(adds, Removes)); }
public bool Lookup(T value) { var added = Adds.FirstOrDefault(a => Equals(a.Value, value)); var removed = Removes.FirstOrDefault(r => Equals(r.Value, value)); if (added is not null && removed is null) { return(true); } if (added is not null && added?.VectorClock > removed?.VectorClock) { return(true); } return(false); }
public LWW_SetWithVC <T> Add(T value, VectorClock vectorClock) { var existingElement = Adds.FirstOrDefault(a => a.Value.Id == value.Id); if (existingElement is not null && existingElement.VectorClock < vectorClock) { var elements = Adds.Remove(existingElement); return(new(elements.Add(new LWW_SetWithVCElement <T>(value, vectorClock)), Removes)); } if (existingElement is null) { return(new(Adds.Add(new LWW_SetWithVCElement <T>(value, vectorClock)), Removes)); } return(this); }
public LWW_Set <T> Assign(T value, long timestamp) { var existingElement = Adds.FirstOrDefault(a => a.Value.Id == value.Id); if (existingElement is not null && existingElement.Timestamp < timestamp) { var elements = Adds.Remove(existingElement); return(new(elements.Add(new LWW_SetElement <T>(value, timestamp)), Removes)); } if (existingElement is null) { return(new(Adds.Add(new LWW_SetElement <T>(value, timestamp)), Removes)); } return(this); }
/// <summary> /// Do all the basic stuff which is shared among all specialisations. /// </summary> /// <returns><c>true</c>, if there was an GCD after a cast, <c>false</c> otherwise.</returns> protected bool DoSharedRotation() { if (UseDarkSoul) { //no globalcd bool DarkSoulCondition = (Target.IsInCombatRangeAndLoS && Target.MaxHealth >= Me.MaxHealth && Target.IsElite() && !UseDarkSoulBossOnly) || IsBoss(Target); CastSelfPreventDouble( "Dark Soul: Instability", () => DarkSoulCondition, 20000 ); CastSelfPreventDouble( "Dark Soul: Knowledge", () => DarkSoulCondition, 20000 ); CastSelfPreventDouble( "Dark Soul: Misery", () => DarkSoulCondition, 20000 ); } Cast( "Command Demon", () => !HasSpell("Grimoire of Sacrifice") && (IsPetActive("Summon Felhunter") || SelectedPet == WarlockPet.Felhunter) && Target.IsCastingAndInterruptible() ); Cast( "Command Demon", () => !HasSpell("Grimoire of Sacrifice") && (IsPetActive("Summon Imp") || SelectedPet == WarlockPet.SoulImp) && Me.HealthFraction <= 0.75 ); Cast( "Command Demon", () => !HasSpell("Grimoire of Sacrifice") && (IsPetActive("Summon Voidwalker") || SelectedPet == WarlockPet.Voidwalker) && Me.HealthFraction < 0.5 ); Cast( "Command Demon", () => !HasSpell("Grimoire of Sacrifice") && HasFelguard() && Adds.Count(u => Vector3.DistanceSquared( Me.Pet.Position, u.Position ) <= 8 * 8) >= 2 ); Cast( "Axe Toss", () => !HasSpell("Grimoire of Sacrifice") && HasFelguard() && Target.IsCastingAndInterruptible() ); //Heal CastSelf("Unbound Will", () => !Me.CanParticipateInCombat); CastSelf("Dark Bargain", () => Me.HealthFraction < 0.5); CastSelf("Sacrificial Pact", () => Me.HealthFraction < 0.6); CastSelf("Unending Resolve", () => Me.HealthFraction <= 0.5); CastSelf("Dark Regeneration", () => Me.HealthFraction <= 0.6); if (Me.HasAlivePet) { UnitObject add = Adds.FirstOrDefault(x => x.Target == Me); if (add != null) { Me.PetAttack(add); } } if (Cast("Mortal Coil", () => Me.HealthFraction <= 0.5)) { return(true); } if (SummonPet()) { return(true); } // Disable DPS Pets if they are the "normal" one. if (!HasSpell("Demonic Servitude")) { if (CastOnTerrain( HasSpell("Grimoire of Supremacy") ? "Summon Abyssal" : "Summon Infernal", Target.Position, () => UseAdditionalDPSPet && (((Target.MaxHealth >= Me.MaxHealth && Target.IsElite() && !UseAdditionalDPSPetBossOnly) || IsBoss(Target)) && (Adds.Count >= 3)) ) || Cast( HasSpell("Grimoire of Supremacy") ? "Summon Terrorguard" : "Summon Doomguard", () => UseAdditionalDPSPet && ((Target.MaxHealth >= Me.MaxHealth && Target.IsElite() && !UseAdditionalDPSPetBossOnly) || IsBoss(Target)) )) { return(true); } } if (HasSpell("Grimoire: Imp")) { bool GrimoireCondition = UseAdditionalDPSPet && ((Target.MaxHealth >= Me.MaxHealth && Target.IsElite() && !UseAdditionalDPSPetBossOnly) || IsBoss(Target)); if (GrimoireCondition) { var GrimoirePet = SelectedGrimoirePet; if (GrimoirePet == WarlockGrimoirePet.CurrentMainPet) { switch (SelectedPet) { case WarlockPet.ManualSelect: case WarlockPet.AutoSelect: GrimoirePet = Target.IsCastingAndInterruptible() ? WarlockGrimoirePet.Felhunter : WarlockGrimoirePet.Doomguard; break; case WarlockPet.SoulImp: GrimoirePet = WarlockGrimoirePet.SoulImp; break; case WarlockPet.Voidwalker: GrimoirePet = WarlockGrimoirePet.Voidwalker; break; case WarlockPet.Succubus: GrimoirePet = WarlockGrimoirePet.Succubus; break; case WarlockPet.Felhunter: GrimoirePet = WarlockGrimoirePet.Felhunter; break; case WarlockPet.Doomguard: GrimoirePet = WarlockGrimoirePet.Doomguard; break; case WarlockPet.Infernal: GrimoirePet = WarlockGrimoirePet.Infernal; break; } } switch (GrimoirePet) { case WarlockGrimoirePet.SoulImp: if (Cast("Grimoire: Imp")) { return(true); } break; case WarlockGrimoirePet.Voidwalker: if (Cast("Grimoire: Voidwalker")) { return(true); } break; case WarlockGrimoirePet.Succubus: if (Cast("Grimoire: Succubus")) { return(true); } break; case WarlockGrimoirePet.Felhunter: if (Cast("Grimoire: Felhunter")) { return(true); } break; case WarlockGrimoirePet.Doomguard: if (Cast("Grimoire: Doomguard")) { return(true); } break; case WarlockGrimoirePet.Infernal: if (Cast("Grimoire: Infernal")) { return(true); } break; } } } if (CurrentBotName == "PvP" && CastFearIfFeasible()) { return(true); } if (CastShadowfuryIfFeasible()) { return(true); } if (DoHealingAndManaManagement()) { return(true); } return(HasGlobalCooldown()); }
/// <summary> /// This will try to cast a fear spell. /// /// It will hereby utilize a FearBanList for players, so it won't try to fear all the time. /// </summary> /// <returns><c>true</c>, if a fear spell was cast, <c>false</c> otherwise.</returns> protected bool CastFearIfFeasible() { if (!FearDoFear) { return(false); } try { FearTrackingList = FearTrackingList.Where(x => !x.IsExpired()).ToList(); // trim the list to all non expired feared objects. var FearableAdds = Adds.Where(x => x.DistanceSquared < 11 * 11); if (CastSelf("Howl of Terror", () => FearableAdds.Count() >= 2)) { foreach (var fearedAdd in FearableAdds.Where(x => x.IsPlayer)) { FearTrackingList.Add(new ExpirableObject(fearedAdd, FearBanTime)); } // Do not fear them again (at least not with feat, howl of terror won't be affected by its fear descision, for the moment...) return(true); } foreach (var add in Adds.Where(x => x.IsPlayer && x.HasAura("Fear"))) { // Add feared adds which were not feared by us //if(FearTrackingList.Count(y => y.Unit == x) == 0) var alreadyAdded = FearTrackingList.FirstOrDefault(y => add.Equals(y.ExpiringObject)); if (alreadyAdded != null) { alreadyAdded.ResetTime(); } else { FearTrackingList.Add(new ExpirableObject(add, FearBanTime)); } } } catch (Exception e) { // catch everything API.PrintError( "Got an error in fear management logic. Disabling fear for now... Please Report to Avoloos.", e ); FearDoFear = false; } UnitObject add2 = Adds.FirstOrDefault(x => x.Target != null && x.DistanceSquared <= SpellMaxRangeSq("Fear")); if (add2 != null && add2.DistanceSquared < SpellMaxRangeSq("Fear")) { var add = add2; // Fear only real close targets which attack us if (CastPreventDouble( "Fear", () => (!add.HasAura("Fear") &&// its not already feared by other ppl. !add.HasAura("Howl of Terror") &&// and its not already feared by howl Target.DistanceSquared <= 6.5 * 6.5 &&// and its close add.Target == Me ||// and its targetting me add.IsCastingAndInterruptible()) &&// or its casting and we can interrupt it with fear :D (FearDoFear && FearTrackingList.Count(x => add.Equals(x.ExpiringObject)) == 0) // and its not banned from fear , add, 1000 )) { return(true); } } return(false); }
/// <summary> /// Does the multitarget rotation. /// </summary> /// <returns><c>true</c>, if a spell was cast, <c>false</c> otherwise.</returns> /// <param name="mobsInFrontOfMe">Mobs in front of me.</param> bool DoMultitargetRotation(int mobsInFrontOfMe) { int burningEmbers = Me.GetPower(WoWPowerType.WarlockDestructionBurningEmbers); if (mobsInFrontOfMe >= 3) { CastSelf( "Mannoroth's Fury", () => HasSpell("Mannoroth's Fury") && !Me.HasAura("Mannoroth's Fury") ); } // Priority #1 if (CastSpellOnBestAoETarget( "Rain of Fire", u => !HasAura("Rain of Fire") && (HasAura("Mannoroth's Fury") || mobsInFrontOfMe >= 5) )) { return(true); } // Priority #2 if ( SpellCooldown("Havoc") <= 0.01 && burningEmbers >= 1 && mobsInFrontOfMe < 12) { // Dont waste Havoc apply it to one of the mid-enemies (high max health, low current health) var havocAdd = Me.Focus; if (!UseHavocOnFocus) { havocAdd = Adds .OrderByDescending(x => x.Health) .FirstOrDefault(x => x.HealthFraction <= HavocHealthPercentage / 100f && x.IsInLoS && x.DistanceSquared <= SpellMaxRangeSq("Havoc")) ?? Adds.FirstOrDefault(); } if (havocAdd != null && havocAdd.IsFriendly) { havocAdd = havocAdd.Target; } if (havocAdd != null && Cast("Havoc", havocAdd)) { return(true); } } // cast Chaosbolt or shadowburn on target as soon as possible and if feasible if (Adds.Count(x => x.HasAura("Havoc", true)) > 0 || burningEmbers >= 4) { var shadowBurnTarget = Adds .Where(x => x.HealthFraction <= 0.2 && !x.HasAura("Havoc") && x.IsInLoS && x.DistanceSquared <= SpellMaxRangeSq("Shadowburn")) .OrderBy(x => x.Health) .FirstOrDefault() ?? Target; if (Cast("Shadowburn", () => mobsInFrontOfMe < 12, shadowBurnTarget)) { return(true); } if (Cast("Chaos Bolt", () => mobsInFrontOfMe < 6)) { return(true); } } if (mobsInFrontOfMe >= 3) { // Apply Immolate to all adds through Cataclysm if (CastSpellOnBestAoETarget("Cataclysm")) { return(true); } } // Priority #3 var countAddsInRange = Adds.Count(x => x.DistanceSquaredTo(Target) <= SpellAoERange("Conflagrate")); if ((burningEmbers >= 2 && countAddsInRange > 2) || (burningEmbers >= 1 && countAddsInRange >= 8)) { // Ensure Fire and Brimstone! CastSelf("Fire and Brimstone", () => !HasAura("Fire and Brimstone")); if (CastSpellOnBestAoETarget("Conflagrate")) { return(true); } if (CastSpellOnBestAoETarget( "Immolate", y => !y.HasAura("Immolate") && y.HpLessThanOrElite(0.15) )) { return(true); } if (CastSpellOnBestAoETarget("Incinerate")) { return(true); } } return(false); }