private static Composite CreateArmsAoeCombat(SimpleIntDelegate aoeCount) { return(new PrioritySelector( new Decorator(ret => Spell.UseAOE && aoeCount(ret) >= 3, new PrioritySelector( Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownAOE), Spell.Cast("Cleave"), Spell.Cast("Thunder Clap"), Spell.Cast("Bladestorm", ret => aoeCount(ret) >= 4), Spell.Cast("Shockwave", ret => Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 10f) >= 3), Spell.Cast("Whirlwind", ret => Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), Spell.Cast("Mortal Strike"), Spell.Cast("Colossus Smash", ret => !StyxWoW.Me.CurrentTarget.HasMyAura("Colossus Smash")), Spell.Cast("Overpower") ) ) )); }
private static Composite CreateArmsAoeCombat(SimpleIntDelegate aoeCount) { return(new PrioritySelector( new Decorator(ret => aoeCount(ret) >= 3, new PrioritySelector( Spell.Cast("Thunder Clap"), Spell.Cast("Bladestorm", ret => aoeCount(ret) >= 4), Spell.Cast("Shockwave", ret => Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 10f) >= 3), Spell.Cast("Dragon Roar"), Spell.Cast("Whirlwind"), Spell.Cast("Mortal Strike"), Spell.Cast("Colossus Smash", ret => !StyxWoW.Me.CurrentTarget.HasMyAura("Colossus Smash")), Spell.Cast("Overpower") ) ), Spell.BuffSelf("Sweeping Strikes", ret => aoeCount(ret) == 2) )); }
private static Composite CreateArmsAoeCombat(SimpleIntDelegate aoeCount) { return(new PrioritySelector( //cleave new Decorator( ret => Spell.UseAOE && aoeCount(ret) >= 2 && Common.HasTalent(WarriorTalents.SweepingStrikes), new PrioritySelector( Spell.Cast("Mortal Strike"), Spell.Cast("Execute", ret => Me.HasAura("Stone Heart")), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses") && !Target.HasAura("Precise Strikes")), Spell.Cast("Warbreaker", ret => !Me.HasAura("Shattered Defenses")), Spell.Cast("Whirlwind", ret => Common.HasTalent(WarriorTalents.FervorOfBattle) && (DebuffColossusSmashUp || (Me.CurrentRage >= Me.MaxRage - 50)) && Me.HasAura("Cleave")), Spell.Cast("Rend", ret => Target.GetAuraByName("Rend").TimeLeft() < Target.GetAuraByName("Rend").Duration * .3), Spell.Cast("Bladestorm"), Spell.Cast("Cleave"), Spell.Cast("Whirlwind", ret => Me.CurrentRage >= 40 || Me.HasAura("Cleave")), new ActionAlwaysFail() )), new Decorator( //aoe ret => Spell.UseAOE && aoeCount(ret) >= 5 && Common.HasTalent(WarriorTalents.SweepingStrikes), new PrioritySelector( Spell.Cast("Warbreaker", ret => Spell.GetSpellCooldown("Bladestorm").TotalSeconds < 1 && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 1), Spell.Cast("Bladestorm", ret => Me.HasAura("Battle Cry") && (NumTier20Pieces >= 4 || StyxWoW.Me.Inventory.Equipped.Head.ItemInfo.Guid == 151823)), Spell.Cast("Colossus Smash", ret => !Me.HasAura("In For The Kill") && Common.HasTalent(WarriorTalents.InForTheKill)), Spell.Cast("Colossus Smash", ret => !DebuffColossusSmashUp && Unit.UnfriendlyUnits(8).Count() <= 10), Spell.Cast("Cleave"), Spell.Cast("Whirlwind", ret => Me.HasAura("Cleave")), Spell.Cast("Whirlwind", ret => Unit.UnfriendlyUnits(8).Count() >= 7), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses")), Spell.Cast("Execute", ret => Me.HasAura("Stone Heart")), Spell.Cast("Mortal Strike", ret => Me.HasAura("Shattered Defenses") || Target.GetAuraByName("Executioner's Precision").stackCount == 0), Spell.Cast("Rend", ret => Target.GetAuraByName("Rend").TimeLeft() < Target.GetAuraByName("Rend").Duration * .3 && Unit.UnfriendlyUnits(8).Count() <= 3, RendCycleTarget), Spell.Cast("Whirlwind") ) ) )); }
/// <summary> /// Creates a behavior to cast a spell by ID, with special requirements, on a specific unit. /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <param name = "spellId">Identifier for the spell.</param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite Cast(SimpleIntDelegate spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements) { if (spellId == null || onUnit == null || requirements == null) { System.Diagnostics.Debug.Assert(spellId != null); System.Diagnostics.Debug.Assert(onUnit != null); System.Diagnostics.Debug.Assert(requirements != null); return new ActionAlwaysFail(); } return new Throttle( new Action(ret => { int id = spellId(ret); // exit now if spell search not needed if (id == 0) return RunStatus.Failure; SpellFindResults sfr; if (SpellManager.FindSpell(id, out sfr)) { WoWUnit castOnUnit = onUnit(ret); if (castOnUnit != null && requirements(ret)) { if (Spell.CanCastHack(sfr, castOnUnit, skipWowCheck: true)) { WoWSpell spell = sfr.Override ?? sfr.Original; // LogCast(spell.Name, castOnUnit, spell.IsHealingSpell); LogCast(spell.Name, castOnUnit, spell.IsHeal()); if (Spell.CastPrimative(spell, castOnUnit)) { return RunStatus.Success; } } } } return RunStatus.Failure; }) ); }
/// <summary> /// Creates a behavior to cast a buff by ID on yourself with special requirements. Returns RunStatus.Success if /// successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 5/6/2011. /// </remarks> /// <param name = "spellId">The buff ID.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite BuffSelf(SimpleIntDelegate spellId, SimpleBooleanDelegate requirements) { System.Diagnostics.Debug.Assert(requirements != null); return Buff(spellId, ret => StyxWoW.Me, requirements); }
/// <summary> /// Creates a behavior to cast a buff by name, with special requirements, on a specific unit. Returns /// RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "spellId">The ID of the buff</param> /// <param name = "onUnit">The on unit</param> /// <param name = "requirements">The requirements.</param> /// <returns></returns> public static Composite Buff(SimpleIntDelegate spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, HasGcd gcd = HasGcd.Yes) { return new Decorator( req => onUnit(req) != null && onUnit(req).Auras.Values.All(a => a.SpellId != spellId(req)), Cast(spellId, onUnit, requirements) ); }
public static Composite BuffSelf(SimpleIntDelegate idd, SimpleBooleanDelegate requirements, HasGcd gcd) { return Buff(idd, on => Me, requirements, gcd); }
public static Composite CreateMonkCloseDistanceBehavior( SimpleIntDelegate minDist = null, UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate canReq = null) { /* new Decorator( unit => (unit as WoWUnit).SpellDistance() > 10 && Me.IsSafelyFacing(unit as WoWUnit, 5f), Spell.Cast("Roll") ) */ bool hasFSKGlpyh = TalentManager.HasGlyph("Flying Serpent Kick"); bool hasTigersLust = HasTalent(MonkTalents.TigersLust); if (minDist == null) minDist = min => Me.Combat ? 10 : 12; if (onUnit == null) onUnit = on => Me.CurrentTarget; if (canReq == null) canReq = req => true; return new Throttle( 1, new PrioritySelector( ctx => onUnit(ctx), new Decorator( req => { if (!MovementManager.IsClassMovementAllowed) return false; if (!canReq(req)) return false; float dist = Me.SpellDistance(req as WoWUnit); if ( dist <= minDist(req)) return false; if ((req as WoWUnit).IsAboveTheGround()) return false; float facingPrecision = (req as WoWUnit).SpellDistance() < 15 ? 6f : 4f; if (!Me.IsSafelyFacing(req as WoWUnit, facingPrecision)) return false; bool isObstructed = Movement.MeshTraceline(Me.Location, (req as WoWUnit).Location); if (isObstructed == true) return false; return true; }, new PrioritySelector( Spell.BuffSelf( "Tiger's Lust", req => hasTigersLust && !Me.HasAuraWithEffect(WoWApplyAuraType.ModIncreaseSpeed) && Me.HasAuraWithEffect(WoWApplyAuraType.ModRoot, WoWApplyAuraType.ModDecreaseSpeed) ), new Sequence( Spell.Cast( "Flying Serpent Kick", on => (WoWUnit) on, ret => TalentManager.CurrentSpec == WoWSpec.MonkWindwalker && !Me.Auras.ContainsKey("Flying Serpent Kick") && ((ret as WoWUnit).SpellDistance() > 25 || Spell.IsSpellOnCooldown("Roll")) ), /* wait until in progress */ new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(750), until => Me.Auras.ContainsKey("Flying Serpent Kick"), new Action( r => Logger.WriteDebug("CloseDistance: Flying Serpent Kick detected towards {0} @ {1:F1} yds in progress", (r as WoWUnit).SafeName(), (r as WoWUnit).SpellDistance())) ), new Action( r => { Logger.WriteDebug("CloseDistance: failure - did not see Flying Serpent Kick aura appear - lag?"); return RunStatus.Failure; }) ), /* cancel when in range */ new Wait( TimeSpan.FromMilliseconds(2500), until => { if (!Me.Auras.ContainsKey("Flying Serpent Kick")) { Logger.WriteDebug("CloseDistance: Flying Serpent Kick completed on {0} @ {1:F1} yds and {2} behind me", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance(), (until as WoWUnit).IsBehind(Me) ? "IS" : "is NOT"); return true; } if (!hasFSKGlpyh) { SpellFindResults sfr; SpellManager.FindSpell("Flying Serpent Kick", out sfr); if (((until as WoWUnit).IsWithinMeleeRange || (until as WoWUnit).SpellDistance() < 8f)) { Logger.Write(LogColor.Cancel, "/cancel Flying Serpent Kick in melee range of {0} @ {1:F1} yds", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance()); //Spell.CastPrimative("Flying Serprent Kick"); // Lua.DoString("CastSpellByID(" + sfr.Original.Id + ")"); return true; } else if ((until as WoWUnit).IsBehind(Me)) { Logger.Write(LogColor.Cancel, "/cancel Flying Serpent Kick flew past {0} @ {1:F1} yds", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance()); //Spell.CastPrimative("Flying Serprent Kick"); //Lua.DoString("CastSpellByID(" + sfr.Original.Id + ")"); return true; } } return false; }, new PrioritySelector( new Decorator( req => !Me.Auras.ContainsKey("Flying Serpent Kick"), new ActionAlwaysSucceed() ), new Sequence( new Action( r => { if (hasFSKGlpyh) { Logger.WriteDebug("CloseDistance: FSK is glyphed, should not be here - notify developer!"); } else { Logger.WriteDebug("CloseDistance: casting Flying Serpent Kick to cancel"); Spell.CastPrimative(101545); } }), /* wait until cancel takes effect */ new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(450), until => !Me.Auras.ContainsKey("Flying Serpent Kick"), new Action( r => Logger.WriteDebug("CloseDistance: Flying Serpent Kick complete, landed {0:F1} yds from {1}", (r as WoWUnit).SpellDistance(), (r as WoWUnit).SafeName())) ), new Action( r => { Logger.WriteDebug("CloseDistance: error - Flying Serpent Kick was not removed - lag?"); }) ) ) ) ) ), Spell.BuffSelf("Tiger's Lust", req => hasTigersLust ), new Sequence( Spell.Cast("Roll", on => (WoWUnit)on, req => !MonkSettings.DisableRoll && MovementManager.IsClassMovementAllowed), new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(500), until => Me.Auras.ContainsKey("Roll"), new Action(r => Logger.WriteDebug("CloseDistance: Roll in progress")) ), new Action( r => { Logger.WriteDebug("CloseDistance: failure - did not detect Roll in progress aura- lag?"); return RunStatus.Failure; }) ), new Wait( TimeSpan.FromMilliseconds(950), until => !Me.Auras.ContainsKey("Roll"), new Action(r => Logger.WriteDebug("CloseDistance: Roll has ended")) ) ) ) ) ) ); }
/// <summary> /// Creates a behavior to cast a spell by ID, with special requirements, on a specific unit. /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <param name = "spellId">Identifier for the spell.</param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite Cast(SimpleIntDelegate spellId, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements) { return new Decorator(ret => requirements != null && onUnit != null, new Throttle( new Action(ret => { RunStatus runStat = RunStatus.Failure; _castOnUnit = onUnit(ret); // if (_castOnUnit == null || !requirements(ret) || !Spell.CanCastHack(spellId(ret), _castOnUnit, true)) if (_castOnUnit != null && requirements(ret)) { _castSpell = WoWSpell.FromId(spellId(ret)); if (_castSpell != null) { if (Spell.CanCastHack(_castSpell.Name, onUnit(ret), skipWowCheck: true)) { string sname = _castSpell != null ? _castSpell.Name : "#" + _castSpell.Id.ToString(); LogCast(sname, _castOnUnit); if (SpellManager.Cast(_castSpell.Id, _castOnUnit)) { runStat = RunStatus.Success; } } } } _castSpell = null; _castOnUnit = null; return runStat; }) ) ); }
/// <summary> /// Creates a behavior to cast a buff by ID on yourself with special requirements. Returns RunStatus.Success if /// successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 5/6/2011. /// </remarks> /// <param name = "spellId">The buff ID.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite BuffSelf(SimpleIntDelegate spellId, SimpleBooleanDelegate requirements) { return Buff(spellId, ret => StyxWoW.Me, requirements); }
private static Composite CreateArmsAoeCombat(SimpleIntDelegate aoeCount) { return new PrioritySelector( new Decorator(ret => aoeCount(ret) >= 3, new PrioritySelector( Spell.Cast( "Thunder Clap" ), Spell.Cast("Bladestorm", ret => aoeCount(ret) >= 4), Spell.Cast("Shockwave", ret => Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 10f) >= 3), Spell.Cast("Dragon Roar"), Spell.Cast("Whirlwind"), Spell.Cast("Mortal Strike"), Spell.Cast("Colossus Smash", ret => !StyxWoW.Me.CurrentTarget.HasMyAura("Colossus Smash")), Spell.Cast("Overpower") ) ), Spell.BuffSelf("Sweeping Strikes", ret => aoeCount(ret) == 2) ); }
public static Composite CreateMonkCloseDistanceBehavior(SimpleIntDelegate minDist = null, UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate canReq = null) { /* * new Decorator( * unit => (unit as WoWUnit).SpellDistance() > 10 * && Me.IsSafelyFacing(unit as WoWUnit, 5f), * Spell.Cast("Roll") * ) */ bool hasFSKGlpyh = TalentManager.HasGlyph("Flying Serpent Kick"); bool hasTigersLust = HasTalent(MonkTalents.TigersLust); if (minDist == null) { minDist = min => Me.Combat ? 10 : 12; } if (onUnit == null) { onUnit = on => Me.CurrentTarget; } if (canReq == null) { canReq = req => true; } return(new Throttle(1, new PrioritySelector( ctx => onUnit(ctx), new Decorator( req => { if (!MovementManager.IsClassMovementAllowed) { return false; } if (!canReq(req)) { return false; } float dist = Me.SpellDistance(req as WoWUnit); if (dist <= minDist(req)) { return false; } if ((req as WoWUnit).IsAboveTheGround()) { return false; } float facingPrecision = (req as WoWUnit).SpellDistance() < 15 ? 6f : 4f; if (!Me.IsSafelyFacing(req as WoWUnit, facingPrecision)) { return false; } bool isObstructed = Movement.MeshTraceline(Me.Location, (req as WoWUnit).Location); if (isObstructed == true) { return false; } return true; }, new PrioritySelector( Spell.BuffSelf( "Tiger's Lust", req => hasTigersLust && !Me.HasAuraWithEffect(WoWApplyAuraType.ModIncreaseSpeed) && Me.HasAuraWithEffect(WoWApplyAuraType.ModRoot, WoWApplyAuraType.ModDecreaseSpeed) ), new Sequence( Spell.Cast( "Flying Serpent Kick", on => (WoWUnit)on, ret => TalentManager.CurrentSpec == WoWSpec.MonkWindwalker && !Me.Auras.ContainsKey("Flying Serpent Kick") && ((ret as WoWUnit).SpellDistance() > 25 || Spell.IsSpellOnCooldown("Roll")) ), /* wait until in progress */ new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(750), until => Me.Auras.ContainsKey("Flying Serpent Kick"), new Action(r => Logger.WriteDebug("CloseDistance: Flying Serpent Kick detected towards {0} @ {1:F1} yds in progress", (r as WoWUnit).SafeName(), (r as WoWUnit).SpellDistance())) ), new Action(r => { Logger.WriteDebug("CloseDistance: failure - did not see Flying Serpent Kick aura appear - lag?"); return RunStatus.Failure; }) ), /* cancel when in range */ new Wait( TimeSpan.FromMilliseconds(2500), until => { if (!Me.Auras.ContainsKey("Flying Serpent Kick")) { Logger.WriteDebug("CloseDistance: Flying Serpent Kick completed on {0} @ {1:F1} yds and {2} behind me", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance(), (until as WoWUnit).IsBehind(Me) ? "IS" : "is NOT"); return true; } if (!hasFSKGlpyh) { SpellFindResults sfr; SpellManager.FindSpell("Flying Serpent Kick", out sfr); if (((until as WoWUnit).IsWithinMeleeRange || (until as WoWUnit).SpellDistance() < 8f)) { Logger.Write(LogColor.Cancel, "/cancel Flying Serpent Kick in melee range of {0} @ {1:F1} yds", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance()); //Spell.CastPrimative("Flying Serprent Kick"); // Lua.DoString("CastSpellByID(" + sfr.Original.Id + ")"); return true; } else if ((until as WoWUnit).IsBehind(Me)) { Logger.Write(LogColor.Cancel, "/cancel Flying Serpent Kick flew past {0} @ {1:F1} yds", (until as WoWUnit).SafeName(), (until as WoWUnit).SpellDistance()); //Spell.CastPrimative("Flying Serprent Kick"); //Lua.DoString("CastSpellByID(" + sfr.Original.Id + ")"); return true; } } return false; }, new PrioritySelector( new Decorator( req => !Me.Auras.ContainsKey("Flying Serpent Kick"), new ActionAlwaysSucceed() ), new Sequence( new Action(r => { if (hasFSKGlpyh) { Logger.WriteDebug("CloseDistance: FSK is glyphed, should not be here - notify developer!"); } else { Logger.WriteDebug("CloseDistance: casting Flying Serpent Kick to cancel"); Spell.CastPrimative(101545); } }), /* wait until cancel takes effect */ new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(450), until => !Me.Auras.ContainsKey("Flying Serpent Kick"), new Action(r => Logger.WriteDebug("CloseDistance: Flying Serpent Kick complete, landed {0:F1} yds from {1}", (r as WoWUnit).SpellDistance(), (r as WoWUnit).SafeName())) ), new Action(r => { Logger.WriteDebug("CloseDistance: error - Flying Serpent Kick was not removed - lag?"); }) ) ) ) ) ), Spell.BuffSelf("Tiger's Lust", req => hasTigersLust), new Sequence( Spell.Cast("Roll", on => (WoWUnit)on, req => !MonkSettings.DisableRoll && MovementManager.IsClassMovementAllowed), new PrioritySelector( new Wait( TimeSpan.FromMilliseconds(500), until => Me.Auras.ContainsKey("Roll"), new Action(r => Logger.WriteDebug("CloseDistance: Roll in progress")) ), new Action(r => { Logger.WriteDebug("CloseDistance: failure - did not detect Roll in progress aura- lag?"); return RunStatus.Failure; }) ), new Wait( TimeSpan.FromMilliseconds(950), until => !Me.Auras.ContainsKey("Roll"), new Action(r => Logger.WriteDebug("CloseDistance: Roll has ended")) ) ) ) ) ) )); }