Module:Infobox Appearance

From the RuneScape Wiki, the wiki for all things RuneScape
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Infobox Appearance/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:Infobox Appearance/doc. [edit]
Module:Infobox Appearance's function main is invoked by Template:Infobox Appearance.
Module:Infobox Appearance requires Module:Infobox.
Module:Infobox Appearance requires Module:Mainonly.
Module:Infobox Appearance requires Module:Plink.
Module:Infobox Appearance requires Module:Yesno.
Function list
L 22 — split_comma
L 35 — p.main
L 40 — p._main
L 214 — genderdarg
L 234 — genderddisp
L 248 — typearg
L 280 — typedisp
L 297 — swatchesarg
L 303 — sleevesarg
L 311 — sleevesdisp
L 319 — wristsarg
L 327 — wristsdisp
L 335 — hintarg
L 343 — hintdisp
L 347 — hiddenarg
L 355 — hiddendisp
L 363 — iddisp
L 375 — idbucket
L 383 — make_chisel_links
L 394 — to_json_value
L 402 — bucketarg
L 413 — match_pattern
L 417 — match_pattern_raw
L 429 — match_args
L 450 — addcategories
local p = {}

local onmain = require('Module:Mainonly').on_main
local infobox = require('Module:Infobox')
local plink = require("Module:Plink")._plink
local yesno = require('Module:Yesno')
local var = mw.ext.VariablesLua
local lang = mw.language.getContentLanguage()
local isDefined = infobox.isDefined


-- forward declarations
local genderdarg, genderddisp, typearg, typedisp, swatchesarg
local sleevesarg, sleevesdisp, wristsarg, wristsdisp
local hintarg, hintdisp, hiddenarg, hiddendisp
local iddisp, idbucket, make_chisel_links, bucketarg, addcategories

local left = '8'
local right = '14'
local full = '22'

local function split_comma(arg)
    if not arg then
        return {}
    end

    local arg_lower = arg:lower()
    if arg_lower == "no" or arg_lower == "none" then
        return {}
    end

    return mw.text.split(arg, "%s*,%s*")
end

function p.main(frame)
    local args = frame:getParent().args
    return p._main(args)
end

