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
Line 24: Line 24:


local function getPassives()
local function getPassives()
    if not passivesCache then
if not passivesCache then
        passivesCache = GameData.loadPassives()
passivesCache = GameData.loadPassives()
    end
end
    return passivesCache
return passivesCache
end
end


local function getArgs(frame)
local function getArgs(frame)
    local parent = frame:getParent()
local parent = frame:getParent()
    if parent then
if parent then
        return parent.args
return parent.args
    end
end
    return frame.args
return frame.args
end
end


local function listToText(list, sep)
local function listToText(list, sep)
    if type(list) ~= "table" or #list == 0 then
if type(list) ~= "table" or #list == 0 then
        return nil
return nil
    end
end
    return table.concat(list, sep or ", ")
return table.concat(list, sep or ", ")
end
end


-- Tag body rows so we can style/center without touching the hero row
-- Tag body rows so we can style/center without touching the hero rows
local function addRow(tbl, label, value)
local function addRow(tbl, label, value)
    if value == nil or value == "" then
if value == nil or value == "" then
        return
return
    end
end
    local row = tbl:tag("tr")
 
    row:addClass("spiritvale-passive-body-row")
local row = tbl:tag("tr")
    row:tag("th"):wikitext(label):done()
row:addClass("spiritvale-passive-body-row")
    row:tag("td"):wikitext(value):done()
row:tag("th"):wikitext(label):done()
row:tag("td"):wikitext(value):done()
end
end


-- Tag section header rows as body rows too (for centering)
-- 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")
row:addClass("spiritvale-passive-body-row")


    local cell = row:tag("th")
local cell = row:tag("th")
    cell:attr("colspan", 2)
cell:attr("colspan", 2)
    cell:addClass("spiritvale-infobox-section-header")
cell:addClass("spiritvale-infobox-section-header")
    cell:wikitext(label)
cell:wikitext(label)
end
end


-- Lookup by Internal Name
-- Lookup by Internal Name
local function getPassiveById(id)
local function getPassiveById(id)
    if not id or id == "" then
if not id or id == "" then
        return nil
return nil
    end
end
    local dataset = getPassives()
local dataset = getPassives()
    local byId = dataset.byId or {}
local byId = dataset.byId or {}
    return byId[id]
return byId[id]
end
end


-- Lookup by display Name (for editors)
-- Lookup by display Name (for editors)
local function findPassiveByName(name)
local function findPassiveByName(name)
    if not name or name == "" then
if not name or name == "" then
        return nil
return nil
    end
end
    local dataset = getPassives()
local dataset = getPassives()
    for _, rec in ipairs(dataset.records or {}) do
for _, rec in ipairs(dataset.records or {}) do
        if rec["Name"] == name then
if rec["Name"] == name then
            return rec
return rec
        end
end
    end
end
    return nil
return nil
end
end


Line 96: Line 97:


local function asUl(items)
local function asUl(items)
    if type(items) ~= "table" or #items == 0 then
if type(items) ~= "table" or #items == 0 then
        return nil
return nil
    end
end
    return '<ul class="spiritvale-infobox-list"><li>'
return '<ul class="spiritvale-infobox-list"><li>'
        .. table.concat(items, "</li><li>")
.. table.concat(items, "</li><li>")
        .. "</li></ul>"
.. "</li></ul>"
end
end


local function formatBasePer(block)
local function formatBasePer(block)
    if type(block) ~= "table" then
if type(block) ~= "table" then
        return nil
return nil
    end
end
    local parts = {}
local parts = {}
    if block.Base ~= nil then
if block.Base ~= nil then
        table.insert(parts, string.format("Base %s", tostring(block.Base)))
table.insert(parts, string.format("Base %s", tostring(block.Base)))
    end
end
    if block["Per Level"] ~= nil then
if block["Per Level"] ~= nil then
        table.insert(parts, string.format("%s / Lv", tostring(block["Per Level"])))
table.insert(parts, string.format("%s / Lv", tostring(block["Per Level"])))
    end
