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)) ) ) ) ) )); }
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)) ) ) ) ) )); }