Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Join the Playtest on Steam Now: SpiritVale

Module:GamePassives: Difference between revisions

From SpiritVale Wiki
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 formatPassiveEffects(list)
-- 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 nil
         return {}
     end
     end


     local parts = {}
     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 seg = name
            -- Optional qualifiers (weapon/stance/etc.), if present in data
             if #detail > 0 then
             local qual = eff.Weapon or eff["Weapon"] or eff["Weapon Type"]
                 seg = seg -- name
                      or eff.Stance or eff["Stance"] or eff["Stance Type"]
                    .. " – " .. table.concat(detail, ", ")
             if type(qual) == "string" and qual ~= "" then
                 table.insert(detail, qual)
             end
             end


             table.insert(parts, seg)
            local right = (#detail > 0) and table.concat(detail, ", ") or "—"
             table.insert(rows, { label = name, value = right })
         end
         end
     end
     end


     if #parts == 0 then
     return rows
        return nil
    end
 
    return table.concat(parts, "<br />")
end
end


Line 192: Line 205:
     end
     end


    if #parts == 0 then
     return asUl(parts)
        return nil
    end
 
     return table.concat(parts, "<br />")
end
end


Line 226: Line 235:
     end
     end


    if #parts == 0 then
     return asUl(parts)
        return nil
    end
 
     return table.concat(parts, "<br />")
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"
             local seg    = string.format("%s → %s", action, name)
             table.insert(parts, string.format("%s → %s", action, name))
            table.insert(parts, seg)
         end
         end
     end
     end


    if #parts == 0 then
     return asUl(parts)
        return nil
    end
 
     return table.concat(parts, "<br />")
end
end


Line 282: Line 282:
     collect("Special",  mods["Special Modifiers"])
     collect("Special",  mods["Special Modifiers"])


    if #parts == 0 then
     return asUl(parts)
        return nil
    end
 
     return table.concat(parts, "<br />")
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("wikitable spiritvale-passive-infobox")
     root:addClass("spiritvale-passive-infobox")


     -- ==========================================================
     -- ==========================================================
Line 376: Line 372:
     addSectionHeader(root, "General")
     addSectionHeader(root, "General")


    -- Description is now in the hero row; don't repeat it here.
     addRow(root, "Max Level", rec["Max Level"] and tostring(rec["Max Level"]))
    -- addRow(root, "Description", rec.Description)
 
     addRow(root, "Max level", rec["Max Level"] and tostring(rec["Max Level"]))


    -- Classes intentionally removed (template is used on class pages)
     local users = rec.Users or {}
     local users = rec.Users or {}
    addRow(root, "Classes",  listToText(users.Classes))
     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 skills", table.concat(skillParts, ", "))
             addRow(root, "Required Skills", table.concat(skillParts, ", "))
         end
         end


         addRow(root, "Required weapons", listToText(req["Required Weapons"]))
         addRow(root, "Required Weapons", listToText(req["Required Weapons"]))
         addRow(root, "Required stances", listToText(req["Required Stances"]))
         addRow(root, "Required Stances", listToText(req["Required Stances"]))
     end
     end


     ------------------------------------------------------------------
     ------------------------------------------------------------------
     -- Passive effects
     -- Passive Effects (one row per effect)
     ------------------------------------------------------------------
     ------------------------------------------------------------------
     local peText = formatPassiveEffects(rec["Passive Effects"])
     local peRows = passiveEffectRows(rec["Passive Effects"])
     if peText then
     if #peRows > 0 then
         addSectionHeader(root, "Passive effects")
         addSectionHeader(root, "Passive Effects")
         addRow(root, "Effects", peText)
         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
    ------------------------------------------------------------------
    -- Status
    ------------------------------------------------------------------
    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 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