end
    if #parts == 0 then
if #parts == 0 then
        return nil
return nil
    end
end
    return table.concat(parts, ", ")
return table.concat(parts, ", ")
end
end


-- Passive Effects: return rows (label/value), not a single text blob
-- Passive Effects: return rows (label/value), not a single text blob
local function passiveEffectRows(list)
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 rows = {}


    local rows = {}
for _, eff in ipairs(list) do
if type(eff) == "table" then
local t = eff.Type or {}
local name = t.Name or eff.ID or "Unknown"


    for _, eff in ipairs(list) do
local value = eff.Value or {}
        if type(eff) == "table" then
local detail = {}
            local t = eff.Type or {}
            local name = t.Name or eff.ID or "Unknown"


            local value = eff.Value or {}
if value.Base ~= nil then
            local detail = {}
table.insert(detail, string.format("Base %s", tostring(value.Base)))
end
if value["Per Level"] ~= nil then
table.insert(detail, string.format("%s / Lv", tostring(value["Per Level"])))
end
if value.Expression ~= nil and value.Expression ~= "" then
table.insert(detail, tostring(value.Expression))
end


            if value.Base ~= nil then
-- Optional qualifiers (weapon/stance/etc.), if present in data
                table.insert(detail, string.format("Base %s", tostring(value.Base)))
local qual = eff.Weapon or eff["Weapon"] or eff["Weapon Type"]
            end
or eff.Stance or eff["Stance"] or eff["Stance Type"]
            if value["Per Level"] ~= nil then
                table.insert(detail, string.format("%s / Lv", tostring(value["Per Level"])))
            end
            if value.Expression ~= nil and value.Expression ~= "" then
                table.insert(detail, tostring(value.Expression))
            end


            -- Optional qualifiers (weapon/stance/etc.), if present in data
if type(qual) == "string" and qual ~= "" then
            local qual = eff.Weapon or eff["Weapon"] or eff["Weapon Type"]
table.insert(detail, qual)
                      or eff.Stance or eff["Stance"] or eff["Stance Type"]
end
            if type(qual) == "string" and qual ~= "" then
                table.insert(detail, qual)
            end


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


    return rows
return rows
end
end


local function formatStatusApplications(list)
local function formatStatusApplications(list)
    if type(list) ~= "table" or #list == 0 then
if type(list) ~= "table" or #list == 0 then
        return nil
return nil
    end
end


    local parts = {}
local parts = {}


    for _, s in ipairs(list) do
for _, s in ipairs(list) do
        if type(s) == "table" then
if type(s) == "table" then
            local scope = s.Scope or "Target"
local scope = s.Scope or "Target"
            local name  = s["Status Name"] or s["Status ID"] or "Unknown status"
local name  = s["Status Name"] or s["Status ID"] or "Unknown status"


            local seg = scope .. " – " .. name
local seg = scope .. " – " .. name
            local detail = {}
local detail = {}


            local dur = s.Duration
local dur = s.Duration
            if type(dur) == "table" then
if type(dur) == "table" then
                local t = formatBasePer(dur)
local t = formatBasePer(dur)
                if t then
if t then
                    table.insert(detail, "Duration " .. t)
table.insert(detail, "Duration " .. t)
                end
end
            end
end


            local ch = s.Chance
local ch = s.Chance
            if type(ch) == "table" then
if type(ch) == "table" then
                local t = formatBasePer(ch)
local t = formatBasePer(ch)
                if t then
if t then
                    table.insert(detail, "Chance " .. t)
table.insert(detail, "Chance " .. t)
                end
end
            end
end


            if s["Fixed Duration"] then
if s["Fixed Duration"] then
                table.insert(detail, "Fixed duration")
table.insert(detail, "Fixed duration")
            end
end


            if #detail > 0 then
if #detail > 0 then
                seg = seg .. " (" .. table.concat(detail, ", ") .. ")"
seg = seg .. " (" .. table.concat(detail, ", ") .. ")"
            end
end


            table.insert(parts, seg)
