local Tinkr, Bastion = ... local GuardianModule = Bastion.Module:New('guardian') local Evaluator = Tinkr.Util.Evaluator local Player = Bastion.UnitManager:Get('player') local None = Bastion.UnitManager:Get('none') local Target = Bastion.UnitManager:Get('target') local myconf = Tinkr.Util.Config:New('guardian_druid') -- for saving variables local AutoAttack = Bastion.SpellBook:GetSpell(6603) local WarStomp = Bastion.SpellBook:GetSpell(20549) local Barkskin = Bastion.SpellBook:GetSpell(22812) local BearForm = Bastion.SpellBook:GetSpell(5487) local Berserk = Bastion.SpellBook:GetSpell(50334) local CatForm = Bastion.SpellBook:GetSpell(768) local Dash = Bastion.SpellBook:GetSpell(1850) local EntanglingRoots = Bastion.SpellBook:GetSpell(339) local FerociousBite = Bastion.SpellBook:GetSpell(22568) local FrenziedRegeneration = Bastion.SpellBook:GetSpell(22842) local Growl = Bastion.SpellBook:GetSpell(6795) local Ironfur = Bastion.SpellBook:GetSpell(192081) local Mangle = Bastion.SpellBook:GetSpell(33917) local MarkoftheWild = Bastion.SpellBook:GetSpell(1126) local Moonfire = Bastion.SpellBook:GetSpell(8921) local MoonfireDebuff = Bastion.SpellBook:GetSpell(164812) local Prowl = Bastion.SpellBook:GetSpell(5215) local Regrowth = Bastion.SpellBook:GetSpell(8936) local Revive = Bastion.SpellBook:GetSpell(50769) local Shred = Bastion.SpellBook:GetSpell(5221) local SkullBash = Bastion.SpellBook:GetSpell(106839) local Thrash = Bastion.SpellBook:GetSpell(77758) local ThrashDebuff = Bastion.SpellBook:GetSpell(192090) local TravelForm = Bastion.SpellBook:GetSpell(783) local Wrath = Bastion.SpellBook:GetSpell(5176) local Maul = Bastion.SpellBook:GetSpell(6807) local SurvivalInstincts = Bastion.SpellBook:GetSpell(61336) local Swipe = Bastion.SpellBook:GetSpell(213771) local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('skullbash', function(unit) local interrupt = nil Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 40 then return false end if Player:InMelee(unit) and unit:IsInterruptible(5) and Player:IsFacing(unit) then interrupt = unit return true end end) if interrupt == nil then interrupt = None end return interrupt end) local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit) local tank = nil Bastion.UnitManager:EnumFriends(function(unit) if Player:GetDistance(unit) > 40 then return false end if not Player:CanSee(unit) then return false end if unit:IsDead() then return false end if unit:IsTank() then tank = unit return true end return false end) if tank == nil then tank = None end return tank end) local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(unit) local explosive = nil Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 40 then return false end if Player:InMelee(unit) and unit:GetID() == 120651 and Player:IsFacing(unit) then explosive = unit return true end end) if explosive == nil then explosive = None end return explosive end) local RestingAPL = Bastion.APL:New('resting') local OpenerAPL = Bastion.APL:New('opener') local DefensivesAPL = Bastion.APL:New('defensives') local STAPL = Bastion.APL:New('st') local UtilityAPL = Bastion.APL:New('utility') -- Resting - Out of Combat Actions local motw = myconf:Read('motw') RestingAPL:AddSpell( MarkoftheWild:CastableIf(function(self) return motw and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(MarkoftheWild):IsUp() and not IsMounted() end):SetTarget(Player) ) -- Opener spells local opener = myconf:Read('opener') OpenerAPL:AddSpell( Moonfire:CastableIf(function(self) return opener == 'moonfire' and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() end):SetTarget(Target) ) -- Defensive spells local ironfur = myconf:Read('ironfur') local ironfurpercent = myconf:Read('ironfurpercent') DefensivesAPL:AddSpell( Ironfur:CastableIf(function(self) return ironfur and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindMy(Ironfur):IsUp() and Player:GetHP() <= ironfurpercent end):SetTarget(Player) ) -- Heal yourself with Frenzied Regeneration if your health ever dips low local fregen = myconf:Read('fregen') local fregenpercent = myconf:Read('fregenpercent') DefensivesAPL:AddSpell( FrenziedRegeneration:CastableIf(function(self) return fregen and self:IsKnownAndUsable() and Player:GetHP() <= fregenpercent end):SetTarget(Player) ) -- Utility spells local skullbash = myconf:Read('skullbash') UtilityAPL:AddSpell( SkullBash:CastableIf(function(self) return skullbash and InterruptTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() end):SetTarget(InterruptTarget) ) -- Single Target Action Priority List -- Bear Form STAPL:AddSpell( BearForm:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(BearForm):IsUp() end):SetTarget(Player) ) -- Auto Attack STAPL:AddSpell( AutoAttack:CastableIf(function(self) return self:IsKnownAndUsable() and not IsCurrentSpell(AutoAttack) and Player:InMelee(Target) end):SetTarget(Target) ) -- Opener spells STAPL:AddSpell( Moonfire:CastableIf(function(self) return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Target:GetAuras():FindMy(MoonfireDebuff):IsUp() end):SetTarget(Target) ) -- Spend your rage on Maul as required STAPL:AddSpell( Maul:CastableIf(function(self) return self:IsKnownAndUsable() and Player:InMelee(Target) end):SetTarget(Target) ) -- Maintain Moonfire on as many mobs as possible -- Thrash on cooldown STAPL:AddSpell( Thrash:CastableIf(function(self) return not Target:GetAuras():FindMy(ThrashDebuff):IsUp() and Player:InMelee(Target) end):SetTarget(Target) ) -- Mangle on cooldown STAPL:AddSpell( Mangle:CastableIf(function(self) return self:IsKnownAndUsable() and Player:InMelee(Target) end):SetTarget(Target) ) -- Fill your empty GCDs with Swipe STAPL:AddSpell( Swipe:CastableIf(function(self) return not self:IsOnCooldown() and Player:InMelee(Target) end):SetTarget(Target) ) -- Module that dictates APL flow GuardianModule:Sync(function() if not Player:IsAffectingCombat() then RestingAPL:Execute() end if not Player:IsAffectingCombat() and Target:Exists() and Target:IsHostile() and not Target:IsDead() then OpenerAPL:Execute() end if Player:IsAffectingCombat() and Target:Exists() and Target:IsHostile() and not Target:IsDead() then DefensivesAPL:Execute() STAPL:Execute() end end) Bastion:Register(GuardianModule) local tab1 = { layoutConfig = { padding = { top = 40 } }, rows = { [1] = { shadpr = { type = 'label', label = 'Open Combat' } }, [2] = { opener = { type = 'dropdown', label = 'Opener', column = 6, order = 1, options = { { text = 'Moonfire', value = 'moonfire'}, { text = 'None', value = 'none'}, }, initialValue = myconf:Read('opener', 'moonfire'), onValueChanged = function(_, value) myconf:Write('opener', value) end }, }, [3] = { shadpr = { type = 'label', label = 'Buffs' } }, [4] = { motw = { type = 'checkbox', label = 'Mark of the Wild', column = 12, order = 1, initialValue = myconf:Read('motw', false), onValueChanged = function(_, flag) myconf:Write('motw', flag) end }, }, [5] = { shadpr = { type = 'label', label = 'Defensives' } }, [6] = { shield1 = { type = 'checkbox', label = 'Ironfur', column = 6, order = 1, initialValue = myconf:Read('ironfur', false), onValueChanged = function(_, flag) myconf:Write('ironfur', flag) end }, shield2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, min = 1, max = 100, precision = 0, initialValue = myconf:Read('ironfurpercent', 35), onValueChanged = function(_, value) myconf:Write('ironfurpercent', value) end }, }, [7] = { dispersion1 = { type = 'checkbox', label = 'Frenzied Regeneration', column = 6, order = 1, initialValue = myconf:Read('fregen', false), onValueChanged = function(_, flag) myconf:Write('fregen', flag) end }, dispersion2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, min = 1, max = 100, precision = 0, initialValue = myconf:Read('fregenpercent', 35), onValueChanged = function(_, value) myconf:Write('fregenpercent', value) end }, }, [8] = { shadpr = { type = 'label', label = 'Interrupts' } }, [9] = { silence = { type = 'checkbox', label = 'Skull Bash on CD', column = 12, order = 1, initialValue = myconf:Read('skullbash', false), onValueChanged = function(_, flag) myconf:Write('skullbash', flag) end }, }, [10] = { shadpr = { type = 'header', label = 'Purify Disease' } }, [11] = { incombat = { type = 'checkbox', label = 'In Combat', column = 6, order = 1, initialValue = myconf:Read('purifyic', false), onValueChanged = function(_, flag) myconf:Write('purifyic', flag) end }, outcombat = { type = 'checkbox', label = 'Out of Combat', column = 6, order = 2, initialValue = myconf:Read('purifyooc', false), onValueChanged = function(_, flag) myconf:Write('purifyooc', flag) end }, }, [12] = { shadpr = { type = 'header', label = 'Dispel Magic' } }, [13] = { incombat = { type = 'checkbox', label = 'In Combat', column = 12, order = 1, initialValue = myconf:Read('dispelic', false), onValueChanged = function(_, flag) myconf:Write('dispelic', flag) end }, }, [14] = { shadpr = { type = 'header', label = 'Dispel Delay Time' } }, [15] = { delay = { type = 'slider', label = 'In seconds', column = 6, order = 1, min = 0.5, max = 2, precision = 1, initialValue = myconf:Read('dispeldelay', 1), onValueChanged = function(_, value) myconf:Write('dispeldelay', value) end }, }, }, } local tab2 = { layoutConfig = { padding = { top = 40 } }, rows = { [1] = { shadpr = { type = 'header', label = 'Player Healing' } }, [2] = { incombat = { type = 'checkbox', label = 'In Combat Healing', column = 6, order = 1, initialValue = myconf:Read('playericheal', false), onValueChanged = function(_, flag) myconf:Write('playericheal', flag) end }, outcombat = { type = 'checkbox', label = 'Out of Combat Healing', column = 6, order = 2, initialValue = myconf:Read('playeroocheal', false), onValueChanged = function(_, flag) myconf:Write('playeroocheal', flag) end }, }, [3] = { shadowmend1 = { type = 'checkbox', label = 'Shadow Mend', column = 6, order = 1, initialValue = myconf:Read('shadowmend', false), onValueChanged = function(_, flag) myconf:Write('shadowmend', flag) end }, shadowmend2 = { type = 'slider', label = 'Player Health', column = 6, order = 2, min = 1, max = 100, precision = 0, initialValue = myconf:Read('shadowmendpercent', 35), onValueChanged = function(_, value) myconf:Write('shadowmendpercent', value) end }, }, }, } local guardianconfig = { layoutConfig = { padding = { top = 30 } }, rows = { [1] = { container = { type = 'tab', fullSize = true, tabs = { { name = 'player', title = 'Player Settings', layout = tab1 }, { name = 'group', title = 'Placeholder', layout = tab2 } }, } }, }, } Bastion.settingstemplate(guardianconfig, 'Guardian Druid', 400, 600, 1.00, 0.49, 0.04) -- config, Title of Settings Frame, Width, Height, ClassRGB -- Class colours -- Death Knight 0.77 0.12 0.23 Red -- Demon Hunter 0.64 0.19 0.79 Dark Magenta -- Druid 1.00 0.49 0.04 Orange -- Evoker 0.20 0.58 0.50 Dark Emerald -- Hunter 0.67 0.83 0.45 Green -- Mage 0.25 0.78 0.92 Light Blue -- Monk 0.00 1.00 0.60 Spring Green -- Paladin 0.96 0.55 0.73 Pink -- Priest 1.00 1.00 1.00 White -- Rogue 1.00 0.96 0.41 Yellow -- Shaman 0.00 0.44 0.87 Blue -- Warlock 0.53 0.53 0.93 Purple -- Warrior 0.78 0.61 0.43 Tan