Skylords Reborn
Advertisement
Skylords Reborn

Edit documentation

Description

Handles together with template Map page template the creation of the playable maps' appearences in the wiki.

See also


local p = {}
local lib = require('Module:Shared')
local data = mw.loadData('Module:Map/data')
local concat = lib.concat
local format = lib.format
local getArgs = lib.getArgs
local length = lib.length

function p._positions(pos, pos_type, start_at, reduce_size)
    local res = mw.html.create('')
    if type(pos) ~= 'table' then return end
    if type(pos[1]) ~= 'table' then pos = {pos} end
    local start_at = start_at or 1
    for k,v in ipairs(pos) do
        local wktxt,title = '',''
        if pos_type == 'player' then
            wktxt = format("[[File:Starting_Position_Player_%02d_Icon.png|%spx|link=]]", start_at, reduce_size and '18' or '23')
            title = format('Starting position of player %s.', start_at)
            start_at = start_at + 1
        elseif pos_type == 'quest' then
            wktxt = format("[[File:Goal_Letter_Icon_%s.png|17px|link=]]", (type(v.letter) == 'string' and v.letter:upper() or 'Blank'))
            title = v[3] or format('Quest goal %s', (v.letter or ''):upper())
        elseif pos_type == 'chest' then
            wktxt = format("[[File:Gold_Chest_Icon_Glow.png|%spx|link=]]", reduce_size and '18' or '23')
            title = 'A gold chest can be found here.'
        end

        res:tag('div'):css({
            ["position"] = "absolute",
            ["z-index"] = 100,
            ["left"] = (v[1] or '') .. '%',
            ["bottom"] = (v[2] or '') .. '%',
        }):attr('title', title):wikitext(wktxt):done()
    end
    return tostring(res:allDone())
end

function p._rankings(rankings)
    local res = {}
    if type(rankings) ~= 'table' then return res end
    
    for k,v in ipairs(rankings) do
        local key = '#p'..v.ranking_numberplayers
        res[key] = {}
        local t = {}
        for k_,v_ in ipairs(type(v.ranking_players) == 'table' and v.ranking_players or {v.ranking_players}) do t[k_] = v_ end
        res[key].t = v.ranking_time
        res[key].d = v.ranking_date
        res[key].dif = v.ranking_difficulty
        res[key].apc = #t -- actual player count
        res[key].p = table.concat(t, ' + ')
    end
    
    return res
end


function p.for_each(frame)
    local args = getArgs(frame)
    local list = lib.orderedList(data)
    local result
    
    if args[1] == 'list_of_chests' then
        result = mw.html.create()
        
        for k,v in ipairs(list) do
            if data[v].type == 'PvE' then
            	local is12p = p.get{v, 'is_12_player_map'}
                local mi = p.icon{v, show_chests = true}
                local players = p.get{v, 'max_players'}
                local chests = p.get{v, 'number_of_chests',raw=true}
                
                result:tag('tr'):addClass('search-item'):attr('data-search', v)
                    :tag('td'):node(mi):done()
                    :tag('td'):wikitext(players):done()
                    :tag('td'):wikitext(chests):done()
                :done()
            end
        end
    end
    
    return result
end

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

    local name = args.name or args[1]
    if not name then return 'Error: Missing Map Name' end

    local mini = 'File:'..name..'_Minimap.jpg'
    local orig = 'File:'..name..'_Minimap_Original.jpg'
    local bann = 'File:'..name..'_Banner.png'
    local orig_old = 'File:'..name..'_Minimap_Original_Old.jpg'
    local mini_old = 'File:'..name..'_Minimap_Old.jpg'
    local orig_old2 = 'File:'..name..'_Minimap_Original_Old_2.jpg'
    local mini_old2 = 'File:'..name..'_Minimap_Old_2.jpg'
    local orig_old3 = 'File:'..name..'_Minimap_Original_Old_3.jpg'
    local mini_old3 = 'File:'..name..'_Minimap_Old_3.jpg'

    local images = {}
    if mw.title.new(orig).fileExists then images[#images+1] = orig..'|Original Minimap' end
    if mw.title.new(mini).fileExists then images[#images+1] = mini..'|Minimap' end
    if mw.title.new(bann).fileExists then images[#images+1] = format('%s|[[Loading_Screens#%s|Loading Screen Banner]]', bann, name:gsub(' ', '_')) end
    if p.get{name, 'type', raw=true} == 'PvP' then images[#images+1] = 'File:Loading_Screen_Default.jpg|[[Loading Screens#PvP|PvP Loading Screen Banner]]' end
    if mw.title.new(orig_old).fileExists then images[#images+1] = orig_old..'|Old Original Minimap - Version 1' end
    if mw.title.new(mini_old).fileExists then images[#images+1] = mini_old..'|Old Minimap - Version 1' end
    if mw.title.new(orig_old2).fileExists then images[#images+1] = orig_old2..'|Old Original Minimap - Version 2' end
    if mw.title.new(mini_old2).fileExists then images[#images+1] = mini_old2..'|Old Minimap - Version 2' end
    if mw.title.new(orig_old3).fileExists then images[#images+1] = orig_old3..'|Old Original Minimap - Version 3' end
    if mw.title.new(mini_old3).fileExists then images[#images+1] = mini_old3..'|Old Minimap - Version 3' end

    local gal = frame:extensionTag(
        'gallery',
        table.concat(images, '\n'),
        { mode="slideshow", type="slideshow", widths="700px", position="center", hideaddbutton="true" }
    )

    return gal
end

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

    local name = args['name'] or args[1]
    if not name then return 'Error: Missing Map Name' end

    local getter = args['get'] or args[2]
    if not getter then return 'Error: No value to get specified' end
    getter = getter:lower()

    local data = data[name]
    if not data then return format('Error: Map "%s" not found', name) end

    local val = {}
    
    local is12p = type(data.min_players) == 'table'
    
    if getter == 'is_12_player_map' then return is12p end

    if getter == 'difficulties' then
        if (data.difficulties or {})['standard'] then
            table.insert(val, 'Standard')
        end
        if (data.difficulties or {})['advanced'] then
            table.insert(val, 'Advanced')
        end
        if (data.difficulties or {})['expert'] then
            table.insert(val, 'Expert')
        end
    elseif getter == 'prerequisites' then
        val = lib.mwDataToTable(data.prerequisites)
    elseif getter == 'unlocks' then
        val = lib.mwDataToTable(data.unlocks)
    elseif getter == 'number_of_players' then
        val = 0
        if is12p then
            val = data.min_players[1] + data.min_players[2] + data.min_players[3]
            if val ~= 12 then val = tostring(val) .. ' - 12' end
        else
            local d = data.starting_positions
            if type(d) == 'table' and type(d[1]) ~= 'table' then d = {d} end
            val = length(d)
            if data.min_players ~= val then val = (data.min_players or 0) .. ' - ' .. val end
        end
    elseif getter == 'min_players' then
        val = 0
        if is12p then
            val = data.min_players[1] + data.min_players[2] + data.min_players[3]
        else val = data.min_players end
    elseif getter == 'max_players' then
        if is12p then
            val = 12
        else
            local d = data.starting_positions
            if type(d) == 'table' and type(d[1]) ~= 'table' then d = {d} end
            val = length(d)
        end
    elseif getter == 'number_of_chests' then
        val = 0
        local dataChests = data.chest_positions
        if dataChests then
            if is12p then
            	local names = data.map_names or {}
                local a = length(dataChests[1])
                local b = length(dataChests[2])
                local c = length(dataChests[3])
                val = lib.p{
                	texttip='true',
                	a,
                	'Maximum obtainable gold chests on '..(names[1] or 'Map 1'),
                	b,
                	'Maximum obtainable gold chests on '..(names[2] or 'Map 2'),
                	c,
                	'Maximum obtainable gold chests on '..(names[3] or 'Map 3')
                }
            else
                val = length(dataChests)
            end
        end
    elseif getter == 'loading_screen_text' or getter == 'plot2' or getter == 'conclusion1' or getter == 'conclusion2' then
    	val = data[getter]
    	if val == '' then return '<span style="color:red;">Error: Missing data in [[Module:Map/data]].</span>' end
    else
        val = data[getter]
    end

    if args.raw then return val end

    if type(args[3]) == 'string' and args[3]:lower() == 'listtotext' then
        return mw.text.listToText(val, ', ', ' and ')
    end

    if type(args[3]) == 'string' and args[3]:lower() == 'concat' then
        return table.concat(val, ', ')
    end
    
    if type(val) == 'string' and type(args[3]) == 'string' and args[3]:lower() == 'preprocess' then
        return frame:preprocess(val)
    end

    if type(val) == 'table' then
        if type(args[3]) == 'number' then return val[args[3]] end
        return table.concat(val, ', ')
    end

    return val

end

function p.icon(frame)
    local args = getArgs(frame)
    
    local is12p = p.get{args[1], 'is_12_player_map'} == true -- comapre with true to handle soft errors as false
    
    local el = mw.html.create('span')
        :addClass('custom-tooltip mi')
        :attr('data-tt-type', 'map')
        :attr('data-1', args[1])
        :attr('data-2', args.show_chests and 'show_chests' or (args.show_players and 'show_players' or nil))
        
    local link = args['nolink'] and '' or args['link'] or args[1]
        
    if is12p then
        if args['icononly'] then
            if args['map_number'] then
                el:wikitext(format('[[File:%s_Map_%s_Minimap.jpg|%s|link=%s]]', args[1], args['map_number'], args['size'] or '20px', link))
            else
                el:wikitext(format('[[File:%s_Map_1_Minimap.jpg|%s|link=%s]][[File:%s_Map_2_Minimap.jpg|%s|link=%s]][[File:%s_Map_3_Minimap.jpg|%s|link=%s]]',
                    args[1], args['size'] or '20px', args[1], args[1], args['size'] or '20px', args[1], args[1], args['size'] or '20px', args[1]))
            end
        else
            if args['map_number'] then
                el:wikitext(format('[[File:%s_Map_%s_Minimap.jpg|%s|link=%s]]&nbsp;[[%s|%s]]', args[1], args['map_number'], args['size'] or '20px', link, link, args[2] or args[1]))
            else
                el:wikitext(format('[[File:%s_Map_1_Minimap.jpg|%s|link=%s]][[File:%s_Map_2_Minimap.jpg|%s|link=%s]][[File:%s_Map_3_Minimap.jpg|%s|link=%s]]&nbsp;[[%s|%s]]',
                    args[1], args['size'] or '20px', link, link, args['size'] or '20px', link, link, args['size'] or '20px', link, link, args[2] or args[1]))
            end
        end
    else
        if args['icononly'] then
            el:wikitext(format('[[File:%s_Minimap.jpg|%s|link=%s]]', args[1], args['size'] or '20px', link))
        else
            el:wikitext(format('[[File:%s_Minimap.jpg|%s|link=%s]]&nbsp;[[%s|%s]]', args[1], args['size'] or '20px', link, link, args[2] or args[1]))
        end
    end
    
    return el:done()
end

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

    local name = args['name'] or args[1]
    if not name then return 'Error: Missing Map Name' end

    local data = data[name]
    if not data then return format('Error: Map "%s" not found', name) end
    
    local prereq = p.get{name, 'prerequisites', raw=true}
    local unlocks = p.get{name, 'unlocks', raw=true}
    
    for k,v in ipairs(prereq) do if v ~= 'None' then prereq[k] = tostring(p.icon{v}) end end
    for k,v in ipairs(unlocks) do if v ~= 'None' then unlocks[k] = tostring(p.icon{v}) end end
    
    local is12p = type(data.min_players) == 'table'

    local rankings = p._rankings(data.rankings)
    
    local infoboxArgs = {
        name = name,
        maptype = data.type,
        description = data.mission_briefing,
        campaign_name = data.campaign_name,
        difficulties = p.get{name, 'difficulties'},
        prerequisites = table.concat(prereq, '<br>'),
        unlocks = table.concat(unlocks, '<br>'),
        numberofchests = p.get{name, 'number_of_chests', raw=true},
        mission_briefing_description = data.mission_briefing_description,
        spectator_map_available = data.spectator_map_available ~= nil and (data.spectator_map_available and 'Available' or 'Unavailable') or nil,
        ranking_4p_time = rankings['#p4'] and rankings['#p4'].t,
        ranking_4p_names = rankings['#p4'] and rankings['#p4'].p,
        ranking_4p_date = rankings['#p4'] and rankings['#p4'].d,
        ranking_4p_difficulty = rankings['#p4'] and rankings['#p4'].dif,
        ranking_3p_time = rankings['#p3'] and rankings['#p3'].t,
        ranking_3p_names = rankings['#p3'] and rankings['#p3'].p,
        ranking_3p_date = rankings['#p3'] and rankings['#p3'].d,
        ranking_3p_difficulty = rankings['#p3'] and rankings['#p3'].dif,
        ranking_2p_time = rankings['#p2'] and rankings['#p2'].t,
        ranking_2p_names = rankings['#p2'] and rankings['#p2'].p,
        ranking_2p_date = rankings['#p2'] and rankings['#p2'].d,
        ranking_2p_difficulty = rankings['#p2'] and rankings['#p2'].dif,
        ranking_1p_time = rankings['#p1'] and rankings['#p1'].t,
        ranking_1p_names = rankings['#p1'] and rankings['#p1'].p,
        ranking_1p_date = rankings['#p1'] and rankings['#p1'].d,
        ranking_1p_difficulty = rankings['#p1'] and rankings['#p1'].dif,
    }
    
    if type(data.min_players) == 'table' then -- 12 player map
        infoboxArgs.ranking_12p_time = rankings['#p12'] and rankings['#p12'].t
        infoboxArgs.ranking_12p_names = rankings['#p12'] and rankings['#p12'].p
        infoboxArgs.ranking_12p_date = rankings['#p12'] and rankings['#p12'].d
        infoboxArgs.ranking_12p_difficulty = rankings['#p12'] and rankings['#p12'].dif
        infoboxArgs.ranking_11p_time = rankings['#p11'] and rankings['#p11'].t
        infoboxArgs.ranking_11p_names = rankings['#p11'] and rankings['#p11'].p
        infoboxArgs.ranking_11p_date = rankings['#p11'] and rankings['#p11'].d
        infoboxArgs.ranking_11p_difficulty = rankings['#p11'] and rankings['#p11'].dif
        infoboxArgs.ranking_10p_time = rankings['#p10'] and rankings['#p10'].t
        infoboxArgs.ranking_10p_names = rankings['#p10'] and rankings['#p10'].p
        infoboxArgs.ranking_10p_date = rankings['#p10'] and rankings['#p10'].d
        infoboxArgs.ranking_10p_difficulty = rankings['#p10'] and rankings['#p10'].dif
        infoboxArgs.ranking_9p_time = rankings['#p9'] and rankings['#p9'].t
        infoboxArgs.ranking_9p_names = rankings['#p9'] and rankings['#p9'].p
        infoboxArgs.ranking_9p_date = rankings['#p9'] and rankings['#p9'].d
        infoboxArgs.ranking_9p_difficulty = rankings['#p9'] and rankings['#p9'].dif
        infoboxArgs.ranking_8p_time = rankings['#p8'] and rankings['#p8'].t
        infoboxArgs.ranking_8p_names = rankings['#p8'] and rankings['#p8'].p
        infoboxArgs.ranking_8p_date = rankings['#p8'] and rankings['#p8'].d
        infoboxArgs.ranking_8p_difficulty = rankings['#p8'] and rankings['#p8'].dif
        infoboxArgs.ranking_7p_time = rankings['#p7'] and rankings['#p7'].t
        infoboxArgs.ranking_7p_names = rankings['#p7'] and rankings['#p7'].p
        infoboxArgs.ranking_7p_date = rankings['#p7'] and rankings['#p7'].d
        infoboxArgs.ranking_7p_difficulty = rankings['#p7'] and rankings['#p7'].dif
        infoboxArgs.ranking_6p_time = rankings['#p6'] and rankings['#p6'].t
        infoboxArgs.ranking_6p_names = rankings['#p6'] and rankings['#p6'].p
        infoboxArgs.ranking_6p_date = rankings['#p6'] and rankings['#p6'].d
        infoboxArgs.ranking_6p_difficulty = rankings['#p6'] and rankings['#p6'].dif
        infoboxArgs.ranking_5p_time = rankings['#p5'] and rankings['#p5'].t
        infoboxArgs.ranking_5p_names = rankings['#p5'] and rankings['#p5'].p
        infoboxArgs.ranking_5p_date = rankings['#p5'] and rankings['#p5'].d
        infoboxArgs.ranking_5p_difficulty = rankings['#p5'] and rankings['#p5'].dif

        local s = data.starting_positions or {}
        local q = data.quest_positions or {}
        local c = data.chest_positions or {}
        local m = type(data.minimap_image) == 'table' and data.minimap_image or {name..'_Map_1_Minimap.jpg',name..'_Map_2_Minimap.jpg',name..'_Map_3_Minimap.jpg'}

        if data.map_names then
            infoboxArgs.map_1_name = data.map_names[1]
            infoboxArgs.map_2_name = data.map_names[2]
            infoboxArgs.map_3_name = data.map_names[3]
        end

        infoboxArgs.minimap_image_1 = m[1]
        infoboxArgs.startings_1 = p._positions(s[1], 'player')
        infoboxArgs.quests_1 = p._positions(q[1], 'quest')
        infoboxArgs.chests_1 = p._positions(c[1], 'chest')
        infoboxArgs.minimap_image_2 = m[2]
        infoboxArgs.startings_2 = p._positions(s[2], 'player', length(s[1])+1)
        infoboxArgs.quests_2 = p._positions(q[2], 'quest')
        infoboxArgs.chests_2 = p._positions(c[2], 'chest')
        infoboxArgs.minimap_image_3 = m[3]
        infoboxArgs.startings_3 = p._positions(s[3], 'player', length(s[1])+length(s[2])+1)
        infoboxArgs.quests_3 = p._positions(q[3], 'quest')
        infoboxArgs.chests_3 = p._positions(c[3], 'chest')
        infoboxArgs.numberofplayers = format("{{p|texttip=true|%s - 4|Players on %s|%s - 4|Players on %s|%s - 4|Players on %s}}", data.min_players[1], (infoboxArgs.map_1_name or 'Map 1'), data.min_players[2], (infoboxArgs.map_2_name or 'Map 2'), data.min_players[3], (infoboxArgs.map_3_name or 'Map 3'))

    else --nromal map
        infoboxArgs.numberofplayers = p.get{name, 'number_of_players'}
        infoboxArgs.minimap_image = data.minimap_image or (name..'_Minimap.jpg')
        infoboxArgs.startings = p._positions(data.starting_positions, 'player')
        infoboxArgs.quests = p._positions(data.quest_positions, 'quest')
        infoboxArgs.chests = p._positions(data.chest_positions, 'chest')
    end

    return frame:expandTemplate{
        title = 'Infobox map',
        args = infoboxArgs
    }
end

function p.tree(frame)
    local list = lib.orderedList(data)
    local t, hash, res = {}, {}, {}
    
    for _,map in ipairs(list) do
        if data[map].type == 'PvE' then
            local c, p = {}, {}
            local pre = type(data[map].prerequisites) ~= 'table' and {data[map].prerequisites} or data[map].prerequisites
            local unl = type(data[map].unlocks) ~= 'table' and {data[map].unlocks} or data[map].unlocks
            if pre[1] and pre[1] ~= 'None' then
                local _p = {}
                for _,v in ipairs(pre) do _p[#_p+1] = v end
                p = _p
            end
            if unl[1] and unl[1] ~= 'None' then
                local _c = {}
                for _,v in ipairs(unl) do _c[#_c+1] = v end
                c = _c
            end
            t[#t+1] = {name = map, children = c[1] and c, parents = p[1] and p}
        end
    end
    
    while t[1] do
        for k,v in ipairs(t) do
            if not v.parents then
                res[#res+1] = {name = v.name, children = v.children and {} or nil}
                hash[v.name] = 1
                t[k] = nil
            else
                t[k] = nil
            end
        end
    end
    
    return mw.dumpObject(res)
end

return p