Module:PlasmaWeaponLister

From Terra Invicta Official Wiki

Documentation for this module may be created at Module:PlasmaWeaponLister/doc

---
---Reads the Plasma Weapon data files and presents them in readable formats, with additional calculated statistics.
---
---@module PlasmaWeaponLister
local PlasmaWeaponLister = {}

--region Dependencies
local IconModule = require('Module:Icon')
local PlasmaWeaponData = mw.loadData('Module:CSVReader/PlasmaWeapon')
local PlasmaWeaponNames = mw.loadData('Module:ENReader/PlasmaWeapon')
local ProjectNameBuilder = require('Module:ProjectLister/NameBuilder')
--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
--endregion

--region Private methods
local function getMountDisplayName(mount)
    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"
    }
    return mountNames[mount] or mount
end

local function calculateStationaryDamage(wmass, muzzle)
    return tonumber(wmass) * tonumber(muzzle) ^ 2 / 40
end

local function calculateFireRate(salvo, cooldown, scooldown)
    if not salvo or tonumber(salvo) == 1 then
        return 60 / tonumber(cooldown)
    else
        local fullCooldown = tonumber(cooldown) + (tonumber(salvo) - 1) * tonumber(scooldown)
        return math.max(1,tonumber(salvo)) * 60 / fullCooldown
    end
end

local function calculateFullCooldown(salvo, cooldown, scooldown)
    if not salvo or salvo == 1 then
        return tonumber(cooldown)
    else
        return tonumber(cooldown) + (tonumber(salvo) - 1) * tonumber(scooldown)
    end
end

local function calculatePowerPerShot(charge, amass, muzzle, eff)
    return (tonumber(charge) + tonumber(amass) * tonumber(muzzle) ^ 2 / 2000) / tonumber(eff)
end

local function calculatePowerPerMinute(fireRate, powerPerShot)
    return fireRate * powerPerShot
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 calculateAmmoResourceCost(magazine, amass, resourceWeight)
    return tonumber(magazine) * tonumber(amass) * (tonumber(resourceWeight) or 0) / 10000
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
function PlasmaWeaponLister.ListBasicPlasmaWeapons()
    local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
    returnString = returnString .. '\n! Plasma Weapon'
    returnString = returnString .. '\n! Warhead Mass<br>(kg)'
    returnString = returnString .. '\n! Muzzle Velocity<br>(km/s)'
    returnString = returnString .. '\n! Stationary Damage'
    returnString = returnString .. '\n! Chip %'
    returnString = returnString .. '\n! Fire Rate<br>(shots/min)'
    returnString = returnString .. '\n! Chip Damage Per Minute'
    returnString = returnString .. '\n! Range<br>(km)'
    returnString = returnString .. '\n|-'
    
    for rowID, row in pairs(PlasmaWeaponData) do
        returnString = returnString .. '\n| ' .. (PlasmaWeaponNames['TIPlasmaWeaponTemplate.displayName.' .. rowID] or rowID)
        returnString = returnString .. '\n| ' .. getValue(row, 'warheadMass_kg', 0)
        returnString = returnString .. '\n| ' .. getValue(row, 'muzzleVelocity_kps', 0)
        
        local stationaryDamage = calculateStationaryDamage(getValue(row, 'warheadMass_kg'), getValue(row, 'muzzleVelocity_kps'))
        returnString = returnString .. '\n| ' .. round(stationaryDamage,3)
        local chipPercent = (tonumber(getValue(row, 'flatChipping')) or 0) * 100
        returnString = returnString .. '\n| ' .. chipPercent .. '%'
        
        local fireRate = calculateFireRate(getValue(row, 'salvo_shots',1), getValue(row, 'cooldown_s'), getValue(row, 'intraSalvoCooldown_s'))
        returnString = returnString .. '\n| ' .. round(fireRate,3)
        returnString = returnString .. '\n| ' .. round(stationaryDamage * chipPercent / 100 * fireRate,3)
        
        returnString = returnString .. '\n| ' .. getValue(row, 'targetingRange_km', 0)
        returnString = returnString .. '\n|-'
    end
    
    returnString = returnString .. '\n|}'
    return returnString
end

