Esempio n. 1
0
        /// <summary>Creates an interrupt spell cast composite. This attempts to use spells in order of range (shortest to longest).  
        /// behavior consists only of spells that apply to current toon based upon class, spec, and race
        /// </summary>
        public static Composite CreateInterruptBehavior()
        {
            if ( SingularSettings.Instance.InterruptTarget == CheckTargets.None )
                return new ActionAlwaysFail();

            Composite actionSelectTarget;
            if (SingularSettings.Instance.InterruptTarget == CheckTargets.Current)
                actionSelectTarget = new Action(
                    ret => {
                        WoWUnit u = Me.CurrentTarget;
                        _unitInterrupt = IsInterruptTarget(u) ? u : null;
                        if (_unitInterrupt != null && SingularSettings.Debug)
                            Logger.WriteDebug("Possible Interrupt Target: {0} @ {1:F1} yds casting {2} #{3} for {4} ms", _unitInterrupt.SafeName(), _unitInterrupt.Distance, _unitInterrupt.CastingSpell.Name, _unitInterrupt.CastingSpell.Id, _unitInterrupt.CurrentCastTimeLeft.TotalMilliseconds );
                    }
                    );
            else // if ( SingularSettings.Instance.InterruptTarget == InterruptType.All )
            {
                actionSelectTarget = new Action(
                    ret => {
                        _unitInterrupt = Unit.NearbyUnitsInCombatWithMeOrMyStuff.Where(u => IsInterruptTarget(u)).OrderBy( u => u.Distance ).FirstOrDefault();
                        if (_unitInterrupt != null && SingularSettings.Debug)
                            Logger.WriteDebug("Possible Interrupt Target: {0} @ {1:F1} yds casting {2} #{3} for {4} ms", _unitInterrupt.SafeName(), _unitInterrupt.Distance, _unitInterrupt.CastingSpell.Name, _unitInterrupt.CastingSpell.Id, _unitInterrupt.CurrentCastTimeLeft.TotalMilliseconds);
                        }
                    );
            }

            PrioritySelector prioSpell = new PrioritySelector();

            #region Pet Spells First!

            if (Me.Class == WoWClass.Warlock)
            {
                // this will be either a Optical Blast or Spell Lock
                prioSpell.AddChild(
                    Spell.Cast(
                        "Command Demon",
                        on => _unitInterrupt,
                        ret => _unitInterrupt != null
                            && _unitInterrupt.Distance < 40
                            && Singular.ClassSpecific.Warlock.Common.GetCurrentPet() == WarlockPet.Felhunter
                        )
                    );
            }

            #endregion

            #region Melee Range

            if ( Me.Class == WoWClass.Paladin )
                prioSpell.AddChild( Spell.Cast("Rebuke", ctx => _unitInterrupt));

            if ( Me.Class == WoWClass.Rogue)
            {
                prioSpell.AddChild( Spell.Cast("Kick", ctx => _unitInterrupt));
                prioSpell.AddChild( Spell.Cast("Gouge", ctx => _unitInterrupt, ret => !_unitInterrupt.IsBoss() && Me.IsSafelyFacing(_unitInterrupt)));
            }

            if ( Me.Class == WoWClass.Warrior)
                prioSpell.AddChild( Spell.Cast("Pummel", ctx => _unitInterrupt));

            if ( Me.Class == WoWClass.Monk )
                prioSpell.AddChild( Spell.Cast("Spear Hand Strike", ctx => _unitInterrupt));

            if ( Me.Class == WoWClass.Druid)
            {
                // Spell.Cast("Skull Bash (Cat)", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Cat));
                // Spell.Cast("Skull Bash (Bear)", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Bear));
                prioSpell.AddChild( Spell.Cast("Skull Bash", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Bear || StyxWoW.Me.Shapeshift == ShapeshiftForm.Cat));
                prioSpell.AddChild( Spell.Cast("Mighty Bash", ctx => _unitInterrupt, ret => !_unitInterrupt.IsBoss() && _unitInterrupt.IsWithinMeleeRange));
            }

            if ( Me.Class == WoWClass.DeathKnight)
                prioSpell.AddChild( Spell.Cast("Mind Freeze", ctx => _unitInterrupt));

            if ( Me.Race == WoWRace.Pandaren )
                prioSpell.AddChild( Spell.Cast("Quaking Palm", ctx => _unitInterrupt));

            #endregion

            #region 8 Yard Range

            if ( Me.Race == WoWRace.BloodElf )
                prioSpell.AddChild(Spell.Cast("Arcane Torrent", ctx => _unitInterrupt, req => _unitInterrupt.Distance < 8 && !Unit.NearbyUnfriendlyUnits.Any(u => u.IsSensitiveDamage( 8))));

            if ( Me.Race == WoWRace.Tauren)
                prioSpell.AddChild(Spell.Cast("War Stomp", ctx => _unitInterrupt, ret => _unitInterrupt.Distance < 8 && !_unitInterrupt.IsBoss() && !Unit.NearbyUnfriendlyUnits.Any(u => u.IsSensitiveDamage( 8))));

            #endregion

            #region 10 Yards

            if (Me.Class == WoWClass.Paladin)
                prioSpell.AddChild( Spell.Cast("Hammer of Justice", ctx => _unitInterrupt));

            if (Me.Specialization == WoWSpec.DruidBalance )
                prioSpell.AddChild( Spell.Cast("Hammer of Justice", ctx => _unitInterrupt));

            if (Me.Class == WoWClass.Warrior)
                prioSpell.AddChild( Spell.Cast("Disrupting Shout", ctx => _unitInterrupt));

            #endregion

            #region 25 yards

            if ( Me.Class == WoWClass.Shaman)
                prioSpell.AddChild( Spell.Cast("Wind Shear", ctx => _unitInterrupt, req => Me.IsSafelyFacing(_unitInterrupt)));

            #endregion

            #region 30 yards

            if (Me.Specialization == WoWSpec.PaladinProtection)
                prioSpell.AddChild( Spell.Cast("Avenger's Shield", ctx => _unitInterrupt));

            if (Me.Class == WoWClass.Shaman)
                // Gag Order only works on non-bosses due to it being a silence, not an interrupt!
                prioSpell.AddChild( Spell.Cast("Heroic Throw", ctx => _unitInterrupt, ret => TalentManager.HasGlyph("Gag Order") && !_unitInterrupt.IsBoss()));

            if ( Me.Class == WoWClass.Priest )
                prioSpell.AddChild( Spell.Cast("Silence", ctx => _unitInterrupt));

            if (Me.Class == WoWClass.DeathKnight)
                prioSpell.AddChild(Spell.Cast("Strangulate", ctx => _unitInterrupt));

            if (Me.Class == WoWClass.Mage)
                prioSpell.AddChild(Spell.Cast("Frostjaw", ctx => _unitInterrupt));

            #endregion

            #region 40 yards

            if ( Me.Class == WoWClass.Mage)
                prioSpell.AddChild( Spell.Cast("Counterspell", ctx => _unitInterrupt));

            if ( Me.Class == WoWClass.Hunter)
                prioSpell.AddChild( Spell.Cast("Silencing Shot", ctx => _unitInterrupt));

            if ( Me.Class == WoWClass.Druid)
                prioSpell.AddChild( Spell.Cast("Solar Beam", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Moonkin));

            if (Me.Specialization == WoWSpec.ShamanElemental || Me.Specialization == WoWSpec.ShamanEnhancement )
                prioSpell.AddChild( Spell.Cast("Solar Beam", ctx => _unitInterrupt, ret => true));

            #endregion

            return new Throttle(
                new Sequence(
                    actionSelectTarget,
                    new Decorator(
                        ret => _unitInterrupt != null,
                        // majority of these are off GCD, so throttle all to avoid most fail messages
                        new Throttle( TimeSpan.FromMilliseconds(500), prioSpell )
                        )
                    )
                );
        }
