This is great but it doesn't interrupt for me. Does not use pummel at all.
EDIT: lol, turns out there's a comment indicator before the pummel line. just remove that and it works fine.
Here's my copy which I've optimised for PvP. Doesn't use any cooldowns and shouldn't change your stance.
EDIT: lol, turns out there's a comment indicator before the pummel line. just remove that and it works fine.
Here's my copy which I've optimised for PvP. Doesn't use any cooldowns and shouldn't change your stance.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Styx;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;
namespace Armed
{
public class Routine : CombatRoutine
{
/// <summary>
/// The name of this CombatRoutine
/// </summary>
/// <value>
/// The name.
/// </value>
public override string Name { get { return "Armed"; } }
/// <summary>
/// The <see cref="T:Styx.WoWClass"/> to be used with this routine
/// </summary>
/// <value>
/// The class.
/// </value>
public override WoWClass Class { get { return WoWClass.Warrior; } }
private Composite _combat, _buffs;
public override Composite CombatBehavior { get { return _combat; } }
public override Composite PreCombatBuffBehavior { get { return _buffs; } }
public override Composite CombatBuffBehavior { get { return _buffs; } }
public override void Initialize()
{
_combat = CreateCombat();
_buffs = CreateBuffs();
}
Composite CreateBuffs()
{
return Cast("Battle Shout", ret => !StyxWoW.Me.HasAura("Battle Shout"));
}
Composite CreateCombat()
{
return new PrioritySelector(
// Interrupt please.
Cast("Pummel", ret => StyxWoW.Me.CurrentTarget.IsCasting && StyxWoW.Me.CurrentTarget.CanInterruptCurrentSpellCast),
Cast("Impending Victory", ret => StyxWoW.Me.HealthPercent <= 90 && StyxWoW.Me.HasAura("Victorious")),
// Kee SS up if we've got more than 2 mobs to get to killing.
new Decorator(ret => UnfriendlyUnits.Count() >= 2,
CreateAoe()),
new Decorator(ret => StyxWoW.Me.CurrentTarget.HealthPercent <= 20,
CreateExecuteRange()),
new Decorator(ret => StyxWoW.Me.CurrentTarget.HealthPercent > 20,
new PrioritySelector(
Cast("Hamstring", ret =>
StyxWoW.Me.CurrentTarget.IsPlayer && StyxWoW.Me.CurrentTarget.IsWithinMeleeRange &&
!StyxWoW.Me.CurrentTarget.HasAura("Hamstring") &&
!StyxWoW.Me.CurrentTarget.HasAura("Piercing Howl") &&
!StyxWoW.Me.CurrentTarget.HasAura("Crippling Poison") &&
!StyxWoW.Me.CurrentTarget.HasAura("Hand of Freedom") &&
!StyxWoW.Me.CurrentTarget.HasAura("Sluggish") &&
!StyxWoW.Me.CurrentTarget.HasAura("Infected Wounds")
),
// Only drop DC if we need to use HS for TFB. This lets us avoid breaking HS as a rage dump, when we don't want it to be one.
Cast("Deadly Calm", ret => NeedTasteForBloodDump),
Cast("Heroic Strike", ret => NeedHeroicStrikeDump),
Cast("Bloodbath", ret => StyxWoW.Me.CurrentTarget.IsBoss),
Cast("Colossus Smash", ret => !StyxWoW.Me.CurrentTarget.HasAura("Colossus Smash") && StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Execute", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Mortal Strike", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
//HeroicLeap(),
Cast("Storm Bolt"),
Cast("Dragon Roar"),
Cast("Overpower"),
// Rage dump!
Cast("Slam", ret => (StyxWoW.Me.RagePercent >= 60 && StyxWoW.Me.CurrentTarget.IsWithinMeleeRange || StyxWoW.Me.CurrentTarget.HasAura("Colossus Smash")) && StyxWoW.Me.CurrentTarget.HealthPercent > 20 && StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Battle Shout", ret => StyxWoW.Me.RagePercent < 30),
// Don't use this in execute range, unless we need the heal. Thanks!
Cast("Impending Victory", ret => StyxWoW.Me.CurrentTarget.HealthPercent > 20 || StyxWoW.Me.HealthPercent < 50))
)
);
}
Composite CreateAoe()
{
return new PrioritySelector(
Cast("Dragon Roar"),
Cast("Shockwave"),
Cast("Bladestorm", ret=>UnfriendlyUnits.Count() >= 4),
Cast("Sweeping Strikes"),
Cast("Thunder Clap")
);
}
Composite CreateExecuteRange()
{
return new PrioritySelector(
// Pop all our CDs. Get ready to truck the mob.
Cast("Bloodbath", ret => StyxWoW.Me.CurrentTarget.IsBoss),
new Action(ret => { UseTrinkets(); return RunStatus.Failure; }),
Cast("Colossus Smash", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Execute", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Mortal Strike", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Overpower", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Storm Bolt"),
Cast("Dragon Roar", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Slam", ret => StyxWoW.Me.CurrentTarget.IsWithinMeleeRange),
Cast("Battle Shout")
);
}
Composite HeroicLeap()
{
return new Decorator(ret=> StyxWoW.Me.CurrentTarget.HasAura("Colossus Smash") && SpellManager.CanCast("Heroic Leap"),
new Action(ret=>
{
var tpos = StyxWoW.Me.CurrentTarget.Location;
var trot = StyxWoW.Me.CurrentTarget.Rotation;
var leapRight = WoWMathHelper.CalculatePointAtSide(tpos, trot, 5, true);
var leapLeft = WoWMathHelper.CalculatePointAtSide(tpos, trot, 5, true);
var myPos = StyxWoW.Me.Location;
var leftDist = leapLeft.Distance(myPos);
var rightDist = leapRight.Distance(myPos);
var leapPos = WoWMathHelper.CalculatePointBehind(tpos, trot, 8);
if (leftDist > rightDist && leftDist <= 40 && leftDist >= 8)
leapPos = leapLeft;
else if (rightDist > leftDist && rightDist <= 40 && rightDist >= 8)
leapPos = leapLeft;
SpellManager.Cast("Heroic Leap");
SpellManager.ClickRemoteLocation(leapPos);
StyxWoW.Me.CurrentTarget.Face();
}));
}
void UseTrinkets()
{
var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;
var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;
if(firstTrinket != null && CanUseEquippedItem(firstTrinket))
firstTrinket.Use();
if(secondTrinket != null && CanUseEquippedItem(secondTrinket))
secondTrinket.Use();
}
private static bool CanUseEquippedItem(WoWItem item)
{
// Check for engineering tinkers!
string itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0);
if (string.IsNullOrEmpty(itemSpell))
return false;
return item.Usable && item.Cooldown <= 0;
}
IEnumerable<WoWUnit> UnfriendlyUnits
{
get { return ObjectManager.GetObjectsOfType<WoWUnit>(true, false).Where(u => !u.IsDead && u.CanSelect && u.Attackable && !u.IsFriendly && u.IsWithinMeleeRange); }
}
bool NeedTasteForBloodDump
{
get
{
var tfb = StyxWoW.Me.GetAuraByName("Taste for Blood");
if (tfb != null)
{
// If we have more than 1 stacks, pop HS
if (tfb.StackCount >= 1)
return true;
// If it's about to drop, and we have at least 2 stacks, then pop HS.
// If we have 1 stack, then a slam is better used here.
if (tfb.TimeLeft.TotalSeconds < 1 && tfb.StackCount >= 1)
return true;
}
return false;
}
}
bool NeedHeroicStrikeDump
{
get
{
// Flat out, drop HS if we need to.
if (StyxWoW.Me.RagePercent >= 90)
return true;
return NeedTasteForBloodDump;
}
}
private delegate T Selection<out T>(object context);
Composite Cast(string spell, Selection<bool> reqs = null)
{
return
new Decorator(
ret => ((reqs != null && reqs(ret)) || (reqs == null)) && SpellManager.CanCast(spell),
new Action(ret => SpellManager.Cast(spell)));
}
public static TimeSpan GetSpellCooldown(string spell)
{
SpellFindResults results;
if (SpellManager.FindSpell(spell, out results))
{
if (results.Override != null)
return results.Override.CooldownTimeLeft;
return results.Original.CooldownTimeLeft;
}
return TimeSpan.MaxValue;
}
}
}
Last edited: