Call of Duty Esports Wiki
Advertisement
Call of Duty Esports Wiki

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


local lang = mw.getLanguage('en')
local m_team = require('Module:Team')
local TeamHistory = require('Module:Infobox/TeamHist').teamHist
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_game = require('Module:GameUtil')
local util_html = require('Module:HtmlUtil')
local util_infobox = require('Module:InfoboxUtil')
local util_map = require('Module:MapUtil')
local util_sentence = require("Module:SentenceUtil")
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 RoleList = require('Module:RoleList')
local Country = require('Module:Country')
local CountryList = require('Module:CountryList')
local Region = require('Module:Region')
local RegionList = require('Module:RegionList')
local ChampionList = require('Module:ChampionList')
local PlayerCurrentTeam = require('Module:PlayerCurrentTeam').main
local IntroSentence = require('Module:IntroSentence/Player').main

local NOIMAGE = 'Unknown Infobox Image - Player.png'

local Infobox = require('Module:Infobox'):extends()

Infobox.type = 'Player'

Infobox.LAYOUT = {
	tabs = 'PlayerTabsHeader',
	sections = { 'Background Information', 'Competitive', 'Social Media & Links', 'Team History' },
	contents = {
		{ 'Name', 'Country', 'Nationality', 'Birthday', 'Died', 'Residency', 'ResidencyPrev' },
		{ 'Team', 'Role', 'PreviousRole', 'Input', 'Platform', 'PlatformPrev',  'CompIDs', 'PSNIDs','XBLIDs','BattleTags' },
		{ 'social', social = 'wide' },
		{ 'teamhist', teamhist = 'wide' },
	},
}

local DIRECT_STORE = { ID = 'id', Stream = 'stream', Twitter = 'twitter', Facebook = 'facebook', Askfm = 'askfm', Reddit = 'reddit', Youtube = 'youtube', UMG = 'umg', GameBattles = 'gamebattles', Instagram = 'instagram', IsRetired = 'isretired',
}

local h = {} -- helper functions
local p = {}
function p.main(frame)
	local args = util_args.merge()
	return Infobox(args):run()
end

function Infobox:castArgs(args)
	args.role = RoleList(args.role, { sub = util_args.castAsBool(args.checkboxIsSub) })
	args.role_prev = RoleList(util_args.numberedArgsToTable(args, 'prev'))
	args.favchamps = ChampionList(util_args.numberedArgsToTable(args, 'favchamp'))
	args.residency = Region(args.residency)
	args.res_prev1 = Region(args['residency-prev1'])
	args.res_prev2 = Region(args['residency-prev2'])
	args.res_prev = RegionList(util_args.numberedArgsToTable(args, 'residency-prev'))
	args.country = Country(args.country)
	args.nationality = CountryList(args.nationality)
end

function Infobox:getProcessed(args)
	if util_args.castAsBool(args.checkboxAutoTeams) then
		args.team = nil
		args.team2 = nil
	end
	local processed = {
		pagename = mw.title.getCurrentTitle().text,
		bday = h.getBirthdayAndAgeIfAppropriate(args),
		died = h.getDeathDateIfNeeded(args),
		lc = args.id and lang:lcfirst(args.id) == args.id,
		hasAutoTeams = util_args.castAsBool(args.checkboxAutoTeams),
		image = h.getImage(args),
		isLowContent = util_args.castAsBool(args.low_content)
	}
	processed.entity = processed.lc and util_text.lcfirst(processed.pagename) or processed.pagename
	local teamhist, last = TeamHistory(args)
	processed.teams = h.getTeamsTable(args, processed, last)
	processed.teamhist = not processed.hasAutoTeams and teamhist
	processed.roleLast = h.getCargoLastRole(args, processed)
	return processed
end

function h.getImage(args)
	if not util_args.castAsBool(args.checkboxAutoImage) then
		return util_infobox.getFile(args.image, NOIMAGE)
	end
	local image = h.queryForImage(args)
	return image or NOIMAGE
end

function h.getBirthdayAndAgeIfAppropriate(args)
	local bday = util_infobox.makeBday(args.birth_date_year, args.birth_date_month, args.birth_date_day)
	if args.died then
		bday.age = nil
		bday.displayandage = bday.display
	end
	return bday
