Die Dokumentation für dieses Modul kann unter Modul:WeaponPersonal/Doku erstellt werden
require( 'strict' )
local WeaponPersonal = {}
local metatable = {}
local methodtable = {}
metatable.__index = methodtable
-- Extensions
local infobox = require( 'Module:InfoboxNeue' )
local manufacturer = require( 'Module:Hersteller' )
local common = require( 'Module:Common' )
local api = require( 'Module:Common/Api' )
local TNT = require( 'Module:Translate' ):new()
local localized = require( 'Module:Localized' )
local item = require( 'Module:Item' )
local commodity = require( 'Module:Commodity' )
local data = mw.loadData( 'Module:WeaponPersonal/Data' )
--- @param class string
--- @return string
local function translateClass( class )
return {
de_DE = ( data.classTranslations[ class ] or class ),
en_EN = class,
}
end
--- @param type string
--- @return string
local function translateType( type )
return {
de_DE = ( data.typeTranslations[ type ] or type ),
en_EN = type,
}
end
--- @param magazine string
--- @return string
local function translateMagazine( magazine )
if magazine == nil or #magazine == 0 then
return nil
end
return {
de_DE = ( data.magazineTranslations[ magazine ] or magazine ),
en_EN = magazine,
}
end
--- Add manual smw data
function methodtable.addManual( self )
if self.frameArgs == nil then
return
end
local function addLangCode( key )
if self.frameArgs[ key ] ~= nil then
return self.frameArgs[ key ] .. '@de'
end
return nil
end
local setObj = {
[ 'Name' ] = self.frameArgs[ 'Name' ] or nil,
[ 'Größe' ] = self.frameArgs[ 'Gewicht' ] or nil,
[ 'Hersteller' ] = self.frameArgs[ 'Hersteller' ] or nil,
[ 'Beschreibung' ] = addLangCode( 'Beschreibung' ),
[ 'Waffentyp' ] = self.frameArgs[ 'Waffentyp' ] or nil,
[ 'Waffenklasse' ] = self.frameArgs[ 'Waffenklasse' ] or nil,
[ 'Magazingröße' ] = self.frameArgs[ 'Magazingröße' ] or nil,
[ 'Effektive Reichweite' ] = self.frameArgs[ 'Effektive Reichweite' ] or nil,
[ 'Feuerrate' ] = self.frameArgs[ 'Feuerrate' ] or nil,
[ 'Spielversion' ] = self.frameArgs[ 'Spielversion' ] or nil,
}
mw.smw.set( setObj )
end
--- Request Api Data
--- Using current subpage name
--- @return table
function methodtable.getApiDataForCurrentPage( self )
local name = self.frameArgs[ 'name' ] or mw.title.getCurrentTitle().subpageText
local json = mw.text.jsonDecode( mw.ext.Apiunto.get_raw( 'v2/weapons/' .. name, {
include = {
'shops.items',
}
} ) )
api.checkResponseStructure( json, true, false )
self.apiData = json[ 'data' ]
return self.apiData
end
--- Queries the SMW Store
--- @return table
function methodtable.getSmwData( self )
-- Cache multiple calls
if self.smwData ~= nil then
return self.smwData
end
-- name from args or current page
local queryName = self.frameArgs[ 'name' ] or localized.getMainTitle()
local data = mw.smw.ask( {
'[[' .. queryName .. ']]',
'?#-=page',
'?Name#-=name',
'?Größe#-=size',
'?Hersteller#-=manufacturer',
'?Beschreibung=description', '+lang=' .. common.getLocaleForPage(),
'?Waffentyp=type', '+lang=' .. common.getLocaleForPage(),
'?Waffentyp=type_de', '+lang=de',
'?Waffenklasse=class', '+lang=' .. common.getLocaleForPage(),
'?Waffenklasse=class_de', '+lang=de',
'?Magazingröße#-=magazine_size',
'?Magazintyp=magazine_type', '+lang=' .. common.getLocaleForPage(),
'?Magazintyp=magazine_type_de', '+lang=de',
'?Effektive Reichweite#-=range',
'?Schaden pro Schuss#-=dps',
'?Feuerrate#-=rof',
'?Länge=length',
'?Breite=width',
'?Höhe=height',
'?Volumen=volume',
'?Spielversion#-=version',
'mainlabel=-'
} )
if data == nil or data[ 1 ] == nil then
error( TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'msg_no_data', queryName ), 0 )
end
self.smwData = data[ 1 ]
local weaponSubobjects = require( 'Module:WeaponSubobjects' ):new()
self.smwData.modes = weaponSubobjects:getWeaponModes( queryName )
self.smwData.defaultAttachments = weaponSubobjects:getDefaultAttachments( queryName )
self.smwData.attachmentPorts = weaponSubobjects:getAttachmentPorts( queryName )
self.smwData.damages = weaponSubobjects:getDamages( queryName )
self.smwData.ammunition = weaponSubobjects:getAmmunition( queryName )
self.smwData.price = commodity.getPrice( queryName )
if self.smwData.price ~= nil then
self.smwData.price = self.smwData.price[ 1 ].price
end
return self.smwData
end
--- Base Properties that are shared across all Vehicles
--- @return table SMW Result
function methodtable.setSemanticProperties( self )
-- Api Error, don't set anything
if self.apiData == nil or mw.title.getCurrentTitle().isSubpage then
return
end
local rof = nil
if self.apiData.personal_weapon ~= nil then
rof = self.apiData.personal_weapon.rof
if rof ~= nil then
rof = mw.text.split( rof, ' ', true )[ 1 ] or nil
rof = string.gsub( rof, ',', '' )
end
end
local item = item:new( '', self.apiData )
--- The base data for the page
local setData = item:makeSmwObject()
if type( self.apiData.personal_weapon ) == 'table' then
setData[ 'Waffentyp' ] = api.mapTranslation( translateType( self.apiData.personal_weapon.type or nil ) )
setData[ 'Waffenklasse' ] = api.mapTranslation( translateClass( self.apiData.personal_weapon.class or nil ) )
setData[ 'Magazingröße' ] = self.apiData.personal_weapon.magazine_size or nil
setData[ 'Magazintyp' ] = api.mapTranslation( translateMagazine( self.apiData.personal_weapon.magazine_type or nil ) )
setData[ 'Effektive Reichweite' ] = self.apiData.personal_weapon.effective_range or nil
setData[ 'Schaden pro Schuss' ] = common.formatNum( self.apiData.personal_weapon.damage_per_shot, nil )
setData[ 'Feuerrate' ] = common.formatNum( rof, nil )
end
local result = mw.smw.set( setData )
local weaponSubobjects = require( 'Module:WeaponSubobjects' ):new()
weaponSubobjects:setSemanticProperties( self.apiData )
commodity:new():addShopData( self.apiData )
return result
end
--- Sets the main categories for this object
function methodtable.setCategories( self, smwData )
if smwData.manufacturer == nil then
table.insert( self.categories, '[[Category:Seiten mit Skriptfehlern]]' )
return
end
if self.lang == 'de' then
table.insert( self.categories, '[[Category:' .. smwData.manufacturer .. '|' .. smwData.name .. ' ]]' )
if smwData.type ~= nil then
table.insert( self.categories, '[[Category:' .. smwData.type_de .. '|' .. smwData.name .. ' ]]' )
end
else
table.insert( self.categories, '[[Category:' .. smwData.name ..'|' .. smwData.name .. ' ]]' )
end
end
--- Entrypoint for {{#seo:}}
function methodtable.setSeoData( self )
if self.currentFrame == nil then
error( 'No frame set. Call "setFrame" first.', 0 )
end
local data = self:getSmwData()
if nil == data.manufacturer then
-- Faulty SMW data, don't call #seo
return
end
require( 'Module:SEO' ).set(
TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'seo_section' ),
data.page,
table.concat({
data.name,
data.manufacturer,
self.currentFrame:preprocess( '{{SITENAME}}' )
}, ' - '),
'replace',
{
data.name or '',
data.type or '',
data.class or '',
data.manufacturer or '',
manufacturer.getCodeFromName( data.manufacturer ) or '',
},
nil,
self.frameArgs[ 'image' ],
data.page
)
end
--- Creates the infobox
--- TODO: This is a mess ;_;
function methodtable.getInfoBox( self )
local data = self:getSmwData()
if nil == data.manufacturer then
return TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'msg_smw_loading' )
end
-- Set Title
common.setDisplayTitle( self.currentFrame, data.name )
local box = infobox:new( {
removeEmpty = true,
emptyString = '-',
placeholderImage = 'Platzhalter Waffen.webp',
} )
local cleanedImageName = string.gsub( data.name or '', '"', '' )
-- Image
box:renderImage( common.getImage( {
self.frameArgs[ 'image' ],
cleanedImageName
} ) )
box:renderHeader( {
title = data.name,
subtitle = '[[' .. data.manufacturer .. ']]' .. api.getVersionInfoRef( data.version, self.lang )
} )
local weaponType = data.type
if weaponType ~= nil then
weaponType = string.format('[[:Kategorie:%s|%s]]', data.type_de, weaponType)
end
local weaponClass = data.class
if weaponClass ~= nil then
weaponClass = string.format('[[:Kategorie:%s|%s]]', data.class_de, weaponClass)
end
local maxRange = '-'
local muzzleVelocity = '-'
if type( data.ammunition ) == 'table' then
maxRange = data.ammunition[ 1 ][ 'Maximalreichweite' ]
muzzleVelocity = data.ammunition[ 1 ][ 'Mündungsgeschwindigkeit' ]
end
local section = {}
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'lbl_type' ), weaponType ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'lbl_class' ), weaponClass ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'lbl_price' ), data.price or TNT.formatInLanguage( self.lang, 'Module:Common/i18n.json', 'txt_cant_buy' ) ) )
if data.magazine_size ~= nil then
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_magazine_size' ), data.magazine_size .. ' ' .. TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_shots' ) ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_dps' ), data.dps ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_magazine_type' ), data.magazine_type ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_rof' ), ( data.rof or '-' ) .. ' ' .. TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_shot_s' ) ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_muzzle_velocity' ), muzzleVelocity ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_effective_range' ), data.range ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_max_range' ), maxRange ) )
end
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_weight' ), data.volume or '-' ) )
box:renderSection( {
col = 2,
content = section,
} )
--[[
Weapon Modes
]]--
if data.modes ~= nil and type( data.modes ) == 'table' then
section = {}
for _, mode in pairs( data.modes ) do
local dps = mode.dps or nil
if dps ~= nil then
dps = string.format("%.2f", dps)
else
dps = ' - '
end
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_mode' ), mode.name ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_rof' ), (mode.rof or ' - ') .. ' ' .. TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_shot_s' ) ) )
table.insert( section, box:renderItem( TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_dps' ), dps ) )
end
box:renderSection( {
title = TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_fire_modes' ),
col = 3,
content = section
} )
end
--[[
Weapon Attachments
]]--
if data.attachmentPorts ~= nil and type( data.attachmentPorts ) == 'table' then
section = {}
for _, attachment in pairs( data.attachmentPorts ) do
if type( attachment ) == 'table' and attachment.position_de ~= 'Magazin' then
table.insert( section, box:renderItem( attachment.position, 'S' .. attachment.min_size ) )
end
end
box:renderSection( {
title = TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_attachments' ),
col = 3,
content = section
} )
end
--[[
Weapon Default Loadout
]]--
if data.defaultAttachments ~= nil and type( data.defaultAttachments ) == 'table' then
section = {}
for _, attachment in pairs( data.defaultAttachments ) do
if type( attachment ) == 'table' and attachment.name ~= nil then
local size = attachment.size
if size ~= nil and tonumber( size ) > 0 then
size = 'S' .. size .. ' '
end
table.insert( section, box:renderItem( attachment.position, size .. string.format( '[[%s]]', attachment.name ) ) )
end
end
box:renderSection( {
title = TNT.formatInLanguage( self.lang, 'Module:WeaponPersonal/i18n.json', 'lbl_standard_equipment' ),
content = section
} )
end
return tostring( box ) .. tostring( common.generateInterWikiLinks( data.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 )
if type( self.frameArgs[ 'Bild' ] ) == 'string' then
self.frameArgs[ 'image' ] = self.frameArgs[ 'Bild' ]
end
end
--- Get categories
function methodtable.getCategories( self )
return tostring( table.concat( self.categories ) )
end
--- Save Api Data to SMW store
function methodtable.saveApiData( self )
if self.currentFrame == nil then
error( 'No frame set. Call "setFrame" first.', 0 )
end
local data = self:getApiDataForCurrentPage()
self:setSemanticProperties()
return data
end
--- Template entry
function WeaponPersonal.main( frame )
local instance = WeaponPersonal:new()
instance:setFrame( frame )
if not localized.isLanguagePage() then
if instance.frameArgs[ 'Manuell' ] ~= nil then
instance:addManual()
else
instance:saveApiData()
end
end
instance:setCategories( instance:getSmwData() )
instance:setSeoData()
return tostring( instance:getInfoBox() ) .. instance:getCategories()
end
--- New Instance
function WeaponPersonal.new( self )
local instance = {
categories = {},
lang = require( 'Module:Template translation' )._getLanguageSubpage( mw.title.getCurrentTitle() )
}
setmetatable( instance, metatable )
return instance
end
return WeaponPersonal