Module:SpaceBodyLister

From Terra Invicta Official Wiki

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

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

--region Dependencies
local RestrictionChecker = require('Module:RestrictionChecker')
local IconModule = require('Module:Icon')

local SpaceBodyData = mw.loadData('Module:CSVReader/SpaceBody')
local SpaceBodyMiningData = mw.loadData('Module:SpaceBodyLister/Mining')
local SpaceBodyBombardData = mw.loadData('Module:SpaceBodyLister/Bombard')
local SpaceBodySystemData = mw.loadData('Module:SpaceBodyLister/System')
--local SpaceBodyExploreData = mw.loadData('Module:SpaceBodyLister/Explore')

local SpaceBodyNames = mw.loadData('Module:ENReader/SpaceBody')
--Note ExploreEffectNames is hard-coded, not a lookup. If the Mission To... techs ever change, this will need manual updating.
local ExploreEffectNames = mw.loadData('Module:ExploreEffectNames') 
--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 member variables
--none
--endregion

--region Private methods


--endregion

--region Public methods
function SpaceBodyLister.ListRestrictedMiningModifiers(frame)
	return SpaceBodyLister.ListMiningModifiers(frame.args)
end
function SpaceBodyLister.ListRestrictedBombardValues(frame)
	return SpaceBodyLister.ListBombardValues(frame.args)
end
function SpaceBodyLister.ListRestrictedSystemData(frame)
	return SpaceBodyLister.ListSystemData(frame.args)
end
function SpaceBodyLister.ListRestrictedExplorationData(frame)
	return SpaceBodyLister.ListExplorationData(frame.args)
end

---@return wiki table of Space Body Mining Modifiers
function SpaceBodyLister.ListMiningModifiers(restrictionsTable)
--{| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;width:100%;"
--|+ Table of Mining Site Modifiers for each Space Body
--|-
--! rowspan=2|Minable Space Body !! rowspan=2|Mass (kg) !! rowspan=2|Density (g / cm<sup>3</sup>) !! colspan=4 | Mass/Density Modifiers (Only for Modifiable Mining Profiles)
--|-
--! Mass Modifier !! Density Modifier !! Effect on [[File:ICO water.png|25px]] Water and [[File:ICO volatiles.png|25px]] Volatiles !! Effect on [[File:ICO metal.png|25px]] Base Metals, [[File:ICO metal noble.png|25px]] Noble Metals, and [[File:ICO fissile.png|25px]] Fissiles

	local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! rowspan=2|Minable Space Body'
	returnString = returnString .. '\n! rowspan=2|Mass (kg)'
	returnString = returnString .. '\n! rowspan=2|Density (g / cm³)'
	returnString = returnString .. "\n! colspan=4 | Mass/Density Modifiers (Only for Modifiable Mining Profiles)"

	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Mass Modifier'
	returnString = returnString .. '\n! Density Modifier'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'water'}}) .. IconModule.Icon({args={'volatiles'}}) .. ' Modifier'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'metals'}}) .. IconModule.Icon({args={'nobles'}}) .. IconModule.Icon({args={'fissiles'}}) .. ' Modifier'
	returnString = returnString .. '\n|-'
	
	for rowID, row in pairs(SpaceBodyData) do
		if row['habSites/0'] and row['habSites/0'] ~= '' and RestrictionChecker.AllPass(restrictionsTable, row) then
			returnString = returnString .. '\n| ' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. rowID] or rowID)
			local spaceBodyMass = row['mass_kg']
			local spaceBodyDensity = row['density_gcm3']
			if spaceBodyMass and spaceBodyMass ~= '' and tonumber(spaceBodyMass) then
				returnString = returnString .. '\n| ' .. round(tonumber(spaceBodyMass),3)
			else
				returnString = returnString .. '\n| ' 
			end
			if spaceBodyDensity and spaceBodyDensity ~= '' and tonumber(spaceBodyDensity) then
				returnString = returnString .. '\n| ' .. round(tonumber(spaceBodyDensity),3)
			else
				returnString = returnString .. '\n| ' 
			end
			returnString = returnString .. '\n| ' .. round(SpaceBodyMiningData[rowID]['massModifier'],3)
			returnString = returnString .. '\n| ' .. round(SpaceBodyMiningData[rowID]['densityModifier'],3)
			returnString = returnString .. '\n| ' .. round(SpaceBodyMiningData[rowID]['modifierA'],3)
			returnString = returnString .. '\n| ' .. round(SpaceBodyMiningData[rowID]['modifierB'],3)
	    	returnString = returnString .. '\n|-'
	    end
	end
	returnString = returnString .. '\n|}'
	
	return returnString
