Untitled diff

Created Diff never expires
50 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
573 lines
49 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
563 lines
//In trunk
//Modified
using System;
using System;
using System.Linq;
using System.Linq;
using Trinity.Config.Combat;
using Trinity.Config.Combat;
using Trinity.Reference;
using Trinity.Reference;
using Trinity.Technicals;
using Trinity.Technicals;
using Zeta.Bot;
using Zeta.Bot;
using Zeta.Common;
using Zeta.Common;
using Zeta.Game;
using Zeta.Game;
using Zeta.Game.Internals.Actors;
using Zeta.Game.Internals.Actors;
using Zeta.Game.Internals.SNO;
using Zeta.Game.Internals.SNO;
using Logger = Trinity.Technicals.Logger;
using Logger = Trinity.Technicals.Logger;


namespace Trinity.Combat.Abilities
namespace Trinity.Combat.Abilities
{
{
class BarbarianCombat : CombatBase
class BarbarianCombat : CombatBase
{
{
private static bool _allowSprintOoc = true;
private static bool _allowSprintOoc = true;
private const float MaxFuriousChargeDistance = 300f;
private const float MaxFuriousChargeDistance = 70f;


private static TrinityPower QueuedPower { get; set; }
private static TrinityPower QueuedPower { get; set; }


public static TrinityPower GetPower()
public static TrinityPower GetPower()
{
{
if (UseDestructiblePower)
if (UseDestructiblePower)
return DestroyObjectPower;
return DestroyObjectPower;


if (UseOOCBuff)
if (UseOOCBuff)
{
{
// Call of The Ancients
// Call of The Ancients
if (CanUseCallOfTheAncients && Sets.ImmortalKingsCall.IsFullyEquipped)
if (CanUseCallOfTheAncients && Sets.ImmortalKingsCall.IsFullyEquipped)
return PowerCallOfTheAncients;
return PowerCallOfTheAncients;


// Sprint OOC
// Sprint OOC
if (CanUseSprintOOC)
if (CanUseSprintOOC)
return PowerSprint;
return PowerSprint;
}
}
else
else
{
{
if (QueuedPower != null && !Player.IsIncapacitated && PowerManager.CanCast(QueuedPower.SNOPower) && !Player.IsCastingOrLoading)
if (QueuedPower != null && !Player.IsIncapacitated && PowerManager.CanCast(QueuedPower.SNOPower) && !Player.IsCastingOrLoading)
{
{
Logger.LogVerbose(LogCategory.Behavior, "Casting Queued Power {0}", QueuedPower);
Logger.LogVerbose(LogCategory.Behavior, "Casting Queued Power {0}", QueuedPower);
var next = QueuedPower;
var next = QueuedPower;
QueuedPower.MaxFailedCastReTryAttempts = 5;
QueuedPower.MaxFailedCastReTryAttempts = 5;
QueuedPower.WaitBeforeUseDelay = 750;
QueuedPower.WaitBeforeUseDelay = 750;
QueuedPower = null;
QueuedPower = null;
return next;
return next;
}
}
}
}


// Ignore Pain when near Frozen
// Ignore Pain when near Frozen
if ((ZetaDia.Me.IsFrozen || ZetaDia.Me.IsRooted || Trinity.ObjectCache.Any(o => o.AvoidanceType == AvoidanceType.IceBall)) && CanCastIgnorePain)
if ((ZetaDia.Me.IsFrozen || ZetaDia.Me.IsRooted || Trinity.ObjectCache.Any(o => o.AvoidanceType == AvoidanceType.IceBall)) && CanCastIgnorePain)
{
{
Logger.Log("Used Ignore Pain to prevent Frozen");
Logger.Log("Used Ignore Pain to prevent Frozen");
return PowerIgnorePain;
return PowerIgnorePain;
}
}


if (!UseOOCBuff)
if (!UseOOCBuff)
{
{
// Refresh Frenzy
// Refresh Frenzy
if (CanCast(SNOPower.Barbarian_Frenzy) && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) > 3000 && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) < 4000)
if (CanCast(SNOPower.Barbarian_Frenzy) && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) > 3000 && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) < 4000)
return PowerFrenzy;
return PowerFrenzy;


// Refresh Bash - Punish
// Refresh Bash - Punish
if (CanCast(SNOPower.Barbarian_Bash) && TimeSincePowerUse(SNOPower.Barbarian_Bash) > 4000 && TimeSincePowerUse(SNOPower.Barbarian_Bash) < 5000)
if (CanCast(SNOPower.Barbarian_Bash) && TimeSincePowerUse(SNOPower.Barbarian_Bash) > 4000 && TimeSincePowerUse(SNOPower.Barbarian_Bash) < 5000)
return PowerBash;
return PowerBash;
}
}


// Ignore Pain when low on health
// Ignore Pain when low on health
if (CanCastIgnorePain)
if (CanCastIgnorePain)
return PowerIgnorePain;
return PowerIgnorePain;


// WOTB
// WOTB
if (CanUseWrathOfTheBerserker)
if (CanUseWrathOfTheBerserker)
return PowerWrathOfTheBerserker;
return PowerWrathOfTheBerserker;


// Call of the Ancients
// Call of the Ancients
if (CanUseCallOfTheAncients)
if (CanUseCallOfTheAncients)
return PowerCallOfTheAncients;
return PowerCallOfTheAncients;


// Leap with Earth Set.
// Leap with Earth Set.
if (CanUseLeap && Sets.MightOfTheEarth.IsThirdBonusActive)
if (CanUseLeap && Sets.MightOfTheEarth.IsThirdBonusActive)
return PowerLeap;
return PowerLeap;


// Earthquake
// Earthquake
if (CanUseEarthquake)
if (CanUseEarthquake)
return PowerEarthquake;
return PowerEarthquake;


// Avalanche
// Avalanche
if (CanUseAvalanche)
if (CanUseAvalanche)
return PowerAvalanche;
return PowerAvalanche;


// War Cry
// War Cry
if (CanUseWarCry)
if (CanUseWarCry)
return PowerWarCry;
return PowerWarCry;


// Battle Rage
// Battle Rage
if (CanUseBattleRage)
if (CanUseBattleRage)
return PowerBattleRage;
return PowerBattleRage;


// Rend
// Rend
if (CanUseRend)
if (CanUseRend)
return PowerRend;
return PowerRend;


// Overpower
// Overpower
if (CanUseOverPower)
if (CanUseOverPower)
return PowerOverpower;
return PowerOverpower;


// Threatening Shout
// Threatening Shout
if (CanUseThreatingShout)
if (CanUseThreatingShout)
return PowerThreateningShout;
return PowerThreateningShout;


// Ground Stomp
// Ground Stomp
if (CanUseGroundStomp)
if (CanUseGroundStomp)
return PowerGroundStomp;
return PowerGroundStomp;


// Revenge
// Revenge
if (CanUseRevenge)
if (CanUseRevenge)
return PowerRevenge;
return PowerRevenge;


// Ancient Spear
// Ancient Spear
if (CanUseAncientSpear)
if (CanUseAncientSpear)
return PowerAncientSpear;
return PowerAncientSpear;


// Sprint
// Sprint
if (CanUseSprint)
if (CanUseSprint)
return PowerSprint;
return PowerSprint;


// Furious Charge
// Furious Charge
if (CanUseFuriousCharge)
if (CanUseFuriousCharge)
return PowerFuriousCharge;
return PowerFuriousCharge;


// Leap
// Leap
if (CanUseLeap)
if (CanUseLeap)
return PowerLeap;
return PowerLeap;


// Seismic Slam
// Seismic Slam
if (CanUseSeismicSlam)
if (CanUseSeismicSlam)
return PowerSeismicSlam;
return PowerSeismicSlam;


// Bash to 3 stacks (Punish)
// Bash to 3 stacks (Punish)
if (CanUseBashTo3)
if (CanUseBashTo3)
return PowerBash;
return PowerBash;


// Frenzy to 5 stacks (Maniac)
// Frenzy to 5 stacks (Maniac)
if (CanUseFrenzyTo5)
if (CanUseFrenzyTo5)
return PowerFrenzy;
return PowerFrenzy;


// HOTA Elites
// HOTA Elites
if (CanUseHammerOfTheAncientsElitesOnly)
if (CanUseHammerOfTheAncientsElitesOnly)
return PowerHammerOfTheAncients;
return PowerHammerOfTheAncients;


// Whirlwind
// Whirlwind
if (CanUseWhirlwind)
if (CanUseWhirlwind)
return PowerWhirlwind;
return PowerWhirlwind;


// Hammer of the Ancients
// Hammer of the Ancients
if (CanUseHammerOfTheAncients)
if (CanUseHammerOfTheAncients)
return PowerHammerOfTheAncients;
return PowerHammerOfTheAncients;


// Weapon Throw
// Weapon Throw
if (CanUseWeaponThrow)
if (CanUseWeaponThrow)
return PowerWeaponThrow;
return PowerWeaponThrow;


// Frenzy Fury Generator
// Frenzy Fury Generator
if (CanUseFrenzy)
if (CanUseFrenzy)
return PowerFrenzy;
return PowerFrenzy;


// Bash Fury Generator
// Bash Fury Generator
if (CanUseBash)
if (CanUseBash)
return PowerBash;
return PowerBash;


// Cleave Fury Generator
// Cleave Fury Generator
if (CanUseCleave)
if (CanUseCleave)
return PowerCleave;
return PowerCleave;


// Default Attacks
// Default Attacks
return DefaultPower;
return DefaultPower;
}
}


