示例#1
0
        public static Composite CreateRestoShamanCombatBehaviorSolo()
        {
            return(new PrioritySelector(

                       Helpers.Common.EnsureReadyToAttackFromMediumRange(),

                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               CreateRestoDiagnosticOutputBehavior(on => null),

                               Helpers.Common.CreateInterruptBehavior(),
                               Totems.CreateTotemsBehavior(),

                               Movement.WaitForFacing(),
                               Movement.WaitForLineOfSpellSight(),

                               Dispelling.CreatePurgeEnemyBehavior("Purge"),

                               Common.CastElementalBlast(),
                               Spell.Buff("Flame Shock", 3, on => Me.CurrentTarget, req => true),
                               Spell.Cast("Lava Burst"),
                               Spell.Cast("Frost Shock"),
                               Spell.Cast("Chain Lightning", ret => Spell.UseAOE && Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2 && !Unit.UnfriendlyUnitsNearTarget(12f).Any(u => u.IsCrowdControlled())),
                               Spell.Cast("Lightning Bolt")
                               )
                           )
                       ));
        }
示例#2
0
        public static Composite CreateRestoShamanCombatBehaviorBattlegrounds()
        {
            return(new PrioritySelector(

                       Spell.WaitForCastOrChannel(),

                       CreateRestoDiagnosticOutputBehavior(on => HealerManager.Instance.FirstUnit),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown() && HealerManager.Instance.TargetList.Any(t => !t.IsMe && t.IsAlive),
                           new PrioritySelector(
                               HealerManager.CreateStayNearTankBehavior(),
                               CreateRestoShamanHealingOnlyBehavior(selfOnly: false)
                               )
                           ),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown() && HealerManager.AllowHealerDPS(),
                           new PrioritySelector(

                               Helpers.Common.EnsureReadyToAttackFromMediumRange(),

                               Spell.WaitForCastOrChannel(),

                               new Decorator(
                                   ret => !Spell.IsGlobalCooldown(),
                                   new PrioritySelector(

                                       Helpers.Common.CreateInterruptBehavior(),
                                       Totems.CreateTotemsBehavior(),

                                       Movement.WaitForFacing(),
                                       Movement.WaitForLineOfSpellSight(),

                                       Dispelling.CreatePurgeEnemyBehavior("Purge"),

                                       Common.CastElementalBlast(),
                                       Spell.Buff("Flame Shock", 3, on => Me.CurrentTarget, req => true),
                                       Spell.Cast("Lava Burst"),
                                       Spell.Cast("Frost Shock"),
                                       Spell.Cast("Chain Lightning", ret => Spell.UseAOE && Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2 && !Unit.UnfriendlyUnitsNearTarget(12f).Any(u => u.IsCrowdControlled())),
                                       Spell.Cast("Lightning Bolt")
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#3
0
        public static Composite CreateShamanEnhancementNormalPull()
        {
            return(new PrioritySelector(
                       new Decorator(req => Me.Level < 20, Helpers.Common.EnsureReadyToAttackFromMediumRange()),
                       new Decorator(req => Me.Level >= 20, Helpers.Common.EnsureReadyToAttackFromMelee()),
                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               CreateEnhanceDiagnosticOutputBehavior(),

                               Common.CreateShamanDpsShieldBehavior(),

                               Totems.CreateTotemsBehavior(),

                               Movement.WaitForFacing(),
                               Movement.WaitForLineOfSpellSight(),

                               Spell.Cast("Feral Lunge", ret => ShamanSettings.UseFeralLunge),

                               Spell.Cast("Lightning Bolt", ret => !ShamanSettings.AvoidMaelstromDamage && StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                               Spell.Cast("Unleash Elements",
                                          ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id == 5),
                               new Decorator(
                                   req => Spell.UseAOE,
                                   new PrioritySelector(
                                       Spell.Cast("Flame Shock", req => StyxWoW.Me.HasAura("Unleash Flame")),
                                       Spell.Buff("Flame Shock", true, req => Me.CurrentTarget.Elite || (!Me.CurrentTarget.IsTrivial() && Unit.UnfriendlyUnits(12).Count() > 1))
                                       )
                                   ),

                               Spell.Cast("Frost Shock"),

                               Spell.Cast("Lightning Bolt", ret => Me.Level < 20 || Me.CurrentTarget.IsFlying || !Movement.CanNavigateToMelee(Me.CurrentTarget))
                               )
                           )
                       ));
        }
示例#4
0
        public static Composite CreateRestoShamanHealingOnlyBehavior(bool selfOnly = false)
        {
            HealerManager.NeedHealTargeting = true;
            PrioritizedBehaviorList behavs = new PrioritizedBehaviorList();
            int cancelHeal = (int)Math.Max(SingularSettings.Instance.IgnoreHealTargetsAboveHealth, Math.Max(ShamanSettings.RestoHealSettings.HealingWave, ShamanSettings.RestoHealSettings.HealingSurge));

            bool moveInRange = false;

            if (!selfOnly)
            {
                moveInRange = (SingularRoutine.CurrentWoWContext == WoWContext.Battlegrounds);
            }

            Logger.WriteDebugInBehaviorCreate("Shaman Healing: will cancel cast of direct heal if health reaches {0:F1}%", cancelHeal);

            int dispelPriority = (SingularSettings.Instance.DispelDebuffs == RelativePriority.HighPriority) ? 999 : -999;

            if (SingularSettings.Instance.DispelDebuffs != RelativePriority.None)
            {
                behavs.AddBehavior(dispelPriority, "Purify Spirit", null, Dispelling.CreateDispelBehavior());
            }

            #region Save the Group

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.SpiritLinkTotem) + 600, "Spirit Link Totem", "Spirit Link Totem",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   Spell.CastOnGround("Spirit Link Totem",
                                                      on => (WoWUnit)on,
                                                      ret => HealerManager.Instance.TargetList.Count(
                                                          p => p.PredictedHealthPercent() < ShamanSettings.RestoHealSettings.SpiritLinkTotem && p.Distance <= Totems.GetTotemRange(WoWTotem.SpiritLink)) >= ShamanSettings.RestoHealSettings.MinSpiritLinkCount
                                                      )
                                   )
                               );

            #endregion

            #region AoE Heals

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.HealingTideTotem) + 400, "Healing Tide Totem", "Healing Tide Totem",
                               new Decorator(
                                   ret => (Me.Combat || ((WoWUnit)ret).Combat) &&
                                   (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid) &&
                                   (!Totems.Exist(WoWTotem.Cloudburst) || (Totems.GetTotem(WoWTotem.Cloudburst).Expires - DateTime.UtcNow).TotalMilliseconds < 1500),
                                   Spell.Cast(
                                       "Healing Tide Totem",
                                       on => Me,
                                       req => Me.Combat && HealerManager.Instance.TargetList.Count(p => p.PredictedHealthPercent() < ShamanSettings.RestoHealSettings.HealingTideTotem && p.Distance <= Totems.GetTotemRange(WoWTotem.HealingTide)) >= ShamanSettings.RestoHealSettings.MinHealingTideCount
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.HealingStreamTotem) + 300, "Healing Stream Totem", "Healing Stream Totem",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   Spell.Cast(
                                       "Healing Stream Totem",
                                       on =>
            {
                if (Totems.Exist(WoWTotemType.Water))
                {
                    return(null);
                }

                if (Spell.IsSpellOnCooldown(Totems.ToSpellId(WoWTotem.HealingStream)))
                {
                    return(null);
                }

                // if tank in group, make sure we are near the tank
                WoWUnit tank = HealerManager.TankToStayNear;
                if (tank != null)
                {
                    if (!HealerManager.IsTankSettledIntoFight(tank))
                    {
                        return(null);
                    }
                    if (tank.Distance > Totems.GetTotemRange(WoWTotem.HealingStream))
                    {
                        return(null);
                    }
                }

                WoWUnit unit = HealerManager.Instance.TargetList
                               .FirstOrDefault(
                    p => p.PredictedHealthPercent() < ShamanSettings.RestoHealSettings.HealingStreamTotem &&
                    p.Distance <= Totems.GetTotemRange(WoWTotem.HealingStream)
                    );

                return(unit);
            }
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.GiftoftheQueen) + 300, "Gift of the Queen", "Gift of the Queen",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   new PrioritySelector(
                                       context => GetBestGiftoftheQueenTarget(),
                                       new Decorator(
                                           ret => ret != null,
                                           Spell.CastOnGround("Gift of the Queen", on => (WoWUnit)on, req => true, false)
                                           )
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.CloudburstTotem) + 300, "Cloudburst Totem", "Cloudburst Totem",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   Spell.Cast(
                                       "Cloudburst Totem",
                                       on =>
            {
                if (Totems.Exist(WoWTotemType.Water))
                {
                    return(null);
                }

                if (Spell.IsSpellOnCooldown(Totems.ToSpellId(WoWTotem.Cloudburst)))
                {
                    return(null);
                }

                if (Unit.ValidUnit(Me.CurrentTarget) && (Me.CurrentTarget.TimeToDeath() < 20 || Unit.UnitsInCombatWithUsOrOurStuff().Count() < 3))
                {
                    return(null);
                }

                // if tank in group, make sure we are near the tank
                WoWUnit tank = HealerManager.TankToStayNear;
                if (tank != null)
                {
                    if (!HealerManager.IsTankSettledIntoFight(tank))
                    {
                        return(null);
                    }
                    if (tank.Distance > Totems.GetTotemRange(WoWTotem.Cloudburst))
                    {
                        return(null);
                    }
                }

                WoWUnit unit = HealerManager.Instance.TargetList
                               .Where(
                    p => p.HealthPercent < ShamanSettings.RestoHealSettings.CloudburstTotem &&
                    p.Distance <= Totems.GetTotemRange(WoWTotem.Cloudburst)
                    )
                               .OrderBy(p => (int)p.HealthPercent)
                               .FirstOrDefault();

                return(unit);
            }
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.HealingRain) + 200, "Healing Rain", "Healing Rain",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   new PrioritySelector(
                                       context => GetBestHealingRainTarget(),
                                       new Decorator(
                                           ret => ret != null,
                                           Spell.CastOnGround("Healing Rain", on => (WoWUnit)on, req => true, false)
                                           )
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.ChainHeal) + 150, "Chain Heal", "Chain Heal",
                               new Decorator(
                                   ret => Me.Combat && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   new PrioritySelector(
                                       ctx => GetBestChainHealTarget(),
                                       new Decorator(
                                           ret => ret != null,
                                           new Sequence(
                                               new DecoratorContinue(
                                                   req => ((WoWUnit)req).HasAuraExpired("Riptide", TimeSpan.FromMilliseconds(ChainHealCastTime), true),
                                                   new Sequence(
                                                       Spell.Cast("Riptide", on => (WoWUnit)on, req => true, cancel => false),
                                                       new Wait(TimeSpan.FromMilliseconds(1500), until => !Spell.IsGlobalCooldown(LagTolerance.No), new ActionAlwaysSucceed()),
                                                       new Action(r => TidalWaveRefresh())
                                                       )
                                                   ),
                                               new WaitContinue(TimeSpan.FromMilliseconds(1500), until => !Spell.IsGlobalCooldown(LagTolerance.No), new ActionAlwaysSucceed()),
                                               Spell.Cast("Chain Heal", on => (WoWUnit)on),
                                               new Action(r => TidalWaveRefresh())
                                               )
                                           )
                                       )
                                   )
                               );

            #endregion

            #region Single Target Heals

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.HealingWave), "Healing Wave", "Healing Wave",
                               new Decorator(ret => ((WoWUnit)ret).PredictedHealthPercent() < ShamanSettings.RestoHealSettings.HealingWave,
                                             new Sequence(
                                                 new WaitContinue(TimeSpan.FromMilliseconds(1500), until => !Spell.IsGlobalCooldown(), new ActionAlwaysSucceed()),
                                                 new WaitContinue(2, until => !Spell.IsGlobalCooldown(), new ActionAlwaysSucceed()),
                                                 Spell.Cast("Healing Wave",
                                                            mov => true,
                                                            on => (WoWUnit)on,
                                                            req => true,
                                                            cancel => ((WoWUnit)cancel).HealthPercent > cancelHeal),
                                                 new Action(r => TidalWaveConsume())
                                                 )
                                             )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.HealingSurge), "Healing Surge", "Healing Surge",
                               new Decorator(ret => ((WoWUnit)ret).PredictedHealthPercent() < ShamanSettings.RestoHealSettings.HealingSurge,
                                             new Sequence(
                                                 new WaitContinue(TimeSpan.FromMilliseconds(1500), until => !Spell.IsGlobalCooldown(), new ActionAlwaysSucceed()),
                                                 new WaitContinue(2, until => !Spell.IsGlobalCooldown(), new ActionAlwaysSucceed()),
                                                 Spell.Cast("Healing Surge",
                                                            mov => true,
                                                            on => (WoWUnit)on,
                                                            req => true,
                                                            cancel => ((WoWUnit)cancel).HealthPercent > cancelHeal),
                                                 new Action(r => TidalWaveConsume())
                                                 )
                                             )

                               );

            #endregion

            #region Healing Cooldowns

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.RestoHealSettings.Ascendance) + 100, "Ascendance", "Ascendance",
                               new Decorator(
                                   ret => ShamanSettings.UseAscendance && (StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid),
                                   Spell.BuffSelf(
                                       "Ascendance",
                                       ret => HealerManager.Instance.TargetList.Count(p => p.PredictedHealthPercent() < ShamanSettings.RestoHealSettings.Ascendance) >= ShamanSettings.RestoHealSettings.MinAscendanceCount
                                       )
                                   )
                               );

            #endregion

            behavs.OrderBehaviors();

            if (selfOnly == false && CompositeBuilder.CurrentBehaviorType == BehaviorType.Combat)
            {
                behavs.ListBehaviors();
            }


            return(new PrioritySelector(
                       ctx => selfOnly ? StyxWoW.Me : HealerManager.FindLowestHealthTarget(),
                       // HealerManager.Instance.FirstUnit,

                       CreateRestoDiagnosticOutputBehavior(ret => (WoWUnit)ret),

                       new Decorator(
                           ret =>
                           ret != null &&
                           (Me.Combat || ((WoWUnit)ret).Combat || ((WoWUnit)ret).PredictedHealthPercent() <= 99),

                           new PrioritySelector(
                               new Decorator(
                                   ret => !Spell.IsGlobalCooldown(),
                                   new PrioritySelector(

                                       Totems.CreateTotemsBehavior(),

                                       // roll Riptide on Tanks otherwise
                                       new Sequence(
                                           Spell.Cast("Riptide", on =>
            {
                WoWUnit unit = GetBestRiptideTankTarget();
                if (unit != null && Spell.CanCastHack("Riptide", unit, skipWowCheck: true))
                {
                    Logger.WriteDebug("Buffing RIPTIDE ON TANK: {0}", unit.SafeName());
                    return unit;
                }
                return null;
            }),
                                           new Action(r => TidalWaveRefresh())
                                           ),

                                       // cast Riptide if we are a low level
                                       CreateRestoShamanBuffRiptideLowLevel(),

                                       // cast Riptide if we need Tidal Waves -- skip if Ancestral Swiftness is
                                       CreateRestoShamanBuffTidalWaves(),

                                       behavs.GenerateBehaviorTree(),

                                       // cast Riptide if we need Tidal Waves -- skip if Ancestral Swiftness is
                                       new Decorator(
                                           ret =>
            {
                int rollCount =
                    HealerManager.Instance.TargetList.Count(
                        u => u.IsAlive && u.HasMyAura("Riptide"));
                // Logger.WriteDebug("GetBestRiptideTarget:  currently {0} group members have my Riptide", rollCount);
                return rollCount < ShamanSettings.RestoHealSettings.RollRiptideCount;
            },
                                           new Sequence(
                                               Spell.Cast("Riptide", on =>
            {
                // if tank needs Riptide, bail out on Rolling as they have priority
                if (GetBestRiptideTankTarget() != null)
                {
                    return null;
                }

                // get the best target from all wowunits in our group
                WoWUnit unit = GetBestRiptideTarget();
                if (unit != null)
                {
                    Logger.WriteDebug(Color.White, "ROLLING RIPTIDE on: {0}",
                                      unit.SafeName());
                }

                return unit;
            }),
                                               new Action(r => TidalWaveRefresh())
                                               )
                                           ),

                                       new Decorator(
                                           ret => moveInRange,
                                           new Sequence(
                                               new Action(r => _moveToHealUnit = (WoWUnit)r),
                                               new PrioritySelector(
                                                   Movement.CreateMoveToLosBehavior(on => _moveToHealUnit),
                                                   Movement.CreateMoveToUnitBehavior(on => _moveToHealUnit, 40f, 34f)
                                                   )
                                               )
                                           )
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#5
0
        public static Composite CreateRestoShamanCombatBehaviorInstances()
        {
#if OLD_APPROACH
            return(new PrioritySelector(

                       ctx => HealerManager.Instance.TargetList.Any(t => !t.IsMe && t.IsAlive),

                       Safers.EnsureTarget(),
                       Movement.CreateFaceTargetBehavior(),

                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               CreateRestoDiagnosticOutputBehavior(on => Me.CurrentTarget),

                               new Decorator(
                                   ret => (bool)ret,
                                   new PrioritySelector(
                                       HealerManager.CreateStayNearTankBehavior(),
                                       CreateRestoShamanHealingOnlyBehavior(selfOnly: false),
                                       Helpers.Common.CreateInterruptBehavior(),
                                       Dispelling.CreatePurgeEnemyBehavior("Purge"),
                                       Totems.CreateTotemsBehavior(),
                                       Spell.Cast("Lightning Bolt", ret => TalentManager.HasGlyph("Telluric Currents"))
                                       )
                                   ),

                               new Decorator(
                                   ret => !((bool)ret),
                                   new PrioritySelector(
                                       CreateRestoDiagnosticOutputBehavior(on => HealerManager.Instance.FirstUnit),
                                       Spell.Cast("Elemental Blast"),
                                       Spell.Buff("Flame Shock", true, on => Me.CurrentTarget, req => true, 3),
                                       Spell.Cast("Lava Burst"),
                                       Spell.Cast("Frost Shock"),
                                       Spell.Cast("Chain Lightning", ret => Spell.UseAOE && Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2 && !Unit.UnfriendlyUnitsNearTarget(12f).Any(u => u.IsCrowdControlled())),
                                       Spell.Cast("Lightning Bolt")
                                       )
                                   )

                               )
                           )
                       ));
#else
            return(new PrioritySelector(

                       Spell.WaitForCastOrChannel(),
                       CreateRestoDiagnosticOutputBehavior(on => HealerManager.FindLowestHealthTarget()),

                       HealerManager.CreateStayNearTankBehavior(),

                       new Decorator(
                           ret => Me.Combat && HealerManager.AllowHealerDPS(),
                           new PrioritySelector(

                               Helpers.Common.EnsureReadyToAttackFromMediumRange(),
                               Movement.CreateFaceTargetBehavior(),
                               Spell.WaitForCastOrChannel(),

                               new Decorator(
                                   ret => !Spell.IsGlobalCooldown(),
                                   new PrioritySelector(
                                       Helpers.Common.CreateInterruptBehavior(),

                                       Totems.CreateTotemsBehavior(),

                                       Movement.WaitForFacing(),
                                       Movement.WaitForLineOfSpellSight(),

                                       Common.CastElementalBlast(cancel: c => HealerManager.CancelHealerDPS()),
                                       Spell.Buff("Flame Shock", 3, on => Me.CurrentTarget, req => true),
                                       Spell.Cast("Lava Burst", on => Me.CurrentTarget, req => true, cancel => HealerManager.CancelHealerDPS()),
                                       Spell.Cast("Frost Shock"),
                                       Spell.Cast("Chain Lightning", on => Me.CurrentTarget, req => Spell.UseAOE && Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2 && !Unit.UnfriendlyUnitsNearTarget(12f).Any(u => u.IsCrowdControlled()), cancel => HealerManager.CancelHealerDPS()),
                                       Spell.Cast("Lightning Bolt", on => Me.CurrentTarget, req => true, cancel => HealerManager.CancelHealerDPS())
                                       )
                                   )
                               )
                           ),

                       new Decorator(
                           ret => Unit.NearbyGroupMembers.Any(m => m.IsAlive && !m.IsMe),
                           new PrioritySelector(
                               CreateRestoShamanHealingOnlyBehavior(selfOnly: false),
                               Helpers.Common.CreateInterruptBehavior(),
                               Dispelling.CreatePurgeEnemyBehavior("Purge"),
                               Totems.CreateTotemsBehavior(),
                               new Decorator(
                                   req => TalentManager.HasGlyph("Telluric Currents"),
                                   new PrioritySelector(
                                       Safers.EnsureTarget(),
                                       Movement.CreateFaceTargetBehavior(),
                                       Spell.Cast("Lightning Bolt",
                                                  mov => true,
                                                  on => Unit.NearbyUnitsInCombatWithUsOrOurStuff
                                                  .Where(u => u.IsAlive && u.SpellDistance() < 40 && Me.IsSafelyFacing(u))
                                                  .OrderByDescending(u => u.HealthPercent)
                                                  .FirstOrDefault(),
                                                  req => !HealerManager.Instance.TargetList.Any(h => h.IsAlive && h.SpellDistance() < 40 && h.HealthPercent < ShamanSettings.RestoHealSettings.TelluricHealthCast),
                                                  cancel => HealerManager.Instance.TargetList.Any(h => h.IsAlive && h.SpellDistance() < 40 && h.HealthPercent < ShamanSettings.RestoHealSettings.TelluricHealthCancel)
                                                  )
                                       )
                                   )
                               )
                           )
                       ));
#endif
        }
示例#6
0
        public static Composite CreateShamanEnhancementNormalCombat()
        {
            return(new PrioritySelector(
                       Helpers.Common.EnsureReadyToAttackFromMelee(),
                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal),
                               SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs),

                               CreateEnhanceDiagnosticOutputBehavior(),

                               Helpers.Common.CreateInterruptBehavior(),

                               Totems.CreateTotemsBehavior(),

                               Movement.WaitForFacing(),
                               Movement.WaitForLineOfSpellSight(),

                               Spell.BuffSelf("Feral Spirit", ret => !Me.CurrentTarget.IsTrivial() && NeedFeralSpirit),

                               // Artifact Weapon
                               new Decorator(
                                   ret => ShamanSettings.UseArtifactOnlyInAoE && Unit.NearbyUnitsInCombatWithMeOrMyStuff.Count() > 1,
                                   new PrioritySelector(
                                       Spell.Cast("Doom Winds", ret => ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown)
                                       )
                                   ),
                               Spell.Cast("Doom Winds", ret => !ShamanSettings.UseArtifactOnlyInAoE && ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown),

                               new Decorator(
                                   req => AttackEvenIfGhostWolf,
                                   new PrioritySelector(

                                       Dispelling.CreatePurgeEnemyBehavior("Purge"),

                                       Common.CreateShamanDpsShieldBehavior(),
                                       // Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),

                                       // pull more logic (use instants first, then ranged pulls if possible)

                                       Spell.CastOnGround("Lightning Surge Totem", on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location,
                                                          ret => ShamanSettings.UseLightningSurgeTotem && SingularRoutine.CurrentWoWContext == WoWContext.Normal &&
                                                          Unit.UnfriendlyUnits(8).Count() >= ShamanSettings.LightningSurgeTotemCount),
                                       Spell.Cast("Ascendance", req => Me.HealthPercent <= ShamanSettings.AscendanceHealthPercent),
                                       Spell.Cast("Lava Lash", req => Me.HasActiveAura("Hot Hand")),
                                       Spell.Cast("Windsong"),
                                       Spell.Cast("Rockbiter",
                                                  req => (Common.HasTalent(ShamanTalents.Boulderfist) && !Me.HasActiveAura("Boulderfist")) ||
                                                  (Common.HasTalent(ShamanTalents.Landslide) && !Me.HasActiveAura("Landslide"))),
                                       Spell.Cast("Frostbrand", req => Common.HasTalent(ShamanTalents.Hailstorm) && !Me.HasActiveAura("Frostbrand")),
                                       Spell.Cast("Boulderfist", req => Me.CurrentMaelstrom < 130 && Spell.GetCharges("Boulderfist") >= 2),
                                       Spell.Cast("Flametongue", req => !Me.HasActiveAura("Flametongue")),
                                       Spell.Cast("Feral Spirit", ret => NeedFeralSpirit),
                                       Spell.Cast("Earthen Spike"),
                                       Spell.Cast("Crash Lightning", when => Unit.UnfriendlyUnitsNearTarget(10).Count(u => u.TaggedByMe || !u.TaggedByOther) >= 2),
                                       Spell.Cast("Stormstrike"),
                                       Spell.Cast("Crash Ligthning", req => Common.HasTalent(ShamanTalents.CrashingStorm)),
                                       Spell.Cast("Lava Lash", req => Me.CurrentMaelstrom > 110),
                                       Spell.Cast("Sundering", req => SingularRoutine.CurrentWoWContext != WoWContext.Instances),
                                       Spell.Cast("Rockbiter"),
                                       Spell.Cast("Lightning Bolt", req => !Me.CurrentTarget.IsWithinMeleeRange),
                                       // won't happen often, but if at range and no abilities enter ghost wolf
                                       CreateInCombatGapCloser()
                                       )
                                   )
                               )
                           ),

                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#7
0
        public static Composite CreateDpsShamanOffHealBehavior()
        {
            HealerManager.NeedHealTargeting = true;
            PrioritizedBehaviorList behavs = new PrioritizedBehaviorList();
            int cancelHeal = (int)Math.Max(SingularSettings.Instance.IgnoreHealTargetsAboveHealth, ShamanSettings.OffHealSettings.HealingSurge);

            bool moveInRange = (SingularRoutine.CurrentWoWContext == WoWContext.Battlegrounds);

            Logger.WriteDebugInBehaviorCreate("Shaman Healing: will cancel cast of direct heal if health reaches {0:F1}%", cancelHeal);

/*
 *          int dispelPriority = (SingularSettings.Instance.DispelDebuffs == RelativePriority.HighPriority) ? 999 : -999;
 *          if (SingularSettings.Instance.DispelDebuffs != RelativePriority.None)
 *              behavs.AddBehavior(dispelPriority, "Cleanse Spirit", null, Dispelling.CreateDispelBehavior());
 */
            #region Save the Group

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.OffHealSettings.AncestralSwiftness) + 500,
                               String.Format("Oh Shoot Heal @ {0}%", ShamanSettings.OffHealSettings.AncestralSwiftness),
                               null,
                               new Decorator(
                                   ret => (Me.Combat || ((WoWUnit)ret).Combat) && ((WoWUnit)ret).PredictedHealthPercent() < ShamanSettings.OffHealSettings.AncestralSwiftness,
                                   new PrioritySelector(
                                       Spell.HandleOffGCD(Spell.BuffSelf("Ancestral Swiftness")),
                                       Spell.Cast("Healing Surge", on => (WoWUnit)on)
                                       )
                                   )
                               );

            #endregion

            #region AoE Heals

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.OffHealSettings.HealingStreamTotem) + 300,
                               string.Format("Healing Stream Totem @ {0}%", ShamanSettings.OffHealSettings.HealingStreamTotem),
                               "Healing Stream Totem",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   Spell.Cast(
                                       "Healing Stream Totem",
                                       on => (!Me.Combat || Totems.Exist(WoWTotemType.Water)) ? null : HealerManager.Instance.TargetList.FirstOrDefault(p => p.PredictedHealthPercent() < ShamanSettings.OffHealSettings.HealingStreamTotem && p.Distance <= Totems.GetTotemRange(WoWTotem.HealingStream))
                                       )
                                   )
                               );

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.OffHealSettings.HealingRain) + 200,
                               string.Format("Healing Rain @ {0}% Count={1}", ShamanSettings.OffHealSettings.HealingRain, ShamanSettings.OffHealSettings.MinHealingRainCount),
                               "Healing Rain",
                               Spell.CastOnGround("Healing Rain", on => Restoration.GetBestHealingRainTarget(), req => HealerManager.Instance.TargetList.Count() > 1, false)
                               );

            #endregion

            #region Single Target Heals

            behavs.AddBehavior(HealerManager.HealthToPriority(ShamanSettings.OffHealSettings.HealingSurge),
                               string.Format("Healing Surge @ {0}%", ShamanSettings.OffHealSettings.HealingSurge),
                               "Healing Surge",
                               Spell.Cast("Healing Surge",
                                          mov => true,
                                          on => (WoWUnit)on,
                                          req => ((WoWUnit)req).PredictedHealthPercent(includeMyHeals: true) < ShamanSettings.OffHealSettings.HealingSurge,
                                          cancel => ((WoWUnit)cancel).HealthPercent > cancelHeal
                                          )
                               );

            #endregion

            behavs.OrderBehaviors();

            if (Singular.Dynamics.CompositeBuilder.CurrentBehaviorType == BehaviorType.Heal)
            {
                behavs.ListBehaviors();
            }

            return(new PrioritySelector(
                       ctx => HealerManager.FindLowestHealthTarget(), // HealerManager.Instance.FirstUnit,

                       new Decorator(
                           ret => ret != null && (Me.Combat || ((WoWUnit)ret).Combat || ((WoWUnit)ret).PredictedHealthPercent() <= 99),

                           new PrioritySelector(
                               new Decorator(
                                   ret => !Spell.IsGlobalCooldown(),
                                   new PrioritySelector(

                                       Totems.CreateTotemsBehavior(),

                                       /*
                                        *                          Spell.Cast("Earth Shield",
                                        *                              ret => (WoWUnit)ret,
                                        *                              ret => ret is WoWUnit && Group.Tanks.Contains((WoWUnit)ret) && Group.Tanks.All(t => !t.HasMyAura("Earth Shield"))),
                                        */

                                       behavs.GenerateBehaviorTree(),

                                       new Decorator(
                                           ret => moveInRange,
                                           new Sequence(
                                               new Action(r => _moveToHealUnit = (WoWUnit)r),
                                               new PrioritySelector(
                                                   Movement.CreateMoveToLosBehavior(on => _moveToHealUnit),
                                                   Movement.CreateMoveToUnitBehavior(on => _moveToHealUnit, 30f, 25f)
                                                   )
                                               )
                                           )
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#8
0
        public static Composite CreateShamanCombatBuffsPVP()
        {
            return(new PrioritySelector(

                       Totems.CreateTotemsBehavior(),

                       Spell.BuffSelf("Astral Shift", ret => Me.HealthPercent < ShamanSettings.AstralShiftPercent || Common.StressfulSituation),
                       Spell.BuffSelf(WoWTotem.StoneBulwark.ToSpellId(), ret => !Me.IsMoving && (Common.StressfulSituation || Me.HealthPercent < ShamanSettings.StoneBulwarkTotemPercent && !Totems.Exist(WoWTotem.EarthElemental))),
                       Spell.BuffSelf("Shamanistic Rage", ret => Me.HealthPercent < 70 || Me.ManaPercent < 70 || Common.StressfulSituation),

                       // hex someone if they are not current target, attacking us, and 12 yds or more away
                       new PrioritySelector(
                           ctx => Unit.NearbyUnfriendlyUnits
                           .Where(u => (u.CreatureType == WoWCreatureType.Beast || u.CreatureType == WoWCreatureType.Humanoid) &&
                                  (u.Aggro || u.PetAggro || (u.Combat && u.IsTargetingMeOrPet)) &&
                                  u.Distance.Between(10, 30) && Me.IsSafelyFacing(u) && u.InLineOfSpellSight && Me.GotTarget() && u.Location.Distance(Me.CurrentTarget.Location) > 10)
                           .OrderByDescending(u => u.Distance)
                           .FirstOrDefault(),
                           Spell.Cast("Hex", onUnit => (WoWUnit)onUnit)
                           ),

                       new Decorator(
                           req => {
                if (!Unit.ValidUnit(Me.CurrentTarget))
                {
                    return false;
                }
                if (Me.Specialization == WoWSpec.ShamanEnhancement && !Me.CurrentTarget.IsWithinMeleeRange)
                {
                    return false;
                }

                if (Me.CurrentTarget.TimeToDeath() > 5 || Me.CurrentTarget.HealthPercent > 20 || Me.HealthPercent < Me.CurrentTarget.HealthPercent)
                {
                    return true;
                }
                if (Unit.UnfriendlyUnits(40).Count(u => u.IsTargetingMyStuff()) >= 2)
                {
                    return true;
                }

                return false;
            },
                           new PrioritySelector(
                               Spell.BuffSelfAndWait(PartyBuff.BloodlustSpellName,
                                                     req => ShamanSettings.UseBloodlust &&
                                                     MovementManager.IsClassMovementAllowed &&
                                                     IsPvpFightWorthLusting,
                                                     gcd: HasGcd.No
                                                     ),

                               Spell.BuffSelf(
                                   "Ascendance",
                                   req => ShamanSettings.UseAscendance &&
                                   ((Me.GotTarget() && Me.CurrentTarget.HealthPercent > 70) ||
                                    Unit.NearbyUnfriendlyUnits.Count() > 1),
                                   gcd: HasGcd.No
                                   ),

                               Spell.BuffSelf(
                                   "Elemental Mastery",
                                   req => !PartyBuff.WeHaveBloodlust,
                                   gcd: HasGcd.No
                                   )
                               )
                           )
                       // , Spell.BuffSelf("Spiritwalker's Grace", ret => Me.IsMoving && Me.Combat)

                       ));
        }
示例#9
0
        public static Composite CreateShamanCombatBuffs()
        {
            return(new Decorator(
                       req => !Unit.IsTrivial(Me.CurrentTarget),
                       new PrioritySelector(

                           Totems.CreateTotemsBehavior(),

                           // hex someone if they are not current target, attacking us, and 12 yds or more away
                           new Decorator(
                               req => Me.GotTarget() && (TalentManager.CurrentSpec != WoWSpec.ShamanEnhancement || !ShamanSettings.AvoidMaelstromDamage),
                               new PrioritySelector(
                                   new PrioritySelector(
                                       ctx => Unit.NearbyUnfriendlyUnits
                                       .Where(u => (u.CreatureType == WoWCreatureType.Beast || u.CreatureType == WoWCreatureType.Humanoid) &&
                                              Me.CurrentTargetGuid != u.Guid &&
                                              (u.Aggro || u.PetAggro || (u.Combat && u.IsTargetingMeOrPet)) &&
                                              !u.IsCrowdControlled() &&
                                              u.SpellDistance().Between(10, 30) && Me.IsSafelyFacing(u) && u.InLineOfSpellSight && u.Location.Distance(Me.CurrentTarget.Location) > 10)
                                       .OrderByDescending(u => u.Distance)
                                       .FirstOrDefault(),
                                       Spell.Cast("Hex", onUnit => (WoWUnit)onUnit)
                                       ),

                                   // bind someone if we can
                                   new PrioritySelector(
                                       ctx => Unit.NearbyUnfriendlyUnits
                                       .Where(u => u.CreatureType == WoWCreatureType.Elemental &&
                                              Me.CurrentTargetGuid != u.Guid &&
                                              (u.Aggro || u.PetAggro || (u.Combat && u.IsTargetingMeOrPet)) &&
                                              !u.IsCrowdControlled() &&
                                              u.Distance.Between(10, 30) && Me.IsSafelyFacing(u) && u.InLineOfSpellSight && u.Location.Distance(Me.CurrentTarget.Location) > 10)
                                       .OrderByDescending(u => u.Distance)
                                       .FirstOrDefault(),
                                       Spell.Cast("Bind Elemental", onUnit => (WoWUnit)onUnit)
                                       )
                                   )
                               ),

                           new Decorator(
                               ret => ShamanSettings.UseBloodlust && MovementManager.IsClassMovementAllowed,
                               Spell.BuffSelf(
                                   PartyBuff.BloodlustSpellName,
                                   req => {
                // when Solo, use it if in a stressful fight
                if (SingularRoutine.CurrentWoWContext == WoWContext.Normal)
                {
                    if (Unit.GroupMembers.Any(m => m.IsAlive && m.Distance < 100))
                    {
                        return false;
                    }

                    return Common.StressfulSituation;
                }

                // should be manually cast when LazyRaiding, or by DungeonBuddy
                if (SingularRoutine.CurrentWoWContext == WoWContext.Instances)
                {
                    return !Me.GroupInfo.IsInRaid && Me.CurrentTarget.IsBoss();
                }

                return false;
            }
                                   )
                               ),

                           Spell.BuffSelf("Ascendance", ret => ShamanSettings.UseAscendance && SingularRoutine.CurrentWoWContext == WoWContext.Normal && Common.StressfulSituation),

                           Spell.BuffSelf("Elemental Mastery", ret => !PartyBuff.WeHaveBloodlust)

                           // , Spell.BuffSelf("Spiritwalker's Grace", ret => Me.IsMoving && Me.Combat)
                           )
                       ));
        }
示例#10
0
        public static Composite CreateRestoShamanHealingOnlyBehavior(bool selfOnly, bool moveInRange)
        {
            HealerManager.NeedHealTargeting = true;
            PrioritizedBehaviorList behavs = new PrioritizedBehaviorList();

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.AncestralSwiftness),
                               "Unleash Elements",
                               "Unleash Elements",
                               Spell.Buff("Unleash Elements",
                                          ret => (WoWUnit)ret,
                                          ret => (Me.IsMoving || ((WoWUnit)ret).GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.AncestralSwiftness) &&
                                          Common.IsImbuedForHealing(Me.Inventory.Equipped.MainHand)
                                          ));

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.AncestralSwiftness),
                               String.Format("Ancestral Swiftness @ {0}%", SingularSettings.Instance.Shaman.Heal.AncestralSwiftness),
                               "Ancestral Swiftness",
                               new Sequence(
                                   Spell.BuffSelf("Ancestral Swiftness", ret => ((WoWUnit)ret).GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.AncestralSwiftness),
                                   Spell.Heal("Greater Healing Wave", ret => (WoWUnit)ret)
                                   ));

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.GreaterHealingWave), "Greater Healing Wave", "Greater Healing Wave",
                               Spell.Heal("Greater Healing Wave", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.GreaterHealingWave));

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.HealingWave), "Healing Wave", "Healing Wave",
                               Spell.Heal("Healing Wave", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.HealingWave));

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.HealingSurge), "Healing Surge", "Healing Surge",
                               Spell.Heal("Healing Surge", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.HealingSurge));

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.ChainHeal), "Chain Heal", "Chain Heal",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   new PrioritySelector(
                                       new PrioritySelector(
                                           context => Clusters.GetBestUnitForCluster(ChainHealPlayers, ClusterType.Chained, ChainHealHopRange),
                                           Spell.Heal(
                                               "Chain Heal", ret => (WoWPlayer)ret,
                                               ret => Clusters.GetClusterCount((WoWPlayer)ret, ChainHealPlayers, ClusterType.Chained, ChainHealHopRange) >= 3)
                                           )
                                       )
                                   )
                               );

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.HealingRain), "Healing Rain", "Healing Rain",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   new PrioritySelector(
                                       context => Clusters.GetBestUnitForCluster(Unit.NearbyFriendlyPlayers.Cast <WoWUnit>(), ClusterType.Radius, 10f),
                                       Spell.CastOnGround(
                                           "Healing Rain",
                                           ret => ((WoWPlayer)ret).Location,
                                           ret => (StyxWoW.Me.GroupInfo.IsInRaid ? 3 : 2) < Clusters.GetClusterCount((WoWPlayer)ret, Unit.NearbyFriendlyPlayers.Cast <WoWUnit>(), ClusterType.Radius, 10f))
                                       )
                                   )
                               );

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.SpiritLinkTotem), "Spirit Link Totem", "Spirit Link Totem",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   Spell.Cast(
                                       "Spirit Link Totem", ret => (WoWPlayer)ret,
                                       ret => Unit.NearbyFriendlyPlayers.Count(
                                           p => p.GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.SpiritLinkTotem && p.Distance <= Totems.GetTotemRange(WoWTotem.SpiritLink)) >= (Me.GroupInfo.IsInRaid ? 3 : 2)
                                       )
                                   )
                               );

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.HealingTideTotemPercent), "Healing Tide Totem", "Healing Tide Totem",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   Spell.Cast(
                                       "Healing Tide Totem",
                                       ret => Unit.NearbyFriendlyPlayers.Count(p => p.GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.HealingTideTotemPercent && p.Distance <= Totems.GetTotemRange(WoWTotem.HealingTide)) >= (Me.GroupInfo.IsInRaid ? 3 : 2)
                                       )
                                   )
                               );

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.HealingStreamTotem), "Healing Stream Totem", "Healing Stream Totem",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   Spell.Cast(
                                       "Healing Stream Totem",
                                       ret => Unit.NearbyFriendlyPlayers.Count(p => p.GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.HealingStreamTotem && p.Distance <= Totems.GetTotemRange(WoWTotem.HealingTide)) >= (Me.GroupInfo.IsInRaid ? 3 : 2) &&
                                       !Totems.Exist(WoWTotemType.Water)
                                       )
                                   )
                               );

            behavs.AddBehavior(HealthToPriority(SingularSettings.Instance.Shaman.Heal.Ascendance), "Ascendance", "Ascendance",
                               new Decorator(
                                   ret => StyxWoW.Me.GroupInfo.IsInParty || StyxWoW.Me.GroupInfo.IsInRaid,
                                   Spell.BuffSelf(
                                       "Ascendance",
                                       ret => Unit.NearbyFriendlyPlayers.Count(p => p.GetPredictedHealthPercent() < SingularSettings.Instance.Shaman.Heal.Ascendance) >= (Me.GroupInfo.IsInRaid ? 3 : 2)
                                       )
                                   )
                               );


            behavs.OrderBehaviors();
            behavs.ListBehaviors();


            return(new PrioritySelector(
                       ctx => selfOnly ? StyxWoW.Me : HealerManager.Instance.FirstUnit,
//                ctx => selfOnly ? StyxWoW.Me : GetHealTarget(),

                       Spell.WaitForCast(),

                       new Decorator(
                           ret => Me.IsCasting,
                           new ActionAlwaysSucceed()),

                       new Decorator(
                           ret => ret != null && ((WoWUnit)ret).GetPredictedHealthPercent() <= SingularSettings.Instance.IgnoreHealTargetsAboveHealth,

                           new PrioritySelector(

                               new Sequence(
                                   new Decorator(
                                       ret => guidLastHealTarget != ((WoWUnit)ret).Guid,
                                       new Action(ret =>
            {
                guidLastHealTarget = ((WoWUnit)ret).Guid;
                Logger.WriteDebug(Color.LightGreen, "Heal Target - {0} {1:F1}% @ {2:F1} yds", ((WoWUnit)ret).SafeName(), ((WoWUnit)ret).GetPredictedHealthPercent(), ((WoWUnit)ret).Distance);
            })),
                                   new Action(ret => { return RunStatus.Failure; })
                                   ),

/*
 *                      new Sequence(
 *                          new Action(ret => Logger.WriteDebug(Color.LightGreen, "-- past spellcast")),
 *                          new Action(ret => { return RunStatus.Failure; })
 *                          ),
 */
                               new Decorator(
                                   ret => !SpellManager.GlobalCooldown,

                                   new PrioritySelector(

                                       /*
                                        *                          new Sequence(
                                        *                              new Action(ret => Logger.WriteDebug(Color.LightGreen, "-- past gcd")),
                                        *                              new Action(ret => { return RunStatus.Failure; })
                                        *                              ),
                                        */
                                       Totems.CreateTotemsBehavior(),

                                       Spell.Heal("Earth Shield",
                                                  ret => (WoWUnit)ret,
                                                  ret => ret is WoWPlayer && Group.Tanks.Contains((WoWPlayer)ret) && Group.Tanks.All(t => !t.HasMyAura("Earth Shield"))),

                                       // Just pop RT on CD. Plain and simple. Calling GetBestRiptideTarget will see if we can spread RTs (T12 2pc)
                                       Spell.Heal("Riptide",
                                                  ret => GetBestRiptideTarget((WoWPlayer)ret),
                                                  ret => !Me.HasAnyAura("Tidal Waves", "Ancestral Swiftness") &&
                                                  (((WoWPlayer)ret).GetPredictedHealthPercent() > 15 || Spell.GetSpellCooldown("Ancestral Swiftness").TotalMinutes > 0f) // use Ancestral Swiftness value to check
                                                  ),

                                       behavs.GenerateBehaviorTree(),

                                       Spell.Heal("Riptide",
                                                  ret => GetBestRiptideTarget((WoWPlayer)ret),
                                                  ret => !Me.HasAura("Ancestral Swiftness"))

    #if false
                                       ,
                                       new Sequence(
                                           new Action(ret => Logger.WriteDebug(Color.LightGreen, "No Action - stunned:{0} silenced:{1}"
                                                                               , Me.Stunned || Me.IsStunned()
                                                                               , Me.Silenced
                                                                               )),
                                           new Action(ret => { return RunStatus.Failure; })
                                           )
                                       ,

                                       new Decorator(
                                           ret => StyxWoW.Me.Combat && StyxWoW.Me.GotTarget && !Unit.NearbyFriendlyPlayers.Any(u => u.IsInMyPartyOrRaid),
                                           new PrioritySelector(
                                               Movement.CreateMoveToLosBehavior(),
                                               Movement.CreateFaceTargetBehavior(),
                                               Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                                               Spell.Cast("Earth Shock"),
                                               Spell.Cast("Lightning Bolt"),
                                               Movement.CreateMoveToTargetBehavior(true, 35f)
                                               ))
    #endif
                                       )
                                   ),

                               new Decorator(
                                   ret => moveInRange,
                                   Movement.CreateMoveToRangeAndStopBehavior(ret => (WoWUnit)ret, ret => 38f))
                               )
                           )
                       ));
        }