function p._main(args)
    local skin = infobox.new(args)
    skin:defineParams {
        { name = 'name', func = 'name' }, -- Module.Infobox default
        -- { name = 'image', func = { name = imgarg, params = { 'male', 'female' }, flag = { 'd' } } },
        { name = 'release', func = 'release' },
        { name = 'removal', func = 'removal' },
        { name = 'type', func = { name = typearg, params = { 'type' }, flag = { 'd' } } },
        { name = 'type_disp', func = { name = typedisp, params = { 'type' }, flag = { 'd' } } },
        { name = 'gender', func = { name = genderdarg, params = { 'gender' }, flag = { 'd' } } },
        { name = 'gender_disp', func = { name = genderddisp, params = { 'gender' }, flag = { 'd' } } },
        { name = 'swatches', func = { name = swatchesarg, params = { 'swatches' }, flag = { 'd' } }, dupes = true },
        { name = 'sleeves', func = { name = sleevesarg, params = { 'sleeves', 'type' }, flag = { 'd' } } },
        { name = 'sleeves_disp', func = { name = sleevesdisp, params = { 'sleeves' }, flag = { 'd' } } },
        { name = 'wrists', func = { name = wristsarg, params = { 'wrists', 'type' }, flag = { 'd' } } },
        { name = 'wrists_disp', func = { name = wristsdisp, params = { 'wrists' }, flag = { 'd' } } },
        { name = 'hint', func = { name = hintarg, params = { 'hint' }, flag = { 'd' } } },
        { name = 'hint_disp', func = { name = hintdisp, params = { 'hint' }, flag = { 'd' } } },
        { name = 'hidden', func = { name = hiddenarg, params = { 'hidden' }, flag = { 'd' } } },
        { name = 'hidden_disp', func = { name = hiddendisp, params = { 'hidden' }, flag = { 'd' } } },
        { name = 'female_id', func = { name = iddisp, params = { 'female_id' }, flag = 'd' } },
        { name = 'female_id_bucket', func = { name = idbucket, params = { 'female_id' }, flag = 'd' } },
        { name = 'female_chisel_links', func = { name = make_chisel_links, params = { 'female_id_bucket' }, flag = 'd' } },
        { name = 'male_id', func = { name = iddisp, params = { 'male_id' }, flag = 'd' } },
        { name = 'male_id_bucket', func = { name = idbucket, params = { 'male_id' }, flag = 'd' } },
        { name = 'male_chisel_links', func = { name = make_chisel_links, params = { 'male_id_bucket' }, flag = 'd' } },
        { name = 'bucketarg', func = { name = bucketarg, params = {
            'sleeves', 'wrists', 'hint', 'hidden' },
            flag = 'd' } },
    }

    skin:useBucket('infobox_appearance', {
        name = 'name',
        gender = 'gender',
        type = 'type',
        swatches = 'swatches',
        bucketarg = 'json',
        male_id_bucket = 'male_idkit',
        female_id_bucket = 'female_idkit',
    })

    skin:create()
    skin:cleanParams()
    skin:addButtonsCaption()

    skin:defineLinks()

    skin:defineName('Infobox Appearance')
    skin:addClass('infobox-appearance')

    -- PARAMETER: name
    skin:addRow {
        { tag = 'argh', content = 'name', class = 'infobox-header', colspan = full },
    }
        :pad(full)

    -- -- PARAMETER: male, female
    -- skin:addRow {
    -- 	{ tag = 'argd', content = 'image', class = 'infobox-image infobox-full-width-content', colspan = '20' },
    -- }
    -- 	:pad(full)

    -- PARAMETER: release
    -- (update included automatically by infobox)
    skin:addRow {
        { tag = 'th', content = 'Release', colspan = '8' },
        { tag = 'argd', content = 'release', colspan = '12' },
    }

    -- PARAMETER: removal
    if skin:paramDefined('removal') then
        skin:addRow {
            { tag = 'th', content = 'Removal', colspan = '8' },
            { tag = 'argd', content = 'removal', colspan = '12' },
        }
    end

    -- PARAMETER: type
    skin:addRow {
        { tag = 'th', content = 'Type', colspan = left },
        { tag = 'argd', content = 'type_disp', colspan = right },
    }

    -- PARAMETER: gender
    skin:addRow {
        { tag = 'th', content = 'Gender', colspan = left },
        { tag = 'argd', content = 'gender_disp', colspan = right },
    }

    -- PARAMETER: sleeves
    if skin:paramDefined('sleeves') then
        skin:addRow {
            { tag = 'th', content = 'Sleeves', colspan = left },
            { tag = 'argd', content = 'sleeves_disp', colspan = right },
        }
    end

    -- PARAMETER: wrists
    if skin:paramDefined('wrists') then
        skin:addRow {
            { tag = 'th', content = 'Wrists', colspan = left },
            { tag = 'argd', content = 'wrists_disp', colspan = right },
        }
    end

    -- PARAMETER: hint
    if skin:paramDefined('hint') then
        skin:addRow {
            { tag = 'th', content = 'Unlock hint', colspan = left },
            { tag = 'argd', content = 'hint_disp', colspan = right },
        }
    end

    -- PARAMETER: hidden
    if skin:paramDefined('hidden') then
        skin:addRow {
            { tag = 'th', content = 'Visibility', colspan = left },
            { tag = 'argd', content = 'hidden_disp', colspan = right },
        }
    end

    skin:pad(full)

    -- Advanced data
    skin:addRow {
        { tag = 'th', content = 'Advanced data', class = 'infobox-subheader', colspan = full },
        meta = { addClass = 'advanced-data' },
    }
        :pad(full, 'advanced-data')

    -- PARAMETER: male_id
    if skin:paramDefined('male_id') then
        skin:addRow {
            { tag = 'th', content = 'Male idkit ID', colspan = left },
            { tag = 'argd', content = 'male_id', colspan = right },
            meta = { addClass = 'advanced-data' },
        }

        -- PARAMETER: male_chisel_links
        skin:addRow {
            { tag = 'th', content = 'Male links', colspan = left },
            { tag = 'argd', content = 'male_chisel_links', colspan = right },
            meta = { addClass = 'advanced-data' },
        }
    end

    -- PARAMETER: female_id
    if skin:paramDefined('female_id') then
        skin:addRow {
            { tag = 'th', content = 'Female idkit ID', colspan = left },
            { tag = 'argd', content = 'female_id', colspan = right },
            meta = { addClass = 'advanced-data' },
        }

        -- PARAMETER: female_chisel_links
        skin:addRow {
            { tag = 'th', content = 'Female links', colspan = left },
            { tag = 'argd', content = 'female_chisel_links', colspan = right },
            meta = { addClass = 'advanced-data' },
        }
    end

    skin:pad(full, 'advanced-data')

    skin:finish()
    if onmain() then
        local a1 = skin:param('all')
        local a2 = skin:categoryData()
        skin:wikitext(addcategories(a1, a2))
    end

    return skin:tostring()