public static bool CanCastIgnorePain
public static bool CanCastIgnorePain
{
{
get
get
{
{
if (UseOOCBuff)
if (UseOOCBuff)
return false;
return false;


if (GetHasBuff(SNOPower.Barbarian_IgnorePain))
if (GetHasBuff(SNOPower.Barbarian_IgnorePain))
return false;
return false;


if (!CanCast(SNOPower.Barbarian_IgnorePain))
if (!CanCast(SNOPower.Barbarian_IgnorePain))
return false;
return false;


if (Settings.Combat.Barbarian.IgnorePainOffCooldown)
if (Settings.Combat.Barbarian.IgnorePainOffCooldown)
return true;
return true;


if (Player.CurrentHealthPct <= Settings.Combat.Barbarian.IgnorePainMinHealthPct)
if (Player.CurrentHealthPct <= Settings.Combat.Barbarian.IgnorePainMinHealthPct)
return true;
return true;


if (Player.IsFrozen || Player.IsRooted || Player.IsJailed || Trinity.ObjectCache.Any(o => o.AvoidanceType == AvoidanceType.IceBall))
if (Player.IsFrozen || Player.IsRooted || Player.IsJailed || Trinity.ObjectCache.Any(o => o.AvoidanceType == AvoidanceType.IceBall))
return true;
return true;


return Sets.TheLegacyOfRaekor.IsFullyEquipped && ShouldFuryDump;
return Sets.TheLegacyOfRaekor.IsFullyEquipped && ShouldFuryDump;
}
}
}
}