示例#11
0
        public static Composite CreateElementalNormalCombat()
        {
            return(new PrioritySelector(

                       Helpers.Common.EnsureReadyToAttackFromLongRange(),

                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               Helpers.Common.CreateInterruptBehavior(),

                               Totems.CreateTotemsBehavior(),

                               Movement.WaitForFacing(),
                               Movement.WaitForLineOfSpellSight(),

                               Dispelling.CreatePurgeEnemyBehavior("Purge"),

                               Common.CreateShamanDpsShieldBehavior(),

                               Spell.BuffSelf("Thunderstorm", ret => Unit.NearbyUnfriendlyUnits.Count(u => u.Distance < 10f) >= 3),

                               Common.CastElementalBlast(),

                               Spell.CastOnGround("Lightning Surge Totem",
                                                  on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location,
                                                  ret => ShamanSettings.UseLightningSurgeTotem &&
                                                  SingularRoutine.CurrentWoWContext == WoWContext.Normal &&
                                                  Unit.UnfriendlyUnits(8).Count() >= ShamanSettings.LightningSurgeTotemCount),
                               Spell.BuffSelf("Earth Elemental", ret => ShamanSettings.EarthElementalHealthPercent <= Me.HealthPercent),
                               Spell.BuffSelf("Totem Mastery", req => !Me.HasAura("Ember Totem")), // Only one buff should need to be checked.
                               Spell.Buff("Flame Shock", true, req => !Me.CurrentTarget.HasMyAura("Flame Shock") && Me.CurrentTarget.TimeToDeath(int.MaxValue) > 6),
                               Spell.Cast("Fire Elemental"),
                               Spell.Cast("Earth Shock", req => MaelstormDeficit <= 0),
                               Spell.Cast("Ascendance"),
                               Spell.BuffSelf("Elemental Mastery"),
                               Spell.Cast("Lava Burst"),
                               Spell.CastOnGround("Earthquake Totem",
                                                  on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location,
                                                  req => Spell.UseAOE &&
                                                  Me.CurrentTarget.Distance < 34 &&
                                                  (Me.ManaPercent > ShamanSettings.EarthquakeMaelPercent || Me.GetAuraTimeLeft("Lucidity") > TimeSpan.Zero) &&
                                                  Unit.UnfriendlyUnitsNearTarget(10f).Count() >= ShamanSettings.EarthquakeCount - 1),
                               Spell.Cast("Earth Shock", req => Me.CurrentMaelstrom >= 90),

                               // Artifact Weapon
                               new Decorator(
                                   ret => ShamanSettings.UseArtifactOnlyInAoE && Unit.UnfriendlyUnitsNearTarget(10f).Count() > 1, // Focused toward Chain Lightning
                                   new PrioritySelector(
                                       Spell.Cast("Stormkeeper",
                                                  ret =>
                                                  ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || !Common.HasTalent(ShamanTalents.Ascendance) ||
                                                  (ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Common.HasTalent(ShamanTalents.Ascendance) && Spell.GetSpellCooldown("Ascendance") > TimeSpan.FromSeconds(15))
                                                  )
                                       )
                                   ),
                               Spell.Cast("Stormkeeper",
                                          ret =>
                                          ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || !Common.HasTalent(ShamanTalents.Ascendance) ||
                                          (ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Common.HasTalent(ShamanTalents.Ascendance) && Spell.GetSpellCooldown("Ascendance") > TimeSpan.FromSeconds(15))
                                          ),

                               Spell.Cast("Chain Lightning", ret => Spell.UseAOE && Unit.UnfriendlyUnitsNearTarget(10f).Count() > 1 && !Unit.UnfriendlyUnitsNearTarget(10f).Any(u => u.IsCrowdControlled())),
                               Spell.Cast("Lightning Bolt")
                               )
                           )

                       // Movement.CreateMoveToUnitBehavior( on => StyxWoW.Me.CurrentTarget, 38f, 33f)
                       // Movement.CreateMoveToRangeAndStopBehavior(ret => Me.CurrentTarget, ret => NormalPullDistance)
                       ));
        }
