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))));
        }
Esempio n. 2
0
        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))));
        }
Esempio n. 3
0
        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));
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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);
                }