function PlasmaWeaponLister.ListDetailedPlasmaWeapons()
    local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
    returnString = returnString .. '\n! rowspan=2|Plasma Weapon'
    returnString = returnString .. '\n! rowspan=2|Required Project'
    returnString = returnString .. '\n! rowspan=2|Hard Points'
    returnString = returnString .. '\n! rowspan=2|Warhead Mass<br>(kg)'
    returnString = returnString .. '\n! rowspan=2|Muzzle Velocity<br>(km/s)'
    returnString = returnString .. '\n! rowspan=2|Stationary Damage'
    returnString = returnString .. '\n! rowspan=2|Chip %'
    returnString = returnString .. '\n! rowspan=2|Salvo'
    returnString = returnString .. '\n! rowspan=2|Full Cooldown<br>(s)'
    returnString = returnString .. '\n! rowspan=2|Fire Rate<br>(shots/min)'
    returnString = returnString .. '\n! rowspan=2|Chip Damage Per Minute'
    returnString = returnString .. '\n! rowspan=2|Range<br>(km)'
    returnString = returnString .. '\n! rowspan=2|Crew'
    returnString = returnString .. '\n! rowspan=2|Mass<br>(tons)'
    returnString = returnString .. '\n! colspan=5|Build Resources'
    returnString = returnString .. '\n! rowspan=2|Magazine'
    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)'
    returnString = returnString .. '\n|-'
    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|-'
    
    for rowID, row in pairs(PlasmaWeaponData) do
        returnString = returnString .. '\n| ' .. (PlasmaWeaponNames['TIPlasmaWeaponTemplate.displayName.' .. rowID] or rowID)
        
		returnString = returnString .. '\n| ' .. ProjectNameBuilder.buildName({args={row['requiredProjectName']}})
        
        returnString = returnString .. '\n| ' .. getMountDisplayName(getValue(row, 'mount'))

        returnString = returnString .. '\n| ' .. getValue(row, 'warheadMass_kg', 0)
        returnString = returnString .. '\n| ' .. getValue(row, 'muzzleVelocity_kps', 0)
        
        local stationaryDamage = calculateStationaryDamage(getValue(row, 'warheadMass_kg'), getValue(row, 'muzzleVelocity_kps'))
        returnString = returnString .. '\n| ' .. round(stationaryDamage,3)
        
        local chipPercent = (tonumber(getValue(row, 'flatChipping')) or 0) * 100
        returnString = returnString .. '\n| ' .. chipPercent .. '%'
        returnString = returnString .. '\n| ' .. getValue(row, 'salvo_shots',1)
        
        local fullCooldown = calculateFullCooldown(getValue(row, 'salvo_shots',1), getValue(row, 'cooldown_s'), getValue(row, 'intraSalvoCooldown_s'))
        returnString = returnString .. '\n| ' .. fullCooldown
        
        local fireRate = calculateFireRate(getValue(row, 'salvo_shots',1), getValue(row, 'cooldown_s'), getValue(row, 'intraSalvoCooldown_s'))
        returnString = returnString .. '\n| ' .. round(fireRate,3)
        returnString = returnString .. '\n| ' .. round(stationaryDamage * chipPercent / 100 * fireRate,3)
        
        returnString = returnString .. '\n| ' .. getValue(row, 'targetingRange_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
        
        -- Non-ammo build resources
        local waterCost = calculateResourceCost(getValue(row, 'baseWeaponMass_tons'), 0, 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)
        
        returnString = returnString .. '\n| ' .. round(waterCost, 1)
        returnString = returnString .. '\n| ' .. round(volatilesCost, 1)
        returnString = returnString .. '\n| ' .. round(metalsCost, 1)
        returnString = returnString .. '\n| ' .. round(noblesCost, 1)
        returnString = returnString .. '\n| ' .. round(exoticsCost, 1)
        
        returnString = returnString .. '\n| ' .. getValue(row, 'magazine', 0)
        
        returnString = returnString .. '\n| ' .. getValue(row, 'efficiency', 1)
        
        local charge = tonumber(row['chargingEnergy_GJ']) or (tonumber(row['chargingEnergy_MJ']) / 1000)
        local powerPerShot = calculatePowerPerShot(charge, getValue(row, 'warheadMass_kg'), getValue(row, 'muzzleVelocity_kps'), getValue(row, 'efficiency'))
        returnString = returnString .. '\n| ' .. round(powerPerShot,3)
        
        local powerPerMinute = calculatePowerPerMinute(fireRate, powerPerShot)
        returnString = returnString .. '\n| ' .. round(powerPerMinute,3)
        
        returnString = returnString .. '\n|-'
    end
    
    returnString = returnString .. '\n|}'
    
    return returnString
end

--endregion

return PlasmaWeaponLister