Module:Game

From StrategyWiki, the video game walkthrough and strategy guide wiki

Documentation for this module may be created at Module:Game/Documentation

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

local p = {}

local args = {}
local root
local newRoot
local gameContainer

local function getArgNums(prefix)
	-- Returns a table containing the numbers of the arguments that exist
	-- for the specified prefix. For example, if the prefix was 'data', and
	-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
	local nums = {}
	for k, v in pairs(args) do
		local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
		if num then table.insert(nums, tonumber(num)) end
	end
	table.sort(nums)
	return nums
end

local function renderCompletion()
	args.completion = args.completion or "0"
	if args.completion == "5" then
		link = "[[:Category:Guides at completion stage 5|Featured]]"
	else
		link = "[[:Category:Guides at completion stage "  .. args.completion .. "|Stage " .. args.completion .. "]]"
	end
	newRoot:wikitext(mw.getCurrentFrame():extensionTag( 
		'indicator', 
		"[[File:000" .. args.completion 
		.. ".svg|32px|This guide is at completion stage " .. args.completion 
		.. ". Click here for more information.|link=:Category:Guides at completion stage " 
		.. args.completion .. "]] " .. link, 
		{ name = 'cs' } ) )
end

local function renderSeriesDisambig()
	args.seriesDisambig = args.seriesDisambig or args.title or mw.title.getCurrentTitle().text
	
	if args.seriesDisambig == args.series or args.seriesDisambig == args.series2 or args.seriesDisambig == args.series3 or args.seriesDisambig == args.series4 then
		local seriesCat = mw.title.new( args.seriesDisambig, 14 )
		newRoot
			:wikitext("<p class='noexcerpt'>''This is the first game in the '''" .. seriesCat.text .. "''' series. For other games in the series see the [[:" .. seriesCat.prefixedText .. "|" .. seriesCat.text .. " category]].''</p>" )
	end
end

local function addRow( rowArgs )
	-- Adds a row to the infobox, with either a header cell
	-- or a label/data cell combination.
	if rowArgs.header then
		root
			:tag( 'tr' )
				:addClass( rowArgs.rowclass )
				:tag( 'th' )
					:attr( 'colspan', 2 )
					:css( 'text-align', 'center' )
					:cssText( rowArgs.headerstyle )
					:wikitext( rowArgs.header )
	else
		local row = root:tag( 'tr' ):addClass( rowArgs.rowclass )

		if rowArgs.label then
			row
				:tag( 'th' )
					:cssText( rowArgs.labelstyle )
					:wikitext( rowArgs.label )
					:done()
		end

		local dataCell = row:tag( 'td' )
		if not rowArgs.label then
			dataCell
				:attr( 'colspan', 2 )
				:cssText( rowArgs.rowstyles or 'text-align: center;' )
		end
		dataCell
			:wikitext( rowArgs.data )
	end
end

local function renderTitle()
	args.title = args.title or mw.title.getCurrentTitle().text

	root
		:tag( 'tr' )
			:tag( 'th' )
				:attr( 'colspan', 2 )
				:addClass( 'infobox_heading' )
				:wikitext( args.title )
end

local function renderImage()
	if args.image then
		gameContainer:wikitext( '[[File:' .. args.image .. '|250px|left|Box artwork for ' .. args.title .. '.]]' )
	end
end

local function renderRows()
	if args.japanese then addRow( {label = 'Japanese title', data = args.japanese} ) end
	if args.designer then addRow( {label = 'Designer(s)', data = args.designer} ) end
	addRow( { label = 'Genre(s)', data = args.genre, rowclass = 'mw-row-no-collapse' } )
	if args.players then addRow( {label = 'Players', data = args.players} ) end
	if args.modes then addRow( {label = 'Modes', data = args.modes} ) end
	if args.version then addRow( {label = 'Latest version', data = args.version} ) end
	if args.ratings then addRow( { label = 'Rating(s)', data = args.ratings, rowclass = 'mw-row-no-collapse' } ) end
	if args.input then addRow( {label = 'Input', data = args.input} ) end
end

local function renderRowsCommon()
	addRow( { label = 'Developer(s)', data = args.developer } )
	addRow( { label = 'Publisher(s)', data = args.publisher } )
	if args.year then dataYear = '[[:Category:' .. args.year .. '|' .. args.year .. ']]' else dataYear = "" end
	addRow( { label = 'Year released', data = dataYear } )
	addRow( { label = 'System(s)', data = args.systems, rowclass = 'mw-row-no-collapse' } )
	if args.expansion then addRow( { label = 'Expansion pack(s)', labelstyle = 'white-space: nowrap;', data = args.expansion } ) end
	if args['preceded by'] then addRow( { label = 'Preceded by', labelstyle = 'white-space: nowrap;', data = "''" .. args['preceded by'] .. "''" } ) end
	if args['followed by'] then addRow( { label = 'Followed by', labelstyle = 'white-space: nowrap;', data = "''" .. args['followed by'] .. "''" } ) end
	if args.series then
		local data2 = ''
		if args.series2 then data2 = ',<br />[[:Category:' .. args.series2 .. '|' .. args.series2 .. ']]' end
		if args.series3 then data2 = data2 .. ',<br />[[:Category:' .. args.series3 .. '|' .. args.series3 .. ']]' end
		if args.series4 then data2 = data2 .. ',<br />[[:Category:' .. args.series4 .. '|' .. args.series4 .. ']]' end
		addRow( { label = 'Series', data = '[[:Category:' .. args.series .. '|' .. args.series .. ']]' .. data2 } )
	end
end

local function renderRelease( listnum )
	if args[ 'title' .. listnum ] then
		root
			:tag( 'tr' )
				:tag( 'th' )
					:attr( 'colspan', 2 )
					:addClass( 'infobox_heading' )
					:wikitext( args[ 'title' .. listnum ] )
	end

	if args[ 'japanese' .. listnum ] then addRow( {label = 'Japanese title', data = args[ 'japanese' .. listnum ]} ) end
	addRow( { label = 'Developer(s)', data = args[ 'developer' .. listnum ], rowclass = 'mw-row-no-collapse' } )
	addRow( { label = 'Publisher(s)', data = args[ 'publisher' .. listnum ] } )
	addRow( { label = 'Year released', data = '[[:Category:' .. args[ 'year' .. listnum ] .. '|' .. args[ 'year' .. listnum ] .. ']]', rowclass = 'mw-row-no-collapse' } )
	root:wikitext( '[[Category:' .. args[ 'year' .. listnum ] .. ']]' )
	addRow( { label = 'System(s)', data = args[ 'systems' .. listnum ], rowclass = 'mw-row-no-collapse' } )
	if args[ 'version' .. listnum ] then addRow( {label = 'Latest version', data = args[ 'version' .. listnum ]} ) end
	if args[ 'ratings' .. listnum ] then addRow( { label = 'Rating(s)', data = args[ 'ratings' .. listnum ] } ) end
	if args[ 'input' .. listnum ] then addRow( {label = 'Input', data = args[ 'input' .. listnum ]} ) end
end

