示例#1
0
 public static Composite CreateElementalPreCombatBuffsPvp()
 {
     return(new PrioritySelector(
                Common.CreateShamanDpsShieldBehavior(),
                Totems.CreateRecallTotems()
                ));
 }
示例#2
0
        public static Composite CreateEnhancementShamanPreCombatBuffs()
        {
            return(new PrioritySelector(

                       new Decorator(
                           ret => !Item.HasWeaponImbue(WoWInventorySlot.MainHand, "Windfury") && SpellManager.HasSpell("Windfury Weapon") &&
                           SpellManager.CanCast("Windfury Weapon", null, false, false),
                           new Sequence(
                               new Action(ret => Lua.DoString("CancelItemTempEnchantment(1) CancelItemTempEnchantment(2)")),
                               new Action(ret => Logger.Write("Imbuing main hand weapon with Windfury")),
                               new Action(ret => SpellManager.Cast("Windfury Weapon", null)))),
                       new Decorator(
                           ret => !Item.HasWeaponImbue(WoWInventorySlot.MainHand, "Flametongue") && !SpellManager.HasSpell("Windfury Weapon") &&
                           SpellManager.CanCast("Flametongue Weapon", null, false, false),
                           new Sequence(
                               new Action(ret => Lua.DoString("CancelItemTempEnchantment(1) CancelItemTempEnchantment(2)")),
                               new Action(ret => Logger.Write("Imbuing main hand weapon with Flametongue")),
                               new Action(ret => SpellManager.Cast("Flametongue Weapon", null)))),
                       new Decorator(
                           ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                           StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon &&
                           !Item.HasWeaponImbue(WoWInventorySlot.OffHand, "Flametongue") &&
                           StyxWoW.Me.Inventory.Equipped.MainHand != null && StyxWoW.Me.Inventory.Equipped.MainHand.TemporaryEnchantment != null &&
                           SpellManager.CanCast("Flametongue Weapon", null, false, false),
                           new Sequence(
                               new Action(ret => Lua.DoString("CancelItemTempEnchantment(2)")),
                               new Action(ret => Logger.Write("Imbuing off hand weapon with Flametongue")),
                               new Action(ret => SpellManager.Cast("Flametongue Weapon", null)))),

                       Spell.Cast("Lightning Shield", ret => StyxWoW.Me, ret => !StyxWoW.Me.HasAura("Lightning Shield", 2)),
                       new Decorator(ret => Totems.NeedToRecallTotems,
                                     new Action(ret => Totems.RecallTotems()))
                       ));
        }
示例#3
0
        public static Composite CreateEnhancementShamanNormalPull()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       Spell.Cast("Lightning Shield", ret => StyxWoW.Me, ret => !StyxWoW.Me.HasAura("Lightning Shield", 2)),

                       new Decorator(
                           ret => StyxWoW.Me.Level < 20,
                           new PrioritySelector(
                               new Decorator(
                                   ret => StyxWoW.Me.CurrentTarget.DistanceSqr < 40 * 40,
                                   Totems.CreateSetTotems()),
                               Spell.Cast("Lightning Bolt"),
                               Movement.CreateMoveToTargetBehavior(true, 35f)
                               )),

                       Common.CreateAutoAttack(true),
                       new Decorator(
                           ret => StyxWoW.Me.CurrentTarget.DistanceSqr < 20 * 20,
                           Totems.CreateSetTotems()),
                       Spell.Cast("Earth Shock"),
                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#4
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")
                               )
                           )
                       ));
        }