end

function genderdarg(arg)
    if not isDefined(arg) then
        return nil
    end

    local gens = split_comma(arg)

    local ret = { male = false, female = false }
    for _, value in ipairs(gens) do
        local gl = string.lower(value)
        if gl == 'male' then
            ret.male = true
        elseif gl == 'female' then
            ret.female = true
        end
    end

    return ret
end

function genderddisp(arg)
    if not isDefined(arg) then
        return nil
    end

    if arg.female and arg.male then
        return 'All'
    elseif arg.male then
        return 'Male only'
    elseif arg.female then
        return 'Female only'
    end
end

function typearg(arg)
    if not isDefined(arg) then
        return nil
    end

    local type = string.lower(arg)

    if type == 'hairstyle' or type == 'hair' then
        return 'hairstyle'
    elseif type == 'premium hairstyle' or type == 'premium hair' then
        return 'premium hairstyle'
    elseif type == 'bespoke hairstyle' or type == 'bespoke hair' then
        return 'bespoke hairstyle'
    elseif type == 'beard' or type == 'beards' then
        return 'beard'
    elseif type == 'premium beard' or type == 'premium beards' then
        return 'premium beard'
    elseif type == 'top' then
        return 'top'
    elseif type == 'sleeves' or type == 'sleeve' then
        return 'sleeves'
    elseif type == 'wrists' or type == 'wrist' then
        return 'wrists'
    elseif type == 'leggings' or type == 'legging' then
        return 'leggings'
    elseif type == 'shoes' or type == 'shoe' then
        return 'shoes'
    else
        return nil
    end
end

function typedisp(typ)
    local display = {
        ['hairstyle'] = 'Hairstyle',
        ['premium hairstyle'] = 'Premium hairstyle',
        ['bespoke hairstyle'] = 'Bespoke hairstyle',
        ['beard'] = 'Beard',
        ['premium beard'] = 'Premium beard',
        ['top'] = 'Top',
        ['sleeves'] = 'Sleeves',
        ['wrists'] = 'Wrists',
        ['leggings'] = 'Leggings',
        ['shoes'] = 'Shoes',
    }

    return display[typ]
end

function swatchesarg(arg)
    if not isDefined(arg) then
        return nil
    end
end

function sleevesarg(arg)
    if not isDefined(arg) then
        return nil
    end

    return yesno(arg, nil)
end

function sleevesdisp(arg)
    if not isDefined(arg) then
        return nil
    end

    return arg and 'Yes' or 'No'
end

function wristsarg(arg)
    if not isDefined(arg) then
        return nil
    end

    return yesno(arg, nil)
end

function wristsdisp(arg)
    if not isDefined(arg) then
        return nil
    end

    return arg and 'Yes' or 'No'
end

