Пример #1
0
 /// <summary>
 ///   Creates a move behind target behavior. If it cannot fully navigate will move to target location
 /// </summary>
 /// <remarks>
 ///   Created 2/12/2011.
 /// </remarks>
 /// <param name="requirements">Aditional requirments.</param>
 /// <returns>.</returns>
 public static Composite CreateMoveBehindTargetBehavior(SimpleBooleanDelegate requirements)
 {
     return(new Decorator(
                ret =>
     {
         if (StyxWoW.Me.CurrentMap.IsBattleground || !requirements(ret) || Spell.IsCastingOrChannelling() || Group.MeIsTank)
         {
             return false;
         }
         var currentTarget = StyxWoW.Me.CurrentTarget;
         if (currentTarget == null || currentTarget.MeIsSafelyBehind || !currentTarget.IsAlive || BossList.AvoidRearBosses.Contains(currentTarget.Entry))
         {
             return false;
         }
         return currentTarget.Stunned || currentTarget.CurrentTarget != StyxWoW.Me;
     },
                new PrioritySelector(
                    ctx => CalculatePointBehindTarget(),
                    new Decorator(
                        req => Navigator.CanNavigateFully(StyxWoW.Me.Location, (WoWPoint)req, 4),
                        new Sequence(
                            new Action(ret => Logging.WriteDiagnostic("MoveBehind: behind {0} @ {1:F1} yds", StyxWoW.Me.CurrentTarget.SafeName(), StyxWoW.Me.CurrentTarget.Distance)),
                            //Logger.WriteDebug(Color.White, "MoveBehind: behind {0} @ {1:F1} yds", StyxWoW.Me.CurrentTarget.SafeName(), StyxWoW.Me.CurrentTarget.Distance)),
                            new Action(behindPoint => Navigator.MoveTo((WoWPoint)behindPoint)),
                            new Action(behindPoint => StopMoving.AtLocation((WoWPoint)behindPoint))
                            )
                        )
                    )
                ));
 }
Пример #2
0
 /// <summary>
 /// private function to buff individual units.  makes assumptions
 /// that certain states have been checked previously. only the
 /// group interface to PartyBuffs is exposed since it handles the
 /// case of LocalPlayer not in a group as well
 /// </summary>
 /// <param name="name">spell name</param>
 /// <param name="onUnit">unit selection delegate</param>
 /// <param name="requirements">requirements delegate that must be true to cast buff</param>
 /// <param name="myMutexBuffs">list of buffs your mechanics make mutually exclusive for you to cast.  For example, BuffGroup("Blessing of Kings", ret => true, "Blessing of Might") </param>
 /// <returns></returns>
 private static Composite BuffUnit(string name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, params string[] myMutexBuffs)
 {
     return
         (new Decorator(
              ret => onUnit(ret) != null &&
              (PartyBuffType.None != (onUnit(ret).GetMissingPartyBuffs() & GetPartyBuffForSpell(name))) &&
              (myMutexBuffs == null || myMutexBuffs.Count() == 0 || !onUnit(ret).GetAllAuras().Any(a => a.CreatorGuid == StyxWoW.Me.Guid && myMutexBuffs.Contains(a.Name))),
              new Sequence(
                  Spell.Buff(name, onUnit, requirements),
                  new Wait(1, until => StyxWoW.Me.HasPartyBuff(name), new ActionAlwaysSucceed()),
                  new Action(ret =>
     {
         System.Diagnostics.Debug.Assert(PartyBuffType.None != GetPartyBuffForSpell(name));
         if (PartyBuffType.None != GetPartyBuffForSpell(name))
         {
             ResetReadyToPartyBuffTimer();
         }
         else
         {
             Logging.WriteDiagnostic("Programmer Error: should use Spell.Buff(\"{0}\") instead", name);
         }
     })
                  )
              ));
 }
Пример #3
0
 private Composite CastLikeMonk(string spell, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, bool face = false)
 {
     return(new Decorator(
                ret => requirements != null && onUnit != null && requirements(ret) && onUnit(ret) != null && spell != null && CanCastLikeMonk(spell, onUnit(ret)),
                new Sequence(
                    new Styx.TreeSharp.Action(ctx =>
     {
         Logging.Write(LogLevel.Normal, MONK_COLOR, "{0} on {1} at {2:F1} yds at {3:F1}%", spell, onUnit(ctx).Name, onUnit(ctx).Distance, onUnit(ctx).HealthPercent);
         if (face)
         {
             onUnit(ctx).Face();
         }
         SpellManager.Cast(spell, onUnit(ctx));
     }
                                              ),
                    new WaitContinue(TimeSpan.FromMilliseconds((int)StyxWoW.WoWClient.Latency << 1),
                                     ctx => !(SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null),
                                     new ActionAlwaysSucceed()
                                     ),
                    new WaitContinue(TimeSpan.FromMilliseconds((int)StyxWoW.WoWClient.Latency << 1),
                                     ctx => SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null,
                                     new ActionAlwaysSucceed()
                                     )
                    )
                ));
 }
Пример #4
0
        public static Composite CastElementalBlast(UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate requirements = null, SimpleBooleanDelegate cancel = null)
        {
            const string          ELEMENTAL_BLAST = "Elemental Blast";
            UnitSelectionDelegate ondel           = onUnit ?? (o => Me.CurrentTarget);
            SimpleBooleanDelegate reqdel          = requirements ?? (r => true);
            SimpleBooleanDelegate candel          = cancel ?? (c => false);

            // we do a doublecast check with Me as the target
            // .. since the buff appears on us -- a different model requiring custom handling below
            return(new Decorator(
                       req => {
                if (Spell.DoubleCastContains(Me, ELEMENTAL_BLAST))
                {
                    return false;
                }
                if (!Me.HasAuraExpired(ELEMENTAL_BLAST, 0, myAura: true))
                {
                    return false;
                }
                return true;
            },
                       new Sequence(
                           Spell.Cast(ELEMENTAL_BLAST, ondel, reqdel, candel),
                           new Action(r => Spell.UpdateDoubleCast(ELEMENTAL_BLAST, Me, 750))
                           )
                       ));
        }
