无编辑摘要 |
标签:回退 |
||
第1行: | 第1行: | ||
local | local VehicleHardPoint = {} | ||
local metatable = {} | local metatable = {} | ||
local methodtable = {} | local methodtable = {} | ||
local common = require( 'Module:Common' ) | |||
local data = mw.loadData( 'Module:VehicleHardpoint/Data' ) | |||
local | |||
local | |||
local hatnote = require( 'Module:Hatnote' )._hatnote | local hatnote = require( 'Module:Hatnote' )._hatnote | ||
metatable.__index = methodtable | |||
-- | -- Local functions | ||
--- Checks if an entry contains a 'child' key with further entries | --- Checks if an entry contains a 'child' key with further entries | ||
第51行: | 第19行: | ||
end | end | ||
--- Creates a key to be used in 'setHardPointObjects' | |||
--- Creates | --- This allows to sum the total count of each similar object | ||
--- | --- | ||
--- @param row table - API Data | --- @param row table - API Data | ||
--- @param hardpointData table - Data from getHardpointData | --- @param hardpointData table - Data from getHardpointData | ||
--- @param parent table|nil - Parent hardpoint | --- @param parent table|nil - Parent hardpoint | ||
--- @param root string|nil - Root hardpoint | --- @param root string|nil - Root hardpoint | ||
--- @return string Key | --- @return string Key | ||
第123行: | 第30行: | ||
local key | local key | ||
if type( row.item ) == 'table' then | if type( row.item ) == 'table' then | ||
if row.type == 'ManneuverThruster' or | if row.type == 'ManneuverThruster' or | ||
row.type == 'MainThruster' or | row.type == 'MainThruster' or | ||
row.type == 'WeaponDefensive' or | |||
row.type == 'WeaponLocker' or | |||
row.type == 'ArmorLocker' or | row.type == 'ArmorLocker' or | ||
row.type == 'Bed' or | row.type == 'Bed' or | ||
row.type == 'CargoGrid | row.type == 'CargoGrid' | ||
then | then | ||
key = row.type .. row.sub_type | key = row.type .. row.sub_type | ||
else | else | ||
key = row.type .. row.sub_type .. row.item.uuid | |||
end | end | ||
else | else | ||
key = hardpointData.class .. hardpointData.type | key = hardpointData.class .. hardpointData.type | ||
end | end | ||
if row.type ~= 'WeaponDefensive' then | |||
if parent ~= nil then | |||
key = key .. parent[ 'Hardpoint' ] | |||
if | end | ||
if root ~= nil and not string.match( key, root ) and ( hardpointData.class == 'Weapons' ) then | |||
key = key .. root | |||
end | |||
end | end | ||
if hardpointData.class == 'Weapons' and row.name ~= nil and row.type == 'MissileLauncher' then | if hardpointData.class == 'Weapons' and row.name ~= nil and row.type == 'MissileLauncher' then | ||
key = key .. row.name | |||
end | end | ||
mw. | --mw.log(string.format('Key: %s', key)) | ||
return key | return key | ||
end | end | ||
--- Get pre-defined hardpoint data for a given hardpoint type | --- Tries to fix hardpoints that have no item, but everything set on the 'child' key | ||
--- | |||
--- @param row table - API Data | |||
--- @return table - Fixed entry | |||
local function fixChild( row ) | |||
if row.item == nil and hasChildren( row ) and #row.children == 1 then | |||
local item = row.children[ 1 ] | |||
local children = {} | |||
if hasChildren( item ) then | |||
children = item.children | |||
if item.item ~= nil and item.item.children ~= nil then | |||
item.item.children = {} | |||
end | |||
end | |||
row.name = item.name | |||
row.type = item.type | |||
row.sub_type = item.sub_type | |||
row.item = item.item | |||
if #children > 1 then | |||
row.children = children | |||
else | |||
row.children = { data = {} } | |||
end | |||
end | |||
return row | |||
end | |||
--- Get pre-defined hardpoint data for a given hardpoint type or name | |||
--- | --- | ||
--- @param hardpointType string | --- @param hardpointType string | ||
--- @return table|nil | --- @return table|nil | ||
function methodtable.getHardpointData( self, hardpointType ) | function methodtable.getHardpointData( self, hardpointType ) | ||
if type( data. | if type( data.hardPointMappings[ hardpointType ] ) == 'table' then | ||
return data. | return data.hardPointMappings[ hardpointType ] | ||
end | end | ||
for hType, mappingData in pairs( data. | for hType, mappingData in pairs( data.hardPointMappings ) do | ||
if hardpointType == hType then | if hardpointType == hType then | ||
return mappingData | return mappingData | ||
第199行: | 第121行: | ||
end | end | ||
--- Creates a settable SMW Subobject | |||
--- Creates a | |||
--- | --- | ||
--- @param row table - API Data | --- @param row table - API Data | ||
第311行: | 第139行: | ||
end | end | ||
object[ | object[ 'Hardpoint' ] = row.name | ||
object[ | --object[ 'From game data' ] = true | ||
object[ | object[ 'Hardpoint minimum size' ] = row.min_size | ||
object[ | object[ 'Hardpoint maximum size' ] = row.max_size | ||
object[ | object[ 'Vehicle hardpoints template group' ] = hardpointData.class | ||
if | if data.hardPointNames[ row.type ] ~= nil then | ||
object[ | object[ 'Hardpoint type' ] = data.hardPointNames[ row.type ] | ||
else | |||
object[ 'Hardpoint type' ] = hardpointData.type | |||
end | end | ||
if data.hardPointNames[ row.sub_type ] ~= nil then | |||
object[ 'Hardpoint subtype' ] = data.hardPointNames[ row.sub_type ] | |||
else | |||
object[ 'Hardpoint subtype' ] = hardpointData.type | |||
end | end | ||
if hardpointData.item ~= nil then | |||
if type( hardpointData.item.name ) == 'string' then object[ 'Name' ] = hardpointData.item.name end | |||
if hardpointData.item ~= nil | |||
end | end | ||
if type( row.item ) == 'table' then | if type( row.item ) == 'table' then | ||
local itemObj = row.item | local itemObj = row.item | ||
if itemObj.name ~= '<= PLACEHOLDER =>' then | if itemObj.name ~= '<= PLACEHOLDER =>' then | ||
local match = string.match( row.class_name or '', ' | local match = string.match( row.class_name or '', 'Destruct_(%d+s)') | ||
if row.type == 'SelfDestruct' and match ~= nil then | if row.type == 'SelfDestruct' and match ~= nil then | ||
object[ | object[ 'Name' ] = 'Self destruct (' .. match .. ')' | ||
else | else | ||
object[ | object[ 'Name' ] = row.item.name | ||
end | end | ||
end | end | ||
object[ | if itemObj.type == 'WeaponDefensive' and type( itemObj.counter_measure ) == 'table' then | ||
object[ 'Magazine capacity' ] = itemObj.counter_measure.capacity | |||
end | |||
if ( itemObj.type == 'Cargo' or itemObj.type == 'SeatAccess' or itemObj.type == 'CargoGrid' or itemObj.type == 'Container' ) | if ( itemObj.type == 'Cargo' or itemObj.type == 'SeatAccess' or itemObj.type == 'CargoGrid' or itemObj.type == 'Container' ) | ||
and type( itemObj.inventory ) == 'table' then | |||
object[ 'Inventory' ] = common.formatNum( (itemObj.inventory.scu or nil), nil ) | |||
end | |||
if | if object[ 'Hardpoint minimum size' ] == nil then | ||
object[ 'Hardpoint minimum size' ] = itemObj.size | |||
object[ 'Hardpoint maximum size' ] = itemObj.size | |||
object[ | |||
object[ | |||
end | end | ||
第400行: | 第190行: | ||
if parent ~= nil then | if parent ~= nil then | ||
object[ | object[ 'Parent hardpoint UUID' ] = parent[ 'UUID' ] | ||
object[ | object[ 'Parent hardpoint' ] = parent[ 'Hardpoint' ] | ||
end | end | ||
if root ~= nil and root ~= row.name then | |||
object[ 'Root hardpoint' ] = root | |||
object[ | |||
end | end | ||
-- Remove SeatAccess Hardpoints without storage | |||
if row.item ~= nil and row.item.type == 'SeatAccess' and object[ 'Inventory' ] == nil then | |||
object = nil | |||
end | |||
return object; | return object; | ||
end | end | ||
--- Sets all available hardpoints as sub-objects | |||
--- Sets all available hardpoints as | --- This is the main method called by others | ||
--- This method | |||
--- | --- | ||
--- @param hardpoints table API Hardpoint data | --- @param hardpoints table API Hardpoint data | ||
function methodtable.setHardPointObjects( self, hardpoints ) | function methodtable.setHardPointObjects( self, hardpoints ) | ||
if type( hardpoints ) ~= 'table' then | if type( hardpoints ) ~= 'table' then | ||
error | error( 'Hardpoints need to be a table' ) | ||
end | end | ||
local | local out = {} | ||
local function addToOut( object, key ) | local function addToOut( object, key ) | ||
if object == nil then | if object == nil then | ||
第479行: | 第222行: | ||
end | end | ||
if type( out[ key ] ) ~= 'table' then | |||
if type( | |||
if object ~= nil then | if object ~= nil then | ||
out[ key ] = object | |||
out[ key ][ 'Item quantity' ] = 1 | |||
end | end | ||
else | else | ||
out[ key ][ 'Item quantity' ] = out[ key ][ 'Item quantity' ] + 1 | |||
if type( out[ key ][ 'Magazine capacity' ] ) == 'number' then | |||
out[ key ][ 'Magazine capacity' ] = out[ key ][ 'Magazine capacity' ] + object[ 'Magazine capacity' ] | |||
end | end | ||
if object[ 'Hardpoint type' ] == 'Cargo grid' then | |||
out[ key ][ 'Item quantity' ] = 1 | |||
if out[ key ][ 'Inventory' ] ~= nil and object[ 'Inventory' ] ~= nil then | |||
out[ key ][ 'Inventory' ] = tonumber(out[ key ][ 'Inventory' ]) + tonumber(object[ 'Inventory' ]) | |||
end | |||
end | |||
end | end | ||
end | end | ||
local depth = 1 | |||
local function addHardpoints( hardpoints, parent, root ) | local function addHardpoints( hardpoints, parent, root ) | ||
for _, hardpoint in pairs( hardpoints ) do | for _, hardpoint in pairs( hardpoints ) do | ||
hardpoint.name = string.lower( hardpoint.name ) | hardpoint.name = string.lower( hardpoint.name ) | ||
hardpoint = fixChild( hardpoint ) | |||
if | if depth == 1 then | ||
hardpoint. | root = hardpoint.name | ||
--mw.log(string.format('Root: %s', root)) | |||
end | end | ||
hardpoint = | hardpoint = VehicleHardPoint.fixTypes( hardpoint ) | ||
local hardpointData = self:getHardpointData( hardpoint.type or hardpoint.name ) | local hardpointData = self:getHardpointData( hardpoint.type or hardpoint.name ) | ||
if hardpointData ~= nil then | if hardpointData ~= nil then | ||
local key = makeKey( hardpoint, hardpointData, parent, root ) | local key = makeKey( hardpoint, hardpointData, parent, root ) | ||
第553行: | 第266行: | ||
addToOut( obj, key ) | addToOut( obj, key ) | ||
if hasChildren( hardpoint ) then | if hasChildren( hardpoint ) then | ||
depth = depth + 1 | depth = depth + 1 | ||
第571行: | 第283行: | ||
addHardpoints( hardpoints ) | addHardpoints( hardpoints ) | ||
--mw.logObject(out) | |||
-- | |||
for _, subobject in pairs( out ) do | |||
for _, subobject in pairs( | |||
mw.smw.subobject( subobject ) | mw.smw.subobject( subobject ) | ||
end | end | ||
end | end | ||
--- Queries the SMW store for all available hardpoint subobjects for a given page | --- Queries the SMW store for all available hardpoint subobjects for a given page | ||
第681行: | 第300行: | ||
end | end | ||
local smwData = mw.smw.ask( { | |||
'[[-Has subobject::' .. page .. ']][[Hardpoint type::+]][[Vehicle hardpoints template group::+]]', | |||
'?Item quantity#-=count', | |||
'?Hardpoint minimum size#-=min_size', | |||
'?Hardpoint maximum size#-=max_size', | |||
'?Vehicle hardpoints template group=class', | |||
'?Hardpoint type=type', | |||
'?Hardpoint subtype=sub_type', | |||
'?Name#-=name', | |||
'?Inventory#-n=scu', | |||
'?UUID#-=uuid', | |||
'?Hardpoint#-=hardpoint', | |||
'?Magazine capacity#-=magazine_size', | |||
'?Parent hardpoint#-=parent_hardpoint', | |||
'?Root hardpoint#-=root_hardpoint', | |||
'?Parent UUID#-=parent_uuid', | |||
'?Name.Grade#-=item_grade', | |||
'?Name.Class#-=item_class', | |||
'?Name.Size#-=item_size', | |||
'?Name.Manufacturer#-=manufacturer', | |||
'sort=Vehicle hardpoints template group,Hardpoint type,Hardpoint maximum size,Item quantity', | |||
'order=asc,asc,asc,asc', | |||
'limit=1000' | |||
} ) | |||
if smwData == nil or smwData[ 1 ] == nil then | if smwData == nil or smwData[ 1 ] == nil then | ||
第687行: | 第329行: | ||
end | end | ||
mw.logObject( smwData ) | |||
self.smwData = smwData | self.smwData = smwData | ||
第693行: | 第335行: | ||
return self.smwData | return self.smwData | ||
end | end | ||
--- Group Hardpoints by Class and type | --- Group Hardpoints by Class and type | ||
第706行: | 第347行: | ||
end | end | ||
for _, row in | for _, row in self.spairs( smwData ) do | ||
if not row.isChild and row.class ~= nil and row.type ~= nil | if not row.isChild and row.class ~= nil and row.type ~= nil then | ||
if type( grouped[ row.class ] ) ~= 'table' then | if type( grouped[ row.class ] ) ~= 'table' then | ||
grouped[ row.class ] = {} | grouped[ row.class ] = {} | ||
第722行: | 第358行: | ||
table.insert( grouped[ row.class ][ row.type ], row ) | table.insert( grouped[ row.class ][ row.type ], row ) | ||
end | end | ||
end | end | ||
第732行: | 第365行: | ||
return grouped | return grouped | ||
end | end | ||
--- Adds children to the according parents | --- Adds children to the according parents | ||
第739行: | 第371行: | ||
--- @return table The stratified table | --- @return table The stratified table | ||
function methodtable.createDataStructure( self, smwData ) | function methodtable.createDataStructure( self, smwData ) | ||
-- Maps | -- Maps object id to key in array | ||
local idMapping = {} | local idMapping = {} | ||
for | for key, object in pairs( smwData ) do | ||
if object.hardpoint ~= nil then | |||
if object. | local keyMap = ( object.root_hardpoint or object.hardpoint ) .. object.hardpoint | ||
idMapping[ keyMap ] = key | |||
end | end | ||
end | end | ||
local function stratify( toStratify ) | local function stratify( toStratify ) | ||
for _, object in | for _, object in pairs( toStratify ) do | ||
if object.parent_hardpoint ~= nil then | if object.parent_hardpoint ~= nil then | ||
local | local parentEl = toStratify[ idMapping[ (object.root_hardpoint or '') .. object.parent_hardpoint ] ] | ||
if parentEl ~= nil then | if parentEl ~= nil then | ||
第778行: | 第400行: | ||
end | end | ||
stratify( smwData ) | stratify( smwData ) | ||
return smwData | return smwData | ||
end | end | ||
--- Generate the output | --- Generate the output | ||
第974行: | 第412行: | ||
local classOutput = {} | local classOutput = {} | ||
-- An item with potential children | |||
local function makeEntry( item, depth ) | local function makeEntry( item, depth ) | ||
-- Info if data stems from ship-matrix or game files | |||
if classOutput.info == nil then | if classOutput.info == nil then | ||
local text | local text | ||
if item.from_gamedata == true then | ---if item.from_gamedata == true then | ||
text = 'Data extracted from game data.' | |||
else | ---else | ||
--- text = 'Data extracted from ship matrix.' | |||
end | ---end | ||
classOutput.info = hatnote( text, { icon = 'WikimediaUI-Robot.svg' } ) | classOutput.info = hatnote( text, { icon = 'WikimediaUI-Robot.svg' } ) | ||
第990行: | 第428行: | ||
depth = depth or 1 | depth = depth or 1 | ||
local row = mw.html.create( 'div' ) | |||
:addClass( 'template-component' ) | :addClass( 'template-component' ) | ||
:addClass( string.format( 'template-component--level-%d', depth ) ) | :addClass( string.format( 'template-component--level-%d', depth) ) | ||
:tag('div') | |||
:addClass('template-component__connectors') | |||
:tag('div'):addClass('template-component__connectorX'):done() | |||
:tag('div'):addClass('template-component__connectorY'):done() | |||
:done() | |||
if item.magazine_size ~= nil then | |||
item.count = item.magazine_size | |||
end | |||
local size = 'N/A' | local size = 'N/A' | ||
local prefix = '' | local prefix = 'S' | ||
-- | ---if item.from_gamedata == true or item.class == 'Weapons' then | ||
--- prefix = 'S' | |||
---end | |||
end | |||
if item.item_size ~= nil then | if item.item_size ~= nil then | ||
第1,022行: | 第455行: | ||
local nodeSizeCount = mw.html.create( 'div' ) | local nodeSizeCount = mw.html.create( 'div' ) | ||
:addClass('template-component__port') | |||
:tag( 'div' ) | |||
:addClass( 'template-component__count' ) | |||
:wikitext( string.format( '%dx', item.count ) ) | |||
:done() | :done() | ||
if item.class ~= | if item.class ~= 'Cargo grid' then | ||
nodeSizeCount | |||
:tag( 'div' ) | |||
:addClass( 'template-component__size' ) | |||
:wikitext( size ) | |||
:done() | |||
end | end | ||
nodeSizeCount = nodeSizeCount:allDone() | nodeSizeCount = nodeSizeCount:allDone() | ||
local | local title = item.sub_type or item.type | ||
if item.name ~= nil then | if item.name ~= nil then | ||
if | if data.nameFixes[ item.name ] ~= nil then | ||
title = string.format( '[[%s|%s]]', data.nameFixes[ item.name ], item.name ) | |||
else | else | ||
title = string.format( '[[%s]]', item.name ) | |||
end | end | ||
end | end | ||
local | local subtitle = item.manufacturer or 'N/A' | ||
if item.manufacturer ~= nil and item.manufacturer ~= 'N/A' then | |||
subtitle = string.format( '[[%s]]', item.manufacturer ) | |||
end | |||
-- Show SCU in subtitle | |||
if item.scu ~= nil then | |||
if item.type == 'Cargo grid' then | |||
subtitle = item.scu .. ' SCU' or 'N/A' | |||
elseif item.type == 'Personal storage' then | |||
subtitle = item.scu * 100 .. 'K µSCU' or 'N/A' | |||
end | |||
end | |||
local nodeItemManufacturer = mw.html.create( 'div' ) | |||
:addClass( 'template-component__item' ) | |||
:tag( 'div' ) | |||
:addClass( 'template-component__title' ) | |||
:wikitext( title ) | |||
:done() | |||
:tag( 'div' ) | |||
:addClass( 'template-component__subtitle' ) | :addClass( 'template-component__subtitle' ) | ||
:wikitext( subtitle ) | :wikitext( subtitle ) | ||
:done() | |||
:allDone() | |||
row:tag( 'div' ) | row:tag('div') | ||
:addClass('template-component__card') | |||
:node( nodeSizeCount ) | |||
:node( nodeItemManufacturer ) | |||
:done() | |||
row = tostring( row ) | row = tostring( row ) | ||
第1,071行: | 第516行: | ||
if type( item.children ) == 'table' then | if type( item.children ) == 'table' then | ||
depth = depth + 1 | depth = depth + 1 | ||
for _, child in | for _, child in self.spairs( item.children ) do | ||
row = row .. makeEntry( child, depth ) | row = row .. makeEntry( child, depth ) | ||
end | end | ||
第1,080行: | 第525行: | ||
-- Items of a given class e.g. avionics | |||
local function makeSection( types ) | local function makeSection( types ) | ||
local out = '' | local out = '' | ||
for classType, items in | for classType, items in self.spairs( types ) do | ||
local label = classType | |||
-- Label override | |||
if data.sectionLabelFixes[ classType ] ~= nil then | |||
label = data.sectionLabelFixes[ classType ] | |||
label = data. | |||
end | end | ||
local | local icon = string.format( '[[File:Hardpoints icon %s.svg|20px|link=]]', string.lower( label ) ) | ||
-- Disable label missing icons for now | |||
for _, labelMissingIcon in pairs( data.labelsMissingIcon ) do | |||
if label == labelMissingIcon then icon = '' end | |||
end | end | ||
local section = mw.html.create( 'div' ) | local section = mw.html.create( 'div' ) | ||
:addClass( 'template-components__section') | |||
:tag( 'div' ) | |||
:addClass( 'template-components__label' ) | |||
:wikitext( string.format( | |||
'%s %s', | |||
icon, | |||
label | |||
) ) | |||
:done() | |||
:tag( 'div' ):addClass( 'template-components__group' ) | |||
local str = '' | local str = '' | ||
for _, item in | for _, item in self.spairs( items ) do | ||
if not item.isChild then | if not item.isChild then | ||
local subGroup = mw.html.create('div') | |||
:addClass( 'template-components__subgroup' ) | |||
:node( makeEntry( item ) ) | |||
:allDone() | |||
str = str .. tostring( subGroup ) | |||
end | end | ||
end | end | ||
第1,128行: | 第573行: | ||
end | end | ||
for class, types in | |||
for class, types in self.spairs( groupedData ) do | |||
classOutput[ class ] = makeSection( types ) | classOutput[ class ] = makeSection( types ) | ||
end | end | ||
mw.logObject( classOutput | ---mw.logObject(classOutput) | ||
return classOutput | return classOutput | ||
end | end | ||
--- Generates tabber output | --- Generates tabber output | ||
第1,143行: | 第588行: | ||
if smwData == nil then | if smwData == nil then | ||
return hatnote( | return hatnote( 'SMW data not found on [[' .. self.page .. ']].', { icon = 'WikimediaUI-Error.svg' } ) | ||
end | end | ||
第1,151行: | 第596行: | ||
local output = self:makeOutput( smwData ) | local output = self:makeOutput( smwData ) | ||
local | --- Class corresponds to Module:VehicleHardpoint/Data | ||
local avSys = ( tostring( output[ 'Avionics' ] or '' ) ) .. ( tostring( output[ 'Systems' ] or '' ) ) | |||
local prThr = ( tostring( output[ 'Propulsion' ] or '' ) ) .. ( tostring( output[ 'Thrusters' ] or '' ) ) | |||
local weUti = ( tostring( output[ 'Weapons' ] or '' ) ) .. ( tostring( output[ 'Utility' ] or '' ) ) | |||
local caFac = ( tostring( output[ 'Cargo' ] or '' ) ) .. ( tostring( output[ 'Facilities' ] or '' ) ) | |||
if #avSys > 0 then | |||
avSys = avSys .. ( output.info or '' ) | |||
else | |||
avSys = hatnote( 'No avionics or systems available' ) | |||
end | |||
if #prThr > 0 then | |||
prThr = prThr .. ( output.info or '' ) | |||
else | |||
prThr = hatnote( 'No propulsion or thrusters available.' ) | |||
end | |||
if #weUti > 0 then | |||
weUti = weUti .. ( output.info or '' ) | |||
else | |||
weUti = hatnote( 'No weaponry or utility items present.' ) | |||
end | |||
if #caFac > 0 then | |||
caFac = caFac .. ( output.info or '' ) | |||
else | |||
caFac = hatnote( 'No cargo or facilities information found.' ) | |||
end | end | ||
local format = string.format([[ | |||
%s=%s | |||
|-| | |||
%s=%s | |||
|-| | |||
%s=%s | |||
|-| | |||
%s=%s | |||
]], | |||
'Avionics & Systems', | |||
avSys, | |||
'Propulsion & Thrusters', | |||
prThr, | |||
'Weaponry & Utility', | |||
weUti, | |||
'Cargo & Facilities', | |||
caFac | |||
) | |||
return | return mw.getCurrentFrame():extensionTag{ | ||
name = 'tabber', content = format | |||
} .. mw.getCurrentFrame():extensionTag{ | |||
name = 'templatestyles', args = { src = 'Template:Vehicle hardpoints/styles.css' } | |||
} | |||
end | end | ||
--- Manually fix some (sub_)types by checking the hardpoint name | --- Manually fix some (sub_)types by checking the hardpoint name | ||
--- | --- | ||
--- @param hardpoint table Entry from the api | --- @param hardpoint table Entry from the api | ||
--- @return table The fixed entry | --- @return table The fixed entry | ||
function | function VehicleHardPoint.fixTypes( hardpoint ) | ||
if hardpoint.type == 'ManneuverThruster' or hardpoint.type == 'MainThruster' then | |||
if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
string.match( string.lower( hardpoint.name ), 'vtol' ) ~= nil then | |||
hardpoint.sub_type = 'VtolThruster' | |||
end | |||
if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
string.match( string.lower( hardpoint.name ), 'retro' ) ~= nil then | |||
hardpoint.sub_type = 'RetroThruster' | |||
end | |||
if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
end | string.match( string.lower( hardpoint.name ), 'retro' ) ~= nil then | ||
hardpoint.sub_type = 'RetroThruster' | |||
end | |||
if ( hardpoint.sub_type == 'JointThruster' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
string.match( string.lower( hardpoint.name ), 'grav' ) ~= nil then | |||
hardpoint.sub_type = 'GravLev' | |||
end | |||
if hardpoint.type == 'MainThruster' then | |||
hardpoint.sub_type = 'Main' .. hardpoint.sub_type | |||
end | end | ||
end | end | ||
if hardpoint.type == 'WeaponDefensive' then | |||
if ( hardpoint.sub_type == 'CountermeasureLauncher' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
( string.match( string.lower( hardpoint.class_name ), 'decoy' ) ~= nil or | |||
string.match( string.lower( hardpoint.class_name ), 'flare' ) ~= nil) then | |||
hardpoint.sub_type = 'DecoyLauncher' | |||
end | |||
if ( hardpoint.sub_type == 'CountermeasureLauncher' or hardpoint.sub_type == 'UNDEFINED' ) and | |||
( string.match( string.lower( hardpoint.class_name ), 'chaff' ) ~= nil or | |||
string.match( string.lower( hardpoint.class_name ), 'noise' ) ~= nil) then | |||
hardpoint.sub_type = 'NoiseLauncher' | |||
end | |||
if type( hardpoint.item ) == 'table' and hardpoint.item ~= nil then | |||
hardpoint.item.name = '<= PLACEHOLDER =>' | |||
end | end | ||
end | end | ||
if hardpoint.type == 'FuelTank' or hardpoint.type == 'QuantumFuelTank' then | |||
if | local prefix = '' | ||
if hardpoint.type == 'QuantumFuelTank' then | |||
prefix = 'Quantum' | |||
end | |||
--- Fuel refinery (e.g. Starfarer) | |||
if string.match( string.lower( hardpoint.class_name ), 'fuel_refinery' ) ~= nil then | |||
hardpoint.type = 'FuelRefinery' | |||
end | |||
if string.match( string.lower( hardpoint.class_name ), 'small' ) ~= nil then | |||
hardpoint.sub_type = prefix .. 'FuelTankSmall' | |||
end | |||
if string.match( string.lower( hardpoint.class_name ), 'large' ) ~= nil then | |||
hardpoint.sub_type = prefix .. 'FuelTankLarge' | |||
end | end | ||
end | end | ||
-- | if hardpoint.type == 'Turret' then | ||
--- Gimbal mount | |||
if hardpoint.sub_type == 'GunTurret' and string.match( string.lower( hardpoint.class_name ), 'mount_gimbal' ) ~= nil then | |||
hardpoint.type = 'WeaponGun' | |||
hardpoint.sub_type = 'GimbalMount' | |||
-- Pilot controllable weapon (e.g. F7CM, Mustang Delta) | |||
elseif hardpoint.sub_type == 'BallTurret' or hardpoint.sub_type == 'CanardTurret' then | |||
hardpoint.type = 'WeaponGun' | |||
-- Reclaimer remote salvage turret | |||
elseif hardpoint.sub_type == 'Utility' and string.match( string.lower( hardpoint.class_name ), 'salvage' ) ~= nil then | |||
hardpoint.type = 'UtilityTurret' | |||
hardpoint.sub_type = 'GunTurret' | |||
-- Fix remote turret designation | |||
elseif hardpoint.sub_type == 'Turret' and string.match( string.lower( hardpoint.class_name ), 'remote' ) ~= nil then | |||
hardpoint.sub_type = 'RemoteTurret' | |||
end | end | ||
end | |||
if hardpoint.type == 'ToolArm' then | |||
if hardpoint.sub_type == 'UNDEFINED' then | |||
if string.match( string.lower( hardpoint.class_name ), 'mining' ) ~= nil then | |||
hardpoint.sub_type = 'MiningArm' | |||
elseif string.match( string.lower( hardpoint.class_name ), 'salvage' ) ~= nil then | |||
hardpoint.sub_type = 'SalvageArm' | |||
end | |||
end | |||
end | |||
for _, mapping in pairs( data. | -- Manual mapping defined in Module:VehicleHardpoint/Data | ||
if type( hardpoint.item ) == 'table' and hardpoint.item ~= nil then | |||
for _, mapping in pairs( data.hardPointTypeFixes ) do | |||
for _, matcher in pairs( data.hardPointMappings[mapping]['matches'] ) do | |||
if string.match( hardpoint.name, matcher ) ~= nil then | |||
hardpoint.type = mapping | |||
return hardpoint | |||
end | |||
end | |||
end | |||
end | end | ||
return hardpoint | return hardpoint | ||
end | end | ||
--- New Instance | --- New Instance | ||
--- | --- | ||
--- @return table | --- @return table VehicleHardPoint | ||
function | function VehicleHardPoint.new( self, page ) | ||
local instance = { | local instance = { | ||
page = page or nil, | page = page or nil, | ||
spairs = require( 'Module:Common' ).spairs | |||
} | } | ||
第1,303行: | 第777行: | ||
return instance | return instance | ||
end | end | ||
--- Parser call for generating the table | --- Parser call for generating the table | ||
function | function VehicleHardPoint.outputTable( frame ) | ||
local args = require( 'Module:Arguments' ).getArgs( frame ) | |||
local page = args[ 1 ] or args[ 'Name' ] or mw.title.getCurrentTitle().rootText | local page = args[ 1 ] or args[ 'Name' ] or mw.title.getCurrentTitle().rootText | ||
local instance = | local instance = VehicleHardPoint:new( page ) | ||
if args['debug'] ~= nil then | |||
local smwData = instance:querySmwStore(page) | |||
local struct = instance:createDataStructure( smwData ) | |||
local group = instance:group( struct ) | |||
return mw.dumpObject(smwData) .. mw.dumpObject(struct) .. mw.dumpObject(group) | |||
return out | end | ||
return instance:out() | |||
end | end | ||
return VehicleHardPoint | |||
2023年11月19日 (日) 11:04的最新版本
This documentation is transcluded from 模块:VehicleHardpoint/doc. Changes can be proposed in the talk page.
This module saves and displays the hardpoints found on a vehicle. Implements {{Vehicle hardpoints}}.
local VehicleHardPoint = {} local metatable = {} local methodtable = {} local common = require( 'Module:Common' ) local data = mw.loadData( 'Module:VehicleHardpoint/Data' ) local hatnote = require( 'Module:Hatnote' )._hatnote metatable.__index = methodtable -- Local functions --- Checks if an entry contains a 'child' key with further entries --- --- @return boolean local function hasChildren( row ) return row.children ~= nil and type( row.children ) == 'table' and #row.children > 0 end --- Creates a key to be used in 'setHardPointObjects' --- This allows to sum the total count of each similar object --- --- @param row table - API Data --- @param hardpointData table - Data from getHardpointData --- @param parent table|nil - Parent hardpoint --- @param root string|nil - Root hardpoint --- @return string Key local function makeKey( row, hardpointData, parent, root ) local key if type( row.item ) == 'table' then if row.type == 'ManneuverThruster' or row.type == 'MainThruster' or row.type == 'WeaponDefensive' or row.type == 'WeaponLocker' or row.type == 'ArmorLocker' or row.type == 'Bed' or row.type == 'CargoGrid' then key = row.type .. row.sub_type else key = row.type .. row.sub_type .. row.item.uuid end else key = hardpointData.class .. hardpointData.type end if row.type ~= 'WeaponDefensive' then if parent ~= nil then key = key .. parent[ 'Hardpoint' ] end if root ~= nil and not string.match( key, root ) and ( hardpointData.class == 'Weapons' ) then key = key .. root end end if hardpointData.class == 'Weapons' and row.name ~= nil and row.type == 'MissileLauncher' then key = key .. row.name end --mw.log(string.format('Key: %s', key)) return key end --- Tries to fix hardpoints that have no item, but everything set on the 'child' key --- --- @param row table - API Data --- @return table - Fixed entry local function fixChild( row ) if row.item == nil and hasChildren( row ) and #row.children == 1 then local item = row.children[ 1 ] local children = {} if hasChildren( item ) then children = item.children if item.item ~= nil and item.item.children ~= nil then item.item.children = {} end end row.name = item.name row.type = item.type row.sub_type = item.sub_type row.item = item.item if #children > 1 then row.children = children else row.children = { data = {} } end end return row end --- Get pre-defined hardpoint data for a given hardpoint type or name --- --- @param hardpointType string --- @return table|nil function methodtable.getHardpointData( self, hardpointType ) if type( data.hardPointMappings[ hardpointType ] ) == 'table' then return data.hardPointMappings[ hardpointType ] end for hType, mappingData in pairs( data.hardPointMappings ) do if hardpointType == hType then return mappingData elseif type( mappingData.matches ) == 'table' then for _, matcher in pairs( mappingData.matches ) do if string.match( hardpointType, matcher ) ~= nil then return mappingData end end end end return nil end --- Creates a settable SMW Subobject --- --- @param row table - API Data --- @param hardpointData table - Data from getHardpointData --- @param parent table|nil - Parent hardpoint --- @param root string|nil - Root hardpoint --- @return table function methodtable.makeObject( self, row, hardpointData, parent, root ) local object = {} if hardpointData == nil then hardpointData = self:getHardpointData( row.type or row.name ) end if hardpointData == nil then return nil end object[ 'Hardpoint' ] = row.name --object[ 'From game data' ] = true object[ 'Hardpoint minimum size' ] = row.min_size object[ 'Hardpoint maximum size' ] = row.max_size object[ 'Vehicle hardpoints template group' ] = hardpointData.class if data.hardPointNames[ row.type ] ~= nil then object[ 'Hardpoint type' ] = data.hardPointNames[ row.type ] else object[ 'Hardpoint type' ] = hardpointData.type end if data.hardPointNames[ row.sub_type ] ~= nil then object[ 'Hardpoint subtype' ] = data.hardPointNames[ row.sub_type ] else object[ 'Hardpoint subtype' ] = hardpointData.type end if hardpointData.item ~= nil then if type( hardpointData.item.name ) == 'string' then object[ 'Name' ] = hardpointData.item.name end end if type( row.item ) == 'table' then local itemObj = row.item if itemObj.name ~= '<= PLACEHOLDER =>' then local match = string.match( row.class_name or '', 'Destruct_(%d+s)') if row.type == 'SelfDestruct' and match ~= nil then object[ 'Name' ] = 'Self destruct (' .. match .. ')' else object[ 'Name' ] = row.item.name end end if itemObj.type == 'WeaponDefensive' and type( itemObj.counter_measure ) == 'table' then object[ 'Magazine capacity' ] = itemObj.counter_measure.capacity end if ( itemObj.type == 'Cargo' or itemObj.type == 'SeatAccess' or itemObj.type == 'CargoGrid' or itemObj.type == 'Container' ) and type( itemObj.inventory ) == 'table' then object[ 'Inventory' ] = common.formatNum( (itemObj.inventory.scu or nil), nil ) end if object[ 'Hardpoint minimum size' ] == nil then object[ 'Hardpoint minimum size' ] = itemObj.size object[ 'Hardpoint maximum size' ] = itemObj.size end object[ 'UUID' ] = row.item.uuid end if parent ~= nil then object[ 'Parent hardpoint UUID' ] = parent[ 'UUID' ] object[ 'Parent hardpoint' ] = parent[ 'Hardpoint' ] end if root ~= nil and root ~= row.name then object[ 'Root hardpoint' ] = root end -- Remove SeatAccess Hardpoints without storage if row.item ~= nil and row.item.type == 'SeatAccess' and object[ 'Inventory' ] == nil then object = nil end return object; end --- Sets all available hardpoints as sub-objects --- This is the main method called by others --- --- @param hardpoints table API Hardpoint data function methodtable.setHardPointObjects( self, hardpoints ) if type( hardpoints ) ~= 'table' then error( 'Hardpoints need to be a table' ) end local out = {} local function addToOut( object, key ) if object == nil then return end if type( out[ key ] ) ~= 'table' then if object ~= nil then out[ key ] = object out[ key ][ 'Item quantity' ] = 1 end else out[ key ][ 'Item quantity' ] = out[ key ][ 'Item quantity' ] + 1 if type( out[ key ][ 'Magazine capacity' ] ) == 'number' then out[ key ][ 'Magazine capacity' ] = out[ key ][ 'Magazine capacity' ] + object[ 'Magazine capacity' ] end if object[ 'Hardpoint type' ] == 'Cargo grid' then out[ key ][ 'Item quantity' ] = 1 if out[ key ][ 'Inventory' ] ~= nil and object[ 'Inventory' ] ~= nil then out[ key ][ 'Inventory' ] = tonumber(out[ key ][ 'Inventory' ]) + tonumber(object[ 'Inventory' ]) end end end end local depth = 1 local function addHardpoints( hardpoints, parent, root ) for _, hardpoint in pairs( hardpoints ) do hardpoint.name = string.lower( hardpoint.name ) hardpoint = fixChild( hardpoint ) if depth == 1 then root = hardpoint.name --mw.log(string.format('Root: %s', root)) end hardpoint = VehicleHardPoint.fixTypes( hardpoint ) local hardpointData = self:getHardpointData( hardpoint.type or hardpoint.name ) if hardpointData ~= nil then local key = makeKey( hardpoint, hardpointData, parent, root ) local obj = self:makeObject( hardpoint, hardpointData, parent, root ) addToOut( obj, key ) if hasChildren( hardpoint ) then depth = depth + 1 addHardpoints( hardpoint.children, obj, root ) end end end depth = depth - 1 if depth < 1 then depth = 1 root = nil end end addHardpoints( hardpoints ) --mw.logObject(out) for _, subobject in pairs( out ) do mw.smw.subobject( subobject ) end end --- Queries the SMW store for all available hardpoint subobjects for a given page --- --- @param page string - The page to query --- @return table hardpoints function methodtable.querySmwStore( self, page ) -- Cache multiple calls if self.smwData ~= nil then return self.smwData end local smwData = mw.smw.ask( { '[[-Has subobject::' .. page .. ']][[Hardpoint type::+]][[Vehicle hardpoints template group::+]]', '?Item quantity#-=count', '?Hardpoint minimum size#-=min_size', '?Hardpoint maximum size#-=max_size', '?Vehicle hardpoints template group=class', '?Hardpoint type=type', '?Hardpoint subtype=sub_type', '?Name#-=name', '?Inventory#-n=scu', '?UUID#-=uuid', '?Hardpoint#-=hardpoint', '?Magazine capacity#-=magazine_size', '?Parent hardpoint#-=parent_hardpoint', '?Root hardpoint#-=root_hardpoint', '?Parent UUID#-=parent_uuid', '?Name.Grade#-=item_grade', '?Name.Class#-=item_class', '?Name.Size#-=item_size', '?Name.Manufacturer#-=manufacturer', 'sort=Vehicle hardpoints template group,Hardpoint type,Hardpoint maximum size,Item quantity', 'order=asc,asc,asc,asc', 'limit=1000' } ) if smwData == nil or smwData[ 1 ] == nil then return nil end mw.logObject( smwData ) self.smwData = smwData return self.smwData end --- Group Hardpoints by Class and type --- --- @param smwData table SMW data - Requires a 'class' key on each row --- @return table function methodtable.group( self, smwData ) local grouped = {} if type( smwData ) ~= 'table' then return {} end for _, row in self.spairs( smwData ) do if not row.isChild and row.class ~= nil and row.type ~= nil then if type( grouped[ row.class ] ) ~= 'table' then grouped[ row.class ] = {} end if type( grouped[ row.class ][ row.type ] ) ~= 'table' then grouped[ row.class ][ row.type ] = {} end table.insert( grouped[ row.class ][ row.type ], row ) end end --mw.logObject( grouped ) return grouped end --- Adds children to the according parents --- --- @param smwData table All available Hardpoint objects for this page --- @return table The stratified table function methodtable.createDataStructure( self, smwData ) -- Maps object id to key in array local idMapping = {} for key, object in pairs( smwData ) do if object.hardpoint ~= nil then local keyMap = ( object.root_hardpoint or object.hardpoint ) .. object.hardpoint idMapping[ keyMap ] = key end end local function stratify( toStratify ) for _, object in pairs( toStratify ) do if object.parent_hardpoint ~= nil then local parentEl = toStratify[ idMapping[ (object.root_hardpoint or '') .. object.parent_hardpoint ] ] if parentEl ~= nil then if parentEl.children == nil then parentEl.children = {} end object.isChild = true table.insert( parentEl.children, object ) end end end end stratify( smwData ) return smwData end --- Generate the output --- --- @param groupedData table Grouped SMW data --- @return table function methodtable.makeOutput( self, groupedData ) local classOutput = {} -- An item with potential children local function makeEntry( item, depth ) -- Info if data stems from ship-matrix or game files if classOutput.info == nil then local text ---if item.from_gamedata == true then text = 'Data extracted from game data.' ---else --- text = 'Data extracted from ship matrix.' ---end classOutput.info = hatnote( text, { icon = 'WikimediaUI-Robot.svg' } ) end depth = depth or 1 local row = mw.html.create( 'div' ) :addClass( 'template-component' ) :addClass( string.format( 'template-component--level-%d', depth) ) :tag('div') :addClass('template-component__connectors') :tag('div'):addClass('template-component__connectorX'):done() :tag('div'):addClass('template-component__connectorY'):done() :done() if item.magazine_size ~= nil then item.count = item.magazine_size end local size = 'N/A' local prefix = 'S' ---if item.from_gamedata == true or item.class == 'Weapons' then --- prefix = 'S' ---end if item.item_size ~= nil then size = string.format( '%s%s', prefix, item.item_size ) else size = string.format( '%s%s', prefix, item.max_size ) end local nodeSizeCount = mw.html.create( 'div' ) :addClass('template-component__port') :tag( 'div' ) :addClass( 'template-component__count' ) :wikitext( string.format( '%dx', item.count ) ) :done() if item.class ~= 'Cargo grid' then nodeSizeCount :tag( 'div' ) :addClass( 'template-component__size' ) :wikitext( size ) :done() end nodeSizeCount = nodeSizeCount:allDone() local title = item.sub_type or item.type if item.name ~= nil then if data.nameFixes[ item.name ] ~= nil then title = string.format( '[[%s|%s]]', data.nameFixes[ item.name ], item.name ) else title = string.format( '[[%s]]', item.name ) end end local subtitle = item.manufacturer or 'N/A' if item.manufacturer ~= nil and item.manufacturer ~= 'N/A' then subtitle = string.format( '[[%s]]', item.manufacturer ) end -- Show SCU in subtitle if item.scu ~= nil then if item.type == 'Cargo grid' then subtitle = item.scu .. ' SCU' or 'N/A' elseif item.type == 'Personal storage' then subtitle = item.scu * 100 .. 'K µSCU' or 'N/A' end end local nodeItemManufacturer = mw.html.create( 'div' ) :addClass( 'template-component__item' ) :tag( 'div' ) :addClass( 'template-component__title' ) :wikitext( title ) :done() :tag( 'div' ) :addClass( 'template-component__subtitle' ) :wikitext( subtitle ) :done() :allDone() row:tag('div') :addClass('template-component__card') :node( nodeSizeCount ) :node( nodeItemManufacturer ) :done() row = tostring( row ) if type( item.children ) == 'table' then depth = depth + 1 for _, child in self.spairs( item.children ) do row = row .. makeEntry( child, depth ) end end return row end -- Items of a given class e.g. avionics local function makeSection( types ) local out = '' for classType, items in self.spairs( types ) do local label = classType -- Label override if data.sectionLabelFixes[ classType ] ~= nil then label = data.sectionLabelFixes[ classType ] end local icon = string.format( '[[File:Hardpoints icon %s.svg|20px|link=]]', string.lower( label ) ) -- Disable label missing icons for now for _, labelMissingIcon in pairs( data.labelsMissingIcon ) do if label == labelMissingIcon then icon = '' end end local section = mw.html.create( 'div' ) :addClass( 'template-components__section') :tag( 'div' ) :addClass( 'template-components__label' ) :wikitext( string.format( '%s %s', icon, label ) ) :done() :tag( 'div' ):addClass( 'template-components__group' ) local str = '' for _, item in self.spairs( items ) do if not item.isChild then local subGroup = mw.html.create('div') :addClass( 'template-components__subgroup' ) :node( makeEntry( item ) ) :allDone() str = str .. tostring( subGroup ) end end out = out .. tostring( section:node( str ):allDone() ) end return out end for class, types in self.spairs( groupedData ) do classOutput[ class ] = makeSection( types ) end ---mw.logObject(classOutput) return classOutput end --- Generates tabber output function methodtable.out( self ) local smwData = self:querySmwStore( self.page ) if smwData == nil then return hatnote( 'SMW data not found on [[' .. self.page .. ']].', { icon = 'WikimediaUI-Error.svg' } ) end smwData = self:createDataStructure( smwData ) smwData = self:group( smwData ) local output = self:makeOutput( smwData ) --- Class corresponds to Module:VehicleHardpoint/Data local avSys = ( tostring( output[ 'Avionics' ] or '' ) ) .. ( tostring( output[ 'Systems' ] or '' ) ) local prThr = ( tostring( output[ 'Propulsion' ] or '' ) ) .. ( tostring( output[ 'Thrusters' ] or '' ) ) local weUti = ( tostring( output[ 'Weapons' ] or '' ) ) .. ( tostring( output[ 'Utility' ] or '' ) ) local caFac = ( tostring( output[ 'Cargo' ] or '' ) ) .. ( tostring( output[ 'Facilities' ] or '' ) ) if #avSys > 0 then avSys = avSys .. ( output.info or '' ) else avSys = hatnote( 'No avionics or systems available' ) end if #prThr > 0 then prThr = prThr .. ( output.info or '' ) else prThr = hatnote( 'No propulsion or thrusters available.' ) end if #weUti > 0 then weUti = weUti .. ( output.info or '' ) else weUti = hatnote( 'No weaponry or utility items present.' ) end if #caFac > 0 then caFac = caFac .. ( output.info or '' ) else caFac = hatnote( 'No cargo or facilities information found.' ) end local format = string.format([[ %s=%s |-| %s=%s |-| %s=%s |-| %s=%s ]], 'Avionics & Systems', avSys, 'Propulsion & Thrusters', prThr, 'Weaponry & Utility', weUti, 'Cargo & Facilities', caFac ) return mw.getCurrentFrame():extensionTag{ name = 'tabber', content = format } .. mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Template:Vehicle hardpoints/styles.css' } } end --- Manually fix some (sub_)types by checking the hardpoint name --- --- @param hardpoint table Entry from the api --- @return table The fixed entry function VehicleHardPoint.fixTypes( hardpoint ) if hardpoint.type == 'ManneuverThruster' or hardpoint.type == 'MainThruster' then if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and string.match( string.lower( hardpoint.name ), 'vtol' ) ~= nil then hardpoint.sub_type = 'VtolThruster' end if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and string.match( string.lower( hardpoint.name ), 'retro' ) ~= nil then hardpoint.sub_type = 'RetroThruster' end if ( hardpoint.sub_type == 'FixedThruster' or hardpoint.sub_type == 'UNDEFINED' ) and string.match( string.lower( hardpoint.name ), 'retro' ) ~= nil then hardpoint.sub_type = 'RetroThruster' end if ( hardpoint.sub_type == 'JointThruster' or hardpoint.sub_type == 'UNDEFINED' ) and string.match( string.lower( hardpoint.name ), 'grav' ) ~= nil then hardpoint.sub_type = 'GravLev' end if hardpoint.type == 'MainThruster' then hardpoint.sub_type = 'Main' .. hardpoint.sub_type end end if hardpoint.type == 'WeaponDefensive' then if ( hardpoint.sub_type == 'CountermeasureLauncher' or hardpoint.sub_type == 'UNDEFINED' ) and ( string.match( string.lower( hardpoint.class_name ), 'decoy' ) ~= nil or string.match( string.lower( hardpoint.class_name ), 'flare' ) ~= nil) then hardpoint.sub_type = 'DecoyLauncher' end if ( hardpoint.sub_type == 'CountermeasureLauncher' or hardpoint.sub_type == 'UNDEFINED' ) and ( string.match( string.lower( hardpoint.class_name ), 'chaff' ) ~= nil or string.match( string.lower( hardpoint.class_name ), 'noise' ) ~= nil) then hardpoint.sub_type = 'NoiseLauncher' end if type( hardpoint.item ) == 'table' and hardpoint.item ~= nil then hardpoint.item.name = '<= PLACEHOLDER =>' end end if hardpoint.type == 'FuelTank' or hardpoint.type == 'QuantumFuelTank' then local prefix = '' if hardpoint.type == 'QuantumFuelTank' then prefix = 'Quantum' end --- Fuel refinery (e.g. Starfarer) if string.match( string.lower( hardpoint.class_name ), 'fuel_refinery' ) ~= nil then hardpoint.type = 'FuelRefinery' end if string.match( string.lower( hardpoint.class_name ), 'small' ) ~= nil then hardpoint.sub_type = prefix .. 'FuelTankSmall' end if string.match( string.lower( hardpoint.class_name ), 'large' ) ~= nil then hardpoint.sub_type = prefix .. 'FuelTankLarge' end end if hardpoint.type == 'Turret' then --- Gimbal mount if hardpoint.sub_type == 'GunTurret' and string.match( string.lower( hardpoint.class_name ), 'mount_gimbal' ) ~= nil then hardpoint.type = 'WeaponGun' hardpoint.sub_type = 'GimbalMount' -- Pilot controllable weapon (e.g. F7CM, Mustang Delta) elseif hardpoint.sub_type == 'BallTurret' or hardpoint.sub_type == 'CanardTurret' then hardpoint.type = 'WeaponGun' -- Reclaimer remote salvage turret elseif hardpoint.sub_type == 'Utility' and string.match( string.lower( hardpoint.class_name ), 'salvage' ) ~= nil then hardpoint.type = 'UtilityTurret' hardpoint.sub_type = 'GunTurret' -- Fix remote turret designation elseif hardpoint.sub_type == 'Turret' and string.match( string.lower( hardpoint.class_name ), 'remote' ) ~= nil then hardpoint.sub_type = 'RemoteTurret' end end if hardpoint.type == 'ToolArm' then if hardpoint.sub_type == 'UNDEFINED' then if string.match( string.lower( hardpoint.class_name ), 'mining' ) ~= nil then hardpoint.sub_type = 'MiningArm' elseif string.match( string.lower( hardpoint.class_name ), 'salvage' ) ~= nil then hardpoint.sub_type = 'SalvageArm' end end end -- Manual mapping defined in Module:VehicleHardpoint/Data if type( hardpoint.item ) == 'table' and hardpoint.item ~= nil then for _, mapping in pairs( data.hardPointTypeFixes ) do for _, matcher in pairs( data.hardPointMappings[mapping]['matches'] ) do if string.match( hardpoint.name, matcher ) ~= nil then hardpoint.type = mapping return hardpoint end end end end return hardpoint end --- New Instance --- --- @return table VehicleHardPoint function VehicleHardPoint.new( self, page ) local instance = { page = page or nil, spairs = require( 'Module:Common' ).spairs } setmetatable( instance, metatable ) return instance end --- Parser call for generating the table function VehicleHardPoint.outputTable( frame ) local args = require( 'Module:Arguments' ).getArgs( frame ) local page = args[ 1 ] or args[ 'Name' ] or mw.title.getCurrentTitle().rootText local instance = VehicleHardPoint:new( page ) if args['debug'] ~= nil then local smwData = instance:querySmwStore(page) local struct = instance:createDataStructure( smwData ) local group = instance:group( struct ) return mw.dumpObject(smwData) .. mw.dumpObject(struct) .. mw.dumpObject(group) end return instance:out() end return VehicleHardPoint