public static bool CanUseCallOfTheAncients
public static bool CanUseCallOfTheAncients
{
{
get
get
{
{
return !UseOOCBuff &&
return //!UseOOCBuff &&
!IsCurrentlyAvoiding &&
//!IsCurrentlyAvoiding &&
CanCast(SNOPower.Barbarian_CallOfTheAncients) &&
CanCast(SNOPower.Barbarian_CallOfTheAncients) &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
!GetHasBuff(SNOPower.Barbarian_CallOfTheAncients) &&
//!GetHasBuff(SNOPower.Barbarian_CallOfTheAncients) &&
(Sets.ImmortalKingsCall.IsFullyEquipped && Trinity.PlayerOwnedAncientCount < 3 ||
(Sets.ImmortalKingsCall.IsFullyEquipped && Trinity.PlayerOwnedAncientCount < 3);// ||
CurrentTarget.IsEliteRareUnique ||
//CurrentTarget.IsEliteRareUnique ||
TargetUtil.EliteOrTrashInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange")) ||
//TargetUtil.EliteOrTrashInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange")) ||
TargetUtil.AnyMobsInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange"), 3) ||
//TargetUtil.AnyMobsInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange"), 3) ||
TargetUtil.AnyElitesInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange")));
//TargetUtil.AnyElitesInRange(V.F("Barbarian.CallOfTheAncients.MinEliteRange")));
}
}
}
}


public static bool CanUseWrathOfTheBerserker
public static bool CanUseWrathOfTheBerserker
{
{
get
get
{
{
/* WOTB should be used when the following conditions are met:
/* WOTB should be used when the following conditions are met:
* If ignoring elites, when 3 monsters in 25 yards or 10 monsters in 50 yards are present, OR
* If ignoring elites, when 3 monsters in 25 yards or 10 monsters in 50 yards are present, OR
* If using on hard elites only, when an elite with the required affix is present, OR
* If using on hard elites only, when an elite with the required affix is present, OR
* If normal mode, when any elite is within 20 yards, OR
* If normal mode, when any elite is within 20 yards, OR
* If we have low health (use potion health)
* If we have low health (use potion health)
* And not on the Heart of sin
* And not on the Heart of sin
*/
*/


var anyTime = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.WhenReady && !Player.IsInTown;
var anyTime = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.WhenReady && !Player.IsInTown;
var whenInCombat = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.WhenInCombat &&
var whenInCombat = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.WhenInCombat &&
TargetUtil.AnyMobsInRange(50) && !UseOOCBuff;
TargetUtil.AnyMobsInRange(50) && !UseOOCBuff;
var hasBuff = GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker);
var hasBuff = GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker);
var hasInfiniteCasting = GetHasBuff(SNOPower.Pages_Buff_Infinite_Casting);
var hasInfiniteCasting = GetHasBuff(SNOPower.Pages_Buff_Infinite_Casting);


var emergencyHealth = Player.CurrentHealthPct <= V.F("Barbarian.WOTB.EmergencyHealth") && Settings.Combat.Barbarian.WOTBEmergencyHealth;
var emergencyHealth = Player.CurrentHealthPct <= V.F("Barbarian.WOTB.EmergencyHealth") && Settings.Combat.Barbarian.WOTBEmergencyHealth;


var result =
var result =
//Player.PrimaryResource >= V.I("Barbarian.WOTB.MinFury") && // WOTB is "free" !
//Player.PrimaryResource >= V.I("Barbarian.WOTB.MinFury") && // WOTB is "free" !
// Don't still have the buff
// Don't still have the buff
!hasBuff && CanCast(SNOPower.Barbarian_WrathOfTheBerserker) &&
!hasBuff && CanCast(SNOPower.Barbarian_WrathOfTheBerserker) &&
(WOTBGoblins || WOTBIgnoreElites || WOTBElitesPresent || emergencyHealth || hasInfiniteCasting ||
(WOTBGoblins || WOTBIgnoreElites || WOTBElitesPresent || emergencyHealth || hasInfiniteCasting ||
anyTime || whenInCombat);
anyTime || whenInCombat);


return result;
return result;
}
}
}
}


/// <summary>
/// <summary>
/// If using WOTB on all elites, or if we should only use on "hard" affixes
/// If using WOTB on all elites, or if we should only use on "hard" affixes
/// </summary>
/// </summary>
public static bool WOTBElitesPresent
public static bool WOTBElitesPresent
{
{
get
get
{
{
//bool hardEliteOverride = Trinity.ObjectCache.Any(o => DataDictionary.ForceUseWOTBIds.Contains(o.ActorSNO)) ||
//bool hardEliteOverride = Trinity.ObjectCache.Any(o => DataDictionary.ForceUseWOTBIds.Contains(o.ActorSnoId)) ||
// TargetUtil.AnyElitesInRange(V.F("Barbarian.WOTB.HardEliteRangeOverride"), V.I("Barbarian.WOTB.HardEliteCountOverride"));
// TargetUtil.AnyElitesInRange(V.F("Barbarian.WOTB.HardEliteRangeOverride"), V.I("Barbarian.WOTB.HardEliteCountOverride"));


//// WotB only used on Arcane, Frozen, Jailer, Molten, Electrified+Reflect Damage elites, or bosses and ubers, or when more than 4 elites are present
//// WotB only used on Arcane, Frozen, Jailer, Molten, Electrified+Reflect Damage elites, or bosses and ubers, or when more than 4 elites are present
//bool wotbHardElitesPresent = HardElitesPresent || hardEliteOverride;
//bool wotbHardElitesPresent = HardElitesPresent || hardEliteOverride;


bool hardElitesOnly = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.HardElitesOnly;
bool hardElitesOnly = Settings.Combat.Barbarian.WOTBMode == BarbarianWOTBMode.HardElitesOnly;


bool elitesPresent = TargetUtil.AnyElitesInRange(V.F("Barbarian.WOTB.MinRange"), V.I("Barbarian.WOTB.MinCount"));
bool elitesPresent = TargetUtil.AnyElitesInRange(V.F("Barbarian.WOTB.MinRange"), V.I("Barbarian.WOTB.MinCount"));


return ((!hardElitesOnly && elitesPresent) || (hardElitesOnly && HardElitesPresent));
return ((!hardElitesOnly && elitesPresent) || (hardElitesOnly && HardElitesPresent));
}
}
}
}