示例#5
0
        public static Composite CreateShamanEnhancementNormalPull()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),

                       Common.CreateShamanImbueMainHandBehavior(Imbue.Windfury, Imbue.Flametongue),
                       Common.CreateShamanImbueOffHandBehavior(Imbue.Flametongue),

                       Spell.BuffSelf("Lightning Shield"),

                       new Decorator(
                           ret => StyxWoW.Me.Level < 20,
                           new PrioritySelector(
                               Spell.Cast("Lightning Bolt"),
                               Movement.CreateMoveToTargetBehavior(true, 35f)
                               )),

                       Helpers.Common.CreateAutoAttack(true),
                       new Decorator(ret => StyxWoW.Me.CurrentTarget.DistanceSqr < 20 * 20,
                                     Totems.CreateTotemsNormalBehavior()),
                       Spell.Cast("Lightning Bolt", ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                       Spell.Cast("Unleash Weapon",
                                  ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                  StyxWoW.Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id == 5),
                       Spell.Cast("Earth Shock"),
                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#6
0
        public static Composite CreateShamanNonHealBehavior()
        {
            return
                (new PrioritySelector(

                     new Decorator(
                         ret => !StyxWoW.Me.Combat,
                         Spell.Heal(
                             "Healing Surge",
                             ret => StyxWoW.Me,
                             ret => StyxWoW.Me.HealthPercent <= 70)
                         ),
                     new Decorator(
                         ret => StyxWoW.Me.Combat,
                         new PrioritySelector(
                             Spell.BuffSelf(
                                 "Healing Tide Totem",
                                 ret => Unit.NearbyFriendlyPlayers.Any(
                                     p => p.HealthPercent < SingularSettings.Instance.Shaman.HealingTideTotemPercent &&
                                     p.Distance <= Totems.GetTotemRange(WoWTotem.HealingTide))),
                             Spell.BuffSelf(
                                 "Healing Stream Totem",
                                 ret => !Totems.Exist(WoWTotemType.Water) &&
                                 Unit.NearbyFriendlyPlayers.Any(
                                     p => p.HealthPercent < SingularSettings.Instance.Shaman.HealHealingStreamTotem &&
                                     p.Distance <= Totems.GetTotemRange(WoWTotem.HealingTide))),
                             Spell.Heal(
                                 "Healing Surge",
                                 ret => StyxWoW.Me,
                                 ret => StyxWoW.Me.HealthPercent <= 30)
                             )
                         )
                     ));
        }
示例#7
0
        public static Composite CreateEnhancementShamanInstancePullAndCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       Totems.CreateSetTotems(),
                       Common.CreateAutoAttack(true),
                       Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                       Spell.BuffSelf("Lightning Shield"),
                       Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),
                       Spell.BuffSelf("Feral Spirit"),
                       new Decorator(
                           ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                           new PrioritySelector(
                               Spell.Cast("Unleash Elements"),
                               Spell.BuffSelf("Magma Totem",
                                              ret => !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.Magma)),
                               Spell.Buff("Flame Shock", true),
                               Spell.Cast("Lava Lash",
                                          ret => StyxWoW.Me.CurrentTarget.HasMyAura("Flame Shock") &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),
                               Spell.Cast("Fire Nova"),
                               Spell.Cast("Chain Lightning", ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                               Spell.Cast("Stormstrike"),
                               Movement.CreateMoveToMeleeBehavior(true)
                               )),

                       // Totem stuff
                       // Pop the ele on bosses
                       Spell.BuffSelf("Fire Elemental Totem",
                                      ret => StyxWoW.Me.CurrentTarget.IsBoss() && StyxWoW.Me.CurrentTarget.DistanceSqr < 20 * 20 &&
                                      !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.FireElemental)),
                       Spell.BuffSelf("Searing Totem",
                                      ret => StyxWoW.Me.CurrentTarget.Distance < Totems.GetTotemRange(WoWTotem.Searing) - 2f &&
                                      !StyxWoW.Me.Totems.Any(
                                          t => t.Unit != null && t.WoWTotem == WoWTotem.Searing &&
                                          t.Unit.Location.Distance(StyxWoW.Me.CurrentTarget.Location) < Totems.GetTotemRange(WoWTotem.Searing)) &&
                                      !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.FireElemental)),

                       Spell.Cast("Stormstrike"),
                       Spell.Cast("Primal Strike", ret => !SpellManager.HasSpell("Stormstrike")),
                       Spell.Cast("Lava Lash",
                                  ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                  StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),
                       Spell.Cast("Lightning Bolt", ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                       Spell.Cast("Unleash Elements"),
                       Spell.Buff("Flame Shock", true, ret => StyxWoW.Me.HasAura("Unleash Wind") || !SpellManager.HasSpell("Unleash Elements")),
                       Spell.Cast("Earth Shock", ret => StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 6),

                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#8
0
        public static Composite CreateShamanEnhancementNormalCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       Helpers.Common.CreateAutoAttack(true),
                       Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                       Common.CreateShamanImbueMainHandBehavior(Imbue.Windfury, Imbue.Flametongue),
                       Common.CreateShamanImbueOffHandBehavior(Imbue.Flametongue),

                       Spell.BuffSelf("Lightning Shield"),
                       Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),
                       Spell.BuffSelf("Feral Spirit", ret =>
                                      SingularSettings.Instance.Shaman.FeralSpiritCastOn == CastOn.All ||
                                      (SingularSettings.Instance.Shaman.FeralSpiritCastOn == CastOn.Bosses && StyxWoW.Me.CurrentTarget.Elite) ||
                                      (SingularSettings.Instance.Shaman.FeralSpiritCastOn == CastOn.Players && Unit.NearbyUnfriendlyUnits.Any(u => u.IsPlayer && u.Combat && u.IsTargetingMeOrPet))),

                       Totems.CreateTotemsNormalBehavior(),

                       Spell.BuffSelf("Elemental Mastery",
                                      ret => !StyxWoW.Me.HasAnyAura(Common.BloodlustName, "Time Warp", "Ancient Hysteria")),

                       Common.CreateShamanInCombatBuffs(true),

                       Spell.Cast("Stormstrike"),
                       Spell.Buff("Flame Shock", true,
                                  ret => (StyxWoW.Me.HasAura("Unleash Flame") || !SpellManager.HasSpell("Unleash Elements")) &&
                                  (StyxWoW.Me.CurrentTarget.Elite || (SpellManager.HasSpell("Fire Nova") && Unit.UnfriendlyUnitsNearTarget(10).Count(u => u.IsTargetingMeOrPet) >= 3))),
                       Spell.Cast("Earth Shock",
                                  ret => StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 3 ||
                                  !StyxWoW.Me.CurrentTarget.Elite ||
                                  !SpellManager.HasSpell("Flame Shock")),
                       Spell.Cast("Lava Lash",
                                  ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                  StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),
                       Spell.BuffSelf("Fire Nova",
                                      ret => StyxWoW.Me.CurrentTarget.HasMyAura("Flame Shock") &&
                                      Unit.NearbyUnfriendlyUnits.Count(u =>
                                                                       u.IsTargetingMeOrPet &&
                                                                       u.Location.DistanceSqr(StyxWoW.Me.CurrentTarget.Location) < 10 * 10) >= 3),
                       Spell.Cast("Primal Strike", ret => !SpellManager.HasSpell("Stormstrike")),
                       Spell.Cast("Unleash Elements"),

                       new Decorator(ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5),
                                     new PrioritySelector(
                                         Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                                         Spell.Cast("Lightning Bolt")
                                         )
                                     ),

                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#9
0
        public static Composite CreateShamanElementalPvPPullAndCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),

                       new Decorator(
                           ret => !Common.InGCD,
                           new PrioritySelector(

                               Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                               new Decorator(
                                   ret => Common.GetImbue(StyxWoW.Me.Inventory.Equipped.MainHand) == Imbue.None,
                                   Common.CreateShamanImbueMainHandBehavior(Imbue.Flametongue)),

                               Spell.BuffSelf("Lightning Shield"),

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

                               Spell.BuffSelf("Elemental Mastery",
                                              ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat &&
                                              (!SpellManager.HasSpell("Spiritwalker's Grace") ||
                                               SpellManager.Spells["Spiritwalker's Grace"].Cooldown && !StyxWoW.Me.HasAura("Spiritwalker's Grace"))),

                               Spell.BuffSelf("Thunderstorm", ret => StyxWoW.Me.IsStunned() && Unit.NearbyUnfriendlyUnits.Any(u => u.Distance < 10f)),

                               Totems.CreateTotemsPvPBehavior(),

                               new Decorator(
                                   ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                                   new PrioritySelector(
                                       // Pop the ele on bosses
                                       Spell.BuffSelf("Fire Elemental Totem", ret => !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.FireElemental)),
                                       Spell.CastOnGround("Earthquake", ret => StyxWoW.Me.CurrentTarget.Location),
                                       Spell.Cast("Chain Lightning", ret => Clusters.GetBestUnitForCluster(Unit.UnfriendlyUnitsNearTarget(15f), ClusterType.Chained, 12))
                                       )),

                               Spell.Buff("Flame Shock", true),
                               Spell.Cast("Lava Burst"),
                               Spell.Cast("Earth Shock",
                                          ret => StyxWoW.Me.HasAura("Lightning Shield", 5) &&
                                          StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 3),
                               Spell.Cast("Unleash Elements",
                                          ret => StyxWoW.Me.IsMoving && !StyxWoW.Me.HasAura("Spiritwalker's Grace") &&
                                          Common.IsImbuedForDPS(StyxWoW.Me.Inventory.Equipped.MainHand)),
                               Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                               Spell.Cast("Lightning Bolt")
                               )
                           ),
                       Movement.CreateMoveToTargetBehavior(true, 35f)
                       ));
        }
示例#10
0
        public static Composite CreateShamanElementalPreCombatBuffs()
        {
            return(new PrioritySelector(
                       Common.CreateShamanImbueMainHandBehavior(Imbue.Flametongue),

                       Spell.BuffSelf("Lightning Shield"),

                       new Decorator(ret => Totems.NeedToRecallTotems,
                                     new Action(ret => Totems.RecallTotems()))
                       ));
        }
示例#11
0
        public static Composite CreateElementalShamanInstancePullAndCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       Totems.CreateSetTotems(),
                       Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                       Spell.BuffSelf("Lightning Shield"),
                       Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),
                       Spell.BuffSelf("Elemental Mastery",
                                      ret => StyxWoW.Me.HasAnyAura("Bloodlust", "Heroism", "Time Warp", "Ancient Hysteria")),
                       Spell.BuffSelf("Elemental Mastery",
                                      ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat &&
                                      (!SpellManager.HasSpell("Spiritwalker's Grace") ||
                                       SpellManager.Spells["Spiritwalker's Grace"].Cooldown && !StyxWoW.Me.HasAura("Spiritwalker's Grace"))),

                       new Decorator(
                           ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                           new PrioritySelector(
                               Spell.CastOnGround("Earthquake", ret => StyxWoW.Me.CurrentTarget.Location),
                               Spell.Cast("Chain Lightning", ret => Clusters.GetBestUnitForCluster(Unit.UnfriendlyUnitsNearTarget(15f), ClusterType.Chained, 12))
                               )),

                       // Totem stuff
                       // Pop the ele on bosses
                       Spell.BuffSelf("Fire Elemental Totem", ret => StyxWoW.Me.CurrentTarget.IsBoss() && !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.FireElemental)),
                       Spell.BuffSelf("Searing Totem",
                                      ret => StyxWoW.Me.CurrentTarget.Distance < Totems.GetTotemRange(WoWTotem.Searing) - 2f &&
                                      !StyxWoW.Me.Totems.Any(
                                          t => t.Unit != null && t.WoWTotem == WoWTotem.Searing &&
                                          t.Unit.Location.Distance(StyxWoW.Me.CurrentTarget.Location) < Totems.GetTotemRange(WoWTotem.Searing)) &&
                                      !StyxWoW.Me.Totems.Any(t => t.WoWTotem == WoWTotem.FireElemental)),

                       Spell.Buff("Flame Shock", true),
                       Spell.Cast("Lava Burst"),
                       Spell.Cast("Earth Shock",
                                  ret => (StyxWoW.Me.HasAura("Lightning Shield", 7) || TalentManager.GetCount(1, 13) == 0) &&
                                  StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 6),
                       Spell.Cast("Unleash Elements",
                                  ret => Item.HasWeaponImbue(WoWInventorySlot.MainHand, "Flametongue") && StyxWoW.Me.IsMoving && !StyxWoW.Me.HasAura("Spiritwalker's Grace")),
                       Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                       Spell.Cast("Lightning Bolt"),
                       Movement.CreateMoveToTargetBehavior(true, 35f)
                       ));
        }
示例#12
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")
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#13
0
        public static Composite CreateElementalShamanPreCombatBuffs()
        {
            return(new PrioritySelector(
                       new Decorator(
                           ret => !Item.HasWeaponImbue(WoWInventorySlot.MainHand, "Flametongue") && SpellManager.HasSpell("Flametongue Weapon") &&
                           SpellManager.CanCast("Flametongue Weapon", null, false, false),
                           new Sequence(
                               new Action(ret => Lua.DoString("CancelItemTempEnchantment(1)")),
                               new Action(ret => Logger.Write("Imbuing main hand weapon with Flametongue")),
                               new Action(ret => SpellManager.Cast("Flametongue Weapon", null))
                               )),

                       Spell.Cast("Lightning Shield", ret => StyxWoW.Me, ret => !StyxWoW.Me.HasAura("Lightning Shield", 2)),
                       new Decorator(ret => Totems.NeedToRecallTotems,
                                     new Action(ret => Totems.RecallTotems()))
                       ));
        }
示例#14
0
        public static Composite CreateShamanEnhancementPvPPullAndCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       new Decorator(
                           ret => !SpellManager.GlobalCooldown,
                           new PrioritySelector(
                               Helpers.Common.CreateAutoAttack(true),
                               Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                               Common.CreateShamanImbueMainHandBehavior(Imbue.Windfury, Imbue.Flametongue),
                               Common.CreateShamanImbueOffHandBehavior(Imbue.Frostbrand, Imbue.Flametongue),

                               Spell.BuffSelf("Lightning Shield"),
                               Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),
                               Spell.BuffSelf("Feral Spirit"),

                               Totems.CreateTotemsPvPBehavior(),

                               Spell.Cast("Stormstrike"),
                               Spell.Cast("Primal Strike", ret => !SpellManager.HasSpell("Stormstrike")),
                               Spell.Cast("Lava Lash",
                                          ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),

                               new Decorator(ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5) && (StyxWoW.Me.GetAuraTimeLeft("Maelstom Weapon", true).TotalSeconds < 3000 || StyxWoW.Me.GetPredictedHealthPercent() > 90),
                                             new PrioritySelector(
                                                 Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                                                 Spell.Cast("Lightning Bolt")
                                                 )
                                             ),

                               Spell.Cast("Unleash Elements"),
                               Spell.Buff("Flame Shock", true, ret => StyxWoW.Me.HasAura("Unleash Wind") || !SpellManager.HasSpell("Unleash Elements")),
                               Spell.Cast("Earth Shock", ret => StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 6)
                               )
                           ),

                       Movement.CreateMoveToMeleeBehavior(true)
                       ));
        }
示例#15
0
        private static bool IsMagmaTotemNeeded()
        {
            if (Spell.UseAOE && Me.GotTarget() && TotemIsKnown(WoWTotem.Magma) && AllowDpsTotems)
            {
                WoWTotemInfo ti = GetTotem(WoWTotemType.Fire);

                if (ti.WoWTotem == WoWTotem.FireElemental)
                {
                    return(false);
                }

                // for existing magma return no cast needed if it has enough mobs
                float rangeCheck = rangeCheck = Totems.GetTotemRange(WoWTotem.Magma);
                if (ti.WoWTotem == WoWTotem.Magma)
                {
                    int existcount = Unit.NearbyUnitsInCombatWithUsOrOurStuff.Count(u => ti.Unit.SpellDistance(u) < rangeCheck);
                    if (existcount >= 3)
                    {
                        return(false);
                    }
                }

                // so no good magma in range, so now check if we want one to be
                int nearcount = Unit.NearbyUnitsInCombatWithUsOrOurStuff.Count(u => u.SpellDistance() < rangeCheck);
                if (nearcount < 3)
                {
                    return(false);
                }

                if (ti.WoWTotem == WoWTotem.Magma)
                {
                    Logger.WriteDebug("IsMagmaTotemNeeded: existing Magma out of range, resetting since {0} mobs near me", nearcount);
                }
                else
                {
                    Logger.WriteDebug("IsMagmaTotemNeeded: found {0} mobs near me, setting Magma", nearcount);
                }

                return(true);
            }

            return(false);
        }
示例#16
0
        public static Composite CreateShamanElementalNormalPull()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),

                       Spell.BuffSelf("Lightning Shield"),

                       new Decorator(
                           ret => StyxWoW.Me.CurrentTarget.DistanceSqr < 40 * 40,
                           Totems.CreateTotemsNormalBehavior()),

                       // 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 => StyxWoW.Me.CurrentTarget.Distance < 12 ||
                           ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).Any(p => p.Location.DistanceSqr(StyxWoW.Me.CurrentTarget.Location) <= 40 * 40),
                           new PrioritySelector(
                               Spell.Buff("Flame Shock", true),
                               Spell.Cast("Unleash Weapon", ret => Common.IsImbuedForDPS(StyxWoW.Me.Inventory.Equipped.MainHand)),
                               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", ret => !StyxWoW.Me.IsMoving || StyxWoW.Me.HasAura("Spiritwalker's Grace") || TalentManager.HasGlyph("Unleashed Lightning")),

                       // we are moving so throw an instant of some type
                       Spell.Cast("Flame Shock"),
                       Spell.Cast("Unleash Weapon", ret => Common.IsImbuedForDPS(StyxWoW.Me.Inventory.Equipped.MainHand)),

                       Movement.CreateMoveToTargetBehavior(true, 35f)
                       ));
        }
示例#17
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))
                               )
                           )
                       ));
        }
示例#18
0
        public static Composite CreateShamanElementalInstancePullAndCombat()
        {
            return(new PrioritySelector(
                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),
                       Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                       Common.CreateShamanImbueMainHandBehavior(Imbue.Flametongue),

                       Spell.BuffSelf("Lightning Shield"),
                       Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),

                       Spell.BuffSelf("Elemental Mastery", ret => StyxWoW.Me.Combat),

                       Totems.CreateTotemsInstanceBehavior(),

                       new Decorator(
                           ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                           new PrioritySelector(
                               new Action(act => { Logger.WriteDebug("performing aoe behavior"); return RunStatus.Failure; }),
                               Spell.CastOnGround("Earthquake", ret => StyxWoW.Me.CurrentTarget.Location),
                               Spell.Cast("Chain Lightning", ret => Clusters.GetBestUnitForCluster(Unit.UnfriendlyUnitsNearTarget(15f), ClusterType.Chained, 12))
                               )),

                       Spell.Buff("Flame Shock", true),
                       Spell.Cast("Lava Burst"),
                       Spell.Cast("Earth Shock",
                                  ret => StyxWoW.Me.HasAura("Lightning Shield", 5) &&
                                  StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 3),
                       Spell.Cast("Unleash Elements",
                                  ret => StyxWoW.Me.IsMoving &&
                                  !StyxWoW.Me.HasAura("Spiritwalker's Grace") &&
                                  Common.IsImbuedForDPS(StyxWoW.Me.Inventory.Equipped.MainHand)),
                       Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                       Spell.Cast("Lightning Bolt"),
                       Movement.CreateMoveToTargetBehavior(true, 35f)
                       ));
        }
示例#19
0
        public static Composite CreateShamanEnhancementInstancePullAndCombat()
        {
            return(new PrioritySelector(
                       Spell.WaitForCast(true),
                       Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                       Spell.BuffSelf("Lightning Shield"),
                       Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat),
                       Spell.BuffSelf("Feral Spirit", ret => Unit.IsBoss(Me.CurrentTarget)),

                       Totems.CreateTotemsNormalBehavior(),
                       new Decorator(
                           ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                           new PrioritySelector(
                               Spell.Cast("Shamanistic Rage", ret => Me.CurrentMana <= 70),
                               Spell.Cast("Unleash Elements"),
                               Spell.Buff("Flame Shock", true),
                               Spell.Cast("Lava Lash",
                                          ret => StyxWoW.Me.CurrentTarget.HasMyAura("Flame Shock") &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                          StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),
                               Spell.Cast("Fire Nova"),
                               Spell.Cast("Chain Lightning", ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                               Spell.Cast("Stormstrike"),
                               Movement.CreateMoveToMeleeBehavior(true)
                               )),

                       Spell.Cast("Stormstrike"),
                       Spell.Cast("Primal Strike", ret => !SpellManager.HasSpell("Stormstrike")),
                       Spell.Cast("Lava Lash",
                                  ret => StyxWoW.Me.Inventory.Equipped.OffHand != null &&
                                  StyxWoW.Me.Inventory.Equipped.OffHand.ItemInfo.ItemClass == WoWItemClass.Weapon),
                       Spell.Cast("Lightning Bolt", ret => StyxWoW.Me.HasAura("Maelstrom Weapon", 5)),
                       Spell.Cast("Unleash Elements"),
                       Spell.Buff("Flame Shock", true, ret => StyxWoW.Me.HasAura("Unleash Flame") || !SpellManager.HasSpell("Unleash Elements")),
                       Spell.Cast("Earth Shock", ret => StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 6)
                       ));
        }
示例#20
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)

                       ));
        }
示例#21
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)
                                                   )
                                               )
                                           )
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#22
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
        }