Esempio n. 2
0
        /// <summary>Creates an interrupt spell cast composite. This attempts to use spells in order of range (shortest to longest).
        /// behavior consists only of spells that apply to current toon based upon class, spec, and race
        /// </summary>
        public static Composite CreateInterruptBehavior()
        {
            Composite actionSelectTarget;

            if (Me.CurrentTarget != null)
            {
                actionSelectTarget = new Action(
                    ret => {
                    WoWUnit u      = Me.CurrentTarget;
                    _unitInterrupt = IsInterruptTarget(u) ? u : null;
                    if (_unitInterrupt != null)
                    {
                        Logging.WriteDiagnostic("Possible Interrupt Target: {0} @ {1:F1} yds casting {2} #{3} for {4} ms", _unitInterrupt.SafeName(), _unitInterrupt.Distance, _unitInterrupt.CastingSpell.Name, _unitInterrupt.CastingSpell.Id, _unitInterrupt.CurrentCastTimeLeft.TotalMilliseconds);
                    }
                }
                    );
            }
            else // if ( SingularSettings.Instance.InterruptTarget == InterruptType.All )
            {
                actionSelectTarget = new Action(
                    ret => {
                    _unitInterrupt = Unit.NearbyUnfriendlyUnits.Where(u => IsInterruptTarget(u)).OrderBy(u => u.Distance).FirstOrDefault();
                    if (_unitInterrupt != null)
                    {
                        Logging.WriteDiagnostic("Possible Interrupt Target: {0} @ {1:F1} yds casting {2} #{3} for {4} ms", _unitInterrupt.SafeName(), _unitInterrupt.Distance, _unitInterrupt.CastingSpell.Name, _unitInterrupt.CastingSpell.Id, _unitInterrupt.CurrentCastTimeLeft.TotalMilliseconds);
                    }
                }
                    );
            }

            PrioritySelector prioSpell = new PrioritySelector();

            #region Pet Spells First!

            if (Me.Class == WoWClass.Warlock)
            {
                // this will be either a Optical Blast or Spell Lock
                prioSpell.AddChild(
                    Spell.Cast(
                        "Command Demon",
                        on => _unitInterrupt,
                        ret => _unitInterrupt != null &&
                        _unitInterrupt.Distance < 40
                        )
                    );
            }

            #endregion

            #region Melee Range

            if (Me.Class == WoWClass.Paladin)
            {
                prioSpell.AddChild(Spell.Cast("Rebuke", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Rogue)
            {
                prioSpell.AddChild(Spell.Cast("Kick", ctx => _unitInterrupt, true));
                prioSpell.AddChild(Spell.Cast("Gouge", ctx => _unitInterrupt, ret => !_unitInterrupt.IsBoss() && Me.IsSafelyFacing(_unitInterrupt)));
            }

            if (Me.Class == WoWClass.Warrior)
            {
                prioSpell.AddChild(Spell.Cast("Pummel", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Monk)
            {
                prioSpell.AddChild(Spell.Cast("Spear Hand Strike", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Druid)
            {
                // Spell.Cast("Skull Bash (Cat)", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Cat));
                // Spell.Cast("Skull Bash (Bear)", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Bear));
                prioSpell.AddChild(Spell.Cast("Skull Bash", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Bear || StyxWoW.Me.Shapeshift == ShapeshiftForm.Cat, true));
                prioSpell.AddChild(Spell.Cast("Mighty Bash", ctx => _unitInterrupt, ret => !_unitInterrupt.IsBoss() && _unitInterrupt.IsWithinMeleeRange));
            }

            if (Me.Class == WoWClass.DeathKnight)
            {
                prioSpell.AddChild(Spell.Cast("Mind Freeze", ctx => _unitInterrupt, true));
            }

            if (Me.Race == WoWRace.Pandaren)
            {
                prioSpell.AddChild(Spell.Cast("Quaking Palm", ctx => _unitInterrupt));
            }

            #endregion

            #region 8 Yard Range

            if (Me.Race == WoWRace.BloodElf)
            {
                prioSpell.AddChild(Spell.Cast("Arcane Torrent", ctx => _unitInterrupt, req => _unitInterrupt.Distance < 8 && !Unit.NearbyUnfriendlyUnits.Any(u => u.IsSensitiveDamage(8f)), true));
            }

            if (Me.Race == WoWRace.Tauren)
            {
                prioSpell.AddChild(Spell.Cast("War Stomp", ctx => _unitInterrupt, ret => _unitInterrupt.Distance < 8 && !_unitInterrupt.IsBoss() && !Unit.NearbyUnfriendlyUnits.Any(u => u.IsSensitiveDamage(8f))));
            }

            #endregion

            #region 10 Yards

            if (Me.Class == WoWClass.Paladin)
            {
                prioSpell.AddChild(Spell.Cast("Hammer of Justice", ctx => _unitInterrupt));
            }

            if (Me.Specialization == WoWSpec.DruidBalance)
            {
                prioSpell.AddChild(Spell.Cast("Hammer of Justice", ctx => _unitInterrupt));
            }

            if (Me.Class == WoWClass.Warrior)
            {
                prioSpell.AddChild(Spell.Cast("Disrupting Shout", ctx => _unitInterrupt, true));
            }

            #endregion

            #region 25 yards

            if (Me.Class == WoWClass.Shaman)
            {
                prioSpell.AddChild(Spell.Cast("Wind Shear", ctx => _unitInterrupt, req => Me.IsSafelyFacing(_unitInterrupt), true));
            }

            #endregion

            #region 30 yards

            if (Me.Specialization == WoWSpec.PaladinProtection)
            {
                prioSpell.AddChild(Spell.Cast("Avenger's Shield", ctx => _unitInterrupt));
            }

            if (Me.Class == WoWClass.Shaman)
            {
                // Gag Order only works on non-bosses due to it being a silence, not an interrupt!
                prioSpell.AddChild(Spell.Cast("Heroic Throw", ctx => _unitInterrupt, ret => TalentManager.HasGlyph("Gag Order") && !_unitInterrupt.IsBoss()));
            }

            if (Me.Class == WoWClass.Priest)
            {
                prioSpell.AddChild(Spell.Cast("Silence", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.DeathKnight)
            {
                prioSpell.AddChild(Spell.Cast("Strangulate", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Mage)
            {
                prioSpell.AddChild(Spell.Cast("Frostjaw", ctx => _unitInterrupt));
            }

            #endregion

            #region 40 yards

            if (Me.Class == WoWClass.Mage)
            {
                prioSpell.AddChild(Spell.Cast("Counterspell", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Hunter)
            {
                prioSpell.AddChild(Spell.Cast("Silencing Shot", ctx => _unitInterrupt, true));
            }

            if (Me.Class == WoWClass.Druid)
            {
                prioSpell.AddChild(Spell.Cast("Solar Beam", ctx => _unitInterrupt, ret => StyxWoW.Me.Shapeshift == ShapeshiftForm.Moonkin, true));
            }

            if (Me.Specialization == WoWSpec.ShamanElemental || Me.Specialization == WoWSpec.ShamanEnhancement)
            {
                prioSpell.AddChild(Spell.Cast("Solar Beam", ctx => _unitInterrupt, true));
            }

            #endregion

            return(new Sequence(
                       actionSelectTarget,
                       new Decorator(
                           ret => _unitInterrupt != null,
                           // majority of these are off GCD, so throttle all to avoid most fail messages
                           new Throttle(TimeSpan.FromMilliseconds(500), prioSpell)
                           )
                       ));
        }