Editing Module:NpcData

Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
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.
-- Retrieves a specific stat value for a given NPC. Handles both simple and nested calls.
-- {{#invoke:NpcData|get_npc_var|NPC_KEY|STAT_KEY_1|STAT_KEY_2|...|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)
    -- Safer argument handling for both live and debug environments
-- Use pcall to handle both template and module calls gracefully
    local args = {}
local parent_args = frame:getParent() and frame:getParent().args or {}
    if frame.getParent then
local direct_args = frame.args
        local parent_args = frame:getParent().args
local args = {}
        for k, v in pairs(parent_args) do args[k] = v end
-- Merge args, giving direct #invoke args priority
    end
for k, v in pairs(parent_args) do args[k] = v end
    -- Direct args from #invoke or the debug table overwrite parent args
for k, v in pairs(direct_args) do args[k] = v end
    for k, v in pairs(frame.args) do args[k] = v end


    local npc_name = args[1] and mw.text.trim(args[1]) or nil
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


    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


    local current_value = npc
local current_value = npc
    local last_key_index = 1
local last_key_index = 1
    local path = {npc_name} -- Track the path for better error messages


    -- Traverse through the arguments to find the nested value
-- Traverse through the arguments to find the nested value
    for i = 2, #args do
for i = 2, #args do
        local key = args[i] and mw.text.trim(args[i]) or nil
local key = args[i] and mw.text.trim(args[i]) or nil
        if not key or key == '' then break end
if not key or key == '' then break end


        -- Check if this might be the sig_figs argument (numeric on a non-table)
-- Stop traversing if the next key looks like a number for rounding
        if tonumber(key) and type(current_value) ~= "table" then
if tonumber(key) then
            break
break
        end
end


        if type(current_value) ~= "table" then
if type(current_value) ~= "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: Invalid path. Tried to index a non-table value.</span>'
        end
end
       
        -- Try string key first
current_value = current_value[key]
        local next_value = current_value[key]
if current_value == nil then
       
return '<span class="error">Error: Key "' .. key .. '" not found.</span>'
        -- If nil, try numeric key
end
        if next_value == nil then
last_key_index = i
            local num_key = tonumber(key)
end
            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


    -- Handle sig_figs if provided
-- Determine if a rounding value was provided
    local sig_figs_arg = args[last_key_index + 1]
local sig_figs_arg = args[last_key_index + 1]
    local sig_figs = sig_figs_arg and tonumber(mw.text.trim(sig_figs_arg)) or nil
local sig_figs = sig_figs_arg and tonumber(mw.text.trim(sig_figs_arg)) or nil
   
    if sig_figs then
if sig_figs then
        if type(current_value) ~= "number" then
current_value = util_module.round_to_sig_fig(current_value, sig_figs)
            return '<span class="error">Error: Cannot apply sig_figs to non-numeric value at "' .. table.concat(path, '.') .. '" (type: ' .. type(current_value) .. ').</span>'
if current_value == nil then
        end
return '<span class="error">Error: Rounding failed for value.</span>'
        current_value = util_module.round_to_sig_fig(current_value, sig_figs)
end
        if current_value == nil then
end
            return '<span class="error">Error: Rounding failed for value at "' .. table.concat(path, '.') .. '".</span>'
        end
    end


    -- Convert tables/booleans to strings for display
return current_value
    if type(current_value) == "table" then
end
        return '<span class="error">Error: Path "' .. table.concat(path, '.') .. '" points to a table/object. Specify a deeper path to get a value.</span>'
 
    elseif type(current_value) == "boolean" then
-- Retrieves an element from a list (array) within an NPC's data.
        return tostring(current_value)
--{{#invoke:NpcData|get_list_elem|NPC_KEY|LIST_KEY|INDEX}}--
    end
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 a nested value using dot notation (e.g., "Shield.BaseAbsorptionPerSecond")
--{{#invoke:NpcData|get_nested_var|NPC_KEY|PATH|SIG_FIGS}}--
p.get_nested_var = function(frame)
local args = frame.args
local npc_name = args[1] and mw.text.trim(args[1]) or nil
local path = args[2] and mw.text.trim(args[2]) or nil
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
    -- try first with the raw key, then with a number conversion
    local next = value[key] or value[tonumber(key)] or value[tostring(key)]
    if next == nil then
        return '<span class="error">Error: Key "' .. key .. '" not found in path.</span>'
    end
    value = next
end
 
-- Apply rounding if needed
if sig_figs and tonumber(sig_figs) then
value = util_module.round_to_sig_fig(value, sig_figs)
if value == nil then
return '<span class="error">Error: Rounding failed for value.</span>'
end
end


    return current_value
return value
end
end


return p
return p
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template

Pages included on this page: