local Tinkr, Bastion = ... local BloodDKModule = Bastion.Module:New('BloodDeathKnight') local Player = Bastion.UnitManager:Get('player') local Target = Bastion.UnitManager:Get('target') local SpellBook = Bastion.SpellBook:New() -- Spells local DeathStrike = SpellBook:GetSpell(49998) local Marrowrend = SpellBook:GetSpell(195182) local HeartStrike = SpellBook:GetSpell(206930) local BloodBoil = SpellBook:GetSpell(50842) local DeathAndDecay = SpellBook:GetSpell(43265) local DancingRuneWeapon = SpellBook:GetSpell(49028) local Tombstone = SpellBook:GetSpell(219809) local Bonestorm = SpellBook:GetSpell(194844) local AbominationLimb = SpellBook:GetSpell(315443) local EmpowerRuneWeapon = SpellBook:GetSpell(47568) local DeathsCaress = SpellBook:GetSpell(195292) local RaiseDead = SpellBook:GetSpell(46585) local BlindingSleet = SpellBook:GetSpell(207167) local AntiMagicShell = SpellBook:GetSpell(48707) local GorefiendGrasp = SpellBook:GetSpell(108199) local MindFreeze = SpellBook:GetSpell(47528) local Asphyxiate = SpellBook:GetSpell(221562) local RaiseAlly = SpellBook:GetSpell(61999) local AntiMagicZone = SpellBook:GetSpell(51052) local VampiricBlood = SpellBook:GetSpell(55233) -- Buffs local BoneShield = SpellBook:GetSpell(195181) local DancingRuneWeaponBuff = SpellBook:GetSpell(81256) local DeathAndDecayBuff = SpellBook:GetSpell(188290) -- Helper Functions local function GetEnemiesInRange(range) local count = 0 Bastion.UnitManager:EnumEnemies(function(unit) if unit:GetDistance(Player) <= range then count = count + 1 end end) return count end local function HasEnoughRunicPower(cost) return Player:GetPower() >= cost end local function ShouldUseDeathStrike() local hp = Player:GetHP() local runicPower = Player:GetPower() return hp <= 70 or runicPower > 110 or (hp <= 85 and HasEnoughRunicPower(45)) end -- Create APLs local DefaultAPL = Bastion.APL:New('default') local CooldownAPL = Bastion.APL:New('cooldown') local DefensiveAPL = Bastion.APL:New('defensive') local UtilityAPL = Bastion.APL:New('utility') -- Utility APL UtilityAPL:AddSpell( BlindingSleet:CastableIf(function(self) return self:IsKnownAndUsable() and GetEnemiesInRange(12) >= 3 end):SetTarget(Player) ) UtilityAPL:AddSpell( GorefiendGrasp:CastableIf(function(self) return self:IsKnownAndUsable() and GetEnemiesInRange(15) >= 3 end):SetTarget(Target) ) UtilityAPL:AddSpell( MindFreeze:CastableIf(function(self) return self:IsKnownAndUsable() and Target:IsCasting() and Target:IsInterruptible() end):SetTarget(Target) ) UtilityAPL:AddSpell( Asphyxiate:CastableIf(function(self) return self:IsKnownAndUsable() and not Target:IsStunned() end):SetTarget(Target) ) -- Cooldown APL CooldownAPL:AddSpell( DancingRuneWeapon:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(DancingRuneWeaponBuff):IsUp() end):SetTarget(Player) ) CooldownAPL:AddSpell( AbominationLimb:CastableIf(function(self) return self:IsKnownAndUsable() end):SetTarget(Player) ) CooldownAPL:AddSpell( EmpowerRuneWeapon:CastableIf(function(self) return self:IsKnownAndUsable() end):SetTarget(Player) ) -- Defensive APL DefensiveAPL:AddSpell( AntiMagicShell:CastableIf(function(self) return self:IsKnownAndUsable() and Player:GetHP() <= 70 end):SetTarget(Player) ) DefensiveAPL:AddSpell( AntiMagicZone:CastableIf(function(self) return self:IsKnownAndUsable() and Player:GetHP() <= 50 end):SetTarget(Player) ) DefensiveAPL:AddSpell( VampiricBlood:CastableIf(function(self) return self:IsKnownAndUsable() and Player:GetHP() <= 60 end):SetTarget(Player) ) -- Default APL DefaultAPL:AddSpell( DeathStrike:CastableIf(function(self) return self:IsKnownAndUsable() and ShouldUseDeathStrike() end):SetTarget(Target) ) DefaultAPL:AddSpell( Marrowrend:CastableIf(function(self) local boneShieldCount = Player:GetAuras():FindMy(BoneShield):GetCount() return self:IsKnownAndUsable() and (boneShieldCount <= 6 or (boneShieldCount <= 7 and Player:GetAuras():FindMy(BoneShield):GetRemainingTime() < 3)) end):SetTarget(Target) ) DefaultAPL:AddSpell( Tombstone:CastableIf(function(self) return self:IsKnownAndUsable() and Player:GetAuras():FindMy(BoneShield):GetCount() > 6 and not Player:GetAuras():FindMy(DancingRuneWeaponBuff):IsUp() and Player:GetAuras():FindMy(DeathAndDecayBuff):IsUp() and DancingRuneWeapon:GetCooldownRemaining() > 0 end):SetTarget(Player) ) DefaultAPL:AddSpell( Bonestorm:CastableIf(function(self) return self:IsKnownAndUsable() and Player:GetAuras():FindMy(BoneShield):GetCount() > 11 and not Player:GetAuras():FindMy(DancingRuneWeaponBuff):IsUp() and Player:GetAuras():FindMy(DeathAndDecayBuff):IsUp() and HasEnoughRunicPower(100) and DancingRuneWeapon:GetCooldownRemaining() > 0 end):SetTarget(Player) ) DefaultAPL:AddSpell( DeathAndDecay:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(DeathAndDecayBuff):IsUp() end):SetTarget(Player):OnCast(function(self) local loc = Bastion.UnitManager:FindEnemiesCentroid(10, 30) if loc then self:Click(loc) end end) ) DefaultAPL:AddSpell( BloodBoil:CastableIf(function(self) return self:IsKnownAndUsable() and self:GetCharges() > 1 end):SetTarget(Target) ) DefaultAPL:AddSpell( HeartStrike:CastableIf(function(self) return self:IsKnownAndUsable() end):SetTarget(Target) ) -- Opener sequence local OpenerSequence = Bastion.Sequencer:New({ function(self) if DeathAndDecay:IsKnownAndUsable() then DeathAndDecay:Cast(Player):OnCast(function(self) local loc = Bastion.UnitManager:FindEnemiesCentroid(10, 30) if loc then self:Click(loc) end end) return true end return false end, function(self) if DeathsCaress:IsKnownAndUsable() then DeathsCaress:Cast(Target) return true end return false end, function(self) if RaiseDead:IsKnownAndUsable() then RaiseDead:Cast(Player) return true end return false end, function(self) if DancingRuneWeapon:IsKnownAndUsable() then DancingRuneWeapon:Cast(Player) return true end return false end, function(self) if BloodBoil:IsKnownAndUsable() then BloodBoil:Cast(Target) return true end return false end, function(self) if Tombstone:IsKnownAndUsable() then Tombstone:Cast(Player) return true end return false end, function(self) if HeartStrike:IsKnownAndUsable() then HeartStrike:Cast(Target) return true end return false end, function(self) if DeathStrike:IsKnownAndUsable() and ShouldUseDeathStrike() then DeathStrike:Cast(Target) return true end return false end, function(self) if HeartStrike:IsKnownAndUsable() then HeartStrike:Cast(Target) return true end return false end, function(self) if BloodBoil:IsKnownAndUsable() then BloodBoil:Cast(Target) return true end return false end, function(self) if DeathStrike:IsKnownAndUsable() and ShouldUseDeathStrike() then DeathStrike:Cast(Target) return true end return false end, function(self) if Marrowrend:IsKnownAndUsable() then Marrowrend:Cast(Target) return true end return false end, }, function() return not Player:IsAffectingCombat() end) DefaultAPL:AddSequence(OpenerSequence, function() return not Player:IsAffectingCombat() end) BloodDKModule:Sync(function() if not Player:IsAffectingCombat() then return end DefensiveAPL:Execute() UtilityAPL:Execute() CooldownAPL:Execute() DefaultAPL:Execute() end) Bastion:Register(BloodDKModule)