loadRgd and error handling
You can use
pcall
to catch any errors coming out of functions like
loadRgd
, like so:
function at_end()
loaded,rgd = pcall(loadRgd,
[[attrib\attrib\bags\ability_bag.rgd]]
)
if loaded and rgd
-- rgd was loaded
for k in rgd.GameData do print(k) end
else
if rgd
-- rgd is the error message
print("Error: Cannot load RGD. Stack trace:\n"
.. rgd)
else
-- permission denied to load rgds
print "Error: Not permitted to load RGD"
end
end
end
You can also use
xpcall
to get an extended stack trace:
function error_handler(e)
local trace = debug.traceback()
if not trace | e end
trace_parts = trace:split "\n"
trace = ""
for n = #trace_parts, 2, -1
trace = trace .. trace_parts[n]:after"\t" .. "\n"
end
trace_parts = e:split"\r\n"
for _,part in ipairs(trace_parts)
if part ~= ""
trace = trace .. "[" .. part:before" line " ..
"]:" .. part:after" line ":before": " ..
": " .. part:after": " .. "\n"
end
end
return trace
end
function at_end()
loaded,rgd = xpcall([| loadRgd(
[[attrib\attrib\bags\ability_bag.rgd]]
)] , error_handler)
if loaded and rgd
-- rgd was loaded
for k in rgd.GameData do print(k) end
else
if rgd
-- rgd is the error message
print("Error: Cannot load RGD. Stack trace:\n"
.. rgd)
else
-- permission denied to load rgds
print "Error: Not permitted to load RGD"
end
end
end
Access to more than one folder
If you want your macro to work over more than one folder, then you can run it over the main attrib folder and use some magic to access the bits you want. If you place this at the top of your script then you can do all your hard work inside the at_end function.
function each_file(rgd)
local map_part = _G
local key = "filemap"
for _,part in ipairs(rgd.path:lower():after"\\attrib\\"
:split"\\")
map_part = map_part[key]
key = part
end
map_part[key] = rgd
end
function filemap_autotable(t,k)
if filemap_autotable
t[k] = setmetatable({}, {__index = filemap_autotable})
return t[k]
end
end
filemap_autotable(_G, "filemap")
function filemap_folder(path)
local map_part = filemap
for k,part in ipairs(path:lower():split"[/\\]")
map_part = map_part[part]
end
return map_part
end
function pairs_recursive(t)
| [ (state, v1)
local k,v = next(state[#state], v1)
local f = [
if type(v) == "table"
state[#state] = {state[#state], k}
state[1+#state] = v
k,v = next(state[#state])
| 1
elseif type(v) == "nil"
state[#state] = nil
if not state[#state] | nil end
v1 = state[#state][2]
state[#state] = state[#state][1]
k,v = next(state[#state], v1)
| 1
end ]
while f() end
| k,v
], {t}
end
The at_end function then looks something like this:
function at_end()
for filename,rgd in pairs_recursive(filemap.racebps) do
-- do something with RaceBPs RGDs
end
for filename,rgd in pairs_recursive(filemap.ebps.races) do
-- do something with EBPS RGDs
end
end
The DoW DPS macro that comes with mod studio uses this method to great effect.
Back to advanced topics list
This documentation is provided under the GNU General Public License. All trademarks / copyrights are tm/r/c their respective owners.