Module:GameSkills: Difference between revisions
From SpiritVale Wiki
More actions
No edit summary |
No edit summary |
||
| Line 6: | Line 6: | ||
-- - Adds .sv-skill-card + data-max-level / data-level hooks for JS | -- - Adds .sv-skill-card + data-max-level / data-level hooks for JS | ||
-- - Replaces large Lv1/Lv2/... lists with data-series dynamic spans | -- - Replaces large Lv1/Lv2/... lists with data-series dynamic spans | ||
-- - NEW: Removes "General" + "Type" section bars and merges Level Select + Type into one unified top band | |||
-- (Level Select on the left; Type/Element/Target/Cast Type list on the right) | |||
-- | -- | ||
-- Requires the JS you installed in MediaWiki:Common.js. | -- Requires the JS you installed in MediaWiki:Common.js. | ||
| Line 543: | Line 545: | ||
end | end | ||
-- | -- Special Mechanics supports dynamic Per Level lists | ||
local function formatMechanicEffects(effects, maxLevel, level) | local function formatMechanicEffects(effects, maxLevel, level) | ||
if type(effects) ~= "table" then | if type(effects) ~= "table" then | ||
| Line 557: | Line 559: | ||
local parts = {} | local parts = {} | ||
local function effectAmount(block) | local function effectAmount(block) | ||
if type(block) ~= "table" then | if type(block) ~= "table" then | ||
| Line 565: | Line 566: | ||
local per = block["Per Level"] | local per = block["Per Level"] | ||
if type(per) == "table" and #per > 0 then | if type(per) == "table" and #per > 0 then | ||
if isFlatList(per) then | if isFlatList(per) then | ||
| Line 577: | Line 577: | ||
end | end | ||
local pair = { Base = block.Base, ["Per Level"] = block["Per Level"] } | local pair = { Base = block.Base, ["Per Level"] = block["Per Level"] } | ||
local txt = valuePairRawText(pair) | local txt = valuePairRawText(pair) | ||
| Line 588: | Line 587: | ||
local t = block.Type | local t = block.Type | ||
if t ~= nil and tostring(t) ~= "" then | if t ~= nil and tostring(t) ~= "" then | ||
local amt = effectAmount(block) | local amt = effectAmount(block) | ||
| Line 596: | Line 594: | ||
end | end | ||
table.insert(parts, seg) | table.insert(parts, seg) | ||
else | else | ||
local txt = valuePairDynamicText(name, block, maxLevel, level, ", ") | local txt = valuePairDynamicText(name, block, maxLevel, level, ", ") | ||
| Line 703: | Line 699: | ||
local amt = nil | local amt = nil | ||
if type(r["Per Level"]) == "table" and #r["Per Level"] > 0 and not isFlatList(r["Per Level"]) then | if type(r["Per Level"]) == "table" and #r["Per Level"] > 0 and not isFlatList(r["Per Level"]) then | ||
local series = {} | local series = {} | ||
| Line 812: | Line 807: | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||
-- Infobox builder | -- Infobox builder (Top band: Level Select + Type) | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||
local function buildLevelSelectUI(level, maxLevel) | local function buildLevelSelectUI(level, maxLevel) | ||
-- | -- JS expectations: | ||
-- .sv-level-slider placeholder for the <input type="range"> | -- .sv-level-slider placeholder for the <input type="range"> | ||
-- .sv-level-num span for updating the number | -- .sv-level-num span for updating the number | ||
local wrap = mw.html.create("div") | local wrap = mw.html.create("div") | ||
wrap:addClass("sv-level-ui") | wrap:addClass("sv-level-ui") | ||
wrap:addClass("sv-level-box") | |||
local | -- Top box (label + current level) | ||
label:wikitext("Level <span class=\"sv-level-num\">" .. tostring(level) .. "</span> / " .. tostring(maxLevel)) | local top = wrap:tag("div"):addClass("sv-level-top") | ||
top:tag("div"):addClass("sv-level-title"):wikitext("Level Select") | |||
top:tag("div"):addClass("sv-level-label") | |||
:wikitext("Level <span class=\"sv-level-num\">" .. tostring(level) .. "</span> / " .. tostring(maxLevel)) | |||
-- Bottom box (slider placeholder) | |||
wrap:tag("div"):addClass("sv-level-bottom") | |||
:tag("div"):addClass("sv-level-slider") | |||
return tostring(wrap) | return tostring(wrap) | ||
end | |||
local function buildTypeListUI(typeBlock) | |||
if type(typeBlock) ~= "table" or next(typeBlock) == nil then | |||
return nil | |||
end | |||
local wrap = mw.html.create("div") | |||
wrap:addClass("sv-type-box") | |||
local function addItem(label, value) | |||
if not value or value == "" then return end | |||
local row = wrap:tag("div"):addClass("sv-type-row") | |||
row:tag("span"):addClass("sv-type-key"):wikitext(mw.text.nowiki(label)) | |||
row:tag("span"):addClass("sv-type-val"):wikitext(mw.text.nowiki(value)) | |||
end | |||
local dt = typeBlock["Damage Type"] | |||
if type(dt) == "table" and dt.Name then | |||
addItem("Type", dt.Name) -- renamed from "Damage Type" | |||
end | |||
local et = typeBlock["Element Type"] | |||
if type(et) == "table" and et.Name then | |||
addItem("Element", et.Name) | |||
end | |||
local tt = typeBlock["Target Type"] | |||
if type(tt) == "table" and tt.Name then | |||
addItem("Target", tt.Name) | |||
end | |||
local ct = typeBlock["Cast Type"] | |||
if type(ct) == "table" and ct.Name then | |||
addItem("Cast Type", ct.Name) | |||
end | |||
-- If nothing was added, return nil | |||
if not wrap or tostring(wrap) == "" then | |||
return nil | |||
end | |||
return tostring(wrap) | |||
end | |||
local function addTopBand(tbl, levelUI, typeUI) | |||
-- One row (colspan=2) that *contains* a 2-column grid: | |||
-- - left: level select (top text + bottom slider) | |||
-- - right: type list (label/value pairs) | |||
if not levelUI and not typeUI then | |||
return | |||
end | |||
local row = tbl:tag("tr") | |||
local cell = row:tag("td") | |||
cell:attr("colspan", 2) | |||
cell:addClass("sv-topband-cell") | |||
local wrap = cell:tag("div") | |||
wrap:addClass("sv-skill-topband") | |||
local left = wrap:tag("div"):addClass("sv-topband-left") | |||
left:wikitext(levelUI or "") | |||
local right = wrap:tag("div"):addClass("sv-topband-right") | |||
right:wikitext(typeUI or "") | |||
-- Styling is handled via Common.css (recommended). | |||
end | end | ||
| Line 881: | Line 950: | ||
end | end | ||
-- | ------------------------------------------------------------------ | ||
-- NEW: Unified top band (replaces "General" + "Type" section bars) | |||
------------------------------------------------------------------ | |||
local typeUI = buildTypeListUI(rec.Type or {}) | |||
local levelUI = buildLevelSelectUI(level, maxLevel) | |||
addTopBand(root, levelUI, typeUI) | |||
------------------------------------------------------------------ | |||
-- Users (kept as rows, but no "General" header) | |||
------------------------------------------------------------------ | |||
if showUsers then | if showUsers then | ||
local users = rec.Users or {} | local users = rec.Users or {} | ||
| Line 893: | Line 968: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Requirements | -- Requirements | ||
------------------------------------------------------------------ | |||
local req = rec.Requirements or {} | local req = rec.Requirements or {} | ||
if (req["Required Skills"] and #req["Required Skills"] > 0) | if (req["Required Skills"] and #req["Required Skills"] > 0) | ||
| Line 919: | Line 996: | ||
end | end | ||
-- | ------------------------------------------------------------------ | ||
-- Mechanics | -- Mechanics | ||
------------------------------------------------------------------ | |||
local mech = rec.Mechanics or {} | local mech = rec.Mechanics or {} | ||
if next(mech) ~= nil then | if next(mech) ~= nil then | ||
| Line 951: | Line 1,004: | ||
addRow(root, "Range", formatUnitValue(mech.Range)) | addRow(root, "Range", formatUnitValue(mech.Range)) | ||
addRow(root, "Area", formatArea(mech.Area, maxLevel, level)) | addRow(root, "Area", formatArea(mech.Area, maxLevel, level)) | ||
| Line 959: | Line 1,011: | ||
addRow(root, "Timing", formatTimingBlock(mech["Basic Timings"], maxLevel, level)) | addRow(root, "Timing", formatTimingBlock(mech["Basic Timings"], maxLevel, level)) | ||
addRow(root, "Resource Cost", formatResourceCost(mech["Resource Cost"], maxLevel, level)) | addRow(root, "Resource Cost", formatResourceCost(mech["Resource Cost"], maxLevel, level)) | ||
addRow(root, "Combo", formatCombo(mech.Combo)) | addRow(root, "Combo", formatCombo(mech.Combo)) | ||
| Line 968: | Line 1,018: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Damage & Scaling | -- Damage & Scaling | ||
------------------------------------------------------------------ | |||
local dmg = rec.Damage or {} | local dmg = rec.Damage or {} | ||
if next(dmg) ~= nil then | if next(dmg) ~= nil then | ||
| Line 1,002: | Line 1,054: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Modifiers | -- Modifiers | ||
------------------------------------------------------------------ | |||
local modsText = formatModifiers(rec.Modifiers) | local modsText = formatModifiers(rec.Modifiers) | ||
if modsText then | if modsText then | ||
| Line 1,009: | Line 1,063: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Status | -- Status | ||
------------------------------------------------------------------ | |||
local statusApps = formatStatusApplications(rec["Status Applications"], maxLevel, level) | local statusApps = formatStatusApplications(rec["Status Applications"], maxLevel, level) | ||
local statusRem = formatStatusRemoval(rec["Status Removal"], maxLevel, level) | local statusRem = formatStatusRemoval(rec["Status Removal"], maxLevel, level) | ||
| Line 1,018: | Line 1,074: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Events | -- Events | ||
------------------------------------------------------------------ | |||
local eventsText = formatEvents(rec.Events) | local eventsText = formatEvents(rec.Events) | ||
if eventsText then | if eventsText then | ||
| Line 1,025: | Line 1,083: | ||
end | end | ||
------------------------------------------------------------------ | |||
-- Notes | -- Notes | ||
------------------------------------------------------------------ | |||
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") | ||