示例#23
0
        public static Composite CreateShamanElementalNormalCombat()
        {
            return(new PrioritySelector(

                       new ThrottlePasses(1, CreateElementalDiagnosticOutputBehavior()),

                       Safers.EnsureTarget(),
                       Movement.CreateMoveToLosBehavior(),
                       Movement.CreateFaceTargetBehavior(),
                       Spell.WaitForCast(true),

                       new Decorator(
                           ret => !Common.InGCD,
                           new PrioritySelector(
                               Helpers.Common.CreateInterruptSpellCast(ret => StyxWoW.Me.CurrentTarget),

                               new Decorator(
                                   ret => Common.GetImbue(StyxWoW.Me.Inventory.Equipped.MainHand) == Imbue.None,
                                   Common.CreateShamanImbueMainHandBehavior(Imbue.Flametongue)),

                               Spell.BuffSelf("Lightning Shield"),

                               Spell.BuffSelf("Elemental Mastery",
                                              ret => Unit.NearbyUnitsInCombatWithMe.Any(u => u.Elite || u.IsPlayer) &&
                                              !StyxWoW.Me.HasAnyAura(Common.BloodlustName, "Time Warp", "Ancient Hysteria")),

                               Common.CreateShamanInCombatBuffs(true),

                               Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving),

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

                               Totems.CreateTotemsNormalBehavior(),

                               new Decorator(
                                   ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 3,
                                   new PrioritySelector(
                                       new Action(act => { Logger.WriteDebug("performing aoe behavior"); return RunStatus.Failure; }),

                                       Spell.BuffSelf("Astral Shift", ret => StyxWoW.Me.HealthPercent < 40 || Unit.NearbyUnitsInCombatWithMe.Count() >= 5),

                                       Spell.BuffSelf(Common.BloodlustName,
                                                      ret => Unit.NearbyUnitsInCombatWithMe.Count() >= 5 ||
                                                      Unit.NearbyUnitsInCombatWithMe.Any(u => u.Elite || u.IsPlayer)),

                                       Spell.BuffSelf("Elemental Mastery", ret =>
                                                      !StyxWoW.Me.HasAnyAura(Common.BloodlustName, "Time Warp", "Ancient Hysteria")),

                                       Spell.CastOnGround("Earthquake", ret => StyxWoW.Me.CurrentTarget.Location, req =>
                                                          (StyxWoW.Me.ManaPercent > 60 || StyxWoW.Me.HasAura("Clearcasting")) &&
                                                          Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 6),

                                       Spell.Cast("Chain Lightning", ret => Clusters.GetBestUnitForCluster(Unit.UnfriendlyUnitsNearTarget(15f), ClusterType.Chained, 12))
                                       )),

                               Spell.Buff("Flame Shock", true),

                               Spell.Cast("Lava Burst"),
                               Spell.Cast("Earth Shock",
                                          ret => StyxWoW.Me.HasAura("Lightning Shield", 5) &&
                                          StyxWoW.Me.CurrentTarget.GetAuraTimeLeft("Flame Shock", true).TotalSeconds > 3),

                               Spell.Cast("Unleash Elements", ret =>
                                          StyxWoW.Me.IsMoving &&
                                          !StyxWoW.Me.HasAura("Spiritwalker's Grace") &&
                                          Common.IsImbuedForDPS(StyxWoW.Me.Inventory.Equipped.MainHand)),

                               Spell.Cast("Chain Lightning", ret => Unit.UnfriendlyUnitsNearTarget(10f).Count() >= 2),
                               Spell.Cast("Lightning Bolt")
                               )
                           ),

                       Movement.CreateMoveToTargetBehavior(true, 35f)
                       ));
        }
示例#24
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)
                       ));
        }