end

---@return wiki table of Space Body Bombard Values
function SpaceBodyLister.ListBombardValues(restrictionsTable)
--{| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;width:100%;"
--|+ Table of Bombardment Related Values for each Space Body
--|-
--! rowspan=2|Bombardable Space Body !! rowspan=2|Mass (kg) !! rowspan=2|Mean Radius (km) !! rowspan=2| Sphere of Influence Radius (km) !! rowspan=2|Surface Gravity (m/s²) !! colspan=3|Atmosphere
--|-
--! Type !! Scale Height (km) !! Surface Density (kg/m³)

	local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! rowspan=2|Bombardable Space Body'
	returnString = returnString .. '\n! rowspan=2|Mass (kg)'
	returnString = returnString .. '\n! rowspan=2|Mean Radius (km)'
	returnString = returnString .. '\n! rowspan=2|Sphere of Influence Radius (km)'
	returnString = returnString .. '\n! rowspan=2|Surface Gravity (m/s²)'
	returnString = returnString .. "\n! colspan=3 | Atmosphere"

	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Type'
	returnString = returnString .. '\n! Scale Height'
	returnString = returnString .. '\n! Surface Density (kg/m³)'
	returnString = returnString .. '\n|-'
	
	for rowID, row in pairs(SpaceBodyData) do
		if RestrictionChecker.AllPass(restrictionsTable, row) then
			if (row['habSites/0'] and row['habSites/0'] ~= '') or rowID == 'Earth' then
				returnString = returnString .. '\n| ' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. rowID] or rowID)
				local spaceBodyMass = row['mass_kg']
				if spaceBodyMass and spaceBodyMass ~= '' and tonumber(spaceBodyMass) then
					returnString = returnString .. '\n| ' .. round(tonumber(spaceBodyMass),3)
				else
					returnString = returnString .. '\n| ' 
				end
				returnString = returnString .. '\n| ' .. round(SpaceBodyBombardData[rowID]['computedMeanRadius'],3)
				returnString = returnString .. '\n| ' .. round(SpaceBodyBombardData[rowID]['SOIradius'],3)
				returnString = returnString .. '\n| ' .. round(SpaceBodyBombardData[rowID]['surfaceGravity'],5)
				returnString = returnString .. '\n| ' .. row['atmosphere']
				returnString = returnString .. '\n| ' .. row['atmosphereScaleHeight_km']
				returnString = returnString .. '\n| ' .. row['atmosphereSurfaceDensity_kgpm3']
		    	returnString = returnString .. '\n|-'
		    end
	    end
	end
	returnString = returnString .. '\n|}'
	
	return returnString
end

---@return wiki table of which bodies are in which systems
function SpaceBodyLister.ListSystemData(restrictionsTable)
	local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
	returnString = returnString .. '\n|+ Is the Space Body in the chosen Solar System Size?'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! rowspan=2| Space Body'
	returnString = returnString .. "\n! colspan=5| Solar System Size"

	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Minimal'
	returnString = returnString .. '\n! Light'
	returnString = returnString .. '\n! Medium'
	returnString = returnString .. '\n! Full'
	returnString = returnString .. '\n! Massive'
	returnString = returnString .. '\n|-'

	for rowID, row in pairs(SpaceBodyData) do
		if RestrictionChecker.AllPass(restrictionsTable, row) then
			local systemRow = SpaceBodySystemData[rowID]
			if systemRow then
				returnString = returnString .. '\n| ' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. rowID] or rowID)

				for i = 1, 5 do
					if systemRow[i] then
						returnString = returnString .. '\n| Yes'
					else
						returnString = returnString .. '\n| '
					end
				end
		    	returnString = returnString .. '\n|-'
	    	end
		end
	end
	returnString = returnString .. '\n|}'

	return returnString