Пример #5
0
        /// <summary>
        /// Cast "Freeze" pet ability on a target.  Uses a local store for location to
        /// avoid target position changing during cast preparation and being out of
        /// range after range check
        /// </summary>
        /// <param name="onUnit">target to cast on</param>
        /// <returns></returns>
        public static Composite CastFreeze( UnitSelectionDelegate onUnit, SimpleBooleanDelegate require = null)
        {
            if (onUnit == null)
                return new ActionAlwaysFail();

            if (require == null)
                require = req => true;

            return new Sequence(
                ctx => onUnit(ctx),
                new Decorator(
                    req => req != null && (req as WoWUnit).SpellDistance() < 40 && require(req),
                    new Action( r =>
                    {
                        _locFreeze = (r as WoWUnit).Location;
                        if (StyxWoW.Me.Location.Distance(_locFreeze) > 45)
                            _locFreeze = WoWMathHelper.CalculatePointFrom(StyxWoW.Me.Location, _locFreeze, 7f + (r as WoWUnit).CombatReach);
                        if (StyxWoW.Me.Location.Distance(_locFreeze) > 45)
                            return RunStatus.Failure;
                        return RunStatus.Success;
                    })
                    ),
                new Throttle( TimeSpan.FromMilliseconds(250),
                    Pet.CastPetActionOnLocation(
                        "Freeze",
                        on => _locFreeze,
                        ret => !Me.CurrentTarget.TreatAsFrozen()
                        )
                    )
                );
        }