示例#25
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)
                                                   )
                                               )
                                           )
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#26
0
        public static Composite CreateTotemsNormalBehavior()
        {
            // create Fire Totems behavior first, then wrap if needed
            PrioritySelector fireTotemBehavior = new PrioritySelector();

            fireTotemBehavior.AddChild(
                Spell.Buff(WoWTotem.FireElemental.ToSpellId(),
                           req => Common.StressfulSituation &&
                           Totems.AllowElementalTotems &&
                           !Exist(WoWTotem.EarthElemental) &&
                           !Spell.CanCastHack("Earth Elemental Totem")

                           )
                );

            if (TalentManager.CurrentSpec == WoWSpec.ShamanEnhancement)
            {
                fireTotemBehavior.AddChild(
                    Spell.Cast("Magma Totem", on => Me.CurrentTarget ?? Me, ret => IsMagmaTotemNeeded())
                    );
            }

            fireTotemBehavior.AddChild(
                Spell.BuffSelf("Searing Totem", ret => IsSearingTotemNeeded())
                );

            if (TalentManager.CurrentSpec == WoWSpec.ShamanRestoration)
            {
                fireTotemBehavior = new PrioritySelector(
                    new Decorator(
                        ret => StyxWoW.Me.Combat && StyxWoW.Me.GotTarget() && !Unit.NearbyGroupMembers.Any(),
                        fireTotemBehavior
                        )
                    );
            }

            // now
            return(new PrioritySelector(

                       new Throttle(1,
                                    new Action(r =>
            {
                bool ccMechanic = Me.HasAuraWithMechanic(WoWSpellMechanic.Fleeing | WoWSpellMechanic.Polymorphed | WoWSpellMechanic.Asleep);
                bool ccEffect = Me.HasAuraWithEffect(WoWApplyAuraType.ModFear | WoWApplyAuraType.ModPacify | WoWApplyAuraType.ModPacifySilence);
                bool ccAttrib = Me.Fleeing;
                if (ccMechanic || ccEffect || ccAttrib)
                {
                    Logger.WriteDebug(Color.Pink, "... FEAR CHECKED OUT --  Mechanic={0}  Effect={1}  Attrib={2}", ccMechanic, ccEffect, ccAttrib);
                }
                return RunStatus.Failure;
            })
                                    ),


                       Spell.BuffSelf(WoWTotem.Tremor.ToSpellId(),
                                      ret => Unit.GroupMembers.Any(f => f.Fleeing && f.Distance < Totems.GetTotemRange(WoWTotem.Tremor)) &&
                                      !Exist(WoWTotem.StoneBulwark, WoWTotem.EarthElemental)),

                       new Decorator(
                           req => PetManager.NeedsPetSupport &&
                           Totems.ExistInRange(Me.Location, WoWTotem.EarthElemental) &&
                           !Me.HasAura("Reinforce") &&
                           !Spell.DoubleCastContains(Me, "Reinforce"),
                           new Sequence(
                               PetManager.CastAction("Reinforce", on => Me),
                               new Action(r => Spell.UpdateDoubleCast("Reinforce", Me))
                               )
                           ),

                       new Decorator(
                           req => PetManager.NeedsPetSupport &&
                           Totems.ExistInRange(Me.Location, WoWTotem.FireElemental) &&
                           !Me.HasAura("Empower") &&
                           !Spell.DoubleCastContains(Me, "Empower"),
                           new Sequence(
                               PetManager.CastAction("Empower", on => Me),
                               new Action(r => Spell.UpdateDoubleCast("Empower", Me))
                               )
                           ),

                       new Decorator(
                           ret => ShouldWeDropTotemsYet,

                           new PrioritySelector(

                               // check for stress - enemy player or elite within 8 levels nearby
                               // .. dont use NearbyUnitsInCombatWithMe since it checks .Tagged and we only care if we are being attacked
                               ctx => Common.StressfulSituation,

                               // earth totems
                               Spell.BuffSelf(WoWTotem.EarthElemental.ToSpellId(),
                                              ret => ((bool)ret || Group.Tanks.Any(t => t.IsDead && t.Distance < 40)) &&
                                              Totems.AllowElementalTotems &&
                                              !Exist(WoWTotem.StoneBulwark)
                                              ),

                               Spell.BuffSelf(WoWTotem.StoneBulwark.ToSpellId(),
                                              ret => Me.Combat && Me.HealthPercent < ShamanSettings.StoneBulwarkTotemPercent && !Exist(WoWTotem.EarthElemental)),

                               new PrioritySelector(
                                   ctx => Unit.NearbyUnfriendlyUnits.Any(u => u.IsTargetingMeOrPet && u.IsPlayer && u.Combat),

                                   Spell.BuffSelf(WoWTotem.Earthgrab.ToSpellId(),
                                                  ret => (bool)ret && !Exist(WoWTotemType.Earth)),

                                   Spell.BuffSelf(WoWTotem.Earthbind.ToSpellId(),
                                                  ret => (bool)ret && !Exist(WoWTotemType.Earth))
                                   ),

                               // fire totems
                               fireTotemBehavior,

                               // water totems
                               Spell.BuffSelf("Mana Tide Totem",
                                              ret =>
            {
                if (TalentManager.CurrentSpec != WoWSpec.ShamanRestoration)
                {
                    return false;
                }

                // Logger.WriteDebug("Mana Tide Totem Check:  current mana {0:F1}%", Me.ManaPercent);
                if (Me.ManaPercent > ShamanSettings.ManaTideTotemPercent)
                {
                    return false;
                }
                if (Exist(WoWTotem.HealingTide, WoWTotem.HealingStream))
                {
                    return false;
                }
                return true;
            }),

                               /* Healing...: handle within Helaing logic
                                *              Spell.Cast("Healing Tide Totem", ret => ((bool)ret) && StyxWoW.Me.HealthPercent < 50
                                *                  && !Exist(WoWTotem.ManaTide)),
                                *
                                *              Spell.Cast("Healing Stream Totem", ret => ((bool)ret) && StyxWoW.Me.HealthPercent < 80
                                *                  && !Exist( WoWTotemType.Water)),
                                */

                               // air totems
                               Spell.Cast("Stormlash Totem", ret => PartyBuff.WeHaveBloodlust && !Me.HasAura("Stormlash Totem")),

                               new Decorator(
                                   ret => !Exist(WoWTotemType.Air),
                                   new PrioritySelector(
                                       Spell.Cast("Grounding Totem",
                                                  ret => Unit.NearbyUnfriendlyUnits.Any(u => u.SpellDistance() < 40 && u.IsTargetingMeOrPet && u.IsCasting)),

                                       Spell.Cast("Capacitor Totem",
                                                  ret => ((bool)ret) &&
                                                  Unit.NearbyUnfriendlyUnits.Any(u => u.SpellDistance() < GetTotemRange(WoWTotem.Capacitor))),

                                       Spell.BuffSelf("Windwalk Totem",
                                                      ret => Unit.HasAuraWithMechanic(StyxWoW.Me, WoWSpellMechanic.Rooted, WoWSpellMechanic.Snared))
                                       )
                                   )
                               )
                           )
                       ));
        }
示例#27
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)
                           )
                       ));
        }
示例#28
0
        public static Composite CreateRestoShamanHealingOnlyBehavior(bool selfOnly, bool moveInRange)
        {
            HealerManager.NeedHealTargeting = true;
            return(new PrioritySelector(
                       ctx => selfOnly ? StyxWoW.Me : HealerManager.Instance.FirstUnit,
                       new Decorator(
                           ret => ret != null && (moveInRange || ((WoWUnit)ret).InLineOfSpellSight && ((WoWUnit)ret).DistanceSqr < 40 * 40),
                           new PrioritySelector(
                               Spell.WaitForCast(),
                               new Decorator(
                                   ret => moveInRange,
                                   Movement.CreateMoveToLosBehavior(ret => (WoWUnit)ret)),
                               Totems.CreateSetTotems(),
                               // Mana tide...
                               Spell.Cast("Mana Tide Totem", ret => StyxWoW.Me.ManaPercent < 80),
                               // Grounding...
                               Spell.Cast("Grounding Totem", ret => Unit.NearbyUnfriendlyUnits.Any(u => u.Distance < 40 && u.IsTargetingMeOrPet && u.IsCasting)),

                               // 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)),
                               // And deal with some edge PVP cases.

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

                               // Pop NS if someone is in some trouble.
                               Spell.BuffSelf("Nature's Swiftness", ret => ((WoWUnit)ret).HealthPercent < 15),
                               Spell.Heal("Unleash Elements", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).HealthPercent < 40),
                               // GHW is highest priority. It should be fairly low health %. (High-end healers will have this set to 70ish
                               Spell.Heal("Greater Healing Wave", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).HealthPercent < 50),
                               // Most (if not all) will leave this at 90. Its lower prio, high HPM, low HPS
                               Spell.Heal("Healing Wave", ret => (WoWUnit)ret, ret => ((WoWUnit)ret).HealthPercent < 60),


                               // CH/HR only in parties/raids
                               new Decorator(
                                   ret => StyxWoW.Me.IsInParty || StyxWoW.Me.IsInRaid,
                                   new PrioritySelector(
                                       // This seems a bit tricky, but its really not. This is just how we cache a somewhat expensive lookup.
                                       // Set the context to the "best unit" for the cluster, so we don't have to do that check twice.
                                       // Then just use the context when passing the unit to throw the heal on, and the target of the heal from the cluster count.
                                       // Also ensure it will jump at least 3 times. (CH is pointless to cast if it won't jump 3 times!)
                                       new PrioritySelector(
                                           context => Clusters.GetBestUnitForCluster(ChainHealPlayers, ClusterType.Chained, 12f),
                                           Spell.Heal(
                                               "Chain Heal", ret => (WoWPlayer)ret,
                                               ret => Clusters.GetClusterCount((WoWPlayer)ret, ChainHealPlayers, ClusterType.Chained, 12f) > 2)),

                                       // Now we're going to do the same thing as above, but this time we're going to do it with healing rain.
                                       new PrioritySelector(
                                           context => Clusters.GetBestUnitForCluster(Unit.NearbyFriendlyPlayers.Cast <WoWUnit>(), ClusterType.Radius, 10f),
                                           Spell.CastOnGround(
                                               "Healing Rain", ret => ((WoWPlayer)ret).Location,
                                               ret =>
                                               Clusters.GetClusterCount((WoWPlayer)ret, Unit.NearbyFriendlyPlayers.Cast <WoWUnit>(), ClusterType.Radius, 10f) >
                                               // If we're in a raid, check for 4 players. If we're just in a party, check for 3.
                                               (StyxWoW.Me.IsInRaid ? 3 : 2))))),

                               new Decorator(
                                   ret => moveInRange,
                                   Movement.CreateMoveToTargetBehavior(true, 38f, ret => (WoWUnit)ret))

                               ))));
        }
