Files
TotemBar/core/totemdata.lua
T
2026-08-17 15:19:36 +02:00

162 lines
5.5 KiB
Lua

-- TotemBar - core/totemdata.lua
-- PURE data module (no WoW API calls) - offline-testable.
--
-- Static element -> totem name map for vanilla shaman totems.
--
-- NOTE: TurtleWoW may rename or add totems relative to vanilla 1.12.
-- Use "/tb scan" in-game to print the player's actual known totem spell
-- strings and cross-check them against this map before trusting it.
TotemBar = TotemBar or {}
TotemBar.TOTEM_ELEMENTS = { "Fire", "Earth", "Water", "Air" }
TotemBar.TOTEMS_BY_ELEMENT = {
Fire = {
"Searing Totem",
"Fire Nova Totem",
"Magma Totem",
"Flametongue Totem",
"Frost Resistance Totem",
},
Earth = {
"Earthbind Totem",
"Stoneclaw Totem",
"Stoneskin Totem",
"Strength of Earth Totem",
"Tremor Totem",
},
Water = {
"Fire Resistance Totem",
"Healing Stream Totem",
"Mana Spring Totem",
"Poison Cleansing Totem",
"Disease Cleansing Totem",
"Mana Tide Totem",
},
Air = {
"Grace of Air Totem",
"Grounding Totem",
"Nature Resistance Totem",
"Sentry Totem",
"Windfury Totem",
"Windwall Totem",
"Tranquil Air Totem",
},
}
-- Pure: the largest number of totems any single element offers. ui.lua sizes
-- the hover flyout's icon pool from this. Computed from the data on purpose:
-- the pool used to be a hard-coded 6, but Air has SEVEN totems, and with the
-- Air slot empty the flyout lists ALL known totems of the element (not "all
-- minus the chosen default") -- so the 7th, Tranquil Air Totem, was silently
-- dropped and could not be cast or made default from the bar.
function TotemBar.maxTotemsPerElement()
local maxN = 0
for i = 1, table.getn(TotemBar.TOTEM_ELEMENTS) do
local list = TotemBar.TOTEMS_BY_ELEMENT[TotemBar.TOTEM_ELEMENTS[i]]
local n = (list and table.getn(list)) or 0
if n > maxN then
maxN = n
end
end
return maxN
end
-- Build the reverse lookup (totem name -> element) once at load time.
local elementByName = {}
for elemIdx = 1, table.getn(TotemBar.TOTEM_ELEMENTS) do
local element = TotemBar.TOTEM_ELEMENTS[elemIdx]
local list = TotemBar.TOTEMS_BY_ELEMENT[element]
for totemIdx = 1, table.getn(list) do
elementByName[list[totemIdx]] = element
end
end
-- Returns the element ("Fire"/"Earth"/"Water"/"Air") a totem spell name
-- belongs to, or nil if the name isn't in the static map.
function TotemBar.elementOf(name)
if not name then
return nil
end
return elementByName[name]
end
-- Totem lifetime durations (seconds), tuned to TurtleWoW server timers
-- (mirrors pfUI libtotem's verified values). Keyed by totem spell name;
-- any totem not listed here falls back to DEFAULT_TOTEM_DURATION.
-- Searing Totem is rank-aware (see SEARING_TOTEM_DURATIONS below) and
-- is intentionally NOT listed in this flat table.
TotemBar.DEFAULT_TOTEM_DURATION = 120
-- Cross-checked 2026-07-16 against pfUI's own libtotem.lua duration table
-- (Interface\AddOns\pfUI\libs\libtotem.lua, Spell_Fire_SearingTotem entry:
-- {[-1]=55,[1]=30,[2]=35,[3]=40,[4]=45,[5]=50,[6]=55}) -- byte-identical to
-- the vanilla values below for every rank. TurtleWoW uses vanilla Searing
-- Totem timers, not a custom table; nothing was missing here.
TotemBar.SEARING_TOTEM_DURATIONS = {
[1] = 30,
[2] = 35,
[3] = 40,
[4] = 45,
[5] = 50,
[6] = 55,
}
TotemBar.SEARING_TOTEM_MAX_RANK = 6
TotemBar.SEARING_TOTEM_DEFAULT_DURATION = 55
TotemBar.TOTEM_DURATIONS = {
-- Fire
["Magma Totem"] = 20,
["Fire Nova Totem"] = 5,
["Flametongue Totem"] = 120,
["Frost Resistance Totem"] = 120,
-- Earth
["Stoneclaw Totem"] = 15,
["Earthbind Totem"] = 45,
["Stoneskin Totem"] = 120,
["Strength of Earth Totem"] = 120,
["Tremor Totem"] = 120,
-- Water
["Mana Tide Totem"] = 12,
["Healing Stream Totem"] = 60,
["Mana Spring Totem"] = 60,
["Fire Resistance Totem"] = 120,
["Disease Cleansing Totem"] = 120,
["Poison Cleansing Totem"] = 120,
-- Air
["Grounding Totem"] = 45,
["Grace of Air Totem"] = 120,
["Nature Resistance Totem"] = 120,
-- 5 minutes (spell 6495, TurtleWoW 1.17.2 spell DB). Was missing here
-- entirely and fell through to the 120s default -- but that fallback is
-- meant as a safe OVERestimate, and for Sentry it cut the timer 180s
-- short. pfUI's libtotem has no Sentry entry either, so GetTotemInfo
-- could not correct it.
["Sentry Totem"] = 300,
["Tranquil Air Totem"] = 120,
["Windfury Totem"] = 120,
["Windwall Totem"] = 120,
}
-- Pure: seconds a totem will remain active for, given its exact spell
-- name and (for Searing Totem only) the player's highest known rank
-- number. Unknown/unmapped totems fall back to DEFAULT_TOTEM_DURATION
-- (a safe overestimate, rather than a timer that disappears too early).
function TotemBar.totemDuration(name, highestRank)
if not name then
return TotemBar.DEFAULT_TOTEM_DURATION
end
if name == "Searing Totem" then
if not highestRank or highestRank < 1 then
return TotemBar.SEARING_TOTEM_DEFAULT_DURATION
end
local rank = highestRank
if rank > TotemBar.SEARING_TOTEM_MAX_RANK then
rank = TotemBar.SEARING_TOTEM_MAX_RANK
end
return TotemBar.SEARING_TOTEM_DURATIONS[rank] or TotemBar.SEARING_TOTEM_DEFAULT_DURATION
end
return TotemBar.TOTEM_DURATIONS[name] or TotemBar.DEFAULT_TOTEM_DURATION
end