Module:GamePassives: Difference between revisions
From SpiritVale Wiki
More actions
No edit summary |
No edit summary |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 45: | Line 45: | ||
end | end | ||
-- Tag body rows so we can style/center without touching the hero row | |||
local function addRow(tbl, label, value) | local function addRow(tbl, label, value) | ||
if value == nil or value == "" then | if value == nil or value == "" then | ||
| Line 50: | Line 51: | ||
end | end | ||
local row = tbl:tag("tr") | local row = tbl:tag("tr") | ||
row:addClass("spiritvale-passive-body-row") | |||
row:tag("th"):wikitext(label):done() | row:tag("th"):wikitext(label):done() | ||
row:tag("td"):wikitext(value):done() | row:tag("td"):wikitext(value):done() | ||
end | end | ||
-- Tag section header rows as body rows too (for centering) | |||
local function addSectionHeader(tbl, label) | local function addSectionHeader(tbl, label) | ||
local row = tbl:tag("tr") | local row = tbl:tag("tr") | ||
row:addClass("spiritvale-passive-body-row") | |||
local cell = row:tag("th") | local cell = row:tag("th") | ||
cell:attr("colspan", 2) | cell:attr("colspan", 2) | ||
| Line 89: | Line 94: | ||
-- Formatting helpers | -- Formatting helpers | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||
local function asUl(items) | |||
if type(items) ~= "table" or #items == 0 then | |||
return nil | |||
end | |||
return '<ul class="spiritvale-infobox-list"><li>' | |||
.. table.concat(items, "</li><li>") | |||
.. "</li></ul>" | |||
end | |||
local function formatBasePer(block) | local function formatBasePer(block) | ||
| Line 107: | Line 121: | ||
end | end | ||
local function | -- Passive Effects: return rows (label/value), not a single text blob | ||
local function passiveEffectRows(list) | |||
if type(list) ~= "table" or #list == 0 then | if type(list) ~= "table" or #list == 0 then | ||
return | return {} | ||
end | end | ||
local | local rows = {} | ||
for _, eff in ipairs(list) do | for _, eff in ipairs(list) do | ||
| Line 118: | Line 133: | ||
local t = eff.Type or {} | local t = eff.Type or {} | ||
local name = t.Name or eff.ID or "Unknown" | local name = t.Name or eff.ID or "Unknown" | ||
local value = eff.Value or {} | local value = eff.Value or {} | ||
local detail = {} | local detail = {} | ||
| Line 132: | Line 147: | ||
end | end | ||
local | -- Optional qualifiers (weapon/stance/etc.), if present in data | ||
if | local qual = eff.Weapon or eff["Weapon"] or eff["Weapon Type"] | ||
or eff.Stance or eff["Stance"] or eff["Stance Type"] | |||
if type(qual) == "string" and qual ~= "" then | |||
table.insert(detail, qual) | |||
end | end | ||
table.insert( | local right = (#detail > 0) and table.concat(detail, ", ") or "—" | ||
table.insert(rows, { label = name, value = right }) | |||
end | end | ||
end | end | ||
return rows | |||
end | end | ||
| Line 192: | Line 205: | ||
end | end | ||
return asUl(parts) | |||
return | |||
end | end | ||
| Line 226: | Line 235: | ||
end | end | ||
return asUl(parts) | |||
return | |||
end | end | ||
| Line 243: | Line 248: | ||
local action = ev.Action or "On event" | local action = ev.Action or "On event" | ||
local name = ev["Skill Name"] or ev["Skill ID"] or "Unknown skill" | local name = ev["Skill Name"] or ev["Skill ID"] or "Unknown skill" | ||
table.insert(parts, string.format("%s → %s", action, name)) | |||
end | end | ||
end | end | ||
return asUl(parts) | |||
return | |||
end | end | ||
| Line 282: | Line 282: | ||
collect("Special", mods["Special Modifiers"]) | collect("Special", mods["Special Modifiers"]) | ||
return asUl(parts) | |||
return | |||
end | end | ||
| Line 331: | Line 327: | ||
local function buildInfobox(rec) | local function buildInfobox(rec) | ||
local root = mw.html.create("table") | local root = mw.html.create("table") | ||
root:addClass(" | root:addClass("spiritvale-passive-infobox") | ||
-- ========================================================== | -- ========================================================== | ||
| Line 376: | Line 372: | ||
addSectionHeader(root, "General") | addSectionHeader(root, "General") | ||
addRow(root, "Max Level", rec["Max Level"] and tostring(rec["Max Level"])) | |||
addRow(root, "Max | |||
-- Classes intentionally removed (template is used on class pages) | |||
local users = rec.Users or {} | local users = rec.Users or {} | ||
addRow(root, "Summons", listToText(users.Summons)) | addRow(root, "Summons", listToText(users.Summons)) | ||
addRow(root, "Monsters", listToText(users.Monsters)) | addRow(root, "Monsters", listToText(users.Monsters)) | ||
| Line 408: | Line 401: | ||
end | end | ||
end | end | ||
addRow(root, "Required | addRow(root, "Required Skills", table.concat(skillParts, ", ")) | ||
end | end | ||
addRow(root, "Required | addRow(root, "Required Weapons", listToText(req["Required Weapons"])) | ||
addRow(root, "Required | addRow(root, "Required Stances", listToText(req["Required Stances"])) | ||
end | end | ||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
-- Passive | -- Passive Effects (one row per effect) | ||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
local | local peRows = passiveEffectRows(rec["Passive Effects"]) | ||
if | if #peRows > 0 then | ||
addSectionHeader(root, "Passive | addSectionHeader(root, "Passive Effects") | ||
addRow(root, "Effects", | for _, r in ipairs(peRows) do | ||
addRow(root, r.label, r.value) | |||
end | |||
end | |||
------------------------------------------------------------------ | |||
-- Status Effects | |||
------------------------------------------------------------------ | |||
local statusApps = formatStatusApplications(rec["Status Applications"]) | |||
local statusRem = formatStatusRemoval(rec["Status Removal"]) | |||
if statusApps or statusRem then | |||
addSectionHeader(root, "Status Effects") | |||
addRow(root, "Applies", statusApps) | |||
addRow(root, "Removes", statusRem) | |||
end | end | ||
| Line 431: | Line 437: | ||
addSectionHeader(root, "Modifiers") | addSectionHeader(root, "Modifiers") | ||
addRow(root, "Flags", modsText) | addRow(root, "Flags", modsText) | ||
end | end | ||
| Line 458: | Line 453: | ||
if type(rec.Notes) == "table" and #rec.Notes > 0 then | if type(rec.Notes) == "table" and #rec.Notes > 0 then | ||
addSectionHeader(root, "Notes") | addSectionHeader(root, "Notes") | ||
addRow(root, "Notes", table.concat(rec.Notes, "<br />")) | addRow(root, "Notes", asUl(rec.Notes) or table.concat(rec.Notes, "<br />")) | ||
end | end | ||
return tostring(root) | return tostring(root) | ||
end | |||
---------------------------------------------------------------------- | |||
-- Public: list all passives for a given user/class | |||
---------------------------------------------------------------------- | |||
function p.listForUser(frame) | |||
local args = getArgs(frame) | |||
-- Prefer explicit param, then unnamed, then fall back to the current page name. | |||
local userName = args.user or args[1] | |||
if not userName or userName == "" then | |||
userName = mw.title.getCurrentTitle().text | |||
end | |||
if not userName or userName == "" then | |||
return "<strong>No user name provided to Passive list.</strong>" | |||
end | |||
local dataset = getPassives() | |||
local matches = {} | |||
for _, rec in ipairs(dataset.records or {}) do | |||
if passiveMatchesUser(rec, userName) then | |||
table.insert(matches, rec) | |||
end | |||
end | |||
if #matches == 0 then | |||
return string.format( | |||
"<strong>No passives found for:</strong> %s", | |||
mw.text.nowiki(userName) | |||
) | |||
end | |||
local root = mw.html.create("div") | |||
root:addClass("spiritvale-passive-list") | |||
for _, rec in ipairs(matches) do | |||
root:wikitext(buildInfobox(rec)) | |||
end | |||
return tostring(root) | |||
end | |||
---------------------------------------------------------------------- | |||
-- Public: single-passive or auto-list dispatcher | |||
---------------------------------------------------------------------- | |||
function p.infobox(frame) | |||
local args = getArgs(frame) | |||
local raw1 = args[1] | |||
local name = args.name or raw1 | |||
local id = args.id | |||
local rec | |||
-- 1) Prefer display Name | |||
if name and name ~= "" then | |||
rec = findPassiveByName(name) | |||
end | |||
-- 2) Fallback: internal ID | |||
if not rec and id and id ~= "" then | |||
rec = getPassiveById(id) | |||
end | |||
-- 3) If still nothing, decide if this is "list mode" or truly unknown. | |||
if not rec then | |||
local pageTitle = mw.title.getCurrentTitle() | |||
local pageName = pageTitle and pageTitle.text or "" | |||
local noExplicitArgs = | |||
(not raw1 or raw1 == "") and | |||
(not args.name or args.name == "") and | |||
(not id or id == "") | |||
if noExplicitArgs then | |||
return p.listForUser(frame) | |||
end | |||
if name and name ~= "" and name == pageName and (not id or id == "") then | |||
return p.listForUser(frame) | |||
end | |||
local label = name or id or "?" | |||
return string.format( | |||
"<strong>Unknown passive:</strong> %s[[Category:Pages with unknown passive|%s]]", | |||
mw.text.nowiki(label), | |||
label | |||
) | |||
end | |||
return buildInfobox(rec) | |||
end | end | ||
return p | return p | ||