置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:BAGrowthMaterial

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

该模块实现{{蔚蓝档案技能材料}}的功能。请不要直接调用此模块。

-- Module:BAGrowthMaterial
-- Made with ♥ by User:Leranjun

-- This module implements {{tl|蔚蓝档案技能材料}}.
-- Please refrain from invoking this module directly.

local p = {}

-- unpack() was deprecated in Lua 5.1
table.unpack = table.unpack or unpack

local getArgs = require("Module:Arguments").getArgs

local function isempty(s)
    return not (s and s ~= "")
end

function p.main(frame)
    return p._main(getArgs(frame), frame)
end

-- Types of skill levels
local TYPES = {
    "ex",
    "otr"
}
local TYPENAMES = {
    ex = "EX技能",
    otr = "其他技能"
}

function p._main(args, frame)
    -- For expanding templates later
    if (not frame) then
        frame = mw.getCurrentFrame()
    end

    -- Initialise table structure
    local r = '{| class="wikitable ba-table ba-center ba-growth-table mw-collapsible mw-collapsed"\n|-\n'

    local data = p.parse(args)

    -- Initialise table header
    r = r .. '! colspan=' .. data.count.total .. ' class="ba-header" | 材料需求\n'

    for _, type in ipairs(TYPES) do
        -- Initialise column header for type
        r = r .. "|-\n"
        r = r .. "! rowspan=" .. #data[type] .. " | " .. TYPENAMES[type] .. "\n"

        -- Iterate through levels of type
        for i, lvl_t in ipairs(data[type]) do
            -- Ignore new row for first level
            if (i ~= 1) then
                r = r .. "|-\n"
            end

            -- Initialise column header for specific level
            r = r .. "! " .. lvl_t.fromlevel .. " → " .. lvl_t.fromlevel + 1 .. "\n"

            -- Add credits cell
            r = r .. '| class="ba-bg-dark" | ' .. frame:expandTemplate {
                title = "蔚蓝档案材料",
                args = {
                    "信用点数",
                    type = "Item",
                    num = lvl_t.credits,
                }
            } .. "\n"

            -- Make sure all rows have equal number of columns
            for j = 1, data.count.maxcol, 1 do
                -- Add new cell anyway
                if (j == 1) then
                    r = r .. "| "
                else
                    r = r .. " || "
                end

                -- Only add item if exists
                if (lvl_t.items[j]) then
                    r = r .. frame:expandTemplate {
                        title = "蔚蓝档案材料",
                        args = {
                            lvl_t.items[j],
                            type = "Item",
                            num = lvl_t.quantity[j],
                        }
                    }
                end
            end

            r = r .. "\n"
        end
    end

    r = r .. "|}"

    return r
end

function p.parse(args)
    --[[
        Arguments:
            {
                LevelName: "Item:Quantity;Item:Quantity;...",
                ...
            }
            where LevelName is a String of form "${TypeName}\d+"
                e.g. ex1, ex2, otr1, otr2
                where TypeName is a String in TYPES
                    e.g. ex, otr
            e.g. {
                ex1 = "信用点数:80000;初级战术教育BD(三一):12;水晶埴轮碎片:19",
                ex2 = "信用点数:500000;中级战术教育BD(三一):12;初级战术教育BD(三一):18;破损的水晶埴轮:10;罗洪特抄本书页:26",
                ex3 = "信用点数:3000000;高级战术教育BD(三一):12;中级战术教育BD(三一):18;修好的水晶埴轮:10;毁损的罗洪特抄本:28",
                ex4 = "信用点数:10000000;最高级战术教育BD(三一):8;高级战术教育BD(三一):18;完整的水晶埴轮:9;编辑过的罗洪特抄本:20",
                otr1 = "初级技术笔记(三一):5;信用点数:5000",
                otr2 = "初级技术笔记(三一):8;信用点数:7500",
                otr3 = "中级技术笔记(三一):5;初级技术笔记(三一):12;水晶埴轮碎片:4;信用点数:60000",
                otr4 = "中级技术笔记(三一):8;破损的水晶埴轮:4;罗洪特抄本书页:13;信用点数:90000",
                otr5 = "高级技术笔记(三一):5;中级技术笔记(三一):12;破损的水晶埴轮:9;罗洪特抄本书页:21;信用点数:60000",
            }
        Returns:
            {
                TypeName = TypeDataTable,
                TypeName = TypeDataTable,
                ...
                count = {
                    total = Int, -- Total number of rows
                    maxcol = Int, -- Maximum number of items after "credits"
                }
            }
            where TypeDataTable is a Table of form:
                {
                    fromlevel: Int, -- Current level before upgrade
                    credits: Int, -- Number of credits required
                    items: {
                        String, -- Name of item 1
                        String, -- Name of item 2
                        ...
                    },
                    quantity: {
                        Int, -- Quantity of item 1,
                        Int, -- Quantity of item 2,
                        ...
                    },
                }
    ]]

    local r = {}

    -- Storing count data for table display
    local count = {
        total = 0,
        maxcol = 0,
    }

    for _, type in ipairs(TYPES) do
        -- Stores data for this type of skill
        local type_dat = {}

        local i = 1
        local lvl = type .. i
        local raw = args[lvl]
        while raw do
            -- Update counter
            count.total = count.total + 1

            -- Initialise current level data
            -- Note: parallel arrays are used for items and quantity to preserve input order, as Lua can guarantee the traversal order for numerical-indexed arrays only.
            local cur_dat = {
                fromlevel = i,
                items = {},
                quantity = {},
            }

            -- Split raw string input into items-quantity pairs
            for v in mw.text.gsplit(raw, ";") do
                v = mw.text.trim(v)
                if isempty(v) then
                    break
                end

                item, quantity = table.unpack(mw.text.split(v, ":"))
                if isempty(item) or isempty(quantity) then
                    error(lvl .. "材料或数量为空,请检查")
                end

                if item == "信用点数" then
                    -- Store credits separately
                    cur_dat.credits = quantity
                else
                    -- Add item and quantity to parallel arrays
                    table.insert(cur_dat.items, item)
                    table.insert(cur_dat.quantity, quantity)
                end
            end

            -- Update max column count
            if (#cur_dat.items > count.maxcol) then
                count.maxcol = #cur_dat.items
            end

            -- Add to main table
            table.insert(type_dat, cur_dat)

            i = i + 1
            lvl = type .. i
            raw = args[lvl]
        end

        -- Add to return table
        r[type] = type_dat
    end

    -- Add count data to return table
    r.count = count

    return r
end

return p