Module:HabSiteLister

From Terra Invicta Official Wiki

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

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

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

local HabSiteData = mw.loadData('Module:CSVReader/HabSite')
local MiningProfileData = mw.loadData('Module:CSVReader/MiningProfile')
local SpaceBodyData = mw.loadData('Module:CSVReader/SpaceBody')

local SpaceBodyMiningData = mw.loadData('Module:SpaceBodyLister/Mining')

local HabSiteNames = mw.loadData('Module:ENReader/HabSite')
local MiningProfileNames = mw.loadData('Module:ENReader/MiningProfile')
local SpaceBodyNames = mw.loadData('Module:ENReader/SpaceBody')
--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 outerEffects = {
	Effect_ExploreJupiter = true,
	Effect_ExploreSaturn = true,
	Effect_ExploreOuterPlanets = true,
	Effect_ExploreKuiperBelt = true
}
--endregion



--region Private member variables
--none
--endregion

--region Private methods


--endregion

--region Public methods
function HabSiteLister.ListMedians()
	return HabSiteLister.ListHabSites(1)
end

function HabSiteLister.ListTopMeans()
	return HabSiteLister.ListHabSites(2)
end

--- Example Usage: {{#invoke:HabSiteLister|ListSpecific|mode=1|specificSpaceBody=Mercury}} 
function HabSiteLister.ListSpecific(frame)
	local mode = tonumber(frame.args['mode'])
	local specificSpaceBody = frame.args['specificSpaceBody']
	local restrictInner = frame.args['restrictInner']
	local restrictOuter = frame.args['restrictOuter']
	return HabSiteLister.ListHabSites(mode,specificSpaceBody,restrictInner,restrictOuter)
end

---@param mode int what to display
---- 1: Medians 
---- 2: Top 50% Means 
---@param specificSpaceBody which space body to focus on. Use nil value to show all.
---@param restrictInner do not show outer solar system space bodies
---@param restrictOuter do not show inner solar system space bodies
---@return wiki table of HabSites
function HabSiteLister.ListHabSites(mode, specificSpaceBody, restrictInner, restrictOuter)
-- {| class="wikitable sortable mw-collapsible mw-collapsed" style="text-align: center;"
-- ! rowspan=2|Site Name !! rowspan=2|Parent Body !! rowspan=2| Mining Profile !! colspan=5 | Median Resources ('''after''' Mass/Density Modifiers)<ref>Negative values are not a bug, the game actually sets the median to a negative value to make it incredibly unlikely for the site to have a positive mine output. But note that the actual mined amount cannot actually be negative.</ref><ref>Blank values indicate that the site can never produce this resource. In contrast, 0 indicates that there is still up to 50% chance for the site to produce the resource.</ref>
-- |-
-- ! [[File:ICO water.png|25px]] Water !! [[File:ICO volatiles.png|25px]] Volatiles !! [[File:ICO metal.png|25px]] Base Metals !! [[File:ICO metal noble.png|25px]] Noble Metals !! [[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|Site Name'
	returnString = returnString .. '\n! rowspan=2|Parent Body'
	returnString = returnString .. '\n! rowspan=2|Mining Profile'
	returnString = returnString .. '\n! rowspan=2|Max Hab Tier'
	if mode == 1 then 
		returnString = returnString .. "\n! colspan=5 | Median Resources ('''after''' Mass/Density Modifiers)"
	elseif mode == 2 then
		returnString = returnString .. "\n! colspan=5 | Estimated Top 50% Mean Resources ('''after''' Mass/Density Modifiers)"
	end
	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={'fissiles'}})
	returnString = returnString .. '\n|-'
	
	local totals = {0,0,0,0,0}
	local totalSites = 0
	for rowID, row in pairs(HabSiteData) do
		local spaceBodyID = row['parentBodyName'] or ''
		if (not specificSpaceBody or specificSpaceBody == '' or specificSpaceBody == spaceBodyID)
			and (not restrictInner or restrictInner == '' or not outerEffects[SpaceBodyData[spaceBodyID]['effectToExplore']])
			and (not restrictOuter or restrictOuter == '' or outerEffects[SpaceBodyData[spaceBodyID]['effectToExplore']]) then
				
			totalSites = totalSites + 1
			returnString = returnString .. '\n| ' .. (HabSiteNames['TIHabSiteTemplate.displayName.' .. rowID] or rowID)
			
			if spaceBodyID == '' then
				returnString = returnString .. '\n|' 
			else
				returnString = returnString .. '\n| ' .. (SpaceBodyNames['TISpaceBodyTemplate.displayName.' .. spaceBodyID] or spaceBodyID)
			end
	
			local miningProfileID = row['miningProfileName']
			if not miningProfileID or miningProfileID == '' then
				returnString = returnString .. '\n|' 
			else
				returnString = returnString .. '\n| ' .. (MiningProfileNames['TIMiningProfileTemplate.displayName.' .. miningProfileID] or miningProfileID)
			end	
		
			if not spaceBodyID or spaceBodyID == '' then
				returnString = returnString .. '\n|' 
			else
				returnString = returnString .. '\n| ' .. (SpaceBodyData[spaceBodyID]['maxHabSize'] or 0)
			end
	-- {{!}} {{#switch: 1
	-- | {{#expr: {{#external_value:{{{mp}}}water|0}} > 0}}
	-- | {{#expr: {{#external_value:{{{mp}}}waterw|0}} > 0}} =
	-- {{#ifeq: {{#external_value:{{{mp}}}modify}} | true | {{#expr: {{#external_value:{{{mp}}}water|0}} * {{#external_value:{{{parentbody}}}modifier1}} }} | {{#external_value:{{{mp}}}water|0}} }}
		
			local modifyBySize = MiningProfileData[miningProfileID]['modifyBySize']
			local waterMean = tonumber(MiningProfileData[miningProfileID]['water_mean'])
			local waterWidth = tonumber(MiningProfileData[miningProfileID]['water_width'])
			local waterMin = tonumber(MiningProfileData[miningProfileID]['water_min'])
			local waterJump = tonumber(MiningProfileData[miningProfileID]['water_jump'])
			if waterMean == 0 and waterWidth == 0 then
				returnString = returnString .. '\n| ' 
			elseif not modifyBySize or modifyBySize ~= 'true' then
				if mode == 1 then
					totals[1] = totals[1] + waterMean
					returnString = returnString .. '\n| ' .. tostring(waterMean)
				elseif mode == 2 then
					totals[1] = totals[1] + waterMean + waterWidth * ((1 / (1 - waterJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(waterMean + waterWidth * ((1 / (1 - waterJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			else
				if mode == 1 then
					totals[1] = totals[1] + waterMean * SpaceBodyMiningData[spaceBodyID]['modifierA']
					returnString = returnString .. '\n| ' .. tostring(round(waterMean * SpaceBodyMiningData[spaceBodyID]['modifierA'],3))
				elseif mode == 2 then
					totals[1] = totals[1] + waterMean * SpaceBodyMiningData[spaceBodyID]['modifierA'] + waterWidth * ((1 / (1 - waterJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(waterMean * SpaceBodyMiningData[spaceBodyID]['modifierA'] + waterWidth * ((1 / (1 - waterJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			end
			
			local volatilesMean = tonumber(MiningProfileData[miningProfileID]['volatiles_mean'])
			local volatilesWidth = tonumber(MiningProfileData[miningProfileID]['volatiles_width'])
			local volatilesMin = tonumber(MiningProfileData[miningProfileID]['volatiles_min'])
			local volatilesJump = tonumber(MiningProfileData[miningProfileID]['volatiles_jump'])
			if volatilesMean == 0 and volatilesWidth == 0 then
				returnString = returnString .. '\n| ' 
			elseif not modifyBySize or modifyBySize ~= 'true' then
				if mode == 1 then
					totals[2] = totals[2] + volatilesMean
					returnString = returnString .. '\n| ' .. tostring(volatilesMean)
				elseif mode == 2 then
					totals[2] = totals[2] + volatilesMean + volatilesWidth * ((1 / (1 - volatilesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(volatilesMean + volatilesWidth * ((1 / (1 - volatilesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			else
				if mode == 1 then
					totals[2] = totals[2] + volatilesMean * SpaceBodyMiningData[spaceBodyID]['modifierA']
					returnString = returnString .. '\n| ' .. tostring(round(volatilesMean * SpaceBodyMiningData[spaceBodyID]['modifierA'],3))
				elseif mode == 2 then
					totals[2] = totals[2] + volatilesMean * SpaceBodyMiningData[spaceBodyID]['modifierA'] + volatilesWidth * ((1 / (1 - volatilesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(volatilesMean * SpaceBodyMiningData[spaceBodyID]['modifierA'] + volatilesWidth * ((1 / (1 - volatilesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			end
			
			
			local metalsMean = tonumber(MiningProfileData[miningProfileID]['metals_mean'])
			local metalsWidth = tonumber(MiningProfileData[miningProfileID]['metals_width'])
			local metalsMin = tonumber(MiningProfileData[miningProfileID]['metals_min'])
			local metalsJump = tonumber(MiningProfileData[miningProfileID]['metals_jump'])
			if metalsMean == 0 and metalsWidth == 0 then
				returnString = returnString .. '\n| ' 
			elseif not modifyBySize or modifyBySize ~= 'true' then
				if mode == 1 then
					totals[3] = totals[3] + metalsMean
					returnString = returnString .. '\n| ' .. tostring(metalsMean)
				elseif mode == 2 then
					totals[3] = totals[3] + metalsMean + metalsWidth * ((1 / (1 - metalsJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(metalsMean + metalsWidth * ((1 / (1 - metalsJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			else
				if mode == 1 then
					totals[3] = totals[3] + metalsMean * SpaceBodyMiningData[spaceBodyID]['modifierB']
					returnString = returnString .. '\n| ' .. tostring(round(metalsMean * SpaceBodyMiningData[spaceBodyID]['modifierB'],3))
				elseif mode == 2 then
					totals[3] = totals[3] + metalsMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + metalsWidth * ((1 / (1 - metalsJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(metalsMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + metalsWidth * ((1 / (1 - metalsJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			end
			
			
			local noblesMean = tonumber(MiningProfileData[miningProfileID]['nobles_mean'])
			local noblesWidth = tonumber(MiningProfileData[miningProfileID]['nobles_width'])
			local noblesMin = tonumber(MiningProfileData[miningProfileID]['nobles_min'])
			local noblesJump = tonumber(MiningProfileData[miningProfileID]['nobles_jump'])
			if noblesMean == 0 and noblesWidth == 0 then
				returnString = returnString .. '\n| ' 
			elseif not modifyBySize or modifyBySize ~= 'true' then
				if mode == 1 then
					totals[4] = totals[4] + noblesMean
					returnString = returnString .. '\n| ' .. tostring(noblesMean)
				elseif mode == 2 then
					totals[4] = totals[4] + noblesMean + noblesWidth * ((1 / (1 - noblesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(noblesMean + noblesWidth * ((1 / (1 - noblesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			else
				if mode == 1 then
					totals[4] = totals[4] + noblesMean * SpaceBodyMiningData[spaceBodyID]['modifierB']
					returnString = returnString .. '\n| ' .. tostring(round(noblesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'],3))
				elseif mode == 2 then
					totals[4] = totals[4] + noblesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + noblesWidth * ((1 / (1 - noblesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(noblesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + noblesWidth * ((1 / (1 - noblesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			end
			
			
			local fissilesMean = tonumber(MiningProfileData[miningProfileID]['fissiles_mean'])
			local fissilesWidth = tonumber(MiningProfileData[miningProfileID]['fissiles_width'])
			local fissilesMin = tonumber(MiningProfileData[miningProfileID]['fissiles_min'])
			local fissilesJump = tonumber(MiningProfileData[miningProfileID]['fissiles_jump'])
			if fissilesMean == 0 and fissilesWidth == 0 then
				returnString = returnString .. '\n| ' 
			elseif not modifyBySize or modifyBySize ~= 'true' then
				if mode == 1 then
					totals[5] = totals[5] + fissilesMean
					returnString = returnString .. '\n| ' .. tostring(fissilesMean)
				elseif mode == 2 then
					totals[5] = totals[5] + fissilesMean + fissilesWidth * ((1 / (1 - fissilesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(fissilesMean + fissilesWidth * ((1 / (1 - fissilesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			else
				if mode == 1 then
					totals[5] = totals[5] + fissilesMean * SpaceBodyMiningData[spaceBodyID]['modifierB']
					returnString = returnString .. '\n| ' .. tostring(round(fissilesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'],3))
				elseif mode == 2 then
					totals[5] = totals[5] + fissilesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + fissilesWidth * ((1 / (1 - fissilesJump)) - 1)
					returnString = returnString .. '\n| ' .. tostring(round(fissilesMean * SpaceBodyMiningData[spaceBodyID]['modifierB'] + fissilesWidth * ((1 / (1 - fissilesJump)) - 1),3))
				else
					returnString = returnString .. '\n| ' 
				end
			end
			
	    	returnString = returnString .. '\n|-'
	    end
	end
	returnString = returnString .. '\n|- class="sortbottom"'
	returnString = returnString .. "\n! colspan=4| '''Total:''' " .. totalSites .. ' Hab Sites'
	returnString = returnString .. "\n! " .. round(totals[1],3)
	returnString = returnString .. "\n! " .. round(totals[2],3)
	returnString = returnString .. "\n! " .. round(totals[3],3)
	returnString = returnString .. "\n! " .. round(totals[4],3)
	returnString = returnString .. "\n! " .. round(totals[5],3)
	
	returnString = returnString .. '\n|}'
	
	return returnString
end

--endregion

return HabSiteLister