Дополнительные действия
DarkMuse (обсуждение | вклад) Новая страница: «require( 'strict' ) local Vehicle = {} local metatable = {} local methodtable = {} metatable.__index = methodtable local i18n = require( 'Module:i18n' ):new() local TNT = require( 'Module:Translate' ):new() local common = require( 'Module:Common' ) local manufacturer = require( 'Module:Manufacturer' ):new() local hatnote = require( 'Module:Hatnote' )._hatnote local data = mw.loadJsonData( 'Module:Vehicle/data.json' ) local config = mw.loadJsonData( 'Modu...» |
DarkMuse (обсуждение | вклад) Нет описания правки |
||
| Строка 1: | Строка 1: | ||
require( 'strict' ) | require('strict') | ||
local Vehicle = {} | local Vehicle = {} | ||
| Строка 8: | Строка 8: | ||
metatable.__index = methodtable | metatable.__index = methodtable | ||
local i18n = require( 'Module:i18n' ):new() | local i18n = require('Module:i18n'):new() | ||
local TNT = require( 'Module:Translate' ):new() | local TNT = require('Module:Translate'):new() | ||
local common = require( 'Module:Common' ) | local common = require('Module:Common') | ||
local manufacturer = require( 'Module:Manufacturer' ):new() | local manufacturer = require('Module:Manufacturer'):new() | ||
local hatnote = require( 'Module:Hatnote' )._hatnote | local hatnote = require('Module:Hatnote')._hatnote | ||
local data = mw.loadJsonData( 'Module:Vehicle/data.json' ) | local data = mw.loadJsonData('Module:Vehicle/data.json') | ||
local config = mw.loadJsonData( 'Module:Vehicle/config.json' ) | local config = mw.loadJsonData('Module:Vehicle/config.json') | ||
local lang | local lang | ||
if config.module_lang then | if config.module_lang then | ||
lang = mw.getLanguage( config.module_lang ) | lang = mw.getLanguage(config.module_lang) | ||
else | else | ||
lang = mw.getContentLanguage() | lang = mw.getContentLanguage() | ||
end | end | ||
--- Wrapper function for Module:i18n.translate | --- Wrapper function for Module:i18n.translate | ||
| Строка 28: | Строка 27: | ||
--- @param key string The translation key | --- @param key string The translation key | ||
--- @return string If the key was not found, the key is returned | --- @return string If the key was not found, the key is returned | ||
local function t( key ) | local function t(key) | ||
return i18n:translate( key ) | return i18n:translate(key) | ||
end | end | ||
--- Calls TNT with the given key | --- Calls TNT with the given key | ||
| Строка 38: | Строка 36: | ||
--- @param addSuffix boolean|nil Adds a language suffix if config.smw_multilingual_text is true | --- @param addSuffix boolean|nil Adds a language suffix if config.smw_multilingual_text is true | ||
--- @return string If the key was not found in the .tab page, the key is returned | --- @return string If the key was not found in the .tab page, the key is returned | ||
local function translate( key, addSuffix, ... ) | local function translate(key, addSuffix, ...) | ||
return TNT:translate( 'Module:Vehicle/i18n.json', config, key, addSuffix, {...} ) or key | return TNT:translate('Module:Vehicle/i18n.json', config, key, addSuffix, {...}) or key | ||
end | end | ||
--- Check if the current vehicle is a ground vehicle | --- Check if the current vehicle is a ground vehicle | ||
| Строка 47: | Строка 44: | ||
--- @param smwData table | --- @param smwData table | ||
--- @return boolean | --- @return boolean | ||
local function isGroundVehicle( smwData ) | local function isGroundVehicle(smwData) | ||
local size = smwData[ t( 'SMW_ShipMatrixSize' ) ] | local size = smwData[t('SMW_ShipMatrixSize')] | ||
return ( size ~= nil and size == translate( 'Vehicle' ) ) or smwData[ t( 'SMW_ReverseSpeed' ) ] ~= nil | return (size ~= nil and size == translate('Vehicle')) or smwData[t('SMW_ReverseSpeed')] ~= nil | ||
end | end | ||
--- Creates the object that is used to query the SMW store | --- Creates the object that is used to query the SMW store | ||
| Строка 58: | Строка 54: | ||
--- @param page string the vehicle page containing data | --- @param page string the vehicle page containing data | ||
--- @return table | --- @return table | ||
local function makeSmwQueryObject( page ) | local function makeSmwQueryObject(page) | ||
local langSuffix = '' | |||
if config.smw_multilingual_text == true then | |||
langSuffix = '+lang=' .. (config.module_lang or mw.getContentLanguage():getCode()) | |||
end | |||
local query = { | local query = {string.format('[[%s]]', page), '?Page image#-=image'} | ||
for _, queryPart in pairs( data.smw_data ) do | for _, queryPart in pairs(data.smw_data) do | ||
local smwKey | local smwKey | ||
for key, _ in pairs( queryPart ) do | for key, _ in pairs(queryPart) do | ||
if mw.ustring.sub( key, 1, 3 ) == 'SMW' then | if mw.ustring.sub(key, 1, 3) == 'SMW' then | ||
smwKey = key | smwKey = key | ||
break | break | ||
| Строка 86: | Строка 79: | ||
-- safeguard | -- safeguard | ||
if smwKey ~= nil then | if smwKey ~= nil then | ||
table.insert( query, mw.ustring.format( formatString, t( smwKey ) ) ) | table.insert(query, mw.ustring.format(formatString, t(smwKey))) | ||
if queryPart.type == 'multilingual_text' then | if queryPart.type == 'multilingual_text' then | ||
table.insert( query, langSuffix ) | table.insert(query, langSuffix) | ||
end | end | ||
end | end | ||
end | end | ||
table.insert( query, 'limit=1' ) | table.insert(query, 'limit=1') | ||
return query | return query | ||
end | end | ||
--- FIXME: This should go to somewhere else, like Module:Common | --- FIXME: This should go to somewhere else, like Module:Common | ||
local function makeTimeReadable( time ) | local function makeTimeReadable(time) | ||
if time == nil then return end | if time == nil then return end | ||
-- Fix for | -- Fix for German number format | ||
if mw.ustring.find( time, ',', 1, true ) then | if mw.ustring.find(time, ',', 1, true) then | ||
time = mw.ustring.gsub( time, ',', '.' ) | time = mw.ustring.gsub(time, ',', '.') | ||
end | end | ||
if type( time ) == 'string' then | if type(time) == 'string' then | ||
time = tonumber( time, 10 ) | time = tonumber(time, 10) | ||
end | end | ||
time = lang:formatDuration( time * 60 ) | time = lang:formatDuration(time * 60) | ||
local regex | local regex | ||
if lang:getCode() == 'de' then | if lang:getCode() == 'de' then | ||
regex = { | regex = { | ||
[ '%s?[Tt]agen?' ] = 'd', | ['%s?[Tt]agen?'] = 'd', | ||
[ '%s?[Ss]tunden?' ] = 'h', | ['%s?[Ss]tunden?'] = 'h', | ||
[ '%s?[Mm]inuten?' ] = 'm', | ['%s?[Mm]inuten?'] = 'm', | ||
[ '%s?[Ss]ekunden?' ] = 's', | ['%s?[Ss]ekunden?'] = 's', | ||
[ ','] = '', | [','] = '', | ||
[ 'und%s'] = '' | ['und%s'] = '' | ||
} | } | ||
else | else | ||
regex = { | regex = { | ||
[ '%sdays*' ] = 'd', | ['%sdays*'] = 'd', | ||
[ '%shours*' ] = 'h', | ['%shours*'] = 'h', | ||
[ '%sminutes*' ] = 'm', | ['%sminutes*'] = 'm', | ||
[ '%sseconds*' ] = 's', | ['%sseconds*'] = 's', | ||
[ ','] = '', | [','] = '', | ||
[ 'and%s'] = '' | ['and%s'] = '' | ||
} | } | ||
end | end | ||
for pattern, replace in pairs( regex ) do | for pattern, replace in pairs(regex) do | ||
time = mw.ustring.gsub( time, pattern, replace ) | time = mw.ustring.gsub(time, pattern, replace) | ||
end | end | ||
return time | return time | ||
end | end | ||
--- FIXME: This should go to somewhere else, like Module:Common | --- FIXME: This should go to somewhere else, like Module:Common | ||
--- TODO: Should we color code this for buff and debuff? | --- TODO: Should we color code this for buff and debuff? | ||
local function formatModifier( x ) | local function formatModifier(x) | ||
if x == nil then return end | if x == nil then return end | ||
-- Fix for | -- Fix for German number format | ||
if mw.ustring.find( x, ',', 1, true ) then | if mw.ustring.find(x, ',', 1, true) then | ||
x = mw.ustring.gsub( x, ',', '.' ) | x = mw.ustring.gsub(x, ',', '.') | ||
end | end | ||
if type( x ) == 'string' then x = tonumber( x, 10 ) end | if type(x) == 'string' then x = tonumber(x, 10) end | ||
local diff = x - 1 | local diff = x - 1 | ||
| Строка 159: | Строка 150: | ||
if diff == 0 then | if diff == 0 then | ||
--- Display 'None' instead of 0 % for better readability | --- Display 'None' instead of 0 % for better readability | ||
return translate( 'none' ) | return translate('none') | ||
elseif diff > 0 then | elseif diff > 0 then | ||
--- Extra space for formatting | --- Extra space for formatting | ||
| Строка 166: | Строка 157: | ||
sign = '- ' | sign = '- ' | ||
end | end | ||
return sign .. tostring( math.abs( diff ) * 100 ) .. ' %' | return sign .. tostring(math.abs(diff) * 100) .. ' %' | ||
end | end | ||
--- Request Api Data | --- Request Api Data | ||
--- Using current subpage name without vehicle type suffix | --- Using current subpage name without vehicle type suffix | ||
--- @return table|nil | --- @return table|nil | ||
function methodtable.getApiDataForCurrentPage( self ) | function methodtable.getApiDataForCurrentPage(self) | ||
local api = require( 'Module:Common/Api' ) | local api = require('Module:Common/Api') | ||
local query = self.frameArgs[ translate( 'ARG_UUID' ) ] or self.frameArgs[ translate( 'ARG_Name' ) ] or common.removeTypeSuffix( | local query = self.frameArgs[translate('ARG_UUID')] or self.frameArgs[translate('ARG_Name')] or common.removeTypeSuffix( | ||
mw.title.getCurrentTitle().text, | |||
config.name_suffixes | config.name_suffixes | ||
) | |||
local hardpointFilter = {} | |||
for _, filter in pairs(data.hardpoint_filter or {}) do | |||
table.insert(hardpointFilter, '!' .. filter) | |||
end | |||
local success, json = pcall( mw.text.jsonDecode, mw.ext.Apiunto.get_raw( 'v2/vehicles/' .. query, { | local success, json = pcall(mw.text.jsonDecode, mw.ext.Apiunto.get_raw('v2/vehicles/' .. query, { | ||
include = data.includes, | include = data.includes, | ||
locale = config.api_locale, | locale = config.api_locale, | ||
['filter[hardpoints]'] = table.concat(hardpointFilter, ',') | |||
} ) ) | })) | ||
if not success or api.checkResponseStructure( json, true, false ) == false then return end | if not success or api.checkResponseStructure(json, true, false) == false then return end | ||
self.apiData = json['data'] | |||
self.apiData = api.makeAccessSafe(self.apiData) | |||
return self.apiData | |||
end | end | ||
--- Base Properties that are shared across all Vehicles | --- Base Properties that are shared across all Vehicles | ||
--- @return table SMW Result | --- @return table SMW Result | ||
function methodtable.setSemanticProperties( self ) | function methodtable.setSemanticProperties(self) | ||
local setData = {} | local setData = {} | ||
local smwCommon = require( 'Module:Common/SMW' ) | local smwCommon = require('Module:Common/SMW') | ||
smwCommon.addSmwProperties( | smwCommon.addSmwProperties( | ||
self.apiData, | self.apiData, | ||
| Строка 217: | Строка 206: | ||
) | ) | ||
setData[ t( 'SMW_Name' ) ] = self.frameArgs[ translate( 'ARG_Name' ) ] or common.removeTypeSuffix( | setData[t('SMW_Name')] = self.frameArgs[translate('ARG_Name')] or common.removeTypeSuffix( | ||
mw.title.getCurrentTitle().text, | mw.title.getCurrentTitle().text, | ||
config.name_suffixes | config.name_suffixes | ||
) | ) | ||
if type( setData[ t( 'SMW_Manufacturer' ) ] ) == 'string' then | if type(setData[t('SMW_Manufacturer')]) == 'string' then | ||
local man = manufacturer:get( setData[ t( 'SMW_Manufacturer' ) ] ) | local man = manufacturer:get(setData[t('SMW_Manufacturer')]) | ||
if man ~= nil then man = man.name end | if man ~= nil then man = man.name end | ||
setData[ t( 'SMW_Manufacturer' ) ] = man or setData[ t( 'SMW_Manufacturer' ) ] | setData[t('SMW_Manufacturer')] = man or setData[t('SMW_Manufacturer')] | ||
setData[ t( 'SMW_Manufacturer' ) ] = mw.ustring.format( '[[%s]]', setData[ t( 'SMW_Manufacturer' ) ] ) | setData[t('SMW_Manufacturer')] = mw.ustring.format('[[%s]]', setData[t('SMW_Manufacturer')]) | ||
end | end | ||
| Строка 236: | Строка 225: | ||
if self.apiData.uuid ~= nil then | if self.apiData.uuid ~= nil then | ||
--- Components | --- Components | ||
if self.apiData.hardpoints ~= nil and type( self.apiData.hardpoints ) == 'table' and #self.apiData.hardpoints > 0 then | if self.apiData.hardpoints ~= nil and type(self.apiData.hardpoints) == 'table' and #self.apiData.hardpoints > 0 then | ||
local hardpoint = require( 'Module:VehicleHardpoint' ):new( self.frameArgs[ translate( 'ARG_name' ) ] or mw.title.getCurrentTitle().fullText ) | local hardpoint = require('Module:VehicleHardpoint'):new(self.frameArgs[translate('ARG_name')] or mw.title.getCurrentTitle().fullText) | ||
hardpoint:setHardPointObjects( self.apiData.hardpoints ) | hardpoint:setHardPointObjects(self.apiData.hardpoints) | ||
hardpoint:setParts( self.apiData.parts ) | hardpoint:setParts(self.apiData.parts) | ||
if not self.apiData.hardpoints and type( self.apiData.components ) == 'table' and #self.apiData.components > 0 then | if not self.apiData.hardpoints and type(self.apiData.components) == 'table' and #self.apiData.components > 0 then | ||
hardpoint:setComponents( self.apiData.components ) | hardpoint:setComponents(self.apiData.components) | ||
end | end | ||
end | end | ||
--- Commodity | --- Commodity | ||
local commodity = require( 'Module:Commodity' ):new() | local commodity = require('Module:Commodity'):new() | ||
commodity:addShopData( self.apiData ) | commodity:addShopData(self.apiData) | ||
end | end | ||
end | end | ||
mw.logObject( setData, '💾 [Vehicle] Set SMW data' ) | mw.logObject(setData, '💾 [Vehicle] Set SMW data') | ||
self.setData = setData | self.setData = setData | ||
return mw.smw.set( setData ) | return mw.smw.set(setData) | ||
end | end | ||
--- Queries the SMW Store | --- Queries the SMW Store | ||
--- @return table | --- @return table | ||
function methodtable.getSmwData( self ) | function methodtable.getSmwData(self) | ||
-- Cache multiple calls | -- Cache multiple calls | ||
if self.smwData ~= nil and self.smwData[ t( 'SMW_Name' ) ] ~= nil then | if self.smwData ~= nil and self.smwData[t('SMW_Name')] ~= nil then | ||
return self.smwData | return self.smwData | ||
end | end | ||
local queryName = self.frameArgs[ translate( 'ARG_SmwQueryName' ) ] or | local queryName = self.frameArgs[translate('ARG_SmwQueryName')] or | ||
self.frameArgs[ translate( 'ARG_Name' ) ] or | self.frameArgs[translate('ARG_Name')] or | ||
mw.title.getCurrentTitle().fullText | mw.title.getCurrentTitle().fullText | ||
local smwData = mw.smw.ask( makeSmwQueryObject( queryName ) ) | local smwData = mw.smw.ask(makeSmwQueryObject(queryName)) | ||
if smwData == nil or smwData[ 1 ] == nil then | if smwData == nil or smwData[1] == nil then | ||
return hatnote( mw.ustring.format( | return hatnote(mw.ustring.format( | ||
'%s[[%s]]', | '%s[[%s]]', | ||
t( 'message_error_no_data_text' ), | t('message_error_no_data_text'), | ||
t( 'category_error_pages_with_script_errors' ) | t('category_error_pages_with_script_errors') | ||
), | ), | ||
{ icon = 'WikimediaUI-Error.svg' } | { icon = 'WikimediaUI-Error.svg' } | ||
| Строка 284: | Строка 272: | ||
end | end | ||
self.smwData = smwData[ 1 ] | self.smwData = smwData[1] | ||
return self.smwData | return self.smwData | ||
end | end | ||
--- Creates the infobox | --- Creates the infobox | ||
function methodtable.getInfobox( self ) | function methodtable.getInfobox(self) | ||
local smwData = self:getSmwData() | local smwData = self:getSmwData() | ||
mw.logObject( smwData, '⌛ [Vehicle] Loaded infobox SMW data' ) | mw.logObject(smwData, '⌛ [Vehicle] Loaded infobox SMW data') | ||
local infobox = require( 'Module:InfoboxNeue' ):new( { | local infobox = require('Module:InfoboxNeue'):new({ | ||
placeholderImage = config.placeholder_image | placeholderImage = config.placeholder_image | ||
} ) | }) | ||
local tabber = require( 'Module:Tabber' ).renderTabber | local tabber = require('Module:Tabber').renderTabber | ||
--- SMW Data load error | --- SMW Data load error | ||
--- Infobox data should always have Name property | --- Infobox data should always have Name property | ||
if type( smwData ) ~= 'table' then | if type(smwData) ~= 'table' then | ||
return infobox:renderInfobox( infobox:renderMessage( { | return infobox:renderInfobox(infobox:renderMessage({ | ||
title = t( 'message_error_no_data_title' ), | title = t('message_error_no_data_title'), | ||
desc = t( 'message_error_no_data_text' ), | desc = t('message_error_no_data_text'), | ||
} ) ) | })) | ||
end | end | ||
local function getIndicatorClass() | local function getIndicatorClass() | ||
local state = smwData[ t( 'SMW_ProductionState' ) ] | local state = smwData[t('SMW_ProductionState')] | ||
if state == nil then return end | if state == nil then return end | ||
local classMap = config.productionstate_map | local classMap = config.productionstate_map | ||
for _, map in pairs( classMap ) do | for _, map in pairs(classMap) do | ||
if mw.ustring.match( state, translate( map.name ) ) ~= nil then | if mw.ustring.match(state, translate(map.name)) ~= nil then | ||
return 'infobox__indicator--' .. map.color | return 'infobox__indicator--' .. map.color | ||
end | end | ||
| Строка 324: | Строка 311: | ||
local function getManufacturer() | local function getManufacturer() | ||
if smwData[ t( 'SMW_Manufacturer' ) ] == nil then return end | if smwData[t('SMW_Manufacturer')] == nil then return end | ||
local mfu = manufacturer:get( smwData[ t( 'SMW_Manufacturer' ) ] ) | local mfu = manufacturer:get(smwData[t('SMW_Manufacturer')]) | ||
if mfu == nil then return smwData[ t( 'SMW_Manufacturer' ) ] end | if mfu == nil then return smwData[t('SMW_Manufacturer')] end | ||
return infobox.showDescIfDiff( | return infobox.showDescIfDiff( | ||
table.concat( { '[[', smwData[ t( 'SMW_Manufacturer' ) ], '|', mfu.name , ']]' } ), | table.concat({ '[[', smwData[t('SMW_Manufacturer')], '|', mfu.name, ']]' }), | ||
mfu.code | mfu.code | ||
) | ) | ||
| Строка 336: | Строка 323: | ||
local function getSize() | local function getSize() | ||
if smwData[ t( 'SMW_Size' ) ] == nil then return smwData[ t( 'SMW_ShipMatrixSize' ) ] end | if smwData[t('SMW_Size')] == nil then return smwData[t('SMW_ShipMatrixSize')] end | ||
local codes = { 'XXS', 'XS', 'S', 'M', 'L', 'XL' } | local codes = { 'XXS', 'XS', 'S', 'M', 'L', 'XL' } | ||
local size = smwData[ t( 'SMW_Size' ) ] | local size = smwData[t('SMW_Size')] | ||
-- For uninitialized SMW properties | -- For uninitialized SMW properties | ||
if type( size ) == 'string' then | if type(size) == 'string' then | ||
size = tonumber( size, 10 ) | size = tonumber(size, 10) | ||
end | end | ||
return infobox.showDescIfDiff( | return infobox.showDescIfDiff( | ||
smwData[ t( 'SMW_ShipMatrixSize' ) ], | smwData[t('SMW_ShipMatrixSize')], | ||
table.concat( { 'S', size, '/', codes[ size ] } ) | table.concat({ 'S', size, '/', codes[size] }) | ||
) | ) | ||
end | end | ||
local function getSeries() | local function getSeries() | ||
local series = smwData[ t( 'SMW_Series' ) ] | local series = smwData[t('SMW_Series')] | ||
if series == nil then return end | if series == nil then return end | ||
return mw.ustring.format( | return mw.ustring.format( | ||
'[[:Category:%s|%s]]', | '[[:Category:%s|%s]]', | ||
mw.ustring.format( t( 'category_series' ), series ), | mw.ustring.format(t('category_series'), series), | ||
series | series | ||
) | ) | ||
| Строка 367: | Строка 354: | ||
local section | local section | ||
tabberData[ 'label1' ] = t( 'label_Pledge' ) | tabberData['label1'] = t('label_Pledge') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Standalone' ), | label = t('label_Standalone'), | ||
data = infobox.showDescIfDiff( smwData[ t( 'SMW_PledgePrice' ) ], smwData[ t( 'SMW_OriginalPledgePrice' ) ] ), | data = infobox.showDescIfDiff(smwData[t('SMW_PledgePrice')], smwData[t('SMW_OriginalPledgePrice')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Warbond' ), | label = t('label_Warbond'), | ||
data = infobox.showDescIfDiff( smwData[ t( 'SMW_WarbondPledgePrice' ) ], smwData[ t( 'SMW_OriginalWarbondPledgePrice' ) ] ), | data = infobox.showDescIfDiff(smwData[t('SMW_WarbondPledgePrice')], smwData[t('SMW_OriginalWarbondPledgePrice')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Availability' ), | label = t('label_Availability'), | ||
data = smwData[ t( 'SMW_PledgeAvailability' ) ], | data = smwData[t('SMW_PledgeAvailability')], | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content1' ] = infobox:renderSection( { content = section, col = 2 }, true ) | tabberData['content1'] = infobox:renderSection({ content = section, col = 2 }, true) | ||
tabberData[ 'label2' ] = t( 'label_Insurance' ) | tabberData['label2'] = t('label_Insurance') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Claim' ), | label = t('label_Claim'), | ||
data = makeTimeReadable( smwData[ translate('SMW_InsuranceClaimTime' ) ] ), | data = makeTimeReadable(smwData[translate('SMW_InsuranceClaimTime')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Expedite' ), | label = t('label_Expedite'), | ||
data = makeTimeReadable( smwData[ translate('SMW_InsuranceExpediteTime' ) ] ), | data = makeTimeReadable(smwData[translate('SMW_InsuranceExpediteTime')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_ExpediteFee' ), | label = t('label_ExpediteFee'), | ||
data = smwData[ translate('SMW_InsuranceExpediteCost' ) ], | data = smwData[translate('SMW_InsuranceExpediteCost')], | ||
colspan = 2 | colspan = 2 | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content2' ] = infobox:renderSection( { content = section, col = 4 }, true ) | tabberData['content2'] = infobox:renderSection({ content = section, col = 4 }, true) | ||
return tabber( tabberData ) | return tabber(tabberData) | ||
end | end | ||
| Строка 412: | Строка 399: | ||
local section | local section | ||
tabberData[ 'label1' ] = t( 'label_Dimensions' ) | tabberData['label1'] = t('label_Dimensions') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Length' ), | label = t('label_Length'), | ||
data = infobox.showDescIfDiff( smwData[ t( 'SMW_EntityLength' ) ], smwData[ t( 'SMW_RetractedLength' ) ] ), | data = infobox.showDescIfDiff(smwData[t('SMW_EntityLength')], smwData[t('SMW_RetractedLength')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Width' ), | label = t('label_Width'), | ||
data = infobox.showDescIfDiff( smwData[ t( 'SMW_EntityWidth' ) ], smwData[ t( 'SMW_RetractedWidth' ) ] ), | data = infobox.showDescIfDiff(smwData[t('SMW_EntityWidth')], smwData[t('SMW_RetractedWidth')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Height' ), | label = t('label_Height'), | ||
data = infobox.showDescIfDiff( smwData[ t( 'SMW_EntityHeight' ) ], smwData[ t( 'SMW_RetractedHeight' ) ] ), | data = infobox.showDescIfDiff(smwData[t('SMW_EntityHeight')], smwData[t('SMW_RetractedHeight')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Mass' ), | label = t('label_Mass'), | ||
data = smwData[ t( 'SMW_Mass' ) ], | data = smwData[t('SMW_Mass')], | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content1' ] = infobox:renderSection( { content =section, col = 3 }, true ) | tabberData['content1'] = infobox:renderSection({ content =section, col = 3 }, true) | ||
tabberData[ 'label2' ] = t( 'label_Speed' ) | tabberData['label2'] = t('label_Speed') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_ScmSpeed' ), | label = t('label_ScmSpeed'), | ||
data = smwData[ t( 'SMW_ScmSpeed' ) ] | data = smwData[t('SMW_ScmSpeed')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_0ToScm' ), | label = t('label_0ToScm'), | ||
data = smwData[ t( 'SMW_ZeroToScmSpeedTime' ) ] | data = smwData[t('SMW_ZeroToScmSpeedTime')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_ScmTo0' ), | label = t('label_ScmTo0'), | ||
data = smwData[ t( 'SMW_ScmSpeedToZeroTime' ) ] | data = smwData[t('SMW_ScmSpeedToZeroTime')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_MaxSpeed' ), | label = t('label_MaxSpeed'), | ||
data = smwData[ t( 'SMW_MaximumSpeed' ) ] | data = smwData[t('SMW_MaximumSpeed')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_0ToMax' ), | label = t('label_0ToMax'), | ||
data = smwData[ t( 'SMW_ZeroToMaximumSpeedTime' ) ] | data = smwData[t('SMW_ZeroToMaximumSpeedTime')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_MaxTo0' ), | label = t('label_MaxTo0'), | ||
data = smwData[ t( 'SMW_MaximumSpeedToZeroTime' ) ] | data = smwData[t('SMW_MaximumSpeedToZeroTime')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_ReverseSpeed' ), | label = t('label_ReverseSpeed'), | ||
data = smwData[ t( 'SMW_ReverseSpeed' ) ] | data = smwData[t('SMW_ReverseSpeed')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_RollRate' ), | label = t('label_RollRate'), | ||
data = smwData[ t( 'SMW_RollRate' ) ] | data = smwData[t('SMW_RollRate')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_PitchRate' ), | label = t('label_PitchRate'), | ||
data = smwData[ t( 'SMW_PitchRate' ) ] | data = smwData[t('SMW_PitchRate')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_YawRate' ), | label = t('label_YawRate'), | ||
data = smwData[ t( 'SMW_YawRate' ) ] | data = smwData[t('SMW_YawRate')] | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content2' ] = infobox:renderSection( { content = section, col = 3 }, true ) | tabberData['content2'] = infobox:renderSection({ content = section, col = 3 }, true) | ||
tabberData[ 'label3' ] = t( 'label_Fuel' ) | tabberData['label3'] = t('label_Fuel') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_HydrogenCapacity' ), | label = t('label_HydrogenCapacity'), | ||
data = smwData[ t( 'SMW_HydrogenFuelCapacity' ) ], | data = smwData[t('SMW_HydrogenFuelCapacity')], | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_HydrogenIntake' ), | label = t('label_HydrogenIntake'), | ||
data = smwData[ t( 'SMW_HydrogenFuelIntakeRate' ) ], | data = smwData[t('SMW_HydrogenFuelIntakeRate')], | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_QuantumCapacity' ), | label = t('label_QuantumCapacity'), | ||
data = smwData[ t( 'SMW_QuantumFuelCapacity' ) ], | data = smwData[t('SMW_QuantumFuelCapacity')], | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content3' ] = infobox:renderSection( { content = section, col = 2 }, true ) | tabberData['content3'] = infobox:renderSection({ content = section, col = 2 }, true) | ||
tabberData[ 'label4' ] = t( 'label_Hull' ) | tabberData['label4'] = t('label_Hull') | ||
section = { | section = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_CrossSection' ), | label = t('label_CrossSection'), | ||
data = formatModifier( smwData[ t( 'SMW_CrossSectionSignatureModifier' ) ] ), | data = formatModifier(smwData[t('SMW_CrossSectionSignatureModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Electromagnetic' ), | label = t('label_Electromagnetic'), | ||
data = formatModifier( smwData[ t( 'SMW_ElectromagneticSignatureModifier' ) ] ), | data = formatModifier(smwData[t('SMW_ElectromagneticSignatureModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Infrared' ), | label = t('label_Infrared'), | ||
data = formatModifier( smwData[ t( 'SMW_InfraredSignatureModifier' ) ] ), | data = formatModifier(smwData[t('SMW_InfraredSignatureModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Physical' ), | label = t('label_Physical'), | ||
data = formatModifier( smwData[ t( 'SMW_PhysicalDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_PhysicalDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Energy' ), | label = t('label_Energy'), | ||
data = formatModifier( smwData[ t( 'SMW_EnergyDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_EnergyDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Distortion' ), | label = t('label_Distortion'), | ||
data = formatModifier( smwData[ t( 'SMW_DistortionDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_DistortionDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Thermal' ), | label = t('label_Thermal'), | ||
data = formatModifier( smwData[ t( 'SMW_ThermalDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_ThermalDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Biochemical' ), | label = t('label_Biochemical'), | ||
data = formatModifier( smwData[ t( 'SMW_BiochemicalDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_BiochemicalDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Stun' ), | label = t('label_Stun'), | ||
data = formatModifier( smwData[ t( 'SMW_StunDamageModifier' ) ] ), | data = formatModifier(smwData[t('SMW_StunDamageModifier')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Health' ), | label = t('label_Health'), | ||
data = smwData[ t( 'SMW_HealthPoint' ) ], | data = smwData[t('SMW_HealthPoint')], | ||
} ), | }), | ||
} | } | ||
tabberData[ 'content4' ] = infobox:renderSection( { content = section, col = 3 }, true ) | tabberData['content4'] = infobox:renderSection({ content = section, col = 3 }, true) | ||
return tabber( tabberData ) | return tabber(tabberData) | ||
end | end | ||
| Строка 549: | Строка 536: | ||
local links = {} | local links = {} | ||
for _, site in ipairs( data.official_sites ) do | for _, site in ipairs(data.official_sites) do | ||
local query = smwData[ translate( site.attribute ) ] | local query = smwData[translate(site.attribute)] | ||
if query ~= nil then | if query ~= nil then | ||
table.insert( links, infobox:renderLinkButton( { | table.insert(links, infobox:renderLinkButton({ | ||
label = translate( site.label ), | label = translate(site.label), | ||
link = query | link = query | ||
} ) ) | })) | ||
end | end | ||
end | end | ||
| Строка 566: | Строка 553: | ||
local links = {} | local links = {} | ||
for _, site in ipairs( data.community_sites ) do | for _, site in ipairs(data.community_sites) do | ||
local query = smwData[ translate( site.data ) ] | local query = smwData[translate(site.data)] | ||
if query ~= nil then | if query ~= nil then | ||
if site.data == 'SMW_ClassName' or site.data == 'SMW_UUID' then | if site.data == 'SMW_ClassName' or site.data == 'SMW_UUID' then | ||
query = mw.ustring.lower( query ) | query = mw.ustring.lower(query) | ||
elseif site.data == 'SMW_ShipMatrixName' then | elseif site.data == 'SMW_ShipMatrixName' then | ||
query = mw.uri.encode( query, 'PATH' ) | query = mw.uri.encode(query, 'PATH') | ||
end | end | ||
if site.label == 'FleetYards' then | if site.label == 'FleetYards' then | ||
query = mw.ustring.lower( mw.ustring.gsub( query, '%%20', '-' ) ) | query = mw.ustring.lower(mw.ustring.gsub(query, '%%20', '-')) | ||
end | end | ||
table.insert( links, infobox:renderLinkButton( { | table.insert(links, infobox:renderLinkButton({ | ||
label = site.label, | label = site.label, | ||
link = mw.ustring.format( site.format, query ) | link = mw.ustring.format(site.format, query) | ||
} ) ) | })) | ||
end | end | ||
end | end | ||
| Строка 591: | Строка 578: | ||
local image = self.frameArgs[ translate( 'ARG_Image' ) ] or self.frameArgs[ 'image' ] or smwData[ 'image' ] | local image = self.frameArgs[translate('ARG_Image')] or self.frameArgs['image'] or smwData['image'] | ||
infobox:renderImage( image ) | infobox:renderImage(image) | ||
infobox:renderIndicator( { | infobox:renderIndicator({ | ||
data = smwData[ t( 'SMW_ProductionState' ) ], | data = smwData[t('SMW_ProductionState')], | ||
desc = smwData[ t( 'SMW_ProductionStateDesc' ) ], | desc = smwData[t('SMW_ProductionStateDesc')], | ||
class = getIndicatorClass() | class = getIndicatorClass() | ||
} ) | }) | ||
infobox:renderHeader( { | infobox:renderHeader({ | ||
title = smwData[ t( 'SMW_Name' ) ], | title = smwData[t('SMW_Name')], | ||
--- e.g. Aegis Dynamics (AEGS) | --- e.g. Aegis Dynamics (AEGS) | ||
subtitle = getManufacturer() | subtitle = getManufacturer() | ||
} ) | }) | ||
--- Role, Size, Series and Loaners | --- Role, Size, Series and Loaners | ||
infobox:renderSection( { | infobox:renderSection({ | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Role' ), | label = t('label_Role'), | ||
data = infobox.tableToCommaList( smwData[ t( 'SMW_Role' ) ] ), | data = infobox.tableToCommaList(smwData[t('SMW_Role')]), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Size' ), | label = t('label_Size'), | ||
data = getSize(), | data = getSize(), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Series' ), | label = t('label_Series'), | ||
data = getSeries(), | data = getSeries(), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Loaner' ), | label = t('label_Loaner'), | ||
data = infobox.tableToCommaList( smwData[ t( 'SMW_LoanerVehicle' ) ] ), | data = infobox.tableToCommaList(smwData[t('SMW_LoanerVehicle')]), | ||
} ), | }), | ||
}, | }, | ||
col = 2 | col = 2 | ||
} ) | }) | ||
--- Capacity | --- Capacity | ||
infobox:renderSection( { | infobox:renderSection({ | ||
title = t( 'label_Capacity' ), | title = t('label_Capacity'), | ||
col = 3, | col = 3, | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Crew' ), | label = t('label_Crew'), | ||
data = infobox.formatRange( smwData[ t( 'SMW_MinimumCrew' ) ], smwData[ t( 'SMW_MaximumCrew' ) ], true ), | data = infobox.formatRange(smwData[t('SMW_MinimumCrew')], smwData[t('SMW_MaximumCrew')], true), | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Cargo' ), | label = t('label_Cargo'), | ||
data = smwData[ t( 'SMW_CargoCapacity' ) ], | data = smwData[t('SMW_CargoCapacity')], | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Stowage' ), | label = t('label_Stowage'), | ||
data = smwData[ t( 'SMW_VehicleInventory' ) ], | data = smwData[t('SMW_VehicleInventory')], | ||
} ), | }), | ||
}, | }, | ||
} ) | }) | ||
--- Cost | --- Cost | ||
infobox:renderSection( { | infobox:renderSection({ | ||
title = t( 'label_Cost' ), | title = t('label_Cost'), | ||
class = 'infobox__section--tabber', | class = 'infobox__section--tabber', | ||
content = getCostSection(), | content = getCostSection(), | ||
} ) | }) | ||
--- Specifications | --- Specifications | ||
infobox:renderSection( { | infobox:renderSection({ | ||
title = t( 'label_Specifications' ), | title = t('label_Specifications'), | ||
class = 'infobox__section--tabber', | |||
content = getSpecificationsSection(), | content = getSpecificationsSection(), | ||
} ) | }) | ||
--- Lore section | --- Lore section | ||
infobox:renderSection( { | infobox:renderSection({ | ||
title = t( 'label_Lore' ), | title = t('label_Lore'), | ||
col = 2, | col = 2, | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Released' ), | label = t('label_Released'), | ||
data = smwData[ t( 'SMW_LoreReleaseDate' ) ] | data = smwData[t('SMW_LoreReleaseDate')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Retired' ), | label = t('label_Retired'), | ||
data = smwData[ t( 'SMW_LoreRetirementDate' ) ] | data = smwData[t('SMW_LoreRetirementDate')] | ||
} ), | }), | ||
}, | }, | ||
} ) | }) | ||
--- Development section | --- Development section | ||
infobox:renderSection( { | infobox:renderSection({ | ||
title = t( 'label_Development' ), | title = t('label_Development'), | ||
col = 2, | col = 2, | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_Announced' ), | label = t('label_Announced'), | ||
data = smwData[ t( 'SMW_ConceptAnnouncementDate' ) ] | data = smwData[t('SMW_ConceptAnnouncementDate')] | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_ConceptSale' ), | label = t('label_ConceptSale'), | ||
data = smwData[ t( 'SMW_ConceptSaleDate' ) ] | data = smwData[t('SMW_ConceptSaleDate')] | ||
} ), | }), | ||
}, | }, | ||
} ) | }) | ||
--- Metadata section | --- Metadata section | ||
infobox:renderSection( { | infobox:renderSection({ | ||
class = 'infobox__section--metadata infobox__section--hasBackground', | class = 'infobox__section--metadata infobox__section--hasBackground', | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'SMW_UUID' ), | label = t('SMW_UUID'), | ||
data = smwData[ t( 'SMW_UUID' ) ], | data = smwData[t('SMW_UUID')], | ||
row = true, | row = true, | ||
spacebetween = true | spacebetween = true | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'SMW_ClassName' ), | label = t('SMW_ClassName'), | ||
data = smwData[ t( 'SMW_ClassName' ) ], | data = smwData[t('SMW_ClassName')], | ||
row = true, | row = true, | ||
spacebetween = true | spacebetween = true | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'SMW_GameBuild' ), | label = t('SMW_GameBuild'), | ||
data = smwData[ t( 'SMW_GameBuild' ) ], | data = smwData[t('SMW_GameBuild')], | ||
row = true, | row = true, | ||
spacebetween = true | spacebetween = true | ||
} ) | }) | ||
}, | }, | ||
} ) | }) | ||
--- Actions section | --- Actions section | ||
if smwData[ t( 'SMW_UUID' ) ] then | if smwData[t('SMW_UUID')] then | ||
infobox:renderSection( { | infobox:renderSection({ | ||
class = 'infobox__section--actions infobox__section--hasBackground', | class = 'infobox__section--actions infobox__section--hasBackground', | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
icon = 'WikimediaUI-Search.svg', | icon = 'WikimediaUI-Search.svg', | ||
data = translate( 'label_actions_find_item_title' ), | data = translate('label_actions_find_item_title'), | ||
desc = t( 'label_actions_find_item_text' ), | desc = t('label_actions_find_item_text'), | ||
-- FIXME: Make this configurable? | -- FIXME: Make this configurable? | ||
link = 'https://finder.cstone.space/search/' .. smwData[ t( 'SMW_UUID' ) ] | link = 'https://finder.cstone.space/search/' .. smwData[t('SMW_UUID')] | ||
} ) | }) | ||
} | } | ||
} ) | }) | ||
end | end | ||
--- Footer | --- Footer | ||
infobox:renderFooter( { | infobox:renderFooter({ | ||
button = { | button = { | ||
icon = 'WikimediaUI-Globe.svg', | icon = 'WikimediaUI-Globe.svg', | ||
label = t( 'label_OtherSites' ), | label = t('label_OtherSites'), | ||
type = 'popup', | type = 'popup', | ||
content = infobox:renderSection( { | content = infobox:renderSection({ | ||
content = { | content = { | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_OfficialSites' ), | label = t('label_OfficialSites'), | ||
data = table.concat( getOfficialSites(), '' ) | data = table.concat(getOfficialSites(), '') | ||
} ), | }), | ||
infobox:renderItem( { | infobox:renderItem({ | ||
label = t( 'label_CommunitySites' ), | label = t('label_CommunitySites'), | ||
data = table.concat( getCommunitySites(), '' ) | data = table.concat(getCommunitySites(), '') | ||
} ), | }), | ||
}, | }, | ||
class = 'infobox__section--linkButtons', | class = 'infobox__section--linkButtons', | ||
}, true ) | }, true) | ||
} | } | ||
} ) | }) | ||
return infobox:renderInfobox( nil, smwData[ t( 'SMW_Name' ) ] ) | return infobox:renderInfobox(nil, smwData[t('SMW_Name')]) | ||
end | end | ||
| Строка 771: | Строка 758: | ||
--- Set the frame and load args | --- Set the frame and load args | ||
--- @param frame table | --- @param frame table | ||
function methodtable.setFrame( self, frame ) | function methodtable.setFrame(self, frame) | ||
self.currentFrame = frame | self.currentFrame = frame | ||
self.frameArgs = require( 'Module:Arguments' ).getArgs( frame ) | self.frameArgs = require('Module:Arguments').getArgs(frame) | ||
end | end | ||
--- Sets the main categories for this object | --- Sets the main categories for this object | ||
function methodtable.setCategories( self ) | function methodtable.setCategories(self) | ||
if config.set_categories == false then | if config.set_categories == false then | ||
return | return | ||
end | end | ||
local size = self.smwData[ t( 'SMW_ShipMatrixSize' ) ] | local size = self.smwData[t('SMW_ShipMatrixSize')] | ||
local size_cat, pledge_cat | local size_cat, pledge_cat | ||
local isGroundVehicle = isGroundVehicle( self.smwData ) | local isGroundVehicle = isGroundVehicle(self.smwData) | ||
if isGroundVehicle then | if isGroundVehicle then | ||
| Строка 793: | Строка 780: | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', t( 'category_ground_vehicle' ) ) | string.format('[[Category:%s]]', t('category_ground_vehicle')) | ||
) | ) | ||
else | else | ||
| Строка 800: | Строка 787: | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', t( 'category_ship' ) ) | string.format('[[Category:%s]]', t('category_ship')) | ||
) | ) | ||
end | end | ||
| Строка 807: | Строка 794: | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', mw.ustring.format( t( size_cat ), size ) ) | string.format('[[Category:%s]]', mw.ustring.format(t(size_cat), size)) | ||
) | ) | ||
end | end | ||
if self.smwData[ t( 'SMW_Manufacturer' ) ] ~= nil then | if self.smwData[t('SMW_Manufacturer')] ~= nil then | ||
local manufacturer = mw.ustring.gsub( self.smwData[ t( 'SMW_Manufacturer' ) ], '%[+', '' ) | local manufacturer = mw.ustring.gsub(self.smwData[t('SMW_Manufacturer')], '%[+', '') | ||
manufacturer = mw.ustring.gsub( manufacturer, '%]+', '' ) | manufacturer = mw.ustring.gsub(manufacturer, '%]+', '') | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', manufacturer ) | string.format('[[Category:%s]]', manufacturer) | ||
) | ) | ||
end | end | ||
if self.smwData[ t( 'SMW_ProductionState' ) ] ~= nil then | if self.smwData[t('SMW_ProductionState')] ~= nil then | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', self.smwData[ t( 'SMW_ProductionState' ) ] ) | string.format('[[Category:%s]]', self.smwData[t('SMW_ProductionState')]) | ||
) | ) | ||
end | end | ||
if self.smwData[ t( 'SMW_Series' ) ] ~= nil then | if self.smwData[t('SMW_Series')] ~= nil then | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', mw.ustring.format( t( 'category_series' ), self.smwData[ t( 'SMW_Series' ) ] ) ) | string.format('[[Category:%s]]', mw.ustring.format(t('category_series'), self.smwData[t('SMW_Series')])) | ||
) | ) | ||
end | end | ||
if pledge_cat and self.smwData[ t( 'SMW_PledgePrice' ) ] ~= nil then | if pledge_cat and self.smwData[t('SMW_PledgePrice')] ~= nil then | ||
table.insert( | table.insert( | ||
self.categories, | self.categories, | ||
string.format( '[[Category:%s]]', translate( pledge_cat ) ) | string.format('[[Category:%s]]', translate(pledge_cat)) | ||
) | ) | ||
end | end | ||
| Строка 844: | Строка 831: | ||
--- Sets the short description for this object | --- Sets the short description for this object | ||
function methodtable.setShortDescription( self ) | function methodtable.setShortDescription(self) | ||
local shortdesc | local shortdesc | ||
local vehicleType | local vehicleType | ||
local isGroundVehicle = isGroundVehicle( self.smwData ) | local isGroundVehicle = isGroundVehicle(self.smwData) | ||
if isGroundVehicle then | if isGroundVehicle then | ||
vehicleType = t( 'shortdesc_ground_vehicle' ) | vehicleType = t('shortdesc_ground_vehicle') | ||
else | else | ||
vehicleType = t( 'shortdesc_ship' ) | vehicleType = t('shortdesc_ship') | ||
end | end | ||
if self.smwData[ t( 'SMW_Role' ) ] ~= nil then | if self.smwData[t('SMW_Role')] ~= nil then | ||
local vehicleRole = self.smwData[ t( 'SMW_Role' ) ] | local vehicleRole = self.smwData[t('SMW_Role')] | ||
if type( vehicleRole ) == 'table' then | if type(vehicleRole) == 'table' then | ||
vehicleRole = table.concat( vehicleRole, ' ' ) | vehicleRole = table.concat(vehicleRole, ' ') | ||
end | end | ||
vehicleRole = mw.ustring.lower( vehicleRole ) | vehicleRole = mw.ustring.lower(vehicleRole) | ||
for _, noun in pairs( config.role_suffixes ) do | for _, noun in pairs(config.role_suffixes) do | ||
local match = mw.ustring.find( vehicleRole, '%f[%a]' .. noun .. '%f[%A]' ) | local match = mw.ustring.find(vehicleRole, '%f[%a]' .. noun .. '%f[%A]') | ||
--- Remove suffix from role | --- Remove suffix from role | ||
if match then | if match then | ||
vehicleRole = mw.text.trim( mw.ustring.gsub( vehicleRole, noun, '' ) ) | vehicleRole = mw.text.trim(mw.ustring.gsub(vehicleRole, noun, '')) | ||
vehicleType = noun | vehicleType = noun | ||
end | end | ||
end | end | ||
shortdesc = mw.ustring.format( '%s %s', vehicleRole, vehicleType ) | shortdesc = mw.ustring.format('%s %s', vehicleRole, vehicleType) | ||
else | else | ||
shortdesc = vehicleType | shortdesc = vehicleType | ||
end | end | ||
if not isGroundVehicle and self.smwData[ t( 'SMW_ShipMatrixSize' ) ] ~= nil then | if not isGroundVehicle and self.smwData[t('SMW_ShipMatrixSize')] ~= nil then | ||
local vehicleSize = self.smwData[ t( 'SMW_ShipMatrixSize' ) ] | local vehicleSize = self.smwData[t('SMW_ShipMatrixSize')] | ||
--- Special handling for single-seat ship | --- Special handling for single-seat ship | ||
if self.smwData[ t( 'SMW_MaximumCrew' ) ] ~= nil and self.smwData[ t( 'SMW_MaximumCrew' ) ] == 1 then | if self.smwData[t('SMW_MaximumCrew')] ~= nil and self.smwData[t('SMW_MaximumCrew')] == 1 then | ||
vehicleSize = t( 'shortdesc_single_seat' ) | vehicleSize = t('shortdesc_single_seat') | ||
end | end | ||
shortdesc = mw.ustring.format( '%s %s', vehicleSize, shortdesc ) | shortdesc = mw.ustring.format('%s %s', vehicleSize, shortdesc) | ||
end | end | ||
if self.smwData[ t( 'SMW_Manufacturer' ) ] ~= nil then | if self.smwData[t('SMW_Manufacturer')] ~= nil then | ||
local mfuname = self.smwData[ t( 'SMW_Manufacturer' ) ] | local mfuname = self.smwData[t('SMW_Manufacturer')] | ||
local man = manufacturer:get( mfuname ) | local man = manufacturer:get(mfuname) | ||
--- Use short name if possible | --- Use short name if possible | ||
if man ~= nil and man.shortname ~= nil then mfuname = man.shortname end | if man ~= nil and man.shortname ~= nil then mfuname = man.shortname end | ||
shortdesc = mw.ustring.format( t( 'shortdesc_manufactured_by' ), shortdesc, mfuname ) | shortdesc = mw.ustring.format(t('shortdesc_manufactured_by'), shortdesc, mfuname) | ||
end | end | ||
shortdesc = lang:ucfirst( shortdesc ) | shortdesc = lang:ucfirst(shortdesc) | ||
self.currentFrame:callParserFunction( 'SHORTDESC', shortdesc ) | self.currentFrame:callParserFunction('SHORTDESC', shortdesc) | ||
end | end | ||
--- Save Api Data to SMW store | --- Save Api Data to SMW store | ||
function methodtable.saveApiData( self ) | function methodtable.saveApiData(self) | ||
self:getApiDataForCurrentPage() | self:getApiDataForCurrentPage() | ||
self:setSemanticProperties() | self:setSemanticProperties() | ||
| Строка 910: | Строка 897: | ||
--- Generates debug output | --- Generates debug output | ||
function methodtable.makeDebugOutput( self ) | function methodtable.makeDebugOutput(self) | ||
local debug = require( 'Module:Common/Debug' ) | local debug = require('Module:Common/Debug') | ||
self.smwData = nil | self.smwData = nil | ||
local smwData = self:getSmwData() | local smwData = self:getSmwData() | ||
local queryName = self.frameArgs[ translate( 'ARG_SmwQueryName' ) ] or | local queryName = self.frameArgs[translate('ARG_SmwQueryName')] or | ||
self.frameArgs[ translate( 'ARG_Name' ) ] or | self.frameArgs[translate('ARG_Name')] or | ||
mw.title.getCurrentTitle().fullText | mw.title.getCurrentTitle().fullText | ||
| Строка 923: | Строка 910: | ||
{ | { | ||
title = 'SMW Query', | title = 'SMW Query', | ||
content = debug.convertSmwQueryObject( makeSmwQueryObject( queryName ) ), | content = debug.convertSmwQueryObject(makeSmwQueryObject(queryName)), | ||
}, | }, | ||
{ | { | ||
| Строка 940: | Строка 927: | ||
--- New Instance | --- New Instance | ||
function Vehicle.new( self ) | function Vehicle.new(self) | ||
local instance = { | local instance = { | ||
categories = {} | categories = {} | ||
} | } | ||
setmetatable( instance, metatable ) | setmetatable(instance, metatable) | ||
return instance | return instance | ||
| Строка 955: | Строка 942: | ||
--- @param frame table Invocation frame | --- @param frame table Invocation frame | ||
--- @return string|nil | --- @return string|nil | ||
function Vehicle.loadApiData( frame ) | function Vehicle.loadApiData(frame) | ||
local instance = Vehicle:new() | local instance = Vehicle:new() | ||
instance:setFrame( frame ) | instance:setFrame(frame) | ||
instance:saveApiData() | instance:saveApiData() | ||
local debugOutput | local debugOutput | ||
if instance.frameArgs[ 'debug' ] ~= nil then | if instance.frameArgs['debug'] ~= nil then | ||
local debug = require( 'Module:Common/Debug' ) | local debug = require('Module:Common/Debug') | ||
debugOutput = debug.collapsedDebugSections({ | debugOutput = debug.collapsedDebugSections({ | ||
{ | { | ||
title = 'SMW Set Data', | title = 'SMW Set Data', | ||
content = mw.getCurrentFrame():callParserFunction( '#tag', { 'nowiki', mw.dumpObject( instance.setData or {} ) } ), | content = mw.getCurrentFrame():callParserFunction('#tag', {'nowiki', mw.dumpObject(instance.setData or {})}), | ||
}, | }, | ||
}) | }) | ||
| Строка 980: | Строка 967: | ||
--- @param frame table Invocation frame | --- @param frame table Invocation frame | ||
--- @return string | --- @return string | ||
function Vehicle.infobox( frame ) | function Vehicle.infobox(frame) | ||
local instance = Vehicle:new() | local instance = Vehicle:new() | ||
instance:setFrame( frame ) | instance:setFrame(frame) | ||
local debugOutput = '' | local debugOutput = '' | ||
if instance.frameArgs[ 'debug' ] ~= nil then | if instance.frameArgs['debug'] ~= nil then | ||
debugOutput = instance:makeDebugOutput() | debugOutput = instance:makeDebugOutput() | ||
end | end | ||
return tostring( instance:getInfobox() ) .. debugOutput | return tostring(instance:getInfobox()) .. debugOutput | ||
end | end | ||
| Строка 997: | Строка 984: | ||
--- @param frame table Invocation frame | --- @param frame table Invocation frame | ||
--- @return string | --- @return string | ||
function Vehicle.main( frame ) | function Vehicle.main(frame) | ||
local instance = Vehicle:new() | local instance = Vehicle:new() | ||
instance:setFrame( frame ) | instance:setFrame(frame) | ||
instance:saveApiData() | instance:saveApiData() | ||
local debugOutput = '' | local debugOutput = '' | ||
if instance.frameArgs[ 'debug' ] ~= nil then | if instance.frameArgs['debug'] ~= nil then | ||
debugOutput = instance:makeDebugOutput() | debugOutput = instance:makeDebugOutput() | ||
end | end | ||
local infobox = tostring( instance:getInfobox() ) | local infobox = tostring(instance:getInfobox()) | ||
-- Only set categories and short desc if this is the page that also holds the smw attributes | -- Only set categories and short desc if this is the page that also holds the smw attributes | ||
| Строка 1015: | Строка 1002: | ||
instance:setShortDescription() | instance:setShortDescription() | ||
-- FIXME: Is there a cleaner way? | -- FIXME: Is there a cleaner way? | ||
infobox = infobox .. common.generateInterWikiLinks( mw.title.getCurrentTitle().text ) | infobox = infobox .. common.generateInterWikiLinks(mw.title.getCurrentTitle().text) | ||
end | end | ||
return infobox .. debugOutput .. table.concat( instance.categories ) | return infobox .. debugOutput .. table.concat(instance.categories) | ||
end | end | ||
--- | --- | ||
function Vehicle.test( page ) | function Vehicle.test(page) | ||
page = page or '300i' | page = page or '300i' | ||
local instance = Vehicle:new() | local instance = Vehicle:new() | ||
instance.frameArgs = {} | instance.frameArgs = {} | ||
instance.frameArgs[ translate( 'ARG_Name' ) ] = page | instance.frameArgs[translate('ARG_Name')] = page | ||
instance:saveApiData() | instance:saveApiData() | ||
Текущая версия от 20:21, 3 сентября 2024
message_transclude_desc
message_module_configuration
message_module_configuration_subtext
message_module_i18n
message_module_i18n_subtext
| Function list |
|---|
| L 29 — t L 38 — translate L 46 — isGroundVehicle L 56 — makeSmwQueryObject L 95 — makeTimeReadable L 139 — formatModifier L 165 — methodtable.getApiDataForCurrentPage L 194 — methodtable.setSemanticProperties L 252 — methodtable.getSmwData L 280 — methodtable.getInfobox L 299 — getIndicatorClass L 312 — getManufacturer L 324 — getSize L 341 — getSeries L 352 — getCostSection L 397 — getSpecificationsSection L 535 — getOfficialSites L 552 — getCommunitySites L 760 — methodtable.setFrame L 767 — methodtable.setCategories L 833 — methodtable.setShortDescription L 892 — methodtable.saveApiData L 899 — methodtable.makeDebugOutput L 929 — Vehicle.new L 944 — Vehicle.loadApiData L 969 — Vehicle.infobox L 986 — Vehicle.main L 1012 — Vehicle.test |
| type = website | description = Модуль:Vehicle is a template page used on the iCCup Wiki. Templates are pages that are embedded (transcluded) into other pages to allow for the repetition of information. | site_name = iCCup Wiki | locale = ru }}
This module handles data related to vehicles. On the vehicle page
- Saves template parameters and API data as SMW data
- Set category from SMW data
- Set short description from SMW data
- Display infobox from SMW data
On other pages, it can be used to display the infobox of other vehicles.
require('strict')
local Vehicle = {}
local metatable = {}
local methodtable = {}
metatable.__index = methodtable
local i18n = require('Module:i18n'):new()
local TNT = require('Module:Translate'):new()
local common = require('Module:Common')
local manufacturer = require('Module:Manufacturer'):new()
local hatnote = require('Module:Hatnote')._hatnote
local data = mw.loadJsonData('Module:Vehicle/data.json')
local config = mw.loadJsonData('Module:Vehicle/config.json')
local lang
if config.module_lang then
lang = mw.getLanguage(config.module_lang)
else
lang = mw.getContentLanguage()
end
--- Wrapper function for Module:i18n.translate
---
--- @param key string The translation key
--- @return string If the key was not found, the key is returned
local function t(key)
return i18n:translate(key)
end
--- Calls TNT with the given key
---
--- @param key string The translation key
--- @param addSuffix boolean|nil Adds a language suffix if config.smw_multilingual_text is true
--- @return string If the key was not found in the .tab page, the key is returned
local function translate(key, addSuffix, ...)
return TNT:translate('Module:Vehicle/i18n.json', config, key, addSuffix, {...}) or key
end
--- Check if the current vehicle is a ground vehicle
---
--- @param smwData table
--- @return boolean
local function isGroundVehicle(smwData)
local size = smwData[t('SMW_ShipMatrixSize')]
return (size ~= nil and size == translate('Vehicle')) or smwData[t('SMW_ReverseSpeed')] ~= nil
end
--- Creates the object that is used to query the SMW store
---
--- @param page string the vehicle page containing data
--- @return table
local function makeSmwQueryObject(page)
local langSuffix = ''
if config.smw_multilingual_text == true then
langSuffix = '+lang=' .. (config.module_lang or mw.getContentLanguage():getCode())
end
local query = {string.format('[[%s]]', page), '?Page image#-=image'}
for _, queryPart in pairs(data.smw_data) do
local smwKey
for key, _ in pairs(queryPart) do
if mw.ustring.sub(key, 1, 3) == 'SMW' then
smwKey = key
break
end
end
local formatString = '?%s'
if queryPart.smw_format then
formatString = formatString .. queryPart.smw_format
end
-- safeguard
if smwKey ~= nil then
table.insert(query, mw.ustring.format(formatString, t(smwKey)))
if queryPart.type == 'multilingual_text' then
table.insert(query, langSuffix)
end
end
end
table.insert(query, 'limit=1')
return query
end
--- FIXME: This should go to somewhere else, like Module:Common
local function makeTimeReadable(time)
if time == nil then return end
-- Fix for German number format
if mw.ustring.find(time, ',', 1, true) then
time = mw.ustring.gsub(time, ',', '.')
end
if type(time) == 'string' then
time = tonumber(time, 10)
end
time = lang:formatDuration(time * 60)
local regex
if lang:getCode() == 'de' then
regex = {
['%s?[Tt]agen?'] = 'd',
['%s?[Ss]tunden?'] = 'h',
['%s?[Mm]inuten?'] = 'm',
['%s?[Ss]ekunden?'] = 's',
[','] = '',
['und%s'] = ''
}
else
regex = {
['%sdays*'] = 'd',
['%shours*'] = 'h',
['%sminutes*'] = 'm',
['%sseconds*'] = 's',
[','] = '',
['and%s'] = ''
}
end
for pattern, replace in pairs(regex) do
time = mw.ustring.gsub(time, pattern, replace)
end
return time
end
--- FIXME: This should go to somewhere else, like Module:Common
--- TODO: Should we color code this for buff and debuff?
local function formatModifier(x)
if x == nil then return end
-- Fix for German number format
if mw.ustring.find(x, ',', 1, true) then
x = mw.ustring.gsub(x, ',', '.')
end
if type(x) == 'string' then x = tonumber(x, 10) end
local diff = x - 1
local sign = ''
if diff == 0 then
--- Display 'None' instead of 0 % for better readability
return translate('none')
elseif diff > 0 then
--- Extra space for formatting
sign = '+ '
elseif diff < 0 then
sign = '- '
end
return sign .. tostring(math.abs(diff) * 100) .. ' %'
end
--- Request Api Data
--- Using current subpage name without vehicle type suffix
--- @return table|nil
function methodtable.getApiDataForCurrentPage(self)
local api = require('Module:Common/Api')
local query = self.frameArgs[translate('ARG_UUID')] or self.frameArgs[translate('ARG_Name')] or common.removeTypeSuffix(
mw.title.getCurrentTitle().text,
config.name_suffixes
)
local hardpointFilter = {}
for _, filter in pairs(data.hardpoint_filter or {}) do
table.insert(hardpointFilter, '!' .. filter)
end
local success, json = pcall(mw.text.jsonDecode, mw.ext.Apiunto.get_raw('v2/vehicles/' .. query, {
include = data.includes,
locale = config.api_locale,
['filter[hardpoints]'] = table.concat(hardpointFilter, ',')
}))
if not success or api.checkResponseStructure(json, true, false) == false then return end
self.apiData = json['data']
self.apiData = api.makeAccessSafe(self.apiData)
return self.apiData
end
--- Base Properties that are shared across all Vehicles
--- @return table SMW Result
function methodtable.setSemanticProperties(self)
local setData = {}
local smwCommon = require('Module:Common/SMW')
smwCommon.addSmwProperties(
self.apiData,
self.frameArgs,
setData,
translate,
config,
data,
'Vehicle'
)
setData[t('SMW_Name')] = self.frameArgs[translate('ARG_Name')] or common.removeTypeSuffix(
mw.title.getCurrentTitle().text,
config.name_suffixes
)
if type(setData[t('SMW_Manufacturer')]) == 'string' then
local man = manufacturer:get(setData[t('SMW_Manufacturer')])
if man ~= nil then man = man.name end
setData[t('SMW_Manufacturer')] = man or setData[t('SMW_Manufacturer')]
setData[t('SMW_Manufacturer')] = mw.ustring.format('[[%s]]', setData[t('SMW_Manufacturer')])
end
-- Set properties with API data
if self.apiData ~= nil then
-- Flight ready vehicles
--- Override template parameter with in-game data
if self.apiData.uuid ~= nil then
--- Components
if self.apiData.hardpoints ~= nil and type(self.apiData.hardpoints) == 'table' and #self.apiData.hardpoints > 0 then
local hardpoint = require('Module:VehicleHardpoint'):new(self.frameArgs[translate('ARG_name')] or mw.title.getCurrentTitle().fullText)
hardpoint:setHardPointObjects(self.apiData.hardpoints)
hardpoint:setParts(self.apiData.parts)
if not self.apiData.hardpoints and type(self.apiData.components) == 'table' and #self.apiData.components > 0 then
hardpoint:setComponents(self.apiData.components)
end
end
--- Commodity
local commodity = require('Module:Commodity'):new()
commodity:addShopData(self.apiData)
end
end
mw.logObject(setData, '💾 [Vehicle] Set SMW data')
self.setData = setData
return mw.smw.set(setData)
end
--- Queries the SMW Store
--- @return table
function methodtable.getSmwData(self)
-- Cache multiple calls
if self.smwData ~= nil and self.smwData[t('SMW_Name')] ~= nil then
return self.smwData
end
local queryName = self.frameArgs[translate('ARG_SmwQueryName')] or
self.frameArgs[translate('ARG_Name')] or
mw.title.getCurrentTitle().fullText
local smwData = mw.smw.ask(makeSmwQueryObject(queryName))
if smwData == nil or smwData[1] == nil then
return hatnote(mw.ustring.format(
'%s[[%s]]',
t('message_error_no_data_text'),
t('category_error_pages_with_script_errors')
),
{ icon = 'WikimediaUI-Error.svg' }
)
end
self.smwData = smwData[1]
return self.smwData
end
--- Creates the infobox
function methodtable.getInfobox(self)
local smwData = self:getSmwData()
mw.logObject(smwData, '⌛ [Vehicle] Loaded infobox SMW data')
local infobox = require('Module:InfoboxNeue'):new({
placeholderImage = config.placeholder_image
})
local tabber = require('Module:Tabber').renderTabber
--- SMW Data load error
--- Infobox data should always have Name property
if type(smwData) ~= 'table' then
return infobox:renderInfobox(infobox:renderMessage({
title = t('message_error_no_data_title'),
desc = t('message_error_no_data_text'),
}))
end
local function getIndicatorClass()
local state = smwData[t('SMW_ProductionState')]
if state == nil then return end
local classMap = config.productionstate_map
for _, map in pairs(classMap) do
if mw.ustring.match(state, translate(map.name)) ~= nil then
return 'infobox__indicator--' .. map.color
end
end
end
local function getManufacturer()
if smwData[t('SMW_Manufacturer')] == nil then return end
local mfu = manufacturer:get(smwData[t('SMW_Manufacturer')])
if mfu == nil then return smwData[t('SMW_Manufacturer')] end
return infobox.showDescIfDiff(
table.concat({ '[[', smwData[t('SMW_Manufacturer')], '|', mfu.name, ']]' }),
mfu.code
)
end
local function getSize()
if smwData[t('SMW_Size')] == nil then return smwData[t('SMW_ShipMatrixSize')] end
local codes = { 'XXS', 'XS', 'S', 'M', 'L', 'XL' }
local size = smwData[t('SMW_Size')]
-- For uninitialized SMW properties
if type(size) == 'string' then
size = tonumber(size, 10)
end
return infobox.showDescIfDiff(
smwData[t('SMW_ShipMatrixSize')],
table.concat({ 'S', size, '/', codes[size] })
)
end
local function getSeries()
local series = smwData[t('SMW_Series')]
if series == nil then return end
return mw.ustring.format(
'[[:Category:%s|%s]]',
mw.ustring.format(t('category_series'), series),
series
)
end
--- Cost section
local function getCostSection()
local tabberData = {}
local section
tabberData['label1'] = t('label_Pledge')
section = {
infobox:renderItem({
label = t('label_Standalone'),
data = infobox.showDescIfDiff(smwData[t('SMW_PledgePrice')], smwData[t('SMW_OriginalPledgePrice')]),
}),
infobox:renderItem({
label = t('label_Warbond'),
data = infobox.showDescIfDiff(smwData[t('SMW_WarbondPledgePrice')], smwData[t('SMW_OriginalWarbondPledgePrice')]),
}),
infobox:renderItem({
label = t('label_Availability'),
data = smwData[t('SMW_PledgeAvailability')],
}),
}
tabberData['content1'] = infobox:renderSection({ content = section, col = 2 }, true)
tabberData['label2'] = t('label_Insurance')
section = {
infobox:renderItem({
label = t('label_Claim'),
data = makeTimeReadable(smwData[translate('SMW_InsuranceClaimTime')]),
}),
infobox:renderItem({
label = t('label_Expedite'),
data = makeTimeReadable(smwData[translate('SMW_InsuranceExpediteTime')]),
}),
infobox:renderItem({
label = t('label_ExpediteFee'),
data = smwData[translate('SMW_InsuranceExpediteCost')],
colspan = 2
}),
}
tabberData['content2'] = infobox:renderSection({ content = section, col = 4 }, true)
return tabber(tabberData)
end
--- Specifications section
local function getSpecificationsSection()
local tabberData = {}
local section
tabberData['label1'] = t('label_Dimensions')
section = {
infobox:renderItem({
label = t('label_Length'),
data = infobox.showDescIfDiff(smwData[t('SMW_EntityLength')], smwData[t('SMW_RetractedLength')]),
}),
infobox:renderItem({
label = t('label_Width'),
data = infobox.showDescIfDiff(smwData[t('SMW_EntityWidth')], smwData[t('SMW_RetractedWidth')]),
}),
infobox:renderItem({
label = t('label_Height'),
data = infobox.showDescIfDiff(smwData[t('SMW_EntityHeight')], smwData[t('SMW_RetractedHeight')]),
}),
infobox:renderItem({
label = t('label_Mass'),
data = smwData[t('SMW_Mass')],
}),
}
tabberData['content1'] = infobox:renderSection({ content =section, col = 3 }, true)
tabberData['label2'] = t('label_Speed')
section = {
infobox:renderItem({
label = t('label_ScmSpeed'),
data = smwData[t('SMW_ScmSpeed')]
}),
infobox:renderItem({
label = t('label_0ToScm'),
data = smwData[t('SMW_ZeroToScmSpeedTime')]
}),
infobox:renderItem({
label = t('label_ScmTo0'),
data = smwData[t('SMW_ScmSpeedToZeroTime')]
}),
infobox:renderItem({
label = t('label_MaxSpeed'),
data = smwData[t('SMW_MaximumSpeed')]
}),
infobox:renderItem({
label = t('label_0ToMax'),
data = smwData[t('SMW_ZeroToMaximumSpeedTime')]
}),
infobox:renderItem({
label = t('label_MaxTo0'),
data = smwData[t('SMW_MaximumSpeedToZeroTime')]
}),
infobox:renderItem({
label = t('label_ReverseSpeed'),
data = smwData[t('SMW_ReverseSpeed')]
}),
infobox:renderItem({
label = t('label_RollRate'),
data = smwData[t('SMW_RollRate')]
}),
infobox:renderItem({
label = t('label_PitchRate'),
data = smwData[t('SMW_PitchRate')]
}),
infobox:renderItem({
label = t('label_YawRate'),
data = smwData[t('SMW_YawRate')]
}),
}
tabberData['content2'] = infobox:renderSection({ content = section, col = 3 }, true)
tabberData['label3'] = t('label_Fuel')
section = {
infobox:renderItem({
label = t('label_HydrogenCapacity'),
data = smwData[t('SMW_HydrogenFuelCapacity')],
}),
infobox:renderItem({
label = t('label_HydrogenIntake'),
data = smwData[t('SMW_HydrogenFuelIntakeRate')],
}),
infobox:renderItem({
label = t('label_QuantumCapacity'),
data = smwData[t('SMW_QuantumFuelCapacity')],
}),
}
tabberData['content3'] = infobox:renderSection({ content = section, col = 2 }, true)
tabberData['label4'] = t('label_Hull')
section = {
infobox:renderItem({
label = t('label_CrossSection'),
data = formatModifier(smwData[t('SMW_CrossSectionSignatureModifier')]),
}),
infobox:renderItem({
label = t('label_Electromagnetic'),
data = formatModifier(smwData[t('SMW_ElectromagneticSignatureModifier')]),
}),
infobox:renderItem({
label = t('label_Infrared'),
data = formatModifier(smwData[t('SMW_InfraredSignatureModifier')]),
}),
infobox:renderItem({
label = t('label_Physical'),
data = formatModifier(smwData[t('SMW_PhysicalDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Energy'),
data = formatModifier(smwData[t('SMW_EnergyDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Distortion'),
data = formatModifier(smwData[t('SMW_DistortionDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Thermal'),
data = formatModifier(smwData[t('SMW_ThermalDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Biochemical'),
data = formatModifier(smwData[t('SMW_BiochemicalDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Stun'),
data = formatModifier(smwData[t('SMW_StunDamageModifier')]),
}),
infobox:renderItem({
label = t('label_Health'),
data = smwData[t('SMW_HealthPoint')],
}),
}
tabberData['content4'] = infobox:renderSection({ content = section, col = 3 }, true)
return tabber(tabberData)
end
--- Other sites
local function getOfficialSites()
local links = {}
for _, site in ipairs(data.official_sites) do
local query = smwData[translate(site.attribute)]
if query ~= nil then
table.insert(links, infobox:renderLinkButton({
label = translate(site.label),
link = query
}))
end
end
return links
end
local function getCommunitySites()
local links = {}
for _, site in ipairs(data.community_sites) do
local query = smwData[translate(site.data)]
if query ~= nil then
if site.data == 'SMW_ClassName' or site.data == 'SMW_UUID' then
query = mw.ustring.lower(query)
elseif site.data == 'SMW_ShipMatrixName' then
query = mw.uri.encode(query, 'PATH')
end
if site.label == 'FleetYards' then
query = mw.ustring.lower(mw.ustring.gsub(query, '%%20', '-'))
end
table.insert(links, infobox:renderLinkButton({
label = site.label,
link = mw.ustring.format(site.format, query)
}))
end
end
return links
end
local image = self.frameArgs[translate('ARG_Image')] or self.frameArgs['image'] or smwData['image']
infobox:renderImage(image)
infobox:renderIndicator({
data = smwData[t('SMW_ProductionState')],
desc = smwData[t('SMW_ProductionStateDesc')],
class = getIndicatorClass()
})
infobox:renderHeader({
title = smwData[t('SMW_Name')],
--- e.g. Aegis Dynamics (AEGS)
subtitle = getManufacturer()
})
--- Role, Size, Series and Loaners
infobox:renderSection({
content = {
infobox:renderItem({
label = t('label_Role'),
data = infobox.tableToCommaList(smwData[t('SMW_Role')]),
}),
infobox:renderItem({
label = t('label_Size'),
data = getSize(),
}),
infobox:renderItem({
label = t('label_Series'),
data = getSeries(),
}),
infobox:renderItem({
label = t('label_Loaner'),
data = infobox.tableToCommaList(smwData[t('SMW_LoanerVehicle')]),
}),
},
col = 2
})
--- Capacity
infobox:renderSection({
title = t('label_Capacity'),
col = 3,
content = {
infobox:renderItem({
label = t('label_Crew'),
data = infobox.formatRange(smwData[t('SMW_MinimumCrew')], smwData[t('SMW_MaximumCrew')], true),
}),
infobox:renderItem({
label = t('label_Cargo'),
data = smwData[t('SMW_CargoCapacity')],
}),
infobox:renderItem({
label = t('label_Stowage'),
data = smwData[t('SMW_VehicleInventory')],
}),
},
})
--- Cost
infobox:renderSection({
title = t('label_Cost'),
class = 'infobox__section--tabber',
content = getCostSection(),
})
--- Specifications
infobox:renderSection({
title = t('label_Specifications'),
class = 'infobox__section--tabber',
content = getSpecificationsSection(),
})
--- Lore section
infobox:renderSection({
title = t('label_Lore'),
col = 2,
content = {
infobox:renderItem({
label = t('label_Released'),
data = smwData[t('SMW_LoreReleaseDate')]
}),
infobox:renderItem({
label = t('label_Retired'),
data = smwData[t('SMW_LoreRetirementDate')]
}),
},
})
--- Development section
infobox:renderSection({
title = t('label_Development'),
col = 2,
content = {
infobox:renderItem({
label = t('label_Announced'),
data = smwData[t('SMW_ConceptAnnouncementDate')]
}),
infobox:renderItem({
label = t('label_ConceptSale'),
data = smwData[t('SMW_ConceptSaleDate')]
}),
},
})
--- Metadata section
infobox:renderSection({
class = 'infobox__section--metadata infobox__section--hasBackground',
content = {
infobox:renderItem({
label = t('SMW_UUID'),
data = smwData[t('SMW_UUID')],
row = true,
spacebetween = true
}),
infobox:renderItem({
label = t('SMW_ClassName'),
data = smwData[t('SMW_ClassName')],
row = true,
spacebetween = true
}),
infobox:renderItem({
label = t('SMW_GameBuild'),
data = smwData[t('SMW_GameBuild')],
row = true,
spacebetween = true
})
},
})
--- Actions section
if smwData[t('SMW_UUID')] then
infobox:renderSection({
class = 'infobox__section--actions infobox__section--hasBackground',
content = {
infobox:renderItem({
icon = 'WikimediaUI-Search.svg',
data = translate('label_actions_find_item_title'),
desc = t('label_actions_find_item_text'),
-- FIXME: Make this configurable?
link = 'https://finder.cstone.space/search/' .. smwData[t('SMW_UUID')]
})
}
})
end
--- Footer
infobox:renderFooter({
button = {
icon = 'WikimediaUI-Globe.svg',
label = t('label_OtherSites'),
type = 'popup',
content = infobox:renderSection({
content = {
infobox:renderItem({
label = t('label_OfficialSites'),
data = table.concat(getOfficialSites(), '')
}),
infobox:renderItem({
label = t('label_CommunitySites'),
data = table.concat(getCommunitySites(), '')
}),
},
class = 'infobox__section--linkButtons',
}, true)
}
})
return infobox:renderInfobox(nil, smwData[t('SMW_Name')])
end
--- Set the frame and load args
--- @param frame table
function methodtable.setFrame(self, frame)
self.currentFrame = frame
self.frameArgs = require('Module:Arguments').getArgs(frame)
end
--- Sets the main categories for this object
function methodtable.setCategories(self)
if config.set_categories == false then
return
end
local size = self.smwData[t('SMW_ShipMatrixSize')]
local size_cat, pledge_cat
local isGroundVehicle = isGroundVehicle(self.smwData)
if isGroundVehicle then
--Ground vehicle has no ship matrix size currently
--size_cat = 'category_ground_vehicle_size'
pledge_cat = 'category_ground_vehicle_pledge'
table.insert(
self.categories,
string.format('[[Category:%s]]', t('category_ground_vehicle'))
)
else
size_cat = 'category_ship_size'
pledge_cat = 'category_ship_pledge'
table.insert(
self.categories,
string.format('[[Category:%s]]', t('category_ship'))
)
end
if size ~= nil and size_cat then
table.insert(
self.categories,
string.format('[[Category:%s]]', mw.ustring.format(t(size_cat), size))
)
end
if self.smwData[t('SMW_Manufacturer')] ~= nil then
local manufacturer = mw.ustring.gsub(self.smwData[t('SMW_Manufacturer')], '%[+', '')
manufacturer = mw.ustring.gsub(manufacturer, '%]+', '')
table.insert(
self.categories,
string.format('[[Category:%s]]', manufacturer)
)
end
if self.smwData[t('SMW_ProductionState')] ~= nil then
table.insert(
self.categories,
string.format('[[Category:%s]]', self.smwData[t('SMW_ProductionState')])
)
end
if self.smwData[t('SMW_Series')] ~= nil then
table.insert(
self.categories,
string.format('[[Category:%s]]', mw.ustring.format(t('category_series'), self.smwData[t('SMW_Series')]))
)
end
if pledge_cat and self.smwData[t('SMW_PledgePrice')] ~= nil then
table.insert(
self.categories,
string.format('[[Category:%s]]', translate(pledge_cat))
)
end
end
--- Sets the short description for this object
function methodtable.setShortDescription(self)
local shortdesc
local vehicleType
local isGroundVehicle = isGroundVehicle(self.smwData)
if isGroundVehicle then
vehicleType = t('shortdesc_ground_vehicle')
else
vehicleType = t('shortdesc_ship')
end
if self.smwData[t('SMW_Role')] ~= nil then
local vehicleRole = self.smwData[t('SMW_Role')]
if type(vehicleRole) == 'table' then
vehicleRole = table.concat(vehicleRole, ' ')
end
vehicleRole = mw.ustring.lower(vehicleRole)
for _, noun in pairs(config.role_suffixes) do
local match = mw.ustring.find(vehicleRole, '%f[%a]' .. noun .. '%f[%A]')
--- Remove suffix from role
if match then
vehicleRole = mw.text.trim(mw.ustring.gsub(vehicleRole, noun, ''))
vehicleType = noun
end
end
shortdesc = mw.ustring.format('%s %s', vehicleRole, vehicleType)
else
shortdesc = vehicleType
end
if not isGroundVehicle and self.smwData[t('SMW_ShipMatrixSize')] ~= nil then
local vehicleSize = self.smwData[t('SMW_ShipMatrixSize')]
--- Special handling for single-seat ship
if self.smwData[t('SMW_MaximumCrew')] ~= nil and self.smwData[t('SMW_MaximumCrew')] == 1 then
vehicleSize = t('shortdesc_single_seat')
end
shortdesc = mw.ustring.format('%s %s', vehicleSize, shortdesc)
end
if self.smwData[t('SMW_Manufacturer')] ~= nil then
local mfuname = self.smwData[t('SMW_Manufacturer')]
local man = manufacturer:get(mfuname)
--- Use short name if possible
if man ~= nil and man.shortname ~= nil then mfuname = man.shortname end
shortdesc = mw.ustring.format(t('shortdesc_manufactured_by'), shortdesc, mfuname)
end
shortdesc = lang:ucfirst(shortdesc)
self.currentFrame:callParserFunction('SHORTDESC', shortdesc)
end
--- Save Api Data to SMW store
function methodtable.saveApiData(self)
self:getApiDataForCurrentPage()
self:setSemanticProperties()
end
--- Generates debug output
function methodtable.makeDebugOutput(self)
local debug = require('Module:Common/Debug')
self.smwData = nil
local smwData = self:getSmwData()
local queryName = self.frameArgs[translate('ARG_SmwQueryName')] or
self.frameArgs[translate('ARG_Name')] or
mw.title.getCurrentTitle().fullText
return debug.collapsedDebugSections({
{
title = 'SMW Query',
content = debug.convertSmwQueryObject(makeSmwQueryObject(queryName)),
},
{
title = 'SMW Data',
content = smwData,
tag = 'pre',
},
{
title = 'Frame Args',
content = self.frameArgs,
tag = 'pre',
},
})
end
--- New Instance
function Vehicle.new(self)
local instance = {
categories = {}
}
setmetatable(instance, metatable)
return instance
end
--- Load data from api.star-citizen.wiki and save it to SMW
---
--- @param frame table Invocation frame
--- @return string|nil
function Vehicle.loadApiData(frame)
local instance = Vehicle:new()
instance:setFrame(frame)
instance:saveApiData()
local debugOutput
if instance.frameArgs['debug'] ~= nil then
local debug = require('Module:Common/Debug')
debugOutput = debug.collapsedDebugSections({
{
title = 'SMW Set Data',
content = mw.getCurrentFrame():callParserFunction('#tag', {'nowiki', mw.dumpObject(instance.setData or {})}),
},
})
end
return debugOutput
end
--- Generates an infobox based on passed frame args and SMW data
---
--- @param frame table Invocation frame
--- @return string
function Vehicle.infobox(frame)
local instance = Vehicle:new()
instance:setFrame(frame)
local debugOutput = ''
if instance.frameArgs['debug'] ~= nil then
debugOutput = instance:makeDebugOutput()
end
return tostring(instance:getInfobox()) .. debugOutput
end
--- "Main" entry point for templates that saves the API Data and outputs the infobox
---
--- @param frame table Invocation frame
--- @return string
function Vehicle.main(frame)
local instance = Vehicle:new()
instance:setFrame(frame)
instance:saveApiData()
local debugOutput = ''
if instance.frameArgs['debug'] ~= nil then
debugOutput = instance:makeDebugOutput()
end
local infobox = tostring(instance:getInfobox())
-- Only set categories and short desc if this is the page that also holds the smw attributes
-- Allows outputting vehicle infoboxes on other pages without setting categories
if instance.smwData ~= nil then
instance:setCategories()
instance:setShortDescription()
-- FIXME: Is there a cleaner way?
infobox = infobox .. common.generateInterWikiLinks(mw.title.getCurrentTitle().text)
end
return infobox .. debugOutput .. table.concat(instance.categories)
end
---
function Vehicle.test(page)
page = page or '300i'
local instance = Vehicle:new()
instance.frameArgs = {}
instance.frameArgs[translate('ARG_Name')] = page
instance:saveApiData()
instance:getInfobox()
end
return Vehicle