Module:AbilityTable: Difference between revisionsGive feedback
Add compact parameter: one row per hero, abilities comma-separated, no extra columns (with help from vergir-bot LLM) |
Refactor compact mode: ul/li output, hero name as text, notes inline after each ability in parentheses (with help from vergir-bot LLM) |
||
| Line 22: | Line 22: | ||
} | } | ||
-- Editor-authored notes appended to the Notes column. | -- Editor-authored notes appended to the Notes column (normal mode) or | ||
-- inline after the ability name in parentheses (compact mode). | |||
local human_notes = { | local human_notes = { | ||
["charges"] = { | ["charges"] = { | ||
| Line 31: | Line 32: | ||
}, | }, | ||
["debuffresist"] = { | ["debuffresist"] = { | ||
["Aura of Suffering"] | ["Aura of Suffering"] = "T1 slow, T3 extra damage. The effect is negligible.", | ||
["Lightning Ball"] | ["Lightning Ball"] = "T2 Slow. The effect is negligible.", | ||
["Static Charge"] | ["Static Charge"] = "Stun duration. Delay before stun is not affected.", | ||
["Enchanter's Satchel"] = "T3 Slow.", | ["Enchanter's Satchel"] = "T3 Slow.", | ||
["Itani Lo Sahn"] = "Despite being described as \"debuff\", it can not be reduced with debuff resist.", | ["Itani Lo Sahn"] = "Despite being described as \"debuff\", it can not be reduced with debuff resist.", | ||
["Scorn"] | ["Scorn"] = "T3 extra damage from Mo & Krill.", | ||
["Hotel Guest"] | ["Hotel Guest"] = "Only T2 late check-out stun can be reduced.", | ||
["Jar of Dead"] | ["Jar of Dead"] = "T2 slow.", | ||
["Grapple Arm"] | ["Grapple Arm"] = "T1 extra damage from Bebop.", | ||
["Binding Word"] | ["Binding Word"] = "Immobilize Duration. Escape time is not affected.", | ||
["Power Slash"] | ["Power Slash"] = "T1 slow.", | ||
["Kinetic Pulse"] | ["Kinetic Pulse"] = "T2 bullet resist reduction and slow.", | ||
["Pain Battery"] | ["Pain Battery"] = "T1 slow.", | ||
["Power Surge"] | ["Power Surge"] = "T3 Spirit Resist reduction.", | ||
["Rain of Arrows"] | ["Rain of Arrows"] = "T2 slow.", | ||
["Soul Exchange"] | ["Soul Exchange"] = "T2 silence.", | ||
["Ground Strike"] | ["Ground Strike"] = "T2 slow.", | ||
["Flog"] | ["Flog"] = "T2 Fire rate slow.", | ||
}, | }, | ||
} | } | ||
| Line 55: | Line 56: | ||
local exclude_list = { | local exclude_list = { | ||
["debuffresist"] = { | ["debuffresist"] = { | ||
"Bookwyrm", -- has | "Bookwyrm", -- has debuffduration for some reason | ||
"Slam Fire", -- has debuffduration for some reason | "Slam Fire", -- has debuffduration for some reason | ||
"Splatter", -- has SlowPercent but no duration to shave off. | "Splatter", -- has SlowPercent but no duration to shave off. | ||
| Line 427: | Line 428: | ||
.. "</div>" | .. "</div>" | ||
) | ) | ||
if compact then | if compact then | ||
-- Compact mode: one | -- Compact mode: <ul> with one <li> per hero. | ||
-- Each item: "{HeroIcon}: {AbilityIcon} (note), {AbilityIcon}, ..." | |||
-- Group abilities by hero, preserving sort order. | -- Group abilities by hero, preserving sort order. | ||
local hero_order | local hero_order = {} | ||
local hero_abilities = {} -- heroName -> list of ability names | local hero_abilities = {} -- heroName -> list of ability names | ||
for _, ability in ipairs(filtered) do | for _, ability in ipairs(filtered) do | ||
| Line 450: | Line 446: | ||
end | end | ||
local items = {} | |||
for _, hero in ipairs(hero_order) do | for _, hero in ipairs(hero_order) do | ||
local hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { hero } } | local hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { hero } } | ||
local ability_parts = {} | local ability_parts = {} | ||
for _, name in ipairs(hero_abilities[hero]) do | for _, name in ipairs(hero_abilities[hero]) do | ||
local ability_cell = frame:expandTemplate{ title = "AbilityIcon", args = { name } } | |||
local note = stat_notes and stat_notes[name] | |||
if note then | |||
table.insert(ability_parts, ability_cell .. " (" .. note .. ")") | |||
else | |||
table.insert(ability_parts, ability_cell) | |||
end | |||
end | end | ||
table.insert( | table.insert(items, "<li>" .. hero_cell .. ": " .. table.concat(ability_parts, ", ") .. "</li>") | ||
end | end | ||
return disclaimer .. "<ul>" .. table.concat(items) .. "</ul>" | |||
end | |||
-- Normal mode: wikitable with one row per ability and stat-specific columns. | |||
local has_notes_header = false | |||
local final_headers = {} | |||
for _, h in ipairs(headers) do | |||
if h == "Notes" then | |||
has_notes_header = true | |||
elseif not hide_set[h] then | |||
table.insert(final_headers, h) | |||
end | end | ||
end | |||
local needs_notes = (has_notes_header or stat_notes ~= nil) and not hide_set["Notes"] | |||
if needs_notes then table.insert(final_headers, "Notes") end | |||
local out = {} | |||
table.insert(out, disclaimer) | |||
table.insert(out, '{| class="wikitable sortable ability-table"') | |||
local header_row = '! class="ability-table-col-hero" | Hero' | |||
.. ' !! class="ability-table-col-ability" | Ability' | |||
for _, h in ipairs(final_headers) do | |||
header_row = header_row .. ' !! class="ability-table-col-' | |||
.. h:lower():gsub("%s+", "-") .. '" | ' .. h | |||
end | |||
table.insert(out, header_row) | |||
for _, ability in ipairs(filtered) do | |||
local info = key_lookup[ability["Key"]] | |||
local hero_cell | |||
if info then | |||
hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { info.heroName } } | |||
else | |||
hero_cell = "—" | |||
end | |||
local ability_cell = frame:expandTemplate{ title = "AbilityIcon", args = { ability["Name"] } } | |||
local extra = get_cells(ability) | |||
if stat_notes and stat_notes[ability["Name"]] then | |||
local human = stat_notes[ability["Name"]] | |||
extra["Notes"] = extra["Notes"] and (extra["Notes"] .. " " .. human) or human | |||
end | |||
local row = '| class="ability-table-cell-hero" | ' .. hero_cell | |||
.. ' || class="ability-table-cell-ability" | ' .. ability_cell | |||
for _, header in ipairs(final_headers) do | |||
local value = extra[header] | |||
local cls = "ability-table-cell-" .. header:lower():gsub("%s+", "-") | |||
local content | |||
if value ~= nil then | |||
local suffix = column_suffix[header] or "" | |||
content = (type(value) == "string" and value:sub(1,1) == "(") | |||
and value or (value .. suffix) | |||
else | |||
content = "—" | |||
end | end | ||
row = row .. ' || class="' .. cls .. '" | ' .. content | |||
end | |||
table.insert(out, "|-") | |||
table.insert(out, row) | |||
end | end | ||