local function renderSocialRows()
	local linksData = ''

	local pagename = mw.uri.encode( mw.title.getCurrentTitle().text, "PATH" )

	linksData = linksData .. mw.getCurrentFrame():preprocess( '{{switcherlink}}' )	

	if args.website then
		linksData = linksData .. '<span class="img-ib-inline">[[File:Link icon.svg|x20px|link=' .. args.website .. '|' .. 'Official website]]</span>'
	end

	if args.pcgamingwiki then
		linksData = linksData .. '<span class="img-ib-inline">[[File:PCGamingWikiLink.svg|x20px|link=pcgamingwiki:' .. args.pcgamingwiki .. '|' .. mw.title.getCurrentTitle().text .. ' at PCGamingWiki]]</span>'
	end

	if args.twitch then
		linksData = linksData .. '<span class="img-ib-inline">[[File:Twitch icon.png|x20px|link=https://www.twitch.tv/directory/game/' .. mw.uri.encode( args.twitch, "PATH" ) .. '|' .. args.twitch .. ' Channel]]</span>'
	else
		linksData = linksData .. '<span class="img-ib-inline img-greyscale">[[File:Twitch icon.png|x20px|link=https://www.twitch.tv/directory/game/' .. pagename .. '|' .. mw.title.getCurrentTitle().text .. ' Channel]]</span>'
	end

	if args.twitter then
		linksData = linksData .. '<span class="img-ib-inline">[[File:Twitter icon.png|x20px|link=https://twitter.com/' .. args.twitter .. '|' .. args.twitter .. ']]</span>'
	else
		linksData = linksData .. '<span class="img-ib-inline img-greyscale">[[File:Twitter icon.png|x20px|link=https://twitter.com/search?f=user&q=' .. pagename .. '|Search]]</span>'
	end

	if args.facebook then
		linksData = linksData .. '<span class="img-ib-inline">[[File:Facebook icon.png|x20px|link=https://www.facebook.com/' .. args.facebook .. '|' .. args.facebook .. ']]</span>'
	else
		linksData = linksData .. '<span class="img-ib-inline img-greyscale">[[File:Facebook icon.png|x20px|link=https://www.facebook.com/search/pages/?q=' .. pagename .. '|Search]]</span>'
 	end

	addRow( { label = 'Links', data = linksData } )

end

local function renderTrackingCategories()
	root:wikitext( '[[Category:Games]]' )

	if args.completion then
		root:wikitext( '[[Category:Guides at completion stage ' .. args.completion .. ']]' )
	end

	if not args.image then
		root:wikitext( '[[Category:Pages needing box artwork]]' )
	end

	if args.year then
		root:wikitext( '[[Category:' .. args.year .. ']]' )
	end

	if not args.developer or not args.publisher or not args.genre or not args.systems or not args.year then
		root:wikitext( '[[Category:Pages needing an infobox]]' )
	end

	if args.series then
		root:wikitext( '[[Category:' .. args.series .. ']]' )
	end
	if args.series2 then
		root:wikitext( '[[Category:' .. args.series2 .. ']]' )
	end
	if args.series3 then
		root:wikitext( '[[Category:' .. args.series3 .. ']]' )
	end
	if args.series4 then
		root:wikitext( '[[Category:' .. args.series4 .. ']]' )
	end
end

local function _game()
	newRoot = mw.html.create()
	renderCompletion()
	renderSeriesDisambig()
	gameContainer = newRoot:tag( 'div' )
	gameContainer
		:addClass( 'game-infobox-container' )

	renderImage()

	root = gameContainer:tag( 'table' )
	root
		:addClass( 'infobox' )
		:addClass( 'bordered' )

	renderTitle()
	renderRowsCommon()

	root = mw.html.create( 'table' )
	root
		:addClass( 'infobox' )
		:addClass( 'bordered' )

	renderRows()
	newRoot:node( root )

	local releasenums = getArgNums( 'title' )
	for k, num in ipairs( releasenums ) do
		root = mw.html.create( 'table' )

		root
			:addClass( 'infobox' )
			:addClass( 'bordered' )
			:addClass( 'mw-collapsible' )
			:addClass( 'mw-collapsed' )

		renderRelease( num )
		newRoot:node( root )
	end

	root = mw.html.create( 'table' )

	root
		:addClass( 'infobox' )
		:addClass( 'bordered' )
		:addClass( 'noprint' )
		:css( 'clear', 'right' )

	root
		:wikitext( mw.getCurrentFrame():preprocess( '<NeoLink />' ) )

	renderSocialRows()
	renderTrackingCategories()

	newRoot:node( root )

	return tostring( newRoot ) .. mw.getCurrentFrame():expandTemplate{ title = 'WikiList', args = { 'games', args.title } } .. '<div style="clear: left;"></div>'
end

function p.game( frame )
	args = getArgs( frame, { wrappers = 'Template:Game' } )

	return _game()
end

return p