Module:SoulUnlock

From The Deadlock Wiki
Revision as of 04:57, 29 October 2024 by Sur (talk | contribs) (translate Individual and Accumulative in write_table)
Jump to navigation Jump to search

Overview

Data for what is unlocked at each increment of Souls. Data is stored and loaded from Data:SoulUnlockData.json.

The data is accumulated into another format that is used by the currently written functions.

Functions

get_max

Retrieve's maximum value for a given key in the accumulated data

Examples

{{#invoke:SoulUnlock|get_max|RequiredSouls}} 48600
{{#invoke:SoulUnlock|get_max|PowerIncrease}} 35
{{#invoke:SoulUnlock|get_max|AbilityUnlocks}} 4
{{#invoke:SoulUnlock|get_max|AbilityPoints}} 32

localize

Localize a key as its stored to the current language using Module:Lang.

Examples

{{#invoke:SoulUnlock|localize|RequiredSouls}} Souls
{{#invoke:SoulUnlock|localize|PowerIncrease}} Boons
{{#invoke:SoulUnlock|localize|AbilityUnlocks}} Ability Unlock
{{#invoke:SoulUnlock|localize|AbilityPoints}} Ability Points

write_accumulated

Writes the accumulated data to wikitext. Not a format that is ready to be displayed on a wiki page yet. Used for debugging for any lua editors working off of the accumulated data as opposed to the original data.

Note: the keys outputted are localized to english. See the localization map at the top of the Module source.

Example

{{#invoke:SoulUnlock|write_accumulated}}
Index1: Souls:0, Ability Unlock:1,
Index2: Ability Unlock:1, Boons:1, Souls:200, Ability Points:1,
Index3: Ability Unlock:2, Boons:2, Souls:500, Ability Points:1,
Index4: Ability Unlock:2, Boons:3, Souls:900, Ability Points:2,
Index5: Ability Unlock:3, Boons:4, Souls:1400, Ability Points:2,
Index6: Ability Unlock:3, Boons:5, Souls:2000, Ability Points:3,
Index7: Ability Unlock:3, Boons:6, Souls:2600, Ability Points:4,
Index8: Ability Unlock:4, Boons:7, Souls:3200, Ability Points:4,
Index9: Ability Unlock:4, Boons:8, Souls:3900, Ability Points:5,
Index10: Ability Unlock:4, Boons:9, Souls:4600, Ability Points:6,
Index11: Ability Unlock:4, Boons:10, Souls:5300, Ability Points:7,
Index12: Ability Unlock:4, Boons:11, Souls:6000, Ability Points:8,
Index13: Ability Unlock:4, Boons:12, Souls:6800, Ability Points:9,
Index14: Ability Unlock:4, Boons:13, Souls:7600, Ability Points:10,
Index15: Ability Unlock:4, Boons:14, Souls:8400, Ability Points:11,
Index16: Ability Unlock:4, Boons:15, Souls:9200, Ability Points:12,
Index17: Ability Unlock:4, Boons:16, Souls:10100, Ability Points:13,
Index18: Ability Unlock:4, Boons:17, Souls:11000, Ability Points:14,
Index19: Ability Unlock:4, Boons:18, Souls:11900, Ability Points:15,
Index20: Ability Unlock:4, Boons:19, Souls:12800, Ability Points:16,
Index21: Ability Unlock:4, Boons:20, Souls:13800, Ability Points:17,
Index22: Ability Unlock:4, Boons:21, Souls:14900, Ability Points:18,
Index23: Ability Unlock:4, Boons:22, Souls:16100, Ability Points:19,
Index24: Ability Unlock:4, Boons:23, Souls:17400, Ability Points:20,
Index25: Ability Unlock:4, Boons:24, Souls:18900, Ability Points:21,
Index26: Ability Unlock:4, Boons:25, Souls:20600, Ability Points:22,
Index27: Ability Unlock:4, Boons:26, Souls:22500, Ability Points:23,
Index28: Ability Unlock:4, Boons:27, Souls:24600, Ability Points:24,
Index29: Ability Unlock:4, Boons:28, Souls:26900, Ability Points:25,
Index30: Ability Unlock:4, Boons:29, Souls:29400, Ability Points:26,
Index31: Ability Unlock:4, Boons:30, Souls:32100, Ability Points:27,
Index32: Ability Unlock:4, Boons:31, Souls:35000, Ability Points:28,
Index33: Ability Unlock:4, Boons:32, Souls:38100, Ability Points:29,
Index34: Ability Unlock:4, Boons:33, Souls:41400, Ability Points:30,
Index35: Ability Unlock:4, Boons:34, Souls:44900, Ability Points:31,
Index36: Ability Unlock:4, Boons:35, Souls:48600, Ability Points:32,

write_table

Example

IndividualAccumulative
SoulsBoonsAbility UnlockAbility PointsBoonsAbility UnlockAbility Points
{{Souls|0}}{{Tick}}1
{{Souls|200}}{{Tick}}{{Tick}}111
{{Souls|500}}{{Tick}}{{Tick}}221
{{Souls|900}}{{Tick}}{{Tick}}322
{{Souls|1400}}{{Tick}}{{Tick}}432
{{Souls|2000}}{{Tick}}{{Tick}}533
{{Souls|2600}}{{Tick}}{{Tick}}634
{{Souls|3200}}{{Tick}}{{Tick}}744
{{Souls|3900}}{{Tick}}{{Tick}}845
{{Souls|4600}}{{Tick}}{{Tick}}946
{{Souls|5300}}{{Tick}}{{Tick}}1047
{{Souls|6000}}{{Tick}}{{Tick}}1148
{{Souls|6800}}{{Tick}}{{Tick}}1249
{{Souls|7600}}{{Tick}}{{Tick}}13410
{{Souls|8400}}{{Tick}}{{Tick}}14411
{{Souls|9200}}{{Tick}}{{Tick}}15412
{{Souls|10100}}{{Tick}}{{Tick}}16413
{{Souls|11000}}{{Tick}}{{Tick}}17414
{{Souls|11900}}{{Tick}}{{Tick}}18415
{{Souls|12800}}{{Tick}}{{Tick}}19416
{{Souls|13800}}{{Tick}}{{Tick}}20417
{{Souls|14900}}{{Tick}}{{Tick}}21418
{{Souls|16100}}{{Tick}}{{Tick}}22419
{{Souls|17400}}{{Tick}}{{Tick}}23420
{{Souls|18900}}{{Tick}}{{Tick}}24421
{{Souls|20600}}{{Tick}}{{Tick}}25422
{{Souls|22500}}{{Tick}}{{Tick}}26423
{{Souls|24600}}{{Tick}}{{Tick}}27424
{{Souls|26900}}{{Tick}}{{Tick}}28425
{{Souls|29400}}{{Tick}}{{Tick}}29426
{{Souls|32100}}{{Tick}}{{Tick}}30427
{{Souls|35000}}{{Tick}}{{Tick}}31428
{{Souls|38100}}{{Tick}}{{Tick}}32429
{{Souls|41400}}{{Tick}}{{Tick}}33430
{{Souls|44900}}{{Tick}}{{Tick}}34431
{{Souls|48600}}{{Tick}}{{Tick}}35432
IndividualAccumulative
SoulsBoonsAbility UnlockAbility PointsBoonsAbility UnlockAbility Points
Souls0Yes1
Souls200YesYes111
Souls500YesYes221
Souls900YesYes322
Souls1400YesYes432
Souls2000YesYes533
Souls2600YesYes634
Souls3200YesYes744
Souls3900YesYes845
Souls4600YesYes946
Souls5300YesYes1047
Souls6000YesYes1148
Souls6800YesYes1249
Souls7600YesYes13410
Souls8400YesYes14411
Souls9200YesYes15412
Souls10100YesYes16413
Souls11000YesYes17414
Souls11900YesYes18415
Souls12800YesYes19416
Souls13800YesYes20417
Souls14900YesYes21418
Souls16100YesYes22419
Souls17400YesYes23420
Souls18900YesYes24421
Souls20600YesYes25422
Souls22500YesYes26423
Souls24600YesYes27424
Souls26900YesYes28425
Souls29400YesYes29426
Souls32100YesYes30427
Souls35000YesYes31428
Souls38100YesYes32429
Souls41400YesYes33430
Souls44900YesYes34431
Souls48600YesYes35432

local p = {}
local util_module = require('Module:Utilities')
local dictionary_module = require('Module:Dictionary')
local soul_unlocks_data = mw.loadJsonData("Data:SoulUnlockData.json")
local localization_map = {
	["RequiredSouls"] = "Citadel_Hero_Stats_Souls",
	["AbilityUnlocks"] = "Citadel_Player_Level_AbilityUnlock",
	["AbilityPoints"] = "guide_upgrades_killing_guardians_header",
	["PowerIncrease"] = "Citadel_Player_Level_PowerIncreases"
}
local lang_module = require('Module:Lang')

-- Accumulate the data from a list of entries of unlocks, AP, and PI's, to a hash with the # of each
local function accumulate() 
	local accumulated_data = {} --holds the sum at each gold count
	local sums = {} --holds only the current sums
	
	for i, su_data in ipairs(soul_unlocks_data) do
		for key, value in pairs(su_data) do
			-- Determine how many to increase sum by
			local num
			if type(value) == 'boolean' then 
				if value == true then
					num = 1
				else
					num = 0
				end
			elseif type(value) == 'number' then 
				num = value 
			else
				return "Module:SoulUnlock.accumulate() error, invalid value type"
			end
			
			
			-- Start at 0
			if sums[key] == nil then sums[key] = 0 end
			
			-- Sum the value, but not for gold because its already summed
			if key == 'RequiredSouls' then
				sums[key] = num
			else
				sums[key] = sums[key] + num
			end
		end
		
		-- Add the current sum to accumulated_data
		table.insert(accumulated_data, util_module.deep_copy(sums))
	end
	
	return accumulated_data
end

local accumulated_data = accumulate()

function p.localize(soul_unlock_key)
	-- If called internally (direct Lua call), args will be passed directly.
    -- If called from wikitext, `soul_unlock_key` will be the `frame` object, and we get args from `frame.args`.

    -- Handle the case where it's called via #invoke (i.e., from wikitext)
    if type(soul_unlock_key) == "table" and soul_unlock_key.args then
        local frame = soul_unlock_key
        soul_unlock_key = frame.args[1]
    end
	
	localization_key = localization_map[soul_unlock_key]
	if localization_key == nil then 
		return string.format("soul_unlock_key %s not in localization_map", soul_unlock_key)
	end
	
	-- Localize, nil for lang override, english string for fallback
	return lang_module.get_string(localization_key, nil, 'en')
end

function p.write_accumulated()
	ret = ""
	for i, data in pairs(accumulated_data) do
		ret = ret .. "Index" .. i .. ": "
		for key, value in pairs(data) do
			ret = ret .. string.format("  %s:%s, ", p.localize(key), value)	
		end
		ret = ret .. '<br>'
	end
	return ret
	--return accumulated_data['0']['AbilityUnlocks']
end

-- Retrieve a certain stat's value at max souls
function p.get_max(soul_unlock_key)
	-- If called internally (direct Lua call), args will be passed directly.
    -- If called from wikitext, `soul_unlock_key` will be the `frame` object, and we get args from `frame.args`.

    -- Handle the case where it's called via #invoke (i.e., from wikitext)
    if type(soul_unlock_key) == "table" and soul_unlock_key.args then
        local frame = soul_unlock_key
        soul_unlock_key = frame.args[1]
    end
	
	last_index = #accumulated_data
	last_value = accumulated_data[last_index][soul_unlock_key]
	return last_value
end

function to_tick(bool)
	if bool == nil or not bool then
		return ''
	else
		return '{{Tick}}'
	end
end

function p.write_table(frame)
	local debug_mode = frame.args['debug_mode']
	if debug_mode == nil then debug_mode = false end
	
	local ret = ''
	
	-- Add header categories
	local tr = ''
	tr = tr .. '<th>' .. '' .. '</th>'
	tr = tr .. '<th colspan="3">' .. dictionary_module.translate('Individual') .. '</th>'
	tr = tr .. '<th colspan="3">' .. dictionary_module.translate('Accumulative') .. '</th>'
	ret = ret .. '<tr>' .. tr .. '</tr>'
	
	-- Add header record, will be soul + each other record twice
	local required_souls_header = '<th>' .. p.localize('RequiredSouls') .. '</th>'
	local non_souls_tr = ''
	for su_key, lang_key in pairs(localization_map) do
		if su_key ~= 'RequiredSouls' then
			non_souls_tr = non_souls_tr .. '<th>' .. p.localize(su_key) .. '</th>'
		end
	end
	local tr = '<tr>' .. required_souls_header .. non_souls_tr .. non_souls_tr .. '</tr>'
	ret = ret .. tr
	
	-- Add data agg_records
	for i, agg_record in ipairs(accumulated_data) do
		local tr = ''
		
		-- Retrieve souls agg_record
		local required_souls = agg_record['RequiredSouls']
		local souls_str = '{{Souls|' .. required_souls .. '}}'
		tr = tr .. '<td>' .. souls_str .. '</td>'
		
		-- Retrieve non-aggregate agg_record
		local non_agg_record = soul_unlocks_data[i]
		for su_key, lang_key in pairs(localization_map) do
			if su_key ~= 'RequiredSouls' then
				local value = to_tick(non_agg_record[su_key])
				
				td = '<td>' .. value .. '</td>'
				tr = tr .. td
			end
		end
		
		-- Retrieve aggregate agg_record
		for su_key, lang_key in pairs(localization_map) do
			if su_key ~= 'RequiredSouls' then
				local value = agg_record[su_key]
				
				-- Display blank instead of nil if missing
				if value == nil then value = '' end
				
				td = '<td>' .. value .. '</td>'
				tr = tr .. td
			end
		end
		
		ret	= ret .. '<tr>' .. tr .. '</tr>'
	end
	
	ret = '<table class="wikitable defaultcenter" style="text-align:center">' .. ret .. '</table>'
	
	if debug_mode then
		return ret
	else
		return frame:preprocess(ret)
	end
end

return p