table.insert(parts, seg)
        end
end
    end
end


    return asUl(parts)
return asUl(parts)
end
end


local function formatStatusRemoval(list)
local function formatStatusRemoval(list)
    if type(list) ~= "table" or #list == 0 then
if type(list) ~= "table" or #list == 0 then
        return nil
return nil
    end
end
 
local parts = {}


    local parts = {}
for _, r in ipairs(list) do
    for _, r in ipairs(list) do
if type(r) == "table" then
        if type(r) == "table" then
local names = r["Status Name"]
            local names = r["Status Name"]
local label
            local label
if type(names) == "table" then
            if type(names) == "table" then
label = table.concat(names, ", ")
                label = table.concat(names, ", ")
elseif type(names) == "string" then
            elseif type(names) == "string" then
label = names
                label = names
else
            else
label = "Status"
                label = "Status"
end
            end


            local bp = formatBasePer(r)
local bp = formatBasePer(r)
            local seg = label
local seg = label
            if bp then
if bp then
                seg = seg .. " – " .. bp
seg = seg .. " – " .. bp
            end
end
            table.insert(parts, seg)
table.insert(parts, seg)
        end
end
    end
end


    return asUl(parts)
return asUl(parts)
end
end


local function formatEvents(list)
local function formatEvents(list)
    if type(list) ~= "table" or #list == 0 then
if type(list) ~= "table" or #list == 0 then
        return nil
return nil
    end
end


    local parts = {}
local parts = {}
    for _, ev in ipairs(list) do
for _, ev in ipairs(list) do
        if type(ev) == "table" then
if type(ev) == "table" then
            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))
table.insert(parts, string.format("%s → %s", action, name))
        end
end
    end
end


    return asUl(parts)
return asUl(parts)
end
end


local function formatModifiers(mods)
local function formatModifiers(mods)
    if type(mods) ~= "table" then
if type(mods) ~= "table" then
        return nil
return nil
    end
end


    local parts = {}
local parts = {}


    local function collect(label, sub)
local function collect(label, sub)
        if type(sub) ~= "table" then
if type(sub) ~= "table" then
            return
return
        end
end
        local flags = {}
local flags = {}
        for k, v in pairs(sub) do
for k, v in pairs(sub) do
            if v then
if v then
                table.insert(flags, k)
table.insert(flags, k)
            end
end
        end
end
        table.sort(flags)
table.sort(flags)
        if #flags > 0 then
if #flags > 0 then
            table.insert(parts, string.format("%s: %s", label, table.concat(flags, ", ")))
table.insert(parts, string.format("%s: %s", label, table.concat(flags, ", ")))
        end
end
    end
end


    collect("Movement", mods["Movement Modifiers"])
collect("Movement", mods["Movement Modifiers"])
    collect("Combat",  mods["Combat Modifiers"])
collect("Combat",  mods["Combat Modifiers"])
    collect("Special",  mods["Special Modifiers"])
collect("Special",  mods["Special Modifiers"])


    return asUl(parts)
return asUl(parts)
end
end


Line 290: Line 293:


local function passiveMatchesUser(rec, userName)
local function passiveMatchesUser(rec, userName)
    if type(rec) ~= "table" or not userName or userName == "" then
if type(rec) ~= "table" or not userName or userName == "" then
        return false
return false
    end
end


    local users = rec.Users
local users = rec.Users
    if type(users) ~= "table" then
if type(users) ~= "table" then
        return false
return false
    end
end


    local userLower = mw.ustring.lower(userName)
local userLower = mw.ustring.lower(userName)


    local function listHas(list)
local function listHas(list)
        if type(list) ~= "table" then
if type(list) ~= "table" then
            return false
return false
        end
end
        for _, v in ipairs(list) do
for _, v in ipairs(list) do
            if type(v) == "string" and mw.ustring.lower(v) == userLower then
if type(v) == "string" and mw.ustring.lower(v) == userLower then
                return true
return true
            end
end
        end
end
        return false
return false
    end
