Last active
January 27, 2017 08:39
-
-
Save JonathonAshworth/f2a5f59da1139cb855ae578a58299bc2 to your computer and use it in GitHub Desktop.
Frost Death Knight rotation weakaura
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
aura_env.updateInterval = 0.05 | |
aura_env.lastUpdate = GetTime() | |
-- SpellID of the spell icon we're showing | |
aura_env.recommended = 212812 | |
-- How many milliseconds until we should use the next ability | |
aura_env.recommendedWait = 0 | |
-- Abilities | |
aura_env.abilities = { | |
frost_strike = 49143, | |
howling_blast = 49184, | |
obliterate = 49020, | |
remorseless_winter = 196770, | |
obliteration = 207256, | |
empower_rune_weapon = 47568, | |
none = 212812 -- ? icon | |
} | |
-- Buffs | |
aura_env.buffs = { | |
icy_talons = 194879, | |
obliteration = 207256, | |
rime = 59052, | |
killing_machine = 51124 | |
} | |
-- Get names for each buff since the WoW API is fucking trash and inexplicably needs them over spellIds for some queries | |
aura_env.buffNames = {} | |
for k,v in pairs(aura_env.buffs) do | |
aura_env.buffNames[v] = GetSpellInfo(v) | |
end | |
-- Debuffs | |
aura_env.debuffs = { | |
frost_fever = 55095 | |
} | |
-- Get names of debuffs | |
aura_env.debuffNames = {} | |
for k,v in pairs(aura_env.debuffs) do | |
aura_env.debuffNames[v] = GetSpellInfo(v) | |
end | |
-- Call to set recommended, makes code more readable later | |
function aura_env.recommend(spell, wait) | |
aura_env.recommended = aura_env.abilities[spell] | |
aura_env.recommendedWait = wait | |
end | |
-- Get the recommended next spell | |
function aura_env.getRecommendation(runicPower, numRunes, cooldowns, buffDurations, buffCounts, debuffDurations) | |
-- Priority list implementation is here | |
-- (1) Build Icy Talons if it's below 3 | |
if runicPower >= 25 and buffCounts["icy_talons"] < 3 then return "frost_strike" | |
-- (2) Maintain Icy Talons if it's about to drop off | |
elseif runicPower >= 25 and buffDurations["icy_talons"] < 2 then return "frost_strike" | |
-- (3) Inflict Frost Fever if it's not up or about to drop off | |
elseif (numRunes >= 1 or buffDurations["rime"] > 0) and debuffDurations["frost_fever"] < 2 then return "howling_blast" | |
-- (4) Dump Runic Power if it's going to cap | |
elseif runicPower >= 70 then return "frost_strike" | |
-- (5) Use up Rime procs if we're not in Obliteration | |
elseif buffDurations["rime"] > 0 and buffDurations["obliteration"] == 0 then return "howling_blast" | |
-- (6) Fire up Obliteration if we have enough resources to sustain it | |
elseif cooldowns["obliteration"] == 0 and runicPower >= 25 and numRunes >= 2 then return "obliteration" | |
-- (7) Use up Killing Machine procs | |
elseif numRunes >= 2 and buffDurations["killing_machine"] > 0 then return "obliterate" | |
-- (8) Use Frost Strike if Obliteration is up | |
elseif runicPower >= 25 and buffDurations["obliteration"] > 0 then return "frost_strike" | |
-- (9) Use Remorseless Winter if it's up | |
elseif numRunes >= 1 and cooldowns["remorseless_winter"] == 0 then return "remorseless_winter" | |
-- (10) Use obliterate without a killing machine proc | |
elseif numRunes >= 2 then return "obliterate" | |
-- (11) Use frost strike if we have enough runic power | |
elseif runicPower >= 40 then return "frost_strike" | |
-- (12) Empower Rune Weapon if we have nothing else to do | |
elseif cooldowns["empower_rune_weapon"] == 0 then return "empower_rune_weapon" | |
-- (13) Otherwise do nothing until we have enough RP, runes or procs | |
else return "none" end | |
end | |
-- Simulates waiting for a particular number of seconds | |
function aura_env.wait(length, runicPower, runes, cooldowns, buffDurations, buffCounts, debuffDurations) | |
-- sim runic power change (assumes runic attenuation talent) | |
-- TODO: Other passive runic power changes? | |
local mainSpd, offSpd = UnitAttackSpeed("player") | |
local mainRunicPower = length / mainSpd | |
local offRunicPower = length / offSpd | |
local newRunicPower = runicPower + mainRunicPower + offRunicPower | |
-- runes | |
local newRunes = {} | |
for k,v in pairs(runes) do | |
newRunes[k] = v - length | |
if(newRunes[k] < 0) then newRunes[k] = 0 end | |
end | |
-- cooldowns | |
local newCooldowns = {} | |
for k,v in pairs(cooldowns) do | |
newCooldowns[k] = v - length | |
if(newCooldowns[k] < 0) then newCooldowns[k] = 0 end | |
end | |
-- buff durations | |
local newBuffDurations = {} | |
for k,v in pairs(buffDurations) do | |
newBuffDurations[k] = v - length | |
if(newBuffDurations[k] < 0) then newBuffDurations[k] = 0 end | |
end | |
-- buff counts | |
local newBuffCounts = {} | |
for k,v in pairs(buffCounts) do | |
if(newBuffDurations[k] == 0) then newBuffCounts[k] = 0 | |
else newBuffCounts[k] = buffCounts[k] end | |
end | |
-- debuff durations | |
local newDebuffDurations = {} | |
for k,v in pairs(debuffDurations) do | |
newDebuffDurations[k] = v - length | |
if(newDebuffDurations[k] < 0) then newDebuffDurations[k] = 0 end | |
end | |
return newRunicPower, newRunes, newCooldowns, newBuffDurations, newBuffCounts, newDebuffDurations | |
end | |
-- Takes the rune cooldowns and returns the number of runes that are ready to use | |
function aura_env.numRunes(runes) | |
local num = 0 | |
for k,v in pairs(runes) do | |
if v == 0 then | |
num = num + 1 | |
end | |
end | |
return num | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Custom, Status, Every Frame | |
function() | |
-- This function runs on every frame | |
-- no point updating all the time if the player is running at 300 fps | |
-- so skip everything if it's already been run in the last n seconds | |
-- can change update interval in the init section | |
local now = GetTime() | |
if now < aura_env.lastUpdate + aura_env.updateInterval then | |
return true | |
end | |
aura_env.lastUpdate = now | |
local gcdStart, gcdDuration = GetSpellCooldown(61304) -- 61304 = GCD | |
local gcdEndpoint = gcdStart + gcdDuration | |
local baselineTime = max( now, gcdEndpoint ) -- "jump" to the end of the GCD if it's active and use that as a baseline for further calculations | |
-- Get resources | |
local runicPower = UnitPower("player", SPELL_POWER_RUNIC_POWER) | |
local runes = {} | |
for i = 1,6 do | |
local start, duration = GetRuneCooldown(i) | |
if start == 0 then | |
runes[i] = 0 | |
else | |
runes[i] = start + duration - baselineTime | |
end | |
end | |
-- Get cooldowns | |
local cooldowns = {} | |
for k,v in pairs(aura_env.abilities) do | |
local start, duration = GetSpellCooldown(v) | |
cooldowns[k] = max(0, start + duration - baselineTime) | |
end | |
-- Get relevant buffs | |
local buffDurations = {} | |
local buffCounts = {} | |
for k,v in pairs(aura_env.buffs) do | |
local _,_,_,count,_,_,expires = UnitBuff("player", aura_env.buffNames[v], nil, 'PLAYER') | |
if expires == nil then | |
buffDurations[k] = 0 | |
buffCounts[k] = 0 | |
else | |
if expires - baselineTime < 0 then | |
buffDurations[k] = 0 | |
buffCounts[k] = 0 | |
else | |
buffDurations[k] = expires - baselineTime | |
buffCounts[k] = count | |
end | |
end | |
end | |
-- Get relevant debuffs | |
local debuffDurations = {} | |
for k,v in pairs(aura_env.debuffs) do | |
local _,_,_,_,_,_,expires = UnitDebuff("target", aura_env.debuffNames[v], nil, 'PLAYER') | |
if expires == nil then | |
debuffDurations[k] = 0 | |
else | |
debuffDurations[k] = max(0, expires - baselineTime) | |
end | |
end | |
local recommendation = "none" | |
local waitRecommendation = 0 | |
while recommendation == "none" do | |
recommendation = aura_env.getRecommendation(runicPower, aura_env.numRunes(runes), cooldowns, buffDurations, buffCounts, debuffDurations) | |
if recommendation == "none" and waitRecommendation < 5 then | |
-- wait 0.05 seconds and try again | |
runicPower, runes, cooldowns, buffDurations, buffCounts, debuffDurations = aura_env.wait(0.05, runicPower, runes, cooldowns, buffDurations, buffCounts, debuffDurations) | |
waitRecommendation = waitRecommendation + 0.05 | |
end | |
end | |
-- If we sim forward 5 seconds and there's still nothing to do then obviously something is fucked, path of frost should never show up | |
-- Set the recommendation | |
aura_env.recommend(recommendation, waitRecommendation) | |
return true | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function() | |
local gcdStart, gcdDuration = GetSpellCooldown(61304) | |
if gcdStart == 0 and gcdDuration == 0 then | |
if aura_env.recommendedWait == 0 then | |
return 0,0 | |
else | |
return gcdDuration + 5, GetTime() + aura_env.recommendedWait | |
end | |
else | |
if aura_env.recommendedWait == 0 then | |
return gcdDuration, gcdStart + gcdDuration | |
else | |
return gcdDuration + 5, gcdStart + gcdDuration + aura_env.recommendedWait | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function() | |
return GetSpellTexture(aura_env.recommended) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment