Module:ShipArmorLister
From Terra Invicta Official Wiki
Documentation for this module may be created at Module:ShipArmorLister/doc
---
---Reads the Armor data files and presents them in readable formats, with additional calculated statistics.
---
---@module ArmorLister
local ArmorLister = {}
--region Dependencies
local IconModule = require('Module:Icon')
local ArmorData = mw.loadData('Module:CSVReader/ShipArmor')
local ArmorNames = mw.loadData('Module:ENReader/ShipArmor')
local ProjectNameBuilder = require('Module:ProjectLister/NameBuilder')
local HabModuleData = mw.loadData('Module:CSVReader/HabModule')
--endregion
--region Private constants
local floor = math.floor
local round = function(num, decimals)
local mult = 10^(decimals or 0)
return floor(num * mult + 0.5) / mult
end
local PI = 3.1415927
-- Predefined hab module masses (fallback values if not in CSV)
local HAB_MODULE_MASSES = {
PointDefenseArray = 50,
LayeredDefenseArray = 100,
Battlestations = 150,
AlienPointDefenseArray = 60,
AlienLayeredDefenseArray = 120,
AlienBattlestations = 180
}
--endregion
--region Private methods
-- Safe value access with fallback
local function getValue(row, key, default)
local value = row[key]
if value == nil or value == '' then
return default or 'None'
end
return value
end
local function calculateMassForGunshipArmor(vapor)
return round(4 / tonumber(vapor) * 5 * 5 * PI, 3)
end
local function calculateThicknessPerPoint(density, vapor)
return round(400000 / tonumber(vapor) / tonumber(density), 3)
end
local function calculateResourceCost(vapor, resourceWeight)
local mass = calculateMassForGunshipArmor(vapor)
return round(tonumber(resourceWeight) * mass / 10, 4)
end
local function calculateArmorForRadiation(halfValue, thicknessPerPoint)
return round(tonumber(halfValue) / thicknessPerPoint, 3)
end
local function getSpecialtyDisplay(specialty, specialtyVal)
if not specialty or specialty == 'None' then
return ''
end
local specialtyNames = {
ChippingResistance = specialtyVal .. "× Chip Damage Taken",
KineticsResistance = specialtyVal .. "× Kinetic Damage Taken",
LaserResistance = specialtyVal .. "× Laser Damage Taken"
}
return specialtyNames[specialty] or specialty
end
-- Get hab module mass by name
local function getHabModuleMass(moduleName)
-- First try to get from CSV data
for rowID, row in pairs(HabModuleData) do
if rowID == moduleName then
return tonumber(row['baseMass_tons']) or HAB_MODULE_MASSES[moduleName] or 0
end
end
-- Fallback to predefined values
return HAB_MODULE_MASSES[moduleName] or 0
end
-- Calculate ground hab armor values
local function calculateGroundHabArmor(vapor, multiplier)
return round(tonumber(vapor) / multiplier, 2) .. " × Module Tier"
end
-- Calculate space hab HP values
local function calculateSpaceHabHP(moduleMass, moduleTier, vapor)
return round(0.3 * moduleMass / moduleTier / 20 * tonumber(vapor), 2)
end
-- Check if armor should be included in hab effects (non-exotic, non-alien)
local function shouldIncludeInHabEffects(row)
local exotics = tonumber(getValue(row, 'weightedBuildMaterials/exotics', 0))
local project = getValue(row, 'requiredProjectName')
return exotics == 0 and project ~= 'Project_AlienMasterProject'
end
--endregion
--region Public methods
function ArmorLister.ListBasicArmor()
local returnString = '{| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;"'
returnString = returnString .. '\n! rowspan=2|Armor'
returnString = returnString .. '\n! rowspan=2|Mass (tons)<br>for 0/0/1 Armor on a Gunship'
returnString = returnString .. '\n! rowspan=2|Bonus Resistance'
returnString = returnString .. '\n! colspan=4| Resource Cost for 0/0/1 Armor on a Gunship'
returnString = returnString .. '\n! colspan=2|Armor Needed to Halve Radiation Damage'
returnString = returnString .. '\n|-'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'volatiles'}}) .. ' Volatiles'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'metals'}}) .. ' Base Metals'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'nobles'}}) .. ' Noble Metals'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'exotics'}}) .. ' Exotics'
returnString = returnString .. '\n! X-Ray'
returnString = returnString .. '\n! Baryonic'
returnString = returnString .. '\n|-'
for rowID, row in pairs(ArmorData) do
returnString = returnString .. '\n| ' .. (ArmorNames['TIShipArmorTemplate.displayName.' .. rowID] or rowID)
local vapor = getValue(row, 'heatofVaporization_MJkg', 1)
local mass = calculateMassForGunshipArmor(vapor)
returnString = returnString .. '\n| ' .. mass
local specialty = getValue(row, 'specialties/2/armorSpecialty')
local specialtyVal = getValue(row, 'specialties/2/value')
local specialtyDisplay = getSpecialtyDisplay(specialty, specialtyVal)
returnString = returnString .. '\n| ' .. specialtyDisplay
-- Resource costs
local volatilesCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/volatiles'))
local metalsCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/metals'))
local noblesCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/nobleMetals'))
local exoticsCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/exotics'))
returnString = returnString .. '\n| ' .. volatilesCost
returnString = returnString .. '\n| ' .. metalsCost
returnString = returnString .. '\n| ' .. noblesCost
returnString = returnString .. '\n| ' .. exoticsCost
-- Radiation calculations
local density = getValue(row, 'density_kgm3', 1)
local thicknessPerPoint = calculateThicknessPerPoint(density, vapor)
local xrayArmor = calculateArmorForRadiation(getValue(row, 'xRayHalfValue_cm'), thicknessPerPoint)
local baryonArmor = calculateArmorForRadiation(getValue(row, 'baryonicHalfValue_cm'), thicknessPerPoint)
returnString = returnString .. '\n| ' .. xrayArmor
returnString = returnString .. '\n| ' .. baryonArmor
returnString = returnString .. '\n|-'
end
returnString = returnString .. '\n|}'
return returnString
end
function ArmorLister.ListDetailedArmor()
local returnString = '{| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;"'
returnString = returnString .. '\n! rowspan=2|Armor'
returnString = returnString .. '\n! rowspan=2|Required Project'
returnString = returnString .. '\n! rowspan=2|Density<br>(kg/m³)'
returnString = returnString .. '\n! rowspan=2|Heat of Vaporization<br>(MJ/kg)'
returnString = returnString .. '\n! rowspan=2|Thickness per point<br>(cm)'
returnString = returnString .. '\n! rowspan=2|Mass (tons)<br>for 0/0/1 Armor on a Gunship'
returnString = returnString .. '\n! rowspan=2|Bonus Resistance'
returnString = returnString .. '\n! colspan=4| Resource Cost for 0/0/1 Armor on a Gunship'
returnString = returnString .. '\n! colspan=2|Half Value (cm)'
returnString = returnString .. '\n! colspan=2|Armor Needed to Halve Radiation Damage'
returnString = returnString .. '\n|-'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'volatiles'}}) .. ' Volatiles'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'metals'}}) .. ' Base Metals'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'nobles'}}) .. ' Noble Metals'
returnString = returnString .. '\n!' .. IconModule.Icon({args={'exotics'}}) .. ' Exotics'
returnString = returnString .. '\n! X-Ray'
returnString = returnString .. '\n! Baryonic'
returnString = returnString .. '\n! X-Ray'
returnString = returnString .. '\n! Baryonic'
returnString = returnString .. '\n|-'
for rowID, row in pairs(ArmorData) do
returnString = returnString .. '\n| ' .. (ArmorNames['TIShipArmorTemplate.displayName.' .. rowID] or rowID)
returnString = returnString .. '\n| ' .. ProjectNameBuilder.buildName({args={row['requiredProjectName']}})
local density = getValue(row, 'density_kgm3', 1)
local vapor = getValue(row, 'heatofVaporization_MJkg', 1)
local thicknessPerPoint = calculateThicknessPerPoint(density, vapor)
local mass = calculateMassForGunshipArmor(vapor)
returnString = returnString .. '\n| ' .. density
returnString = returnString .. '\n| ' .. vapor
returnString = returnString .. '\n| ' .. thicknessPerPoint
returnString = returnString .. '\n| ' .. mass
local specialty = getValue(row, 'specialties/2/armorSpecialty')
local specialtyVal = getValue(row, 'specialties/2/value')
local specialtyDisplay = getSpecialtyDisplay(specialty, specialtyVal)
returnString = returnString .. '\n| ' .. specialtyDisplay
-- Resource costs
local volatilesCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/volatiles'))
local metalsCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/metals'))
local noblesCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/nobleMetals'))
local exoticsCost = calculateResourceCost(vapor, getValue(row, 'weightedBuildMaterials/exotics'))
returnString = returnString .. '\n| ' .. volatilesCost
returnString = returnString .. '\n| ' .. metalsCost
returnString = returnString .. '\n| ' .. noblesCost
returnString = returnString .. '\n| ' .. exoticsCost
-- Half values
local xrayHV = getValue(row, 'xRayHalfValue_cm', 0)
local baryonHV = getValue(row, 'baryonicHalfValue_cm', 0)
returnString = returnString .. '\n| ' .. xrayHV
returnString = returnString .. '\n| ' .. baryonHV
-- Radiation armor calculations
local xrayArmor = calculateArmorForRadiation(xrayHV, thicknessPerPoint)
local baryonArmor = calculateArmorForRadiation(baryonHV, thicknessPerPoint)
returnString = returnString .. '\n| ' .. xrayArmor
returnString = returnString .. '\n| ' .. baryonArmor
returnString = returnString .. '\n|-'
end
returnString = returnString .. '\n|}'
return returnString
end
function ArmorLister.ListHabEffects()
local returnString returnString = '{| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;"'
returnString = returnString .. '\n! rowspan=2|Armor'
returnString = returnString .. '\n! colspan=3| Armor Value for Ground Hab Modules'
returnString = returnString .. '\n! colspan=3|HP Value for Space Hab Modules'
returnString = returnString .. '\n|-'
returnString = returnString .. '\n! Combat Modules'
returnString = returnString .. '\n! Critical Modules'
returnString = returnString .. '\n! Other Modules'
returnString = returnString .. '\n! Point Defense Array'
returnString = returnString .. '\n! Layered Defense Array'
returnString = returnString .. '\n! Battlestation'
returnString = returnString .. '\n|-'
-- Human armors (non-exotic, non-alien)
for rowID, row in pairs(ArmorData) do
if shouldIncludeInHabEffects(row) then
local vapor = getValue(row, 'heatofVaporization_MJkg', 1)
local armorName = ArmorNames['TIShipArmorTemplate.displayName.' .. rowID] or rowID
returnString = returnString .. '\n| ' .. armorName
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(vapor, 2.5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(vapor, 5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(vapor, 10)
-- Space hab HP values
local pdMass = getHabModuleMass('PointDefenseArray')
local ldMass = getHabModuleMass('LayeredDefenseArray')
local bsMass = getHabModuleMass('Battlestations')
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(pdMass, 1, vapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(ldMass, 2, vapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(bsMass, 3, vapor)
returnString = returnString .. '\n|-'
end
end
-- Alien Adamantane Armor
local alienAdamantane = ArmorData['AlienAdamantaneArmor']
if alienAdamantane then
local aVapor = getValue(alienAdamantane, 'heatofVaporization_MJkg', 1)
local armorName = ArmorNames['TIShipArmorTemplate.displayName.AlienAdamantaneArmor'] or 'AlienAdamantaneArmor'
returnString = returnString .. '\n| ' .. armorName
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(aVapor, 2.5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(aVapor, 5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(aVapor, 10)
-- Alien space hab HP values
local aPdMass = getHabModuleMass('AlienPointDefenseArray')
local aLdMass = getHabModuleMass('AlienLayeredDefenseArray')
local aBsMass = getHabModuleMass('AlienBattlestations')
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aPdMass, 1, aVapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aLdMass, 2, aVapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aBsMass, 3, aVapor)
returnString = returnString .. '\n|-'
end
-- Alien Exotic Armor
local alienExotic = ArmorData['AlienExoticArmor']
if alienExotic then
local eVapor = getValue(alienExotic, 'heatofVaporization_MJkg', 1)
local armorName = ArmorNames['TIShipArmorTemplate.displayName.AlienExoticArmor'] or 'AlienExoticArmor'
returnString = returnString .. '\n| ' .. armorName
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(eVapor, 2.5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(eVapor, 5)
returnString = returnString .. '\n| ' .. calculateGroundHabArmor(eVapor, 10)
-- Alien space hab HP values (using same modules as Adamantane)
local aPdMass = getHabModuleMass('AlienPointDefenseArray')
local aLdMass = getHabModuleMass('AlienLayeredDefenseArray')
local aBsMass = getHabModuleMass('AlienBattlestations')
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aPdMass, 1, eVapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aLdMass, 2, eVapor)
returnString = returnString .. '\n| ' .. calculateSpaceHabHP(aBsMass, 3, eVapor)
returnString = returnString .. '\n|-'
end
returnString = returnString .. '\n|}'
return returnString
end
--endregion
return ArmorLister