Пример #6
0
 /// <summary>
 ///   Creates a behavior to cast a buff by name, with special requirements, on a specific unit. Returns
 ///   RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spellId">The ID of the buff</param>
 /// <param name = "onUnit">The on unit</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns></returns>
 public static Composite Buff(int spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
 {
     return
         (new Decorator(
              ret => onUnit(ret) != null && !onUnit(ret).Auras.Values.Any(a => a.SpellId == spellId),
              Cast(spellId, onUnit, requirements)));
 }
Пример #7
0
 /// <summary>
 ///  Creates a behavior to start shooting current target with the wand if extra conditions are met.
 /// </summary>
 /// <param name="extra"> Extra conditions to check to start shooting. </param>
 /// <returns></returns>
 public static Composite CreateUseWand(SimpleBooleanDelegate extra)
 {
     return new PrioritySelector(
         new Decorator(
             ret => Item.HasWand && !StyxWoW.Me.IsWanding() && extra(ret),
             new Action(ret => SpellManager.Cast("Shoot")))
         );
 }
Пример #8
0
 private static Composite CastSoulburn(SimpleBooleanDelegate requirements)
 {
     return(new Throttle(2,
                         new Sequence(
                             Spell.Cast("Soulburn", on => Me, ret => Me.CurrentSoulShards > 0 && requirements(ret) && (Me.CurrentTarget.Elite || Me.CurrentTarget.IsBoss()) && !Me.HasAura("Soulburn")),
                             new Wait(TimeSpan.FromMilliseconds(500), ret => Me.HasAura("Soulburn"), new Action(ret => RunStatus.Success))
                             )));
 }
Пример #9
0
 /// <summary>
 ///  Creates a behavior to start shooting current target with the wand if extra conditions are met.
 /// </summary>
 /// <param name="extra"> Extra conditions to check to start shooting. </param>
 /// <returns></returns>
 public static Composite CreateUseWand(SimpleBooleanDelegate extra)
 {
     return(new PrioritySelector(
                new Decorator(
                    ret => Item.HasWand && !StyxWoW.Me.IsWanding() && extra(ret),
                    new Action(ret => SpellManager.Cast("Shoot")))
                ));
 }
Пример #10
0
        /// <summary>
        ///   Creates a behavior to cast a heal spell by name, with special requirements, on a specific unit. Heal behaviors will make sure
        ///   we don't double cast. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
        /// </summary>
        /// <remarks>
        ///   Created 5/2/2011.
        /// </remarks>
        /// <param name = "name">The name.</param>
        /// <param name="checkMovement"></param>
        /// <param name = "onUnit">The on unit.</param>
        /// <param name = "requirements">The requirements.</param>
        /// <returns>.</returns>
        public static Composite Heal(string name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
        {
            return
                (new Sequence(
                     Cast(name, checkMovement, onUnit, requirements),
                     // Little bit wait here to catch casting
                     new WaitContinue(
                         1,
                         ret =>
            {
                WoWSpell spell;
                if (SpellManager.Spells.TryGetValue(name, out spell))
                {
                    if (spell.CastTime == 0)
                    {
                        return true;
                    }

                    return StyxWoW.Me.IsCasting;
                }

                return true;
            },
                         new ActionAlwaysSucceed()),
                     new WaitContinue(
                         10,
                         ret =>
            {
                // Let channeled heals been cast till end.
                if (StyxWoW.Me.ChanneledCastingSpellId != 0)
                {
                    return false;
                }

                // Interrupted or finished casting. Continue
                if (!StyxWoW.Me.IsCasting)
                {
                    return true;
                }

                // 500ms left till cast ends. Shall continue for next spell
                //if (StyxWoW.Me.CurrentCastTimeLeft.TotalMilliseconds < 500)
                //{
                //    return true;
                //}

                // If requirements don't meet anymore, stop casting and let it continue
                if (!requirements(ret))
                {
                    SpellManager.StopCasting();
                    return true;
                }
                return false;
            },
                         new ActionAlwaysSucceed())));
        }
Пример #11
0
 public static Composite UseHealthStoneBehavior(SimpleBooleanDelegate requirements)
 {
     return(new PrioritySelector(
                ctx => StyxWoW.Me.BagItems.FirstOrDefault(i => i.Entry == 5512),
                new Decorator(
                    ret => ret != null && StyxWoW.Me.HealthPercent < 100 && ((WoWItem)ret).Cooldown == 0 && requirements(ret),
                    new Sequence(
                        new Action(ret => Logger.Write("Using {0}", ((WoWItem)ret).Name)),
                        new Action(ret => ((WoWItem)ret).Use())))
                ));
 }
Пример #12
0
 public static Composite CreateUseManaGemBehavior(SimpleBooleanDelegate requirements)
 {
     return(new PrioritySelector(
                ctx => StyxWoW.Me.BagItems.FirstOrDefault(i => i.Entry == 36799),
                new Decorator(
                    ret => ret != null && StyxWoW.Me.ManaPercent < 100 && ((WoWItem)ret).Cooldown == 0 && requirements(ret),
                    new Sequence(
                        new Action(ret => Logger.Write("Using mana gem")),
                        new Action(ret => ((WoWItem)ret).Use())))
                ));
 }
Пример #13
0
 private Composite Cast(string spell, SimpleBooleanDelegate requirements, UnitSelectionDelegate unit)
 {
     return(new Decorator(ret => requirements != null && requirements(ret) && SpellManager.HasSpell(spell) && SpellManager.CanCast(spell, unit(ret), true, true),
                          new Styx.TreeSharp.Action(ctx =>
     {
         SpellManager.Cast(spell, unit(ctx));
         Logging.Write(LogLevel.Normal, MONK_COLOR, "Casting Spell [{0}].", spell);
         return RunStatus.Success;
     })
                          ));
 }
Пример #14
0
 public static Composite PetBuffGroup(string name, SimpleBooleanDelegate requirements, params string[] myMutexBuffs)
 {
     return(new Decorator(
                ret => IsItTimeToBuff() &&
                PetManager.CanCastPetAction("Qiraji Fortitude") &&
                (!StyxWoW.Me.Mounted || !PVP.IsPrepPhase),
                new PrioritySelector(
                    ctx => Unit.GroupMembers.FirstOrDefault(m => m.IsAlive && m.DistanceSqr < 30 * 30 && (PartyBuffType.None != (m.GetMissingPartyBuffs() & GetPartyBuffForSpell(name)))),
                    PetManager.Buff(name, on => (WoWUnit)on, requirements, myMutexBuffs)
                    )
                ));
 }
Пример #15
0
 /// <summary>
 /// checks group members in range if they have a buff providing the benefits
 /// that this spell does, and if not casts the buff upon them.  understands
 /// similar buffs such as Blessing of Kings being same as Mark of the Wild.
 /// if  not in a group, will treat Me as a group of one.
 /// Will not buff if Mounted unless during prep phase of a battleground
 /// </summary>
 /// <param name="name">spell name of buff</param>
 /// <param name="requirements">requirements delegate that must be true for cast to occur</param>
 /// <param name="myMutexBuffs">list of your buffs which are mutually exclusive to 'name'.  For example, BuffGroup("Blessing of Kings", ret => true, "Blessing of Might") </param>
 /// <returns></returns>
 public static Composite BuffGroup(string name, SimpleBooleanDelegate requirements, params string[] myMutexBuffs)
 {
     return
         (new Decorator(ret => IsItTimeToBuff() &&
                        SpellManager.HasSpell(name) &&
                        (!StyxWoW.Me.Mounted || (Battlegrounds.IsInsideBattleground && DateTime.Now < Battlegrounds.BattlefieldStartTime)),
                        new PrioritySelector(
                            ctx => Unit.GroupMembers.FirstOrDefault(m => m.IsAlive && m.DistanceSqr < 30 * 30 && (PartyBuffType.None != (m.GetMissingPartyBuffs() & GetPartyBuffForSpell(name)))),
                            BuffUnit(name, ctx => (WoWUnit)ctx, requirements, myMutexBuffs)
                            )
                        ));
 }
Пример #16
0
 /// <summary>
 ///   Creates a behavior to cast a spell by ID, with special requirements, on a specific unit.
 ///   Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spellId">Identifier for the spell.</param>
 /// <param name = "onUnit">The on unit.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Cast(int spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
 {
     return(new Decorator(
                ret =>
                requirements != null && requirements(ret) && onUnit != null && onUnit(ret) != null && SpellManager.CanCast(spellId, onUnit(ret), true),
                new Action(
                    ret =>
     {
         Logger.Write("Casting " + spellId + " on " + onUnit(ret).SafeName());
         SpellManager.Cast(spellId);
     })
                ));
 }
Пример #17
0
        private static Composite CastRegrowth(UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, SimpleBooleanDelegate cancel)
        {
            SimpleBooleanDelegate require = r => (glyphRegrowth || !Spell.DoubleCastContains((WoWUnit)r, "Regrowth")) && requirements(r);

            return(new Sequence(
                       ctx => onUnit(ctx),
                       Spell.Cast("Regrowth", on => (WoWUnit)on, req => require(req), cancel),
                       new DecoratorContinue(
                           req => !glyphRegrowth,
                           new Action(ret => Spell.UpdateDoubleCast("Regrowth", (WoWUnit)ret))
                           )
                       ));
        }
Пример #18
0
        public static Composite Buff(string spell, UnitSelectionDelegate onUnit, SimpleBooleanDelegate require, params string[] buffNames)
        {
            return(new Decorator(
                       ret =>
            {
                if (onUnit == null || require == null)
                {
                    return false;
                }

                _buffUnit = onUnit(ret);
                if (_buffUnit == null)
                {
                    return false;
                }

                if (spell == null)
                {
                    return false;
                }

                if (Spell.DoubleCastContains(_buffUnit, spell))
                {
                    return false;
                }

                if (!buffNames.Any())
                {
                    return !_buffUnit.HasAura(spell);
                }

                bool buffFound;
                try
                {
                    buffFound = buffNames.Any(b => _buffUnit.HasAura(b));
                }
                catch
                {
                    // mark as found buff, so we return false
                    buffFound = true;
                }

                return !buffFound;
            },
                       new Sequence(
                           // new Action(ctx => _lastBuffCast = name),
                           new Action(r => PetManager.CastPetAction(spell)),
                           new Action(ret => Spell.UpdateDoubleCast(spell, _buffUnit))
                           )
                       ));
        }
Пример #19
0
 /// <summary>
 ///   Creates a move behind target behavior. If it cannot fully navigate will move to target location
 /// </summary>
 /// <remarks>
 ///   Created 2/12/2011.
 /// </remarks>
 /// <param name="requirements">Aditional requirments.</param>
 /// <returns>.</returns>
 public static Composite CreateMoveBehindTargetBehavior(SimpleBooleanDelegate requirements)
 {
     return
         (new Decorator(
              ret => !SingularSettings.Instance.DisableAllMovement &&
              SingularRoutine.CurrentWoWContext != WoWContext.Battlegrounds &&
              requirements(ret) && !StyxWoW.Me.IsCasting &&
              !Group.MeIsTank && !StyxWoW.Me.CurrentTarget.MeIsBehind &&
              StyxWoW.Me.CurrentTarget.IsAlive &&
              (StyxWoW.Me.CurrentTarget.CurrentTarget == null ||
               StyxWoW.Me.CurrentTarget.CurrentTarget != StyxWoW.Me ||
               StyxWoW.Me.CurrentTarget.Stunned),
              new Action(ret => Navigator.MoveTo(CalculatePointBehindTarget()))));
 }
Пример #20
0
        static Composite CastMindFlay(UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate requirements = null)
        {
            UnitSelectionDelegate o = onUnit ?? (on => Me.CurrentTarget);
            SimpleBooleanDelegate r;

            if (requirements == null)
            {
                r = req => Me.ManaPercent > PriestSettings.MindFlayManaPct;
            }
            else
            {
                r = req => Me.ManaPercent > PriestSettings.MindFlayManaPct && requirements(req);
            }

            return(Spell.Cast("Mind Flay",
                              mov => true,
                              o,
                              r,
                              cancel =>
            {
                if (Spell.IsGlobalCooldown())
                {
                    return false;
                }

                if (!Spell.IsSpellOnCooldown("Mind Blast") && Spell.GetSpellCastTime("Mind Blast") == TimeSpan.Zero)
                {
                    Logger.Write(LogColor.Cancel, "/cancel Mind Flay for instant Mind Blast proc");
                }
                else if (Me.HasAura(SURGE_OF_DARKNESS))
                {
                    Logger.Write(LogColor.Cancel, "/cancel Mind Flay for instant Mind Spike proc");
                }
                else if (SpellManager.HasSpell("Shadow Word: Insanity") && Unit.NearbyUnfriendlyUnits.Any(u => u.GetAuraTimeLeft("Shadow Word: Pain", true).TotalMilliseconds.Between(1000, 5000) && u.InLineOfSpellSight))
                {
                    Logger.Write(LogColor.Cancel, "/cancel Mind Flay for Shadow Word: Insanity proc");
                }
                else if (!Spell.IsSpellOnCooldown("Shadow Word: Death") && Unit.NearbyUnfriendlyUnits.Any(u => u.HealthPercent < 20 && u.InLineOfSpellSight))
                {
                    Logger.Write(LogColor.Cancel, "/cancel Mind Flay for Shadow Word: Death proc");
                }
                else
                {
                    return false;
                }

                return true;
            }));
        }
Пример #21
0
        /// <summary>
        /// retrieve best estimation of number of hops a chained spell will make for a given target
        /// </summary>
        /// <param name="target">spell target all hops originate from</param>
        /// <param name="otherUnits">units to consider as possible targets</param>
        /// <param name="chainRange">chain hop distance</param>
        /// <param name="avoid">delegate to determine if an unwanted target would be hit</param>
        /// <returns>0 avoid target would be hit, otherwise count of targets hit (including initial target)</returns>
        public static int GetChainedClusterCount(WoWUnit target, IEnumerable<WoWUnit> otherUnits, float chainRange, SimpleBooleanDelegate avoid = null)
        {
            if (avoid == null)
                return GetChainedCluster(target, otherUnits, chainRange).Count();

            int cnt = 0;
            foreach (var u in GetChainedCluster(target, otherUnits, chainRange))
            {
                cnt++;
                if (avoid(u))
                {
                    cnt = 0;
                    break;
                }
            }
            return cnt;
        }
Пример #22
0
        private static void Set(StopType type, WoWUnit unit, WoWPoint pt, double range, SimpleBooleanDelegate stop, SimpleBooleanDelegate and)
        {
            //if (MovementManager.IsMovementDisabled)
            //    return;

            Type  = type;
            Unit  = unit;
            Point = pt;
            Range = range;

            if (and == null)
            {
                and = ret => true;
            }

            StopNow = ret => stop(ret) && and(ret);
        }
Пример #23
0
        /// <summary>
        /// cast Ice Lance without requiring FoF, but if FoF active wait until buff stack count updated
        /// to ensure we don't break other Ice Lance logic that depends on FoF being accurate
        /// </summary>
        /// <param name="on"></param>
        /// <returns></returns>
        private static Sequence CreateIceLanceBehavior(UnitSelectionDelegate on = null, SimpleBooleanDelegate requirements = null)
        {
            UnitSelectionDelegate ondel  = on ?? (o => Me.CurrentTarget);
            SimpleBooleanDelegate reqdel = requirements ?? (req => true);

            return(new Sequence(
                       ctx => new ILInfo(ondel(ctx), Me.GetAuraStacks(FINGERS_OF_FROST), ctx),
                       new Decorator(
                           req => ILInfo.Ref(req).Unit != null && (ILInfo.Ref(req).StacksOfFOF > 0 || ILInfo.Ref(req).Unit.IsTrivial()) && Spell.CanCastHack("Ice Lance", ILInfo.Ref(req).Unit) && !ILInfo.Ref(req).Unit.IsImmune(WoWSpellSchool.Frost),
                           new Sequence(
                               Spell.Cast("Ice Lance", o => ((ILInfo)o).Unit, r => reqdel(ILInfo.Ref(r).SaveContext)),
                               Helpers.Common.CreateWaitForLagDuration(
                                   until => ILInfo.Ref(until).StacksOfFOF != Me.GetAuraStacks(FINGERS_OF_FROST) || Me.GetAuraStacks(FINGERS_OF_FROST) == 0
                                   )
                               )
                           )
                       ));
        }
Пример #24
0
        /// <summary>
        /// cast Ice Lance only if FoF active.  waits after cast until FoF stack count changes
        /// to ensure we don't double cast Ice Lance (since we queue spells)
        /// </summary>
        /// <param name="on"></param>
        /// <returns></returns>
        private static Sequence CreateIceLanceFoFBehavior(UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate requirements = null)
        {
            UnitSelectionDelegate ondel  = onUnit ?? (o => Me.CurrentTarget);
            SimpleBooleanDelegate reqdel = requirements ?? (req => true);

            return(new Sequence(
                       ctx => new ILInfo(ondel(ctx), Me.GetAuraStacks(FINGERS_OF_FROST), ctx),
                       new Decorator(
                           // req => Spell.CanCastHack("Ice Lance", (req as ILInfo).Unit) && ((req as ILInfo).Unit != null && ((req as ILInfo).StacksOfFOF > 0 || (req as ILInfo).Unit.IsTrivial())),
                           req => ILInfo.Ref(req).Unit != null && ILInfo.Ref(req).StacksOfFOF > 0 && Spell.CanCastHack("Ice Lance", ILInfo.Ref(req).Unit) && !ILInfo.Ref(req).Unit.IsImmune(WoWSpellSchool.Frost),
                           new Sequence(
                               new Action(r => Logger.Write(LogColor.Hilite, "^Fingers of Frost[{0}]: casting buffed Ice Lance", ILInfo.Ref(r).StacksOfFOF)),
                               Spell.Cast("Ice Lance", mov => false, o => ILInfo.Ref(o).Unit, r => reqdel(ILInfo.Ref(r).SaveContext)), // ret => Unit.NearbyUnfriendlyUnits.Count(t => t.Distance <= 10) < 4),
                               Helpers.Common.CreateWaitForLagDuration(
                                   until => ILInfo.Ref(until).StacksOfFOF != Me.GetAuraStacks(FINGERS_OF_FROST)
                                   )
                               )
                           )
                       ));
        }
Пример #25
0
        /// <summary>
        /// Cast "Freeze" pet ability on a target.  Uses a local store for location to
        /// avoid target position changing during cast preparation and being out of
        /// range after range check
        /// </summary>
        /// <param name="onUnit">target to cast on</param>
        /// <returns></returns>
        public static Composite CastFreeze(UnitSelectionDelegate onUnit, SimpleBooleanDelegate require = null)
        {
            if (onUnit == null)
            {
                return(new ActionAlwaysFail());
            }

            if (require == null)
            {
                require = req => true;
            }

            return(new Sequence(
                       ctx => onUnit(ctx),
                       new Decorator(
                           req => req != null && (req as WoWUnit).SpellDistance() < 40 && require(req),
                           new Action(r =>
            {
                _locFreeze = (r as WoWUnit).Location;
                if (StyxWoW.Me.Location.Distance(_locFreeze) > 45)
                {
                    _locFreeze = WoWMathHelper.CalculatePointFrom(StyxWoW.Me.Location, _locFreeze, 7f + (r as WoWUnit).CombatReach);
                }
                if (StyxWoW.Me.Location.Distance(_locFreeze) > 45)
                {
                    return RunStatus.Failure;
                }
                return RunStatus.Success;
            })
                           ),
                       new Throttle(TimeSpan.FromMilliseconds(250),
                                    Pet.CastPetActionOnLocation(
                                        "Freeze",
                                        on => _locFreeze,
                                        ret => !Me.CurrentTarget.TreatAsFrozen()
                                        )
                                    )
                       ));
        }
Пример #26
0
 private Composite SelfCast(string spell, SimpleBooleanDelegate requirements)
 {
     return Cast(spell, requirements, unit => StyxWoW.Me);
 }
Пример #27
0
 /// <summary>
 ///   Creates a behavior to cast a spell by name, on the ground at the specified location. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spell">The spell.</param>
 /// <param name = "onLocation">The on location.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite CastOnGround(string spell, LocationRetriever onLocation, SimpleBooleanDelegate requirements)
 {
     return(new Decorator(
                ret =>
                requirements(ret) && onLocation != null && SpellManager.CanCast(spell) &&
                (StyxWoW.Me.Location.Distance(onLocation(ret)) <= SpellManager.Spells[spell].MaxRange || SpellManager.Spells[spell].MaxRange == 0),
                new Sequence(
                    new Action(ret => Logger.Write("Casting {0} at location {1}", spell, onLocation(ret))),
                    new Action(ret => SpellManager.Cast(spell)),
                    new WaitContinue(
                        1,
                        ret => StyxWoW.Me.CurrentPendingCursorSpell != null &&
                        StyxWoW.Me.CurrentPendingCursorSpell.Name == spell,
                        new ActionAlwaysSucceed()),
                    new Action(ret => LegacySpellManager.ClickRemoteLocation(onLocation(ret))))
                ));
 }
Пример #28
0
 /// <summary>
 ///   Creates a behavior to cast a buff by name, with special requirements, on a specific unit. Returns
 ///   RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spellId">The ID of the buff</param>
 /// <param name = "onUnit">The on unit</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns></returns>
 public static Composite Buff(int spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
 {
     return new Decorator(ret => onUnit(ret) != null && onUnit(ret).Auras.Values.All(a => a.SpellId != spellId),
         Cast(spellId, onUnit, requirements));
 }
Пример #29
0
 public static Composite Buff(string name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements,
     params string[] buffNames)
 {
     return Buff(name, false, onUnit, requirements, buffNames);
 }
Пример #30
0
 public static Composite Buff(string name, bool myBuff, SimpleBooleanDelegate requirements,
     params string[] buffNames)
 {
     return Buff(name, myBuff, ret => StyxWoW.Me.CurrentTarget, requirements, buffNames);
 }
Пример #31
0
 public static Composite CreateCastSoulburn(SimpleBooleanDelegate requirements)
 {
     return new Sequence(
         Spell.BuffSelf("Soulburn", ret => Me.CurrentSoulShards > 0 && requirements(ret)),
         new Wait(TimeSpan.FromMilliseconds(500), ret => Me.HasAura("Soulburn"), new Action(ret => { return RunStatus.Success; }))
         );
 }
Пример #32
0
 /// <summary>
 /// checks group members in range if they have a buff providing the benefits 
 /// that this spell does, and if not casts the buff upon them.  understands
 /// similar buffs such as Blessing of Kings being same as Mark of the Wild.
 /// if  not in a group, will treat Me as a group of one. 
 /// Will not buff if Mounted unless during prep phase of a battleground
 /// </summary>
 /// <param name="name">spell name of buff</param>
 /// <param name="requirements">requirements delegate that must be true for cast to occur</param>
 /// <param name="myMutexBuffs">list of your buffs which are mutually exclusive to 'name'.  For example, BuffGroup("Blessing of Kings", ret => true, "Blessing of Might") </param>
 /// <returns></returns>
 public static Composite BuffGroup(string name, SimpleBooleanDelegate requirements, params string[] myMutexBuffs)
 {
     return
         new Decorator(ret => IsItTimeToBuff()
                             && SpellManager.HasSpell(name)
                             && (!StyxWoW.Me.Mounted || !PVP.IsPrepPhase),
             new PrioritySelector(
                 ctx => Unit.GroupMembers.FirstOrDefault(m => m.IsAlive && m.DistanceSqr < 30 * 30 && (PartyBuffType.None != (m.GetMissingPartyBuffs() & GetPartyBuffForSpell(name)))),
                 BuffUnit(name, ctx => (WoWUnit)ctx, requirements, myMutexBuffs)
                 )
             );
 }
Пример #33
0
 public static Composite Heal(string name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit,
     SimpleBooleanDelegate requirements, bool allowLagTollerance = false)
 {
     return Heal(name, checkMovement, onUnit, requirements,
         ret => onUnit(ret).HealthPercent > SingularSettings.Instance.IgnoreHealTargetsAboveHealth,
         false);
 }
Пример #34
0
 /// <summary>
 ///   Creates a behavior to cast a heal spell by name, with special requirements. Heal behaviors will make sure
 ///   we don't double cast. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "name">The name.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Heal(string name, SimpleBooleanDelegate requirements)
 {
     return Heal(name, ret => true, ret => StyxWoW.Me, requirements);
 }
Пример #35
0
 /// <summary>
 ///   Creates a behavior to cast a spell by name, on the ground at the specified location. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spell">The spell.</param>
 /// <param name = "onLocation">The on location.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite CastOnGround(string spell, LocationRetriever onLocation,
     SimpleBooleanDelegate requirements)
 {
     return CastOnGround(spell, onLocation, requirements, true);
 }
Пример #36
0
 /// <summary>
 ///   Creates a behavior to cast a spell by ID, with special requirements. Returns
 ///   RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spellId">Identifier for the spell.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Cast(int spellId, SimpleBooleanDelegate requirements)
 {
     return Cast(spellId, ret => StyxWoW.Me.CurrentTarget, requirements);
 }
Пример #37
0
 /// <summary>
 ///   Creates a behavior to cast a buff by ID on yourself with special requirements. Returns RunStatus.Success if
 ///   successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/6/2011.
 /// </remarks>
 /// <param name = "spellId">The buff ID.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite BuffSelf(int spellId, SimpleBooleanDelegate requirements)
 {
     return Buff(spellId, ret => StyxWoW.Me, requirements);
 }
Пример #38
0
        private static Composite CreateShieldCharge(UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate requirements = null)
        {
            if (onUnit == null)
                onUnit = on => Me.CurrentTarget;

            if (requirements == null)
                requirements = req => true;

            return new Sequence(
                new Decorator(
                    req => Spell.DoubleCastContains(Me, "Shield Charge") || !HasShieldInOffHand,
                    new ActionAlwaysFail()
                    ),
                Spell.Cast("Shield Charge", onUnit, req => requirements(req), gcd: HasGcd.No),
                new Action(ret => Spell.UpdateDoubleCast("Shield Charge", Me))
                );
        }
Пример #39
0
 public static Composite CreateUseManaGemBehavior(SimpleBooleanDelegate requirements)
 {
     return new Throttle( 2,
         new PrioritySelector(
             ctx => StyxWoW.Me.BagItems.FirstOrDefault(i => i.Entry == 36799 || i.Entry == 81901),
             new Decorator(
                 ret => ret != null && StyxWoW.Me.ManaPercent < 100 && ((WoWItem)ret).Cooldown == 0 && requirements(ret),
                 new Sequence(
                     new Action(ret => Logger.Write("Using {0}", ((WoWItem)ret).Name)),
                     new Action(ret => ((WoWItem)ret).Use())
                     )
                 )
             )
         );
 }
Пример #40
0
 public static Composite CastThrash( UnitSelectionDelegate on, SimpleBooleanDelegate required, int seconds = 2)
 {
     return Spell.Cast( "Thrash", on, req => required(req) && on(req).HasAuraExpired("Thrash",seconds, true));
     // return Spell.Buff("Thrash", true, on, required, 2);
     //  return Spell.Buff(106832, on => Me.CurrentTarget, req => Me.HasAura("Omen of Clarity") && Me.CurrentTarget.HasAuraExpired("Thrash", 3)),
 }
Пример #41
0
 /// <summary>
 ///   Creates a behavior to cast a buff by name, with special requirements, on current target. Returns
 ///   RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "name">The name of the buff</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns></returns>
 public static Composite Buff(string name, SimpleBooleanDelegate requirements)
 {
     return Buff(name, false, ret => StyxWoW.Me.CurrentTarget, requirements, name);
 }
Пример #42
0
 private Composite Cast(string spell, SimpleBooleanDelegate requirements)
 {
     return Cast(spell, requirements, unit => StyxWoW.Me.CurrentTarget);
 }
Пример #43
0
 public static Composite Buff(string name, bool myBuff, UnitSelectionDelegate onUnit,
     SimpleBooleanDelegate requirements)
 {
     return Buff(name, myBuff, onUnit, requirements, name);
 }
Пример #44
0
 private Composite Cast(string spell, SimpleBooleanDelegate requirements, UnitSelectionDelegate unit)
 {
     return new Decorator(ret => requirements != null && requirements(ret) && SpellManager.HasSpell(spell) && SpellManager.CanCast(spell, unit(ret), true, true),
         new Styx.TreeSharp.Action(ctx =>
         {
             SpellManager.Cast(spell, unit(ctx));
             Logging.Write(LogLevel.Normal, MONK_COLOR, "Casting Spell [{0}].", spell);
             return RunStatus.Success;
         })
     );
 }
Пример #45
0
        //private static string _lastBuffCast = string.Empty;
        //private static System.Diagnostics.Stopwatch _castTimer = new System.Diagnostics.Stopwatch();
        /// <summary>
        ///   Creates a behavior to cast a buff by name, with special requirements, on a specific unit. Returns
        ///   RunStatus.Success if successful, RunStatus.Failure otherwise.
        /// </summary>
        /// <remarks>
        ///   Created 5/2/2011.
        /// </remarks>
        /// <param name = "name">The name of the buff</param>
        /// <param name = "myBuff">Check for self debuffs or not</param>
        /// <param name = "onUnit">The on unit</param>
        /// <param name = "requirements">The requirements.</param>
        /// <returns></returns>
        public static Composite Buff(string name, bool myBuff, UnitSelectionDelegate onUnit,
            SimpleBooleanDelegate requirements, params string[] buffNames)
        {
            //if (name == _lastBuffCast && _castTimer.IsRunning && _castTimer.ElapsedMilliseconds < 250)
            //{
            //    return new Action(ret => RunStatus.Success);
            //}

            //if (name == _lastBuffCast && StyxWoW.Me.IsCasting)
            //{
            //    _castTimer.Reset();
            //    _castTimer.Start();
            //    return new Action(ret => RunStatus.Success);
            //}

            return
                new Decorator(
                    ret =>
                    onUnit(ret) != null && !DoubleCastPreventionDict.ContainsKey(name) &&
                    buffNames.All(b => myBuff ? !onUnit(ret).HasMyAura(b) : !onUnit(ret).HasAura(b)),
                    new Sequence( // new Action(ctx => _lastBuffCast = name),
                        Cast(name, onUnit, requirements),
                        new DecoratorContinue(ret => SpellManager.Spells[name].CastTime > 0,
                            new Sequence(new WaitContinue(1, ret => StyxWoW.Me.IsCasting,
                                new Action(ret => UpdateDoubleCastDict(name)))))));
        }
Пример #46
0
 private Composite CastLikeMonk(string spell, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, bool face = false)
 {
     return new Decorator(
         ret => requirements != null && onUnit != null && requirements(ret) && onUnit(ret) != null && spell != null && CanCastLikeMonk(spell, onUnit(ret)),
         new Sequence(
             new Styx.TreeSharp.Action(ctx =>
                 {
                     Logging.Write(LogLevel.Normal, MONK_COLOR, "{0} on {1} at {2:F1} yds at {3:F1}%", spell, onUnit(ctx).Name, onUnit(ctx).Distance, onUnit(ctx).HealthPercent);
                     if (face)
                         onUnit(ctx).Face();
                     SpellManager.Cast(spell, onUnit(ctx));
                 }
             ),
             new WaitContinue(TimeSpan.FromMilliseconds((int)StyxWoW.WoWClient.Latency << 1),
                 ctx => !(SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null),
                 new ActionAlwaysSucceed()
             ),
             new WaitContinue(TimeSpan.FromMilliseconds((int)StyxWoW.WoWClient.Latency << 1),
                 ctx => SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null,
                 new ActionAlwaysSucceed()
             )
         )
     );
 }
Пример #47
0
 /// <summary>
 ///   Creates a behavior to cast a buff by name on yourself with special requirements. Returns RunStatus.Success if
 ///   successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/6/2011.
 /// </remarks>
 /// <param name = "name">The buff name.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite BuffSelf(string name, SimpleBooleanDelegate requirements)
 {
     return Buff(name, ret => StyxWoW.Me, requirements);
 }
Пример #48
0
        public static Composite StopAndCast(string name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
        {
            return(new Decorator(
                       ret =>
            {
                return requirements(ret) && onUnit(ret) != null && SpellManager.CanCast(name, onUnit(ret), true, false);
            },
                       new Action(
                           ret =>
            {
                WoWSpell spell = GetSpellByName(name);

                if (spell.CastTime > 0 && StyxWoW.Me.IsMoving)
                {
                    WoWMovement.MoveStop();
                }

                Logger.Write("Casting " + name + " on " + onUnit(ret).SafeName());
                SpellManager.Cast(name, onUnit(ret));
            })
                       ));
        }
Пример #49
0
 /// <summary>
 ///   Creates a behavior to cast a spell by name, with special requirements. Returns RunStatus.Success if successful,
 ///   RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "name">The name.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Cast(string name, SimpleBooleanDelegate requirements)
 {
     return Cast(name, ret => true, ret => StyxWoW.Me.CurrentTarget, requirements);
 }
Пример #50
0
 public static void AtLocation(WoWPoint pt, SimpleBooleanDelegate and = null)
 {
     Set(StopType.Location, null, pt, 0, at => StyxWoW.Me.Location.Distance(pt) <= 1, and);
 }
Пример #51
0
 /// <summary>
 ///   Creates a behavior to cast a spell by ID, with special requirements, on a specific unit.
 ///   Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "spellId">Identifier for the spell.</param>
 /// <param name = "onUnit">The on unit.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Cast(int spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
 {
     return
         new Decorator(ret => requirements != null && requirements(ret) && onUnit != null && onUnit(ret) != null && SpellManager.CanCast(spellId, onUnit(ret),true),
             new Action(ret =>
                 {
                     Logger.Write(string.Format("Casting {0} on {1}", spellId, onUnit(ret).SafeName()));
                     SpellManager.Cast(spellId);
                 }));
 }
Пример #52
0
 public static void InRangeOfLocation(WoWPoint pt, double range, SimpleBooleanDelegate and = null)
 {
     Set(StopType.RangeOfLocation, null, pt, range, at => StyxWoW.Me.Location.Distance(pt) <= range, and);
 }
Пример #53
0
        /// <summary>
        ///   Creates a behavior to cast a spell by name, on the ground at the specified location. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
        /// </summary>
        /// <remarks>
        ///   Created 5/2/2011.
        /// </remarks>
        /// <param name = "spell">The spell.</param>
        /// <param name = "onLocation">The on location.</param>
        /// <param name = "requirements">The requirements.</param>
        /// <param name="waitForSpell">Waits for spell to become active on cursor if true. </param>
        /// <returns>.</returns>
        public static Composite CastOnGround(string spell, LocationRetriever onLocation,
            SimpleBooleanDelegate requirements, bool waitForSpell)
        {
            return
                new Decorator(
                    ret =>
                    requirements(ret) && onLocation != null && SpellManager.CanCast(spell) &&
                    (StyxWoW.Me.Location.Distance(onLocation(ret)) <= SpellManager.Spells[spell].MaxRange ||
                     SpellManager.Spells[spell].MaxRange == 0) && GameWorld.IsInLineOfSpellSight(StyxWoW.Me.Location, onLocation(ret)),
                    new Sequence(
                        new Action(ret => Logger.Write("Casting {0} at location {1}", spell, onLocation(ret))),
                        new Action(ret => SpellManager.Cast(spell)),

                        new DecoratorContinue(ctx => waitForSpell,
                            new WaitContinue(1,
                                ret =>
                                StyxWoW.Me.CurrentPendingCursorSpell != null &&
                                StyxWoW.Me.CurrentPendingCursorSpell.Name == spell, new ActionAlwaysSucceed())),

                        new Action(ret => SpellManager.ClickRemoteLocation(onLocation(ret)))));
        }
Пример #54
0
 public static void InRangeOfUnit(WoWUnit unit, double range, SimpleBooleanDelegate and = null)
 {
     Set(StopType.RangeOfUnit, unit, WoWPoint.Empty, range, at => Unit == null || !Unit.IsValid || Unit.Distance <= range, and);
 }
Пример #55
0
 /// <summary>
 ///   Creates a behavior to cast a heal spell by name, on a specific unit. Heal behaviors will make sure
 ///   we don't double cast. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
 /// </summary>
 /// <remarks>
 ///   Created 5/2/2011.
 /// </remarks>
 /// <param name = "name">The name.</param>
 /// <param name = "onUnit">The on unit.</param>
 /// <param name = "requirements">The requirements.</param>
 /// <returns>.</returns>
 public static Composite Heal(string name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements)
 {
     return Heal(name, ret => true, onUnit, requirements);
 }
Пример #56
0
 public static void InMeleeRangeOfUnit(WoWUnit unit, SimpleBooleanDelegate and = null)
 {
     Set(StopType.RangeOfUnit, unit, WoWPoint.Empty, 0, at => Unit == null || !Unit.IsValid || Movement.InMoveToMeleeStopRange(Unit), and);
 }
Пример #57
0
        /// <summary>
        ///   Creates a behavior to cast a heal spell by name, with special requirements, on a specific unit. Heal behaviors will make sure
        ///   we don't double cast. Returns RunStatus.Success if successful, RunStatus.Failure otherwise.
        /// </summary>
        /// <remarks>
        ///   Created 5/2/2011.
        /// </remarks>
        /// <param name = "name">The name.</param>
        /// <param name="checkMovement"></param>
        /// <param name = "onUnit">The on unit.</param>
        /// <param name = "requirements">The requirements.</param>
        /// <param name="cancel">The cancel cast in progress delegate</param>
        /// <param name="allowLagTollerance">allow next spell to queue before this one completes</param>
        /// <returns>.</returns>
        public static Composite Heal(string name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit,
            SimpleBooleanDelegate requirements, SimpleBooleanDelegate cancel, bool allowLagTollerance = false)
        {
            return new PrioritySelector(

                // save context of currently in a GCD or IsCasting before our Cast
                ctx => (bool)(SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null),

                new Sequence(

                    Cast(name, checkMovement, onUnit, requirements),

                    // if saved context indicates action was in progress (so we queued this one) then wait briefly for its progress to finish
                    new WaitContinue(
                        new TimeSpan(0, 0, 0, 0, (int) StyxWoW.WoWClient.Latency * 2),
                        ret => !((bool)ret) || !(SpellManager.GlobalCooldown || StyxWoW.Me.IsCasting || StyxWoW.Me.ChanneledSpell != null),
                        new ActionAlwaysSucceed()
                        ),

                    // now for non-instant spell, wait for .IsCasting to be true
                    new WaitContinue(1,
                        ret => {
                            WoWSpell spell;
                            if (SpellManager.Spells.TryGetValue(name, out spell))
                            {
                                if (spell.CastTime == 0)
                                    return true;

                                return StyxWoW.Me.IsCasting;
                            }

                            return true;
                            },
                        new ActionAlwaysSucceed()
                        ),

                    // finally, wait at this point until heal completes
                    new WaitContinue(10,
                        ret => {
                            // Let channeled heals been cast till end.
                            if (StyxWoW.Me.ChanneledSpell != null) // .ChanneledCastingSpellId != 0)
                            {
                                return false;
                            }

                            // Interrupted or finished casting. Continue (note: following test doesn't deal with latency)
                            if (!StyxWoW.Me.IsCasting)
                            {
                                return true;
                            }

                            // when doing lag tolerance, don't wait for spell to complete before considering finished
                            if (allowLagTollerance)
                            {
                                TimeSpan castTimeLeft = StyxWoW.Me.CurrentCastTimeLeft;
                                if (castTimeLeft != TimeSpan.Zero && castTimeLeft.TotalMilliseconds < (StyxWoW.WoWClient.Latency * 2))
                                    return true;
                            }

                            // 500ms left till cast ends. Shall continue for next spell
                            //if (StyxWoW.Me.CurrentCastTimeLeft.TotalMilliseconds < 500)
                            //{
                            //    return true;
                            //}

                            // temporary hack - checking requirements won't work -- either need global value or cancelDelegate
                            // if ( onUnit(ret).HealthPercent > SingularSettings.Instance.IgnoreHealTargetsAboveHealth) // (!requirements(ret))
                            if ( cancel(ret) )
                            {
                                SpellManager.StopCasting();
                                Logger.Write(System.Drawing.Color.Orange, "/cancel {0} on {1} @ {2:F1}%", name, onUnit(ret).SafeName(), onUnit(ret).HealthPercent);
                                return true;
                            }

                            return false;
                        },
                        new ActionAlwaysSucceed()
                        )
                    )
                );
        }
Пример #58
0
 public static void InLosOfUnit(WoWUnit unit, SimpleBooleanDelegate and = null)
 {
     Set(StopType.LosOfUnit, unit, WoWPoint.Empty, 0, at => Unit == null || !Unit.IsValid || Movement.InLineOfSpellSight(Unit), and);
 }
Пример #59
0
 /// <summary>
 /// private function to buff individual units.  makes assumptions
 /// that certain states have been checked previously. only the 
 /// group interface to PartyBuffs is exposed since it handles the
 /// case of LocalPlayer not in a group as well
 /// </summary>
 /// <param name="name">spell name</param>
 /// <param name="onUnit">unit selection delegate</param>
 /// <param name="requirements">requirements delegate that must be true to cast buff</param>
 /// <param name="myMutexBuffs">list of buffs your mechanics make mutually exclusive for you to cast.  For example, BuffGroup("Blessing of Kings", ret => true, "Blessing of Might") </param>
 /// <returns></returns>
 private static Composite BuffUnit(string name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, params string[] myMutexBuffs)
 {
     return
         new Decorator(
             ret => onUnit(ret) != null
                 && (PartyBuffType.None != (onUnit(ret).GetMissingPartyBuffs() & GetPartyBuffForSpell(name)))
                 && (myMutexBuffs == null || myMutexBuffs.Count() == 0 || !onUnit(ret).GetAllAuras().Any(a => a.CreatorGuid == StyxWoW.Me.Guid && myMutexBuffs.Contains(a.Name))),
             new Sequence(
                 Spell.Buff( name, onUnit, requirements),
                 new Wait( 1, until => StyxWoW.Me.HasPartyBuff(name), new ActionAlwaysSucceed()),
                 new Action(ret =>
                     {
                     System.Diagnostics.Debug.Assert( PartyBuffType.None != GetPartyBuffForSpell(name));
                     if (PartyBuffType.None != GetPartyBuffForSpell(name))
                         ResetReadyToPartyBuffTimer();
                     else
                         Logger.WriteDebug("Programmer Error: should use Spell.Buff(\"{0}\") instead", name);
                     })
                 )
             );
 }
Пример #60
0
 public static void AsSoonAsPossible(SimpleBooleanDelegate and = null)
 {
     Set(StopType.AsSoonAsPossible, null, WoWPoint.Empty, 0, at => true, and);
 }