Module:OfficerLister

From Terra Invicta Official Wiki

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

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

--region Dependencies
local IconModule = require('Module:Icon')
local TVModule = require('Module:TV')
local OfficerData = mw.loadData('Module:CSVReader/Officer')
local OfficerNames = mw.loadData('Module:ENReader/Officer')

--endregion

--region Private constants
local sfind = string.find
local ssub = string.sub
local requirements = {
	FlagBridge = '\n* Requires flag bridge module',
	MissileWeapons =  '\n* Using missiles',
	GunWeapons =  '\n* Using naval, magnetic, or plasma guns',
	EnergyWeapons =  '\n* Using lasers or particles',
	Marines = '\n* Using marines',
	TunableDrive =  '\n* Requires tunable drive',
}
local triggers = {
	WinCombat = 'Winning combat',
	SurviveCombat = 'Surviving combat',
	CombatKill = 'Killing in combat',
	CombatKill_Missiles = 'Killing in combat',
	CombatKill_Guns = 'Killing in combat',
	CombatKill_Beam = 'Killing in combat',
	SuccessfulMarineAssault = 'Successfully assaulting',
	CompleteLongTrajectory = 'Completing interplanetary transfer'
}
local levelColor = {
	[1] = 'red',
	[2] = 'orange',
	[3] = 'green',
}
--endregion



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

--region Private methods
-- Replaces ONE instance of the stringToReplace with replacementString in the fullString
local sreplace = function(fullString, stringToReplace, replacementString)
	local si, ei = sfind(fullString, stringToReplace, 1, true)
	if not si then
		return fullString
	end
	local prefix = ssub(fullString,1,si - 1)
	local suffix = ssub(fullString,ei+1)
	return prefix .. replacementString .. suffix
end

--endregion

--region Public methods

---@return wiki table of Officers. 
function OfficerLister.ListOfficers()
	local returnString = '{| class="wikitable sortable mw-collapsible"'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Officer Name<br><span style="color:' .. levelColor[1] .. '">1st Rank</span><br><span style="color:' .. levelColor[2] .. '">2nd Rank</span><br><span style="color:' .. levelColor[3] .. '">3rd Rank</span>'
	returnString = returnString .. '\n! Spawn<br>Rules'
	returnString = returnString .. '\n! Min<br>Crew'
	returnString = returnString .. '\n! Effects<br><span style="color:' .. levelColor[1] .. '">At 1st Rank</span><br><span style="color:' .. levelColor[2] .. '">At 2nd Rank</span><br><span style="color:' .. levelColor[3] .. '">At 3rd Rank</span>'
	
	
	returnString = returnString .. '\n|-'
	
	for rowID, row in pairs(OfficerData) do
		returnString = returnString .. '\n| ' .. (OfficerNames['TIOfficerTemplate.displayName.' .. rowID] or rowID)
		returnString = returnString .. '<br><span style="color:' .. levelColor[1] .. '">' .. (OfficerNames['TIOfficerTemplate.' .. rowID .. '_1'] or rowID) .. '</span>'
		returnString = returnString .. '<br><span style="color:' .. levelColor[2] .. '">' .. (OfficerNames['TIOfficerTemplate.' .. rowID .. '_2'] or rowID) .. '</span>'
		returnString = returnString .. '<br><span style="color:' .. levelColor[3] .. '">' .. (OfficerNames['TIOfficerTemplate.' .. rowID .. '_3'] or rowID) .. '</span>'
		
		returnString = returnString .. '\n| ' .. ((tonumber(row['spawnChance'] or 0) or 0) * 100) .. '% chance when:\n*' .. (triggers[row['spawnEventType'] or ''] or row['spawnEventType'])
		
		local minCrew = 0
		local bypassOfficerCap = true
		for i = 0, 2 do
			local req = row['requirements/' .. i .. '/requirement']
			if req and req == 'CrewMin' then
				minCrew = row['requirements/' .. i .. '/value']
			elseif req and req == 'MaxTotalOfficersPerShip' then
				bypassOfficerCap = false
			elseif req and requirements[req] then
				returnString = returnString .. requirements[req]
			end
		end
		if bypassOfficerCap then
			returnString = returnString .. '\n* Bypass officer limit'
		end
		returnString = returnString .. '\n| ' .. minCrew
		
		local effects = {}
		effects[1] = ''
		effects[2] = ''
		effects[3] = ''
		for i = 0, 8 do
			local level = tonumber(row['effects/' .. i .. '/level'] or 0) or 0
			if level and level ~= 0 then
				effects[level] = effects[level] .. '* <span style="color:' .. levelColor[level] .. '">'
				local evalue = {}
				evalue[0] = row['effects/' .. i .. '/value']
				evalue[1] = ((tonumber(row['effects/' .. i .. '/value'] or 0) or 0) * 100) .. '%'
				evalue[2] = (100 - (tonumber(row['effects/' .. i .. '/value'] or 0) or 0) * 100) .. '%'
				evalue[3] = ((tonumber(row['effects/' .. i .. '/value'] or 0) or 0) * 100 - 100) .. '%'
				evalue[4] = ((tonumber(row['effects/' .. i .. '/value'] or 0) or 0) * -100) .. '%'
				
				local effect = OfficerNames['TIOfficerTemplate.' .. row['effects/' .. i .. '/effect']] or row['effects/' .. i .. '/effect']
				effect = ssub(effect,2)
				effect = sreplace(effect, '{0}', evalue[0])
				effect = sreplace(effect, '{1}', evalue[1])
				effect = sreplace(effect, '{2}', evalue[2])
				effect = sreplace(effect, '{3}', evalue[3])
				effect = sreplace(effect, '{4}', evalue[4])
				effect = sreplace(effect, '<color=#FFFFFFFF><sprite name="influence"></color>', TVModule.TV({args={'influence'}}))
				
				effects[level] = effects[level] .. effect
				effects[level] = effects[level] .. '</span>\n'
			end
		end
		returnString = returnString .. '\n|\n{|\n|-\n|\n' .. effects[1] .. '\n|-\n|\n' .. effects[2] .. '\n|-\n|\n' .. effects[3] .. '\n|}'
		returnString = returnString .. '\n|-'
	end
	
	returnString = returnString .. '\n|}'
	
	return returnString
end

--endregion

return OfficerLister