示例#29
0
        public static Composite CreateShamanDpsHealBehavior()
        {
            Composite offheal;

            if (!SingularSettings.Instance.DpsOffHealAllowed)
            {
                offheal = new ActionAlwaysFail();
            }
            else
            {
                offheal = new Decorator(
                    ret => HealerManager.ActingAsOffHealer,
                    CreateDpsShamanOffHealBehavior()
                    );
            }

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

                           new Decorator(
                               ret => !Me.Combat &&
                               (!Me.IsMoving || Me.HasAura("Maelstrom Weapon", 5)) &&
                               Me.HealthPercent <= 85 && // not redundant... this eliminates unnecessary GetPredicted... checks
                               SpellManager.HasSpell("Healing Surge") &&
                               Me.PredictedHealthPercent(includeMyHeals: true) < 85,
                               new PrioritySelector(
                                   new Sequence(
                                       ctx => (float)Me.HealthPercent,
                                       new Action(r => Logger.WriteDebug("Healing Surge: {0:F1}% Predict:{1:F1}% and moving:{2}, cancast:{3}", (float)r, Me.PredictedHealthPercent(includeMyHeals: true), Me.IsMoving, Spell.CanCastHack("Healing Surge", Me, skipWowCheck: false))),
                                       Spell.Cast(
                                           "Healing Surge",
                                           mov => true,
                                           on => Me,
                                           req => true,
                                           cancel => Me.HealthPercent > 85
                                           ),
                                       new WaitContinue(TimeSpan.FromMilliseconds(500), until => !Me.IsCasting && Me.HealthPercent > (1.1 * ((float)until)), new ActionAlwaysSucceed()),
                                       new Action(r => Logger.WriteDebug("Healing Surge: After Heal Attempted: {0:F1}% Predicted: {1:F1}%", Me.HealthPercent, Me.PredictedHealthPercent(includeMyHeals: true)))
                                       ),
                                   new Action(r => Logger.WriteDebug("Healing Surge: After Heal Skipped: {0:F1}% Predicted: {1:F1}%", Me.HealthPercent, Me.PredictedHealthPercent(includeMyHeals: true)))
                                   )
                               ),

                           new Decorator(
                               ret => Me.Combat,

                               new PrioritySelector(

                                   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 < ShamanSettings.ShamanisticRagePercent || Common.StressfulSituation),

                                   Spell.HandleOffGCD(
                                       Spell.BuffSelf("Ancestral Guidance",
                                                      ret => Me.HealthPercent < ShamanSettings.SelfAncestralGuidance &&
                                                      Me.GotTarget() &&
                                                      Me.CurrentTarget.TimeToDeath() > 8
                                                      )
                                       ),

                                   new Decorator(
                                       req => !Me.IsMoving && ShamanSettings.SelfHealingStreamTotem > 0 && !Totems.Exist(WoWTotemType.Water),
                                       Spell.BuffSelf(
                                           WoWTotem.HealingStream.ToSpellId(),
                                           req =>
            {
                int count = Unit.NearbyUnitsInCombatWithMeOrMyStuff.Count(u => !u.IsTrivial());
                if (count > 1)
                {
                    return true;
                }
                if (count > 0 && Me.HealthPercent < ShamanSettings.SelfHealingStreamTotem)
                {
                    if (!Me.GotTarget() || Me.CurrentTarget.IsPlayer || Me.CurrentTarget.TimeToDeath() > 5)
                    {
                        return true;
                    }
                    if (Me.HealthPercent < (ShamanSettings.SelfHealingStreamTotem / 2))
                    {
                        return true;
                    }
                }
                return false;
            }
                                           )
                                       ),

                                   // save myself if possible
                                   new Decorator(
                                       ret => (!Me.IsInGroup() || Battlegrounds.IsInsideBattleground) &&
                                       (!Me.IsMoving || Me.HasAura("Maelstrom Weapon", 5) || !Spell.IsSpellOnCooldown("Ancestral Swiftness")) &&
                                       Me.HealthPercent < ShamanSettings.SelfAncestralSwiftnessHeal &&
                                       Me.PredictedHealthPercent(includeMyHeals: true) < ShamanSettings.SelfAncestralSwiftnessHeal,
                                       new PrioritySelector(
                                           Spell.HandleOffGCD(Spell.BuffSelf("Ancestral Swiftness")),
                                           new PrioritySelector(
                                               new Sequence(
                                                   ctx => (float)Me.HealthPercent,
                                                   new Action(r => Logger.WriteDebug("Healing Surge: {0:F1}% Predict:{1:F1}% and moving:{2}, cancast:{3}", (float)r, Me.PredictedHealthPercent(includeMyHeals: true), Me.IsMoving, Spell.CanCastHack("Healing Surge", Me, skipWowCheck: false))),
                                                   Spell.Cast(
                                                       "Healing Surge",
                                                       mov => true,
                                                       on => Me,
                                                       req => true,
                                                       cancel => Me.HealthPercent > 85
                                                       ),
                                                   new WaitContinue(TimeSpan.FromMilliseconds(500), until => !Me.IsCasting && Me.HealthPercent > (1.1 * ((float)until)), new ActionAlwaysSucceed()),
                                                   new Action(r => Logger.WriteDebug("Healing Surge: After Heal Attempted: {0:F1}% Predicted: {1:F1}%", Me.HealthPercent, Me.PredictedHealthPercent(includeMyHeals: true)))
                                                   ),
                                               new Action(r => Logger.WriteDebug("Healing Surge: After Heal Skipped: {0:F1}% Predicted: {1:F1}%", Me.HealthPercent, Me.PredictedHealthPercent(includeMyHeals: true)))
                                               )
                                           )
                                       )
                                   )
                               ),

                           offheal
                           )
                       ));
        }