end


    if listHas(users.Classes)  then return true end
if listHas(users.Classes)  then return true end
    if listHas(users.Summons)  then return true end
if listHas(users.Summons)  then return true end
    if listHas(users.Monsters) then return true end
if listHas(users.Monsters) then return true end
    if listHas(users.Events)  then return true end
if listHas(users.Events)  then return true end


    return false
return false
end
end


Line 326: Line 329:


local function buildInfobox(rec)
local function buildInfobox(rec)
    local root = mw.html.create("table")
local root = mw.html.create("table")
    root:addClass("spiritvale-passive-infobox")
root:addClass("spiritvale-passive-infobox")
 
    -- ==========================================================
    -- Top "hero" rows: title row (icon + name), then description row
    -- (Matches the Skill infobox style)
    -- ==========================================================
    local icon  = rec.Icon
    local title = rec.Name or rec["Internal Name"] or "Unknown Passive"
    local desc  = rec.Description or ""


    -- Row 1: centered icon + title (single cell)
-- ==========================================================
    local titleRow = root:tag("tr")
-- Top "hero" rows: title row (icon + name), then description row
    titleRow:addClass("spiritvale-infobox-main")
-- ==========================================================
    titleRow:addClass("sv-hero-title-row")
local icon  = rec.Icon
local title = rec.Name or rec["Internal Name"] or "Unknown Passive"
local desc  = rec.Description or ""


    local titleCell = titleRow:tag("th")
-- Row 1: centered icon + title (single cell)
    titleCell:attr("colspan", 2)
local titleRow = root:tag("tr")
titleRow:addClass("spiritvale-infobox-main")
titleRow:addClass("sv-hero-title-row")


    local titleInner = titleCell:tag("div")
local titleCell = titleRow:tag("th")
    titleInner:addClass("spiritvale-infobox-main-left-inner")
titleCell:attr("colspan", 2)


    if icon and icon ~= "" then
local titleInner = titleCell:tag("div")
        titleInner:wikitext(string.format("[[File:%s|80px|link=]]", icon))
titleInner:addClass("spiritvale-infobox-main-left-inner")
    end


    titleInner:tag("div")
if icon and icon ~= "" then
        :addClass("spiritvale-infobox-title")
titleInner:wikitext(string.format("[[File:%s|80px|link=]]", icon))
        :wikitext(title)
end


    -- Row 2: description (single cell)
titleInner:tag("div")
    if desc ~= "" then
:addClass("spiritvale-infobox-title")
        local descRow = root:tag("tr")
:wikitext(title)
        descRow:addClass("spiritvale-infobox-main")
        descRow:addClass("sv-hero-desc-row")


        local descCell = descRow:tag("td")
-- Row 2: description (single cell)
        descCell:attr("colspan", 2)
if desc ~= "" then
local descRow = root:tag("tr")
descRow:addClass("spiritvale-infobox-main")
descRow:addClass("sv-hero-desc-row")


        local descInner = descCell:tag("div")
local descCell = descRow:tag("td")
        descInner:addClass("spiritvale-infobox-main-right-inner")
descCell:attr("colspan", 2)


        descInner:tag("div")
local descInner = descCell:tag("div")
            :addClass("spiritvale-infobox-description")
descInner:addClass("spiritvale-infobox-main-right-inner")
            :wikitext(string.format("''%s''", desc))
    end


    ------------------------------------------------------------------
-- Use <i> to avoid apostrophes breaking ''...'' formatting
    -- General
local d = descInner:tag("div")
    ------------------------------------------------------------------
d:addClass("spiritvale-infobox-description")
    addSectionHeader(root, "General")
d:tag("i"):wikitext(desc)
end


    addRow(root, "Max Level", rec["Max Level"] and tostring(rec["Max Level"]))
------------------------------------------------------------------
-- General
------------------------------------------------------------------
addSectionHeader(root, "General")
addRow(root, "Max Level", rec["Max Level"] and tostring(rec["Max Level"]))


    -- Classes intentionally removed (template is used on class pages)
