Документация
Элемент Результат Прежний вид
Песочница Викиданных
d:Q4115189
StarCraft II: Heart of the Swarm
d:Q1207938
  • 12 марта 2013
12 марта 2013
Starfield
d:Q55286432
  • 1 сентября 2023
  • 6 сентября 2023
1 сентября 2023[1] и 6 сентября 2023[2][3]
Dorfromantik
d:Q106235199
Windows
25 марта 2021 (ранний доступ)
28 апреля 2022
Nintendo Switch
29 сентября 2022
25 марта 2021, 28 апреля 2022[4] и 29 сентября 2022
Horizon Zero Dawn
d:Q20155528
PlayStation 4
28 февраля 2017
1 марта 2017
Windows
7 августа 2020
28 февраля 2017, 1 марта 2017 и 7 августа 2020
Among Us
d:Q96417649
  • 16 ноября 2018
Android, iOS
15 июня 2018
Windows
18 июня 2018
17 августа 2018
18 декабря 2020
Nintendo Switch, Nintendo Switch Lite
15 декабря 2020
PlayStation 4, PlayStation 5
14 декабря 2021
Xbox One, Xbox Series X/S
14 декабря 2021
15 июня 2018[5][6][…], 18 июня 2018, 17 августа 2018[7], 16 ноября 2018[8][9][…], 15 декабря 2020[10][11][…], 14 декабря 2021[12][13][…], 14 декабря 2021[14][15][…] и 18 декабря 2020[5]
Baldur’s Gate II: Shadows of Amn
d:Q804859
Windows
22 сентября 2000
24 сентября 2000
29 сентября 2000
1 декабря 2000
Mac OS
сентябрь 2001
24 сентября 2001
15 октября 2001
24 сентября 2000, 29 сентября 2000, 22 сентября 2000[16], 1 декабря 2000, сентябрь 2001, 15 октября 2001[17] и 24 сентября 2001[18]

Примечания

править
local arguments = require( 'Module:Arguments' )
local mwlang = mw.getLanguage( 'ru' )

local p = {}

local platform_aliases = {
	Q1406 = 'Windows',
	Q172742 = 'NES',
	Q183259 = 'SNES',
	Q13522376 = 'Mac OS',
	Q174666 = ''
}

-- Форматирует подгруженную с Викиданных дату в зависимости от её точности.
-- Возвращает строку или Nil.
local function formatDate( value )
	local precision = tonumber( value.precision )

	if value.precision >= 11 then
		return mwlang:formatDate( 'j xg Y', value.time )
	end

	if value.precision == 10 then
		return mwlang:formatDate( 'F Y', value.time )
	end

	if value.precision == 9 then
		return mwlang:formatDate( 'Y', value.time )
	end

	return nil
end

-- Достаёт из квалификаторов к утверждению на Викиданных список платформ.
-- Возвращает строку.
local function getPlatforms( statement )
	if not statement.qualifiers or not statement.qualifiers.P400 then
		-- no 'platform' qualifiers
		return ''
	end

	local platforms = {}

	for _, qualifier in ipairs( statement.qualifiers.P400 ) do
		if qualifier.datavalue then
			local label
			if platform_aliases[qualifier.datavalue.value.id] then
				label = platform_aliases[qualifier.datavalue.value.id]
			else
				label = mw.wikibase.getLabel( qualifier.datavalue.value.id )
			end

			if label ~= '' then
				table.insert( platforms, label )
			end
		end
	end

	table.sort( platforms )

	return table.concat( platforms, ', ' )
end

-- Определяет по квалификаторам к утверждению на Викиданных, относится ли
-- данное утверждение к раннему доступу.
local function isEarlyAccess( statement )
	if not statement.qualifiers or not statement.qualifiers.P3831 then
		-- no 'object has role' qualifiers
		return false
	end

	for _, qualifier in ipairs( statement.qualifiers.P3831 ) do
		if qualifier.datavalue and qualifier.datavalue.value.id == 'Q17042291' then
			-- object has role == early access
			return true
		end
	end

	return false
end

-- Рендерит один блок (заголовок-платформа со списком дат), возвращает строку.
local function renderBlock( header, rows )
	local result
	local listtype

	if header == '' then
		result = ''
		listtype = '* '
	else
		result = '; ' .. header .. '\n'
		listtype = ': '
	end

	for _, data in ipairs(rows) do
		result = result .. listtype .. data[2] .. '\n'
	end

	return result
end

-- Используется для сортировки массива из массивов, в качестве ключа сортировки
-- берётся первый элемент.
local function comparer( a, b )
	return a[1] < b[1]
end

-- Рендерит всё, что указано в P577 (дата публикации) данного элемента Викиданных.
function p.formatVGReleaseDate( context, options )
	local entity = context.entity

	if not entity or not entity.claims.P577 then
		return ''
	end

	-- Step 1: gather data as a table:
	-- 'platform' → { { 'sortkey1', 'datarow1' }, { 'sortkey2', 'datarow2' }, ... }

	local data = {}
	local data_length = 0
	local release_year = nil

	for _, statement in ipairs( entity.claims.P577 ) do
		if statement
			and statement.mainsnak
			and statement.mainsnak.datavalue
			and statement.mainsnak.datavalue.type == 'time'
			and statement.rank ~= 'deprecated'
		then
			local value = statement.mainsnak.datavalue.value
			local datarow = formatDate( value )

			if datarow then
				local sortkey = value.time
				local platforms = getPlatforms( statement )

				datarow = datarow .. context.formatRefs( options, statement )
				if isEarlyAccess( statement ) then
					datarow = datarow .. ' <small>(ранний доступ)</small>'
				else
					-- extract release year for further categorization
					local current_year = tonumber( mwlang:formatDate( 'Y', value.time ) )
					if not release_year or current_year < release_year then
						release_year = current_year
					end
				end

				if data[platforms] then
					table.insert( data[platforms], { sortkey, datarow } )
				else
					data[platforms] = { { sortkey, datarow } }
					data_length = data_length + 1
				end
			end
		end
	end

	-- Step 2: sort data

	local data_indices = {}

	for platform, datarows in pairs(data) do
		table.sort( datarows, comparer )

		local sortkey = datarows[1][1] -- earliest release date
		if platform == '' then
			-- dates with no platform specified should be rendered first tho
			sortkey = ''
		end
		table.insert( data_indices, { sortkey, platform } )
	end

	table.sort( data_indices, comparer )

	-- Step 3: render data

	local result = ''

	for _, index in pairs(data_indices) do
		local platform = index[2]
		if data_length == 1 then
			-- If there's only one block, no need to render the header
			result = result .. renderBlock( '', data[platform] )
		else
			result = result .. renderBlock( platform, data[platform] )
		end
	end

	frame = context.frame
	if release_year
		and frame:callParserFunction( 'NAMESPACE', frame:getTitle() ) == ''
		and not options.nocat
	then
		result = result .. '[[Категория:Компьютерные игры ' .. release_year .. ' года]]'
	end

	return result
end

function p.test( frame )
	local args = arguments.getArgs(frame)
	local entity = mw.wikibase.getEntity( args[1] )
	local formatRefsStub = function() return '' end
	return p.formatVGReleaseDate(
		{ frame = frame, entity = entity, formatRefs = formatRefsStub },
		{ nocat = args.nocat and args.nocat ~= '' }
	)
end

return p