Module:TechLister

From Terra Invicta Official Wiki

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

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

--region Dependencies
local IconModule = require('Module:Icon')
local TechData = mw.loadData('Module:CSVReader/Tech')
local TechNames = mw.loadData('Module:ENReader/Tech')
local ProjectData = mw.loadData('Module:CSVReader/Project')
local ProjectNameBuilder = require('Module:ProjectLister/NameBuilder')

local OrgLister = require('Module:OrgLister')
local OrgNames = mw.loadData('Module:ENReader/Org')

local TechPrereqs = mw.loadData('Module:TechLister/Prereqs')
local TechCosts = mw.loadData('Module:TechLister/Costs')
local TechOrgs = mw.loadData('Module:TechLister/Orgs')
local TechProjects = mw.loadData('Module:TechLister/Projects')
local TechTechs = mw.loadData('Module:TechLister/Techs')

local EffectDescriptionBuilder = require('Module:EffectLister/DescriptionBuilder')
--endregion

--region Private constants
local insert = table.insert
local concat = table.concat
local floor = math.floor
local sfind = string.find
local ssub = string.sub
local ScienceCategories = {
	Energy = 'energy',
	InformationScience='information',
	LifeScience='life',
	Materials='material',
	MilitaryScience='military',
	SocialScience='social',
	SpaceScience='space',
	Xenology='xenology'
}
local FactionLeaders = {
	destroyLeader = 'Colonel Hanse Castillo, [[Humanity First]]',
	resistLeader = 'Commander Fiona Ayouade, [[The Resistance]]',
	escapeLeader = 'Director Khalid Al-Ashgar, [[Project Exodus]]',
	exploitLeader = 'Chairman Soren Van Wyk, [[The Initiative]]',
	cooperateLeader = 'Chancellor Li Qingzhao, [[The Academy]]',
	appeaseLeader = 'Commissioner Kiran Banerjee, [[The Protectorate]]',
	submitLeader = 'Superior Judith Howell, [[The Servants]]',
	alienLeader = "War Master Winter's Sword, The [[Aliens]]",
}
--endregion



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

--region Private methods
local round = function(num, decimals)
    local mult = 10^(decimals or 0)
    return floor(num * mult + 0.5) / mult
end

-- 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
function TechLister.ListDetailedTechs()
	return TechLister.ListTechs(true)
end

function TechLister.ListBasicTechs()
	return TechLister.ListTechs(false)
end

function TechLister.ListDetailedTechsByCategory(frame)
	return TechLister.ListTechs(true, frame.args[1])
end

function TechLister.ListBasicTechsByCategory(frame)
	return TechLister.ListTechs(false, frame.args[1])
end

---@param detailed boolean whether to show the detailed or basic version.
---@return wiki table of Techs
function TechLister.ListTechs(detailed, category)
	local returnString = '{| class="wikitable sortable mw-collapsible" style="text-align: center;"'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Tech'
	returnString = returnString .. '\n! Type'
	returnString = returnString .. '\n! Research<br>Cost'
	returnString = returnString .. '\n! Full<br>Cost'
	if detailed then
		returnString = returnString .. '\n! Unlocked<br>Orgs'
		returnString = returnString .. '\n! Unlockable<br>Projects'
		returnString = returnString .. '\n! Full<br>Prereqs'
	else
		returnString = returnString .. '\n! Direct<br>Prereqs'
	end
	returnString = returnString .. '\n|-'
	
	for rowID, row in pairs(TechData) do
		if not category or row['techCategory'] == category then
			returnString = returnString .. '\n| [[' .. rowID .. '|' .. TechNames['TITechTemplate.displayName.' .. rowID] .. ']]'
			returnString = returnString .. '\n| ' .. IconModule.Icon({args={ScienceCategories[row['techCategory']]}})
			returnString = returnString .. '\n| ' .. row['researchCost']
			returnString = returnString .. '\n| ' .. tostring(TechCosts[rowID]['total'])
			
			if detailed then
				if TechOrgs[rowID] then
					local orgs = {}
					for orgID, _ in pairs(TechOrgs[rowID]) do
						insert(orgs, OrgNames['TIOrgTemplate.displayName.' .. orgID] or orgID)
					end
					returnString = returnString .. '\n| ' .. concat(orgs, '<br>')
				else
					returnString = returnString .. '\n| '
				end
				
				if TechProjects[rowID] then
					local projects = {}
					for projectID, _ in pairs(TechProjects[rowID]) do
						local projectChance = ProjectData[projectID]['factionAvailableChance']
						insert(projects, '(' .. projectChance .. '%)' .. ProjectNameBuilder.buildName({args={projectID}}))
					end
					returnString = returnString .. '\n| ' .. concat(projects, '<br>')
				else
					returnString = returnString .. '\n| '
				end
			end
			
			local prereqs = {}
			if detailed then
				for prereqID, _ in pairs(TechPrereqs[rowID]) do
					insert(prereqs, '[[' .. prereqID .. '|' .. TechNames['TITechTemplate.displayName.' .. prereqID] .. ']]')
				end
			else
				for i = 0, 2 do
					local prereq = row['prereqs/' .. i]
					if prereq and prereq ~= '' and prereq ~= 0 then
						insert(prereqs, '[[' .. prereq .. '|' .. TechNames['TITechTemplate.displayName.' .. prereq] .. ']]')
					end
				end
			end
			returnString = returnString .. '\n| ' .. concat(prereqs, '<br>')
			
			
			returnString = returnString .. '\n|-'
		end
	end
	returnString = returnString .. '\n|}'
	
	return returnString
end

---@param frame a set of arguments that includes:
----frame.args[1] the dataName of the tech
----frame.args['notes'] any additional notes the output table should contain
---@return wiki table of details for that tech
function TechLister.SingleTechTable(frame)
	local TechID = frame.args[1]
    local TechNotes = frame.args['notes'] or ''
    
	local returnString = '{| class="wikitable" style="width: 100%;text-align:center;"'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | <big>' .. (TechNames['TITechTemplate.displayName.' .. TechID] or TechID) .. '</big><br>' .. IconModule.Icon({args={ScienceCategories[TechData[TechID]['techCategory']], size='120px'}})
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | ' .. IconModule.Icon({args={'research'}}) .. 'Research Cost: ' .. TechData[TechID]['researchCost']
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Summary'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n| colspan=4 | ' .. (TechNames['TITechTemplate.summary.' .. TechID] or 'Error: Missing Summary')
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Description'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n| colspan=4 | ' .. (TechNames['TITechTemplate.description.' .. TechID] or 'Error: Missing Description')
	returnString = returnString .. '\n|-'
	
	returnString = returnString .. '\n| colspan=4 | \n{| class="wikitable sortable mw-collapsible" style="width: 100%;text-align:center;"'
	returnString = returnString .. '\n|+ Full List of Prerequisites.'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! Name'
	returnString = returnString .. '\n! Type'
	returnString = returnString .. '\n! Cost'
	returnString = returnString .. '\n|-'
	for prereqID, _ in pairs(TechPrereqs[TechID]) do
		returnString = returnString .. '\n| [[' .. prereqID .. '|' .. (TechNames['TITechTemplate.displayName.' .. prereqID] or prereqID) .. ']]'
		returnString = returnString .. '\n| ' .. IconModule.Icon({args={ScienceCategories[TechData[prereqID]['techCategory']]}})
		returnString = returnString .. '\n| ' .. TechData[prereqID]['researchCost']
		returnString = returnString .. '\n|-'
	end
	returnString = returnString .. '\n|}'
	
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Total ' .. IconModule.Icon({args={'research'}}) .. 'Research Cost (including itself)' 
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'energy'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['energy']
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'information'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['information']
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'life'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['life']
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'material'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['material']
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'military'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['military']
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'social'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['social']
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n!' .. IconModule.Icon({args={'space'}})
	returnString = returnString .. '\n|' .. TechCosts[TechID]['space']
	returnString = returnString .. '\n! Total'
	returnString = returnString .. '\n|' .. TechCosts[TechID]['total']
	returnString = returnString .. '\n|-'

	returnString = returnString .. '\n! colspan=4 | Direct Prerequisite For'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! style="width:50%;" colspan=2 | Techs'
	returnString = returnString .. '\n! style="width:50%;" colspan=2 | Projects'
	returnString = returnString .. '\n|-'
	
	if TechTechs[TechID] then
		local techtechs = {}
		for techtechID, _ in pairs(TechTechs[TechID]) do
			insert(techtechs, '[[' .. techtechID .. '|' .. (TechNames['TITechTemplate.displayName.' .. techtechID] or techtechID) .. ']]')
		end
		returnString = returnString .. '\n| style="width:50%;" colspan=2 | ' .. concat(techtechs, ' • ')
	else
		returnString = returnString .. '\n| style="width:50%;" colspan=2 | '
	end
	
	if TechProjects[TechID] then
		local projects = {}
		for projectID, _ in pairs(TechProjects[TechID]) do
			local projectChance = ProjectData[projectID]['factionAvailableChance']
			insert(projects, '(' .. projectChance .. '%)'  .. ProjectNameBuilder.buildName({args={projectID}}))
		end
		returnString = returnString .. '\n| style="width:50%;" colspan=2 | ' .. concat(projects, ' • ')
	else
		returnString = returnString .. '\n| style="width:50%;" colspan=2 | '
	end
	
	returnString = returnString .. '\n|-'
	if TechOrgs[TechID] then
		returnString = returnString .. '\n! colspan=4 | Unlocks Orgs'
		returnString = returnString .. '\n|-'
		returnString = returnString .. '\n| colspan=4 | \n' .. OrgLister.ListRestrictedOrgs({args={'Match,requiredTechName,' .. TechID}})
