Developer Stuff - Hekili/hekili GitHub Wiki
-
Projects / TODO List
- Track refreshable status of debuffs in real-time across all enemies
- Priority View that shows all abilities/items that are actually used in that priority.
- Persistent List Insertions
- Ability Modifiers
- Ability Handlers
- In-game spell names
- Global item / trinket toggle
- Sandbox encounter timer system
- Make Fire mage great again (projectiles)
- More Weakaura hooks
- In-game tutorial/walkthrough via dialogue boxes
- More target count options
- Macro'd cooldowns
- More visual indicators
- More snapshot output
- Auto-Removal of useless variables
Table of contents generated with markdown-toc
Has a lot of potential, needs work.
ns.refreshableAuraCount = function(auraName)
local startTime = debugprofilestop() -- Start timing
local aura = class.auras[auraName]
if not aura then
return 0
end
local auraID = aura.id
-- Handle dynamic duration (if duration is a function, evaluate it)
local duration = type(aura.duration) == "function" and aura.duration() or aura.duration or 30
local refreshThreshold = 0.3 * duration -- Calculate threshold as 30% of the duration
local refreshableCount = 0
-- Iterate over each nameplate unit (up to 40)
for i = 1, 40 do
local unit = "nameplate" .. i
if not UnitExists(unit) then break end -- Stop if no more nameplates are present
local auraFound = false
-- Check each debuff slot on the unit to find the specific aura
for j = 1, 40 do
local auraData = C_UnitAuras.GetAuraDataBySlot(unit, j)
if auraData and auraData.spellId == auraID then
auraFound = true
local currentTime = GetTime()
local expirationTime = auraData.expirationTime or 0
local remainingTime = expirationTime - currentTime
if remainingTime <= refreshThreshold then
refreshableCount = refreshableCount + 1
end
break
end
end
if not auraFound then
-- If the aura is not found on the unit, consider it refreshable.
refreshableCount = refreshableCount + 1
end
end
-- Calculate elapsed time and add it to the profiling data
local timeSpent = debugprofilestop() - startTime
Hekili:AddProfileData("Refreshable", timeSpent)
return refreshableCount
end
-- Count of refreshable Garrotes
spec:RegisterStateExpr( "refreshable_garrotes", function ()
return ns.refreshableAuraCount("garrote")
end )
-- Count of refreshable Ruptures
spec:RegisterStateExpr( "refreshable_ruptures", function ()
return ns.refreshableAuraCount("rupture")
end )
- related: A way to display/print all referenceable auras for the spec/class within the GUI, sort of a tinkerer's corner
List Insertions for adding pre-precombat, pre-default, fallthrough recommendations that persist when priorities update (with better name than "list insertions").
- this entry is controlled by the specified toggle
- this entry will only display in the specified display
Allow this to be scripted/logical; this would allow us to short-circuit if a required part of the if=
will fail (i.e., if=talent.doodoo.enabled&buff.poopoo.down
-> strict=talent.doodoo.enabled,if=buff.poopoo.down
if condition in box is false, skip the whole list, there's no point. Otherwise, allow checking based on existing code structure.
box would correlate to
strict=talent.cold_heart.enabled
in simc APL sense.
Yeah, more or less; right now there's no strict
option in the UI but it's currently configured to parse as 1/0 true/false and doesn't get evaluated dynamically (I think).
Similarly, I've been thinking about rebuilding all handlers and ability/aura functions on talent changes and other critical updates, and building constructors instead of writing functions. I just don't know if it's worth the squeeze.
Something like:
handler = function()
if talent.alpha.enabled then applyBuff( "alpha" ) end
if talent.beta.enabled then applyBuff( "beta" ) end
end,
vs
handler = function()
local func = ""
if talent.alpha.enabled then func = func .. [[applyBuff( "alpha" )\n]] end
if talent.beta.enabled then func = func .. [[applyBuff( "beta" )\n]] end
if func ~= "" then return Hekili:LoadString( func ) end
end,
Could also put the conditional items in a table and iterate over each
builders = {
handler = {
{ talent.alpha.enabled, [[applyBuff( "alpha" )]] },
{ talent.beta.enabled , [[applyBuff( "beta" )]] }
}
},
handler = function()
if spec.abilities.this_ability.builders and spec.abilities.this_ability.builders.handler then
local func
for i, line in ipairs( spec.abilities.this_ability.builders.handler ) do
if line[1] then func = strformat( "%s\n%s", ( func or "" ), line[2] ) end
end
if len( func ) > 0 then return Hekili:LoadString( func ) end
end
end,
Basically, removing tons of non time-sensitive conditionals across the board.
Caching is probably a better solution, though.
Instead of needing to pause the addon, add in an option to either show a simple spellname (or blizz tooltip) on mouseover, or a weakaura-like name display.
pls
Allow users to input their own timers for an NPC / encounter ID and have this timer be able to trigger things like the cooldown toggle. There would be 0 support for pre-determined or suggested timers as that is dangerous territory.
- Such as a "max" number of targets, or a N-target display
- Hero Tree Selection
- combat status / timer
- When an ability is chosen, list some of the effects that will happen via handler Example for Beast Mastery Cobra Shot
handler = function ()
if talent.dire_summons.enabled then reduceCooldown( "howl_of_the_pack_leader", 1 ) end
if talent.serpentine_rhythm.enabled then
if buff.serpentine_rhythm.stacks == 3 then
removeBuff( "serpentine_rhythm" )
applyBuff( "serpentine_blessing" )
else addStack( "serpentine_rhythm" )
end
end
if talent.barbed_scales.enabled then
gainChargeTime( "barbed_shot", 2 )
end
if talent.killer_cobra.enabled and buff.bestial_wrath.up then setCooldown( "kill_command", 0 ) end
-- Legacy / PvP Stuff
if debuff.concussive_shot.up then debuff.concussive_shot.expires = debuff.concussive_shot.expires + 3 end
if set_bonus.tier30_4pc > 0 then reduceCooldown( "bestial_wrath", 1 ) end
end,
},
The snapshot output may say something like
Cobra shot was chosen
Handler Analysis
if talent.dire_summons.enabled[true] then reduceCooldown( "howl_of_the_pack_leader", 1 ) end
if talent.serpentine_rhythm.enabled[false] then
if buff.serpentine_rhythm.stacks == 3 then
removeBuff( "serpentine_rhythm" )
applyBuff( "serpentine_blessing" )
else addStack( "serpentine_rhythm" )
end
end
if talent.barbed_scales.enabled[true] then
gainChargeTime( "barbed_shot", 2 )
end
if talent.killer_cobra.enabled and buff.bestial_wrath.up[false] then setCooldown( "kill_command", 0 ) end
Effects applied by this action
reduceCooldown( "howl_of_the_pack_leader", 1 )
gainChargeTime( "barbed_shot", 2 )
Example: Unholy DK
actions+=/mind_freeze
## actions+=/variable,name=st_planning,op=set,value=active_enemies=1
## actions+=/variable,name=adds_remain,op=set,value=active_enemies>1
Replace st_planning
with active_enemies=1
Replace adds_remain
with active_enemies>1
Currently this is done manually, and occasionally gets overwritten. Make specific cases in the SIMC importer function to translate them inside the addon?