end

function h.getDeathDateIfNeeded(args)
	if not args.died then return {} end
	return util_infobox.makeBday(args.birth_date_year, args.birth_date_month, args.birth_date_day, args.died)
end

function h.getTeamsTable(args, processed, last)
	if processed.hasAutoTeams then
		return PlayerCurrentTeam(mw.title.getCurrentTitle().text)
	end
	local teams = h.getLegacyTeams(args, processed)
	teams.last = last or {}
	return teams
end

function h.getLegacyTeams(args, processed)
	local ret = util_map.inPlace(
		util_args.numberedArgsToTable(args, 'team') or {},
		h.getOneLegacyTeam, args, processed
	)
	return ret
end

function h.getOneLegacyTeam(team, args, processed)
	local ret = {
		team = m_team.teamlinkname(team),
		role = args.role,
		sub = util_args.castAsBool(args.checkboxIsSub),
	}
	return ret
end

function h.getCargoLastRole(args, processed)
	if not processed.hasAutoTeams then return args.role end
	
	-- role could be nil if player has 0 team entries
	if not processed.teams.last.RoleList then return args.role end
	return processed.teams.last.RoleList:_or(args.role)
end

function Infobox:getDisplay(args, processed)
	local display = self:super('getDisplay', args, processed)
	local tbl = {
		title = args.id or processed.pagename,
		image = not processed.isLowContent and processed.image,
		notice = h.getNotice(args),
		
		-- background info
		Name = args.name and (args.name .. (args.nativename and (' (%s)'):format(args.nativename) or '')),
		Country = args.country:flair(),
		Nationality = args.nationality:flairs{sep='<br>'},
		Birthday = processed.bday.displayandage,
		Died = processed.died.displayandage,
		Residency = args.residency:flair(),
		ResidencyPrev = args.res_prev:flairs{sep='<br>'},
		
		-- competitive
		Team = h.getCurrentTeam(processed.teams),
		Contract = h.getContract(processed.teams),
		Role = args.role:flairs{len='role'},
		PreviousRole = args.role_prev:flairs{sep='<br>'},
		Input = args.input,
		Platform = args.platform,
		PlatformPrev = util_table.concatFromArgs(args, 'platform-prev', '<br>'),
		Champions = args.favchamps:images(),
		CompIDs = util_table.concatFromArgs(args, 'compID',', '),
		PSNIDs = args.psn,
		XBLIDs = args.xbl,
		BattleTags = args.battletag,
		
		-- social
		teamhist = processed.teamhist,
		
		class = h.getClass(args, processed)
	}
	return Infobox.mergeDisplay(display, tbl)
end

function h.queryForImage(args)
	local query = {
		tables = {
			'PlayerRedirects=PR',
			'PlayerImages=PI',
			'Tournaments=T',
		},
		join = {
			'PR.AllName=PI.Link',
			'PI.Tournament=T.OverviewPage',
		},
		where = h.getImageWhere(args),
		fields = { 'PI.FileName' },
		orderBy = 'COALESCE(PI.SortDate, T.DateStart, T.Date) DESC',
	}
	return util_cargo.getOneResult(query)
end

function h.getImageWhere(args)
	local where = {
		('PR._pageName="%s"'):format(mw.title.getCurrentTitle().text),
		('PI._pageName IS NOT NULL'),
		('PI.IsProfileImage="1"'),
	}
	return where
end

function h.getNotice(args)
	if args.died then
		return 'Player is deceased.'
	end
	if util_args.castAsBool(args.isretired) then
		return 'Player has retired.'
	end
	return nil
end

function h.getCurrentTeam(teams)
	if #teams == 0 then return nil end
	return util_table.concat(
		util_map.extractField(teams, 'team', m_team.rightmediumlinked),
		'<br>'
	)
end

function h.getContract(teams)
	if #teams == 0 then return nil end
	if not teams.contractDates then return nil end
	if #teams == 1 then
		return h.getContractDateFromFirstTeam(teams)
	end
	
	-- if they are on two teams but it's one org, we just show the date, nothing else
	-- but if they're on more than one org then we need to show a team icon next to the contract date
	local allSisterTeams = h.getListOfSisterTeamPages(teams)
	if #allSisterTeams == 1 then
		return h.getContractDateFromFirstTeam(teams)
	end
	return h.getAllContracts(teams)
