Leaguepedia | League of Legends Esports Wiki
Advertisement
Leaguepedia | League of Legends Esports Wiki

To edit the documentation or categories for this module, click here. This module has an i18n file. Click here to edit it.

For the query, see Special:RunQuery/TournamentStatistics


local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require('Module:EsportsUtil')
local util_form = require('Module:FormUtil')
local util_game = require('Module:GameUtil')
local util_html = require('Module:HtmlUtil')
local util_map = require('Module:MapUtil')
local util_math = require('Module:MathUtil')
local util_sort = require('Module:SortUtil')
local util_stats = require('Module:StatsUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local i18n = require('Module:i18nUtil')
local Sprite = require('Module:Sprite').sprite
local m_team = require('Module:Team')
local Role = require('Module:Role')
local RoleList = require('Module:RoleList')
local Champion = require('Module:Champion')
local ChampionList = require('Module:ChampionList')
local RegionList = require('Module:RegionList')
local MostRecentGameIncluded = require('Module:MostRecentGameIncluded').main
local SETTINGS = require('Module:ScoreboardPlayerStats/Settings')
local PRELOAD
local MAX_SUBJECT_TEAMS = 5
local SHOWN_ITEMS_PER_LIST = { Champion = 3, Role = 5 }
local LCS = require('Module:LuaClassSystem')

local s = {}
function s.ChampionSprite(id, link)
	return Sprite{
		id,
		size = 25,
		type = 'Champion',
		--nosize = true,
		notext = true,
		link = link,
	}
end
function s.RoleSprite(id, link)
	return Sprite{
		id,
		size = 20,
		type = 'Role',
		--nosize = true,
		notext = true,
		link = link,
	}
end
local h = {}
local p = LCS.class
h.GAMES_ALREADY_INCLUDED = {}
function p.main(frame)
	local args = util_args.merge()
	return p:_main(args)
end
function p:_main(args)
	i18n.init('ScoreboardPlayerStats')
	h.GAMES_ALREADY_INCLUDED = {}
	h.setPreloadAndValidate(args)
	local args2 = h.castArgs(args)
	local dataFromQuery = self:getData(args2)
	if #dataFromQuery == 0 and args2.require_results then
		return '[[Category:Empty ScoreboardPlayerStats]]'
	end
	local output = mw.html.create('div'):addClass('wide-content-scroll')
	return MostRecentGameIncluded(args, self.query),
		self:printOutputFromData(output, dataFromQuery, args, args2)
end
function p:printOutputFromData(output, dataFromQuery, args, args2)
	i18n.init('ScoreboardPlayerStats')
	h.GAMES_ALREADY_INCLUDED = {}
	h.setPreloadAndValidate(args)
	local dataCounted = h.countData(dataFromQuery)
	h.formatData(dataCounted, args)
	h.printOutput(output, dataCounted, PRELOAD.headings, args)
	local tournamentList = h.makeIncludedTournaments(dataCounted.total.lists.Tournament, args)
	local permalink = h.makePermalink(args, args2)
	return output, tournamentList, permalink
end
function p:CPTMH(output, dataFromQuery, args)
	-- this only exists because it used to exist. it's kind of gross. if maintaining this makes your life impossibly hard just kill it.
	-- used by MatchHistoryPlayer
	i18n.init('ScoreboardPlayerStats')
	PRELOAD = SETTINGS.preloads.cptmh
	local cptmhArgs = h.getSetOfArgsForCPTMH(args)
	h.printLabels(output, PRELOAD.headings)
	for _, thisArgs in ipairs(cptmhArgs) do
		local thisArgs2 = h.castArgs(thisArgs)
		local thisData = self:getData(thisArgs2)
		local dataCounted = {}
		h.countRowsInTotal(dataCounted, thisData)
		dataCounted.total = h.formatTotalsAsCPTMH(dataCounted.total, thisArgs)
		h.printTotalLine(output, dataCounted.total, PRELOAD.headings)
	end
end
function h.getSetOfArgsForCPTMH(args)
	local argsChampionOnly = mw.clone(args)
	local argsPlayerOnly = mw.clone(args)
	argsChampionOnly.link = nil
	argsPlayerOnly.champion = nil
	args.label = i18n.print('cptmh_total')
	argsChampionOnly.label = i18n.print('cptmh_total_champion', Champion(args.champion):flair())
	argsPlayerOnly.label = i18n.print('cptmh_total_player', util_text.intLinkOrText(args.link))
	return { args, argsChampionOnly, argsPlayerOnly }
end
function h.setPreloadAndValidate(args)
	PRELOAD = h.getPreload(args.preload)
	util_stats.validatePreload(args, PRELOAD)
end
function h.getPreload(str)
	local preload = SETTINGS.preloads[str:lower()]
	if not preload then
		error(i18n.print('error_invalidPreload'))
	elseif type(preload) == 'string' then
		preload = SETTINGS.preloads[preload]
	end
	return preload
end
function h.castArgs(args)
	local args2 = mw.clone(args)
	args2.role = RoleList(args2.role, {sep=','})
	args2.champion = RoleList(args2.champion)
	args2.region = RegionList(args2.region)
	args2.require_results = util_args.castAsBool(args.require_results)
	return args2
end
-- get dataFromQuery / cargo
function p:getData(args)
	self.query = h.getGeneralQuery(args)
	util_vars.log(self.query.where)
	util_vars.log(self.query.tables)
	util_vars.log(self.query.join)
	local dataFromQuery = util_cargo.queryAndCast(self.query)
	if PRELOAD.bans then
		dataFromQuery.bans = util_cargo.queryAndCast(h.getBanQuery(args))
	end
	return dataFromQuery
end
function h.getGeneralQuery(args)
	return {
		tables = h.getGeneralTables(args),
		join = h.getGeneralJoin(args),
		fields = h.getGeneralFields(args),
		where = h.getGeneralWhere(args),
		limit = args.limit or 9999,
		orderBy = 'SG.DateTime_UTC ASC',
	}
end
function h.getGeneralTables(args)
	local ret = {
		'ScoreboardGames=SG',
		'Tournaments=T',
		'ScoreboardPlayers=SP',
		'ScoreboardPlayers=SPVs',
		'PlayerRedirects=PR',
		'TeamRedirects=TRed',
	}
	return ret
end
function h.getGeneralJoin(args)
	local ret = {
		'SG.GameId=SP.GameId',
		'T.OverviewPage=SG.OverviewPage',
		'SP.UniqueLineVs=SPVs.UniqueLine',
		'SP.Link=PR.AllName',
		'SP.Team=TRed.AllName',
	}
	return ret
end
function h.getGeneralFields(args)
	local ret = {
		'COALESCE(PR._pageName, SP.Link)=Link',
		'SP.Name=Name',
		'SP.Team=Team',
		'SP.Champion=Champion',
		'SP.Kills=K [number]',
		'SP.Deaths=D [number]',
		'SP.Assists=A [number]',
		'SP.Gold=G [number]',
		'SP.CS=CS [number]',
		'SP.IngameRole=Role',
		'SP.TeamKills=TeamKills',
		'SP.TeamGold=TeamGold',
		'T.StandardName=Tournament',
		'SP.PlayerWin=PlayerWin [boolean]',
		'SP.GameId',
		'SG.Gamelength_Number=Len [number]',
		'T.Region=RegionPlaintext',
		'T._pageName=_pageName',
		'SG.GameId',
		'SG._pageName=SBPage',
	}
	if not util_args.castAsBool('skiptypes') then
		ret[#ret+1] = 'T.Region=Region [region]'
	end
	return ret
end
function h.getGeneralWhere(args)
	local tbl = {
		'SP._pageName IS NOT NULL',
		util_cargo.whereFromArg('(%s)', args.where),
		util_cargo.whereFromArgList('SP.OverviewPage="%s"', args.tournament, nil, util_title.target),
		h.getLinkWhereCondition(args.link),
		util_cargo.whereFromArgList('TRed._pageName="%s"', args.team,  nil, m_team.teamlinkname),
		util_cargo.whereFromCompoundEntity('SP.Champion="%s"', args.champion),
		util_cargo.whereFromCompoundEntity('SP.IngameRole="%s"', args.role),
		util_cargo.whereFromCompoundEntity('T.Region="%s"', args.region),
		util_cargo.whereFromArgList('T.Year="%s"', args.year),
		util_cargo.whereFromArgList('T.TournamentLevel="%s"', args.tournamentlevel),
		util_cargo.whereFromArgList('SG.Patch="%s"', args.patch),
	}
	h.validateWhere(tbl)
	return util_cargo.concatWhere(tbl)
end
function h.getLinkWhereCondition(link)
	if not link then return nil end
	if mw.title.new(link, '').exists then
		return util_cargo.whereFromArgList('PR._pageName="%s"', link, nil, util_title.target)
	else
		return util_cargo.whereFromArgList('SP.Link="%s"', link, nil, util_title.target)
	end
end
function h.validateWhere(tbl)
	local total = 0
	for _, v in pairs(tbl) do
		if v then total = total + 1 end
	end
	if total == 1 then error(i18n.print('error_NoWhere')) end
end
function h.getBanQuery(args)
	return {
		tables = { 'ScoreboardGames=SG', 'Tournaments=T' },
		join = 'SG.OverviewPage=T.OverviewPage',
		fields = h.getBanFields(args),
		where = h.getBanWhere(args),
		limit = args.limit or 9999
	}
end
function h.getBanFields(args)
	local ret = {
		'SG.Team1Bans__full=Team1Bans',
		'SG.Team2Bans__full=Team2Bans',
		'SG.GameId',
		'T.Region=Region [region]',
		'T.Region=RegionPlaintext',
		'T.StandardName=Tournament',
	}
	return ret
end
function h.getBanWhere(args)
	-- role, as a RoleList object, will always exist
	-- if it's undefined, it will be `is_nil`
	if not args.role.is_nil or args.link then
		error(i18n.print('invalidBanArg'))
	end
	local tbl = {
		'SG._pageName IS NOT NULL',
		util_cargo.whereFromArg('(%s)', args.where),
		util_cargo.whereFromArgList('SG.OverviewPage="%s"', args.tournament, nil, util_title.target),
		util_cargo.whereFromArgList('T.Year="%s"', args.year),
		util_cargo.whereFromArgList('T.TournamentLevel="%s"', args.tournamentlevel),
		util_cargo.whereFromCompoundEntity('T.Region="%s"', args.region),
		util_cargo.whereFromArgList('SG.Patch="%s"', args.patch),
		h.getChampionBanWhere(args.champion),
	}
	return util_cargo.concatWhere(tbl)
end
function h.getChampionBanWhere(champion)
	if not champion:exists() then return nil end
	local tbl = {
		util_cargo.fakeHolds('SG.Team1Bans', champion),
		util_cargo.fakeHolds('SG.Team2Bans', champion),
	}
	return util_cargo.concatWhereOr(tbl)
end
-- count data
function h.countData(dataFromQuery)
	local dataCounted = {}
	h.countRowsByGroup(dataCounted, dataFromQuery)
	h.countRowsInTotal(dataCounted, dataFromQuery)
	dataCounted.playerLinks = h.getPlayerLinks(dataFromQuery)
	if PRELOAD.bans then
		h.addBanDataToData(dataCounted, dataFromQuery.bans)
	end
	if PRELOAD.count_bans_by_group then
		h.addBanCountsToGames(dataCounted.total.lists.Tournament, dataFromQuery.bans)
	end
	dataCounted.count = h.getCounts(dataFromQuery, dataCounted)
	return dataCounted
end
function h.countRowsByGroup(dataCounted, dataFromQuery)
	for _, row in ipairs(dataFromQuery) do
		h.countRow(dataCounted, row)
	end
end
function h.countRowsInTotal(dataCounted, dataFromQuery)
	dataCounted.total = h.getTableOfZeroes()
	for _, row in ipairs(dataFromQuery) do
		h.updateCountsFromDataRow(dataCounted.total, row)
		h.GAMES_ALREADY_INCLUDED[row.GameId] = true
	end
end
function h.countRow(dataCounted, row)
	h.verifyRow(row)
	h.initRowCount(dataCounted, row[PRELOAD.groupby])
	h.updateCountsFromDataRow(dataCounted[row[PRELOAD.groupby]], row)
end
function h.verifyRow(row)
	if not row[PRELOAD.groupby] then
		util_vars.log(row)
		error(i18n.print('error_missing_key', PRELOAD.groupby, row.GameId or row.SBPage or row._pageName))
	end
end
function h.initRowCount(dataCounted, groupName)
	if dataCounted[groupName] then return end
	dataCounted[#dataCounted+1] = groupName
	dataCounted[groupName] = h.getTableOfZeroes(groupName)
end
function h.getTableOfZeroes(groupName)
	return {
		Group = groupName,
		Games = 0,
		Contests = 0,
		Wins = 0,
		K = 0,
		D = 0,
		A = 0,
		CS = 0,
		G = 0,
		Len = 0,
		TeamKills = 0,
		TeamGold = 0,
		lists = h.initRowCountLists()
	}
end
function h.initRowCountLists()
	local ret = {}
	for _, v in ipairs(SETTINGS.lists) do
		ret[v] = {}
	end
	return ret
end
function h.updateCountsFromDataRow(countedData, row)
	h.incrementGames(countedData, h.getWinValue(row.PlayerWin))
	h.updateRunningTotals(countedData, row)
	h.updateLists(countedData.lists, row)
end
function h.incrementGames(dataRow, winValue)
	dataRow.Games = dataRow.Games + 1
	dataRow.Contests = dataRow.Contests + 1
	dataRow.Wins = dataRow.Wins + winValue
end
function h.getWinValue(playerWin)
	return playerWin and 1 or 0
end
function h.updateRunningTotals(groupedData, row)
	for _, v in ipairs({'K', 'D', 'A', 'CS', 'G', 'Len', 'TeamKills', 'TeamGold'}) do
		if groupedData[v] and row[v] then
			groupedData[v] = groupedData[v] + row[v]
		else
			groupedData[v] = nil
		end
	end
	groupedData.Team = row.Team
	groupedData.Region = row.Region
	groupedData.Tournament = row.Tournament
end
function h.updateLists(lists, row)
	if h.GAMES_ALREADY_INCLUDED[row.GameId] then return end
	for _, v in ipairs(SETTINGS.lists) do
		h.updateOneList(lists[v], row[v])
	end
end
function h.updateOneList(list, val)
	if not val then return end
	h.initRowGroupCount(list, val)
	list[val] = list[val] + 1
end
function h.initRowGroupCount(keyList, rowValue)
	if not keyList[rowValue] then
		keyList[#keyList+1] = rowValue
		keyList[rowValue] = 0
	end
end
function h.addBanCountsToGames(list, banDataFromQuery)
	for _, row in ipairs(banDataFromQuery) do
		if not h.GAMES_ALREADY_INCLUDED[row.GameId] then
			h.updateOneList(list, row.Tournament)
		end
		h.GAMES_ALREADY_INCLUDED[row.GameId] = true
	end
end
function h.getCounts(dataFromQuery, dataCounted)
	return {
		lines = #dataCounted,
		games = util_table.generalLength(h.GAMES_ALREADY_INCLUDED),
		cargo_results = #dataFromQuery,
	}
end
function h.getPlayerLinks(dataFromQuery)
	local ret = {}
	for _, row in ipairs(dataFromQuery) do
		if row.Link then
			ret[row.Link] = util_text.intLink(row.Link, row.Name)
		end
	end
	return ret
end
function h.addBanDataToData(dataCounted, banDataFromQuery)
	local bansByCriteria = h.countBanData(banDataFromQuery)
	bansByCriteria.champion["Loss of Ban"] = nil
	bansByCriteria.champion["None"] = nil
	h.addCountedBanDataToData(dataCounted, bansByCriteria)
end
function h.countBanData(banDataFromQuery)
	if not banDataFromQuery then return {} end
	local bansByCriteria = {
		champion = {},
		group = {},
		groupConstants = {},
	}
	for _, row in ipairs(banDataFromQuery) do
		h.incrementBansByChampion(bansByCriteria.champion, row.Team1Bans)
		h.incrementBansByChampion(bansByCriteria.champion, row.Team2Bans)
		h.incrementBansByGroup(bansByCriteria.group, row)
		h.setGroupConstants(bansByCriteria.groupConstants, row)
	end
	return bansByCriteria
end
function h.incrementBansByChampion(bansByChampion, teamBans)
	for _, champ in ipairs(util_text.split(teamBans)) do
		h.initializeAndIncrement(bansByChampion, champ)
	end
end
function h.initializeAndIncrement(arr, key)
	arr[key] = 1 + (arr[key] or 0)
end
function h.incrementBansByGroup(bansByGroup, row)
	if not PRELOAD.count_bans_by_group then return end
	h.initializeAndIncrement(bansByGroup, row[PRELOAD.groupby])
end
function h.setGroupConstants(groupConstants, row)
	util_table.initTable(groupConstants, row.Tournament, {
		Region = row.RegionPlaintext,
		Tournament = row.Tournament,
		Team = row.Team,
	})
end
function h.addCountedBanDataToData(dataCounted, bansByCriteria)
	if PRELOAD.count_bans_by_group then
		h.addCountedGroupBanDataToData(dataCounted, bansByCriteria.group, bansByCriteria)
	else
		h.addCountedChampionBanDataToData(dataCounted, bansByCriteria.champion)
	end
end
function h.addCountedGroupBanDataToData(dataCounted, groupBans, bansByCriteria)
	for groupName, numberOfBans in pairs(groupBans) do
		h.initRowCountOnlyBans(dataCounted, groupName)
		h.addBanTotalsToRow(dataCounted[groupName], numberOfBans)
		h.setGroupBanConstants(dataCounted[groupName], bansByCriteria.groupConstants[groupName])
	end
end
function h.addCountedChampionBanDataToData(dataCounted, championBans)
	for champion, numberOfBans in pairs(championBans) do
		h.initRowCountOnlyBans(dataCounted, champion)
		h.addBanTotalsToRow(dataCounted[champion], numberOfBans)
	end
end
function h.initRowCountOnlyBans(dataCounted, groupName)
	if dataCounted[groupName] then return end
	dataCounted[#dataCounted+1] = groupName
	dataCounted[groupName] = {
		Group = groupName,
		Games = 0,
		Contests = 0,
		Wins = 0,
		onlybans = true,
		lists = {
			Champion = {},
			Link = {},
			Role = {},
			Team = {},
			Region = {}, -- plaintext key
			Tournament = {}
		}
	}
end
function h.addBanTotalsToRow(row, bans)
	row.Bans = bans
	row.Contests = row.Contests + bans
end
function h.setGroupBanConstants(group, constants)
	group.Team = constants.Team
	group.Region = constants.Region -- plaintext
	group.Tournament = constants.Tournament
end
-- make things pretty and get totals for printing
function h.formatData(dataCounted, args)
	local format = util_args.castAsBool(args.shownet) and h.formatRowForNetDisplay or h.formatRow
	util_map.dictInPlace(dataCounted, format, dataCounted, args)
	util_sort.dictByKeys(dataCounted, PRELOAD.sort.fields, PRELOAD.sort.increasing)
	dataCounted.overall = h.formatTotalsAsOverall(dataCounted.total, dataCounted, args)
	dataCounted.total = h.formatTotalsAsTotals(dataCounted.total, args)
	dataCounted.totalGamesExtraInfo = h.getTotalGamesExtraInfo(dataCounted, args)
end
function h.formatRow(row, dataCounted, args)
	local newRow = {}
	row[PRELOAD.groupby] = row.Group
	h.copyConstants(row, newRow)
	newRow.ContestRate = util_math.percent(row.Contests / dataCounted.count.games, 0.1)
	if row.onlybans then
		h.addBanConstants(row, newRow)
	else
		h.calcPerGameTotals(row, newRow)
		newRow.GamesDisplay = h.gamesMatchHistoryQuery(row, args)
		newRow.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
		newRow.CSPM = row.CS and row.Len and util_math.roundnum(row.CS / row.Len, .01)
		newRow.Tournament = util_stats.tournamentAndRegion(row)
		h.calcLossesAndWinrate(row, newRow)
		h.calcTeamKillTotals(row, newRow)
		h.calcGoldTotalsAsPerGame(row, newRow)
		h.calcSecondaryTotals(row, newRow, args)
	end
	h.formatForDisplay(newRow, dataCounted.playerLinks)
	return newRow
end
function h.formatRowForNetDisplay(row, dataCounted, args)
	local newRow = mw.clone(row)
	newRow[PRELOAD.groupby] = row.Group
	h.copyEssentialConstants(row, newRow)
	newRow.ContestRate = util_math.percent(row.Contests / dataCounted.count.games, 0.1)
	if row.onlybans then
		h.addBanConstants(row, newRow)
	else
		newRow.GamesDisplay = h.gamesMatchHistoryQuery(row, args)
		newRow.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
		newRow.CSPM = row.CS and row.Len and util_math.roundnum(row.CS / row.Len, .01)
		newRow.Tournament = util_stats.tournamentAndRegion(row)
		h.calcLossesAndWinrate(row, newRow)
		h.calcTeamKillTotals(row, newRow)
		h.calcGoldTotalsAsTotals(row, newRow)
		h.calcSecondaryTotals(row, newRow, args)
	end
	h.formatForDisplay(newRow, dataCounted.playerLinks)
	return newRow
end
function h.formatTotalsAsOverall(row, dataCounted, args)
	local newRow = {}
	h.calcPerGameTotals(row, newRow)
	newRow.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
	newRow.CSPM = row.CS and row.Len and util_math.roundnum(row.CS / row.Len, .01)
	h.calcTeamKillTotals(row, newRow)
	h.calcGoldTotalsAsPerGame(row, newRow)
	newRow[PRELOAD.groupby] = i18n.print('OverallLabel')
	return newRow
end
function h.formatTotalsAsTotals(row, args)
	local newRow = mw.clone(row)
	newRow.GamesDisplay = row.Games
	h.calcLossesAndWinrate(row, newRow)
	newRow[PRELOAD.groupby] = i18n.print('TotalLabel')
	newRow.G = util_esports.roundedGold(row.G)
	newRow.Team = nil
	return newRow
end
function h.formatTotalsAsCPTMH(row, args)
	local newRow = {}
	newRow.GamesDisplay = row.Games
	newRow.Wins = row.Wins
	h.calcLossesAndWinrate(row, newRow)
	h.calcPerGameTotals(row, newRow)
	newRow.KDA = util_esports.calculateKDA(row.K, row.D, row.A)
	newRow.CSPM = row.CS and row.Len and util_math.roundnum(row.CS / row.Len, .01)
	h.calcTeamKillTotals(row, newRow)
	h.calcGoldTotalsAsPerGame(row, newRow)
	newRow.Label = args.label
	return newRow
end
function h.copyConstants(row, newRow)
	for _, v in ipairs({ 'Link', 'Champion', 'Team', 'Contests', 'Games', 'Wins', 'Bans' }) do
		newRow[v] = row[v]
	end
	h.copyEssentialConstants(row, newRow)
end
function h.copyEssentialConstants(row, newRow)
	for _, v in ipairs({ 'Tournament', 'Region' }) do
		newRow[v] = row[v]
	end
end
function h.calcPerGameTotals(row, newRow)
	for _, v in ipairs({ 'K', 'D', 'A', 'CS' }) do
		if row[v] then
			newRow[v] = util_math.roundnum(row[v] / row.Games, 0.01)
		end
	end
end
function h.gamesMatchHistoryQuery(row, args)
	local formArgs = util_stats.initFormArgs(args)
	formArgs.preload = PRELOAD.mh_preload
	formArgs[PRELOAD.groupby:lower()] = row.Group
	local link = util_form.fullURL(SETTINGS.form_info_mh, formArgs)
	return util_text.extLink(link, row.Games)
end
function h.calcLossesAndWinrate(row, newRow)
	newRow.Losses = row.Games - row.Wins
	newRow.Winrate = util_math.percent(row.Wins / row.Games, 0.1)
end
function h.calcTeamKillTotals(row, newRow)
	if not row.TeamKills then return end
	newRow.KPAR = util_math.percent((row.K + row.A) / row.TeamKills, .1)
	newRow.KS = util_math.percent(row.K / row.TeamKills, .1)
end
function h.calcGoldTotalsAsPerGame(row, newRow)
	if not row.G then return end
	newRow.G = util_math.roundedThousands(row.G / row.Games)
	newRow.GPM = row.Len and util_math.roundnum(row.G / row.Len, 1)
	newRow.GS = row.TeamGold and util_math.percent(row.G / row.TeamGold, .1)
end
function h.calcGoldTotalsAsTotals(row, newRow)
	if not row.G then return end
	newRow.G = util_esports.roundedGold(row.G)
	newRow.GPM = row.Len and util_math.roundnum(row.G / row.Len, 1)
	newRow.GS = row.TeamGold and util_math.percent(row.G / row.TeamGold, .1)
end
function h.calcSecondaryTotals(row, newRow, args)
	-- only support champion lists until the OO formatting is done
	for k, v in pairs(row.lists) do
		local extraFormArgs = h.totalsExtraFormArgs(row.Group)
		newRow[k .. 'N'] = util_text.extLinkOrText(h.getSecondaryForm(k, 'N', args, extraFormArgs), #v)
	end
	newRow.ChampionList = h.getSecondaryTotalsList('Champion', row, args)
	newRow.RoleList = h.getSecondaryTotalsList('Role', row, args)
end
function h.totalsExtraFormArgs(restriction)
	return { [PRELOAD.groupby:lower()] = restriction }
end
function h.getSecondaryForm(k, preloadSuffix, args, extraArgs)
	local formPreload = PRELOAD.outlinks and PRELOAD.outlinks[k .. preloadSuffix]
	if not formPreload then return end
	local formArgs = util_stats.initFormArgs(args)
	util_table.merge(formArgs, formPreload.args)
	util_table.merge(formArgs, extraArgs)
	return util_form.fullURL(formPreload.form or SETTINGS.form_info, formArgs)
end
function h.getSecondaryTotalsList(key, row, args)
	util_sort.sortConstantDictionary(row.lists[key])
	local function getFormLink(str)
		local extraFormArgs = h.listExtraFormArgs(row.Group, key, str)
		local link = h.getSecondaryForm(key, 'List', args, extraFormArgs)
		return h.pickSecondaryMarkupByType(key, str, link)
	end
	return util_table.concat(util_table.slice(row.lists[key], 1, SHOWN_ITEMS_PER_LIST[key]), '', getFormLink)
end
function h.pickSecondaryMarkupByType(key, str, link)
	if key == 'Champion' then
		return s.ChampionSprite(str, link)
	elseif key == 'Role' then
		return s.RoleSprite(str, link)
	end
end
function h.listExtraFormArgs(restriction, key, str)
	local ret =  {
		[PRELOAD.groupby:lower()] = restriction,
		[key:lower()] = str,
	}
	return ret
end
function h.addBanConstants(row, newRow)
	newRow.Wins = 0
	newRow.Losses = 0
	newRow.GamesDisplay = i18n.print('onlyBanned', 0)
	util_vars.log(newRow)
	newRow.Tournament = util_stats.tournamentAndRegion(row)
end
function h.formatForDisplay(newRow, playerLinks)
	if PRELOAD.groupby == 'Champion' then
		newRow.Champion = Champion(newRow.Champion):flair()
	elseif PRELOAD.groupby == 'Link' then
		newRow.Team = m_team.onlyimagelinked(newRow.Team)
		newRow.Link = playerLinks[newRow.Link]
	end
end
function h.getTotalGamesExtraInfo(dataCounted, args)
	if PRELOAD.subject == 'Player' then
		return i18n.print('listOfPlayerTeams', h.subjectTeams(dataCounted.total.lists.Team, args))
	elseif PRELOAD.subject == 'Champion' then
		return i18n.print('listOfChampionRoles', h.subjectRoles(dataCounted.total.lists.Role, args))
	end
end
function h.subjectTeams(list, args)
	local function formatTeam(team)
		local formArgs = util_stats.initFormArgs(args)
		formArgs.team = team
		local formLink = util_form.fullURL(SETTINGS.form_info, formArgs)
		return m_team.rightshort(team, {link = formLink})
	end
	return util_table.concat(util_table.slice(list, 1, MAX_SUBJECT_TEAMS), '', formatTeam) .. h.tooManyTeams(list)
end
function h.tooManyTeams(list)
	if #list <= MAX_SUBJECT_TEAMS then return '' end
	return '&ensp;' .. i18n.print('extraTeams', MAX_SUBJECT_TEAMS)
end
function h.subjectRoles(list, args)
	local function formatRole(role)
		local formArgs = util_stats.initFormArgs(args)
		formArgs.role = role
		local formLink = util_form.fullURL(SETTINGS.form_info, formArgs)
		return s.RoleSprite(role, formLink)
	end
	return util_table.concat(list, '', formatRole)
end
-- print output (html object was pre-created in case adding to a MH)
function h.printOutput(output, dataCounted, headings, args)
	h.printWarningsIfNeeded(output, dataCounted)
	local tbl = output:tag('table')
		:addClass('wikitable sortable spstats plainlinks hoverable-rows')
		:addClass(args.class)
	h.printHeadingCell(tbl, args, #headings, 'ScoreboardPlayerStats')
	h.printTotalGamesRow(tbl, dataCounted.count, #headings, dataCounted.totalGamesExtraInfo)
	h.printRoleLinksRow(tbl, #headings, args)
	h.printLabels(tbl, headings)
	--util_html.printEmptySortRow(tbl, #headings)
	h.printRows(tbl, dataCounted, headings)
	h.printTotals(tbl, dataCounted, headings, args)
end
function h.printWarningsIfNeeded(output, dataCounted)
	if dataCounted.count.cargo_results == 5000 then
		output:tag('div'):addClass('big'):wikitext(i18n.print('tooManyGames'))
	end
end
function h.printHeadingCell(tbl, args, colspan)
	local displayTbl = {
		util_stats.heading(args, 'ScoreboardPlayerStats'),
		i18n.print(util_args.castAsBool(args.shownet) and 'shownet' or 'showgame'),
		util_stats.openAsQueryLink(SETTINGS.form_info, args)
	}
	util_html.printColspanHeader(tbl, util_table.concat(displayTbl, ' - '), colspan)
end
function h.printTotalGamesRow(tbl, count, colspan, totalGamesExtraInfo)
	local tr = tbl:tag('tr')
	local tbl = {
		i18n.print(PRELOAD.type .. '_heading', count.games, count.lines) or i18n.print('heading'),
		totalGamesExtraInfo
	}
	tr:tag('th')
		:attr('colspan', colspan)
		:wikitext(util_table.concat(tbl, ' '))
end
function h.printRoleLinksRow(tbl, colspan, args)
	if not PRELOAD.rolelinks then return end
	local tr = util_html.innerColspanTable(tbl, colspan):tag('tr')
	local th = tr:tag('th')
	th:addClass('spstats-rolelinks-title')
		:wikitext(i18n.print('RoleRestrict'))
	h.printRoleLinkCells(tr, args)
end
function h.printRoleLinkCells(tr, args)
	for i = 1, util_game.players_per_team do
		local role = Role(tostring(i)):name()
		tr:tag('td')
			:addClass('spstats-rolelinks-cell')
			:wikitext(util_text.extLink(h.getRoleFormLink(role, args), role))
	end
end
function h.getRoleFormLink(role, args)
	local formArgs = util_stats.initFormArgs(args)
	formArgs.role = role
	formArgs.preload = args.preload .. 'Role'
	return util_form.fullURL(SETTINGS.form_info, formArgs)
end
function h.printLabels(tbl, headings)
	local tr = tbl:tag('tr')
	for _, v in ipairs(headings) do
		local th = tr:tag('th')
			:wikitext(h.printI18n(v, PRELOAD.type))
		h.printLabelAttrs(th, v)
	end
end
function h.printLabelAttrs(th, v)
	if not SETTINGS.attrs then return end
	for attr, val in pairs(SETTINGS.attrs[v] or {}) do
		th:attr(attr, val)
	end
end
function h.printI18n(key)
	return i18n.print(PRELOAD.type .. '_' .. key) or i18n.print(key)
end
function h.printRows(tbl, dataCounted, headings)
	for _, key in ipairs(dataCounted) do
		local tr = tbl:tag('tr')
		h.printOneRow(tr, dataCounted[key], headings)
	end
end
function h.printOneRow(tr, row, headings)
	for _, col in ipairs(headings) do
		tr:tag('td')
			:wikitext(row[col] or '-')
			:addClass(h.getClass(col))
	end
end
function h.getClass(col)
	local class = SETTINGS.classes[col]
	if not class then return nil end
	return 'spstats-' .. class
end
function h.printTotals(tbl, dataCounted, headings, args)
	if not PRELOAD.totals then return end
	for _, line in ipairs({ 'overall', 'total' }) do
		h.printTotalLine(tbl, dataCounted[line], headings)
	end
end
function h.printTotalLine(tbl, row, headings)
	local tr = tbl:tag('tr')
	for _, col in ipairs(headings) do
		tr:tag('th')
			:wikitext(row[col] or '-')
	end
end
function h.makeIncludedTournaments(tournamentData, args)
	if util_args.castAsBool(args.hidetournamentlist) or PRELOAD.hidetournamentlist then return end
	local output = mw.html.create()
	if args.tournament then return end
	output:tag('span'):addClass('big'):wikitext(i18n.print('IncludedTournaments'))
	local ul = output:tag('ul')
	for _, v in ipairs(tournamentData) do
		ul:tag('li')
			:wikitext(util_text.intLinkOrText(v))
			:wikitext(' - ')
			:wikitext(i18n.print('NumberOfGames', tournamentData[v]))
	end
	return output
end
function h.makePermalink(args, args2)
	if not util_args.castAsBool(args.spl) then return end
	local output = mw.html.create()
	output:tag('hr')
	util_form.permalink(output, args, SETTINGS.form_info)
	output:tag('hr')
	output:wikitext(i18n.print('debugInfo'))
	output:wikitext(h.getGeneralWhere(args2))
	if PRELOAD.bans then
		output:wikitext('<br>', h.getBanWhere(args2))
	end
	util_form.printLog(output)
	return output
end
return p
Advertisement