Module:建筑导航

来自缺氧 Wiki
跳转到导航 跳转到搜索

本模板为建筑生成导航框。 详见Template:建筑导航



-- Module:建筑导航
--- 本模板为建筑生成导航框。详见[[Template:建筑导航]]
local p = {}
local fstr = mw.ustring.format -- shortcut for formattig a string

local yesno = require([[Dev:Yesno]])
local utils = require([[Module:Utils]])
local i18ndu = require([[Module:I18n]]).loadMessages([[Module:i18n/Ui]])
local i18ndb = require([[Module:I18n]]).loadMessages([[Module:i18n/Buildings]])
local _u = function(...) return i18ndu:msg(...) end
local _b = function(...) return i18ndb:msg(...) end
local getArgs = require('Dev:Arguments').getArgs
local buData = mw.loadData([[Module:Data/Buildings]])

local catList = {
    "BASE", "OXYGEN", "POWER", "FOOD", "PLUMBING", "HVAC", "REFINING",
    "MEDICAL", "FURNITURE", "EQUIPMENT", "UTILITIES", "AUTOMATION",
    "CONVEYANCE", "ROCKETRY", "HEP"
}

local function catCode(l)
    local ret = {}
    for _, c in ipairs(catList) do
        table.insert(ret, "STRINGS.UI.BUILDCATEGORIES." .. string.upper(c) ..
                         ".NAME")
    end
    table.insert(ret, "STRINGS.UI.UISIDESCREENS.ROCKETMODULESIDESCREEN.TITLE")
    table.insert(ret, "Special")
    return ret
end

local function nameCode(id)
    return fstr("STRINGS.BUILDINGS.PREFABS.%s.NAME", string.upper(id))
end

-- test by: = p.main()
function p.main(frame)
    local out = {"[[建筑]]"} -- start with the navbox title
    local cats = {}
    for _, c in ipairs(catCode(catList)) do cats[c] = {} end
    for k, v in pairs(buData) do
    	if v.Deprecated then
    		-- do nothing
    	else
        	local vCat = v.category or "Special"
        	if cats[vCat] then
            	table.insert(cats[vCat], k)
        	else
            	mw.logObject("Invalid categoriy: " .. vCat)
        	end
        end
    end
    for _, c in ipairs(catCode(catList)) do
        table.sort(cats[c]) -- sort with the in-game id
        local catMap = {} -- map from targetpage to linktext()
        local catSeq = {}
        for _, bu in ipairs(cats[c]) do
        	if buData[bu].Deprecated then
        		-- do nothing
            elseif utils.getEntry(bu) then
            	local pagename = buData[bu].pagename or _b(nameCode(bu))
            	local linktext = _b(nameCode(bu))
            	if catMap[pagename] == nil then
                	catMap[pagename] = {}
                	table.insert(catSeq, pagename)
            	end
            	table.insert(catMap[pagename], linktext)
            end
        end

        local currCat = {}
        for _, p_name in ipairs(catSeq) do
            local linktext = catMap[p_name][1]
            if #(catMap[p_name]) > 1 then
                if utils.table.ihas(catMap[p_name], p_name) then
                    linktext = p_name
                else
                    mw.log("Unable to choose the best linktext: ")
                    mw.logObject(catMap[p_name])
                end
            end
            table.insert(currCat, fstr("[[%s|%s]]", p_name, linktext))
        end

        if #currCat > 0 then
            if c == "Special" then
                table.insert(out, "[[建筑#特殊|特殊]]")
            elseif c == "STRINGS.UI.UISIDESCREENS.ROCKETMODULESIDESCREEN.TITLE" then
                local cataName = _u(c)
                table.insert(out, fstr("[[建筑#%s|%s]]", cataName, cataName))
            else
                local cataName = _u(c)
                table.insert(out,
                             fstr("{{图|32|%s菜单|建筑#%s|%s|text=1}}",
                                  cataName, cataName, cataName, cataName))
            end
            table.insert(out, table.concat(currCat, " ! "))
        end
    end
    out.collapse = "yes"
    out.class = "nav-building"
    mw.logObject(out, "debug_raw_out")
    return mw.getCurrentFrame():expandTemplate{
        title = "PortableNavbox",
        args = out
    }
end

-- test by: = p._list{format="%s\n", category="STRINGS.UI.BUILDCATEGORIES.FURNITURE.NAME"}
-- test by: = p._list{format="%s\\n", isIndustrialMachinery = true}
-- test by: = p._list{format="%s\\n", isIndustrialMachinery = true, sort="category"}
-- test by: = p._list{format="%s \t %s\n", category="Special"}
-- test by: = p._list{format="%s \t %s\n", category="Special", unique="false"}
function p._list(args)
    local argvMap = {["true"] = true, ["false"] = false}
    local specialArgs = {format = true, sort = true, unique = true}
    local format = args.format or "%s"
    format = mw.ustring.gsub(format, '\\n', '\n') -- as lf will be trimmed in param passing 
    local out = {}
    for k, bu in pairs(buData) do
    	if bu.Deprecated then
    		-- do nothing
    	else
        	local include = true
        	for argk, argv in pairs(args) do
            	local valid = specialArgs[argk] ~= true
            	local mappedArgv = argvMap[argv] or argv
            	if valid and (bu[argk] == nil or bu[argk] ~= mappedArgv) then
                	include = false
                	break
            	end
        	end
        	if include then table.insert(out, bu) end
        end
    end

    if yesno(args.unique) ~= false then -- args.unique default to true
        local uniqueOut = {}
        local uniqueOutIdx = {}
        for _, e in ipairs(out) do
            local p_name = e.pagename or _b(nameCode(e.id))
            if uniqueOutIdx[p_name] == nil then
                table.insert(uniqueOut, e)
                uniqueOutIdx[p_name] = #uniqueOut
            elseif p_name == _b(nameCode(e.id)) then
                uniqueOut[uniqueOutIdx[p_name]] = e
            end
        end
        out = uniqueOut
    end

    if args.sort ~= nil then
        local catOrder = {}
        for i, c in ipairs(catCode(catList)) do catOrder[c] = i end
        setmetatable(catOrder, {__index = function() return 999 end})

        local sortFuncs = {
            category = function(a, b)
                return catOrder[a.category] < catOrder[b.category]
            end
        }

        local comp = sortFuncs[args.sort]
        if comp == nil then
            error(fstr('"args.sort = %s" is not supported', args.sort))
        end

        table.sort(out, comp)
    end

    for i, e in ipairs(out) do
        out[i] = fstr(format, e.pagename or _b(nameCode(e.id)),
                      _b(nameCode(e.id)))
    end
    return table.concat(out, "")
end

function p.list(frame)
    return mw.getCurrentFrame():preprocess(p._list(getArgs(frame)))
end

return p