/// <summary>
/// <summary>
/// Make sure we are allowed to use wrath on goblins, else make sure this isn't a goblin
/// Make sure we are allowed to use wrath on goblins, else make sure this isn't a goblin
/// </summary>
/// </summary>
public static bool WOTBGoblins
public static bool WOTBGoblins
{
{
get
get
{
{
if (CurrentTarget == null)
if (CurrentTarget == null)
return false;
return false;
return CurrentTarget.IsTreasureGoblin && Settings.Combat.Barbarian.UseWOTBGoblin;
return CurrentTarget.IsTreasureGoblin && Settings.Combat.Barbarian.UseWOTBGoblin;
}
}
}
}


/// <summary>
/// <summary>
/// If ignoring elites completely, trigger on 3 trash within 25 yards, or 10 trash in 50 yards
/// If ignoring elites completely, trigger on 3 trash within 25 yards, or 10 trash in 50 yards
/// </summary>
/// </summary>
public static bool WOTBIgnoreElites
public static bool WOTBIgnoreElites
{
{
get
get
{
{
return
return
IgnoringElites &&
IgnoringElites &&
(TargetUtil.AnyMobsInRange(V.F("Barbarian.WOTB.RangeNear"), V.I("Barbarian.WOTB.CountNear")) ||
(TargetUtil.AnyMobsInRange(V.F("Barbarian.WOTB.RangeNear"), V.I("Barbarian.WOTB.CountNear")) ||
TargetUtil.AnyMobsInRange(V.F("Barbarian.WOTB.RangeFar"), V.I("Barbarian.WOTB.CountFar")) ||
TargetUtil.AnyMobsInRange(V.F("Barbarian.WOTB.RangeFar"), V.I("Barbarian.WOTB.CountFar")) ||
TargetUtil.AnyMobsInRange(Settings.Combat.Misc.TrashPackClusterRadius, Settings.Combat.Misc.TrashPackSize));
TargetUtil.AnyMobsInRange(Settings.Combat.Misc.TrashPackClusterRadius, Settings.Combat.Misc.TrashPackSize));
}
}
}
}


public static bool CanUseEarthquake
public static bool CanUseEarthquake
{
{
get
get
{
{
double minFury = 50f;
double minFury = 50f;
bool hasCaveIn = CacheData.Hotbar.ActiveSkills.Any(p => p.Power == SNOPower.Barbarian_Earthquake && p.RuneIndex == 4);
bool hasCaveIn = CacheData.Hotbar.ActiveSkills.Any(p => p.Power == SNOPower.Barbarian_Earthquake && p.RuneIndex == 4);
float range = hasCaveIn ? 24f : 14f;
float range = hasCaveIn ? 24f : 14f;


return
return
!UseOOCBuff &&
!UseOOCBuff &&
!IsCurrentlyAvoiding &&
!IsCurrentlyAvoiding &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
CanCast(SNOPower.Barbarian_Earthquake) &&
CanCast(SNOPower.Barbarian_Earthquake) &&
Player.PrimaryResource >= minFury &&
Player.PrimaryResource >= minFury &&
(TargetUtil.IsEliteTargetInRange(range) || TargetUtil.AnyMobsInRange(range, 10));
(TargetUtil.IsEliteTargetInRange(range) || TargetUtil.AnyMobsInRange(range, 10));


}
}
}
}


public static bool CanUseBattleRage
public static bool CanUseBattleRage
{
{
get
get
{
{
var shouldRefreshTaeguk = GetHasBuff(SNOPower.ItemPassive_Unique_Gem_015_x1) && !Hotbar.Contains(SNOPower.Barbarian_Whirlwind) &&
var shouldRefreshTaeguk = Gems.Taeguk.IsEquipped /*GetHasBuff(SNOPower.ItemPassive_Unique_Gem_015_x1)*/ && !Hotbar.Contains(SNOPower.Barbarian_Whirlwind) &&
Skills.Barbarian.BattleRage.TimeSinceUse >= 2300 && Skills.Barbarian.BattleRage.TimeSinceUse <= 3000;
/*Skills.Barbarian.BattleRage.TimeSinceUse >= 1500 && Skills.Barbarian.BattleRage.TimeSinceUse <= 3000 &&*/ Skills.Barbarian.HammerOfTheAncients.TimeSinceUse >= 1000;


return !Player.IsIncapacitated && CanCast(SNOPower.Barbarian_BattleRage, CanCastFlags.NoTimer) &&
return !Player.IsIncapacitated && CanCast(SNOPower.Barbarian_BattleRage, CanCastFlags.NoTimer) &&
(!GetHasBuff(SNOPower.Barbarian_BattleRage) || ShouldFuryDump || shouldRefreshTaeguk) &&
(!GetHasBuff(SNOPower.Barbarian_BattleRage) /*|| Player.CurrentHealthPct < 0.8f*/ || shouldRefreshTaeguk) && //ShouldFuryDump || ) &&
Player.PrimaryResource >= V.F("Barbarian.BattleRage.MinFury");
Player.PrimaryResource >= 40;
}
}
}
}