示例#30
0
        public static Composite CreateTotemsInstanceBehavior()
        {
            // create Fire Totems behavior first, then wrap if needed
            PrioritySelector fireTotemBehavior = new PrioritySelector();

            fireTotemBehavior.AddChild(
                Spell.Buff(
                    "Fire Elemental Totem",
                    req => Me.CurrentTarget.IsBoss() &&
                    AllowElementalTotems
                    )
                );

            if (TalentManager.CurrentSpec == WoWSpec.ShamanEnhancement)
            {
                fireTotemBehavior.AddChild(
                    Spell.Cast("Magma Totem", on => Me.CurrentTarget ?? Me, ret => IsMagmaTotemNeeded())
                    );
            }

            if (TalentManager.CurrentSpec == WoWSpec.ShamanRestoration)
            {
                fireTotemBehavior = new PrioritySelector(
                    new Decorator(
                        ret => StyxWoW.Me.Combat && StyxWoW.Me.GotTarget() && !HealerManager.Instance.TargetList.Any(m => m.IsAlive),
                        fireTotemBehavior
                        )
                    );
            }
            else
            {
                fireTotemBehavior.AddChild(
                    Spell.Cast("Searing Totem", ret => IsSearingTotemNeeded())
                    );
            }


            // now
            return(new PrioritySelector(

                       Spell.BuffSelf(WoWTotem.Tremor.ToSpellId(),
                                      ret => Unit.GroupMembers.Any(f => f.Fleeing && f.Distance < Totems.GetTotemRange(WoWTotem.Tremor)) &&
                                      !Exist(WoWTotem.StoneBulwark, WoWTotem.EarthElemental)),

                       new Decorator(
                           req => Totems.ExistInRange(Me.Location, WoWTotem.EarthElemental) &&
                           !Me.HasAura("Reinforce") &&
                           !Spell.DoubleCastContains(Me, "Reinforce"),
                           new Sequence(
                               PetManager.CastAction("Reinforce", on => Me),
                               new Action(r => Spell.UpdateDoubleCast("Reinforce", Me))
                               )
                           ),

                       new Decorator(
                           req => Totems.ExistInRange(Me.Location, WoWTotem.FireElemental) &&
                           !Me.HasAura("Empower") &&
                           !Spell.DoubleCastContains(Me, "Empower"),
                           new Sequence(
                               PetManager.CastAction("Empower", on => Me),
                               new Action(r => Spell.UpdateDoubleCast("Empower", Me))
                               )
                           ),

                       new Decorator(
                           ret => ShouldWeDropTotemsYet,

                           new PrioritySelector(

                               // earth totems
                               Spell.Cast(WoWTotem.EarthElemental.ToSpellId(),
                                          on => Me.CurrentTarget ?? Me,
                                          req => {
                if (!Totems.AllowElementalTotems)
                {
                    return false;
                }

                if (Exist(WoWTotem.StoneBulwark))
                {
                    return false;
                }

                if (Spell.IsSpellOnCooldown("Earth Elemental Totem"))
                {
                    return false;
                }

                // no living tanks in range
                IEnumerable <WoWUnit> tanks = Group.Tanks.Where(u => u.DistanceSqr < 65 * 65);
                if (!tanks.Any(t => t.IsAlive) || tanks.Any(t => t.IsDead))
                {
                    // we are okay if another Earth Elemental active
                    if (ObjectManager.GetObjectsOfType <WoWUnit>(false, false).Any(o => o.Entry == 15352))
                    {
                        return false;
                    }

                    // we are okay if nothing in combat with our group
                    if (!Unit.NearbyUnitsInCombatWithUsOrOurStuff.Any())
                    {
                        return false;
                    }
                }

                // check we can cast it before messaging
                if (!Spell.CanCastHack("Earth Elemental Totem"))
                {
                    return false;
                }

                Logger.Write(LogColor.Hilite, "^Earth Elemental Totem: tank is dead or not nearby");
                return true;
            }),

                               // Stone Bulwark handled in CombatBuffs with Astral Shift

                               // fire totems
                               fireTotemBehavior,

                               // water totems
                               Spell.BuffSelf("Mana Tide Totem",
                                              ret =>
            {
                if (TalentManager.CurrentSpec != WoWSpec.ShamanRestoration)
                {
                    return false;
                }

                // Logger.WriteDebug("Mana Tide Totem Check:  current mana {0:F1}%", Me.ManaPercent);
                if (Me.ManaPercent > ShamanSettings.ManaTideTotemPercent)
                {
                    return false;
                }
                if (Exist(WoWTotem.HealingTide, WoWTotem.HealingStream))
                {
                    return false;
                }
                return true;
            }),


                               /* Healing...: handle within Helaing logic
                                *              Spell.Cast("Healing Tide Totem", ret => ((bool)ret) && StyxWoW.Me.HealthPercent < 50
                                *                  && !Exist(WoWTotem.ManaTide)),
                                *
                                *              Spell.Cast("Healing Stream Totem", ret => ((bool)ret) && StyxWoW.Me.HealthPercent < 80
                                *                  && !Exist( WoWTotemType.Water)),
                                */

                               // air totems
                               Spell.Cast("Stormlash Totem", ret => PartyBuff.WeHaveBloodlust && !Me.HasAura("Stormlash Totem")),

                               new Decorator(
                                   ret => !Exist(WoWTotemType.Air),
                                   new PrioritySelector(
                                       Spell.Cast("Grounding Totem",
                                                  on => Unit.NearbyUnfriendlyUnits.FirstOrDefault(u => u.SpellDistance() < 40 && u.IsTargetingMeOrPet && u.IsCasting)),

                                       Spell.Cast("Capacitor Totem",
                                                  on => Unit.NearbyUnfriendlyUnits.FirstOrDefault(u => u.SpellDistance() < GetTotemRange(WoWTotem.Capacitor) && u.IsTargetingMeOrPet)),

                                       Spell.BuffSelf("Windwalk Totem",
                                                      ret => Unit.HasAuraWithMechanic(StyxWoW.Me, WoWSpellMechanic.Rooted, WoWSpellMechanic.Snared))
                                       )
                                   )
                               )
                           )
                       ));
        }