Module:Maps

From Liquipedia Age of Empires Wiki

Documentation for this module may be created at Module:Maps/doc

local Abbreviation = require('Module:Abbreviation')
local Array = require('Module:Array')
local Class = require('Module:Class')
local Json = require('Module:Json')
local Logic = require('Module:Logic')
local String = require('Module:StringUtils')
local Table = require('Module:Table')
local Variables = require('Module:Variables')

local Maps = {}

local PLACEHOLDER = 'MapImagePlaceholder.jpg'

function Maps.main(args)
	local maps = Maps.getMaps(args)
	if Table.isEmpty(maps) then
		return Abbreviation.make('TBD', 'To be determined')
	end
		
	return Maps.buildDisplay(maps, args)
end

function Maps.getMaps(args)
	local maps, failure
	if args.map1 then
		maps = Maps.getManualMaps(args)
	elseif String.isNotEmpty(Variables.varDefault('tournament_maps')) then
		maps, failure = Json.parse(Variables.varDefault('tournament_maps'))
	end
	if failure or args.tournament or String.isEmpty(Variables.varDefault('tournament_maps')) and not args.map1 then
		maps = Maps.getMapsFromLpdb(args)
	end

	Array.map(maps, Maps.fetchMapData)
	return maps
end
	
function Maps.getMapsFromLpdb(args)
	local tournament = args.tournament or mw.title.getCurrentTitle().prefixedText or ''
	local data = mw.ext.LiquipediaDB.lpdb('tournament', {
		conditions = '[[pagename::' .. tournament:gsub(' ', '_') .. ']]',
		query = 'maps'
	})
	
	if type(data) == 'table' and data[1] then
		local maps, failure = Json.parse(data[1].maps)
		if failure then
			maps = Array.map(
				mw.text.split(data[1].maps, ';', true),
				function(map) return {link = map} end
			)
		end
		return maps
	else
		error("No data available for page " .. tournament)
	end
end

function Maps.getManualMaps(args)
	local maps = {}
	for key, value in Table.iter.pairsByPrefix(args, 'map') do
		local input = mw.text.split(value, '|', true)
		local link = args[key .. 'link'] and args[key .. 'link'] or mw.ext.TeamLiquidIntegration.resolve_redirect(input[1])
		local name = input[2] and input[2] or input[1]

		table.insert(maps, {
			link = link,
			name = name,
			image = args[key .. 'image']
		})
	end
	return maps
end

function Maps.fetchMapData(map)
	data = mw.ext.LiquipediaDB.lpdb('datapoint', {
		conditions = '[[type::map]] AND [[pagename::' .. string.gsub(map.link, ' ', '_') .. ']]',
		query = 'name, image, extradata',
	})
	
	if type(data) == 'table' and data[1] then
		map.name = map.name or data[1].name
		map.image = map.image or data[1].image
		map.icon = (data[1].extradata or {}).icon
	else
		map.name = map.name or map.link
	end
	
	return map
end

function Maps.buildDisplay(maps, args)
	local display = mw.html.create('table')
		:addClass('wikitable mapstable')
		:css('text-align', 'center')

	if args.title then
		display:tag('tr')
			:tag('th')
				:attr('colspan', #maps)
				:wikitext(config.title):done():done()
	end

	local nameRow = mw.html.create('tr')
	local imageRow = mw.html.create('tr')
	
	local useIcons = Logic.nilOr(
		Logic.readBoolOrNil(args.useIcons),
		Array.all(maps, function(map) return String.isNotEmpty(map.icon) end)
	)

	for _, mapData in ipairs(maps) do
		nameRow:tag('th')
			:wikitext('[[' .. mapData.link .. '|' .. mapData.name .. ']]'):done()

		imageRow:tag('td')
			:css('padding', 0)
			:wikitext(Maps.buildImage(mapData, args.size or 'x100px', useIcons)):done()
	end

	display
		:node(nameRow:done())
		:node(imageRow:done())

	if args.note then
		display:tag('tr')
			:tag('td')
				:attr('colspan', #mapList)
				:css('text-align', 'left')
				:wikitext(args.note)
	end

	return mw.html.create('div'):addClass('table-responsive'):node(display)
end

function Maps.buildImage(map, size, useIcons)
	local image = PLACEHOLDER
	if useIcons and String.isNotEmpty(map.icon) then
		image = map.icon
	elseif String.isNotEmpty(map.image) then
		image = map.image
	end
	return '[[File:' .. image .. '|' .. size .. '|link=' .. map.link .. ']]'
end

return Class.export(Maps)