end

function h.getContractDateFromFirstTeam(teams)
	return teams.contractDates[teams[1].SisterTeamPage]
end

function h.getAllContracts(teams)
	local contracts = {}
	for _, team in ipairs(teams) do
		local contract = teams.contractDates[team.SisterTeamPage]
		if contract then
			contracts[#contracts+1] = ('%s%s'):format(
				m_team.onlyimagelinked(team.team),
				contract
			)
		end
	end
	if #contracts == 0 then return nil end
	return util_table.concat(contracts, '<br>')
end

function h.getListOfSisterTeamPages(teams)
	local sisterTeamsUsed = {}
	local allSisterTeams = {}
	for _, team in ipairs(teams) do
		if not sisterTeamsUsed[team.SisterTeamPage] then
			allSisterTeams[#allSisterTeams+1] = team.SisterTeamPage
			sisterTeamsUsed[team.SisterTeamPage] = true
		end
	end
	return allSisterTeams
end

function h.getClass(args, processed)
	local listOfClasses = {
		processed.hasAutoTeams and 'infobox-player-narrow',
		processed.isLowContent and 'infobox-low-content',
	}
	return util_table.concat(listOfClasses, ' ')
end

function Infobox:getCargo(args, processed)
	local cargo = self:super('getCargo', args, processed)
	cargo[#cargo+1] = h.getPlayersCargo(args, processed)
	util_table.mergeArrays(
		cargo,
		h.getPlayerLeagueHistory(args)
	)
	return cargo
end

function h.getPlayersCargo(args, processed)
	local ret = {
		_table = 'Players',
		OverviewPage = mw.title.getCurrentTitle().text,
		Image = h.getImageCargo(args, processed),
		Name = args.name,
		Player = processed.entity,
		NativeName = args.nativename,
		NameAlphabet = args.namealphabet,
		NameFull = args.name and (args.name .. (args.nativename and (' (%s)'):format(args.nativename) or '')),
		Country = args.country,
		Nationality = args.nationality,
		NationalityPrimary = args.nationality:first(),
		Age = processed.bday.age or '',
		Birthdate = processed.bday.store or '',
		ResidencyFormer = args['residency-prev1'],
		Team = processed.teams[1] and processed.teams[1].team,
		Team2 = processed.teams[2] and processed.teams[2].team,
		TeamSystem = 'PC',
		Team2System = 'PC',
		Residency = args.residency,
		Role = args.role,
		Input = args.input,
		Platform = args.platform,
		PlatformPrev = util_table.concatFromArgs(args, 'platform-prev', ', '),
		FavChamps = util_table.concatFromArgs(args, 'favchamp', ','),
		TeamLast = processed.teams.last and processed.teams.last.team,
		RoleLast = processed.roleLast,
		IsSubstitute = args.checkboxIsSub,
		IsLowercase = processed.lc,
		IsAutoTeam = args.checkboxAutoTeams,
		SoloqueueIds = args.ids,
		IsPersonality = args.page_type == 'Personality',
		IsLowContent = processed.isLowContent,
	}
	h.addUnprocessedArgs(ret, args)
	return ret
end

function h.getImageCargo(args, processed)
	if util_args.castAsBool(args.checkboxAutoImage) then
		return nil
	end
	if processed.image == NOIMAGE then return nil end
	if not processed.image then return nil end
	return processed.image:gsub('_', ' ')
end

function h.addUnprocessedArgs(tbl, args)
	for k, v in pairs(DIRECT_STORE) do
		tbl[k] = args[v]
	end
end

function h.getPlayerLeagueHistory(args)
	if util_args.castAsBool(args.noplh) then return {} end
	if not util_game.store_player_league_history then return {} end
	local plhTable = require('Module:PlayerLeagueHistory')._main(mw.title.getCurrentTitle().text)
	return plhTable
end

function Infobox:getDisambigSentence(args, processed)
	-- we can't store "now known as" here but we can store everything else
	-- the "now known as" text is going to have to change, but that's ok maybe
	local replacements = {
		RESIDENCY = args.residency:image(),
		LINK = util_text.intLinkOrText(mw.title.getCurrentTitle().text),
		
		-- TODO: should this, actually be country...?
		NATIONALITY = args.country:exists() and args.country:get('adjective'),
		FORMER = not processed.teams[1] and i18n.default('former') or '',
		ROLE = processed.roleLast:sentence(),
		TEAM = processed.teams[1] and m_team.rightmediumlinked(processed.teams[1].team),
		-- NOW_KNOWN_AS = row.CurrentName and i18n.default('nowKnownAs', row.CurrentName) or '',
	}
	return util_sentence.makeReplacements(i18n.default('disambigSentence'), replacements)
end

function Infobox:getVariables(args, processed)
	local variables = self:super('getVariables', args, processed)
	local tbl = {
		suppressorgnavbox = args.checkboxSuppressOrgNavbox,
		introSentence = h.getIntroSentence(args, processed, 'Display'),
		description = h.getIntroSentence(args, processed, 'Description'),
		checkboxAutoTeams = args.checkboxAutoTeams,
		residency = args.residency:get(),
		isretired = args.isretired,
		current_id = processed.entity,
	}
	local i = 2
	repeat
		thisteam = 'team' .. i
		tbl[thisteam] = args[thisteam] and m_team.teamlinkname(args[thisteam])
		i = i + 1
	until(not args[thisteam])
	return util_table.merge(variables, tbl)
end

function h.getIntroSentence(args, processed, sentenceType)
	local data = mw.clone(args)
	local name = mw.text.split(args.name or '', ' ')
	data.firstname = table.remove(name, 1)
	data.lastname = table.concat(name, ' ')
	data.lastteam = processed.teams.last.team
	data.role = args.role:_or(processed.roleLast)
	data.teamStr = args.team and m_team.teamlinkname(args.team)
	data.isasub = util_args.castAsBool(args.checkboxIsSub)
	data.ispersonality = args.page_type == 'Personality'
	data.page_type = args.page_type
	data.isretired = util_args.castAsBool(args.isretired)
	data.lastteampresent = h.getLastTeamPresent(args, processed)
	data.currentTeamList = processed.teams
	data.hasAutoTeams = processed.hasAutoTeams
	return IntroSentence(data, sentenceType)
end

function h.getLastTeamPresent(args, processed)
	if processed.teams and #processed.teams > 0 then return true end
	return processed.teams.last.date and processed.teams.last.date:find('Present')
end

function Infobox:getCategories(args, processed)
	local tbl = {
		'Players',
		args.residency:exists() and args.residency:get('adjective') .. ' Residents',
		args.res_prev1:exists() and ('Former %s Residents'):format(args.res_prev1:get('adjective')),
		args.res_prev2:exists() and ('Former %s Residents'):format(args.res_prev2:get('adjective')),
		not args.role:exists() and 'Players Without Role',
		h.getSuspendedCategory(args, processed),
		h.isAFreeAgent(args, processed) and 'Free Agents',
		util_args.castAsBool(args.isretired) and 'Retired Players',
		args.birth_date_year and 'Players Born In ' .. args.birth_date_year,
		args.role:has(nil, 'Coach') and 'Coaches',
		processed.isLowContent and 'LowContent',
	}
	
	if args.country:exists() then
		if args.page_type == 'Personality' then
			tbl[#tbl+1] = ('%s Personalities'):format(args.country:get('adjective'))
		else
			tbl[#tbl+1] = 'Players Born in ' .. args.country:name{the=true}
		end
	end
	return tbl
end

function h.isAFreeAgent(args, processed)
	if not util_args.castAsBool(args.checkboxAutoTeams) then
		if args.team then return false end
		if util_args.castAsBool(args.isretired) then return false end
		return true
	end
	return not h.getCurrentTeam(processed.teams)
end

function h.getSuspendedCategory(args, processed)
	if processed.teams.last.team ~= 'Suspended' then return false end
	if not processed.teams.last.date then return false end
	if not processed.teams.last.date:find('Present') then return false end
	return 'Suspended Players'
end

return p
Advertisement