Module:SoulUnlock: Difference between revisionsGive feedback
m get_max example and parameters now support invoke options |
Gammaton32 (talk | contribs) No edit summary |
||
| (8 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local util_module = require('Module:Utilities') | local util_module = require('Module:Utilities') | ||
local dictionary_module = require('Module:Dictionary') | |||
local soul_unlocks_data = mw.loadJsonData("Data:SoulUnlockData.json") | local soul_unlocks_data = mw.loadJsonData("Data:SoulUnlockData.json") | ||
local localization_map = { | local localization_map = { | ||
[" | ["RequiredSouls"] = "Citadel_Hero_Stats_Souls", | ||
["AbilityUnlocks"] = "Citadel_Player_Level_AbilityUnlock", | ["AbilityUnlocks"] = "Citadel_Player_Level_AbilityUnlock", | ||
["AbilityPoints"] = "guide_upgrades_killing_guardians_header", | ["AbilityPoints"] = "guide_upgrades_killing_guardians_header", | ||
| Line 36: | Line 37: | ||
-- Sum the value, but not for gold because its already summed | -- Sum the value, but not for gold because its already summed | ||
if key == ' | if key == 'RequiredSouls' then | ||
sums[key] = num | sums[key] = num | ||
else | else | ||
| Line 76: | Line 77: | ||
ret = ret .. "Index" .. i .. ": " | ret = ret .. "Index" .. i .. ": " | ||
for key, value in pairs(data) do | for key, value in pairs(data) do | ||
ret = ret .. string.format(" %s:%s, ", p.localize(key), | local display_value = value | ||
--Add 600 | |||
if key == "RequiredSouls" then | |||
display_value = display_value + 600 | |||
end | |||
ret = ret .. string.format(" %s:%s, ", p.localize(key), display_value) | |||
end | end | ||
ret = ret .. '<br>' | ret = ret .. '<br>' | ||
| Line 97: | Line 103: | ||
last_index = #accumulated_data | last_index = #accumulated_data | ||
last_value = accumulated_data[last_index][soul_unlock_key] | last_value = accumulated_data[last_index][soul_unlock_key] | ||
return | --Add 600 | ||
if soul_unlock_key == "RequiredSouls" then | |||
return last_value + 600 | |||
else | |||
return last_value | |||
end | |||
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'] | |||
--Add 600 | |||
local souls_str = '{{Souls|' .. (required_souls + 600) .. '}}' | |||
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 | end | ||
return p | return p | ||
Latest revision as of 06:09, 22 November 2025
Overview
[edit source]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
[edit source]get_max
[edit source]Retrieve's maximum value for a given key in the accumulated data
Examples
[edit source]{{#invoke:SoulUnlock|get_max|RequiredSouls}} 49200
{{#invoke:SoulUnlock|get_max|PowerIncrease}} 35
{{#invoke:SoulUnlock|get_max|AbilityUnlocks}} 4
{{#invoke:SoulUnlock|get_max|AbilityPoints}} 32
localize
[edit source]Localize a key as its stored to the current language using Module:Lang.
Examples
[edit source]{{#invoke:SoulUnlock|localize|RequiredSouls}} Souls
{{#invoke:SoulUnlock|localize|PowerIncrease}} Boons
{{#invoke:SoulUnlock|localize|AbilityUnlocks}} Ability Unlock
{{#invoke:SoulUnlock|localize|AbilityPoints}} Ability Points
write_accumulated
[edit source]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
[edit source]{{#invoke:SoulUnlock|write_accumulated}}
Index1: Souls:600, Ability Unlock:1,
Index2: Ability Unlock:1, Boons:1, Souls:800, Ability Points:1,
Index3: Ability Unlock:2, Boons:2, Souls:1100, Ability Points:1,
Index4: Ability Unlock:2, Boons:3, Souls:1500, Ability Points:2,
Index5: Ability Unlock:3, Boons:4, Souls:2000, Ability Points:2,
Index6: Ability Unlock:3, Boons:5, Souls:2600, Ability Points:3,
Index7: Ability Unlock:3, Boons:6, Souls:3200, Ability Points:4,
Index8: Ability Unlock:4, Boons:7, Souls:3800, Ability Points:4,
Index9: Ability Unlock:4, Boons:8, Souls:4500, Ability Points:5,
Index10: Ability Unlock:4, Boons:9, Souls:5200, Ability Points:6,
Index11: Ability Unlock:4, Boons:10, Souls:5900, Ability Points:7,
Index12: Ability Unlock:4, Boons:11, Souls:6600, Ability Points:8,
Index13: Ability Unlock:4, Boons:12, Souls:7400, Ability Points:9,
Index14: Ability Unlock:4, Boons:13, Souls:8200, Ability Points:10,
Index15: Ability Unlock:4, Boons:14, Souls:9000, Ability Points:11,
Index16: Ability Unlock:4, Boons:15, Souls:9800, Ability Points:12,
Index17: Ability Unlock:4, Boons:16, Souls:10700, Ability Points:13,
Index18: Ability Unlock:4, Boons:17, Souls:11600, Ability Points:14,
Index19: Ability Unlock:4, Boons:18, Souls:12500, Ability Points:15,
Index20: Ability Unlock:4, Boons:19, Souls:13400, Ability Points:16,
Index21: Ability Unlock:4, Boons:20, Souls:14400, Ability Points:17,
Index22: Ability Unlock:4, Boons:21, Souls:15500, Ability Points:18,
Index23: Ability Unlock:4, Boons:22, Souls:16700, Ability Points:19,
Index24: Ability Unlock:4, Boons:23, Souls:18000, Ability Points:20,
Index25: Ability Unlock:4, Boons:24, Souls:19500, Ability Points:21,
Index26: Ability Unlock:4, Boons:25, Souls:21200, Ability Points:22,
Index27: Ability Unlock:4, Boons:26, Souls:23100, Ability Points:23,
Index28: Ability Unlock:4, Boons:27, Souls:25200, Ability Points:24,
Index29: Ability Unlock:4, Boons:28, Souls:27500, Ability Points:25,
Index30: Ability Unlock:4, Boons:29, Souls:30000, Ability Points:26,
Index31: Ability Unlock:4, Boons:30, Souls:32700, Ability Points:27,
Index32: Ability Unlock:4, Boons:31, Souls:35600, Ability Points:28,
Index33: Ability Unlock:4, Boons:32, Souls:38700, Ability Points:29,
Index34: Ability Unlock:4, Boons:33, Souls:42000, Ability Points:30,
Index35: Ability Unlock:4, Boons:34, Souls:45500, Ability Points:31,
Index36: Ability Unlock:4, Boons:35, Souls:49200, Ability Points:32,
write_table
[edit source]Example
[edit source]| Individual | Accumulative | |||||
|---|---|---|---|---|---|---|
| Souls | Boons | Ability Unlock | Ability Points | Boons | Ability Unlock | Ability Points |
| {{Souls|600}} | {{Tick}} | 1 | ||||
| {{Souls|800}} | {{Tick}} | {{Tick}} | 1 | 1 | 1 | |
| {{Souls|1100}} | {{Tick}} | {{Tick}} | 2 | 2 | 1 | |
| {{Souls|1500}} | {{Tick}} | {{Tick}} | 3 | 2 | 2 | |
| {{Souls|2000}} | {{Tick}} | {{Tick}} | 4 | 3 | 2 | |
| {{Souls|2600}} | {{Tick}} | {{Tick}} | 5 | 3 | 3 | |
| {{Souls|3200}} | {{Tick}} | {{Tick}} | 6 | 3 | 4 | |
| {{Souls|3800}} | {{Tick}} | {{Tick}} | 7 | 4 | 4 | |
| {{Souls|4500}} | {{Tick}} | {{Tick}} | 8 | 4 | 5 | |
| {{Souls|5200}} | {{Tick}} | {{Tick}} | 9 | 4 | 6 | |
| {{Souls|5900}} | {{Tick}} | {{Tick}} | 10 | 4 | 7 | |
| {{Souls|6600}} | {{Tick}} | {{Tick}} | 11 | 4 | 8 | |
| {{Souls|7400}} | {{Tick}} | {{Tick}} | 12 | 4 | 9 | |
| {{Souls|8200}} | {{Tick}} | {{Tick}} | 13 | 4 | 10 | |
| {{Souls|9000}} | {{Tick}} | {{Tick}} | 14 | 4 | 11 | |
| {{Souls|9800}} | {{Tick}} | {{Tick}} | 15 | 4 | 12 | |
| {{Souls|10700}} | {{Tick}} | {{Tick}} | 16 | 4 | 13 | |
| {{Souls|11600}} | {{Tick}} | {{Tick}} | 17 | 4 | 14 | |
| {{Souls|12500}} | {{Tick}} | {{Tick}} | 18 | 4 | 15 | |
| {{Souls|13400}} | {{Tick}} | {{Tick}} | 19 | 4 | 16 | |
| {{Souls|14400}} | {{Tick}} | {{Tick}} | 20 | 4 | 17 | |
| {{Souls|15500}} | {{Tick}} | {{Tick}} | 21 | 4 | 18 | |
| {{Souls|16700}} | {{Tick}} | {{Tick}} | 22 | 4 | 19 | |
| {{Souls|18000}} | {{Tick}} | {{Tick}} | 23 | 4 | 20 | |
| {{Souls|19500}} | {{Tick}} | {{Tick}} | 24 | 4 | 21 | |
| {{Souls|21200}} | {{Tick}} | {{Tick}} | 25 | 4 | 22 | |
| {{Souls|23100}} | {{Tick}} | {{Tick}} | 26 | 4 | 23 | |
| {{Souls|25200}} | {{Tick}} | {{Tick}} | 27 | 4 | 24 | |
| {{Souls|27500}} | {{Tick}} | {{Tick}} | 28 | 4 | 25 | |
| {{Souls|30000}} | {{Tick}} | {{Tick}} | 29 | 4 | 26 | |
| {{Souls|32700}} | {{Tick}} | {{Tick}} | 30 | 4 | 27 | |
| {{Souls|35600}} | {{Tick}} | {{Tick}} | 31 | 4 | 28 | |
| {{Souls|38700}} | {{Tick}} | {{Tick}} | 32 | 4 | 29 | |
| {{Souls|42000}} | {{Tick}} | {{Tick}} | 33 | 4 | 30 | |
| {{Souls|45500}} | {{Tick}} | {{Tick}} | 34 | 4 | 31 | |
| {{Souls|49200}} | {{Tick}} | {{Tick}} | 35 | 4 | 32 | |
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
local display_value = value
--Add 600
if key == "RequiredSouls" then
display_value = display_value + 600
end
ret = ret .. string.format(" %s:%s, ", p.localize(key), display_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]
--Add 600
if soul_unlock_key == "RequiredSouls" then
return last_value + 600
else
return last_value
end
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']
--Add 600
local souls_str = '{{Souls|' .. (required_souls + 600) .. '}}'
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