Description[]
Handles together with template Map page template the creation of the playable maps' appearences in the wiki.
See also[]
- Module Map/data
- Template Map page template
- Category Modules
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({
["cursor"] = title and 'help' or nil,
["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 mini_12p1 = 'File:'..name..'_Map_1_Minimap.jpg'
local mini_12p2 = 'File:'..name..'_Map_2_Minimap.jpg'
local mini_12p3 = 'File:'..name..'_Map_3_Minimap.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 p.get{name, 'is_12_player_map'} then
local mns = p.get{name, 'map_names', raw=true} or {}
if mw.title.new(mini_12p1).fileExists then images[#images+1] = mini_12p1..'|Minimap - Map 1: '..(mns[1] or 'Name missing') end
if mw.title.new(mini_12p2).fileExists then images[#images+1] = mini_12p2..'|Minimap - Map 2: '..(mns[2] or 'Name missing') end
if mw.title.new(mini_12p3).fileExists then images[#images+1] = mini_12p3..'|Minimap - Map 3: '..(mns[3] or 'Name missing') end
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
if type(dataChests[1]) == 'number' then
val = 1
else
val = length(dataChests)
end
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]] [[%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]] [[%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]] [[%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