示例#12
0
        public static Composite CreateElementalNormalPull()
        {
            return(new PrioritySelector(

                       Helpers.Common.EnsureReadyToAttackFromLongRange(),

                       Spell.WaitForCastOrChannel(),

                       new Decorator(
                           ret => !Spell.IsGlobalCooldown(),
                           new PrioritySelector(

                               Common.CreateShamanDpsShieldBehavior(),

                               Totems.CreateTotemsBehavior(),
                               Spell.BuffSelf("Totem Mastery", req => !Me.HasAura("Ember Totem")), // Only one buff should need to be checked.

                               Movement.WaitForFacing(),
                               Movement.WaitForLineOfSpellSight(),

                               // grinding or questing, if target meets these cast Flame Shock if possible
                               // 1. mob is less than 12 yds, so no benefit from delay in Lightning Bolt missile arrival
                               // 2. area has another player competing for mobs (we want to tag the mob quickly)
                               new Decorator(
                                   ret => {
                if (StyxWoW.Me.CurrentTarget.IsHostile && StyxWoW.Me.CurrentTarget.Distance < 12)
                {
                    Logger.WriteDiagnostic("NormalPull: fast pull since hostile target is {0:F1} yds away", StyxWoW.Me.CurrentTarget.Distance);
                    return true;
                }
                WoWPlayer nearby = ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).FirstOrDefault(p => !p.IsMe && p.DistanceSqr <= 40 * 40);
                if (nearby != null)
                {
                    Logger.WriteDiagnostic("NormalPull: fast pull since player {0} nearby @ {1:F1} yds", nearby.SafeName(), nearby.Distance);
                    return true;
                }
                return false;
            },
                                   new PrioritySelector(
                                       // have a big attack loaded up, so don't waste it
                                       Spell.Cast("Earth Shock", ret => StyxWoW.Me.HasAura("Lightning Shield", 5)),
                                       Spell.Buff("Flame Shock", true, req => SpellManager.HasSpell("Lava Burst")),
                                       Spell.Cast("Earth Shock", ret => !SpellManager.HasSpell("Flame Shock"))
                                       )
                                   ),

                               // have a big attack loaded up, so don't waste it
                               Spell.Cast("Earth Shock", ret => StyxWoW.Me.HasAura("Lightning Shield", 5)),

                               // otherwise, start with Lightning Bolt so we can follow with an instant
                               // to maximize damage at initial aggro
                               Spell.Cast("Lightning Bolt"),

                               // we are moving so throw an instant of some type
                               Spell.Buff("Flame Shock", true, req => SpellManager.HasSpell("Lava Burst")),
                               Spell.Buff("Lava Burst", true, req => Me.GotTarget() && Me.CurrentTarget.HasMyAura("Flame Shock")),
                               Spell.Cast("Earth Shock")
                               )
                           )

                       // Movement.CreateMoveToUnitBehavior( on => StyxWoW.Me.CurrentTarget, 38f, 33f)
                       ));
        }