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 CreateDeathKnightUnholyCombat() { return(new PrioritySelector( UnholyCastRaiseDead(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDeathKnightPullMore(), Common.CreateDeathGripBehavior(), Common.CreateAntiMagicShellBehavior(), Spell.Cast("Death Strike", ret => (Me.HasActiveAura("Dark Succor") && Me.HealthPercent <= DeathKnightSettings.DeathStrikeSuccorPercent) || Me.HealthPercent <= DeathKnightSettings.DeathStrikePercent ), Spell.Cast("Icebound Fortitude", ret => Me.HealthPercent <= DeathKnightSettings.IceboundFortitudePercent), //Corpse Shield new Decorator( ret => Common.HasTalent(DeathKnightTalents.CorpseShield) && Me.HealthPercent <= DeathKnightSettings.CorpseShieldPercent && Me.GotAlivePet, new PrioritySelector( PetManager.CastAction("Protective Bile", on => Me.Pet), Spell.Cast("Corpse Shield") ) ), // Artifact Weapon new Decorator( ret => DeathKnightSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) > 1, new PrioritySelector( Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ) ) ), Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ), new Decorator( ret => Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) >= DeathKnightSettings.DeathAndDecayCount || Common.HasTalent(DeathKnightTalents.Epidemic) && Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount, new PrioritySelector( Spell.Cast("Summon Gargoyle", ret => Me.CurrentTarget.IsStressful() && DeathKnightSettings.UseSummonGargoyle), Spell.Cast("Outbreak", ret => Unit.NearbyUnfriendlyUnits.Any(u => u.IsWithinMeleeRange && u.GetAuraTimeLeft("Virulent Plague").TotalSeconds < 1.8)), Spell.BuffSelf("Dark Transformation", ret => Me.GotAlivePet), Spell.CastOnGround("Death and Decay", on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location), Spell.Cast("Scourge Strike"), Spell.Cast("Epidemic", ret => Spell.IsSpellOnCooldown("Death and Decay") || Spell.IsSpellOnCooldown("Defile") || Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) < DeathKnightSettings.DeathAndDecayCount), Spell.Cast("Festering Strike", ret => Me.CurrentTarget.GetAuraStacks("Festering Wound") < 5), Spell.Cast("Death Coil", ret => Me.RunicPowerPercent > 90 || Me.HasActiveAura("Sudden Doom")) ) ), new Decorator( ret => Me.Level < 100, CreateLowLevelRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.DarkArbiter), CreateDarkArbiterRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.Defile), CreateDefileRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.SoulReaper), CreateSoulReaperRotation() ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
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)) ) ) ) ) )); }