end

---@return wiki table of which bodies need which techs, what their hab limits are, etc.
function SpaceBodyLister.ListExplorationData(restrictionsTable)
	local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
	returnString = returnString .. '\n|+ Exploration characteristics of space bodies'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Space Body'
	returnString = returnString .. '\n! Object Type'
	returnString = returnString .. '\n! Parent Body'
	returnString = returnString .. "\n! Unlock Tech"
	returnString = returnString .. "\n! Orbital Radius (AU)"
	returnString = returnString .. "\n! Diameter (km)"
	returnString = returnString .. "\n! Max Hab Size"
	returnString = returnString .. "\n! # Hab Sites"
	returnString = returnString .. "\n! # Orbits"
	returnString = returnString .. '\n|-'
	
	for rowID, row in pairs(SpaceBodyData) do
		if RestrictionChecker.AllPass(restrictionsTable, row) then
			--pre-calculate hab/orbit counts and max hab size
			local habSiteCount = 0
			for i = 0, 30 do
				if row['habSites/' .. i] and row['habSites/' .. i] ~= '' then
					habSiteCount = habSiteCount + 1
				else
					break
				end
			end
			local orbitCount = 0
			for i = 0, 12 do
				if row['orbits/' .. i] and row['orbits/' .. i] ~= '' then
					orbitCount = orbitCount + 1
				else
					break
				end
			end
			local maxHabSize = tonumber(row['maxHabSize'])
			local displayHabSize = row['maxHabSize'] or ''
			if maxHabSize == 4 then --devs future-proofing, not a real value
			    displayHabSize = 3
			end
	
			if habSiteCount >= 4 then --big enough to have an article
				returnString = returnString .. '\n| ' .. '[[' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. rowID] or rowID) .. ']]'
			else
				returnString = returnString .. '\n| ' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. rowID] or rowID)
			end
			returnString = returnString .. '\n| ' .. (row['objectType'] or '')
			returnString = returnString .. '\n| ' .. '[[' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. (row['barycenterName'] or '')] or row['barycenterName'] or '') .. ']]'
			
			local effectKey = row['effectToExplore']
			if ExploreEffectNames[effectKey] then
				returnString = returnString .. '\n| ' .. '[[' .. ExploreEffectNames[effectKey] .. ']]'
			else
				returnString = returnString .. '\n| ' .. (effectKey or '')
			end
			
			--orbital AU is only stored for objects orbiting Sol, so for moons we look up the parent body 
			if row['barycenterName'] == 'Sol' then
				returnString = returnString .. '\n| ' .. (row['semiMajorAxis_AU'] or '')
			elseif row['dataName'] == 'Sol' then
				returnString = returnString .. '\n| 0'
			else
			    local parentRow = SpaceBodyData[row['barycenterName']]
			    if parentRow and parentRow['semiMajorAxis_AU'] then
			        returnString = returnString .. '\n| ' .. parentRow['semiMajorAxis_AU']
			    else
			        returnString = returnString .. '\n| '
			    end
			end
			
			returnString = returnString .. '\n| ' .. (row['friendlyDiameter'] or '')
			returnString = returnString .. '\n| ' .. displayHabSize
			returnString = returnString .. '\n| ' .. habSiteCount
			returnString = returnString .. '\n| ' .. orbitCount
			
			returnString = returnString .. '\n|-'
		end
	end
	returnString = returnString .. '\n|}'

	return returnString
end
--endregion

return SpaceBodyLister