Auto-commit: changes committed

main
Emlembow 5 months ago
parent 4ff584abe2
commit 0c1d11c772
  1. 394
      BMHunter.lua

@ -1,158 +1,382 @@
-- Talents: C0PAAAAAAAAAAAAAAAAAAAAAAAMmxGDsALjGaYDAAAAAADAAAAAAgZsNjxMjZYmxMMmZMzYMjZyMMmxMzMmZMDjhZGmlBjZG2A
local Tinkr, Bastion = ...
local BeastMasteryModule = Bastion.Module:New('BeastMasteryHunter')
local BMHunterModule = Bastion.Module:New('BMHunter')
local Player = Bastion.UnitManager:Get('player')
local Target = Bastion.UnitManager:Get('target')
local Pet = Bastion.UnitManager:Get('pet')
local Focus = Bastion.UnitManager:Get('focus')
-- Initialize SpellBook
local SpellBook = Bastion.SpellBook:New()
-- Spells
local KillCommand = SpellBook:GetSpell(34026)
local HuntersMark = SpellBook:GetSpell(257284)
local BestialWrath = SpellBook:GetSpell(19574)
local BarbedShot = SpellBook:GetSpell(217200)
local DireBeast = SpellBook:GetSpell(120679)
local KillCommand = SpellBook:GetSpell(34026)
local BlackArrow = SpellBook:GetSpell(194599)
local KillShot = SpellBook:GetSpell(53351)
local CallOfTheWild = SpellBook:GetSpell(359844)
local Bloodshed = SpellBook:GetSpell(321530)
local CobraShot = SpellBook:GetSpell(193455)
local ExplosiveShot = SpellBook:GetSpell(212431)
local MultiShot = SpellBook:GetSpell(2643)
local BeastCleave = SpellBook:GetSpell(115939)
local AspectOfTheWild = SpellBook:GetSpell(193530)
local BestialWrath = SpellBook:GetSpell(19574)
local Bloodshed = SpellBook:GetSpell(321530)
local DireBeast = SpellBook:GetSpell(120679)
local Barrage = SpellBook:GetSpell(120360)
local AutoShot = SpellBook:GetSpell(75)
local CallPet = SpellBook:GetSpell(883)
local FeedPet = SpellBook:GetSpell(6991)
local CounterShot = SpellBook:GetSpell(147362)
local Intimidation = SpellBook:GetSpell(19577)
local BindingShot = SpellBook:GetSpell(109248)
local FreezingTrap = SpellBook:GetSpell(187650)
local TarTrap = SpellBook:GetSpell(187698)
local MendPet = SpellBook:GetSpell(136)
local Exhilaration = SpellBook:GetSpell(109304)
local FeignDeath = SpellBook:GetSpell(5384)
local TranquilizingShot = SpellBook:GetSpell(19801)
local SurvivalOfTheFittest = SpellBook:GetSpell(264735)
-- Buffs
-- Buffs and Debuffs
local FrenzyBuff = SpellBook:GetSpell(272790)
local BeastCleaveBuff = SpellBook:GetSpell(268877)
local BestialWrathBuff = SpellBook:GetSpell(19574)
-- Custom Units
local BestTarget = Bastion.UnitManager:CreateCustomUnit('besttarget', function()
local bestTarget = nil
local highestHealth = 0
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 40 and Player:CanSee(unit) then
local health = unit:GetHealth()
if health > highestHealth then
highestHealth = health
bestTarget = unit
end
end
end)
return bestTarget or Bastion.UnitManager:Get('target')
end)
-- Create APLs
local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('interrupttarget', function()
local target = nil
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 40 and Player:CanSee(unit)
and unit:IsCasting() and unit:IsInterruptible() then
local castPercentage = GetCastPercentage(unit)
if castPercentage >= 30 and castPercentage <= 80 then
target = unit
return true
end
end
end)
return target or BestTarget
end)
-- APLs
local DefaultAPL = Bastion.APL:New('default')
local CooldownAPL = Bastion.APL:New('cooldown')
local AoEAPL = Bastion.APL:New('aoe')
local PetAPL = Bastion.APL:New('pet')
local InterruptAPL = Bastion.APL:New('interrupt')
local DefensiveAPL = Bastion.APL:New('defensive')
local UtilityAPL = Bastion.APL:New('utility')
local BossAPL = Bastion.APL:New('boss')
-- Utility APL
UtilityAPL:AddSpell(
CounterShot:CastableIf(function(self)
return self:IsKnownAndUsable() and (Target:IsCasting() and Target:IsInterruptible() or
(Focus:Exists() and Focus:IsCasting() and Focus:IsInterruptible()))
end):SetTarget(function() return Focus:Exists() and Focus:IsCasting() and Focus or Target end)
-- Helper Functions
local function GetBarbedShotCharges()
return BarbedShot:GetCharges()
end
local function GetFrenzyStacks()
return Pet:GetAuras():FindMy(FrenzyBuff):GetCount()
end
local function IsKillerCobraTalented()
-- Implement logic to check if Killer Cobra is talented
-- This is a placeholder and should be replaced with actual talent checking logic
return true
end
local function IsVenomsBiteTalented()
-- Implement logic to check if Venom's Bite is talented
-- This is a placeholder and should be replaced with actual talent checking logic
return true
end
local function ShouldUseMultiShot()
local beastCleaveBuff = Pet:GetAuras():FindMy(BeastCleaveBuff)
return Player:GetEnemies(8) >= 2 and (not beastCleaveBuff:IsUp() or beastCleaveBuff:GetRemainingTime() < 2)
end
local lastFeedTime = 0
local function ShouldFeedPet()
return GetTime() - lastFeedTime > 1800 -- 30 minutes
end
local lastAutoAttackTime = 0
local function IsAutoAttacking()
return GetTime() - lastAutoAttackTime < 2
end
local function GetCastPercentage(unit)
local spell, _, _, startTimeMS, endTimeMS = UnitCastingInfo(unit:GetOMToken())
if not spell then
return 0
end
local castTime = (endTimeMS - startTimeMS) / 1000
local elapsed = (GetTime() * 1000 - startTimeMS) / 1000
return elapsed / castTime * 100
end
local function ShouldInterrupt(unit)
local castPercentage = GetCastPercentage(unit)
local randomThreshold = math.random(30, 80)
return castPercentage >= randomThreshold
end
-- Default APL
DefaultAPL:AddSpell(
AutoShot:CastableIf(function(self)
return BestTarget:Exists() and not IsAutoAttacking() and Player:CanSee(BestTarget)
end):SetTarget(BestTarget):OnCast(function()
lastAutoAttackTime = GetTime()
end)
)
UtilityAPL:AddSpell(
Intimidation:CastableIf(function(self)
return self:IsKnownAndUsable() and Target:IsCasting() and not Target:IsInterruptible()
end):SetTarget(Target)
DefaultAPL:AddSpell(
BarbedShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and (GetFrenzyStacks() < 3 or GetBarbedShotCharges() == 2)
end):SetTarget(BestTarget)
)
UtilityAPL:AddSpell(
BindingShot:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetEnemies(30) > 2
end):SetTarget(Target)
DefaultAPL:AddSpell(
KillCommand:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
UtilityAPL:AddSpell(
TarTrap:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetEnemies(40) > 2
end):SetTarget(Target)
DefaultAPL:AddSpell(
DireBeast:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
UtilityAPL:AddSpell(
TranquilizingShot:CastableIf(function(self)
return self:IsKnownAndUsable() and Target:GetAuras():HasAnyStealableAura()
end):SetTarget(Target)
DefaultAPL:AddSpell(
KillShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and BestTarget:GetHP() < 20
end):SetTarget(BestTarget)
)
-- Defensive APL
DefensiveAPL:AddSpell(
Exhilaration:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 30
end):SetTarget(Player)
DefaultAPL:AddSpell(
CobraShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and (Player:GetAuras():FindMy(BestialWrathBuff):IsUp() or Player:GetPower() > 70)
end):SetTarget(BestTarget)
)
DefensiveAPL:AddSpell(
FeignDeath:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 15
end):SetTarget(Player)
DefaultAPL:AddSpell(
ExplosiveShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not Player:GetAuras():FindMy(BestialWrathBuff):IsUp()
end):SetTarget(BestTarget)
)
-- Cooldown APL
CooldownAPL:AddSpell(
AspectOfTheWild:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Player)
HuntersMark:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not BestTarget:GetAuras():FindMy(HuntersMark):IsUp()
end):SetTarget(BestTarget)
)
CooldownAPL:AddSpell(
BestialWrath:CastableIf(function(self)
return self:IsKnownAndUsable()
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
BlackArrow:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
CooldownAPL:AddSpell(
CallOfTheWild:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
Bloodshed:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Target)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
-- AoE APL
AoEAPL:AddSpell(
BarbedShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and (GetFrenzyStacks() < 3 or GetBarbedShotCharges() == 2)
end):SetTarget(BestTarget)
)
AoEAPL:AddSpell(
BlackArrow:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
AoEAPL:AddSpell(
MultiShot:CastableIf(function(self)
return self:IsKnownAndUsable() and (not Pet:GetAuras():FindMy(BeastCleaveBuff):IsUp() or
Pet:GetAuras():FindMy(BeastCleaveBuff):GetRemainingTime() < 2)
end):SetTarget(Target)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and ShouldUseMultiShot()
end):SetTarget(BestTarget)
)
AoEAPL:AddSpell(
Barrage:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetEnemies(10) >= 3
end):SetTarget(Target)
DireBeast:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
-- Default APL
DefaultAPL:AddSpell(
BarbedShot:CastableIf(function(self)
return self:IsKnownAndUsable() and
(Pet:GetAuras():FindMy(FrenzyBuff):GetRemainingTime() < 2 or self:GetCharges() == 2)
end):SetTarget(Target)
AoEAPL:AddSpell(
CallOfTheWild:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
DefaultAPL:AddSpell(
AoEAPL:AddSpell(
BestialWrath:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
AoEAPL:AddSpell(
KillCommand:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Target)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
DireBeast:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Target)
AoEAPL:AddSpell(
BarbedShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and GetBarbedShotCharges() > 0
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
AoEAPL:AddSpell(
CobraShot:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetPower() > 70 and KillCommand:GetCooldownRemaining() > 2
end):SetTarget(Target)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetAuras():FindMy(BestialWrathBuff):IsUp() and IsKillerCobraTalented()
end):SetTarget(BestTarget)
)
BeastMasteryModule:Sync(function()
if not Player:IsAffectingCombat() then return end
AoEAPL:AddSpell(
KillShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and IsVenomsBiteTalented() and BestTarget:GetHP() < 20
end):SetTarget(BestTarget)
)
UtilityAPL:Execute()
DefensiveAPL:Execute()
AoEAPL:AddSpell(
ExplosiveShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
if Player:GetEnemies(10) >= 3 then
AoEAPL:Execute()
AoEAPL:AddSpell(
CobraShot:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
-- Pet APL
PetAPL:AddSpell(
CallPet:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not Pet:Exists()
end):SetTarget(Player)
)
PetAPL:AddSpell(
FeedPet:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Pet:Exists() and ShouldFeedPet()
end):SetTarget(Pet):OnCast(function()
lastFeedTime = GetTime()
end)
)
PetAPL:AddSpell(
MendPet:CastableIf(function(self)
return Pet:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Pet:GetHP() < 90 and not Pet:GetAuras():FindMy(MendPet):IsUp()
end):SetTarget(Pet)
)
-- Interrupt APL
InterruptAPL:AddSpell(
CounterShot:CastableIf(function(self)
if not BestTarget:Exists() or not self:IsKnownAndUsable() or Player:IsCastingOrChanneling() then
return false
end
if BestTarget:IsCasting() and BestTarget:IsInterruptible() then
return ShouldInterrupt(BestTarget)
end
return false
end):SetTarget(BestTarget)
)
-- Defensive APL
DefensiveAPL:AddSpell(
Exhilaration:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetHP() < 80
end):SetTarget(Player)
)
DefensiveAPL:AddSpell(
SurvivalOfTheFittest:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetHP() < 80
end):SetTarget(Player)
)
-- Boss APL
BossAPL:AddSpell(
CallOfTheWild:CastableIf(function(self)
return BestTarget:Exists() and BestTarget:IsBoss() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Module Sync
BMHunterModule:Sync(function()
if Player:IsMounted() then
return
end
DefensiveAPL:Execute()
DefensiveAPL:Execute() -- Add this line to check defensives
PetAPL:Execute()
if Player:IsAffectingCombat() then
InterruptAPL:Execute()
local enemyCount = Player:GetEnemies(8)
if enemyCount >= 2 then
AoEAPL:Execute()
else
CooldownAPL:Execute()
DefaultAPL:Execute()
end
end
end)
Bastion:Register(BeastMasteryModule)
Bastion:Register(BMHunterModule)
-- Event handler for auto-attack tracking
Bastion.Globals.EventManager:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function()
local _, subEvent, _, sourceGUID, _, _, _, _, _, _, _, spellID = CombatLogGetCurrentEventInfo()
if sourceGUID == Player:GetGUID() and (subEvent == "SWING_DAMAGE" or subEvent == "SWING_MISSED") then
lastAutoAttackTime = GetTime()
end
end)
Loading…
Cancel
Save