162 lines
5.5 KiB
Lua
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
|