-- 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))
    addRow(root, "Events",  listToText(users.Events))
addRow(root, "Events",  listToText(users.Events))


    ------------------------------------------------------------------
------------------------------------------------------------------
    -- 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)
        or (req["Required Weapons"] and #req["Required Weapons"] > 0)
or (req["Required Weapons"] and #req["Required Weapons"] > 0)
        or (req["Required Stances"] and #req["Required Stances"] > 0) then
or (req["Required Stances"] and #req["Required Stances"] > 0) then


        addSectionHeader(root, "Requirements")
addSectionHeader(root, "Requirements")


        if type(req["Required Skills"]) == "table" and #req["Required Skills"] > 0 then
if type(req["Required Skills"]) == "table" and #req["Required Skills"] > 0 then
            local skillParts = {}
local skillParts = {}
            for _, rs in ipairs(req["Required Skills"]) do
for _, rs in ipairs(req["Required Skills"]) do
                local name  = rs["Skill Name"] or rs["Skill ID"] or "Unknown"
local sname = rs["Skill Name"] or rs["Skill ID"] or "Unknown"
                local level = rs["Required Level"]
local level = rs["Required Level"]
                if level then
if level then
                    table.insert(skillParts, string.format("%s (Lv.%s)", name, level))
table.insert(skillParts, string.format("%s (Lv.%s)", sname, level))
                else
else
                    table.insert(skillParts, name)
table.insert(skillParts, sname)
                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 (one row per effect)
-- Passive Effects (one row per effect)
    ------------------------------------------------------------------
------------------------------------------------------------------
    local peRows = passiveEffectRows(rec["Passive Effects"])
local peRows = passiveEffectRows(rec["Passive Effects"])
    if #peRows > 0 then
if #peRows > 0 then
        addSectionHeader(root, "Passive Effects")
addSectionHeader(root, "Passive Effects")
        for _, r in ipairs(peRows) do
for _, r in ipairs(peRows) do
            addRow(root, r.label, r.value)
addRow(root, r.label, r.value)
        end
end
    end
end


    ------------------------------------------------------------------
------------------------------------------------------------------
    -- Status Effects
-- Status Effects
    ------------------------------------------------------------------
------------------------------------------------------------------
    local statusApps = formatStatusApplications(rec["Status Applications"])
local statusApps = formatStatusApplications(rec["Status Applications"])
    local statusRem  = formatStatusRemoval(rec["Status Removal"])
local statusRem  = formatStatusRemoval(rec["Status Removal"])
    if statusApps or statusRem then
if statusApps or statusRem then
        addSectionHeader(root, "Status Effects")
addSectionHeader(root, "Status Effects")
        addRow(root, "Applies", statusApps)
addRow(root, "Applies", statusApps)
        addRow(root, "Removes", statusRem)
addRow(root, "Removes", statusRem)
    end
end


    ------------------------------------------------------------------
------------------------------------------------------------------
    -- Modifiers
-- Modifiers
    ------------------------------------------------------------------
------------------------------------------------------------------
    local modsText = formatModifiers(rec.Modifiers)
local modsText = formatModifiers(rec.Modifiers)
    if modsText then
if modsText then
        addSectionHeader(root, "Modifiers")
addSectionHeader(root, "Modifiers")
        addRow(root, "Flags", modsText)
addRow(root, "Flags", modsText)
    end
end


    ------------------------------------------------------------------
------------------------------------------------------------------
    -- Events
-- Events
    ------------------------------------------------------------------
------------------------------------------------------------------
    local eventsText = formatEvents(rec.Events)
local eventsText = formatEvents(rec.Events)
    if eventsText then
if eventsText then
        addSectionHeader(root, "Events")
addSectionHeader(root, "Events")
        addRow(root, "Triggers", eventsText)
addRow(root, "Triggers", eventsText)
    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")
        addRow(root, "Notes", asUl(rec.Notes) or 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
end


Line 470: Line 472:


function p.listForUser(frame)
function p.listForUser(frame)
    local args = getArgs(frame)
local args = getArgs(frame)


    -- Prefer explicit param, then unnamed, then fall back to the current page name.
-- Prefer explicit param, then unnamed, then fall back to the current page name.
    local userName = args.user or args[1]
local userName = args.user or args[1]
    if not userName or userName == "" then
if not userName or userName == "" then
        userName = mw.title.getCurrentTitle().text
userName = mw.title.getCurrentTitle().text
    end
end


    if not userName or userName == "" then
if not userName or userName == "" then
        return "<strong>No user name provided to Passive list.</strong>"
return "<strong>No user name provided to Passive list.</strong>"
    end
end


    local dataset = getPassives()
local dataset = getPassives()
    local matches = {}
local matches = {}


    for _, rec in ipairs(dataset.records or {}) do
for _, rec in ipairs(dataset.records or {}) do
        if passiveMatchesUser(rec, userName) then
if passiveMatchesUser(rec, userName) then
            table.insert(matches, rec)
table.insert(matches, rec)
        end
end
    end
end


    if #matches == 0 then
if #matches == 0 then
        return string.format(
return string.format(
            "<strong>No passives found for:</strong> %s",
"<strong>No passives found for:</strong> %s",
            mw.text.nowiki(userName)
mw.text.nowiki(userName)
        )
)
    end
end


    local root = mw.html.create("div")
local root = mw.html.create("div")
    root:addClass("spiritvale-passive-list")
root:addClass("spiritvale-passive-list")


    for _, rec in ipairs(matches) do
for _, rec in ipairs(matches) do
        root:wikitext(buildInfobox(rec))
root:wikitext(buildInfobox(rec))
    end
end


    return tostring(root)
return tostring(root)
end
end


Line 513: Line 515:


function p.infobox(frame)
function p.infobox(frame)
    local args = getArgs(frame)
local args = getArgs(frame)


    local raw1 = args[1]
local raw1 = args[1]
    local name = args.name or raw1
local name = args.name or raw1
    local id  = args.id
local id  = args.id


    local rec
local rec


    -- 1) Prefer display Name
-- 1) Prefer display Name
    if name and name ~= "" then
if name and name ~= "" then
        rec = findPassiveByName(name)
rec = findPassiveByName(name)
    end
end


    -- 2) Fallback: internal ID
-- 2) Fallback: internal ID
    if not rec and id and id ~= "" then
if not rec and id and id ~= "" then
        rec = getPassiveById(id)
rec = getPassiveById(id)
    end
end


    -- 3) If still nothing, decide if this is "list mode" or truly unknown.