function hintarg(arg)
    if not isDefined(arg) then
        return nil
    end

    return arg
end

function hintdisp(arg)
    return arg
end

function hiddenarg(arg)
    if not isDefined(arg) then
        return nil
    end

    return yesno(arg, nil)
end

function hiddendisp(arg)
    if not isDefined(arg) then
        return nil
    end

    return arg and 'Hidden until unlocked' or nil
end

function iddisp(id)
    if isDefined(id) then
        if id:lower() ~= 'no' and id:lower() ~= 'none' then
            local r = string.gsub(id, ', *', ', ')
            return r
        elseif id:lower() == 'no' or id:lower() == 'none' then
            return 'None'
        end
    end
    return nil
end

function idbucket(id)
    if isDefined(id) and id:lower() ~= 'no' and id:lower() ~= 'none' then
        local r = string.gsub(id, ', *', infobox.splitpoint)
        return r
    end
    return nil
end

function make_chisel_links(id)
    local link1 = 'https://chisel.weirdgloop.org/structs_rs3/'
    if isDefined(id) then
        link1 = link1 .. "index.html?type=idkits&id=" .. id
        return string.format('[%s idkit%s]', link1, id)
    else
        return nil
    end
end

-- bucket JSON
local function to_json_value(value, default)
    if isDefined(value) then
        return value
    else
        return default
    end
end

function bucketarg(sleeves, wrists, hint, hidden)
    local toJSON = {
        sleeves = to_json_value(sleeves),
        wrists = to_json_value(wrists),
        hint = to_json_value(hint),
        hidden = to_json_value(hidden),
    }

    return mw.text.killMarkers(mw.text.jsonEncode(toJSON))
end

local function match_pattern(val, pattern)
    return isDefined(val) and string.lower(tostring(val) or '') == pattern
end

local function match_pattern_raw(val, pattern)
    if type(val) == "table" then
        for _, x in ipairs(val) do
            if match_pattern(x, pattern) then
                return true
            end
        end
    else
        return match_pattern(val, pattern)
    end
end

local function match_args(arg, pattern)
    if not arg then
        return false
    end

    local val = arg.d
    if match_pattern_raw(val, pattern) then
        return true
    end

    if arg.switches then
        for _, x in ipairs(arg.switches) do
            if match_pattern_raw(x, pattern) then
                return true
            end
        end
    end

    return false
end

function addcategories(args, catargs)
    local ret = { '' }

    local cat_map = {
        -- Added if the parameter has content
        defined = {},
        -- Added if the parameter has no content
        notdefined = {
            id = 'Appearance missing id',
            gender = 'Appearance missing gender',
            type = 'Appearance missing type',
        },
        -- Parameters that have text
        -- map a category to a value
        match = {
            type = {
                ['hairstyle'] = 'Hairstyles',
                ['premium hairstyle'] = 'Premium hairstyles',
                ['bespoke hairstyle'] = 'Bespoke hairstyles',
                ['beard'] = 'Beards',
                ['premium beard'] = 'Premium beards',
                ['top'] = 'Base tops',
                ['sleeves'] = 'Base sleeves',
                ['wrists'] = 'Base wrists',
                ['leggings'] = 'Base leggings',
                ['shoes'] = 'Base shoes',
            },
        },
    }

    -- Run and add mapped categories
    for n, v in pairs(cat_map.defined) do
        if catargs[n] and catargs[n].one_defined then
            table.insert(ret, v)
        end
    end
    for n, v in pairs(cat_map.notdefined) do
        if catargs[n] and catargs[n].all_defined == false then
            table.insert(ret, v)
        end
    end

    -- searches
    for n, v in pairs(cat_map.match) do
        for m, w in pairs(v) do
            if match_args(args[n], m) then
                table.insert(ret, w)
            end
        end
    end

    -- combine table and format category wikicode
    for i, v in ipairs(ret) do
        if (v ~= '') then
            ret[i] = string.format('[[Category:%s]]', v)
        end
    end

    return table.concat(ret, '')
end

return p