public static bool CanUseSprintOOC
public static bool CanUseSprintOOC
{
{
get
get
{
{
return
return
(Settings.Combat.Barbarian.SprintMode != BarbarianSprintMode.CombatOnly) &&
(Settings.Combat.Barbarian.SprintMode != BarbarianSprintMode.CombatOnly) &&
AllowSprintOOC &&
AllowSprintOOC &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
CanCast(SNOPower.Barbarian_Sprint) &&
CanCast(SNOPower.Barbarian_Sprint) &&
(Settings.Combat.Misc.AllowOOCMovement || GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) &&
(Settings.Combat.Misc.AllowOOCMovement || GetHasBuff(SNOPower.Barbarian_WrathOfTheBerserker)) &&
!GetHasBuff(SNOPower.Barbarian_Sprint) &&
!GetHasBuff(SNOPower.Barbarian_Sprint) &&
Player.PrimaryResource >= V.F("Barbarian.Sprint.MinFury");
Player.PrimaryResource >= V.F("Barbarian.Sprint.MinFury");
}
}
}
}
public static bool CanUseWarCry
public static bool CanUseWarCry
{
{
get
get
{
{
return
return
CanCast(SNOPower.X1_Barbarian_WarCry_v2, CanCastFlags.NoTimer) && !Player.IsIncapacitated &&
CanCast(SNOPower.X1_Barbarian_WarCry_v2, CanCastFlags.NoTimer) && !Player.IsIncapacitated &&
(Player.PrimaryResource <= V.F("Barbarian.WarCry.MaxFury") ||
(Player.PrimaryResource <= V.F("Barbarian.WarCry.MaxFury") ||
Skills.Barbarian.WarCry.TimeSinceUse >= Settings.Combat.Barbarian.WarCryWaitDelay) &&
Skills.Barbarian.WarCry.TimeSinceUse >= Settings.Combat.Barbarian.WarCryWaitDelay) &&
(!Legendary.BladeoftheTribes.IsEquipped || TargetUtil.AnyMobsInRange(20f));
(!Legendary.BladeoftheTribes.IsEquipped || TargetUtil.AnyMobsInRange(20f));
}
}
}
}
public static bool CanUseThreatingShout
public static bool CanUseThreatingShout
{
{
get
get
{
{
var range = V.F("Barbarian.ThreatShout.Range");
var range = V.F("Barbarian.ThreatShout.Range");


bool inCombat = !UseOOCBuff &&
bool inCombat = !UseOOCBuff &&
CanCast(SNOPower.Barbarian_ThreateningShout) &&
CanCast(SNOPower.Barbarian_ThreateningShout) &&
!Player.IsIncapacitated && Skills.Barbarian.ThreateningShout.TimeSinceUse > Settings.Combat.Barbarian.ThreateningShoutWaitDelay &&
!Player.IsIncapacitated && Skills.Barbarian.ThreateningShout.TimeSinceUse > Settings.Combat.Barbarian.ThreateningShoutWaitDelay &&
((TargetUtil.AnyMobsInRange(range, Settings.Combat.Barbarian.MinThreatShoutMobCount, false)) || TargetUtil.IsEliteTargetInRange(range) ||
((TargetUtil.AnyMobsInRange(range, Settings.Combat.Barbarian.MinThreatShoutMobCount, false)) || TargetUtil.IsEliteTargetInRange(range) ||


(Hotbar.Contains(SNOPower.Barbarian_Whirlwind) && Player.PrimaryResource <= V.I("Barbarian.Whirlwind.MinFury")) ||
(Hotbar.Contains(SNOPower.Barbarian_Whirlwind) && Player.PrimaryResource <= V.I("Barbarian.Whirlwind.MinFury")) ||
(IsWaitingForSpecial && Player.PrimaryResource <= MinEnergyReserve)
(IsWaitingForSpecial && Player.PrimaryResource <= MinEnergyReserve)
);
);


bool outOfCombat = UseOOCBuff &&
bool outOfCombat = UseOOCBuff &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
Settings.Combat.Barbarian.ThreatShoutOOC && CanCast(SNOPower.Barbarian_ThreateningShout) &&
Settings.Combat.Barbarian.ThreatShoutOOC && CanCast(SNOPower.Barbarian_ThreateningShout) &&
Player.PrimaryResource < V.D("Barbarian.ThreatShout.OOCMaxFury");
Player.PrimaryResource < V.D("Barbarian.ThreatShout.OOCMaxFury");


return inCombat || outOfCombat;
return inCombat || outOfCombat;


}
}
}
}
public static bool CanUseGroundStomp
public static bool CanUseGroundStomp
{
{
get
get
{
{
return
return
!UseOOCBuff &&
!UseOOCBuff &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
CanCast(SNOPower.Barbarian_GroundStomp) &&
CanCast(SNOPower.Barbarian_GroundStomp) &&
(
(
TargetUtil.AnyElitesInRange(V.F("Barbarian.GroundStomp.EliteRange"), V.I("Barbarian.GroundStomp.EliteCount")) ||
TargetUtil.AnyElitesInRange(V.F("Barbarian.GroundStomp.EliteRange"), V.I("Barbarian.GroundStomp.EliteCount")) ||
TargetUtil.AnyMobsInRange(V.F("Barbarian.GroundStomp.TrashRange"), V.I("Barbarian.GroundStomp.TrashCount")) ||
TargetUtil.AnyMobsInRange(V.F("Barbarian.GroundStomp.TrashRange"), V.I("Barbarian.GroundStomp.TrashCount")) ||
(Player.CurrentHealthPct <= V.F("Barbarian.GroundStomp.UseBelowHealthPct") && TargetUtil.AnyMobsInRange(V.F("Barbarian.GroundStomp.TrashRange")))
(Player.CurrentHealthPct <= V.F("Barbarian.GroundStomp.UseBelowHealthPct") && TargetUtil.AnyMobsInRange(V.F("Barbarian.GroundStomp.TrashRange")))
);
);
}
}
}
}
public static bool CanUseRevenge
public static bool CanUseRevenge
{
{
get
get
{
{
return
return
!UseOOCBuff &&
!UseOOCBuff &&
CanCast(SNOPower.Barbarian_Revenge) &&
CanCast(SNOPower.Barbarian_Revenge) &&
!Player.IsIncapacitated &&
!Player.IsIncapacitated &&
// Don't use revenge on goblins, too slow!
// Don't use revenge on goblins, too slow!
(!CurrentTarget.IsTreasureGoblin || TargetUtil.AnyMobsInRange(V.F("Barbarian.Revenge.TrashRange"), V.I("Barbarian.Revenge.TrashCount")));
(!CurrentTarget.IsTreasureGoblin || TargetUtil.AnyMobsInRange(V.F("Barbarian.Revenge.TrashRange"), V.I("Barbarian.Revenge.TrashCount")));
}
}
}
}
public static bool CanUseFuriousCharge
public static bool CanUseFuriousCharge
{
{
get
get
{
{
if (UseOOCBuff)
if (UseOOCBuff)
return false;
return false;


var bestTarget = TargetUtil.GetBestPierceTarget(MaxFuriousChargeDistance);
return CanCast(SNOPower.Barbarian_FuriousCharge, CanCastFlags.NoTimer) && !IsCurrentlyAvoiding && Skills.Barbarian.FuriousCharge.Charges > 0;

var bestClusterTarget = TargetUtil.GetBestClusterUnit(15f, MaxFuriousChargeDistance, 1, false, true);
var bestTarget = TargetUtil.GetBestPierceTarget(MaxFuriousChargeDistance); ;
var unitsInFrontOfBestTarget = 0;
var unitsInFrontOfBestTarget = 0;


if (bestTarget != null)
if (bestTarget != null)
unitsInFrontOfBestTarget = bestTarget.CountUnitsInFront();
unitsInFrontOfBestTarget = bestTarget.CountUnitsInFront();


var currentEliteTargetInRange = CurrentTarget.RadiusDistance > 7f && CurrentTarget.IsBossOrEliteRareUnique && CurrentTarget.RadiusDistance <= 35f;
if (unitsInFrontOfBestTarget < 2 && bestClusterTarget != null)
var shouldRegenFury = CurrentTarget.NearbyUnitsWithinDistance(10) >= 3 && Player.PrimaryResource <= 40;
unitsInFrontOfBestTarget = bestClusterTarget.NearbyUnitsWithinDistance(15f);


if ((Sets.BastionsOfWill.IsFullyEquipped || Legendary.StrongarmBracers.IsEquipped) && !Sets.TheLegacyOfRaekor.IsFullyEquipped)
var currentEliteTargetInRange = (CurrentTarget.NearbyUnitsWithinDistance(15f) == 0 && CurrentTarget.CountUnitsInFront() == 0 && CurrentTarget.HitPointsPct <= 0.3) || CurrentTarget.IsBossOrEliteRareUnique || CurrentTarget.IsTreasureGoblin;
return CanCast(SNOPower.Barbarian_FuriousCharge, CanCastFlags.NoTimer) && !IsCurrentlyAvoiding &&
var shouldRegenFury = CurrentTarget.NearbyUnitsWithinDistance(10) >= 2 && Player.PrimaryResource <= 40;
Skills.Barbarian.FuriousCharge.Charges > 0 && (TimeSincePowerUse(SNOPower.Barbarian_FuriousCharge) > 4000 || shouldRegenFury);


return CanCast(SNOPower.Barbarian_FuriousCharge, CanCastFlags.NoTimer) && !IsCurrentlyAvoiding && Skills.Barbarian.FuriousCharge.Charges > 0 &&
//if ((Sets.BastionsOfWill.IsFullyEquipped || Legendary.StrongarmBracers.IsEquipped) && !Sets.TheLegacyOfRaekor.IsFullyEquipped)
(currentEliteTargetInRange || unitsInFrontOfBestTarget >= 3 || Sets.TheLegacyOfRaekor.IsFullyEquipped);
// return CanCast(SNOPower.Barbarian_FuriousCharge, CanCastFlags.NoTimer) && !IsCurrentlyAvoiding &&
// Skills.Barbarian.FuriousCharge.Charges > 0 && (TimeSincePowerUse(SNOPower.Barbarian_FuriousCharge) > 4000 || shouldRegenFury);

/*&&
(currentEliteTargetInRange || unitsInFrontOfBestTarget >= 2); // || Sets.TheLegacyOfRaekor.IsFullyEquipped);*/


}
}
}
}
public static bool CanUseLeap
public static bool CanUseLeap
{
{
get
get
{
{
bool leapresult = !UseOOCBuff && !Player.IsIncapacitated && CanCast(SNOPower.Barbarian_Leap);
bool leapresult = !UseOOCBuff && !Player.IsIncapacitated && CanCast(SNOPower.Barbarian_Leap);
// This will now cast whenever leap is available and an enemy is around.
// This will now cast whenever leap is available and an enemy is around.
// Disable Leap OOC option. The last line will prevent you from leaping on destructibles
// Disable Leap OOC option. The last line will prevent you from leaping on destructibles
if (Legendary.LutSocks.IsEquipped)
if (Legendary.LutSocks.IsEquipped)
{
{
return leapresult && TargetUtil.AnyMobsInRange(15f, 1);
return leapresult && TargetUtil.AnyMobsInRange(15f, 1);
}
}
return leapresult && (TargetUtil.ClusterExists(15f, 35f, V.I("Barbarian.Leap.TrashCount")) || CurrentTarget.IsBossOrEliteRareUnique);
return leapresult && (TargetUtil.ClusterExists(15f, 35f, V.I("Barbarian.Leap.TrashCount")) || CurrentTarget.IsBossOrEliteRareUnique);
}
}
}
}
public static bool CanUseRend
public static bool CanUseRend
{
{
get
get
{
{
if (UseOOCBuff || IsCurrentlyAvoiding || Player.IsIncapacitated || !CanCast(SNOPower.Barbarian_Rend))
if (UseOOCBuff || IsCurrentlyAvoiding || Player.IsIncapacitated || !CanCast(SNOPower.Barbarian_Rend))
return false;
return false;


if (!CanCast(SNOPower.Barbarian_Rend))
if (!CanCast(SNOPower.Barbarian_Rend))
return false;
return false;


bool hasReserveEnergy = (!IsWaitingForSpecial && Player.PrimaryResource >= 20) || (IsWaitingForSpecial && Player.PrimaryResource > MinEnergyReserve);
bool hasReserveEnergy = (!IsWaitingForSpecial && Player.PrimaryResource >= 20) || (IsWaitingForSpecial && Player.PrimaryResource > MinEnergyReserve);


var mobCountThreshold = Trinity.ObjectCache.Count(o => o.IsUnit && (!o.HasDebuff(SNOPower.Barbarian_Rend)) && o.RadiusDistance <= 12) >= 3 || CurrentTarget.IsEliteRareUnique;
var mobCountThreshold = Trinity.ObjectCache.Count(o => o.IsUnit && (!o.HasDebuff(SNOPower.Barbarian_Rend)) && o.RadiusDistance <= 12) >= 3 || CurrentTarget.IsEliteRareUnique;
if (!mobCountThreshold)
if (!mobCountThreshold)
return false;
return false;


// Spam with Bloodlust
// Spam with Bloodlust
if (Runes.Barbarian.BloodLust.IsActive && Player.CurrentHealthPct <= .25)
if (Runes.Barbarian.BloodLust.IsActive && Player.CurrentHealthPct <= .25)
return true;
return true;


// If lamentation is equipped, cast twice in a row and then wait
// If lamentation is equipped, cast twice in a row and then wait
if (Legendary.Lamentation.IsEquipped)
if (Legendary.Lamentation.IsEquipped)
{
{
var castsWithinTime = SpellHistory.SpellUseCountInTime(SNOPower.Barbarian_Rend, TimeSpan.FromMilliseconds(Settings.Combat.Barbarian.RendWaitDelay));
var castsWithinTime = SpellHistory.SpellUseCountInTime(SNOPower.Barbarian_Rend, TimeSpan.FromMilliseconds(Settings.Combat.Barbarian.RendWaitDelay));


Logger.LogVerbose(LogCategory.Behavior, "Casts within {0}ms = {1}", Settings.Combat.Barbarian.RendWaitDelay, castsWithinTime);
Logger.LogVerbose(LogCategory.Behavior, "Casts within {0}ms = {1}", Settings.Combat.Barbarian.RendWaitDelay, castsWithinTime);


if (hasReserveEnergy && QueuedPower != PowerRend && castsWithinTime == 0)
if (hasReserveEnergy && QueuedPower != PowerRend && castsWithinTime == 0)
{
{
Logger.LogVerbose("Double Rend!");
Logger.LogVerbose("Double Rend!");
QueuedPower = PowerRend;
QueuedPower = PowerRend;
return true;
return true;
}
}


return false;
return false;
}
}


return Skills.Barbarian.Rend.TimeSinceUse > Settings.Combat.Barbarian.RendWaitDelay && hasReserveEnergy;
return Skills.Barbarian.Rend.TimeSinceUse > Settings.Combat.Barbarian.RendWaitDelay && hasReserveEnergy;
}
}
}
}
public static bool CanUseOverPower
public static bool CanUseOverPower
{
{
get
get
{
{
if (CurrentTarget == null || Player.IsIncapacitated || Player.IsInTown || !CanCast(SNOPower.Barbarian_Overpower))
if (CurrentTarget == null || Player.IsIncapacitated || Player.IsInTown || !CanCast(SNOPower.Barbarian_Overpower))
return false;
return false;


var overPowerHasBuffEffect = (Runes.Barbarian.KillingSpree.IsActive ||
var overPowerHasBuffEffect = (Runes.Barbarian.KillingSpree.IsActive ||
Runes.Barbarian.CrushingAdvance.IsActive);
Runes.Barbarian.CrushingAdvance.IsActive);


if (!GetHasBuff(SNOPower.Barbarian_Overpower) && overPowerHasBuffEffect)
if (!GetHasBuff(SNOPower.Barbarian_Overpower) && overPowerHasBuffEffect)
return true;
return true;


return CurrentTarget.RadiusDistance <= V.F("Barbarian.OverPower.MaxRange") && !overPowerHasBuffEffect &&
return CurrentTarget.RadiusDistance <= V.F("Barbarian.OverPower.MaxRange") && !overPowerHasBuffEffect &&
TargetUtil.AnyMobsInRange(V.F("Barbarian.OverPower.MaxRange")) &&
TargetUtil.AnyMobsInRange(V.F("Barbarian.OverPower.MaxRange")) &&
(CurrentTarget.IsEliteRareUnique || CurrentTarget.IsMinion || CurrentTarget.IsBoss || TargetUtil.NumMobsInRangeOfPosition(Trinity.Player.Position, 9) >= 4);
(CurrentTarget.IsEliteRareUnique || CurrentTarget.IsMinion || CurrentTarget.IsBoss || TargetUtil.NumMobsInRangeOfPosition(Trinity.Player.Position, 9) >= 4);
}
}
}
}
public static bool CanUseSeismicSlam
public static bool CanUseSeismicSlam
{
{
get
get
{
{
return !UseOOCBuff && !IsWaitingForSpecial && CanCast(SNOPower.Barbarian_SeismicSlam) && !Player.IsIncapacitated &&
return !UseOOCBuff && !IsWaitingForSpecial && CanCast(SNOPower.Barbarian_SeismicSlam) && !Player.IsIncapacitated &&
(!Hotbar.Contains(SNOPower.Barbarian_BattleRage) || (Hotbar.Contains(SNOPower.Barbarian_BattleRage) && GetHasBuff(SNOPower.Barbarian_BattleRage))) &&
(!Hotbar.Contains(SNOPower.Barbarian_BattleRage) || (Hotbar.Contains(SNOPower.Barbarian_BattleRage) && GetHasBuff(SNOPower.Barbarian_BattleRage))) &&
Player.PrimaryResource >= V.I("Barbarian.SeismicSlam.MinFury") && CurrentTarget.Distance <= V.F("Barbarian.SeismicSlam.CurrentTargetRange") &&
Player.PrimaryResource >= V.I("Barbarian.SeismicSlam.MinFury") && CurrentTarget.Distance <= V.F("Barbarian.SeismicSlam.CurrentTargetRange") &&
(TargetUtil.AnyMobsInRange(V.F("Barbarian.SeismicSlam.TrashRange")) ||
(TargetUtil.AnyMobsInRange(V.F("Barbarian.SeismicSlam.TrashRange")) ||
TargetUtil.IsEliteTargetInRange(V.F("Barbarian.SeismicSlam.EliteRange")));
TargetUtil.IsEliteTargetInRange(V.F("Barbarian.SeismicSlam.EliteRange")));
}
}
}
}
public static bool CanUseAncientSpear
public static bool CanUseAncientSpear
{
{
get
get
{
{
return !UseOOCBuff && !IsWaitingForSpecial && !IsCurrentlyAvoiding && CanCast(SNOPower.X1_Barbarian_AncientSpear) && Player.PrimaryResource >= 25 &&
return !UseOOCBuff && !IsWaitingForSpecial && !IsCurrentlyAvoiding && CanCast(SNOPower.X1_Barbarian_AncientSpear) &&
(/*Skills.Barbarian.AncientSpear.TimeSinceUse > Settings.Combat.Barbarian.AncientSpearWaitDelay || */Player.CurrentHealthPct < 0.9f && Player.PrimaryResourcePct > 0.5 || (!CacheData.Buffs.HasBuff(SNOPower.ItemPassive_Unique_Ring_735_x1, 2)) && Player.PrimaryResource > 20);
// Only boulder toss as a rage dump if we have excess resource
// Only boulder toss as a rage dump if we have excess resource
(!Runes.Barbarian.BoulderToss.IsActive || Player.PrimaryResourcePct > 0.8) &&
//(!Runes.Barbarian.BoulderToss.IsActive || Player.PrimaryResourcePct > 0.8) &&
// Raekor - don't toss if below 5 stacks
// Raekor - don't toss if below 5 stacks
(!Sets.TheLegacyOfRaekor.IsFullyEquipped || GetBuffStacks(SNOPower.P2_ItemPassive_Unique_Ring_026) >= 5) &&
//(!Sets.TheLegacyOfRaekor.IsFullyEquipped || GetBuffStacks(SNOPower.P2_ItemPassive_Unique_Ring_026) >= 5) &&
// Check delay slider
// Check delay slider
Skills.Barbarian.AncientSpear.TimeSinceUse > Settings.Combat.Barbarian.AncientSpearWaitDelay;
}
}
}
}
public static bool CanUseSprint
public static bool CanUseSprint
{
{
get
get
{
{
return Trinity.Settings.Combat.Barbarian.SprintMode != BarbarianSprintMode.MovementOnly &&
return CanCast(SNOPower.Barbarian_Sprint, CanCastFlags.NoTimer) && !Player.IsIncapacitated &&
TimeSincePowerUse(SNOPower.Barbarian_Sprint) >= V.I("Barbarian.Sprint.MinUseDelay") &&
Player.PrimaryResource >= V.F("Barbarian.Sprint.MinFury");
/*return Trinity.Settings.Combat.Barbarian.SprintMode != BarbarianSprintMode.MovementOnly &&
!UseOOCBuff && CanCast(SNOPower.Barbarian_Sprint, CanCastFlags.NoTimer) && !Player.IsIncapacitated &&
!UseOOCBuff && CanCast(SNOPower.Barbarian_Sprint, CanCastFlags.NoTimer) && !Player.IsIncapacitated &&
(
(
// last power used was whirlwind and we don't have sprint up
// last power used was whirlwind and we don't have sprint up
(LastPowerUsed == SNOPower.Barbarian_Whirlwind && !GetHasBuff(SNOPower.Barbarian_Sprint)) ||
(LastPowerUsed == SNOPower.Barbarian_Whirlwind && !GetHasBuff(SNOPower.Barbarian_Sprint)) ||
// Fury Dump Options for sprint: use at max energy constantly
// Fury Dump Options for sprint: use at max energy constantly
ShouldFuryDump ||
ShouldFuryDump ||
// or on a timer
// or on a timer
(
(
(SNOPowerUseTimer(SNOPower.Barbarian_Sprint) && !GetHasBuff(SNOPower.Barbarian_Sprint)) &&
(SNOPowerUseTimer(SNOPower.Barbarian_Sprint) && !GetHasBuff(SNOPower.Barbarian_Sprint)) &&
// Always keep up if we are whirlwinding, if the target is a goblin, or if we are more than 16 feet away from the target
// Always keep up if we are whirlwinding, if the target is a goblin, or if we are more than 16 feet away from the target
(Hotbar.Contains(SNOPower.Barbarian_Whirlwind) || CurrentTarget.IsTreasureGoblin ||
(Hotbar.Contains(SNOPower.Barbarian_Whirlwind) || CurrentTarget.IsTreasureGoblin ||
(CurrentTarget.Distance >= V.F("Barbarian.Sprint.SingleTargetRange") && Player.PrimaryResource >= V.F("Barbarian.Sprint.SingleTargetMinFury"))
(CurrentTarget.Distance >= V.F("Barbarian.Sprint.SingleTargetRange") && Player.PrimaryResource >= V.F("Barbarian.Sprint.SingleTargetMinFury"))
)
)
)
)
) &&
) &&
// minimum time between uses
// minimum time between uses
TimeSincePowerUse(SNOPower.Barbarian_Sprint) >= V.I("Barbarian.Sprint.MinUseDelay") &&

// If they have battle-rage, make sure it's up
(!Hotbar.Contains(SNOPower.Barbarian_BattleRage) || (Hotbar.Contains(SNOPower.Barbarian_BattleRage) && GetHasBuff(SNOPower.Barbarian_BattleRage))) &&
// Check for minimum energy
Player.PrimaryResource >= V.F("Barbarian.Sprint.MinFury");
}
}
public static bool CanUseFrenzyTo5
{
get
{
return !UseOOCBuff && !IsCurrentlyAvoiding && !Player.IsRooted && Hotbar.Contains(SNOPower.Barbarian_Frenzy) &&
!TargetUtil.AnyMobsInRange(15f, 3) && GetBuffStacks(SNOPower.Barbarian_Frenzy) < 5;
}
}
public static bool CanUseBashTo3
{
get
{
return !UseOOCBuff && !IsCurrentlyAvoiding && !Player.IsRooted && Hotbar.Contains(SN