Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 19:43, 12 August 2025 by Gpe (talk | contribs) (// via Wikitext Extension for VSCode)

Documentation for this module may be created at Module:C/doc

local p = {}

local function makeBar(frame, title, content, link, flags, bottom)
    if content == '' then return '' end
    local barSpace = mw.html.create('span')
    barSpace:wikitext(frame:preprocess(' ')):css('display', 'none')
    local barTitle = mw.html.create('span')
    local barTitleClass = "{{lc:" .. title .. "}}"
    barTitleClass = barTitleClass:gsub(' ', '-')
    barTitleClass = barTitleClass:gsub('\'', '')
    barTitleClass = barTitleClass:gsub('\"', '')
    local barText = "{{ucfirst:" .. title .. "}}"
    if link then barText = "[[" .. link .. "|" .. barText .. "]]" end
    barText = barText .. ":"
    barTitle:addClass('ability-bar-title'):wikitext(frame:preprocess(barText))
        :css('font-weight', 'bold'):css('margin-right', '0.5em')
    local barContent = mw.html.create('span')
    barContent:addClass('ability-bar-content'):wikitext(content)
    local output = mw.html.create('div')
    if bottom then output = mw.html.create('span') end
    if not flags then flags = {} end
    for k, v in pairs(flags) do
        if type(v) == 'string' then
            output:addClass('flag-' .. k .. '-' .. v)
        end
    end
    output:addClass('ability-bar'):addClass('ability-bar-' .. barTitleClass)
        :attr(flags):attr('test', 'out'):node(barSpace):node(barTitle):node(
            barSpace):node(barContent):css('display', 'block')
    -- if flags then
    -- for k, v in ipairs(flags) do
    --     output:attr(k, v)
    -- end
    -- end
    return tostring(output)
end

function p.c(frame)
    local args = frame.args
    local rawAbilities = args['a'] or ''

    -- === TAGS & CATEGORIES via TagBuilder ===
    local TagBuilder = require('Module:TagBuilder')
    local tRaw = args['t'] or ''
		local looks = args['l'] or ''
    local name = args['name'] or ''
		local description = args['d'] or ''
		local baseHp = args['hp'] or '1'
		local baseMp = args['mp'] or '1'
    local opts = {
        name = name,
        ns = 'Creature', -- gate categories to the Creature namespace
        transparent = args.o or args.transparent -- optional passthrough
    }
    -- Use TagCreatures data and traits scope
    local tagOut, catOut =
        TagBuilder.build(tRaw, 'TagCreatures', 'traits', opts)

    -- === Parse abilities into a structured table ===
    local abilities = {}
    for ability in mw.text.gsplit(rawAbilities, ";;", true) do
        ability = mw.text.trim(ability)
        if ability ~= "" then
            local name = ability
            local limited, improved = "", ""
            local gifted, adept = false, false

            -- flags
            if mw.ustring.find(ability, "%-g%-") then gifted = true end
            if mw.ustring.find(ability, "%-a%-") then adept = true end

            -- notes (order-insensitive, tolerate any following marker)
            local limitedMatch = mw.ustring.match(ability,
                                                  "%-l%-(.-)(%-[liag]%-|$)") or
                                     mw.ustring.match(ability, "%-l%-(.+)$")
            if limitedMatch then limited = mw.text.trim(limitedMatch) end

            local improvedMatch = mw.ustring.match(ability,
                                                   "%-i%-(.-)(%-[liag]%-|$)") or
                                      mw.ustring.match(ability, "%-i%-(.+)$")
            if improvedMatch then
                improved = mw.text.trim(improvedMatch)
            end

            -- clean name (strip markers + their payloads/flags)
            name = mw.ustring.gsub(name, "%-l%-.+", "")
            name = mw.ustring.gsub(name, "%-i%-.+", "")
            name = mw.ustring.gsub(name, "%-g%-", "")
            name = mw.ustring.gsub(name, "%-a%-", "")
            name = mw.text.trim(name)

            table.insert(abilities, {
                name = name,
                limited = limited,
                improved = improved,
                gifted = gifted,
                adept = adept
            })
        end
    end

    -- Sort alphabetically by name (stable)
    table.sort(abilities, function(a, b) return a.name < b.name end)

    -- Build the out string (NO visible separators between AE templates)
    local transclusions = {}
    for _, a in ipairs(abilities) do
        local t = {"{{AE|", a.name}
        if a.limited ~= "" then table.insert(t, "|limited=" .. a.limited) end
        if a.improved ~= "" then
            table.insert(t, "|improved=" .. a.improved)
        end
        if a.gifted then table.insert(t, "|gifted=1") end
        if a.adept then table.insert(t, "|adept=1") end
        table.insert(t, "}}")
        table.insert(transclusions, table.concat(t))
    end

    -- Use "" (or "\n") so no semicolons are emitted
    local inner = table.concat(transclusions, "") -- <- no separators

		local statContent = ''
		statContent = statContent .. "{{Tag|" .. baseHp .. " HP|❤️|l=:Category:" .. baseHp .. " HP creatures|c=#e01b24|class=cost-tagged hp" .. baseHp .. "}}"
		statContent = statContent .. "{{Tag|" .. baseMp .. " MP|🩵|l=:Category:" .. baseMp .. " MP creatures|c=#3584e4|class=cost-tagged hp" .. baseMp .. "}}"

    -- Assemble output: tags (visible), abilities, then categories (gated by name/ns)
    local out = makeBar(frame, "Traits", (tagOut or ''), nul, nul, false)
		out = out .. makeBar(frame, "Stats", statContent, nul, nul, false)
		out = out .. makeBar(frame, "Looks", looks, nul, nul, false)
		out = out .. '<hr>' .. description .. '<hr>'
    out = out .. '<div class="expandable-table"><div>' ..
              frame:preprocess(inner) .. '</div></div>'
    out = out .. (catOut or '')

    -- Preprocess the whole thing so {{Tag}} expands
    return frame:preprocess(out)
end

return p