|
|
| (7 intermediate revisions by the same user not shown) |
| Line 4: |
Line 4: |
| local npcs_data = mw.loadJsonData("Data:NpcData.json") | | local npcs_data = mw.loadJsonData("Data:NpcData.json") |
| local util_module = require('Module:Utilities') | | local util_module = require('Module:Utilities') |
| local lang_module = require('Module:Lang')
| |
|
| |
|
| -- returns the entire data table for a specific NPC, used by other Lua modules | | -- returns the entire data table for a specific NPC, used by other Lua modules |
| function p.get_npc_data(name) | | function p.get_npc_data(name) |
| if not name or name == '' then
| | if not name or name == '' then |
| return nil
| | return nil |
| end
| | end |
| return npcs_data[name]
| | return npcs_data[name] |
| end | | end |
|
| |
|
| -- Retrieves a specific stat value for a given NPC. | | -- Retrieves a specific stat value for a given NPC. Handles both simple and nested calls. |
| --{{#invoke:NpcData|get_npc_var|NPC_KEY|STAT_KEY|SIG_FIGS}}-- | | -- {{#invoke:NpcData|get_npc_var|NPC_KEY|STAT_KEY_1|STAT_KEY_2|...|SIG_FIGS}} |
| p.get_npc_var = function(frame) | | p.get_npc_var = function(frame) |
| -- Get arguments from the #invoke call and trim whitespace
| | -- Safer argument handling for both live and debug environments |
| local args = frame.args
| | local args = {} |
| local npc_name = args[1] and mw.text.trim(args[1]) or nil
| | if frame.getParent then |
| local npc_stat_key = args[2] and mw.text.trim(args[2]) or nil
| | local parent_args = frame:getParent().args |
| local sig_figs = args[3] and mw.text.trim(args[3]) or nil
| | for k, v in pairs(parent_args) do args[k] = v end |
| | end |
| | -- Direct args from #invoke or the debug table overwrite parent args |
| | for k, v in pairs(frame.args) do args[k] = v end |
|
| |
|
| -- Validate required arguments
| | local npc_name = args[1] and mw.text.trim(args[1]) or nil |
| if not npc_name or npc_name == '' then
| | if not npc_name or npc_name == '' then |
| return '<span class="error">Error: NPC name not provided.</span>'
| | return '<span class="error">Error: NPC name not provided.</span>' |
| end
| | end |
| if not npc_stat_key or npc_stat_key == '' then
| |
| return '<span class="error">Error: Stat key not provided.</span>'
| |
| end
| |
|
| |
|
| -- Retrieve the NPC data table
| | local npc = npcs_data[npc_name] |
| local npc = npcs_data[npc_name]
| | if not npc then |
| if not npc then
| | return '<span class="error">Error: NPC "' .. npc_name .. '" not found.</span>' |
| return '<span class="error">Error: NPC "' .. npc_name .. '" not found.</span>'
| | end |
| end
| |
|
| |
|
| -- Get the specific stat value
| | local current_value = npc |
| local var_value = npc[npc_stat_key]
| | local last_key_index = 1 |
| if var_value == nil then
| | local path = {npc_name} -- Track the path for better error messages |
| return '<span class="error">Error: Stat "' .. npc_stat_key .. '" not found for NPC "' .. npc_name .. '".</span>'
| |
| end
| |
|
| |
|
| -- round if a number is provided
| | -- Traverse through the arguments to find the nested value |
| if sig_figs and tonumber(sig_figs) then
| | for i = 2, #args do |
| var_value = util_module.round_to_sig_fig(var_value, sig_figs)
| | local key = args[i] and mw.text.trim(args[i]) or nil |
| if var_value == nil then
| | if not key or key == '' then break end |
| return '<span class="error">Error: Rounding failed for value.</span>'
| |
| end
| |
| end
| |
|
| |
|
| return var_value
| | -- Check if this might be the sig_figs argument (numeric on a non-table) |
| end
| | if tonumber(key) and type(current_value) ~= "table" then |
| | | break |
| -- Retrieves an element from a list (array) within an NPC's data. | | end |
| --{{#invoke:NpcData|get_list_elem|NPC_KEY|LIST_KEY|INDEX}}-- | |
| p.get_list_elem = function(frame)
| |
| local npc_name = frame.args[1] and mw.text.trim(frame.args[1]) or nil
| |
| local var = frame.args[2] and mw.text.trim(frame.args[2]) or nil
| |
| local number_str = frame.args[3] and mw.text.trim(frame.args[3]) or nil
| |
|
| |
| if not npc_name or npc_name == '' then return '<span class="error">Error: NPC name not provided.</span>' end
| |
| if not var or var == '' then return '<span class="error">Error: List variable name not provided.</span>' end
| |
| if not number_str or number_str == '' then return '<span class="error">Error: Index not provided.</span>' end
| |
|
| |
| local number_int = tonumber(number_str)
| |
| if not number_int then return '<span class="error">Error: Invalid index provided. Must be a number.</span>' end
| |
| | |
| local npc = npcs_data[npc_name]
| |
| if not npc then return '<span class="error">Error: NPC "' .. npc_name .. '" not found.</span>' end
| |
|
| |
| local list = npc[var]
| |
| if list == nil or type(list) ~= "table" then return "" end
| |
|
| |
| local element = list[number_int]
| |
| if element == nil then return "" end
| |
|
| |
| return element
| |
| end
| |
| | |
| -- Retrieves an ability key from an NPC's "BoundAbilities" map.
| |
| --{{#invoke:NpcData|get_ability_key|NPC_KEY|SLOT_KEY}}--
| |
| p.get_ability_key = function(frame)
| |
| local npc_name = frame.args[1] and mw.text.trim(frame.args[1]) or nil
| |
| local slot_name = frame.args[2] and mw.text.trim(frame.args[2]) or nil
| |
| | |
| if not npc_name or npc_name == '' then return '<span class="error">Error: NPC name not provided.</span>' end
| |
| if not slot_name or slot_name == '' then return '<span class="error">Error: Slot name not provided.</span>' end
| |
| | |
| local npc_data = npcs_data[npc_name]
| |
| if not npc_data then return '<span class="error">Error: NPC "'..npc_name.. '" not found.</span>' end
| |
|
| |
|
| local bound_abilities_data = npc_data["BoundAbilities"]
| | if type(current_value) ~= "table" then |
| if not bound_abilities_data or type(bound_abilities_data) ~= "table" then
| | return '<span class="error">Error: Invalid path at "' .. table.concat(path, '.') .. '". Tried to index a ' .. type(current_value) .. ' value.</span>' |
| return '<span class="error">Error: NPC "' .. npc_name .. '" has no \'BoundAbilities\' data.</span>'
| | end |
| end
| | |
| | -- Try string key first |
| | local next_value = current_value[key] |
| | |
| | -- If nil, try numeric key |
| | if next_value == nil then |
| | local num_key = tonumber(key) |
| | if num_key then |
| | next_value = current_value[num_key] |
| | end |
| | end |
| | |
| | if next_value == nil then |
| | return '<span class="error">Error: Key "' .. key .. '" not found in path "' .. table.concat(path, '.') .. '".</span>' |
| | end |
| | |
| | current_value = next_value |
| | table.insert(path, key) |
| | last_key_index = i |
| | end |
|
| |
|
| local ability_key = bound_abilities_data[slot_name]
| | -- Handle sig_figs if provided |
| if not ability_key then | | local sig_figs_arg = args[last_key_index + 1] |
| return '<span class="error">Error: Slot "' .. slot_name .. '" not found for NPC "' .. npc_name .. '".</span>'
| | local sig_figs = sig_figs_arg and tonumber(mw.text.trim(sig_figs_arg)) or nil |
| end
| |
| | | |
| return ability_key
| | if sig_figs then |
| end
| | if type(current_value) ~= "number" then |
| | | return '<span class="error">Error: Cannot apply sig_figs to non-numeric value at "' .. table.concat(path, '.') .. '" (type: ' .. type(current_value) .. ').</span>' |
| -- Retrieves a nested value using dot notation (e.g., "Shield.BaseAbsorptionPerSecond")
| | end |
| --{{#invoke:NpcData|get_nested_var|NPC_KEY|PATH|SIG_FIGS}}--
| | current_value = util_module.round_to_sig_fig(current_value, sig_figs) |
| p.get_nested_var = function(frame)
| | if current_value == nil then |
| local args = frame.args
| | return '<span class="error">Error: Rounding failed for value at "' .. table.concat(path, '.') .. '".</span>' |
| local npc_name = args[1] and mw.text.trim(args[1]) or nil
| | end |
| local path = args[2] and mw.text.trim(args[2]) or nil
| | end |
| local sig_figs = args[3] and mw.text.trim(args[3]) or nil
| |
| | |
| if not npc_name or npc_name == '' then
| |
| return '<span class="error">Error: NPC name not provided.</span>'
| |
| end
| |
| if not path or path == '' then
| |
| return '<span class="error">Error: Path not provided.</span>'
| |
| end
| |
| | |
| local npc = npcs_data[npc_name]
| |
| if not npc then
| |
| return '<span class="error">Error: NPC "' .. npc_name .. '" not found.</span>'
| |
| end
| |
| | |
| -- Traverse nested structure
| |
| local value = npc
| |
| for key in string.gmatch(path, '([^.]+)') do
| |
| if type(value) ~= "table" then
| |
| return '<span class="error">Error: Path "' .. path .. '" is invalid.</span>'
| |
| end
| |
| value = value[key]
| |
| if value == nil then
| |
| return '<span class="error">Error: Key "' .. key .. '" not found in path.</span>'
| |
| end
| |
| end
| |
|
| |
|
| -- Apply rounding if needed
| | -- Convert tables/booleans to strings for display |
| if sig_figs and tonumber(sig_figs) then
| | if type(current_value) == "table" then |
| value = util_module.round_to_sig_fig(value, sig_figs)
| | return '<span class="error">Error: Path "' .. table.concat(path, '.') .. '" points to a table/object. Specify a deeper path to get a value.</span>' |
| if value == nil then
| | elseif type(current_value) == "boolean" then |
| return '<span class="error">Error: Rounding failed for value.</span>'
| | return tostring(current_value) |
| end
| | end |
| end
| |
|
| |
|
| return value
| | return current_value |
| end | | end |
|
| |
|
| return p | | return p |