Module:ParticleWeaponLister
From Terra Invicta Official Wiki
Documentation for this module may be created at Module:ParticleWeaponLister/doc
---
---Reads the Particle Weapon data files and presents them in readable formats, with additional calculated statistics.
---
---@module ParticleWeaponLister
local ParticleWeaponLister = {}
--region Dependencies
local IconModule = require('Module:Icon')
local ParticleWeaponData = mw.loadData('Module:CSVReader/ParticleWeapon')
local ParticleWeaponNames = mw.loadData('Module:ENReader/ParticleWeapon')
local ProjectNameBuilder = require('Module:ProjectLister/NameBuilder')
--endregion
--region Private constants
local mountNames = {
OneHull = "One Hull Slot",
TwoHullHoriz = "Two Hull Slots",
FourHull = "Four Hull Slots",
HalfNose = "Half Nose Slot",
OneNose = "One Nose Slot",
TwoNoseVert = "Two Nose Slots",
ThreeNoseAngle = "Three Nose Slots",
FourNose = "Four Nose Slots"
}
local floor = math.floor
local round = function(num, decimals)
local mult = 10^(decimals or 0)
return floor(num * mult + 0.5) / mult
end
--endregion
--region Private methods
local function calculateFireRate(salvo, cooldown, scooldown)
if not salvo or tonumber(salvo) == 1 then
return round(60 / tonumber(cooldown),1)
else
local fullCooldown = tonumber(cooldown) + (tonumber(salvo) - 1) * tonumber(scooldown)
return round(math.max(1,tonumber(salvo)) * 60 / fullCooldown,1)
end
end
local function calculateResourceCost(mass, resourceWeight, crew, crewResource)
local baseCost = tonumber(mass) * (tonumber(resourceWeight) or 0) / 10
local crewCost = tonumber(crew) * (tonumber(crewResource) or 0)
return baseCost + crewCost
end
local function calculatePowerPerShot(shotpower, eff)
return tonumber(shotpower) / 1000 / tonumber(eff)
end
local function calculatePowerPerMinute(fireRate, powerPerShot)
return fireRate * powerPerShot
end
--{{#ifeq: {{{dispM}}} | Neutral |
--{{#expr: 3.1415927 * ({{{emit}}} * 20 / {{{lensR}}})^2 round 4}}
--| {{#expr: 3.1415927 * ({{{lensR}}} / 100 * 2 ^ (200 / {{{doublingRange}}}))^2 round 4}}
--}}
-- if (particleBeamDispersionModel == ParticleBeamDispersionModel.Charged || particleBeamDispersionModel != ParticleBeamDispersionModel.Neutral)
-- {
-- num = this.lensRadius_cm * Mathf.Pow(2f, range_km / this.doublingRange_km) * 0.01f;
-- }
-- else
-- {
-- num = this.emittance_mrad * (range_km * 1000f) * 1E-06f / (this.lensRadius_cm * 0.01f);
-- }
-- return 3.1415927f * num * num;
local function calculateBeamArea(dispM, emit, lensR, doublingRange, range)
local beamRadius
if dispM ~= 'Neutral' then
beamRadius = tonumber(lensR) * 2 ^ (range / tonumber(doublingRange)) * 0.01
else
beamRadius = tonumber(emit) * range * 0.1 / tonumber(lensR)
end
return beamRadius ^ 2 * 3.1415927
end
-- Safe value access with fallback
local function getValue(row, key, default)
local value = row[key]
if value == nil or value == '' then
return default or 0
end
return value
end
--endregion
--region Public methods
--- Example Usage: {{#invoke:ParticleWeaponLister|ListSpecific|detailed=true|alien=true}}
function ParticleWeaponLister.ListSpecific(frame)
local detailed = frame.args['detailed'] == 'true'
local alien = frame.args['alien'] == 'true'
return ParticleWeaponLister.ListParticleWeapons(detailed, alien)
end
---@param detailed boolean whether to show the detailed or basic version.
---@param alien boolean whether to show alien or human version.
---@return wiki table of batteries
function ParticleWeaponLister.ListParticleWeapons(detailed, alien)
local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
returnString = returnString .. '\n! rowspan=2| Particle<br>Weapon'
if detailed and not alien then
returnString = returnString .. '\n! rowspan=2| Required<br>Project'
end
if detailed then
returnString = returnString .. '\n! rowspan=2| Hard<br>Points'
returnString = returnString .. '\n! rowspan=2| Can<br>PD'
end
returnString = returnString .. '\n! rowspan=2| Damage'
returnString = returnString .. '\n! colspan=3| Damage Type Multipliers'
returnString = returnString .. '\n! rowspan=2| Estimated Baryon Damage'
returnString = returnString .. '\n! rowspan=2| Fire Rate<br>(shots/min)'
returnString = returnString .. '\n! rowspan=2| Range<br>(km)'
if detailed then
returnString = returnString .. '\n! rowspan=2| Dispersion<br>Model'
returnString = returnString .. '\n! rowspan=2| Lens Radius<br>(cm)'
returnString = returnString .. '\n! rowspan=2| Emittence'
returnString = returnString .. '\n! rowspan=2| Doubling<br>Range'
returnString = returnString .. '\n! rowspan=2| Crew'
returnString = returnString .. '\n! rowspan=2| Mass<br>(tons)'
returnString = returnString .. '\n! colspan=6| Build Resources'
returnString = returnString .. '\n! rowspan=2| Efficiency'
returnString = returnString .. '\n! rowspan=2| Power Per Shot<br>(GJ)'
returnString = returnString .. '\n! rowspan=2| Power Per Minute<br>(GJ/min)'
end
returnString = returnString .. '\n! colspan=4| Beam Area (m²) at Range'
returnString = returnString .. '\n|-'
returnString = returnString .. '\n! Heat'
returnString = returnString .. '\n! X-Ray'
returnString = returnString .. '\n! Baryon'
if detailed then
returnString = returnString .. '\n!' .. IconModule.Icon({args={'water'}})
returnString = returnString .. '\n!' .. IconModule.Icon({args={'volatiles'}})
returnString = returnString .. '\n!' .. IconModule.Icon({args={'metals'}})
returnString = returnString .. '\n!' .. IconModule.Icon({args={'nobles'}})
returnString = returnString .. '\n!' .. IconModule.Icon({args={'exotics'}})
returnString = returnString .. '\n!' .. IconModule.Icon({args={'antimatter'}})
end
returnString = returnString .. '\n! 200km'
returnString = returnString .. '\n! 400km'
returnString = returnString .. '\n! 600km'
returnString = returnString .. '\n! 800km'
returnString = returnString .. '\n|-'
for rowID, row in pairs(ParticleWeaponData) do
local mount = mountNames[getValue(row, 'mount')]
local projectID = getValue(row, 'requiredProjectName')
if (alien and (projectID == 'Project_AlienMasterProject' or projectID == 'Project_AlienAdvancedMasterProject')) or ((not alien) and projectID ~= 'Project_AlienMasterProject' and projectID ~= 'Project_AlienAdvancedMasterProject') then
returnString = returnString .. '\n| ' .. (ParticleWeaponNames['TIParticleWeaponTemplate.displayName.' .. rowID] or rowID)
if detailed and not alien then
returnString = returnString .. '\n| ' .. ProjectNameBuilder.buildName({args={row['requiredProjectName']}})
end
if detailed then
returnString = returnString .. '\n| ' .. mount
if getValue(row, 'defenseMode', 'false') == 'true' then
if getValue(row, 'dispersionModel', 0) == 'Neutral' then
returnString = returnString .. '\n| Yes'
else
returnString = returnString .. '\n| Only Missiles'
end
else
returnString = returnString .. '\n| No'
end
end
returnString = returnString .. '\n| ' .. tostring(tonumber(getValue(row, 'shotPower_MJ', 0)) / 20)
returnString = returnString .. '\n| ' .. getValue(row, 'heatFraction', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'xRayFraction', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'baryonFraction', 0)
--{{#expr: {{{shotpower}}} / 20 * {{{baryF}}} / 16 * 5 }}
returnString = returnString .. '\n| ' .. tostring(round(tonumber(getValue(row, 'shotPower_MJ', 0)) * tonumber(getValue(row, 'baryonFraction', 0)) / 64, 4))
local fireRate = calculateFireRate(getValue(row, 'salvo_shots',1), getValue(row, 'cooldown_s'), getValue(row, 'intraSalvoCooldown_s'))
returnString = returnString .. '\n| ' .. fireRate
local trange = tonumber(getValue(row, 'targetingRange_km', 0))
returnString = returnString .. '\n| ' .. trange
if detailed then
returnString = returnString .. '\n| ' .. getValue(row, 'dispersionModel', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'lensRadius_cm', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'emittance_mrad', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'doublingRange_km', 0)
returnString = returnString .. '\n| ' .. getValue(row, 'crew', 0)
local baseMass = tonumber(getValue(row, 'baseWeaponMass_tons', 0))
local crewCount = tonumber(getValue(row, 'crew', 0))
local massWithCrew = baseMass + crewCount * 4
returnString = returnString .. '\n| ' .. massWithCrew
local waterCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/water'), getValue(row, 'crew'), 0.2)
local volatilesCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/volatiles'), getValue(row, 'crew'), 0.2)
local metalsCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/metals'), getValue(row, 'crew'), 0)
local noblesCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/nobleMetals'), getValue(row, 'crew'), 0)
local exoticsCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/exotics'), getValue(row, 'crew'), 0)
local antimatterCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), getValue(row, 'weightedBuildMaterials/antimatter'), getValue(row, 'crew'), 0)
returnString = returnString .. '\n| ' .. round(waterCost, 3)
returnString = returnString .. '\n| ' .. round(volatilesCost, 3)
returnString = returnString .. '\n| ' .. round(metalsCost, 3)
returnString = returnString .. '\n| ' .. round(noblesCost, 3)
returnString = returnString .. '\n| ' .. round(exoticsCost, 3)
returnString = returnString .. '\n| ' .. antimatterCost
returnString = returnString .. '\n| ' .. getValue(row, 'efficiency', 1)
local powerPerShot = calculatePowerPerShot(getValue(row, 'shotPower_MJ'), getValue(row, 'efficiency'))
returnString = returnString .. '\n| ' .. round(powerPerShot,3)
local powerPerMinute = calculatePowerPerMinute(fireRate, powerPerShot)
returnString = returnString .. '\n| ' .. round(powerPerMinute,3)
end
returnString = returnString .. '\n| '
if trange >= 200 then
returnString = returnString .. round(calculateBeamArea(getValue(row, 'dispersionModel'), getValue(row, 'emittance_mrad', 0), getValue(row, 'lensRadius_cm', 0), getValue(row, 'doublingRange_km', 0), 200),4)
end
returnString = returnString .. '\n| '
if trange >= 400 then
returnString = returnString .. round(calculateBeamArea(getValue(row, 'dispersionModel'), getValue(row, 'emittance_mrad', 0), getValue(row, 'lensRadius_cm', 0), getValue(row, 'doublingRange_km', 0), 400),4)
end
returnString = returnString .. '\n| '
if trange >= 600 then
returnString = returnString .. round(calculateBeamArea(getValue(row, 'dispersionModel'), getValue(row, 'emittance_mrad', 0), getValue(row, 'lensRadius_cm', 0), getValue(row, 'doublingRange_km', 0), 600),4)
end
returnString = returnString .. '\n| '
if trange >= 800 then
returnString = returnString .. round(calculateBeamArea(getValue(row, 'dispersionModel'), getValue(row, 'emittance_mrad', 0), getValue(row, 'lensRadius_cm', 0), getValue(row, 'doublingRange_km', 0), 800),4)
end
returnString = returnString .. '\n|-'
end
end
returnString = returnString .. '\n|}'
return returnString
end
--endregion
return ParticleWeaponLister