--		local orgs = {}
--		for orgID, _ in pairs(TechOrgs[TechID]) do
--			insert(orgs, OrgNames['TIOrgTemplate.displayName.' .. orgID] or orgID)
--		end
--		returnString = returnString .. '\n| colspan=4 | ' .. concat(orgs, ' • ')
	end
	
	returnString = returnString .. '\n|-'
	if TechData[TechID]['effects/0'] and TechData[TechID]['effects/0'] ~= '' and TechData[TechID]['effects/0'] ~= 0 then
		returnString = returnString .. '\n! colspan=4| Effects'
		returnString = returnString .. '\n|-'
		for i = 0, 4 do
			local teffect = TechData[TechID]['effects/' .. i]
			if teffect and teffect ~= '' and teffect ~= 0 then
				effectDescription = EffectDescriptionBuilder.buildDescription({args={teffect,primaryDisplay='All Factions'}})
				if effectDescription and effectDescription ~= '' and effectDescription ~= 'ERROR: No Description' then
					returnString = returnString .. '\n| colspan=4| ' .. effectDescription
				else
					returnString = returnString .. '\n| colspan=4| ' .. teffect
				end
				returnString = returnString .. '\n|-'
			end
		end
	end
	
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Quote'
	returnString = returnString .. '\n|-'
	local techQuote = (TechNames['TITechTemplate.quote.' .. TechID] or 'Error: Missing Quote')
	for leader, leaderName in pairs(FactionLeaders) do
		techQuote = sreplace(techQuote, '{' .. leader .. '}', leaderName)
	end
	techQuote = sreplace(techQuote, '<align=right>', '')
	techQuote = sreplace(techQuote, '<align=right>', '')
	techQuote = sreplace(techQuote, '<align=right>', '')
	techQuote = sreplace(techQuote, '<align=left>', '')
	techQuote = sreplace(techQuote, '<align=left>', '')
	techQuote = sreplace(techQuote, '<align=left>', '')
	returnString = returnString .. '\n| colspan=4 | ' .. techQuote
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Notes'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n| colspan=4 | ' .. TechNotes
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Data Sources'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n| colspan=4 | [[TITechTemplate_CSV]] • [[TIProjectTemplate_CSV]] • [[TIOrgTemplate_CSV]] • [[TITechTemplate_EN]] • [[TIProjectTemplate_EN]] • [[TIOrgTemplate_EN]]'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n! colspan=4 | Related Pages'
	returnString = returnString .. '\n|-'
	returnString = returnString .. '\n| colspan=4 | [[Tech List]] • [[Project List]] • [[Technology]]'
	returnString = returnString .. '\n|-'
	
	returnString = returnString .. '\n|}'

	return returnString
end

--endregion

return TechLister