-- 3) If still nothing, decide if this is "list mode" or truly unknown.
    if not rec then
if not rec then
        local pageTitle = mw.title.getCurrentTitle()
local pageTitle = mw.title.getCurrentTitle()
        local pageName  = pageTitle and pageTitle.text or ""
local pageName  = pageTitle and pageTitle.text or ""


        local noExplicitArgs =
local noExplicitArgs =
            (not raw1 or raw1 == "") and
(not raw1 or raw1 == "") and
            (not args.name or args.name == "") and
(not args.name or args.name == "") and
            (not id or id == "")
(not id or id == "")


        if noExplicitArgs then
if noExplicitArgs then
            return p.listForUser(frame)
return p.listForUser(frame)
        end
end


        if name and name ~= "" and name == pageName and (not id or id == "") then
if name and name ~= "" and name == pageName and (not id or id == "") then
            return p.listForUser(frame)
return p.listForUser(frame)
        end
end


        local label = name or id or "?"
local label = name or id or "?"
        return string.format(
return string.format(
            "<strong>Unknown passive:</strong> %s[[Category:Pages with unknown passive|%s]]",
"<strong>Unknown passive:</strong> %s[[Category:Pages with unknown passive|%s]]",
            mw.text.nowiki(label),
mw.text.nowiki(label),
            label
label
        )
)
    end
end


    return buildInfobox(rec)
return buildInfobox(rec)
end
end


return p
return p