Halo Esports Wiki

We are currently performing extensive maintenance to this wiki and as a result there will likely be errors. Please be patient while we work to fix all problems.

READ MORE

Halo Esports Wiki
Advertisement

To edit the documentation or categories for this module, click here.

See {{MatchDetails}} for usage information.


local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require('Module:EsportsUtil')
local util_html = require('Module:HtmlUtil')
local util_map = require('Module:MapUtil')
local util_matches = require('Module:MatchesUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_toggle = require('Module:ToggleUtil')
local util_vars = require('Module:VarsUtil')

local m_team = require('Module:Team')

local lang = mw.getLanguage('en')

sep = '%s*,%s*'

local VODLIST = { 'Vod', 'Vod2', 'Vod3', 'Vod4', 'Vod5', 'Vod6', 'Vod7' }

local HIDDENCLASS = 'toggle-section-hidden'
local TAB_TOGGLES = {
	row = 'mdv-allweeks mdv-week%s %s',
	all = {
		show_attr = '.mdv-allweeks',
		hide_attr = '.mdv-showbuttons',
		show_class = 'mdv-allweeks',
		hide_class = 'mdv-showbuttons',
		show_text = 'show all',
		hide_text = 'hide all',
	},
	week = {
		show_attr = '.mdv-week%s',
		hide_attr = '.mdv-showbutton%s',
		show_class = 'mdv-allweeks mdv-week%s',
		hide_class = 'mdv-showbuttons mdv-showbutton%s',
	}
}

local i18n = {
	Vod = 'Vod',
	Vod2 = 'Vod2',
	Vod3 = 'Vod3',
	Vod4 = 'Vod4',
	Vod5 = 'Vod5',
	Vod6 = 'Vod6',
	Vod7 = 'Vod7',
	Team1Display = 'Team 1',
	Team2Display = 'Team 2',
	Selection = 'Side Sel',
	header = 'VODs & Match Links',
	Highlights = 'HL',
}

local FIELD_ORDER = {
	match = { 'Team1', 'Team2', 'Score', 'PBP', 'Color', 'Interview', 'With', 'Highlights', 'Recap', 'Reddit', 'MVP', 'VODs' },
	game = { 'Blue', 'Red', 'Selection', 'MH', 'Interview', 'With', 'MVP' }
}

local FIELD_LOOKUP = {
	match = {
		pbp = 'PBP',
		color = 'Color',
		int = 'Interview',
		interview = 'Interview',
		w = 'With',
		with = 'With',
		recap = 'Recap',
		reddit = 'Reddit',
		vods = 'VODs',
		mvp = 'MVP',
		hl = 'Highlights',
		highlights = 'Highlights'
	},
	game = {
		b = 'Blue',
		blue = 'Blue',
		r = 'Red',
		red = 'Red',
		ssel = 'Selection',
		['side selection'] = 'Selection',
		mh = 'MH',
		['match history'] = 'MH',
		int = 'Interview',
		interview = 'Interview',
		w = 'With',
		with = 'With',
		mvp = 'MVP',
	}
}

local THIS

local h = {}

local p = {}
function p.main(frame)
	local args = util_args.merge()
	local overviewPage = util_esports.getOverviewPage(args.page)
	local matchData = h.getMatchData(overviewPage, args)
	THIS = util_matches.determineThis(matchData, args.This)
	local gameData = h.getGameData(overviewPage, args)
	h.addGameDataToMatches(matchData, gameData)
	local fields = h.pickFields(args.matchfields, args.gamefields)
	return h.makeOutput(matchData, fields)
end

function h.getMatchData(page, args)
	local matchResult = util_cargo.queryAndCast(h.makeMatchQuery(page, args))
	util_map.rowsInPlace(matchResult, h.processMatchRow)
	local matchData = util_cargo.groupResultOrdered(matchResult, 'Tab')
	return matchData
end

function h.makeMatchQuery(page, args)
	local query = {
		tables = 'MatchSchedule',
		fields = {
			'Team1',
			'Team2',
			'Player1',
			'Player2',
			'Winner [number]',
			'WinnerScoreUnknown [number]',
			'Team1Score [number]',
			'Team2Score [number]',
			'FF [number]',
			'Tab',
			'UniqueMatch',
			'CastersPBP',
			'CastersColor',
			'MVP',
			'VodInterview',
			'Vod',
			'Vod2',
			'Vod3',
			'Vod4',
			'Vod5',
			'Vod6',
			'Vod7',
			'InterviewWith',
			'Recap',
			'Reddit',
			'DateTime_UTC=UTC',
		},
		where = h.makeMatchWhere(page, args),
		orderBy = 'N_Page ASC, N_TabInPage ASC, N_MatchInTab ASC',
		groupBy = 'UniqueMatch',
	}
	return query
end

function h.makeMatchWhere(page, args)
	local tbl = {
		('OverviewPage="%s"'):format(page)
	}
	return util_table.concat(tbl,' AND ')
end
	
function h.processMatchRow(row)
	row.Team1Display = h.getPlayerOrTeamDisplay(row, 1)
	row.Team2Display = h.getPlayerOrTeamDisplay(row, 2)
	if row.FF then
		row['Team' .. row.FF .. 'Score'] = 'FF'
		row['Team' .. util_esports.otherTeamN(row.FF) .. 'Score'] = 'W'
	else
		-- don't print casters if it's a forfeit
		row.PBP = util_esports.playersLinked(row.CastersPBP)
		row.Color = util_esports.playersLinked(row.CastersColor)
	end
	if row.Team1Score and row.Team2Score then
		row.Score = ('%s - %s'):format(row.Team1Score, row.Team2Score)
	elseif row.WinnerScoreUnknown then
		if row.WinnerScoreUnknown == 1 then
			row.Score = ('W - L')
		else
			row.Score = ('L - W')
		end
	else
		row.Score = 'TBD'
	end
	row.MVP = util_esports.playersLinked(row.MVP)
	row.With = util_esports.playersLinked(row.InterviewWith)
	row.Recap = util_text.extLink(row.Recap)
	row.Interview = util_text.extLink(row.VodInterview)
	row.Highlights = util_text.extLink(row.VodHighlights)
	row.Reddit = util_text.extLink(row.Reddit)
	row.VODs = h.makeMatchVodList(row)
	row.classes = {
		Team1 = row.Winner == 1 and 'md-winner',
		Team2 = row.Winner == 2 and 'md-winner'
	}
end

function h.makeMatchVodList(row)
	local tbl = {}
	for _, v in ipairs(VODLIST) do
		if row[v] then
			tbl[#tbl+1] = ('[%s %s]'):format(row[v], i18n[v])
		end
	end
	return table.concat(tbl, ' • ')
end

function h.getPlayerOrTeamDisplay(row, i)
	if not row['Player' .. i] then
		return row['Team' .. i] and m_team.rightshort(row['Team' .. i])
	end
	return m_team.onlyimageshort(row['Team' .. i]) .. util_esports.playerLinked(row['Player' .. i])
end

function h.getPostersDisplay(row)
	if not row.Team1Poster and not row.Team2Poster then return nil end
	local tbl = {}
	tbl[#tbl+1] = row.Team1Poster and util_text.intLink(':' .. row.Team1Poster, m_team.short(row.Team1))
	tbl[#tbl+1] = row.Team2Poster and util_text.intLink(':' .. row.Team2Poster, m_team.short(row.Team2))
	return util_table.concat(tbl, ' • ')
end

function h.getGameData(page, args)
	local gameResult = util_cargo.queryAndCast(h.makeGameQuery(page, args))
	util_map.rowsInPlace(gameResult, h.processGameRow)
	local gameData = util_cargo.groupResultByValue(gameResult, 'UniqueMatch')
	return gameData
end

function h.makeGameQuery(page, args)
	local query = {
		tables = 'MatchScheduleGame',
		fields = {
			'Blue',
			'Red',
			'Winner [number]',
			'Selection',
			'ShownName=Selection',
			'Recap',
			'VodInterview',
			'InterviewWith',
			'MVP',
			'MatchHistory',
			'UniqueMatch',
		},
		where = h.makeGameWhere(page, args),
		orderBy = 'N_Page ASC, N_TabInPage ASC, N_MatchInTab, N_GameInMatch',
		limit = 9999,
		groupBy = 'UniqueLine',
	}
	return query
end

function h.makeGameWhere(page, args)
	local tbl = {
		('OverviewPage="%s"'):format(page)
	}
	return util_table.concat(tbl,' AND ')
end

function h.processGameRow(row)
	local hasteams = row.Blue and row.Red
	local sel = h.getSelectionSide(row)
	row.VODs = h.makeGameVodList(row)
	row.Interview = util_text.extLink(row.VodInterview)
	row.Blue = m_team.short(row.Blue)
	row.Red = m_team.short(row.Red)
	row.Selection = row.Selection and m_team.short(row.Selection)
	row.Recap = util_text.extLink(row.Recap)
	row.MH = util_text.extLink(row.MatchHistory)
	row.MVP = util_esports.playersLinked(row.MVP)
	row.With = util_esports.playersLinked(row.InterviewWith)
	row.Summary = h.makeSummary(row.Summary)
	row.Reddit = util_text.extLink(row.Reddit)
	row.classes = {
		Blue = row.Winner == 1 and 'md-winner',
		Red = row.Winner == 2 and 'md-winner',
		Selection = hasteams and row.Selection and ('standings-mh%s'):format(sel)
	}
end

function h.getSelectionSide(row)
	if not row.Selection then
		return
	end
	return row.Selection == row.Blue and 'Blue' or 'Red'
end

function h.makeGameVodList(row)
	local tbl = {}
	for _, v in ipairs(VODLIST) do
		if row[v] then
			tbl[#tbl+1] = ('[%s %s]'):format(row[v], i18n[v])
		end
	end
	return table.concat(tbl, ' • ')
end

function h.makeSummary(summary)
	if not summary then return nil end
	local popupButton = util_toggle.popupButton()
	popupButton.wrapper
		:addClass('written-summary-outer')
	popupButton.inner:addClass('written-summary-inner')
		:wikitext(summary)
	return tostring(popupButton.tbl)
end

function h.addGameDataToMatches(matchData, gameData)
	for _, tab in ipairs(matchData) do
		for _, row in ipairs(tab) do
			row.gameData = gameData[row.UniqueMatch] or { { classes = {} } }
		end
	end
	return true
end

-- output
function h.pickFields(matcharg, gamearg)
	local matchfields = util_text.split(matcharg or '',sep)
	local gamefields = util_text.split(gamearg or '',sep)
	local tbl = {
		match = { 'Team1Display', 'Team2Display', 'Score' },
		game = {}
	}
	for _, v in ipairs(matchfields) do
		tbl.match[#tbl.match+1] = FIELD_LOOKUP.match[lang:lc(v)]
	end
	for _, v in ipairs(gamefields) do
		tbl.game[#tbl.game+1] = FIELD_LOOKUP.game[lang:lc(v)]
	end
	util_table.sortByKeyOrder(tbl.match, FIELD_ORDER.match)
	util_table.sortByKeyOrder(tbl.game, FIELD_ORDER.game)
	return tbl
end

function h.makeOutput(matchData, fields)
	local colspan = #fields.match + #fields.game
	local output = mw.html.create()
	local tbl = output:tag('table')
		:addClass('wikitable')
		:addClass('md-table')
		:attr('id','md-table')
		:css('min-width', math.max(22, 2 * colspan) .. 'em')
	if #matchData > 1 then
		util_toggle.printToggleHeader(tbl, colspan, i18n.header, TAB_TOGGLES.all)
	else
		util_html.printColspanHeader(tbl, i18n.header, colspan)
	end
	for i, tabData in ipairs(matchData) do
		h.printTab(tbl, tabData, fields, i, THIS == i)
	end
	return output
end

function h.printTab(tbl, tabData, fields, i, isfocused)
	h.printColspanHeading(tbl, tabData.name, fields, i, isfocused)
	local toggle_class = h.getRowToggleClass(i, isfocused)
	h.printHeading(tbl, fields, toggle_class)
	for _, row in ipairs(tabData) do
		h.printRow(tbl, row, fields, toggle_class)
	end
end

function h.printColspanHeading(tbl, name, fields, i, isfocused)
	local toggle_data = h.getWeekToggleData(i, isfocused)
	local colspan = #fields.match + #fields.game
	util_toggle.printToggleHeader(tbl, colspan, name, toggle_data)
end

function h.getWeekToggleData(i, isfocused)
	local data = mw.clone(TAB_TOGGLES.week)
	data.initshown = isfocused
	util_toggle.prepDataByWeek(data, i)
	return data
end

function h.getRowToggleClass(i, isfocused)
	return TAB_TOGGLES.row:format(i, isfocused and '' or HIDDENCLASS)
end

function h.printHeading(tbl, fields, toggle_class)
	local tr = tbl:tag('tr')
		:addClass('column-label-small')
		:addClass(toggle_class)
	for _, v in ipairs(fields.match) do
		tr:tag('th'):wikitext(i18n[v] or v)
	end
	for _, v in ipairs(fields.game) do
		tr:tag('th'):wikitext(i18n[v] or v)
	end
	return
end

function h.printRow(tbl, row, fields, toggle_class)
	local tr = tbl:tag('tr')
		:addClass(toggle_class)
	local rowspan = h.getRowspan(fields.game, row.gameData, row.FF)
	h.printMatchFields(tr, row, fields.match, rowspan)
	local gameData = row.FF and { { classes = {} } } or row.gameData
	h.printGamesFields(tbl, tr, gameData, fields.game, toggle_class)
end

function h.getRowspan(game, gameData, isFF)
	if not game or not next(gameData) or isFF then
		return 1
	else
		return #gameData
	end
end

function h.printMatchFields(tr, row, fields, rowspan)
	for _, v in ipairs(fields) do
		tr:tag('td')
			:attr('rowspan',rowspan)
			:addClass(row.classes[v] or '')
			:wikitext(row[v])
	end
end

function h.printGamesFields(tbl, tr, gameData, fields, toggle_class)
	for i, game in ipairs(gameData) do
		if i ~= 1 then
			tr = tbl:tag('tr')
				:addClass(toggle_class)
		end
		h.printOneGameFields(tr, game, fields)
	end
end

function h.printOneGameFields(tr, game, fields)
	for _, v in ipairs(fields) do
		tr:tag('td')
			:addClass(game.classes[v] or '')
			:wikitext(game[v])
	end
end

return p
Advertisement