diff --git a/autogen/autogen.sh b/autogen/autogen.sh
index 9459f4d61..4036b217a 100755
--- a/autogen/autogen.sh
+++ b/autogen/autogen.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
python3 ./autogen/gen_math.py $1
+python3 ./autogen/convert_functions.py $1
python3 ./autogen/convert_structs.py $1
python3 ./autogen/gen_hooks.py $1
-python3 ./autogen/convert_functions.py $1
python3 ./autogen/convert_constants.py $1
python3 ./autogen/extract_display_lists.py $1
diff --git a/autogen/common.py b/autogen/common.py
index 2a76f2dd2..9f3ad5714 100644
--- a/autogen/common.py
+++ b/autogen/common.py
@@ -4,7 +4,8 @@ from vec_types import *
usf_types = ['u8', 'u16', 'u32', 'u64', 's8', 's16', 's32', 's64', 'f32', 'f64']
vec_types = list(VEC_TYPES.keys())
-typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory']
+typedef_pointers = ['BehaviorScript', 'ObjectAnimPointer', 'Collision', 'LevelScript', 'Trajectory', 'Texture']
+cobject_function_identifier = 'FUNCTION'
type_mappings = {
'char': 's8',
@@ -117,6 +118,12 @@ def translate_type_to_lvt(ptype, allowArrays=False):
if ptype == "LuaFunction":
return "LVT_LUAFUNCTION"
+ if ptype == "LuaTable":
+ return "LVT_LUATABLE"
+
+ if ptype == cobject_function_identifier:
+ return "LVT_FUNCTION"
+
if "struct" in ptype:
if pointerLvl > 1:
return "LVT_???"
@@ -194,6 +201,12 @@ def translate_type_to_lot(ptype, allowArrays=True):
if ptype == 'LuaFunction':
return 'LOT_NONE'
+ if ptype == 'LuaTable':
+ return 'LOT_NONE'
+
+ if ptype == cobject_function_identifier:
+ return 'LOT_NONE'
+
if ptype in override_types:
return 'LOT_' + ptype.upper()
@@ -280,6 +293,12 @@ def translate_type_to_lua(ptype):
if ptype == 'LuaFunction':
return '`Lua Function` ()', None
+ if ptype == 'LuaTable':
+ return '`table`', None
+
+ if ptype == cobject_function_identifier:
+ return cobject_function_identifier, None
+
if ptype.count('*') == 1 and '???' not in translate_type_to_lvt(ptype):
ptype = ptype.replace('const', '').replace('*', '').strip()
s = '`Pointer` <`%s`>' % translate_type_to_lua(ptype)[0].replace('`', '').strip()
diff --git a/autogen/convert_constants.py b/autogen/convert_constants.py
index 615b442fe..f3939d1cc 100644
--- a/autogen/convert_constants.py
+++ b/autogen/convert_constants.py
@@ -67,7 +67,7 @@ exclude_constants = {
"src/pc/djui/djui_console.h": [ "CONSOLE_MAX_TMP_BUFFER" ],
"src/pc/lua/smlua_hooks.h": [ "MAX_HOOKED_MOD_MENU_ELEMENTS", "^HOOK_RETURN_.*", "^ACTION_HOOK_.*", "^MOD_MENU_ELEMENT_.*" ],
"src/pc/djui/djui_panel_menu.h": [ "RAINBOW_TEXT_LEN" ],
- "src/pc/mods/mod_fs.h": [ "MOD_FS_DIRECTORY", "MOD_FS_EXTENSION", "MOD_FS_VERSION", "INT_TYPE_MAX", "FLOAT_TYPE_MAX", "FILE_SEEK_MAX" ],
+ "src/pc/mods/mod_fs.h": [ "INT_TYPE_MAX", "FLOAT_TYPE_MAX", "FILE_SEEK_MAX" ],
}
include_constants = {
@@ -139,6 +139,7 @@ defined_values = {
'VERSION_JP': False,
'VERSION_SH': False,
'F3DEX_GBI_2': True,
+ 'DEVELOPMENT': False,
}
############################################################################
@@ -255,15 +256,17 @@ def process_define(filename, line, inIfBlock):
val = val.replace('(u8)', '')
val = val.replace('(u64)', '')
val = re.sub(r'\.\d+f', '', val)
+ val = val.strip()
- for p in val.split(' '):
- if p.startswith('0x'):
- continue
- p = re.sub(r'0x[a-fA-F0-9]+', '', p)
- if re.search(r'[a-z]', p) != None and "VERSION_TEXT" not in line and "SM64COOPDX_VERSION" not in line:
- if 'gCurrentObject' not in line and verbose:
- print('UNRECOGNIZED DEFINE: ' + line)
- return None
+ if not (val.startswith('"') and val.endswith('"') and '"' not in val[1:-1]):
+ for p in val.split(' '):
+ if p.startswith('0x'):
+ continue
+ p = re.sub(r'0x[a-fA-F0-9]+', '', p)
+ if re.search(r'[a-z]', p) != None and "VERSION_TEXT" not in line and "SM64COOPDX_VERSION" not in line:
+ if 'gCurrentObject' not in line and verbose:
+ print('UNRECOGNIZED DEFINE: ' + line)
+ return None
if not allowed_identifier(filename, ident):
return None
diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py
index 8f0e8758a..f886f43e0 100644
--- a/autogen/convert_functions.py
+++ b/autogen/convert_functions.py
@@ -138,6 +138,8 @@ override_disallowed_functions = {
"src/game/first_person_cam.h": [ "first_person_update" ],
"src/pc/lua/utils/smlua_collision_utils.h": [ "collision_find_surface_on_ray" ],
"src/engine/behavior_script.h": [ "stub_behavior_script_2", "cur_obj_update" ],
+ "src/pc/mods/mod_storage.h": [ "mod_storage_shutdown" ],
+ "src/pc/mods/mod_fs.h": [ "mod_fs_read_file_from_uri", "mod_fs_shutdown" ],
"src/pc/utils/misc.h": [ "str_.*", "file_get_line", "delta_interpolate_(normal|rgba|mtx)", "detect_and_skip_mtx_interpolation", "precise_delay_f64" ],
"src/engine/lighting_engine.h": [ "le_calculate_vertex_lighting", "le_clear", "le_shutdown" ],
}
@@ -813,6 +815,8 @@ def build_param(fid, param, i):
return ' %s %s = smlua_to_bytestring(L, %d);\n' % (ptype, pid, i)
elif ptype == 'LuaFunction':
return ' %s %s = smlua_to_lua_function(L, %d);\n' % (ptype, pid, i)
+ elif ptype == 'LuaTable':
+ return ' %s %s = smlua_to_lua_table(L, %d);\n' % (ptype, pid, i)
elif translate_type_to_lot(ptype) == 'LOT_POINTER':
lvt = translate_type_to_lvt(ptype)
return ' %s %s = (%s)smlua_to_cpointer(L, %d, %s);\n' % (ptype, pid, ptype, i, lvt)
@@ -868,6 +872,8 @@ def build_call(function):
lfunc = 'lua_pushstring'
elif ftype == 'ByteString':
lfunc = 'smlua_push_bytestring'
+ elif ftype == 'LuaTable':
+ lfunc = 'smlua_push_lua_table'
elif translate_type_to_lot(ftype) == 'LOT_POINTER':
lvt = translate_type_to_lvt(ftype)
return ' smlua_push_pointer(L, %s, (void*)%s, NULL);\n' % (lvt, ccall)
diff --git a/autogen/convert_structs.py b/autogen/convert_structs.py
index c8af5f8e1..eb5a2ced6 100644
--- a/autogen/convert_structs.py
+++ b/autogen/convert_structs.py
@@ -96,6 +96,7 @@ override_field_invisible = {
"Object": [ "firstSurface" ],
"Animation": [ "unusedBoneCount" ],
"ModAudio": [ "sound", "decoder", "buffer", "bufferSize", "sampleCopiesTail" ],
+ "Painting": [ "normalDisplayList", "textureMaps", "rippleDisplayList", "ripples" ],
"DialogEntry": [ "str" ],
"ModFsFile": [ "data", "capacity" ],
"ModFs": [ "files" ],
@@ -141,6 +142,7 @@ override_field_immutable = {
"DialogEntry": [ "unused", "linesPerBox", "leftOffset", "width", "str", "text", "replaced"],
"ModFsFile": [ "*" ],
"ModFs": [ "*" ],
+ "StaticObjectCollision": [ "*" ],
}
override_field_version_excludes = {
@@ -321,6 +323,14 @@ def parse_struct(struct_str, sortFields = False):
field['identifier'] = field_id.strip()
field['field_str'] = field_str
+ # handle function members
+ if field['type'].startswith(cobject_function_identifier):
+ field_function = field['identifier']
+ field_type, field_id = field['type'].split()
+ field['type'] = field_type.strip()
+ field['identifier'] = field_id.strip('"').strip()
+ field['function'] = field_function.strip()
+
struct['fields'].append(field)
if identifier == 'Object':
@@ -484,6 +494,9 @@ def get_struct_field_info(struct, field):
if fid in override_field_mutable[sid] or '*' in override_field_mutable[sid]:
fimmutable = 'false'
+ if ftype == cobject_function_identifier:
+ fimmutable = 'true'
+
if not ('char' in ftype and '[' in ftype and 'unsigned' not in ftype):
array_match = re.search(r'\[([^\]]+)\]', ftype)
if array_match:
@@ -506,6 +519,7 @@ def build_struct(struct):
# build up table and track column width
field_table = []
+ field_functions = []
for field in struct['fields']:
fid, ftype, fimmutable, lvt, lot, size = get_struct_field_info(struct, field)
@@ -531,22 +545,40 @@ def build_struct(struct):
startStr += '#ifndef ' + override_field_version_excludes[fid] + '\n'
endStr += '\n#endif'
startStr += ' { '
- row.append(startStr )
- row.append('"%s", ' % fid )
- row.append('%s, ' % lvt )
- row.append('offsetof(%s%s, %s), ' % (struct_str, name, field['identifier']))
- row.append('%s, ' % fimmutable )
- row.append('%s, ' % lot )
- row.append('%s, ' % size )
- row.append('sizeof(%s)' % ftype )
- row.append(endStr )
+ if ftype == cobject_function_identifier:
+ row.append(startStr )
+ row.append('"%s", ' % fid )
+ row.append('%s, ' % lvt )
+ row.append('(size_t) FUNCTION__%s, ' % (field['function']))
+ row.append('%s, ' % fimmutable )
+ row.append('%s, ' % lot )
+ row.append('%s, ' % size )
+ row.append('sizeof(const char *)' )
+ row.append(endStr )
+ field_functions.append(field['function'])
+ else:
+ row.append(startStr )
+ row.append('"%s", ' % fid )
+ row.append('%s, ' % lvt )
+ row.append('offsetof(%s%s, %s), ' % (struct_str, name, field['identifier']))
+ row.append('%s, ' % fimmutable )
+ row.append('%s, ' % lot )
+ row.append('%s, ' % size )
+ row.append('sizeof(%s)' % ftype )
+ row.append(endStr )
field_table.append(row)
field_table_str, field_count = table_to_string(field_table)
field_count_define = 'LUA_%s_FIELD_COUNT' % identifier_to_caps(sid)
struct_lot = 'LOT_%s' % sid.upper()
- s = "#define %s $[STRUCTFIELDCOUNT]\n" % field_count_define
+ s = ''
+ if field_functions:
+ for field_function in field_functions:
+ s += 'static const char FUNCTION__%s[] = "%s";\n' % (field_function, field_function)
+ s += '\n'
+
+ s += "#define %s $[STRUCTFIELDCOUNT]\n" % field_count_define
s += "static struct LuaObjectField s%sFields[%s] = {\n" % (sid, field_count_define)
s += field_table_str
s += '};\n'
@@ -646,6 +678,21 @@ def build_includes():
############################################################################
+# HACK: Parse docs/functions.md to find the page where the function is documented
+function_links = {}
+
+def doc_find_function_link(function):
+ if not function_links:
+ with open('docs/lua/functions.md') as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.replace(' ', '').strip()
+ res, n = re.subn(r'^-\[(.*)\]\((.*)\)', '\\1,\\2', line)
+ if n != 0:
+ fname, flink = res.split(',')
+ function_links[fname] = flink
+ return function_links.get(function, '')
+
def doc_struct_index(structs):
s = '# Supported Structs\n'
for struct in structs:
@@ -662,26 +709,30 @@ def doc_struct_field(struct, field):
sid = struct['identifier']
if sid in override_field_invisible:
if fid in override_field_invisible[sid]:
- return ''
+ return '', False
if sid in override_field_deprecated:
if fid in override_field_deprecated[sid]:
- return ''
+ return '', False
if '???' in lvt or '???' in lot:
- return ''
+ return '', False
ftype, flink = translate_type_to_lua(ftype)
+ if ftype == cobject_function_identifier:
+ flink = doc_find_function_link(field['function'])
+ return '| %s | [`%s`](%s) |\n' % (fid, field['function'], flink), True
+
restrictions = ('', 'read-only')[fimmutable == 'true']
global total_fields
total_fields += 1
if flink:
- return '| %s | [%s](%s) | %s |\n' % (fid, ftype, flink, restrictions)
+ return '| %s | [%s](%s) | %s |\n' % (fid, ftype, flink, restrictions), False
- return '| %s | %s | %s |\n' % (fid, ftype, restrictions)
+ return '| %s | %s | %s |\n' % (fid, ftype, restrictions), False
def doc_struct_object_fields(struct):
@@ -696,7 +747,8 @@ def doc_struct_object_fields(struct):
s += "| Field | Type | Access |\n"
s += "| ----- | ---- | ------ |\n"
- s += doc_struct_field(struct, field)
+ line, _ = doc_struct_field(struct, field)
+ s += line
return s
@@ -707,17 +759,27 @@ def doc_struct(struct):
s += "| Field | Type | Access |\n"
s += "| ----- | ---- | ------ |\n"
-
# build doc table
- field_table = []
+ field_functions = ''
for field in struct['fields']:
if 'object_field' in field and field['object_field'] == True:
continue
- s += doc_struct_field(struct, field)
+ line, isFunction = doc_struct_field(struct, field)
+ if isFunction:
+ field_functions += line
+ else:
+ s += line
if sid == 'Object':
s += doc_struct_object_fields(struct)
+ # functions
+ if field_functions:
+ s += '\n**Functions:**\n\n'
+ s += "| Name | Reference |\n"
+ s += "| ---- | --------- |\n"
+ s += field_functions
+
s += '\n[:arrow_up_small:](#)\n\n
\n'
return s
@@ -740,6 +802,32 @@ def doc_structs(structs):
def_pointers = []
+# HACK: Parse autogen/lua_definitions/functions.lua to find the function signature
+function_signatures = {}
+
+def get_function_signature(function):
+ if not function_signatures:
+ with open('autogen/lua_definitions/functions.lua') as f:
+ lines = f.readlines()
+ function_params = []
+ function_return = None
+ for line in lines:
+ if line.startswith('--- @param'):
+ function_params.append(line.split()[2:4])
+ elif line.startswith('--- @return'):
+ function_return = line.split()[2]
+ elif line.startswith('function'):
+ sig = 'fun('
+ sig += ', '.join(['%s: %s' % (param_name, param_type) for param_name, param_type in function_params])
+ sig += ')'
+ if function_return:
+ sig += ': %s' % (function_return)
+ function_name = line.replace('(', ' ').split()[1]
+ function_signatures[function_name] = sig
+ function_params.clear()
+ function_return = None
+ return function_signatures.get(function, 'function')
+
def def_struct(struct):
sid = struct['identifier']
@@ -761,7 +849,12 @@ def def_struct(struct):
ftype, flink = translate_type_to_lua(ftype)
- ftype = translate_to_def(ftype)
+ # try to get the function signature
+ if ftype == cobject_function_identifier:
+ ftype = get_function_signature(field['function'])
+ else:
+ ftype = translate_to_def(ftype)
+
if ftype.startswith('Pointer_') and ftype not in def_pointers:
def_pointers.append(ftype)
diff --git a/autogen/extract_structs.py b/autogen/extract_structs.py
index a2d65f1e9..5fb06c5ef 100644
--- a/autogen/extract_structs.py
+++ b/autogen/extract_structs.py
@@ -1,6 +1,7 @@
import os
import re
import sys
+from common import cobject_function_identifier
def extract_structs(filename):
with open(filename) as file:
@@ -36,6 +37,9 @@ def extract_structs(filename):
while (' ' in txt):
txt = txt.replace(' ', ' ')
+ # handle function members (NOT function pointers)
+ txt = re.sub(f'{cobject_function_identifier}\\((.*),(.*)\\)', f'{cobject_function_identifier} \\1 \\2', txt)
+
# strip macros
txt = re.sub(r'[^a-zA-Z0-9_][A-Z0-9_]+\(.*\)', '', txt)
diff --git a/autogen/gen_hooks.py b/autogen/gen_hooks.py
index 98aea889b..73d74769f 100644
--- a/autogen/gen_hooks.py
+++ b/autogen/gen_hooks.py
@@ -309,17 +309,20 @@ def main():
name=input["name"]
)
+ n_outputs = len(hook_event["outputs"])
generated += SMLUA_CALL_EVENT_HOOKS_CALLBACK.format(
n_inputs=len(hook_event["inputs"]) - mod_index_found,
- n_outputs=len(hook_event["outputs"]),
+ n_outputs=n_outputs,
hook_type=hook_event["type"],
set_hook_result=set_hook_result
)
+ # Note: relative indexes for return values are reversed in the Lua stack
+ # -1 is the last value, -2 the penultimate, ... and -N the first
for i, output in enumerate(hook_event["outputs"]):
generated += SMLUA_TYPES[output["type"]]["output"].format(
name=output["name"],
- output_index=i+1,
+ output_index=n_outputs - i,
return_on_output_set=return_on_output_set
)
diff --git a/autogen/gen_math.py b/autogen/gen_math.py
index 98da45c1a..e5ef37b6f 100644
--- a/autogen/gen_math.py
+++ b/autogen/gen_math.py
@@ -1,39 +1,70 @@
import sys
-
-VEC3X_TO_VEC3Y = """
+VECX_TO_VECY = """
/* |description|
-Converts a 3D {{desc}} vector `a` into a 3D {{desc_2}} vector and stores the result in `dest`
+Converts a {{size}}D {{desc}} vector `a` into a {{size}}D {{desc_2}} vector and stores the result in `dest`
|descriptionEnd| */
-INLINE OPTIMIZE_O3 Vec3{{suffix_2}}p vec3{{suffix}}_to_vec3{{suffix_2}}(OUT Vec3{{suffix_2}} dest, Vec3{{suffix}} a) {
- dest[0] = a[0]{{rounding_0}};
- dest[1] = a[1]{{rounding_1}};
- dest[2] = a[2]{{rounding_2}};
+INLINE OPTIMIZE_O3 Vec{{size}}{{suffix_2}}p vec{{size}}{{suffix}}_to_vec{{size}}{{suffix_2}}(OUT Vec{{size}}{{suffix_2}} dest, Vec{{size}}{{suffix}} a) {
+ {{body}}
return dest;
}
"""
-ROUNDING_FORMULA = " + ((a[%d] > 0) ? 0.5f : -0.5f)"
+ROUNDING_FORMULA = " + ((a[{i}] > 0) ? 0.5f : -0.5f)"
-def vec3_write_conversion_functions(generated: str, curr_template: dict, templates: list, size: int) -> str:
+def vec_write_conversion_functions(generated: str, curr_template: dict, templates: list, size: int) -> str:
for template in templates:
if template["suffix"] == curr_template["suffix"]:
continue
- generated += VEC3X_TO_VEC3Y \
+ body = "\n ".join([
+ "dest[{i}] = a[{i}]{rounding};".format(
+ i=i,
+ rounding=ROUNDING_FORMULA.format(i=i) if curr_template["rounding"] else ""
+ ) for i in range(size)
+ ])
+
+ generated += VECX_TO_VECY \
+ .replace("{{size}}", str(size)) \
.replace("{{desc}}", curr_template["desc"]) \
.replace("{{suffix}}", curr_template["suffix"]) \
.replace("{{desc_2}}", template["desc"]) \
- .replace("{{suffix_2}}", template["suffix"])
-
- for i in range(size):
- rounding_i = "{{rounding_%d}}" % (i)
- generated = generated.replace(rounding_i, ROUNDING_FORMULA % (i) if curr_template["rounding"] else "")
+ .replace("{{suffix_2}}", template["suffix"]) \
+ .replace("{{body}}", body)
return generated
TEMPLATES = {
+ "src/engine/math_util_vec2.tmpl": {
+ "size": 2,
+ "templates": [
+ {
+ "desc": "floating-point",
+ "type": "f32",
+ "suffix": "f",
+ "rounding": True
+ },
+ {
+ "desc": "integer",
+ "type": "s32",
+ "suffix": "i",
+ "rounding": False
+ },
+ {
+ "desc": "short integer",
+ "type": "s16",
+ "suffix": "s",
+ "rounding": False
+ }
+ ],
+ "post-template": {
+ "function": vec_write_conversion_functions,
+ "args": {
+ "size": 2
+ }
+ }
+ },
"src/engine/math_util_vec3.tmpl": {
"size": 3,
"templates": [
@@ -57,7 +88,7 @@ TEMPLATES = {
}
],
"post-template": {
- "function": vec3_write_conversion_functions,
+ "function": vec_write_conversion_functions,
"args": {
"size": 3
}
diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 9626d3b75..5f9b76fa0 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -2999,6 +2999,9 @@ GRAPH_RENDER_PLAYER = (1 << 7)
--- @type integer
GRAPH_EXTRA_FORCE_3D = (1 << 0)
+--- @type integer
+GRAPH_EXTRA_ROTATE_HELD = (1 << 1)
+
--- @type integer
GRAPH_NODE_TYPE_FUNCTIONAL = 0x100
@@ -4554,14 +4557,20 @@ GRAB_POS_BOWSER = 3 --- @type MarioGrabPosGSCId
--- | `GRAB_POS_BOWSER`
--- @type integer
-MOD_FS_MAX_SIZE = 0x1000000
+MOD_FS_MAX_SIZE = 0x2000000
--- @type integer
-MOD_FS_MAX_FILES = 0x100
+MOD_FS_MAX_FILES = 0x200
--- @type integer
MOD_FS_MAX_PATH = 0x100
+--- @type string
+MOD_FS_URI_PREFIX = "modfs:/"
+
+--- @type string
+MOD_FS_URI_FORMAT = "modfs:/%s/%s"
+
INT_TYPE_U8 = 0 --- @type ModFsFileIntType
INT_TYPE_U16 = 1 --- @type ModFsFileIntType
INT_TYPE_U32 = 2 --- @type ModFsFileIntType
@@ -6755,6 +6764,9 @@ R_CBUTTONS = CONT_F
--- @type integer
D_CBUTTONS = CONT_D
+--- @type string
+PALETTES_DIRECTORY = "palettes"
+
--- @type integer
MAX_PRESET_PALETTES = 128
@@ -10953,6 +10965,9 @@ SURFACE_FLAG_DYNAMIC = (1 << 0)
--- @type integer
SURFACE_FLAG_NO_CAM_COLLISION = (1 << 1)
+--- @type integer
+SURFACE_FLAG_INTANGIBLE = (1 << 2)
+
--- @type integer
SURFACE_FLAG_X_PROJECTION = (1 << 3)
@@ -11163,5 +11178,11 @@ VERSION_NUMBER = 41
--- @type integer
MINOR_VERSION_NUMBER = 0
+--- @type string
+GAME_NAME = "sm64coopdx"
+
+--- @type string
+WINDOW_NAME = "Super Mario 64 Coop Deluxe"
+
--- @type integer
MAX_VERSION_LENGTH = 128
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index bc9bbc883..3ba796772 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -7435,25 +7435,6 @@ function mod_fs_create()
-- ...
end
---- @return boolean
---- Deletes the modfs object of the active mod if it exists. Returns true on success
-function mod_fs_delete()
- -- ...
-end
-
---- @return boolean
---- Saves the modfs object of the active mod if it exists. Returns true on success
-function mod_fs_save()
- -- ...
-end
-
---- @param pub boolean
---- @return boolean
---- Marks the modfs object of the active mod as public (i.e. readable by other mods) if it exists. Returns true on success
-function mod_fs_set_public(pub)
- -- ...
-end
-
--- @param modFs ModFs
--- @param index integer
--- @return string
@@ -7514,6 +7495,28 @@ function mod_fs_clear(modFs)
-- ...
end
+--- @param modFs ModFs
+--- @return boolean
+--- Saves the provided `modFs` to persistent storage. Returns true on success
+function mod_fs_save(modFs)
+ -- ...
+end
+
+--- @param modFs ModFs
+--- @return boolean
+--- Removes the provided `modFs` from persistent storage and deletes its object. Returns true on success
+function mod_fs_delete(modFs)
+ -- ...
+end
+
+--- @param modFs ModFs
+--- @param pub boolean
+--- @return boolean
+--- Marks the provided `modFs` as public (i.e. readable by other mods). Returns true on success
+function mod_fs_set_public(modFs, pub)
+ -- ...
+end
+
--- @param file ModFsFile
--- @return boolean
--- Reads a boolean from a binary modfs `file`
@@ -7618,6 +7621,13 @@ function mod_fs_file_seek(file, offset, origin)
-- ...
end
+--- @param file ModFsFile
+--- @return boolean
+--- Sets the current position of a modfs `file` to its beginning. Returns true on success
+function mod_fs_file_rewind(file)
+ -- ...
+end
+
--- @param file ModFsFile
--- @return boolean
--- Returns true if the provided modfs `file` has reached its end of file
@@ -7642,6 +7652,14 @@ function mod_fs_file_erase(file, length)
-- ...
end
+--- @param file ModFsFile
+--- @param text boolean
+--- @return boolean
+--- Marks the provided modfs `file` as text. Returns true on success
+function mod_fs_file_set_text_mode(file, text)
+ -- ...
+end
+
--- @param file ModFsFile
--- @param pub boolean
--- @return boolean
@@ -7707,6 +7725,12 @@ function mod_storage_load_bool(key)
-- ...
end
+--- @return table
+--- Loads all keys and values in mod storage as strings and returns them as a table
+function mod_storage_load_all()
+ -- ...
+end
+
--- @param key string
--- @return boolean
--- Checks if a `key` is in mod storage
@@ -10776,12 +10800,19 @@ function gfx_get_vertex_count(cmd)
end
--- @param cmd Pointer_Gfx
---- @return Pointer_integer
+--- @return Pointer_Texture
--- Gets the texture from a display list command if it has an image related op
function gfx_get_texture(cmd)
-- ...
end
+--- @param gfx Pointer_Gfx
+--- @return string
+--- Gets the name of a display list
+function gfx_get_name(gfx)
+ -- ...
+end
+
--- @param gfx Pointer_Gfx
--- @return integer
--- Gets the max length of a display list
@@ -10838,6 +10869,13 @@ function gfx_delete_all()
-- ...
end
+--- @param vtx Pointer_Vtx
+--- @return string
+--- Gets the name of a vertex buffer
+function vtx_get_name(vtx)
+ -- ...
+end
+
--- @param vtx Pointer_Vtx
--- @return integer
--- Gets the max count of vertices of a vertex buffer
@@ -11514,12 +11552,19 @@ function geo_get_current_held_object()
-- ...
end
---- @param tex Pointer_integer
---- Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures.
+--- @param tex Pointer_Texture
+--- Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures
function texture_to_lua_table(tex)
-- ...
end
+--- @param tex Pointer_Texture
+--- @return string
+--- Gets the name of the provided texture pointer `tex`
+function get_texture_name(tex)
+ -- ...
+end
+
--- @param name string
--- @return ModelExtendedId
--- Gets the extended model ID for the `name` of a `GeoLayout`
@@ -12274,6 +12319,27 @@ function load_object_collision_model()
-- ...
end
+--- @return StaticObjectCollision
+--- Loads the object's collision data into static collision. You may run this only once to capture the object's collision at that frame.
+function load_static_object_collision()
+ -- ...
+end
+
+--- @param col StaticObjectCollision
+--- @param tangible boolean
+--- Toggles a collection of static object surfaces
+function toggle_static_object_collision(col, tangible)
+ -- ...
+end
+
+--- @param col StaticObjectCollision
+--- @param index integer
+--- @return Surface
+--- Gets a surface corresponding to `index` from the static object collision
+function get_static_object_surface(col, index)
+ -- ...
+end
+
--- @param o Object
--- @param index integer
--- @return Surface
@@ -12318,6 +12384,7 @@ end
--- @alias Pointer_Collision Collision
--- @alias Pointer_Gfx Gfx
--- @alias Pointer_Vtx Vtx
+--- @alias Pointer_Texture Texture
--- @alias Vec2fp Vec2f
--- @alias Vec3fp Vec3f
--- @alias Vec4fp Vec4f
diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua
index eb545250c..95e263d89 100644
--- a/autogen/lua_definitions/structs.lua
+++ b/autogen/lua_definitions/structs.lua
@@ -1280,7 +1280,7 @@
--- @field public customBehaviorIndex integer
--- @class ModAudio
---- @field public file ModFile
+--- @field public filepath string
--- @field public isStream boolean
--- @field public baseVolume number
--- @field public loaded boolean
@@ -1304,6 +1304,16 @@
--- @field public numFiles integer
--- @field public totalSize integer
--- @field public isPublic boolean
+--- @field public get_filename fun(modFs: ModFs, index: integer): string
+--- @field public get_file fun(modFs: ModFs, filepath: string): ModFsFile
+--- @field public create_file fun(modFs: ModFs, filepath: string, text: boolean): ModFsFile
+--- @field public move_file fun(modFs: ModFs, oldpath: string, newpath: string, overwriteExisting: boolean): boolean
+--- @field public copy_file fun(modFs: ModFs, srcpath: string, dstpath: string, overwriteExisting: boolean): boolean
+--- @field public delete_file fun(modFs: ModFs, filepath: string): boolean
+--- @field public clear fun(modFs: ModFs): boolean
+--- @field public save fun(modFs: ModFs): boolean
+--- @field public delete fun(modFs: ModFs): boolean
+--- @field public set_public fun(modFs: ModFs, pub: boolean): boolean
--- @class ModFsFile
--- @field public modFs ModFs
@@ -1312,6 +1322,25 @@
--- @field public offset integer
--- @field public isText boolean
--- @field public isPublic boolean
+--- @field public read_bool fun(file: ModFsFile): boolean
+--- @field public read_integer fun(file: ModFsFile, intType: ModFsFileIntType): integer
+--- @field public read_number fun(file: ModFsFile, floatType: ModFsFileFloatType): number
+--- @field public read_bytes fun(file: ModFsFile, length: integer): string
+--- @field public read_string fun(file: ModFsFile): string
+--- @field public read_line fun(file: ModFsFile): string
+--- @field public write_bool fun(file: ModFsFile, value: boolean): boolean
+--- @field public write_integer fun(file: ModFsFile, value: integer, intType: ModFsFileIntType): boolean
+--- @field public write_number fun(file: ModFsFile, value: number, floatType: ModFsFileFloatType): boolean
+--- @field public write_bytes fun(file: ModFsFile, bytestring: string): boolean
+--- @field public write_string fun(file: ModFsFile, str: string): boolean
+--- @field public write_line fun(file: ModFsFile, str: string): boolean
+--- @field public seek fun(file: ModFsFile, offset: integer, origin: ModFsFileSeek): boolean
+--- @field public rewind fun(file: ModFsFile): boolean
+--- @field public is_eof fun(file: ModFsFile): boolean
+--- @field public fill fun(file: ModFsFile, byte: integer, length: integer): boolean
+--- @field public erase fun(file: ModFsFile, length: integer): boolean
+--- @field public set_text_mode fun(file: ModFsFile, text: boolean): boolean
+--- @field public set_public fun(file: ModFsFile, pub: boolean): boolean
--- @class ModeTransitionInfo
--- @field public newMode integer
@@ -2176,10 +2205,9 @@
--- @field public rippleTimer number
--- @field public rippleX number
--- @field public rippleY number
---- @field public normalDisplayList Pointer_Gfx
+--- @field public textureArray Pointer_Texture[]
--- @field public textureWidth integer
--- @field public textureHeight integer
---- @field public rippleDisplayList Pointer_Gfx
--- @field public rippleTrigger integer
--- @field public alpha integer
--- @field public marioWasUnder integer
@@ -2338,6 +2366,10 @@
--- @field public dialog5 integer
--- @field public dialog6 integer
+--- @class StaticObjectCollision
+--- @field public index integer
+--- @field public length integer
+
--- @class Surface
--- @field public type integer
--- @field public flags integer
@@ -2357,7 +2389,7 @@
--- @field public object Object
--- @class TextureInfo
---- @field public texture Pointer_integer
+--- @field public texture Pointer_Texture
--- @field public name string
--- @field public width integer
--- @field public height integer
@@ -2528,3 +2560,5 @@
--- @alias Pointer_Mat4 Mat4
--- @alias Pointer_Vec4s Vec4s
--- @alias Pointer_BehaviorScript BehaviorScript
+--- @alias Pointer_Texture[] Texture[]
+--- @alias Pointer_Texture Texture
diff --git a/bin/custom_font.c b/bin/custom_font.c
index 9988d772b..2075d57bc 100644
--- a/bin/custom_font.c
+++ b/bin/custom_font.c
@@ -67,7 +67,7 @@ const f32 font_aliased_widths[] = {
/* 0 1 2 3 4 5 6 7 8 9 */
14, 12, 13, 14, 14, 14, 14, 13, 14, 14,
/* : ; < = > ? @ */
- 6, 8, 10, 12, 10, 11, 18,
+ 8, 8, 10, 12, 10, 11, 18,
/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */
12, 12, 12, 12, 11, 10, 12, 12, 9, 12, 12, 10, 16, 16, 12, 11, 12, 12, 12, 10, 12, 10, 16, 14, 12, 12,
/* [ \ ] ^ _ ` */
@@ -75,7 +75,7 @@ const f32 font_aliased_widths[] = {
/* a b c d e f g h i j k l m n o p q r s t u v w x y z */
10, 10, 10, 10, 9, 8, 12, 10, 7, 9, 10, 4, 13, 10, 9, 9, 10, 9, 10, 9, 10, 9, 14, 12, 10, 10,
/* { | } ~ DEL */
- 10, 8, 10, 16, 10,
+ 10, 8, 10, 16, 16,
};
//////////////////////////////////////////////////////////
diff --git a/data/behavior_table.c b/data/behavior_table.c
index 46c03b76c..6fbdf122b 100644
--- a/data/behavior_table.c
+++ b/data/behavior_table.c
@@ -558,6 +558,8 @@ const struct BehaviorTableEntry gBehaviorTable[id_bhv_max_count] = {
enum BehaviorId get_id_from_behavior(const BehaviorScript* behavior) {
if (behavior == NULL) { return id_bhv_max_count; }
+ if ((behavior[0] >> 24) != 0x00) { return id_bhv_max_count; } // check for BEGIN
+ if ((behavior[1] >> 24) != 0x39) { return id_bhv_max_count; } // check for ID
return (enum BehaviorId)(behavior[1] & 0xFFFF);
}
diff --git a/data/dynos.c.h b/data/dynos.c.h
index 9fd738463..419092eb1 100644
--- a/data/dynos.c.h
+++ b/data/dynos.c.h
@@ -37,17 +37,17 @@ void dynos_generate_packs(const char* directory);
// -- geos -- //
void dynos_actor_override(struct Object* obj, void** aSharedChild);
-void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName);
+bool dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName);
const void* dynos_geolayout_get(const char *name);
bool dynos_actor_get_mod_index_and_token(struct GraphNode *graphNode, u32 tokenIndex, s32 *modIndex, s32 *modFileIndex, const char **token);
void dynos_actor_register_modified_graph_node(struct GraphNode *node);
// -- collisions -- //
-void dynos_add_collision(const char *filePath, const char* collisionName);
+bool dynos_add_collision(const char *filePath, const char* collisionName);
Collision* dynos_collision_get(const char* collisionName);
// -- textures -- //
-void dynos_add_texture(const char *filePath, const char* textureName);
+bool dynos_add_texture(const char *filePath, const char* textureName);
bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureInfo);
bool dynos_texture_get_from_data(const Texture *tex, struct TextureInfo* outTextureInfo);
void dynos_texture_override_set(const char* textureName, struct TextureInfo* overrideTextureInfo);
@@ -90,11 +90,13 @@ void dynos_model_clear_pool(enum ModelPool aModelPool);
// -- gfx -- //
Gfx *dynos_gfx_get_writable_display_list(Gfx* gfx);
Gfx *dynos_gfx_get(const char *name, u32 *outLength);
+const char *dynos_gfx_get_name(Gfx *gfx);
Gfx *dynos_gfx_create(const char *name, u32 length);
bool dynos_gfx_resize(Gfx *gfx, u32 newLength);
bool dynos_gfx_delete(Gfx *gfx);
void dynos_gfx_delete_all();
Vtx *dynos_vtx_get(const char *name, u32 *outCount);
+const char *dynos_vtx_get_name(Vtx *vtx);
Vtx *dynos_vtx_create(const char *name, u32 count);
bool dynos_vtx_resize(Vtx *vtx, u32 newCount);
bool dynos_vtx_delete(Vtx *vtx);
diff --git a/data/dynos.cpp.h b/data/dynos.cpp.h
index 763cec64b..3afdfb859 100644
--- a/data/dynos.cpp.h
+++ b/data/dynos.cpp.h
@@ -897,7 +897,7 @@ void DynOS_Pack_AddTex(PackData* aPackData, DataNode* aTexData);
//
std::map &DynOS_Actor_GetValidActors();
-void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName);
+bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName);
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName);
bool DynOS_Actor_GetModIndexAndToken(const GraphNode *aGraphNode, u32 aTokenIndex, s32 *outModIndex, s32 *outModFileIndex, const char **outToken);
ActorGfx* DynOS_Actor_GetActorGfx(const GraphNode* aGraphNode);
@@ -925,7 +925,7 @@ u8 *DynOS_Tex_ConvertToRGBA32(const u8 *aData, u64 aLength, s32 aFormat, s32 aSi
bool DynOS_Tex_Import(void **aOutput, void *aPtr, s32 aTile, void *aGfxRApi, void **aHashMap, void *aPool, u32 *aPoolPos, u32 aPoolSize);
void DynOS_Tex_Activate(DataNode* aNode, bool aCustomTexture);
void DynOS_Tex_Deactivate(DataNode* aNode);
-void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName);
+bool DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName);
bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo);
bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo);
void DynOS_Tex_Override_Set(const char* textureName, struct TextureInfo* aOverrideTexInfo);
@@ -963,7 +963,7 @@ void DynOS_Bhv_ModShutdown();
// Col Manager
//
-void DynOS_Col_Activate(const SysPath &aFilePath, const char *aCollisionName);
+bool DynOS_Col_Activate(const SysPath &aFilePath, const char *aCollisionName);
Collision* DynOS_Col_Get(const char* collisionName);
void DynOS_Col_ModShutdown();
@@ -996,11 +996,13 @@ void DynOS_Model_ClearPool(enum ModelPool aModelPool);
Gfx *DynOS_Gfx_GetWritableDisplayList(Gfx *aGfx);
Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength);
+const char *DynOS_Gfx_GetName(Gfx *aGfx);
Gfx *DynOS_Gfx_Create(const char *aName, u32 aLength);
bool DynOS_Gfx_Resize(Gfx *aGfx, u32 aNewLength);
bool DynOS_Gfx_Delete(Gfx *aGfx);
void DynOS_Gfx_DeleteAll();
Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount);
+const char *DynOS_Vtx_GetName(Vtx *aVtx);
Vtx *DynOS_Vtx_Create(const char *aName, u32 aCount);
bool DynOS_Vtx_Resize(Vtx *aVtx, u32 aNewCount);
bool DynOS_Vtx_Delete(Vtx *aVtx);
diff --git a/data/dynos_bin_compress.cpp b/data/dynos_bin_compress.cpp
index 02a3546a5..302c6c2b1 100644
--- a/data/dynos_bin_compress.cpp
+++ b/data/dynos_bin_compress.cpp
@@ -1,6 +1,10 @@
#include "dynos.cpp.h"
#include
+extern "C" {
+#include "pc/mods/mod_fs.h"
+}
+
static const u64 DYNOS_BIN_COMPRESS_MAGIC = 0x4E4942534F4E5944llu;
static FILE *sFile = NULL;
static u8 *sBufferUncompressed = NULL;
@@ -154,9 +158,75 @@ bool DynOS_Bin_Compress(const SysPath &aFilename) {
return true;
}
+static BinFile *DynOS_Bin_Decompress_ModFs(const SysPath &aFilename) {
+ DynOS_Bin_Compress_Init();
+
+ // Read file data
+ void *_Buffer = NULL;
+ u32 _Size = 0;
+ if (!mod_fs_read_file_from_uri(aFilename.c_str(), &_Buffer, &_Size)) {
+ DynOS_Bin_Compress_Free();
+ return NULL;
+ }
+ sBufferCompressed = (u8 *) _Buffer;
+ sLengthCompressed = _Size;
+
+ // Check file length
+ u64 _LengthHeader = (u64) (sizeof(u64) + sizeof(u64));
+ if (!DynOS_Bin_Compress_Check(
+ sLengthCompressed >= _LengthHeader,
+ __FUNCTION__, aFilename.c_str(), "Empty file"
+ )) return NULL;
+
+ // Compare with magic constant
+ // If not equal, it's not a compressed file
+ u64 _Magic = ((u64 *) _Buffer)[0];
+ if (_Magic != DYNOS_BIN_COMPRESS_MAGIC) {
+ BinFile *_BinFile = BinFile::OpenB(sBufferCompressed, sLengthCompressed);
+ DynOS_Bin_Compress_Free();
+ return _BinFile;
+ }
+ PrintNoNewLine("Decompressing file \"%s\"...", aFilename.c_str());
+
+ // Read expected uncompressed file size
+ sLengthUncompressed = ((u64 *) _Buffer)[1];
+ sLengthCompressed -= _LengthHeader;
+ u8 *_BufferCompressed = sBufferCompressed + _LengthHeader;
+
+ // Allocate memory for uncompressed buffer
+ if (!DynOS_Bin_Compress_Check(
+ (sBufferUncompressed = (u8 *) calloc(sLengthUncompressed, sizeof(u8))) != NULL,
+ __FUNCTION__, aFilename.c_str(), "Cannot allocate memory for decompression"
+ )) return NULL;
+
+ // Uncompress data
+ uLongf _LengthUncompressed = (uLongf)sLengthUncompressed;
+ int uncompressRc = uncompress(sBufferUncompressed, &_LengthUncompressed, _BufferCompressed, sLengthCompressed);
+ sLengthUncompressed = _LengthUncompressed;
+ if (!DynOS_Bin_Compress_Check(
+ uncompressRc == Z_OK,
+ __FUNCTION__, aFilename.c_str(), "Cannot uncompress data"
+ )) {
+ PrintError("ERROR: uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader);
+ return NULL;
+ }
+ Print("uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader);
+
+ // Return uncompressed data as a BinFile
+ BinFile *_BinFile = BinFile::OpenB(sBufferUncompressed, sLengthUncompressed);
+ DynOS_Bin_Compress_Free();
+ Print(" Done.");
+ return _BinFile;
+}
+
BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) {
DynOS_Bin_Compress_Init();
+ // Check modfs
+ if (is_mod_fs_file(aFilename.c_str())) {
+ return DynOS_Bin_Decompress_ModFs(aFilename);
+ }
+
// Open input file
if (!DynOS_Bin_Compress_Check(
(sFile = f_open_r(aFilename.c_str())) != NULL,
diff --git a/data/dynos_bin_gfx.cpp b/data/dynos_bin_gfx.cpp
index 5d22cfe05..ae61971cc 100644
--- a/data/dynos_bin_gfx.cpp
+++ b/data/dynos_bin_gfx.cpp
@@ -405,6 +405,9 @@ s64 DynOS_Gfx_ParseGfxConstants(const String& _Arg, bool* found) {
gfx_constant(G_LIGHT_MAP_EXT);
gfx_constant(G_LIGHTING_ENGINE_EXT);
gfx_constant(G_PACKED_NORMALS_EXT);
+ gfx_constant(G_CULL_INVERT_EXT);
+ gfx_constant(G_FRESNEL_COLOR_EXT);
+ gfx_constant(G_FRESNEL_ALPHA_EXT);
gfx_constant(G_COL_PRIM);
gfx_constant(G_COL_ENV);
@@ -1211,7 +1214,7 @@ static String ResolveParam(lua_State *L, GfxData *aGfxData, u32 paramIndex, char
case GFX_PARAM_TYPE_TEX: return ConvertParam(
L, aGfxData, paramIndex,
"Texture pointer",
- [] (lua_State *L, u32 paramIndex) { return (Texture *) smlua_to_cpointer(L, paramIndex, LVT_U8_P); },
+ [] (lua_State *L, u32 paramIndex) { return (Texture *) smlua_to_cpointer(L, paramIndex, LVT_TEXTURE_P); },
[&aGfxData] (Texture *texture) { return CreateRawPointerDataNode(aGfxData, texture); }
);
diff --git a/data/dynos_bin_lvl.cpp b/data/dynos_bin_lvl.cpp
index e3e9a27ed..ff20ede76 100644
--- a/data/dynos_bin_lvl.cpp
+++ b/data/dynos_bin_lvl.cpp
@@ -641,6 +641,15 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNode* aNode, u64& aTokenIndex, u32 *luaParams, u32 luaParamFlag) {
+ bool foundParam = true;
+ LevelScript value = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundParam);
+ if (!foundParam) {
+ *luaParams |= luaParamFlag;
+ }
+ return value;
+}
+
static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNode, LevelScript*& aHead, u64& aTokenIndex, Array& aSwitchNodes) {
const String& _Symbol = aNode->mTokens[aTokenIndex++];
@@ -711,7 +720,6 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo
lvl_symbol_0(CMD2D);
lvl_symbol_1(TERRAIN, 1);
lvl_symbol_1(ROOMS, 1);
- lvl_symbol_2(SHOW_DIALOG, 0, 0);
lvl_symbol_1(TERRAIN_TYPE, 0);
lvl_symbol_0(NOP);
@@ -733,75 +741,75 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode* aNo
lvl_symbol_0(ADV_DEMO);
lvl_symbol_0(CLEAR_DEMO_PTR);
- // object
- if (_Symbol == "OBJECT") {
+ // dialog
+ if (_Symbol == "SHOW_DIALOG") {
u64 topTokenIndex = aTokenIndex;
+
+ u32 luaParams = 0;
+ LevelScript index = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, SHOW_DIALOG_EXT_LUA_INDEX);
+ LevelScript dialogId = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, SHOW_DIALOG_EXT_LUA_DIALOG);
- bool foundModel = true;
- bool foundBeh = true;
- LevelScript model = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundModel);
- LevelScript posX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript posY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript posZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript behParam = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript beh = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh);
+ if (luaParams != 0) {
+ LevelScript finalIndex = (luaParams & SHOW_DIALOG_EXT_LUA_INDEX) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]) : index;
+ LevelScript finalDialogId = (luaParams & SHOW_DIALOG_EXT_LUA_DIALOG) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]) : dialogId;
- if (foundModel && foundBeh) {
- aGfxData->mPointerList.Add(aHead + 5);
- LevelScript _Ls[] = { OBJECT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh) };
- memcpy(aHead, _Ls, sizeof(_Ls));
- aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
- } else if (foundModel) {
- u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 8]);
- LevelScript _Ls[] = { OBJECT_EXT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex) };
+ LevelScript _Ls[] = { SHOW_DIALOG_EXT(luaParams, finalIndex, finalDialogId) };
memcpy(aHead, _Ls, sizeof(_Ls));
aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
} else {
- u32 modelIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 0]);
- u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 8]);
- LevelScript _Ls[] = { OBJECT_EXT2(modelIndex, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex) };
+ LevelScript _Ls[] = { SHOW_DIALOG(index, dialogId) };
memcpy(aHead, _Ls, sizeof(_Ls));
aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
}
return;
}
- // object with acts
- if (_Symbol == "OBJECT_WITH_ACTS") {
+ // object
+ if (_Symbol == "OBJECT" || _Symbol == "OBJECT_WITH_ACTS") {
u64 topTokenIndex = aTokenIndex;
- bool foundModel = true;
- bool foundBeh = true;
- LevelScript model = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundModel);
- LevelScript posX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript posY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript posZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleX = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleY = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript angleZ = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript behParam = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
- LevelScript beh = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &foundBeh);
- LevelScript acts = ParseLevelScriptSymbolArg(aGfxData, aNode, aTokenIndex);
+ u32 luaParams = 0;
+ LevelScript model = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_MODEL);
+ LevelScript posX = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_X);
+ LevelScript posY = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_Y);
+ LevelScript posZ = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_POS_Z);
+ LevelScript angleX = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_X);
+ LevelScript angleY = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_Y);
+ LevelScript angleZ = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ANGLE_Z);
+ LevelScript behParam = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_BEH_PARAMS);
+ LevelScript beh = ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_BEHAVIOR);
+ LevelScript acts = (_Symbol == "OBJECT_WITH_ACTS") ? ParseLevelScriptObjectSymbolArgInternal(aGfxData, aNode, aTokenIndex, &luaParams, OBJECT_EXT_LUA_ACTS) : 0x1F;
- if (foundModel && foundBeh) {
+ // At least one parameter is a Lua variable, use OBJECT_EXT_LUA_PARAMS
+ if (luaParams != 0) {
+
+ // Remember behavior pointer if it's not a Lua param
+ if (!(luaParams & OBJECT_EXT_LUA_BEHAVIOR)) {
+ aGfxData->mPointerList.Add(aHead + 9);
+ }
+
+ LevelScript finalModel = (luaParams & OBJECT_EXT_LUA_MODEL) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 1, aNode->mTokens[topTokenIndex + 0]) : model;
+ LevelScript finalPosX = (luaParams & OBJECT_EXT_LUA_POS_X) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 2, aNode->mTokens[topTokenIndex + 1]) : posX;
+ LevelScript finalPosY = (luaParams & OBJECT_EXT_LUA_POS_Y) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 3, aNode->mTokens[topTokenIndex + 2]) : posY;
+ LevelScript finalPosZ = (luaParams & OBJECT_EXT_LUA_POS_Z) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 4, aNode->mTokens[topTokenIndex + 3]) : posZ;
+ LevelScript finalAngleX = (luaParams & OBJECT_EXT_LUA_ANGLE_X) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 4]) : angleX;
+ LevelScript finalAngleY = (luaParams & OBJECT_EXT_LUA_ANGLE_Y) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 5]) : angleY;
+ LevelScript finalAngleZ = (luaParams & OBJECT_EXT_LUA_ANGLE_Z) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 7, aNode->mTokens[topTokenIndex + 6]) : angleZ;
+ LevelScript finalBehParam = (luaParams & OBJECT_EXT_LUA_BEH_PARAMS) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 8, aNode->mTokens[topTokenIndex + 7]) : behParam;
+ LevelScript finalBeh = (luaParams & OBJECT_EXT_LUA_BEHAVIOR) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 9, aNode->mTokens[topTokenIndex + 8]) : beh;
+ LevelScript finalActs = (luaParams & OBJECT_EXT_LUA_ACTS) ? DynOS_Lua_RememberVariable(aGfxData, aHead + 10, aNode->mTokens[topTokenIndex + 9]) : acts;
+
+ LevelScript _Ls[] = { OBJECT_EXT_LUA_PARAMS(luaParams, finalModel, finalPosX, finalPosY, finalPosZ, finalAngleX, finalAngleY, finalAngleZ, finalBehParam, finalBeh, finalActs) };
+ memcpy(aHead, _Ls, sizeof(_Ls));
+ aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
+ }
+
+ // No Lua parameter, use OBJECT_WITH_ACTS
+ else {
aGfxData->mPointerList.Add(aHead + 5);
LevelScript _Ls[] = { OBJECT_WITH_ACTS(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, acts) };
memcpy(aHead, _Ls, sizeof(_Ls));
aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
- } else if (foundModel) {
- u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 8]);
- LevelScript _Ls[] = { OBJECT_WITH_ACTS_EXT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex, acts) };
- memcpy(aHead, _Ls, sizeof(_Ls));
- aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
- } else {
- u32 modelIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 5, aNode->mTokens[topTokenIndex + 0]);
- u32 behIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 6, aNode->mTokens[topTokenIndex + 8]);
- LevelScript _Ls[] = { OBJECT_WITH_ACTS_EXT2(modelIndex, posX, posY, posZ, angleX, angleY, angleZ, behParam, behIndex, acts) };
- memcpy(aHead, _Ls, sizeof(_Ls));
- aHead += (sizeof(_Ls) / sizeof(_Ls[0]));
}
return;
}
@@ -1063,12 +1071,12 @@ static DataNode* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData)
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_LVL, &_Node->mFlags);
if (_Ptr) {
- if (!requirePointer) {
+ if (!requirePointer && _Value != LUA_VAR_CODE) {
PrintError("Didn't expect a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value);
}
_Node->mData[i] = (uintptr_t) _Ptr;
} else {
- if (requirePointer) {
+ if (requirePointer && _Value != LUA_VAR_CODE) {
PrintError("Expected a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value);
_Node->mData[i] = 0;
} else {
diff --git a/data/dynos_bin_lvl_validate.cpp b/data/dynos_bin_lvl_validate.cpp
index 422d26a37..e592036ed 100644
--- a/data/dynos_bin_lvl_validate.cpp
+++ b/data/dynos_bin_lvl_validate.cpp
@@ -134,6 +134,8 @@ static void LvlCmd_Init() {
ADD_COMMAND(OBJECT_EXT2(POINTER, 0, 0, 0, 0, 0, 0, 0, POINTER));
ADD_COMMAND(LOAD_MODEL_FROM_GEO_EXT(0, POINTER));
ADD_COMMAND(JUMP_AREA_EXT(0, 0, POINTER));
+ ADD_COMMAND(OBJECT_EXT_LUA_PARAMS(0, 0, 0, 0, 0, 0, 0, 0, 0, POINTER, 0));
+ ADD_COMMAND(SHOW_DIALOG_EXT(0, 0, 0))
}
void DynOS_Lvl_Validate_Begin() {
diff --git a/data/dynos_bin_tex.cpp b/data/dynos_bin_tex.cpp
index 7385726ae..858526d45 100644
--- a/data/dynos_bin_tex.cpp
+++ b/data/dynos_bin_tex.cpp
@@ -2,8 +2,11 @@
extern "C" {
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
+#include "pc/mods/mod_fs.h"
}
+#define PNG_SIGNATURE 0x0A1A0A0D474E5089llu
+
///////////
// Utils //
///////////
@@ -304,46 +307,67 @@ DataNode* DynOS_Tex_LoadFromBinary(const SysPath &aPackFolder, const Sy
// Load data from binary file
DataNode* _TexNode = NULL;
- BinFile *_File = BinFile::OpenR(aFilename.c_str());
+ BinFile *_File = NULL;
+ if (is_mod_fs_file(aFilename.c_str())) {
+ void *_Buffer = NULL;
+ u32 _Size = 0;
+ if (mod_fs_read_file_from_uri(aFilename.c_str(), &_Buffer, &_Size)) {
+ _File = BinFile::OpenB((const u8 *) _Buffer, _Size);
+ free(_Buffer);
+ }
+ } else {
+ _File = BinFile::OpenR(aFilename.c_str());
+ }
if (!_File) { return NULL; }
u8 type = _File->Read();
if (type == DATA_TYPE_TEXTURE) {
+
// load png-texture
_TexNode = New>();
- _TexNode->mData = New();
-
_TexNode->mName.Read(_File);
+ _TexNode->mData = New();
_TexNode->mData->mPngData.Read(_File);
- BinFile::Close(_File);
+
+ } else if (type == DATA_TYPE_TEXTURE_RAW) {
+
+ // load raw-texture
+ _TexNode = New>();
+ _TexNode->mName.Read(_File);
+ _TexNode->mData = New();
+ _TexNode->mData->mRawFormat = _File->Read();
+ _TexNode->mData->mRawSize = _File->Read();
+ _TexNode->mData->mRawWidth = _File->Read();
+ _TexNode->mData->mRawHeight = _File->Read();
+ _TexNode->mData->mRawData.Read(_File);
+
+ } else if ((_File->SetOffset(0), _File->Read() == PNG_SIGNATURE)) {
+ _File->SetOffset(0);
+
+ // load PNG file
+ _TexNode = New>();
+ _TexNode->mName = aFilename.c_str();
+ _TexNode->mData = New();
+ _TexNode->mData->mPngData.Resize(_File->Size());
+ _File->Read(_TexNode->mData->mPngData.begin(), _File->Size());
+ }
+
+ BinFile::Close(_File);
+
+ if (_TexNode) {
+
+ // For some reason texture nodes are indexed to DynosCustomTexs by their node name,
+ // and not by `aTexName`, but DynOS_Tex_Get searches for `aTexName`...
+ // Normally, this doesn't cause any issue, but things go wrong when `aTexName`
+ // is not the same as the texture node name (which is the case for modfs files).
+ if (is_mod_fs_file(aFilename.c_str())) {
+ _TexNode->mName = aTexName;
+ }
if (aAddToPack) {
if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); }
DynOS_Pack_AddTex(_Pack, _TexNode);
}
-
- return _TexNode;
- } else if (type != DATA_TYPE_TEXTURE_RAW) {
- BinFile::Close(_File);
- return NULL;
- }
-
- // load raw-texture
- _TexNode = New>();
- _TexNode->mData = New();
-
- _TexNode->mName.Read(_File);
- _TexNode->mData->mRawFormat = _File->Read();
- _TexNode->mData->mRawSize = _File->Read();
- _TexNode->mData->mRawWidth = _File->Read();
- _TexNode->mData->mRawHeight = _File->Read();
- _TexNode->mData->mRawData.Read(_File);
-
- BinFile::Close(_File);
-
- if (aAddToPack) {
- if (!_Pack) { _Pack = DynOS_Pack_Add(aPackFolder); }
- DynOS_Pack_AddTex(_Pack, _TexNode);
}
return _TexNode;
diff --git a/data/dynos_c.cpp b/data/dynos_c.cpp
index 850f4006d..0bbd25ed3 100644
--- a/data/dynos_c.cpp
+++ b/data/dynos_c.cpp
@@ -115,8 +115,8 @@ void dynos_actor_override(struct Object* obj, void** aSharedChild) {
DynOS_Actor_Override(obj, aSharedChild);
}
-void dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName) {
- DynOS_Actor_AddCustom(modIndex, modFileIndex, filePath, geoName);
+bool dynos_add_actor_custom(s32 modIndex, s32 modFileIndex, const char *filePath, const char* geoName) {
+ return DynOS_Actor_AddCustom(modIndex, modFileIndex, filePath, geoName);
}
const void* dynos_geolayout_get(const char *name) {
@@ -133,8 +133,8 @@ void dynos_actor_register_modified_graph_node(struct GraphNode *node) {
// -- collisions -- //
-void dynos_add_collision(const char *filePath, const char* collisionName) {
- DynOS_Col_Activate(filePath, collisionName);
+bool dynos_add_collision(const char *filePath, const char* collisionName) {
+ return DynOS_Col_Activate(filePath, collisionName);
}
Collision* dynos_collision_get(const char* collisionName) {
@@ -143,9 +143,9 @@ Collision* dynos_collision_get(const char* collisionName) {
// -- textures -- //
-void dynos_add_texture(const char *filePath, const char* textureName) {
+bool dynos_add_texture(const char *filePath, const char* textureName) {
SysPath _FilePath = filePath;
- DynOS_Tex_AddCustom(_FilePath, textureName);
+ return DynOS_Tex_AddCustom(_FilePath, textureName);
}
bool dynos_texture_get(const char* textureName, struct TextureInfo* outTextureInfo) {
@@ -292,6 +292,10 @@ Gfx *dynos_gfx_get(const char *name, u32 *outLength) {
return DynOS_Gfx_Get(name, outLength);
}
+const char *dynos_gfx_get_name(Gfx *gfx) {
+ return DynOS_Gfx_GetName(gfx);
+}
+
Gfx *dynos_gfx_create(const char *name, u32 length) {
return DynOS_Gfx_Create(name, length);
}
@@ -312,6 +316,10 @@ Vtx *dynos_vtx_get(const char *name, u32 *outCount) {
return DynOS_Vtx_Get(name, outCount);
}
+const char *dynos_vtx_get_name(Vtx *vtx) {
+ return DynOS_Vtx_GetName(vtx);
+}
+
Vtx *dynos_vtx_create(const char *name, u32 count) {
return DynOS_Vtx_Create(name, count);
}
diff --git a/data/dynos_mgr_actor.cpp b/data/dynos_mgr_actor.cpp
index 5aba16350..fda357d0c 100644
--- a/data/dynos_mgr_actor.cpp
+++ b/data/dynos_mgr_actor.cpp
@@ -9,6 +9,7 @@ extern "C" {
#include "game/object_list_processor.h"
#include "pc/configfile.h"
#include "pc/lua/smlua_hooks.h"
+#include "pc/mods/mod_fs.h"
}
// Static maps/arrays
@@ -31,7 +32,7 @@ std::map &DynOS_Actor_GetValidActors() {
return DynosValidActors();
}
-void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName) {
+bool DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFilename, const char *aActorName) {
const void* georef = DynOS_Builtin_Actor_GetFromName(aActorName);
u16 actorLen = strlen(aActorName);
@@ -42,7 +43,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil
if (!_GfxData) {
PrintError(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str());
free(actorName);
- return;
+ return false;
}
_GfxData->mModIndex = aModIndex;
_GfxData->mModFileIndex = aModFileIndex;
@@ -51,7 +52,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil
if (!geoLayout) {
PrintError(" ERROR: Couldn't load geo layout for \"%s\"", actorName);
free(actorName);
- return;
+ return false;
}
// Alloc and init the actors gfx list
@@ -63,7 +64,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil
if (!actorGfx.mGraphNode) {
PrintError(" ERROR: Couldn't load graph node for \"%s\"", actorName);
free(actorName);
- return;
+ return false;
}
actorGfx.mGraphNode->georef = georef;
@@ -76,6 +77,7 @@ void DynOS_Actor_AddCustom(s32 aModIndex, s32 aModFileIndex, const SysPath &aFil
// Add to list
DynOS_Actor_Valid(georef, actorGfx);
free(actorName);
+ return true;
}
const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
@@ -115,6 +117,13 @@ const void *DynOS_Actor_GetLayoutFromName(const char *aActorName) {
}
}
+ // check modfs file
+ if (is_mod_fs_file(aActorName)) {
+ if (DynOS_Actor_AddCustom(gLuaActiveMod->index, -1, aActorName, aActorName)) {
+ return DynOS_Actor_GetLayoutFromName(aActorName);
+ }
+ }
+
return NULL;
}
@@ -222,7 +231,6 @@ void DynOS_Actor_Override(struct Object* obj, void** aSharedChild) {
}
}
-
*aSharedChild = (void*)it->second.mGraphNode;
}
diff --git a/data/dynos_mgr_col.cpp b/data/dynos_mgr_col.cpp
index 9a6d5f4db..66bf497ae 100644
--- a/data/dynos_mgr_col.cpp
+++ b/data/dynos_mgr_col.cpp
@@ -1,17 +1,21 @@
#include "dynos.cpp.h"
+extern "C" {
+#include "pc/mods/mod_fs.h"
+}
+
static Array*>>& DynosCollisions() {
static Array*>> sDynosCollisions;
return sDynosCollisions;
}
-void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) {
+bool DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) {
auto& _DynosCollisions = DynosCollisions();
// check for duplicates
for (s32 i = 0; i < _DynosCollisions.Count(); ++i) {
if (!strcmp(_DynosCollisions[i].first, aCollisionName)) {
- return;
+ return true;
}
}
@@ -24,11 +28,12 @@ void DynOS_Col_Activate(const SysPath &aFilename, const char *aCollisionName) {
DataNode* _Node = DynOS_Col_LoadFromBinary(aFilename, collisionName);
if (!_Node) {
free(collisionName);
- return;
+ return false;
}
// Add to collisions
_DynosCollisions.Add({ collisionName, _Node });
+ return true;
}
Collision* DynOS_Col_Get(const char* collisionName) {
@@ -51,6 +56,13 @@ Collision* DynOS_Col_Get(const char* collisionName) {
}
}
+ // check modfs file
+ if (is_mod_fs_file(collisionName)) {
+ if (DynOS_Col_Activate(collisionName, collisionName)) {
+ return DynOS_Col_Get(collisionName);
+ }
+ }
+
// check builtin collisions
return (Collision*)DynOS_Builtin_Col_GetFromName(collisionName);
}
diff --git a/data/dynos_mgr_gfx.cpp b/data/dynos_mgr_gfx.cpp
index 068cba698..99228d0d6 100644
--- a/data/dynos_mgr_gfx.cpp
+++ b/data/dynos_mgr_gfx.cpp
@@ -3,6 +3,7 @@
extern "C" {
#include "pc/lua/smlua.h"
#include "pc/lua/utils/smlua_gfx_utils.h"
+#include "pc/mods/mods.h"
}
struct MapNode {
@@ -13,6 +14,7 @@ struct MapNode {
// Maps read-only Gfx and Vtx buffers to their writable duplicates
static std::map sRomToRamGfxVtxMap;
+static std::map sRamToRomGfxVtxMap; // Reverse map for duplicate to vanilla lookup
static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) {
if (!aVtx) { return NULL; }
@@ -29,6 +31,7 @@ static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) {
Vtx *vtxDuplicate = vtx_allocate_internal(NULL, vtxCount);
memcpy(vtxDuplicate, aVtx, vtxSize);
sRomToRamGfxVtxMap[aVtx] = { (void *) vtxDuplicate, vtxSize, NULL };
+ sRamToRomGfxVtxMap[vtxDuplicate] = aVtx;
return vtxDuplicate;
}
@@ -81,6 +84,7 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) {
Gfx *gfxCopy = (Gfx *) malloc(gfxSize);
memcpy(gfxCopy, gfxDuplicate, gfxSize);
sRomToRamGfxVtxMap[aGfx] = { (void *) gfxDuplicate, gfxSize, gfxCopy };
+ sRamToRomGfxVtxMap[gfxDuplicate] = aGfx;
}
return gfxDuplicate;
@@ -136,24 +140,20 @@ Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) {
// Check levels
for (auto &lvl : DynOS_Lvl_GetArray()) {
- if (modIndex == -1 || lvl.second->mModIndex == modIndex) {
- for (auto &gfx : lvl.second->mDisplayLists) {
- if (gfx->mName == aName) {
- *outLength = gfx->mSize;
- return gfx->mData;
- }
+ for (auto &gfx : lvl.second->mDisplayLists) {
+ if (gfx->mName == aName) {
+ *outLength = gfx->mSize;
+ return gfx->mData;
}
}
}
// Check loaded actors
for (auto &actor : DynOS_Actor_GetValidActors()) {
- if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) {
- for (auto &gfx : actor.second.mGfxData->mDisplayLists) {
- if (gfx->mName == aName) {
- *outLength = gfx->mSize;
- return gfx->mData;
- }
+ for (auto &gfx : actor.second.mGfxData->mDisplayLists) {
+ if (gfx->mName == aName) {
+ *outLength = gfx->mSize;
+ return gfx->mData;
}
}
}
@@ -176,6 +176,42 @@ Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) {
return NULL;
}
+const char *DynOS_Gfx_GetName(Gfx *aGfx) {
+ if (!aGfx) { return NULL; }
+ s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
+
+ // Check mod data
+ static std::string outName;
+ if (sModsDisplayLists.GetName(modIndex, aGfx, outName)) {
+ return outName.c_str();
+ }
+
+ // Check levels
+ for (auto &lvl : DynOS_Lvl_GetArray()) {
+ for (auto &gfx : lvl.second->mDisplayLists) {
+ if (gfx->mData == aGfx) {
+ return gfx->mName.begin();
+ }
+ }
+ }
+
+ // Check loaded actors
+ for (auto &actor : DynOS_Actor_GetValidActors()) {
+ for (auto &gfx : actor.second.mGfxData->mDisplayLists) {
+ if (gfx->mData == aGfx) {
+ return gfx->mName.begin();
+ }
+ }
+ }
+
+ // Check vanilla display lists
+ auto it = sRamToRomGfxVtxMap.find(aGfx);
+ if (it != sRamToRomGfxVtxMap.end()) {
+ return DynOS_Builtin_Gfx_GetFromData((const Gfx *) it->second);
+ }
+ return DynOS_Builtin_Gfx_GetFromData(aGfx);
+}
+
Gfx *DynOS_Gfx_Create(const char *aName, u32 aLength) {
s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
return sModsDisplayLists.Create(modIndex, aName, aLength);
@@ -240,24 +276,51 @@ Vtx *DynOS_Vtx_Get(const char *aName, u32 *outCount) {
// Check levels
for (auto &lvl : DynOS_Lvl_GetArray()) {
- if (modIndex == -1 || lvl.second->mModIndex == modIndex) {
- for (auto &vtx : lvl.second->mVertices) {
- if (vtx->mName == aName) {
- *outCount = vtx->mSize;
- return vtx->mData;
- }
+ for (auto &vtx : lvl.second->mVertices) {
+ if (vtx->mName == aName) {
+ *outCount = vtx->mSize;
+ return vtx->mData;
}
}
}
// Check loaded actors
for (auto &actor : DynOS_Actor_GetValidActors()) {
- if (modIndex == -1 || actor.second.mGfxData->mModIndex == modIndex) {
- for (auto &vtx : actor.second.mGfxData->mVertices) {
- if (vtx->mName == aName) {
- *outCount = vtx->mSize;
- return vtx->mData;
- }
+ for (auto &vtx : actor.second.mGfxData->mVertices) {
+ if (vtx->mName == aName) {
+ *outCount = vtx->mSize;
+ return vtx->mData;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+const char *DynOS_Vtx_GetName(Vtx *aVtx) {
+ if (!aVtx) { return NULL; }
+ s32 modIndex = (gLuaActiveMod ? gLuaActiveMod->index : -1);
+
+ // Check mod data
+ static std::string outName;
+ if (sModsVertexBuffers.GetName(modIndex, aVtx, outName)) {
+ return outName.c_str();
+ }
+
+ // Check levels
+ for (auto &lvl : DynOS_Lvl_GetArray()) {
+ for (auto &vtx : lvl.second->mVertices) {
+ if (vtx->mData == aVtx) {
+ return vtx->mName.begin();
+ }
+ }
+ }
+
+ // Check loaded actors
+ for (auto &actor : DynOS_Actor_GetValidActors()) {
+ for (auto &vtx : actor.second.mGfxData->mVertices) {
+ if (vtx->mData == aVtx) {
+ return vtx->mName.begin();
}
}
}
diff --git a/data/dynos_mgr_moddata.hpp b/data/dynos_mgr_moddata.hpp
index 56db167a5..c4d3721cf 100644
--- a/data/dynos_mgr_moddata.hpp
+++ b/data/dynos_mgr_moddata.hpp
@@ -135,7 +135,6 @@ public:
mMapNameToItem.clear();
}
-private:
ModDataResult *> Find(T *aPointer, std::string &outName) {
if (!aPointer) {
return { NULL, DYNOS_MOD_DATA_ERROR_POINTER_IS_NULL };
@@ -151,6 +150,7 @@ private:
return { NULL, 0 };
}
+private:
ModDataResult *> FindAvailableItem() {
// Create pool if it doesn't exist yet
@@ -212,6 +212,16 @@ public:
return getResult.first->mBuffer;
}
+ bool GetName(s32 aModIndex, T *aPointer, std::string &outName) {
+ ModDataT *modData = GetModData(aModIndex);
+ auto findResult = modData->Find(aPointer, outName);
+ if (!findResult.first) {
+ gDynosModDataLastError = findResult.second;
+ return false;
+ }
+ return true;
+ }
+
T *Create(s32 aModIndex, const char *aName, u32 aSize) {
ModDataT *modData = GetModData(aModIndex);
auto createResult = modData->Create(aName, aSize);
diff --git a/data/dynos_mgr_tex.cpp b/data/dynos_mgr_tex.cpp
index 5531c0710..5bc3bceb6 100644
--- a/data/dynos_mgr_tex.cpp
+++ b/data/dynos_mgr_tex.cpp
@@ -4,6 +4,7 @@
extern "C" {
#include "pc/gfx/gfx.h"
#include "pc/gfx/gfx_rendering_api.h"
+#include "pc/mods/mod_fs.h"
}
struct OverrideTexture {
@@ -423,13 +424,13 @@ void DynOS_Tex_Deactivate(DataNode* aNode) {
_Schedule.Add(aNode);
}
-void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) {
+bool DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) {
auto& _DynosCustomTexs = DynosCustomTexs();
// check for duplicates
for (s32 i = 0; i < _DynosCustomTexs.Count(); ++i) {
if (!strcmp(_DynosCustomTexs[i].first, aTexName)) {
- return;
+ return true;
}
}
@@ -444,7 +445,9 @@ void DynOS_Tex_AddCustom(const SysPath &aFilename, const char *aTexName) {
free(_TexName);
if (_Node) {
DynOS_Tex_Activate(_Node, true);
+ return true;
}
+ return false;
}
#define CONVERT_TEXINFO(texName) { \
@@ -488,6 +491,13 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
}
}
+ // check modfs file
+ if (is_mod_fs_file(aTexName)) {
+ if (DynOS_Tex_AddCustom(aTexName, aTexName)) {
+ return DynOS_Tex_Get(aTexName, aOutTexInfo);
+ }
+ }
+
// check builtin textures
const struct BuiltinTexInfo* info = DynOS_Builtin_Tex_GetInfoFromName(aTexName);
if (!info) {
@@ -503,7 +513,7 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) {
aOutTexInfo->bitSize = info->bitSize;
aOutTexInfo->width = info->width;
aOutTexInfo->height = info->height;
- aOutTexInfo->texture = (u8*)info->pointer;
+ aOutTexInfo->texture = (Texture*)info->pointer;
aOutTexInfo->name = aTexName;
return true;
}
@@ -522,7 +532,7 @@ bool DynOS_Tex_GetFromData(const Texture *aTex, struct TextureInfo* aOutTexInfo)
aOutTexInfo->bitSize = info->bitSize;
aOutTexInfo->width = info->width;
aOutTexInfo->height = info->height;
- aOutTexInfo->texture = (u8*)info->pointer;
+ aOutTexInfo->texture = (Texture*)info->pointer;
aOutTexInfo->name = info->identifier;
return true;
}
diff --git a/developer/dir2modfs.py b/developer/dir2modfs.py
deleted file mode 100644
index af41a2abd..000000000
--- a/developer/dir2modfs.py
+++ /dev/null
@@ -1,190 +0,0 @@
-import os, sys, re
-
-
-MOD_FS_MAGIC = "MODFSSM64COOPDX"
-MOD_FS_HEADER_SIZE = 32
-MOD_FS_EXTENSION = ".modfs"
-MOD_FS_VERSION = 1
-MOD_FS_MAX_SIZE = 0x1000000
-MOD_FS_MAX_FILES = 0x100
-MOD_FS_MAX_PATH = 0x100
-
-
-def usage():
- print("""
-Directory to modfs:
-
- python dir2modfs.py [--set-public] [--set-file-public ...]
-
- Parameters:
- dirpath Path to directory to turn into a .modfs file
-
- Options:
- --set-public Set modfs file as public (readable by other mods)
- --set-file-public Set the provided files as public (readable by other mods)
-
-modfs to directory:
-
- python dir2modfs.py --extract
-
- Parameters:
- filepath Path to modfs file to extract files from
-""")
- exit(0)
-
-
-def is_binary_file(bytes: bytes):
- textchars = bytearray({0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x1B} | set(range(0x20, 0x100)) - {0x7F})
- return bool(bytes.translate(None, textchars))
-
-
-def get_files(dirpath: str, public_files: list):
- files = []
- for root, _, filenames in os.walk(dirpath):
- for filename in filenames:
- relpath = os.path.join(root, filename)
- filepath = relpath.removeprefix(dirpath).strip("/\\").replace('\\', '/')
- is_public = False
- for public_file in public_files:
- if re.match(public_file, relpath) or re.match(public_file, filepath):
- is_public = True
- break
- files.append({
- "relpath": relpath,
- "filepath": filepath,
- "is_public": is_public,
- "is_text": False,
- "data": None
- })
- return files
-
-
-def convert(dirpath: str, set_public: bool, public_files: list):
- dirpath = dirpath.rstrip("/\\")
- files = sorted(get_files(dirpath, public_files), key=lambda file: file["filepath"])
- if len(files) > MOD_FS_MAX_FILES:
- raise Exception(f"Max number of files exceeded: {len(files)} (max is: {MOD_FS_MAX_FILES})")
-
- total_size = 0
- for file in files:
- filepath = file["filepath"]
- if len(filepath) >= MOD_FS_MAX_PATH:
- raise Exception(f"{filepath} - Exceeded filepath length: {len(filepath)} (max is: {MOD_FS_MAX_PATH-1})")
-
- with open(file["relpath"], "rb") as f:
- data = f.read()
- total_size += len(data)
- if total_size > MOD_FS_MAX_SIZE:
- raise Exception(f"{filepath} - Total size exceeded: {total_size} (max is: {MOD_FS_MAX_SIZE})")
-
- file["data"] = data
- file["is_text"] = not is_binary_file(data)
-
- # write file
- destpath = dirpath + MOD_FS_EXTENSION
- with open(destpath, "wb") as f:
-
- # magic + version
- f.write(MOD_FS_MAGIC.encode())
- f.write(MOD_FS_VERSION.to_bytes(1, byteorder="little", signed=False))
-
- # header
- f.write(len(files).to_bytes(2, byteorder="little", signed=False))
- f.write(set_public.to_bytes(1, byteorder="little", signed=False))
-
- # padding (empty space for future versions)
- padding = MOD_FS_HEADER_SIZE - f.tell()
- f.write(b'\0' * padding)
-
- # files
- for file in files:
-
- # filepath
- f.write(len(file["filepath"]).to_bytes(2, byteorder="little", signed=False))
- f.write(file["filepath"].encode())
-
- # data
- f.write(len(file["data"]).to_bytes(4, byteorder="little", signed=False))
- f.write(file["is_public"].to_bytes(1, byteorder="little", signed=False))
- f.write(file["is_text"].to_bytes(1, byteorder="little", signed=False))
- f.write(file["data"])
-
- # summary
- print("")
- print(f"Directory: {dirpath}")
- print(f"Num files: {len(files)}")
- print(f"Total size: {total_size}")
- print(f"Is public: {set_public}")
-
- filepaths_max = max(8, len(max([file["filepath"] for file in files], key=len)))
- sizes_max = max(4, len(max([str(len(file["data"])) for file in files], key=len)))
- print("")
- print(f"{'FILEPATH'.ljust(filepaths_max)} {'SIZE'.rjust(sizes_max)} {'TEXT'.rjust(5)} {'PUBLIC'.rjust(6)}")
- print(f"{'--------'.ljust(filepaths_max)} {'----'.rjust(sizes_max)} {'----'.rjust(5)} {'------'.rjust(6)}")
- for file in files:
- filepath = file["filepath"]
- size = str(len(file["data"]))
- is_text = str(file["is_text"])
- is_public = str(file["is_public"])
- print(f"{filepath.ljust(filepaths_max)} {size.rjust(sizes_max)} {is_text.rjust(5)} {is_public.rjust(6)}")
-
-
-def extract(filepath: str):
- if not filepath.endswith(MOD_FS_EXTENSION):
- raise Exception("Not a modfs file")
-
- with open(filepath, "rb") as f:
-
- # magic + version
- magic = f.read(len(MOD_FS_MAGIC)).decode()
- if magic != MOD_FS_MAGIC:
- raise Exception("Not a modfs file")
- version = int.from_bytes(f.read(1), byteorder="little", signed=False)
- if version != MOD_FS_VERSION:
- raise Exception("Version mismatch")
-
- # header
- num_files = int.from_bytes(f.read(2), byteorder="little", signed=False)
- is_public = bool.from_bytes(f.read(1), byteorder="little", signed=False)
-
- # padding (empty space for future versions)
- f.seek(MOD_FS_HEADER_SIZE, 0)
-
- # create directory
- dirpath = filepath.removesuffix(MOD_FS_EXTENSION)
- os.makedirs(dirpath, exist_ok=True)
-
- # files
- for _ in range(num_files):
-
- # filepath
- filepath_len = int.from_bytes(f.read(2), byteorder="little", signed=False)
- filepath = os.path.join(dirpath, f.read(filepath_len).decode())
-
- # data
- file_size = int.from_bytes(f.read(4), byteorder="little", signed=False)
- file_is_public = bool.from_bytes(f.read(1), byteorder="little", signed=False)
- file_is_text = bool.from_bytes(f.read(1), byteorder="little", signed=False)
- file_data = f.read(file_size)
-
- # write file
- os.makedirs(os.path.dirname(filepath), exist_ok=True)
- with open(filepath, "wb") as g:
- g.write(file_data)
- print(f"Extracted file of size {file_size} to: {filepath}")
-
-
-def main(argc: int, argv: list):
- if argc < 2:
- usage()
-
- if "--extract" in argv:
- extract(argv[1])
- else:
- set_public = "--set-public" in argv
- set_file_public_index = argv.index("--set-file-public") if "--set-file-public" in argv else argc
- convert(argv[1], set_public, argv[set_file_public_index+1:])
-
-
-if __name__ == "__main__":
- main(len(sys.argv), sys.argv)
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 744db5da8..5c834b889 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -1335,6 +1335,7 @@
- GRAPH_RENDER_CYLBOARD
- GRAPH_RENDER_PLAYER
- GRAPH_EXTRA_FORCE_3D
+- GRAPH_EXTRA_ROTATE_HELD
- GRAPH_NODE_TYPE_FUNCTIONAL
- GRAPH_NODE_TYPE_400
- GRAPH_NODE_TYPE_ROOT
@@ -2143,6 +2144,8 @@
- MOD_FS_MAX_SIZE
- MOD_FS_MAX_FILES
- MOD_FS_MAX_PATH
+- MOD_FS_URI_PREFIX
+- MOD_FS_URI_FORMAT
### [enum ModFsFileIntType](#ModFsFileIntType)
| Identifier | Value |
@@ -2969,6 +2972,7 @@
## [player_palette.h](#player_palette.h)
+- PALETTES_DIRECTORY
- MAX_PRESET_PALETTES
### [enum PlayerPart](#PlayerPart)
@@ -4619,6 +4623,7 @@
- SURFACE_CLASS_NOT_SLIPPERY
- SURFACE_FLAG_DYNAMIC
- SURFACE_FLAG_NO_CAM_COLLISION
+- SURFACE_FLAG_INTANGIBLE
- SURFACE_FLAG_X_PROJECTION
- HAZARD_TYPE_LAVA_FLOOR
- HAZARD_TYPE_LAVA_WALL
@@ -4720,6 +4725,12 @@
- VERSION_TEXT
- VERSION_NUMBER
- MINOR_VERSION_NUMBER
+- GAME_NAME
+- WINDOW_NAME
+- GAME_NAME
+- WINDOW_NAME
+- GAME_NAME
+- WINDOW_NAME
- MAX_VERSION_LENGTH
[:arrow_up_small:](#)
diff --git a/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c b/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c
index e29ce377a..46f01d338 100644
--- a/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c
+++ b/docs/lua/examples/gfx-vtx-demo/actors/shape/model.inc.c
@@ -15,5 +15,6 @@ Gfx shape_template_dl[] = {
/* [11] */ gsSPDisplayList(NULL),
/* [12] */ gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
/* [13] */ gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
-/* [14] */ gsSPEndDisplayList(),
+/* [14] */ gsSPLoadGeometryMode(G_LIGHTING | G_CULL_BACK),
+/* [15] */ gsSPEndDisplayList(),
};
diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md
index 53f109eba..a3ff14601 100644
--- a/docs/lua/functions-5.md
+++ b/docs/lua/functions-5.md
@@ -342,71 +342,6 @@ Creates a modfs object for the active mod if it doesn't exist. Returns the modfs
-## [mod_fs_delete](#mod_fs_delete)
-
-### Description
-Deletes the modfs object of the active mod if it exists. Returns true on success
-
-### Lua Example
-`local booleanValue = mod_fs_delete()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool mod_fs_delete();`
-
-[:arrow_up_small:](#)
-
-
-
-## [mod_fs_save](#mod_fs_save)
-
-### Description
-Saves the modfs object of the active mod if it exists. Returns true on success
-
-### Lua Example
-`local booleanValue = mod_fs_save()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool mod_fs_save();`
-
-[:arrow_up_small:](#)
-
-
-
-## [mod_fs_set_public](#mod_fs_set_public)
-
-### Description
-Marks the modfs object of the active mod as public (i.e. readable by other mods) if it exists. Returns true on success
-
-### Lua Example
-`local booleanValue = mod_fs_set_public(pub)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| pub | `boolean` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool mod_fs_set_public(bool pub);`
-
-[:arrow_up_small:](#)
-
-
-
## [mod_fs_get_filename](#mod_fs_get_filename)
### Description
@@ -579,6 +514,76 @@ Deletes all files of the provided `modFs`. Returns true on success
+## [mod_fs_save](#mod_fs_save)
+
+### Description
+Saves the provided `modFs` to persistent storage. Returns true on success
+
+### Lua Example
+`local booleanValue = mod_fs_save(modFs)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| modFs | [ModFs](structs.md#ModFs) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_fs_save(struct ModFs *modFs);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mod_fs_delete](#mod_fs_delete)
+
+### Description
+Removes the provided `modFs` from persistent storage and deletes its object. Returns true on success
+
+### Lua Example
+`local booleanValue = mod_fs_delete(modFs)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| modFs | [ModFs](structs.md#ModFs) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_fs_delete(struct ModFs *modFs);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mod_fs_set_public](#mod_fs_set_public)
+
+### Description
+Marks the provided `modFs` as public (i.e. readable by other mods). Returns true on success
+
+### Lua Example
+`local booleanValue = mod_fs_set_public(modFs, pub)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| modFs | [ModFs](structs.md#ModFs) |
+| pub | `boolean` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_fs_set_public(struct ModFs *modFs, bool pub);`
+
+[:arrow_up_small:](#)
+
+
+
## [mod_fs_file_read_bool](#mod_fs_file_read_bool)
### Description
@@ -891,6 +896,29 @@ Sets the current position of a modfs `file`. If `origin` is `FILE_SEEK_SET`, fil
+## [mod_fs_file_rewind](#mod_fs_file_rewind)
+
+### Description
+Sets the current position of a modfs `file` to its beginning. Returns true on success
+
+### Lua Example
+`local booleanValue = mod_fs_file_rewind(file)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| file | [ModFsFile](structs.md#ModFsFile) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_fs_file_rewind(struct ModFsFile *file);`
+
+[:arrow_up_small:](#)
+
+
+
## [mod_fs_file_is_eof](#mod_fs_file_is_eof)
### Description
@@ -963,6 +991,30 @@ Erases `length` bytes or characters from a modfs `file`. Returns true on success
+## [mod_fs_file_set_text_mode](#mod_fs_file_set_text_mode)
+
+### Description
+Marks the provided modfs `file` as text. Returns true on success
+
+### Lua Example
+`local booleanValue = mod_fs_file_set_text_mode(file, text)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| file | [ModFsFile](structs.md#ModFsFile) |
+| text | `boolean` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_fs_file_set_text_mode(struct ModFsFile *file, bool text);`
+
+[:arrow_up_small:](#)
+
+
+
## [mod_fs_file_set_public](#mod_fs_file_set_public)
### Description
@@ -1178,6 +1230,27 @@ Loads a bool `value` from a `key` in mod storage
+## [mod_storage_load_all](#mod_storage_load_all)
+
+### Description
+Loads all keys and values in mod storage as strings and returns them as a table
+
+### Lua Example
+`local tableValue = mod_storage_load_all()`
+
+### Parameters
+- None
+
+### Returns
+- `table`
+
+### C Prototype
+`LuaTable mod_storage_load_all(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [mod_storage_exists](#mod_storage_exists)
### Description
@@ -3625,4584 +3698,6 @@ Moves the current object for specifically one second (`oTimer` < 30)
[:arrow_up_small:](#)
-
-
----
-# functions from object_helpers.c
-
-
-
-
-## [clear_move_flag](#clear_move_flag)
-
-### Lua Example
-`local integerValue = clear_move_flag(bitSet, flag)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| bitSet | `Pointer` <`integer`> |
-| flag | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 clear_move_flag(u32 *bitSet, s32 flag);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_room_override](#set_room_override)
-
-### Description
-Overrides the current room Mario is in. Set to -1 to reset override
-
-### Lua Example
-`set_room_override(room)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| room | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_room_override(s16 room);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_update_pos_from_parent_transformation](#obj_update_pos_from_parent_transformation)
-
-### Lua Example
-`obj_update_pos_from_parent_transformation(a0, a1)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | [Mat4](structs.md#Mat4) |
-| a1 | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_apply_scale_to_matrix](#obj_apply_scale_to_matrix)
-
-### Lua Example
-`obj_apply_scale_to_matrix(obj, dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| dst | [Mat4](structs.md#Mat4) |
-| src | [Mat4](structs.md#Mat4) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [create_transformation_from_matrices](#create_transformation_from_matrices)
-
-### Lua Example
-`create_transformation_from_matrices(a0, a1, a2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | [Mat4](structs.md#Mat4) |
-| a1 | [Mat4](structs.md#Mat4) |
-| a2 | [Mat4](structs.md#Mat4) |
-
-### Returns
-- None
-
-### C Prototype
-`void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_held_state](#obj_set_held_state)
-
-### Lua Example
-`obj_set_held_state(obj, heldBehavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| heldBehavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [lateral_dist_between_objects](#lateral_dist_between_objects)
-
-### Lua Example
-`local numberValue = lateral_dist_between_objects(obj1, obj2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj1 | [Object](structs.md#Object) |
-| obj2 | [Object](structs.md#Object) |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [dist_between_objects](#dist_between_objects)
-
-### Lua Example
-`local numberValue = dist_between_objects(obj1, obj2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj1 | [Object](structs.md#Object) |
-| obj2 | [Object](structs.md#Object) |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 dist_between_objects(struct Object *obj1, struct Object *obj2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [dist_between_object_and_point](#dist_between_object_and_point)
-
-### Lua Example
-`local numberValue = dist_between_object_and_point(obj, pointX, pointY, pointZ)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pointX | `number` |
-| pointY | `number` |
-| pointZ | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_forward_vel_approach_upward](#cur_obj_forward_vel_approach_upward)
-
-### Lua Example
-`cur_obj_forward_vel_approach_upward(target, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| target | `number` |
-| increment | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_forward_vel_approach_upward(f32 target, f32 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [approach_f32_signed](#approach_f32_signed)
-
-### Lua Example
-`local integerValue = approach_f32_signed(value, target, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `Pointer` <`number`> |
-| target | `number` |
-| increment | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 approach_f32_signed(f32 *value, f32 target, f32 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [approach_f32_symmetric](#approach_f32_symmetric)
-
-### Lua Example
-`local numberValue = approach_f32_symmetric(value, target, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `number` |
-| target | `number` |
-| increment | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 approach_f32_symmetric(f32 value, f32 target, f32 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [approach_s16_symmetric](#approach_s16_symmetric)
-
-### Lua Example
-`local integerValue = approach_s16_symmetric(value, target, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `integer` |
-| target | `integer` |
-| increment | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 approach_s16_symmetric(s16 value, s16 target, s16 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_rotate_yaw_toward](#cur_obj_rotate_yaw_toward)
-
-### Lua Example
-`local integerValue = cur_obj_rotate_yaw_toward(target, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| target | `integer` |
-| increment | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_angle_to_object](#obj_angle_to_object)
-
-### Lua Example
-`local integerValue = obj_angle_to_object(obj1, obj2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj1 | [Object](structs.md#Object) |
-| obj2 | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_pitch_to_object](#obj_pitch_to_object)
-
-### Lua Example
-`local integerValue = obj_pitch_to_object(obj, target)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| target | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 obj_pitch_to_object(struct Object* obj, struct Object* target);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_angle_to_point](#obj_angle_to_point)
-
-### Lua Example
-`local integerValue = obj_angle_to_point(obj, pointX, pointZ)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pointX | `number` |
-| pointZ | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointZ);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_turn_toward_object](#obj_turn_toward_object)
-
-### Lua Example
-`local integerValue = obj_turn_toward_object(obj, target, angleIndex, turnAmount)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| target | [Object](structs.md#Object) |
-| angleIndex | `integer` |
-| turnAmount | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_parent_relative_pos](#obj_set_parent_relative_pos)
-
-### Lua Example
-`obj_set_parent_relative_pos(obj, relX, relY, relZ)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| relX | `integer` |
-| relY | `integer` |
-| relZ | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_parent_relative_pos(struct Object *obj, s16 relX, s16 relY, s16 relZ);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_pos](#obj_set_pos)
-
-### Lua Example
-`obj_set_pos(obj, x, y, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| x | `integer` |
-| y | `integer` |
-| z | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_pos(struct Object *obj, s16 x, s16 y, s16 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_angle](#obj_set_angle)
-
-### Lua Example
-`obj_set_angle(obj, pitch, yaw, roll)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pitch | `integer` |
-| yaw | `integer` |
-| roll | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_move_angle](#obj_set_move_angle)
-
-### Lua Example
-`obj_set_move_angle(obj, pitch, yaw, roll)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pitch | `integer` |
-| yaw | `integer` |
-| roll | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_move_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_face_angle](#obj_set_face_angle)
-
-### Lua Example
-`obj_set_face_angle(obj, pitch, yaw, roll)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pitch | `integer` |
-| yaw | `integer` |
-| roll | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_face_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_gfx_angle](#obj_set_gfx_angle)
-
-### Lua Example
-`obj_set_gfx_angle(obj, pitch, yaw, roll)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| pitch | `integer` |
-| yaw | `integer` |
-| roll | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_gfx_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_gfx_pos](#obj_set_gfx_pos)
-
-### Lua Example
-`obj_set_gfx_pos(obj, x, y, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_gfx_pos(struct Object *obj, f32 x, f32 y, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_gfx_scale](#obj_set_gfx_scale)
-
-### Lua Example
-`obj_set_gfx_scale(obj, x, y, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_gfx_scale(struct Object *obj, f32 x, f32 y, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_water_droplet](#spawn_water_droplet)
-
-### Lua Example
-`local ObjectValue = spawn_water_droplet(parent, params)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| parent | [Object](structs.md#Object) |
-| params | [WaterDropletParams](structs.md#WaterDropletParams) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_build_relative_transform](#obj_build_relative_transform)
-
-### Lua Example
-`obj_build_relative_transform(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_build_relative_transform(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_using_vel](#cur_obj_move_using_vel)
-
-### Lua Example
-`cur_obj_move_using_vel()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_using_vel(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_graph_y_offset](#obj_copy_graph_y_offset)
-
-### Lua Example
-`obj_copy_graph_y_offset(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_graph_y_offset(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_pos_and_angle](#obj_copy_pos_and_angle)
-
-### Lua Example
-`obj_copy_pos_and_angle(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_pos_and_angle(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_pos](#obj_copy_pos)
-
-### Lua Example
-`obj_copy_pos(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_pos(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_angle](#obj_copy_angle)
-
-### Lua Example
-`obj_copy_angle(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_angle(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_gfx_pos_from_pos](#obj_set_gfx_pos_from_pos)
-
-### Lua Example
-`obj_set_gfx_pos_from_pos(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_gfx_pos_from_pos(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_init_animation](#obj_init_animation)
-
-### Lua Example
-`obj_init_animation(obj, animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| animIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_init_animation(struct Object *obj, s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [linear_mtxf_mul_vec3f](#linear_mtxf_mul_vec3f)
-
-### Description
-Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
-
-### Lua Example
-`linear_mtxf_mul_vec3f(m, dst, v)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [Mat4](structs.md#Mat4) |
-| dst | [Vec3f](structs.md#Vec3f) |
-| v | [Vec3f](structs.md#Vec3f) |
-
-### Returns
-- None
-
-### C Prototype
-`void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);`
-
-[:arrow_up_small:](#)
-
-
-
-## [linear_mtxf_transpose_mul_vec3f](#linear_mtxf_transpose_mul_vec3f)
-
-### Description
-Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
-
-### Lua Example
-`linear_mtxf_transpose_mul_vec3f(m, dst, v)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [Mat4](structs.md#Mat4) |
-| dst | [Vec3f](structs.md#Vec3f) |
-| v | [Vec3f](structs.md#Vec3f) |
-
-### Returns
-- None
-
-### C Prototype
-`void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_apply_scale_to_transform](#obj_apply_scale_to_transform)
-
-### Lua Example
-`obj_apply_scale_to_transform(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_apply_scale_to_transform(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_scale](#obj_copy_scale)
-
-### Lua Example
-`obj_copy_scale(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_scale(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_scale_xyz](#obj_scale_xyz)
-
-### Lua Example
-`obj_scale_xyz(obj, xScale, yScale, zScale)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| xScale | `number` |
-| yScale | `number` |
-| zScale | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_scale_xyz(struct Object *obj, f32 xScale, f32 yScale, f32 zScale);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_scale](#obj_scale)
-
-### Lua Example
-`obj_scale(obj, scale)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| scale | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_scale(struct Object *obj, f32 scale);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_scale](#cur_obj_scale)
-
-### Lua Example
-`cur_obj_scale(scale)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| scale | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_scale(f32 scale);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation](#cur_obj_init_animation)
-
-### Lua Example
-`cur_obj_init_animation(animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_init_animation(s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation_with_sound](#cur_obj_init_animation_with_sound)
-
-### Lua Example
-`cur_obj_init_animation_with_sound(animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_init_animation_with_sound(s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_init_animation_with_accel_and_sound](#obj_init_animation_with_accel_and_sound)
-
-### Lua Example
-`obj_init_animation_with_accel_and_sound(obj, animIndex, accel)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| animIndex | `integer` |
-| accel | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation_with_accel_and_sound](#cur_obj_init_animation_with_accel_and_sound)
-
-### Lua Example
-`cur_obj_init_animation_with_accel_and_sound(animIndex, accel)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-| accel | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_init_animation_with_sound](#obj_init_animation_with_sound)
-
-### Lua Example
-`obj_init_animation_with_sound(obj, animations, animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| animations | [AnimationTable](structs.md#AnimationTable) |
-| animIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_init_animation_with_sound(struct Object *obj, const struct AnimationTable* animations, s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_enable_rendering_and_become_tangible](#cur_obj_enable_rendering_and_become_tangible)
-
-### Lua Example
-`cur_obj_enable_rendering_and_become_tangible(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_enable_rendering_and_become_tangible(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_enable_rendering](#cur_obj_enable_rendering)
-
-### Lua Example
-`cur_obj_enable_rendering()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_enable_rendering(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_disable_rendering_and_become_intangible](#cur_obj_disable_rendering_and_become_intangible)
-
-### Lua Example
-`cur_obj_disable_rendering_and_become_intangible(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_disable_rendering_and_become_intangible(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_disable_rendering](#cur_obj_disable_rendering)
-
-### Lua Example
-`cur_obj_disable_rendering()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_disable_rendering(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_unhide](#cur_obj_unhide)
-
-### Lua Example
-`cur_obj_unhide()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_unhide(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_hide](#cur_obj_hide)
-
-### Lua Example
-`cur_obj_hide()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_hide(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_relative](#cur_obj_set_pos_relative)
-
-### Lua Example
-`cur_obj_set_pos_relative(other, dleft, dy, dforward)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| other | [Object](structs.md#Object) |
-| dleft | `number` |
-| dy | `number` |
-| dforward | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_relative_to_parent](#cur_obj_set_pos_relative_to_parent)
-
-### Lua Example
-`cur_obj_set_pos_relative_to_parent(dleft, dy, dforward)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dleft | `number` |
-| dy | `number` |
-| dforward | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_enable_rendering_2](#cur_obj_enable_rendering_2)
-
-### Lua Example
-`cur_obj_enable_rendering_2()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_enable_rendering_2(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_unused_init_on_floor](#cur_obj_unused_init_on_floor)
-
-### Lua Example
-`cur_obj_unused_init_on_floor()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_unused_init_on_floor(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_face_angle_to_move_angle](#obj_set_face_angle_to_move_angle)
-
-### Lua Example
-`obj_set_face_angle_to_move_angle(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_face_angle_to_move_angle(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_object_list_from_behavior](#get_object_list_from_behavior)
-
-### Lua Example
-`local integerValue = get_object_list_from_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`u32 get_object_list_from_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_nearest_object_with_behavior](#cur_obj_nearest_object_with_behavior)
-
-### Lua Example
-`local ObjectValue = cur_obj_nearest_object_with_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_dist_to_nearest_object_with_behavior](#cur_obj_dist_to_nearest_object_with_behavior)
-
-### Lua Example
-`local numberValue = cur_obj_dist_to_nearest_object_with_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_find_nearest_pole](#cur_obj_find_nearest_pole)
-
-### Lua Example
-`local ObjectValue = cur_obj_find_nearest_pole()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object* cur_obj_find_nearest_pole(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_find_nearest_object_with_behavior](#cur_obj_find_nearest_object_with_behavior)
-
-### Lua Example
-`local ObjectValue = cur_obj_find_nearest_object_with_behavior(behavior, dist)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-| dist | `Pointer` <`number`> |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_count_objects_with_behavior](#cur_obj_count_objects_with_behavior)
-
-### Lua Example
-`local integerValue = cur_obj_count_objects_with_behavior(behavior, dist)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-| dist | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_unimportant_object](#find_unimportant_object)
-
-### Lua Example
-`local ObjectValue = find_unimportant_object()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *find_unimportant_object(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [count_unimportant_objects](#count_unimportant_objects)
-
-### Lua Example
-`local integerValue = count_unimportant_objects()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 count_unimportant_objects(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [count_objects_with_behavior](#count_objects_with_behavior)
-
-### Lua Example
-`local integerValue = count_objects_with_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 count_objects_with_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_object_with_behavior](#find_object_with_behavior)
-
-### Lua Example
-`local ObjectValue = find_object_with_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *find_object_with_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_find_nearby_held_actor](#cur_obj_find_nearby_held_actor)
-
-### Lua Example
-`local ObjectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-| maxDist | `number` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_reset_timer_and_subaction](#cur_obj_reset_timer_and_subaction)
-
-### Lua Example
-`cur_obj_reset_timer_and_subaction()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_reset_timer_and_subaction(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_change_action](#cur_obj_change_action)
-
-### Lua Example
-`cur_obj_change_action(action)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| action | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_change_action(s32 action);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_vel_from_mario_vel](#cur_obj_set_vel_from_mario_vel)
-
-### Lua Example
-`cur_obj_set_vel_from_mario_vel(m, f12, f14)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| f12 | `number` |
-| f14 | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_reverse_animation](#cur_obj_reverse_animation)
-
-### Lua Example
-`cur_obj_reverse_animation()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_reverse_animation(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_extend_animation_if_at_end](#cur_obj_extend_animation_if_at_end)
-
-### Lua Example
-`cur_obj_extend_animation_if_at_end()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_extend_animation_if_at_end(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_if_near_animation_end](#cur_obj_check_if_near_animation_end)
-
-### Lua Example
-`local integerValue = cur_obj_check_if_near_animation_end()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_if_near_animation_end(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_if_at_animation_end](#cur_obj_check_if_at_animation_end)
-
-### Lua Example
-`local integerValue = cur_obj_check_if_at_animation_end()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_if_at_animation_end(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_anim_frame](#cur_obj_check_anim_frame)
-
-### Lua Example
-`local integerValue = cur_obj_check_anim_frame(frame)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| frame | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_anim_frame(s32 frame);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_anim_frame_in_range](#cur_obj_check_anim_frame_in_range)
-
-### Lua Example
-`local integerValue = cur_obj_check_anim_frame_in_range(startFrame, rangeLength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| startFrame | `integer` |
-| rangeLength | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame)
-
-### Lua Example
-`local integerValue = cur_obj_check_frame_prior_current_frame(a0)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | `Pointer` <`integer`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);`
-
-[:arrow_up_small:](#)
-
-
-
-## [mario_is_in_air_action](#mario_is_in_air_action)
-
-### Lua Example
-`local integerValue = mario_is_in_air_action(m)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 mario_is_in_air_action(struct MarioState* m);`
-
-[:arrow_up_small:](#)
-
-
-
-## [mario_is_dive_sliding](#mario_is_dive_sliding)
-
-### Lua Example
-`local integerValue = mario_is_dive_sliding(m)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 mario_is_dive_sliding(struct MarioState* m);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_y_vel_and_animation](#cur_obj_set_y_vel_and_animation)
-
-### Lua Example
-`cur_obj_set_y_vel_and_animation(sp18, sp1C)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp18 | `number` |
-| sp1C | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_unrender_and_reset_state](#cur_obj_unrender_and_reset_state)
-
-### Lua Example
-`cur_obj_unrender_and_reset_state(sp18, sp1C)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp18 | `integer` |
-| sp1C | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_after_thrown_or_dropped](#cur_obj_move_after_thrown_or_dropped)
-
-### Lua Example
-`cur_obj_move_after_thrown_or_dropped(forwardVel, velY)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| forwardVel | `number` |
-| velY | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_get_thrown_or_placed](#cur_obj_get_thrown_or_placed)
-
-### Lua Example
-`cur_obj_get_thrown_or_placed(forwardVel, velY, thrownAction)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| forwardVel | `number` |
-| velY | `number` |
-| thrownAction | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_get_dropped](#cur_obj_get_dropped)
-
-### Lua Example
-`cur_obj_get_dropped()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_get_dropped(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [mario_set_flag](#mario_set_flag)
-
-### Lua Example
-`mario_set_flag(flag)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| flag | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void mario_set_flag(s32 flag);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_clear_interact_status_flag](#cur_obj_clear_interact_status_flag)
-
-### Lua Example
-`local integerValue = cur_obj_clear_interact_status_flag(flag)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| flag | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_clear_interact_status_flag(s32 flag);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_mark_for_deletion](#obj_mark_for_deletion)
-
-### Description
-Marks an object to be unloaded at the end of the frame
-
-### Lua Example
-`obj_mark_for_deletion(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_mark_for_deletion(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_disable](#cur_obj_disable)
-
-### Lua Example
-`cur_obj_disable()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_disable(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_become_intangible](#cur_obj_become_intangible)
-
-### Lua Example
-`cur_obj_become_intangible()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_become_intangible(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_become_tangible](#cur_obj_become_tangible)
-
-### Lua Example
-`cur_obj_become_tangible()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_become_tangible(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_become_tangible](#obj_become_tangible)
-
-### Lua Example
-`obj_become_tangible(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_become_tangible(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_update_floor_height](#cur_obj_update_floor_height)
-
-### Lua Example
-`cur_obj_update_floor_height()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_update_floor_height(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_update_floor_height_and_get_floor](#cur_obj_update_floor_height_and_get_floor)
-
-### Lua Example
-`local SurfaceValue = cur_obj_update_floor_height_and_get_floor()`
-
-### Parameters
-- None
-
-### Returns
-[Surface](structs.md#Surface)
-
-### C Prototype
-`struct Surface *cur_obj_update_floor_height_and_get_floor(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [apply_drag_to_value](#apply_drag_to_value)
-
-### Lua Example
-`apply_drag_to_value(value, dragStrength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `Pointer` <`number`> |
-| dragStrength | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void apply_drag_to_value(f32 *value, f32 dragStrength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_apply_drag_xz](#cur_obj_apply_drag_xz)
-
-### Lua Example
-`cur_obj_apply_drag_xz(dragStrength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dragStrength | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_apply_drag_xz(f32 dragStrength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_xz](#cur_obj_move_xz)
-
-### Lua Example
-`local integerValue = cur_obj_move_xz(steepSlopeNormalY, careAboutEdgesAndSteepSlopes)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| steepSlopeNormalY | `number` |
-| careAboutEdgesAndSteepSlopes | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_update_underwater_flags](#cur_obj_move_update_underwater_flags)
-
-### Lua Example
-`cur_obj_move_update_underwater_flags()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_update_underwater_flags(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_update_ground_air_flags](#cur_obj_move_update_ground_air_flags)
-
-### Lua Example
-`cur_obj_move_update_ground_air_flags(gravity, bounciness)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| gravity | `number` |
-| bounciness | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_y_and_get_water_level](#cur_obj_move_y_and_get_water_level)
-
-### Lua Example
-`local numberValue = cur_obj_move_y_and_get_water_level(gravity, buoyancy)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| gravity | `number` |
-| buoyancy | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_y](#cur_obj_move_y)
-
-### Lua Example
-`cur_obj_move_y(gravity, bounciness, buoyancy)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| gravity | `number` |
-| bounciness | `number` |
-| buoyancy | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_unused_resolve_wall_collisions](#cur_obj_unused_resolve_wall_collisions)
-
-### Lua Example
-`cur_obj_unused_resolve_wall_collisions(offsetY, radius)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| offsetY | `number` |
-| radius | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius);`
-
-[:arrow_up_small:](#)
-
-
-
-## [abs_angle_diff](#abs_angle_diff)
-
-### Lua Example
-`local integerValue = abs_angle_diff(x0, x1)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x0 | `integer` |
-| x1 | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 abs_angle_diff(s16 x0, s16 x1);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_xz_using_fvel_and_yaw](#cur_obj_move_xz_using_fvel_and_yaw)
-
-### Lua Example
-`cur_obj_move_xz_using_fvel_and_yaw()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_xz_using_fvel_and_yaw(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_y_with_terminal_vel](#cur_obj_move_y_with_terminal_vel)
-
-### Lua Example
-`cur_obj_move_y_with_terminal_vel()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_y_with_terminal_vel(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_compute_vel_xz](#cur_obj_compute_vel_xz)
-
-### Lua Example
-`cur_obj_compute_vel_xz()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_compute_vel_xz(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [increment_velocity_toward_range](#increment_velocity_toward_range)
-
-### Lua Example
-`local numberValue = increment_velocity_toward_range(value, center, zeroThreshold, increment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `number` |
-| center | `number` |
-| zeroThreshold | `number` |
-| increment | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 increment_velocity_toward_range(f32 value, f32 center, f32 zeroThreshold, f32 increment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_check_if_collided_with_object](#obj_check_if_collided_with_object)
-
-### Lua Example
-`local integerValue = obj_check_if_collided_with_object(obj1, obj2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj1 | [Object](structs.md#Object) |
-| obj2 | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_check_if_collided_with_object(struct Object *obj1, struct Object *obj2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_behavior](#cur_obj_set_behavior)
-
-### Lua Example
-`cur_obj_set_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_behavior](#obj_set_behavior)
-
-### Lua Example
-`obj_set_behavior(obj, behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_has_behavior](#cur_obj_has_behavior)
-
-### Lua Example
-`local integerValue = cur_obj_has_behavior(behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_has_behavior(const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_has_behavior](#obj_has_behavior)
-
-### Lua Example
-`local integerValue = obj_has_behavior(obj, behavior)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| behavior | `Pointer` <`BehaviorScript`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_lateral_dist_from_obj_to_home](#cur_obj_lateral_dist_from_obj_to_home)
-
-### Lua Example
-`local numberValue = cur_obj_lateral_dist_from_obj_to_home(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_lateral_dist_from_mario_to_home](#cur_obj_lateral_dist_from_mario_to_home)
-
-### Lua Example
-`local numberValue = cur_obj_lateral_dist_from_mario_to_home()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_lateral_dist_from_mario_to_home(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_lateral_dist_to_home](#cur_obj_lateral_dist_to_home)
-
-### Lua Example
-`local numberValue = cur_obj_lateral_dist_to_home()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_lateral_dist_to_home(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_outside_home_square](#cur_obj_outside_home_square)
-
-### Lua Example
-`local integerValue = cur_obj_outside_home_square(halfLength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| halfLength | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_outside_home_square(f32 halfLength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_outside_home_rectangle](#cur_obj_outside_home_rectangle)
-
-### Lua Example
-`local integerValue = cur_obj_outside_home_rectangle(minX, maxX, minZ, maxZ)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| minX | `number` |
-| maxX | `number` |
-| minZ | `number` |
-| maxZ | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_to_home](#cur_obj_set_pos_to_home)
-
-### Lua Example
-`cur_obj_set_pos_to_home()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_to_home(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_to_home_and_stop](#cur_obj_set_pos_to_home_and_stop)
-
-### Lua Example
-`cur_obj_set_pos_to_home_and_stop()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_to_home_and_stop(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_shake_y](#cur_obj_shake_y)
-
-### Lua Example
-`cur_obj_shake_y(amount)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| amount | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_shake_y(f32 amount);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_start_cam_event](#cur_obj_start_cam_event)
-
-### Lua Example
-`cur_obj_start_cam_event(obj, cameraEvent)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| cameraEvent | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_mario_interact_hoot_if_in_range](#set_mario_interact_hoot_if_in_range)
-
-### Lua Example
-`set_mario_interact_hoot_if_in_range(sp0, sp4, sp8)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp0 | `integer` |
-| sp4 | `integer` |
-| sp8 | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_billboard](#obj_set_billboard)
-
-### Lua Example
-`obj_set_billboard(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_billboard(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_cylboard](#obj_set_cylboard)
-
-### Lua Example
-`obj_set_cylboard(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_cylboard(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_billboard_if_vanilla_cam](#cur_obj_set_billboard_if_vanilla_cam)
-
-### Lua Example
-`cur_obj_set_billboard_if_vanilla_cam()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_billboard_if_vanilla_cam(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_hitbox_radius_and_height](#obj_set_hitbox_radius_and_height)
-
-### Lua Example
-`obj_set_hitbox_radius_and_height(o, radius, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| radius | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_hitbox_radius_and_height(struct Object *o, f32 radius, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_hurtbox_radius_and_height](#obj_set_hurtbox_radius_and_height)
-
-### Lua Example
-`obj_set_hurtbox_radius_and_height(o, radius, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| radius | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_hurtbox_radius_and_height(struct Object *o, f32 radius, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_hitbox_radius_and_height](#cur_obj_set_hitbox_radius_and_height)
-
-### Lua Example
-`cur_obj_set_hitbox_radius_and_height(radius, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| radius | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_hurtbox_radius_and_height](#cur_obj_set_hurtbox_radius_and_height)
-
-### Lua Example
-`cur_obj_set_hurtbox_radius_and_height(radius, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| radius | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_spawn_loot_coins](#obj_spawn_loot_coins)
-
-### Lua Example
-`obj_spawn_loot_coins(obj, numCoins, sp30, coinBehavior, posJitter, model)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| numCoins | `integer` |
-| sp30 | `number` |
-| coinBehavior | `Pointer` <`BehaviorScript`> |
-| posJitter | `integer` |
-| model | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30, const BehaviorScript *coinBehavior, s16 posJitter, s16 model);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_spawn_loot_blue_coins](#obj_spawn_loot_blue_coins)
-
-### Lua Example
-`obj_spawn_loot_blue_coins(obj, numCoins, sp28, posJitter)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| numCoins | `integer` |
-| sp28 | `number` |
-| posJitter | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_spawn_loot_blue_coins(struct Object *obj, s32 numCoins, f32 sp28, s16 posJitter);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_spawn_loot_yellow_coins](#obj_spawn_loot_yellow_coins)
-
-### Lua Example
-`obj_spawn_loot_yellow_coins(obj, numCoins, sp28)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| numCoins | `integer` |
-| sp28 | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_spawn_loot_yellow_coins(struct Object *obj, s32 numCoins, f32 sp28);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_spawn_loot_coin_at_mario_pos](#cur_obj_spawn_loot_coin_at_mario_pos)
-
-### Lua Example
-`cur_obj_spawn_loot_coin_at_mario_pos(m)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_abs_y_dist_to_home](#cur_obj_abs_y_dist_to_home)
-
-### Lua Example
-`local numberValue = cur_obj_abs_y_dist_to_home()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 cur_obj_abs_y_dist_to_home(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_advance_looping_anim](#cur_obj_advance_looping_anim)
-
-### Lua Example
-`local integerValue = cur_obj_advance_looping_anim()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_advance_looping_anim(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_detect_steep_floor](#cur_obj_detect_steep_floor)
-
-### Lua Example
-`local integerValue = cur_obj_detect_steep_floor(steepAngleDegrees)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| steepAngleDegrees | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_resolve_wall_collisions](#cur_obj_resolve_wall_collisions)
-
-### Lua Example
-`local integerValue = cur_obj_resolve_wall_collisions()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_resolve_wall_collisions(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_update_floor](#cur_obj_update_floor)
-
-### Lua Example
-`cur_obj_update_floor()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_update_floor(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_update_floor_and_resolve_wall_collisions](#cur_obj_update_floor_and_resolve_wall_collisions)
-
-### Lua Example
-`cur_obj_update_floor_and_resolve_wall_collisions(steepSlopeDegrees)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| steepSlopeDegrees | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_update_floor_and_walls](#cur_obj_update_floor_and_walls)
-
-### Lua Example
-`cur_obj_update_floor_and_walls()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_update_floor_and_walls(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_standard](#cur_obj_move_standard)
-
-### Lua Example
-`cur_obj_move_standard(steepSlopeAngleDegrees)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| steepSlopeAngleDegrees | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_standard(s16 steepSlopeAngleDegrees);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_within_12k_bounds](#cur_obj_within_12k_bounds)
-
-### Lua Example
-`local integerValue = cur_obj_within_12k_bounds()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_within_12k_bounds(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_using_vel_and_gravity](#cur_obj_move_using_vel_and_gravity)
-
-### Lua Example
-`cur_obj_move_using_vel_and_gravity()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_using_vel_and_gravity(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_using_fvel_and_gravity](#cur_obj_move_using_fvel_and_gravity)
-
-### Lua Example
-`cur_obj_move_using_fvel_and_gravity()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_move_using_fvel_and_gravity(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_pos_relative](#obj_set_pos_relative)
-
-### Lua Example
-`obj_set_pos_relative(obj, other, dleft, dy, dforward)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| other | [Object](structs.md#Object) |
-| dleft | `number` |
-| dy | `number` |
-| dforward | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, f32 dforward);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_angle_to_home](#cur_obj_angle_to_home)
-
-### Lua Example
-`local integerValue = cur_obj_angle_to_home()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 cur_obj_angle_to_home(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_gfx_pos_at_obj_pos](#obj_set_gfx_pos_at_obj_pos)
-
-### Lua Example
-`obj_set_gfx_pos_at_obj_pos(obj1, obj2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj1 | [Object](structs.md#Object) |
-| obj2 | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_translate_local](#obj_translate_local)
-
-### Description
-Transforms the vector at `localTranslateIndex` into the object's local coordinates, and then adds it to the vector at `posIndex`
-
-### Lua Example
-`obj_translate_local(obj, posIndex, localTranslateIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| posIndex | `integer` |
-| localTranslateIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_build_transform_from_pos_and_angle](#obj_build_transform_from_pos_and_angle)
-
-### Lua Example
-`obj_build_transform_from_pos_and_angle(obj, posIndex, angleIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| posIndex | `integer` |
-| angleIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s16 angleIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_throw_matrix_from_transform](#obj_set_throw_matrix_from_transform)
-
-### Lua Example
-`obj_set_throw_matrix_from_transform(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_throw_matrix_from_transform(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_build_transform_relative_to_parent](#obj_build_transform_relative_to_parent)
-
-### Lua Example
-`obj_build_transform_relative_to_parent(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_build_transform_relative_to_parent(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_create_transform_from_self](#obj_create_transform_from_self)
-
-### Lua Example
-`obj_create_transform_from_self(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_create_transform_from_self(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_rotate_move_angle_using_vel](#cur_obj_rotate_move_angle_using_vel)
-
-### Lua Example
-`cur_obj_rotate_move_angle_using_vel()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_rotate_move_angle_using_vel(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_rotate_face_angle_using_vel](#cur_obj_rotate_face_angle_using_vel)
-
-### Lua Example
-`cur_obj_rotate_face_angle_using_vel()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_rotate_face_angle_using_vel(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_face_angle_to_move_angle](#cur_obj_set_face_angle_to_move_angle)
-
-### Lua Example
-`cur_obj_set_face_angle_to_move_angle()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_face_angle_to_move_angle(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_follow_path](#cur_obj_follow_path)
-
-### Lua Example
-`local integerValue = cur_obj_follow_path(unusedArg)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| unusedArg | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_follow_path(UNUSED s32 unusedArg);`
-
-[:arrow_up_small:](#)
-
-
-
-## [chain_segment_init](#chain_segment_init)
-
-### Lua Example
-`chain_segment_init(segment)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| segment | [ChainSegment](structs.md#ChainSegment) |
-
-### Returns
-- None
-
-### C Prototype
-`void chain_segment_init(struct ChainSegment *segment);`
-
-[:arrow_up_small:](#)
-
-
-
-## [random_f32_around_zero](#random_f32_around_zero)
-
-### Lua Example
-`local numberValue = random_f32_around_zero(diameter)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| diameter | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 random_f32_around_zero(f32 diameter);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_scale_random](#obj_scale_random)
-
-### Lua Example
-`obj_scale_random(obj, rangeLength, minScale)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| rangeLength | `number` |
-| minScale | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_scale_random(struct Object *obj, f32 rangeLength, f32 minScale);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_translate_xyz_random](#obj_translate_xyz_random)
-
-### Lua Example
-`obj_translate_xyz_random(obj, rangeLength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| rangeLength | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_translate_xyz_random(struct Object *obj, f32 rangeLength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_translate_xz_random](#obj_translate_xz_random)
-
-### Lua Example
-`obj_translate_xz_random(obj, rangeLength)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| rangeLength | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_translate_xz_random(struct Object *obj, f32 rangeLength);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_build_vel_from_transform](#obj_build_vel_from_transform)
-
-### Lua Example
-`obj_build_vel_from_transform(a0)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_build_vel_from_transform(struct Object *a0);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_via_transform](#cur_obj_set_pos_via_transform)
-
-### Lua Example
-`cur_obj_set_pos_via_transform()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_via_transform(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_reflect_move_angle_off_wall](#cur_obj_reflect_move_angle_off_wall)
-
-### Lua Example
-`local integerValue = cur_obj_reflect_move_angle_off_wall()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 cur_obj_reflect_move_angle_off_wall(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_spawn_particles](#cur_obj_spawn_particles)
-
-### Lua Example
-`cur_obj_spawn_particles(info)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| info | [SpawnParticlesInfo](structs.md#SpawnParticlesInfo) |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_spawn_particles(struct SpawnParticlesInfo *info);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_hitbox](#obj_set_hitbox)
-
-### Lua Example
-`obj_set_hitbox(obj, hitbox)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);`
-
-[:arrow_up_small:](#)
-
-
-
-## [signum_positive](#signum_positive)
-
-### Lua Example
-`local integerValue = signum_positive(x)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 signum_positive(s32 x);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_wait_then_blink](#cur_obj_wait_then_blink)
-
-### Lua Example
-`local integerValue = cur_obj_wait_then_blink(timeUntilBlinking, numBlinks)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| timeUntilBlinking | `integer` |
-| numBlinks | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_is_mario_ground_pounding_platform](#cur_obj_is_mario_ground_pounding_platform)
-
-### Lua Example
-`local integerValue = cur_obj_is_mario_ground_pounding_platform()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_is_mario_ground_pounding_platform(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_mario_ground_pounding_platform](#obj_is_mario_ground_pounding_platform)
-
-### Lua Example
-`local integerValue = obj_is_mario_ground_pounding_platform(m, obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_mist_particles](#spawn_mist_particles)
-
-### Lua Example
-`spawn_mist_particles()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void spawn_mist_particles(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_mist_particles_with_sound](#spawn_mist_particles_with_sound)
-
-### Lua Example
-`spawn_mist_particles_with_sound(sp18)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp18 | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void spawn_mist_particles_with_sound(u32 sp18);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_push_mario_away](#cur_obj_push_mario_away)
-
-### Lua Example
-`cur_obj_push_mario_away(radius)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| radius | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_push_mario_away(f32 radius);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_push_mario_away_from_cylinder](#cur_obj_push_mario_away_from_cylinder)
-
-### Lua Example
-`cur_obj_push_mario_away_from_cylinder(radius, extentY)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| radius | `number` |
-| extentY | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY);`
-
-[:arrow_up_small:](#)
-
-
-
-## [bhv_dust_smoke_loop](#bhv_dust_smoke_loop)
-
-### Lua Example
-`bhv_dust_smoke_loop()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void bhv_dust_smoke_loop(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [stub_obj_helpers_3](#stub_obj_helpers_3)
-
-### Lua Example
-`stub_obj_helpers_3(sp0, sp4)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp0 | `integer` |
-| sp4 | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_scale_over_time](#cur_obj_scale_over_time)
-
-### Lua Example
-`cur_obj_scale_over_time(a0, a1, sp10, sp14)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | `integer` |
-| a1 | `integer` |
-| sp10 | `number` |
-| sp14 | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_pos_to_home_with_debug](#cur_obj_set_pos_to_home_with_debug)
-
-### Lua Example
-`cur_obj_set_pos_to_home_with_debug()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_pos_to_home_with_debug(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [stub_obj_helpers_4](#stub_obj_helpers_4)
-
-### Lua Example
-`stub_obj_helpers_4()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void stub_obj_helpers_4(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_is_mario_on_platform](#cur_obj_is_mario_on_platform)
-
-### Lua Example
-`local integerValue = cur_obj_is_mario_on_platform()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_is_mario_on_platform(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_is_any_player_on_platform](#cur_obj_is_any_player_on_platform)
-
-### Lua Example
-`local integerValue = cur_obj_is_any_player_on_platform()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_is_any_player_on_platform(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_shake_y_until](#cur_obj_shake_y_until)
-
-### Lua Example
-`local integerValue = cur_obj_shake_y_until(cycles, amount)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| cycles | `integer` |
-| amount | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_shake_y_until(s32 cycles, s32 amount);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_move_up_and_down](#cur_obj_move_up_and_down)
-
-### Lua Example
-`local integerValue = cur_obj_move_up_and_down(a0)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_move_up_and_down(s32 a0);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_star_with_no_lvl_exit](#spawn_star_with_no_lvl_exit)
-
-### Lua Example
-`local ObjectValue = spawn_star_with_no_lvl_exit(sp20, sp24)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp20 | `integer` |
-| sp24 | `integer` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_base_star_with_no_lvl_exit](#spawn_base_star_with_no_lvl_exit)
-
-### Lua Example
-`spawn_base_star_with_no_lvl_exit()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void spawn_base_star_with_no_lvl_exit(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [bit_shift_left](#bit_shift_left)
-
-### Lua Example
-`local integerValue = bit_shift_left(a0)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a0 | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 bit_shift_left(s32 a0);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_mario_far_away](#cur_obj_mario_far_away)
-
-### Lua Example
-`local integerValue = cur_obj_mario_far_away()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_mario_far_away(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [is_mario_moving_fast_or_in_air](#is_mario_moving_fast_or_in_air)
-
-### Lua Example
-`local integerValue = is_mario_moving_fast_or_in_air(speedThreshold)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| speedThreshold | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);`
-
-[:arrow_up_small:](#)
-
-
-
-## [is_item_in_array](#is_item_in_array)
-
-### Lua Example
-`local integerValue = is_item_in_array(item, array)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| item | `integer` |
-| array | `Pointer` <`integer`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 is_item_in_array(s8 item, s8 *array);`
-
-[:arrow_up_small:](#)
-
-
-
-## [bhv_init_room](#bhv_init_room)
-
-### Lua Example
-`bhv_init_room()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void bhv_init_room(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_enable_rendering_if_mario_in_room](#cur_obj_enable_rendering_if_mario_in_room)
-
-### Lua Example
-`cur_obj_enable_rendering_if_mario_in_room()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_enable_rendering_if_mario_in_room(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_hitbox_and_die_if_attacked](#cur_obj_set_hitbox_and_die_if_attacked)
-
-### Lua Example
-`local integerValue = cur_obj_set_hitbox_and_die_if_attacked(hitbox, deathSound, noLootCoins)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) |
-| deathSound | `integer` |
-| noLootCoins | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_explode_and_spawn_coins](#obj_explode_and_spawn_coins)
-
-### Lua Example
-`obj_explode_and_spawn_coins(sp18, sp1C)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| sp18 | `number` |
-| sp1C | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_if_hit_wall_bounce_away](#cur_obj_if_hit_wall_bounce_away)
-
-### Lua Example
-`cur_obj_if_hit_wall_bounce_away()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_if_hit_wall_bounce_away(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_hide_if_mario_far_away_y](#cur_obj_hide_if_mario_far_away_y)
-
-### Lua Example
-`local integerValue = cur_obj_hide_if_mario_far_away_y(distY)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| distY | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_hide_if_mario_far_away_y(f32 distY);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_hidden](#obj_is_hidden)
-
-### Lua Example
-`local integerValue = obj_is_hidden(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_is_hidden(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [enable_time_stop](#enable_time_stop)
-
-### Lua Example
-`enable_time_stop()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void enable_time_stop(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [enable_time_stop_if_alone](#enable_time_stop_if_alone)
-
-### Lua Example
-`enable_time_stop_if_alone()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void enable_time_stop_if_alone(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [disable_time_stop](#disable_time_stop)
-
-### Lua Example
-`disable_time_stop()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void disable_time_stop(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_time_stop_flags](#set_time_stop_flags)
-
-### Lua Example
-`set_time_stop_flags(flags)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| flags | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_time_stop_flags(s32 flags);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_time_stop_flags_if_alone](#set_time_stop_flags_if_alone)
-
-### Lua Example
-`set_time_stop_flags_if_alone(flags)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| flags | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_time_stop_flags_if_alone(s32 flags);`
-
-[:arrow_up_small:](#)
-
-
-
-## [clear_time_stop_flags](#clear_time_stop_flags)
-
-### Lua Example
-`clear_time_stop_flags(flags)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| flags | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void clear_time_stop_flags(s32 flags);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_can_mario_activate_textbox](#cur_obj_can_mario_activate_textbox)
-
-### Lua Example
-`local integerValue = cur_obj_can_mario_activate_textbox(m, radius, height, unused)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| radius | `number` |
-| height | `number` |
-| unused | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_can_mario_activate_textbox_2](#cur_obj_can_mario_activate_textbox_2)
-
-### Lua Example
-`local integerValue = cur_obj_can_mario_activate_textbox_2(m, radius, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| radius | `number` |
-| height | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_can_mario_activate_textbox_2(struct MarioState* m, f32 radius, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_end_dialog](#cur_obj_end_dialog)
-
-### Lua Example
-`cur_obj_end_dialog(m, dialogFlags, dialogResult)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| dialogFlags | `integer` |
-| dialogResult | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_has_model](#cur_obj_has_model)
-
-### Lua Example
-`local integerValue = cur_obj_has_model(modelID)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| modelID | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_has_model(u16 modelID);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_align_gfx_with_floor](#cur_obj_align_gfx_with_floor)
-
-### Lua Example
-`cur_obj_align_gfx_with_floor()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_align_gfx_with_floor(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [mario_is_within_rectangle](#mario_is_within_rectangle)
-
-### Lua Example
-`local integerValue = mario_is_within_rectangle(minX, maxX, minZ, maxZ)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| minX | `integer` |
-| maxX | `integer` |
-| minZ | `integer` |
-| maxZ | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_shake_screen](#cur_obj_shake_screen)
-
-### Lua Example
-`cur_obj_shake_screen(shake)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| shake | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_shake_screen(s32 shake);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_attack_collided_from_other_object](#obj_attack_collided_from_other_object)
-
-### Lua Example
-`local integerValue = obj_attack_collided_from_other_object(obj)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| obj | [Object](structs.md#Object) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_attack_collided_from_other_object(struct Object *obj);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_was_attacked_or_ground_pounded](#cur_obj_was_attacked_or_ground_pounded)
-
-### Lua Example
-`local integerValue = cur_obj_was_attacked_or_ground_pounded()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_was_attacked_or_ground_pounded(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_copy_behavior_params](#obj_copy_behavior_params)
-
-### Lua Example
-`obj_copy_behavior_params(dst, src)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dst | [Object](structs.md#Object) |
-| src | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_copy_behavior_params(struct Object *dst, struct Object *src);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation_and_anim_frame](#cur_obj_init_animation_and_anim_frame)
-
-### Lua Example
-`cur_obj_init_animation_and_anim_frame(animIndex, animFrame)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-| animFrame | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation_and_check_if_near_end](#cur_obj_init_animation_and_check_if_near_end)
-
-### Lua Example
-`local integerValue = cur_obj_init_animation_and_check_if_near_end(animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_init_animation_and_check_if_near_end(s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_init_animation_and_extend_if_at_end](#cur_obj_init_animation_and_extend_if_at_end)
-
-### Lua Example
-`cur_obj_init_animation_and_extend_if_at_end(animIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_init_animation_and_extend_if_at_end(s32 animIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_grabbed_mario](#cur_obj_check_grabbed_mario)
-
-### Lua Example
-`local integerValue = cur_obj_check_grabbed_mario()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_grabbed_mario(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [player_performed_grab_escape_action](#player_performed_grab_escape_action)
-
-### Lua Example
-`local integerValue = player_performed_grab_escape_action()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 player_performed_grab_escape_action(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_unused_play_footstep_sound](#cur_obj_unused_play_footstep_sound)
-
-### Lua Example
-`cur_obj_unused_play_footstep_sound(animFrame1, animFrame2, sound)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| animFrame1 | `integer` |
-| animFrame2 | `integer` |
-| sound | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 sound);`
-
-[:arrow_up_small:](#)
-
-
-
-## [enable_time_stop_including_mario](#enable_time_stop_including_mario)
-
-### Lua Example
-`enable_time_stop_including_mario()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void enable_time_stop_including_mario(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [disable_time_stop_including_mario](#disable_time_stop_including_mario)
-
-### Lua Example
-`disable_time_stop_including_mario()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void disable_time_stop_including_mario(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_check_interacted](#cur_obj_check_interacted)
-
-### Lua Example
-`local integerValue = cur_obj_check_interacted()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 cur_obj_check_interacted(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_spawn_loot_blue_coin](#cur_obj_spawn_loot_blue_coin)
-
-### Lua Example
-`cur_obj_spawn_loot_blue_coin()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_spawn_loot_blue_coin(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_spawn_star_at_y_offset](#cur_obj_spawn_star_at_y_offset)
-
-### Lua Example
-`cur_obj_spawn_star_at_y_offset(targetX, targetY, targetZ, offsetY)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| targetX | `number` |
-| targetY | `number` |
-| targetZ | `number` |
-| offsetY | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_set_home_once](#cur_obj_set_home_once)
-
-### Description
-Sets the current object's home only the first time it's called
-
-### Lua Example
-`cur_obj_set_home_once()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_set_home_once(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_trajectory_length](#get_trajectory_length)
-
-### Description
-Gets a trajectory's length
-
-### Lua Example
-`local integerValue = get_trajectory_length(trajectory)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| trajectory | `Pointer` <`Trajectory`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 get_trajectory_length(Trajectory* trajectory);`
-
-[:arrow_up_small:](#)
-
---
diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md
index a9fd4062c..de205a965 100644
--- a/docs/lua/functions-6.md
+++ b/docs/lua/functions-6.md
@@ -5,6 +5,4584 @@
[< prev](functions-5.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | 6 | [7](functions-7.md) | [next >](functions-7.md)]
+---
+# functions from object_helpers.c
+
+
+
+
+## [clear_move_flag](#clear_move_flag)
+
+### Lua Example
+`local integerValue = clear_move_flag(bitSet, flag)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| bitSet | `Pointer` <`integer`> |
+| flag | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 clear_move_flag(u32 *bitSet, s32 flag);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_room_override](#set_room_override)
+
+### Description
+Overrides the current room Mario is in. Set to -1 to reset override
+
+### Lua Example
+`set_room_override(room)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| room | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_room_override(s16 room);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_update_pos_from_parent_transformation](#obj_update_pos_from_parent_transformation)
+
+### Lua Example
+`obj_update_pos_from_parent_transformation(a0, a1)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | [Mat4](structs.md#Mat4) |
+| a1 | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_update_pos_from_parent_transformation(Mat4 a0, struct Object *a1);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_apply_scale_to_matrix](#obj_apply_scale_to_matrix)
+
+### Lua Example
+`obj_apply_scale_to_matrix(obj, dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| dst | [Mat4](structs.md#Mat4) |
+| src | [Mat4](structs.md#Mat4) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_apply_scale_to_matrix(struct Object *obj, OUT Mat4 dst, Mat4 src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [create_transformation_from_matrices](#create_transformation_from_matrices)
+
+### Lua Example
+`create_transformation_from_matrices(a0, a1, a2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | [Mat4](structs.md#Mat4) |
+| a1 | [Mat4](structs.md#Mat4) |
+| a2 | [Mat4](structs.md#Mat4) |
+
+### Returns
+- None
+
+### C Prototype
+`void create_transformation_from_matrices(OUT Mat4 a0, Mat4 a1, Mat4 a2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_held_state](#obj_set_held_state)
+
+### Lua Example
+`obj_set_held_state(obj, heldBehavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| heldBehavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [lateral_dist_between_objects](#lateral_dist_between_objects)
+
+### Lua Example
+`local numberValue = lateral_dist_between_objects(obj1, obj2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj1 | [Object](structs.md#Object) |
+| obj2 | [Object](structs.md#Object) |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [dist_between_objects](#dist_between_objects)
+
+### Lua Example
+`local numberValue = dist_between_objects(obj1, obj2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj1 | [Object](structs.md#Object) |
+| obj2 | [Object](structs.md#Object) |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 dist_between_objects(struct Object *obj1, struct Object *obj2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [dist_between_object_and_point](#dist_between_object_and_point)
+
+### Lua Example
+`local numberValue = dist_between_object_and_point(obj, pointX, pointY, pointZ)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pointX | `number` |
+| pointY | `number` |
+| pointZ | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 dist_between_object_and_point(struct Object *obj, f32 pointX, f32 pointY, f32 pointZ);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_forward_vel_approach_upward](#cur_obj_forward_vel_approach_upward)
+
+### Lua Example
+`cur_obj_forward_vel_approach_upward(target, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| target | `number` |
+| increment | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_forward_vel_approach_upward(f32 target, f32 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [approach_f32_signed](#approach_f32_signed)
+
+### Lua Example
+`local integerValue = approach_f32_signed(value, target, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `Pointer` <`number`> |
+| target | `number` |
+| increment | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 approach_f32_signed(f32 *value, f32 target, f32 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [approach_f32_symmetric](#approach_f32_symmetric)
+
+### Lua Example
+`local numberValue = approach_f32_symmetric(value, target, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `number` |
+| target | `number` |
+| increment | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 approach_f32_symmetric(f32 value, f32 target, f32 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [approach_s16_symmetric](#approach_s16_symmetric)
+
+### Lua Example
+`local integerValue = approach_s16_symmetric(value, target, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `integer` |
+| target | `integer` |
+| increment | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 approach_s16_symmetric(s16 value, s16 target, s16 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_rotate_yaw_toward](#cur_obj_rotate_yaw_toward)
+
+### Lua Example
+`local integerValue = cur_obj_rotate_yaw_toward(target, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| target | `integer` |
+| increment | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_rotate_yaw_toward(s16 target, s16 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_angle_to_object](#obj_angle_to_object)
+
+### Lua Example
+`local integerValue = obj_angle_to_object(obj1, obj2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj1 | [Object](structs.md#Object) |
+| obj2 | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 obj_angle_to_object(struct Object *obj1, struct Object *obj2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_pitch_to_object](#obj_pitch_to_object)
+
+### Lua Example
+`local integerValue = obj_pitch_to_object(obj, target)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| target | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 obj_pitch_to_object(struct Object* obj, struct Object* target);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_angle_to_point](#obj_angle_to_point)
+
+### Lua Example
+`local integerValue = obj_angle_to_point(obj, pointX, pointZ)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pointX | `number` |
+| pointZ | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 obj_angle_to_point(struct Object *obj, f32 pointX, f32 pointZ);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_turn_toward_object](#obj_turn_toward_object)
+
+### Lua Example
+`local integerValue = obj_turn_toward_object(obj, target, angleIndex, turnAmount)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| target | [Object](structs.md#Object) |
+| angleIndex | `integer` |
+| turnAmount | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleIndex, s16 turnAmount);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_parent_relative_pos](#obj_set_parent_relative_pos)
+
+### Lua Example
+`obj_set_parent_relative_pos(obj, relX, relY, relZ)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| relX | `integer` |
+| relY | `integer` |
+| relZ | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_parent_relative_pos(struct Object *obj, s16 relX, s16 relY, s16 relZ);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_pos](#obj_set_pos)
+
+### Lua Example
+`obj_set_pos(obj, x, y, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| x | `integer` |
+| y | `integer` |
+| z | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_pos(struct Object *obj, s16 x, s16 y, s16 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_angle](#obj_set_angle)
+
+### Lua Example
+`obj_set_angle(obj, pitch, yaw, roll)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pitch | `integer` |
+| yaw | `integer` |
+| roll | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_move_angle](#obj_set_move_angle)
+
+### Lua Example
+`obj_set_move_angle(obj, pitch, yaw, roll)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pitch | `integer` |
+| yaw | `integer` |
+| roll | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_move_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_face_angle](#obj_set_face_angle)
+
+### Lua Example
+`obj_set_face_angle(obj, pitch, yaw, roll)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pitch | `integer` |
+| yaw | `integer` |
+| roll | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_face_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_gfx_angle](#obj_set_gfx_angle)
+
+### Lua Example
+`obj_set_gfx_angle(obj, pitch, yaw, roll)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| pitch | `integer` |
+| yaw | `integer` |
+| roll | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_gfx_angle(struct Object *obj, s16 pitch, s16 yaw, s16 roll);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_gfx_pos](#obj_set_gfx_pos)
+
+### Lua Example
+`obj_set_gfx_pos(obj, x, y, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_gfx_pos(struct Object *obj, f32 x, f32 y, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_gfx_scale](#obj_set_gfx_scale)
+
+### Lua Example
+`obj_set_gfx_scale(obj, x, y, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_gfx_scale(struct Object *obj, f32 x, f32 y, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_water_droplet](#spawn_water_droplet)
+
+### Lua Example
+`local ObjectValue = spawn_water_droplet(parent, params)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| parent | [Object](structs.md#Object) |
+| params | [WaterDropletParams](structs.md#WaterDropletParams) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_build_relative_transform](#obj_build_relative_transform)
+
+### Lua Example
+`obj_build_relative_transform(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_build_relative_transform(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_using_vel](#cur_obj_move_using_vel)
+
+### Lua Example
+`cur_obj_move_using_vel()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_using_vel(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_graph_y_offset](#obj_copy_graph_y_offset)
+
+### Lua Example
+`obj_copy_graph_y_offset(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_graph_y_offset(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_pos_and_angle](#obj_copy_pos_and_angle)
+
+### Lua Example
+`obj_copy_pos_and_angle(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_pos_and_angle(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_pos](#obj_copy_pos)
+
+### Lua Example
+`obj_copy_pos(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_pos(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_angle](#obj_copy_angle)
+
+### Lua Example
+`obj_copy_angle(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_angle(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_gfx_pos_from_pos](#obj_set_gfx_pos_from_pos)
+
+### Lua Example
+`obj_set_gfx_pos_from_pos(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_gfx_pos_from_pos(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_init_animation](#obj_init_animation)
+
+### Lua Example
+`obj_init_animation(obj, animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| animIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_init_animation(struct Object *obj, s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [linear_mtxf_mul_vec3f](#linear_mtxf_mul_vec3f)
+
+### Description
+Multiplies a vector by a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
+
+### Lua Example
+`linear_mtxf_mul_vec3f(m, dst, v)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [Mat4](structs.md#Mat4) |
+| dst | [Vec3f](structs.md#Vec3f) |
+| v | [Vec3f](structs.md#Vec3f) |
+
+### Returns
+- None
+
+### C Prototype
+`void linear_mtxf_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);`
+
+[:arrow_up_small:](#)
+
+
+
+## [linear_mtxf_transpose_mul_vec3f](#linear_mtxf_transpose_mul_vec3f)
+
+### Description
+Multiplies a vector by the transpose of a matrix of the form: `| ? ? ? 0 |` `| ? ? ? 0 |` `| ? ? ? 0 |` `| 0 0 0 1 |` i.e. a matrix representing a linear transformation over 3 space
+
+### Lua Example
+`linear_mtxf_transpose_mul_vec3f(m, dst, v)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [Mat4](structs.md#Mat4) |
+| dst | [Vec3f](structs.md#Vec3f) |
+| v | [Vec3f](structs.md#Vec3f) |
+
+### Returns
+- None
+
+### C Prototype
+`void linear_mtxf_transpose_mul_vec3f(Mat4 m, OUT Vec3f dst, Vec3f v);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_apply_scale_to_transform](#obj_apply_scale_to_transform)
+
+### Lua Example
+`obj_apply_scale_to_transform(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_apply_scale_to_transform(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_scale](#obj_copy_scale)
+
+### Lua Example
+`obj_copy_scale(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_scale(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_scale_xyz](#obj_scale_xyz)
+
+### Lua Example
+`obj_scale_xyz(obj, xScale, yScale, zScale)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| xScale | `number` |
+| yScale | `number` |
+| zScale | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_scale_xyz(struct Object *obj, f32 xScale, f32 yScale, f32 zScale);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_scale](#obj_scale)
+
+### Lua Example
+`obj_scale(obj, scale)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| scale | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_scale(struct Object *obj, f32 scale);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_scale](#cur_obj_scale)
+
+### Lua Example
+`cur_obj_scale(scale)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| scale | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_scale(f32 scale);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation](#cur_obj_init_animation)
+
+### Lua Example
+`cur_obj_init_animation(animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_init_animation(s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation_with_sound](#cur_obj_init_animation_with_sound)
+
+### Lua Example
+`cur_obj_init_animation_with_sound(animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_init_animation_with_sound(s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_init_animation_with_accel_and_sound](#obj_init_animation_with_accel_and_sound)
+
+### Lua Example
+`obj_init_animation_with_accel_and_sound(obj, animIndex, accel)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| animIndex | `integer` |
+| accel | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_init_animation_with_accel_and_sound(struct Object *obj, s32 animIndex, f32 accel);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation_with_accel_and_sound](#cur_obj_init_animation_with_accel_and_sound)
+
+### Lua Example
+`cur_obj_init_animation_with_accel_and_sound(animIndex, accel)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+| accel | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_init_animation_with_accel_and_sound(s32 animIndex, f32 accel);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_init_animation_with_sound](#obj_init_animation_with_sound)
+
+### Lua Example
+`obj_init_animation_with_sound(obj, animations, animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| animations | [AnimationTable](structs.md#AnimationTable) |
+| animIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_init_animation_with_sound(struct Object *obj, const struct AnimationTable* animations, s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_enable_rendering_and_become_tangible](#cur_obj_enable_rendering_and_become_tangible)
+
+### Lua Example
+`cur_obj_enable_rendering_and_become_tangible(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_enable_rendering_and_become_tangible(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_enable_rendering](#cur_obj_enable_rendering)
+
+### Lua Example
+`cur_obj_enable_rendering()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_enable_rendering(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_disable_rendering_and_become_intangible](#cur_obj_disable_rendering_and_become_intangible)
+
+### Lua Example
+`cur_obj_disable_rendering_and_become_intangible(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_disable_rendering_and_become_intangible(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_disable_rendering](#cur_obj_disable_rendering)
+
+### Lua Example
+`cur_obj_disable_rendering()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_disable_rendering(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_unhide](#cur_obj_unhide)
+
+### Lua Example
+`cur_obj_unhide()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_unhide(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_hide](#cur_obj_hide)
+
+### Lua Example
+`cur_obj_hide()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_hide(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_relative](#cur_obj_set_pos_relative)
+
+### Lua Example
+`cur_obj_set_pos_relative(other, dleft, dy, dforward)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| other | [Object](structs.md#Object) |
+| dleft | `number` |
+| dy | `number` |
+| dforward | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_relative(struct Object *other, f32 dleft, f32 dy, f32 dforward);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_relative_to_parent](#cur_obj_set_pos_relative_to_parent)
+
+### Lua Example
+`cur_obj_set_pos_relative_to_parent(dleft, dy, dforward)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dleft | `number` |
+| dy | `number` |
+| dforward | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_relative_to_parent(f32 dleft, f32 dy, f32 dforward);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_enable_rendering_2](#cur_obj_enable_rendering_2)
+
+### Lua Example
+`cur_obj_enable_rendering_2()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_enable_rendering_2(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_unused_init_on_floor](#cur_obj_unused_init_on_floor)
+
+### Lua Example
+`cur_obj_unused_init_on_floor()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_unused_init_on_floor(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_face_angle_to_move_angle](#obj_set_face_angle_to_move_angle)
+
+### Lua Example
+`obj_set_face_angle_to_move_angle(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_face_angle_to_move_angle(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_object_list_from_behavior](#get_object_list_from_behavior)
+
+### Lua Example
+`local integerValue = get_object_list_from_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`u32 get_object_list_from_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_nearest_object_with_behavior](#cur_obj_nearest_object_with_behavior)
+
+### Lua Example
+`local ObjectValue = cur_obj_nearest_object_with_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *cur_obj_nearest_object_with_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_dist_to_nearest_object_with_behavior](#cur_obj_dist_to_nearest_object_with_behavior)
+
+### Lua Example
+`local numberValue = cur_obj_dist_to_nearest_object_with_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_dist_to_nearest_object_with_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_find_nearest_pole](#cur_obj_find_nearest_pole)
+
+### Lua Example
+`local ObjectValue = cur_obj_find_nearest_pole()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object* cur_obj_find_nearest_pole(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_find_nearest_object_with_behavior](#cur_obj_find_nearest_object_with_behavior)
+
+### Lua Example
+`local ObjectValue = cur_obj_find_nearest_object_with_behavior(behavior, dist)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+| dist | `Pointer` <`number`> |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *cur_obj_find_nearest_object_with_behavior(const BehaviorScript *behavior, f32 *dist);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_count_objects_with_behavior](#cur_obj_count_objects_with_behavior)
+
+### Lua Example
+`local integerValue = cur_obj_count_objects_with_behavior(behavior, dist)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+| dist | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`u16 cur_obj_count_objects_with_behavior(const BehaviorScript* behavior, f32 dist);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_unimportant_object](#find_unimportant_object)
+
+### Lua Example
+`local ObjectValue = find_unimportant_object()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *find_unimportant_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [count_unimportant_objects](#count_unimportant_objects)
+
+### Lua Example
+`local integerValue = count_unimportant_objects()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 count_unimportant_objects(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [count_objects_with_behavior](#count_objects_with_behavior)
+
+### Lua Example
+`local integerValue = count_objects_with_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 count_objects_with_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_object_with_behavior](#find_object_with_behavior)
+
+### Lua Example
+`local ObjectValue = find_object_with_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *find_object_with_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_find_nearby_held_actor](#cur_obj_find_nearby_held_actor)
+
+### Lua Example
+`local ObjectValue = cur_obj_find_nearby_held_actor(behavior, maxDist)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+| maxDist | `number` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *cur_obj_find_nearby_held_actor(const BehaviorScript *behavior, f32 maxDist);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_reset_timer_and_subaction](#cur_obj_reset_timer_and_subaction)
+
+### Lua Example
+`cur_obj_reset_timer_and_subaction()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_reset_timer_and_subaction(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_change_action](#cur_obj_change_action)
+
+### Lua Example
+`cur_obj_change_action(action)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| action | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_change_action(s32 action);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_vel_from_mario_vel](#cur_obj_set_vel_from_mario_vel)
+
+### Lua Example
+`cur_obj_set_vel_from_mario_vel(m, f12, f14)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| f12 | `number` |
+| f14 | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_vel_from_mario_vel(struct MarioState* m, f32 f12, f32 f14);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_reverse_animation](#cur_obj_reverse_animation)
+
+### Lua Example
+`cur_obj_reverse_animation()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_reverse_animation(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_extend_animation_if_at_end](#cur_obj_extend_animation_if_at_end)
+
+### Lua Example
+`cur_obj_extend_animation_if_at_end()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_extend_animation_if_at_end(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_if_near_animation_end](#cur_obj_check_if_near_animation_end)
+
+### Lua Example
+`local integerValue = cur_obj_check_if_near_animation_end()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_if_near_animation_end(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_if_at_animation_end](#cur_obj_check_if_at_animation_end)
+
+### Lua Example
+`local integerValue = cur_obj_check_if_at_animation_end()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_if_at_animation_end(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_anim_frame](#cur_obj_check_anim_frame)
+
+### Lua Example
+`local integerValue = cur_obj_check_anim_frame(frame)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| frame | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_anim_frame(s32 frame);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_anim_frame_in_range](#cur_obj_check_anim_frame_in_range)
+
+### Lua Example
+`local integerValue = cur_obj_check_anim_frame_in_range(startFrame, rangeLength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| startFrame | `integer` |
+| rangeLength | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_anim_frame_in_range(s32 startFrame, s32 rangeLength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_frame_prior_current_frame](#cur_obj_check_frame_prior_current_frame)
+
+### Lua Example
+`local integerValue = cur_obj_check_frame_prior_current_frame(a0)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | `Pointer` <`integer`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_frame_prior_current_frame(s16 *a0);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mario_is_in_air_action](#mario_is_in_air_action)
+
+### Lua Example
+`local integerValue = mario_is_in_air_action(m)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 mario_is_in_air_action(struct MarioState* m);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mario_is_dive_sliding](#mario_is_dive_sliding)
+
+### Lua Example
+`local integerValue = mario_is_dive_sliding(m)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 mario_is_dive_sliding(struct MarioState* m);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_y_vel_and_animation](#cur_obj_set_y_vel_and_animation)
+
+### Lua Example
+`cur_obj_set_y_vel_and_animation(sp18, sp1C)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp18 | `number` |
+| sp1C | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_unrender_and_reset_state](#cur_obj_unrender_and_reset_state)
+
+### Lua Example
+`cur_obj_unrender_and_reset_state(sp18, sp1C)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp18 | `integer` |
+| sp1C | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_after_thrown_or_dropped](#cur_obj_move_after_thrown_or_dropped)
+
+### Lua Example
+`cur_obj_move_after_thrown_or_dropped(forwardVel, velY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| forwardVel | `number` |
+| velY | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_after_thrown_or_dropped(f32 forwardVel, f32 velY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_get_thrown_or_placed](#cur_obj_get_thrown_or_placed)
+
+### Lua Example
+`cur_obj_get_thrown_or_placed(forwardVel, velY, thrownAction)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| forwardVel | `number` |
+| velY | `number` |
+| thrownAction | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_get_dropped](#cur_obj_get_dropped)
+
+### Lua Example
+`cur_obj_get_dropped()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_get_dropped(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mario_set_flag](#mario_set_flag)
+
+### Lua Example
+`mario_set_flag(flag)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| flag | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void mario_set_flag(s32 flag);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_clear_interact_status_flag](#cur_obj_clear_interact_status_flag)
+
+### Lua Example
+`local integerValue = cur_obj_clear_interact_status_flag(flag)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| flag | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_clear_interact_status_flag(s32 flag);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_mark_for_deletion](#obj_mark_for_deletion)
+
+### Description
+Marks an object to be unloaded at the end of the frame
+
+### Lua Example
+`obj_mark_for_deletion(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_mark_for_deletion(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_disable](#cur_obj_disable)
+
+### Lua Example
+`cur_obj_disable()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_disable(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_become_intangible](#cur_obj_become_intangible)
+
+### Lua Example
+`cur_obj_become_intangible()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_become_intangible(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_become_tangible](#cur_obj_become_tangible)
+
+### Lua Example
+`cur_obj_become_tangible()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_become_tangible(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_become_tangible](#obj_become_tangible)
+
+### Lua Example
+`obj_become_tangible(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_become_tangible(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_update_floor_height](#cur_obj_update_floor_height)
+
+### Lua Example
+`cur_obj_update_floor_height()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_update_floor_height(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_update_floor_height_and_get_floor](#cur_obj_update_floor_height_and_get_floor)
+
+### Lua Example
+`local SurfaceValue = cur_obj_update_floor_height_and_get_floor()`
+
+### Parameters
+- None
+
+### Returns
+[Surface](structs.md#Surface)
+
+### C Prototype
+`struct Surface *cur_obj_update_floor_height_and_get_floor(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [apply_drag_to_value](#apply_drag_to_value)
+
+### Lua Example
+`apply_drag_to_value(value, dragStrength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `Pointer` <`number`> |
+| dragStrength | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void apply_drag_to_value(f32 *value, f32 dragStrength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_apply_drag_xz](#cur_obj_apply_drag_xz)
+
+### Lua Example
+`cur_obj_apply_drag_xz(dragStrength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dragStrength | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_apply_drag_xz(f32 dragStrength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_xz](#cur_obj_move_xz)
+
+### Lua Example
+`local integerValue = cur_obj_move_xz(steepSlopeNormalY, careAboutEdgesAndSteepSlopes)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| steepSlopeNormalY | `number` |
+| careAboutEdgesAndSteepSlopes | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlopes);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_update_underwater_flags](#cur_obj_move_update_underwater_flags)
+
+### Lua Example
+`cur_obj_move_update_underwater_flags()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_update_underwater_flags(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_update_ground_air_flags](#cur_obj_move_update_ground_air_flags)
+
+### Lua Example
+`cur_obj_move_update_ground_air_flags(gravity, bounciness)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| gravity | `number` |
+| bounciness | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_y_and_get_water_level](#cur_obj_move_y_and_get_water_level)
+
+### Lua Example
+`local numberValue = cur_obj_move_y_and_get_water_level(gravity, buoyancy)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| gravity | `number` |
+| buoyancy | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_move_y_and_get_water_level(f32 gravity, f32 buoyancy);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_y](#cur_obj_move_y)
+
+### Lua Example
+`cur_obj_move_y(gravity, bounciness, buoyancy)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| gravity | `number` |
+| bounciness | `number` |
+| buoyancy | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_unused_resolve_wall_collisions](#cur_obj_unused_resolve_wall_collisions)
+
+### Lua Example
+`cur_obj_unused_resolve_wall_collisions(offsetY, radius)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| offsetY | `number` |
+| radius | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_unused_resolve_wall_collisions(f32 offsetY, f32 radius);`
+
+[:arrow_up_small:](#)
+
+
+
+## [abs_angle_diff](#abs_angle_diff)
+
+### Lua Example
+`local integerValue = abs_angle_diff(x0, x1)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x0 | `integer` |
+| x1 | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 abs_angle_diff(s16 x0, s16 x1);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_xz_using_fvel_and_yaw](#cur_obj_move_xz_using_fvel_and_yaw)
+
+### Lua Example
+`cur_obj_move_xz_using_fvel_and_yaw()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_xz_using_fvel_and_yaw(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_y_with_terminal_vel](#cur_obj_move_y_with_terminal_vel)
+
+### Lua Example
+`cur_obj_move_y_with_terminal_vel()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_y_with_terminal_vel(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_compute_vel_xz](#cur_obj_compute_vel_xz)
+
+### Lua Example
+`cur_obj_compute_vel_xz()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_compute_vel_xz(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [increment_velocity_toward_range](#increment_velocity_toward_range)
+
+### Lua Example
+`local numberValue = increment_velocity_toward_range(value, center, zeroThreshold, increment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `number` |
+| center | `number` |
+| zeroThreshold | `number` |
+| increment | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 increment_velocity_toward_range(f32 value, f32 center, f32 zeroThreshold, f32 increment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_check_if_collided_with_object](#obj_check_if_collided_with_object)
+
+### Lua Example
+`local integerValue = obj_check_if_collided_with_object(obj1, obj2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj1 | [Object](structs.md#Object) |
+| obj2 | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_check_if_collided_with_object(struct Object *obj1, struct Object *obj2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_behavior](#cur_obj_set_behavior)
+
+### Lua Example
+`cur_obj_set_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_behavior](#obj_set_behavior)
+
+### Lua Example
+`obj_set_behavior(obj, behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_behavior(struct Object *obj, const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_has_behavior](#cur_obj_has_behavior)
+
+### Lua Example
+`local integerValue = cur_obj_has_behavior(behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_has_behavior(const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_has_behavior](#obj_has_behavior)
+
+### Lua Example
+`local integerValue = obj_has_behavior(obj, behavior)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| behavior | `Pointer` <`BehaviorScript`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_has_behavior(struct Object *obj, const BehaviorScript *behavior);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_lateral_dist_from_obj_to_home](#cur_obj_lateral_dist_from_obj_to_home)
+
+### Lua Example
+`local numberValue = cur_obj_lateral_dist_from_obj_to_home(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_lateral_dist_from_obj_to_home(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_lateral_dist_from_mario_to_home](#cur_obj_lateral_dist_from_mario_to_home)
+
+### Lua Example
+`local numberValue = cur_obj_lateral_dist_from_mario_to_home()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_lateral_dist_from_mario_to_home(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_lateral_dist_to_home](#cur_obj_lateral_dist_to_home)
+
+### Lua Example
+`local numberValue = cur_obj_lateral_dist_to_home()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_lateral_dist_to_home(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_outside_home_square](#cur_obj_outside_home_square)
+
+### Lua Example
+`local integerValue = cur_obj_outside_home_square(halfLength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| halfLength | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_outside_home_square(f32 halfLength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_outside_home_rectangle](#cur_obj_outside_home_rectangle)
+
+### Lua Example
+`local integerValue = cur_obj_outside_home_rectangle(minX, maxX, minZ, maxZ)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| minX | `number` |
+| maxX | `number` |
+| minZ | `number` |
+| maxZ | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_outside_home_rectangle(f32 minX, f32 maxX, f32 minZ, f32 maxZ);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_to_home](#cur_obj_set_pos_to_home)
+
+### Lua Example
+`cur_obj_set_pos_to_home()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_to_home(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_to_home_and_stop](#cur_obj_set_pos_to_home_and_stop)
+
+### Lua Example
+`cur_obj_set_pos_to_home_and_stop()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_to_home_and_stop(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_shake_y](#cur_obj_shake_y)
+
+### Lua Example
+`cur_obj_shake_y(amount)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| amount | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_shake_y(f32 amount);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_start_cam_event](#cur_obj_start_cam_event)
+
+### Lua Example
+`cur_obj_start_cam_event(obj, cameraEvent)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| cameraEvent | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_start_cam_event(UNUSED struct Object *obj, s32 cameraEvent);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_mario_interact_hoot_if_in_range](#set_mario_interact_hoot_if_in_range)
+
+### Lua Example
+`set_mario_interact_hoot_if_in_range(sp0, sp4, sp8)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp0 | `integer` |
+| sp4 | `integer` |
+| sp8 | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_mario_interact_hoot_if_in_range(UNUSED s32 sp0, UNUSED s32 sp4, f32 sp8);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_billboard](#obj_set_billboard)
+
+### Lua Example
+`obj_set_billboard(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_billboard(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_cylboard](#obj_set_cylboard)
+
+### Lua Example
+`obj_set_cylboard(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_cylboard(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_billboard_if_vanilla_cam](#cur_obj_set_billboard_if_vanilla_cam)
+
+### Lua Example
+`cur_obj_set_billboard_if_vanilla_cam()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_billboard_if_vanilla_cam(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_hitbox_radius_and_height](#obj_set_hitbox_radius_and_height)
+
+### Lua Example
+`obj_set_hitbox_radius_and_height(o, radius, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| radius | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_hitbox_radius_and_height(struct Object *o, f32 radius, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_hurtbox_radius_and_height](#obj_set_hurtbox_radius_and_height)
+
+### Lua Example
+`obj_set_hurtbox_radius_and_height(o, radius, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| radius | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_hurtbox_radius_and_height(struct Object *o, f32 radius, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_hitbox_radius_and_height](#cur_obj_set_hitbox_radius_and_height)
+
+### Lua Example
+`cur_obj_set_hitbox_radius_and_height(radius, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| radius | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_hitbox_radius_and_height(f32 radius, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_hurtbox_radius_and_height](#cur_obj_set_hurtbox_radius_and_height)
+
+### Lua Example
+`cur_obj_set_hurtbox_radius_and_height(radius, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| radius | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_hurtbox_radius_and_height(f32 radius, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_spawn_loot_coins](#obj_spawn_loot_coins)
+
+### Lua Example
+`obj_spawn_loot_coins(obj, numCoins, sp30, coinBehavior, posJitter, model)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| numCoins | `integer` |
+| sp30 | `number` |
+| coinBehavior | `Pointer` <`BehaviorScript`> |
+| posJitter | `integer` |
+| model | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_spawn_loot_coins(struct Object *obj, s32 numCoins, f32 sp30, const BehaviorScript *coinBehavior, s16 posJitter, s16 model);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_spawn_loot_blue_coins](#obj_spawn_loot_blue_coins)
+
+### Lua Example
+`obj_spawn_loot_blue_coins(obj, numCoins, sp28, posJitter)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| numCoins | `integer` |
+| sp28 | `number` |
+| posJitter | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_spawn_loot_blue_coins(struct Object *obj, s32 numCoins, f32 sp28, s16 posJitter);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_spawn_loot_yellow_coins](#obj_spawn_loot_yellow_coins)
+
+### Lua Example
+`obj_spawn_loot_yellow_coins(obj, numCoins, sp28)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| numCoins | `integer` |
+| sp28 | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_spawn_loot_yellow_coins(struct Object *obj, s32 numCoins, f32 sp28);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_spawn_loot_coin_at_mario_pos](#cur_obj_spawn_loot_coin_at_mario_pos)
+
+### Lua Example
+`cur_obj_spawn_loot_coin_at_mario_pos(m)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_spawn_loot_coin_at_mario_pos(struct MarioState* m);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_abs_y_dist_to_home](#cur_obj_abs_y_dist_to_home)
+
+### Lua Example
+`local numberValue = cur_obj_abs_y_dist_to_home()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 cur_obj_abs_y_dist_to_home(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_advance_looping_anim](#cur_obj_advance_looping_anim)
+
+### Lua Example
+`local integerValue = cur_obj_advance_looping_anim()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_advance_looping_anim(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_detect_steep_floor](#cur_obj_detect_steep_floor)
+
+### Lua Example
+`local integerValue = cur_obj_detect_steep_floor(steepAngleDegrees)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| steepAngleDegrees | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_detect_steep_floor(s16 steepAngleDegrees);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_resolve_wall_collisions](#cur_obj_resolve_wall_collisions)
+
+### Lua Example
+`local integerValue = cur_obj_resolve_wall_collisions()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_resolve_wall_collisions(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_update_floor](#cur_obj_update_floor)
+
+### Lua Example
+`cur_obj_update_floor()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_update_floor(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_update_floor_and_resolve_wall_collisions](#cur_obj_update_floor_and_resolve_wall_collisions)
+
+### Lua Example
+`cur_obj_update_floor_and_resolve_wall_collisions(steepSlopeDegrees)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| steepSlopeDegrees | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegrees);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_update_floor_and_walls](#cur_obj_update_floor_and_walls)
+
+### Lua Example
+`cur_obj_update_floor_and_walls()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_update_floor_and_walls(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_standard](#cur_obj_move_standard)
+
+### Lua Example
+`cur_obj_move_standard(steepSlopeAngleDegrees)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| steepSlopeAngleDegrees | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_standard(s16 steepSlopeAngleDegrees);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_within_12k_bounds](#cur_obj_within_12k_bounds)
+
+### Lua Example
+`local integerValue = cur_obj_within_12k_bounds()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_within_12k_bounds(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_using_vel_and_gravity](#cur_obj_move_using_vel_and_gravity)
+
+### Lua Example
+`cur_obj_move_using_vel_and_gravity()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_using_vel_and_gravity(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_using_fvel_and_gravity](#cur_obj_move_using_fvel_and_gravity)
+
+### Lua Example
+`cur_obj_move_using_fvel_and_gravity()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_move_using_fvel_and_gravity(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_pos_relative](#obj_set_pos_relative)
+
+### Lua Example
+`obj_set_pos_relative(obj, other, dleft, dy, dforward)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| other | [Object](structs.md#Object) |
+| dleft | `number` |
+| dy | `number` |
+| dforward | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, f32 dforward);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_angle_to_home](#cur_obj_angle_to_home)
+
+### Lua Example
+`local integerValue = cur_obj_angle_to_home()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 cur_obj_angle_to_home(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_gfx_pos_at_obj_pos](#obj_set_gfx_pos_at_obj_pos)
+
+### Lua Example
+`obj_set_gfx_pos_at_obj_pos(obj1, obj2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj1 | [Object](structs.md#Object) |
+| obj2 | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_translate_local](#obj_translate_local)
+
+### Description
+Transforms the vector at `localTranslateIndex` into the object's local coordinates, and then adds it to the vector at `posIndex`
+
+### Lua Example
+`obj_translate_local(obj, posIndex, localTranslateIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| posIndex | `integer` |
+| localTranslateIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_build_transform_from_pos_and_angle](#obj_build_transform_from_pos_and_angle)
+
+### Lua Example
+`obj_build_transform_from_pos_and_angle(obj, posIndex, angleIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| posIndex | `integer` |
+| angleIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s16 angleIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_throw_matrix_from_transform](#obj_set_throw_matrix_from_transform)
+
+### Lua Example
+`obj_set_throw_matrix_from_transform(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_throw_matrix_from_transform(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_build_transform_relative_to_parent](#obj_build_transform_relative_to_parent)
+
+### Lua Example
+`obj_build_transform_relative_to_parent(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_build_transform_relative_to_parent(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_create_transform_from_self](#obj_create_transform_from_self)
+
+### Lua Example
+`obj_create_transform_from_self(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_create_transform_from_self(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_rotate_move_angle_using_vel](#cur_obj_rotate_move_angle_using_vel)
+
+### Lua Example
+`cur_obj_rotate_move_angle_using_vel()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_rotate_move_angle_using_vel(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_rotate_face_angle_using_vel](#cur_obj_rotate_face_angle_using_vel)
+
+### Lua Example
+`cur_obj_rotate_face_angle_using_vel()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_rotate_face_angle_using_vel(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_face_angle_to_move_angle](#cur_obj_set_face_angle_to_move_angle)
+
+### Lua Example
+`cur_obj_set_face_angle_to_move_angle()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_face_angle_to_move_angle(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_follow_path](#cur_obj_follow_path)
+
+### Lua Example
+`local integerValue = cur_obj_follow_path(unusedArg)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| unusedArg | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_follow_path(UNUSED s32 unusedArg);`
+
+[:arrow_up_small:](#)
+
+
+
+## [chain_segment_init](#chain_segment_init)
+
+### Lua Example
+`chain_segment_init(segment)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| segment | [ChainSegment](structs.md#ChainSegment) |
+
+### Returns
+- None
+
+### C Prototype
+`void chain_segment_init(struct ChainSegment *segment);`
+
+[:arrow_up_small:](#)
+
+
+
+## [random_f32_around_zero](#random_f32_around_zero)
+
+### Lua Example
+`local numberValue = random_f32_around_zero(diameter)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| diameter | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 random_f32_around_zero(f32 diameter);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_scale_random](#obj_scale_random)
+
+### Lua Example
+`obj_scale_random(obj, rangeLength, minScale)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| rangeLength | `number` |
+| minScale | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_scale_random(struct Object *obj, f32 rangeLength, f32 minScale);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_translate_xyz_random](#obj_translate_xyz_random)
+
+### Lua Example
+`obj_translate_xyz_random(obj, rangeLength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| rangeLength | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_translate_xyz_random(struct Object *obj, f32 rangeLength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_translate_xz_random](#obj_translate_xz_random)
+
+### Lua Example
+`obj_translate_xz_random(obj, rangeLength)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| rangeLength | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_translate_xz_random(struct Object *obj, f32 rangeLength);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_build_vel_from_transform](#obj_build_vel_from_transform)
+
+### Lua Example
+`obj_build_vel_from_transform(a0)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_build_vel_from_transform(struct Object *a0);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_via_transform](#cur_obj_set_pos_via_transform)
+
+### Lua Example
+`cur_obj_set_pos_via_transform()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_via_transform(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_reflect_move_angle_off_wall](#cur_obj_reflect_move_angle_off_wall)
+
+### Lua Example
+`local integerValue = cur_obj_reflect_move_angle_off_wall()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 cur_obj_reflect_move_angle_off_wall(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_spawn_particles](#cur_obj_spawn_particles)
+
+### Lua Example
+`cur_obj_spawn_particles(info)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| info | [SpawnParticlesInfo](structs.md#SpawnParticlesInfo) |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_spawn_particles(struct SpawnParticlesInfo *info);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_hitbox](#obj_set_hitbox)
+
+### Lua Example
+`obj_set_hitbox(obj, hitbox)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);`
+
+[:arrow_up_small:](#)
+
+
+
+## [signum_positive](#signum_positive)
+
+### Lua Example
+`local integerValue = signum_positive(x)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 signum_positive(s32 x);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_wait_then_blink](#cur_obj_wait_then_blink)
+
+### Lua Example
+`local integerValue = cur_obj_wait_then_blink(timeUntilBlinking, numBlinks)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| timeUntilBlinking | `integer` |
+| numBlinks | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_is_mario_ground_pounding_platform](#cur_obj_is_mario_ground_pounding_platform)
+
+### Lua Example
+`local integerValue = cur_obj_is_mario_ground_pounding_platform()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_is_mario_ground_pounding_platform(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_mario_ground_pounding_platform](#obj_is_mario_ground_pounding_platform)
+
+### Lua Example
+`local integerValue = obj_is_mario_ground_pounding_platform(m, obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_mist_particles](#spawn_mist_particles)
+
+### Lua Example
+`spawn_mist_particles()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void spawn_mist_particles(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_mist_particles_with_sound](#spawn_mist_particles_with_sound)
+
+### Lua Example
+`spawn_mist_particles_with_sound(sp18)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp18 | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void spawn_mist_particles_with_sound(u32 sp18);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_push_mario_away](#cur_obj_push_mario_away)
+
+### Lua Example
+`cur_obj_push_mario_away(radius)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| radius | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_push_mario_away(f32 radius);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_push_mario_away_from_cylinder](#cur_obj_push_mario_away_from_cylinder)
+
+### Lua Example
+`cur_obj_push_mario_away_from_cylinder(radius, extentY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| radius | `number` |
+| extentY | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [bhv_dust_smoke_loop](#bhv_dust_smoke_loop)
+
+### Lua Example
+`bhv_dust_smoke_loop()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void bhv_dust_smoke_loop(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [stub_obj_helpers_3](#stub_obj_helpers_3)
+
+### Lua Example
+`stub_obj_helpers_3(sp0, sp4)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp0 | `integer` |
+| sp4 | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void stub_obj_helpers_3(UNUSED s32 sp0, UNUSED s32 sp4);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_scale_over_time](#cur_obj_scale_over_time)
+
+### Lua Example
+`cur_obj_scale_over_time(a0, a1, sp10, sp14)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | `integer` |
+| a1 | `integer` |
+| sp10 | `number` |
+| sp14 | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_pos_to_home_with_debug](#cur_obj_set_pos_to_home_with_debug)
+
+### Lua Example
+`cur_obj_set_pos_to_home_with_debug()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_pos_to_home_with_debug(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [stub_obj_helpers_4](#stub_obj_helpers_4)
+
+### Lua Example
+`stub_obj_helpers_4()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void stub_obj_helpers_4(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_is_mario_on_platform](#cur_obj_is_mario_on_platform)
+
+### Lua Example
+`local integerValue = cur_obj_is_mario_on_platform()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_is_mario_on_platform(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_is_any_player_on_platform](#cur_obj_is_any_player_on_platform)
+
+### Lua Example
+`local integerValue = cur_obj_is_any_player_on_platform()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_is_any_player_on_platform(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_shake_y_until](#cur_obj_shake_y_until)
+
+### Lua Example
+`local integerValue = cur_obj_shake_y_until(cycles, amount)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| cycles | `integer` |
+| amount | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_shake_y_until(s32 cycles, s32 amount);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_move_up_and_down](#cur_obj_move_up_and_down)
+
+### Lua Example
+`local integerValue = cur_obj_move_up_and_down(a0)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_move_up_and_down(s32 a0);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_star_with_no_lvl_exit](#spawn_star_with_no_lvl_exit)
+
+### Lua Example
+`local ObjectValue = spawn_star_with_no_lvl_exit(sp20, sp24)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp20 | `integer` |
+| sp24 | `integer` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *spawn_star_with_no_lvl_exit(s32 sp20, s32 sp24);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_base_star_with_no_lvl_exit](#spawn_base_star_with_no_lvl_exit)
+
+### Lua Example
+`spawn_base_star_with_no_lvl_exit()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void spawn_base_star_with_no_lvl_exit(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [bit_shift_left](#bit_shift_left)
+
+### Lua Example
+`local integerValue = bit_shift_left(a0)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a0 | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 bit_shift_left(s32 a0);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_mario_far_away](#cur_obj_mario_far_away)
+
+### Lua Example
+`local integerValue = cur_obj_mario_far_away()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_mario_far_away(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [is_mario_moving_fast_or_in_air](#is_mario_moving_fast_or_in_air)
+
+### Lua Example
+`local integerValue = is_mario_moving_fast_or_in_air(speedThreshold)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| speedThreshold | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 is_mario_moving_fast_or_in_air(s32 speedThreshold);`
+
+[:arrow_up_small:](#)
+
+
+
+## [is_item_in_array](#is_item_in_array)
+
+### Lua Example
+`local integerValue = is_item_in_array(item, array)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| item | `integer` |
+| array | `Pointer` <`integer`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 is_item_in_array(s8 item, s8 *array);`
+
+[:arrow_up_small:](#)
+
+
+
+## [bhv_init_room](#bhv_init_room)
+
+### Lua Example
+`bhv_init_room()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void bhv_init_room(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_enable_rendering_if_mario_in_room](#cur_obj_enable_rendering_if_mario_in_room)
+
+### Lua Example
+`cur_obj_enable_rendering_if_mario_in_room()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_enable_rendering_if_mario_in_room(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_hitbox_and_die_if_attacked](#cur_obj_set_hitbox_and_die_if_attacked)
+
+### Lua Example
+`local integerValue = cur_obj_set_hitbox_and_die_if_attacked(hitbox, deathSound, noLootCoins)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| hitbox | [ObjectHitbox](structs.md#ObjectHitbox) |
+| deathSound | `integer` |
+| noLootCoins | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_set_hitbox_and_die_if_attacked(struct ObjectHitbox *hitbox, s32 deathSound, s32 noLootCoins);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_explode_and_spawn_coins](#obj_explode_and_spawn_coins)
+
+### Lua Example
+`obj_explode_and_spawn_coins(sp18, sp1C)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| sp18 | `number` |
+| sp1C | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_explode_and_spawn_coins(f32 sp18, s32 sp1C);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_if_hit_wall_bounce_away](#cur_obj_if_hit_wall_bounce_away)
+
+### Lua Example
+`cur_obj_if_hit_wall_bounce_away()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_if_hit_wall_bounce_away(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_hide_if_mario_far_away_y](#cur_obj_hide_if_mario_far_away_y)
+
+### Lua Example
+`local integerValue = cur_obj_hide_if_mario_far_away_y(distY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| distY | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_hide_if_mario_far_away_y(f32 distY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_hidden](#obj_is_hidden)
+
+### Lua Example
+`local integerValue = obj_is_hidden(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_is_hidden(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [enable_time_stop](#enable_time_stop)
+
+### Lua Example
+`enable_time_stop()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void enable_time_stop(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [enable_time_stop_if_alone](#enable_time_stop_if_alone)
+
+### Lua Example
+`enable_time_stop_if_alone()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void enable_time_stop_if_alone(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [disable_time_stop](#disable_time_stop)
+
+### Lua Example
+`disable_time_stop()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void disable_time_stop(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_time_stop_flags](#set_time_stop_flags)
+
+### Lua Example
+`set_time_stop_flags(flags)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| flags | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_time_stop_flags(s32 flags);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_time_stop_flags_if_alone](#set_time_stop_flags_if_alone)
+
+### Lua Example
+`set_time_stop_flags_if_alone(flags)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| flags | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_time_stop_flags_if_alone(s32 flags);`
+
+[:arrow_up_small:](#)
+
+
+
+## [clear_time_stop_flags](#clear_time_stop_flags)
+
+### Lua Example
+`clear_time_stop_flags(flags)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| flags | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void clear_time_stop_flags(s32 flags);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_can_mario_activate_textbox](#cur_obj_can_mario_activate_textbox)
+
+### Lua Example
+`local integerValue = cur_obj_can_mario_activate_textbox(m, radius, height, unused)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| radius | `number` |
+| height | `number` |
+| unused | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_can_mario_activate_textbox(struct MarioState* m, f32 radius, f32 height, UNUSED s32 unused);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_can_mario_activate_textbox_2](#cur_obj_can_mario_activate_textbox_2)
+
+### Lua Example
+`local integerValue = cur_obj_can_mario_activate_textbox_2(m, radius, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| radius | `number` |
+| height | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_can_mario_activate_textbox_2(struct MarioState* m, f32 radius, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_end_dialog](#cur_obj_end_dialog)
+
+### Lua Example
+`cur_obj_end_dialog(m, dialogFlags, dialogResult)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| dialogFlags | `integer` |
+| dialogResult | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_end_dialog(struct MarioState* m, s32 dialogFlags, s32 dialogResult);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_has_model](#cur_obj_has_model)
+
+### Lua Example
+`local integerValue = cur_obj_has_model(modelID)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| modelID | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_has_model(u16 modelID);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_align_gfx_with_floor](#cur_obj_align_gfx_with_floor)
+
+### Lua Example
+`cur_obj_align_gfx_with_floor()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_align_gfx_with_floor(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mario_is_within_rectangle](#mario_is_within_rectangle)
+
+### Lua Example
+`local integerValue = mario_is_within_rectangle(minX, maxX, minZ, maxZ)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| minX | `integer` |
+| maxX | `integer` |
+| minZ | `integer` |
+| maxZ | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_shake_screen](#cur_obj_shake_screen)
+
+### Lua Example
+`cur_obj_shake_screen(shake)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| shake | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_shake_screen(s32 shake);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_attack_collided_from_other_object](#obj_attack_collided_from_other_object)
+
+### Lua Example
+`local integerValue = obj_attack_collided_from_other_object(obj)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| obj | [Object](structs.md#Object) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_attack_collided_from_other_object(struct Object *obj);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_was_attacked_or_ground_pounded](#cur_obj_was_attacked_or_ground_pounded)
+
+### Lua Example
+`local integerValue = cur_obj_was_attacked_or_ground_pounded()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_was_attacked_or_ground_pounded(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_copy_behavior_params](#obj_copy_behavior_params)
+
+### Lua Example
+`obj_copy_behavior_params(dst, src)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dst | [Object](structs.md#Object) |
+| src | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_copy_behavior_params(struct Object *dst, struct Object *src);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation_and_anim_frame](#cur_obj_init_animation_and_anim_frame)
+
+### Lua Example
+`cur_obj_init_animation_and_anim_frame(animIndex, animFrame)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+| animFrame | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_init_animation_and_anim_frame(s32 animIndex, s32 animFrame);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation_and_check_if_near_end](#cur_obj_init_animation_and_check_if_near_end)
+
+### Lua Example
+`local integerValue = cur_obj_init_animation_and_check_if_near_end(animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_init_animation_and_check_if_near_end(s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_init_animation_and_extend_if_at_end](#cur_obj_init_animation_and_extend_if_at_end)
+
+### Lua Example
+`cur_obj_init_animation_and_extend_if_at_end(animIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_init_animation_and_extend_if_at_end(s32 animIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_grabbed_mario](#cur_obj_check_grabbed_mario)
+
+### Lua Example
+`local integerValue = cur_obj_check_grabbed_mario()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_grabbed_mario(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [player_performed_grab_escape_action](#player_performed_grab_escape_action)
+
+### Lua Example
+`local integerValue = player_performed_grab_escape_action()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 player_performed_grab_escape_action(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_unused_play_footstep_sound](#cur_obj_unused_play_footstep_sound)
+
+### Lua Example
+`cur_obj_unused_play_footstep_sound(animFrame1, animFrame2, sound)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| animFrame1 | `integer` |
+| animFrame2 | `integer` |
+| sound | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_unused_play_footstep_sound(s32 animFrame1, s32 animFrame2, s32 sound);`
+
+[:arrow_up_small:](#)
+
+
+
+## [enable_time_stop_including_mario](#enable_time_stop_including_mario)
+
+### Lua Example
+`enable_time_stop_including_mario()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void enable_time_stop_including_mario(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [disable_time_stop_including_mario](#disable_time_stop_including_mario)
+
+### Lua Example
+`disable_time_stop_including_mario()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void disable_time_stop_including_mario(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_check_interacted](#cur_obj_check_interacted)
+
+### Lua Example
+`local integerValue = cur_obj_check_interacted()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 cur_obj_check_interacted(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_spawn_loot_blue_coin](#cur_obj_spawn_loot_blue_coin)
+
+### Lua Example
+`cur_obj_spawn_loot_blue_coin()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_spawn_loot_blue_coin(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_spawn_star_at_y_offset](#cur_obj_spawn_star_at_y_offset)
+
+### Lua Example
+`cur_obj_spawn_star_at_y_offset(targetX, targetY, targetZ, offsetY)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| targetX | `number` |
+| targetY | `number` |
+| targetZ | `number` |
+| offsetY | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_spawn_star_at_y_offset(f32 targetX, f32 targetY, f32 targetZ, f32 offsetY);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_set_home_once](#cur_obj_set_home_once)
+
+### Description
+Sets the current object's home only the first time it's called
+
+### Lua Example
+`cur_obj_set_home_once()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_set_home_once(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_trajectory_length](#get_trajectory_length)
+
+### Description
+Gets a trajectory's length
+
+### Lua Example
+`local integerValue = get_trajectory_length(trajectory)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| trajectory | `Pointer` <`Trajectory`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 get_trajectory_length(Trajectory* trajectory);`
+
+[:arrow_up_small:](#)
+
+
+
---
# functions from object_list_processor.h
@@ -3446,10 +8024,33 @@ Gets the texture from a display list command if it has an image related op
| cmd | `Pointer` <`Gfx`> |
### Returns
-- `Pointer` <`integer`>
+- `Pointer` <`Texture`>
### C Prototype
-`u8 *gfx_get_texture(Gfx *cmd);`
+`Texture *gfx_get_texture(Gfx *cmd);`
+
+[:arrow_up_small:](#)
+
+
+
+## [gfx_get_name](#gfx_get_name)
+
+### Description
+Gets the name of a display list
+
+### Lua Example
+`local stringValue = gfx_get_name(gfx)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| gfx | `Pointer` <`Gfx`> |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char *gfx_get_name(Gfx *gfx);`
[:arrow_up_small:](#)
@@ -3642,6 +8243,29 @@ Deletes all display lists created by `gfx_create`
+## [vtx_get_name](#vtx_get_name)
+
+### Description
+Gets the name of a vertex buffer
+
+### Lua Example
+`local stringValue = vtx_get_name(vtx)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| vtx | `Pointer` <`Vtx`> |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char *vtx_get_name(Vtx *vtx);`
+
+[:arrow_up_small:](#)
+
+
+
## [vtx_get_count](#vtx_get_count)
### Description
@@ -3827,4695 +8451,6 @@ Deletes all vertex buffers created by `vtx_create`
[:arrow_up_small:](#)
-
-
----
-# functions from smlua_level_utils.h
-
-
-
-
-## [smlua_level_util_change_area](#smlua_level_util_change_area)
-
-### Description
-Instantly changes the current area to `areaIndex`
-
-### Lua Example
-`smlua_level_util_change_area(areaIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| areaIndex | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_level_util_change_area(s32 areaIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_level_util_get_info](#smlua_level_util_get_info)
-
-### Description
-Gets information on a custom level from `levelNum`
-
-### Lua Example
-`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| levelNum | `integer` |
-
-### Returns
-[CustomLevelInfo](structs.md#CustomLevelInfo)
-
-### C Prototype
-`struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name)
-
-### Description
-Gets information on a custom level from `shortName`
-
-### Lua Example
-`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| shortName | `string` |
-
-### Returns
-[CustomLevelInfo](structs.md#CustomLevelInfo)
-
-### C Prototype
-`struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num)
-
-### Description
-Gets information on a custom level from `courseNum`
-
-### Lua Example
-`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-[CustomLevelInfo](structs.md#CustomLevelInfo)
-
-### C Prototype
-`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [level_register](#level_register)
-
-### Description
-Registers a fully custom level. Level ID begins at 50
-
-### Lua Example
-`local integerValue = level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| scriptEntryName | `string` |
-| courseNum | `integer` |
-| fullName | `string` |
-| shortName | `string` |
-| acousticReach | `integer` |
-| echoLevel1 | `integer` |
-| echoLevel2 | `integer` |
-| echoLevel3 | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);`
-
-[:arrow_up_small:](#)
-
-
-
-## [level_is_vanilla_level](#level_is_vanilla_level)
-
-### Description
-Checks if `levelNum` is a vanilla level
-
-### Lua Example
-`local booleanValue = level_is_vanilla_level(levelNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| levelNum | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool level_is_vanilla_level(s16 levelNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_to_warpnode](#warp_to_warpnode)
-
-### Description
-Warps to `aWarpId` of `aArea` in `aLevel` during `aAct`
-
-### Lua Example
-`local booleanValue = warp_to_warpnode(aLevel, aArea, aAct, aWarpId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| aLevel | `integer` |
-| aArea | `integer` |
-| aAct | `integer` |
-| aWarpId | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_to_level](#warp_to_level)
-
-### Description
-Warps to `aArea` of `aLevel` in `aAct`
-
-### Lua Example
-`local booleanValue = warp_to_level(aLevel, aArea, aAct)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| aLevel | `integer` |
-| aArea | `integer` |
-| aAct | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_restart_level](#warp_restart_level)
-
-### Description
-Restarts the current level
-
-### Lua Example
-`local booleanValue = warp_restart_level()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_restart_level(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_to_start_level](#warp_to_start_level)
-
-### Description
-Warps to the start level (Castle Grounds by default)
-
-### Lua Example
-`local booleanValue = warp_to_start_level()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_to_start_level(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_exit_level](#warp_exit_level)
-
-### Description
-Exits the current level after `aDelay`
-
-### Lua Example
-`local booleanValue = warp_exit_level(aDelay)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| aDelay | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_exit_level(s32 aDelay);`
-
-[:arrow_up_small:](#)
-
-
-
-## [warp_to_castle](#warp_to_castle)
-
-### Description
-Warps back to the castle from `aLevel`
-
-### Lua Example
-`local booleanValue = warp_to_castle(aLevel)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| aLevel | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool warp_to_castle(s32 aLevel);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from smlua_misc_utils.h
-
-
-
-
-## [get_network_area_timer](#get_network_area_timer)
-
-### Description
-Gets the current area's networked timer
-
-### Lua Example
-`local integerValue = get_network_area_timer()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u32 get_network_area_timer(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_area_update_counter](#get_area_update_counter)
-
-### Description
-Gets the area update counter incremented when objects are updated
-
-### Lua Example
-`local integerValue = get_area_update_counter()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u16 get_area_update_counter(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_temp_s32_pointer](#get_temp_s32_pointer)
-
-### Description
-Returns a temporary signed 32-bit integer pointer with its value set to `initialValue`
-
-### Lua Example
-`local PointerValue = get_temp_s32_pointer(initialValue)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| initialValue | `integer` |
-
-### Returns
-- `Pointer` <`integer`>
-
-### C Prototype
-`s32* get_temp_s32_pointer(s32 initialValue);`
-
-[:arrow_up_small:](#)
-
-
-
-## [deref_s32_pointer](#deref_s32_pointer)
-
-### Description
-Gets the signed 32-bit integer value from `pointer`
-
-### Lua Example
-`local integerValue = deref_s32_pointer(pointer)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| pointer | `Pointer` <`integer`> |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 deref_s32_pointer(s32* pointer);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_popup_create_global](#djui_popup_create_global)
-
-### Description
-Creates a DJUI popup that is broadcasted to every client
-
-### Lua Example
-`djui_popup_create_global(message, lines)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| message | `string` |
-| lines | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void djui_popup_create_global(const char* message, int lines);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_is_popup_disabled](#djui_is_popup_disabled)
-
-### Description
-Returns if popups are disabled
-
-### Lua Example
-`local booleanValue = djui_is_popup_disabled()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool djui_is_popup_disabled(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_set_popup_disabled_override](#djui_set_popup_disabled_override)
-
-### Description
-Sets if popups are disabled
-
-### Lua Example
-`djui_set_popup_disabled_override(value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void djui_set_popup_disabled_override(bool value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_reset_popup_disabled_override](#djui_reset_popup_disabled_override)
-
-### Description
-Resets if popups are disabled
-
-### Lua Example
-`djui_reset_popup_disabled_override()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void djui_reset_popup_disabled_override(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_is_playerlist_open](#djui_is_playerlist_open)
-
-### Description
-Checks if the DJUI playerlist is open
-
-### Lua Example
-`local booleanValue = djui_is_playerlist_open()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool djui_is_playerlist_open(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_attempting_to_open_playerlist](#djui_attempting_to_open_playerlist)
-
-### Description
-Checks if the DJUI playerlist is attempting to be opened
-
-### Lua Example
-`local booleanValue = djui_attempting_to_open_playerlist()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool djui_attempting_to_open_playerlist(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_get_playerlist_page_index](#djui_get_playerlist_page_index)
-
-### Description
-Gets the DJUI playerlist's page index
-
-### Lua Example
-`local integerValue = djui_get_playerlist_page_index()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u8 djui_get_playerlist_page_index(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_menu_get_font](#djui_menu_get_font)
-
-### Description
-Gets the DJUI menu font
-
-### Lua Example
-`local enumValue = djui_menu_get_font()`
-
-### Parameters
-- None
-
-### Returns
-[enum DjuiFontType](constants.md#enum-DjuiFontType)
-
-### C Prototype
-`enum DjuiFontType djui_menu_get_font(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_menu_get_theme](#djui_menu_get_theme)
-
-### Description
-Gets the DJUI menu theme
-
-### Lua Example
-`local DjuiThemeValue = djui_menu_get_theme()`
-
-### Parameters
-- None
-
-### Returns
-[DjuiTheme](structs.md#DjuiTheme)
-
-### C Prototype
-`struct DjuiTheme* djui_menu_get_theme(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [djui_is_playerlist_ping_visible](#djui_is_playerlist_ping_visible)
-
-### Description
-Checks if the DJUI playerlist ping icon is visible
-
-### Lua Example
-`local booleanValue = djui_is_playerlist_ping_visible()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool djui_is_playerlist_ping_visible(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_dialog_box_state](#get_dialog_box_state)
-
-### Description
-Gets the current state of the dialog box
-
-### Lua Example
-`local integerValue = get_dialog_box_state()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s8 get_dialog_box_state(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_dialog_id](#get_dialog_id)
-
-### Description
-Gets the current dialog box ID
-
-### Lua Example
-`local integerValue = get_dialog_id()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 get_dialog_id(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_last_star_or_key](#get_last_star_or_key)
-
-### Description
-Gets if the last objective collected was a star (0) or a key (1)
-
-### Lua Example
-`local integerValue = get_last_star_or_key()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u8 get_last_star_or_key(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_last_star_or_key](#set_last_star_or_key)
-
-### Description
-Sets if the last objective collected was a star (0) or a key (1)
-
-### Lua Example
-`set_last_star_or_key(value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_last_star_or_key(u8 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_last_completed_course_num](#get_last_completed_course_num)
-
-### Description
-Gets the last course a star or key was collected in
-
-### Lua Example
-`local integerValue = get_last_completed_course_num()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u8 get_last_completed_course_num(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_last_completed_course_num](#set_last_completed_course_num)
-
-### Description
-Sets the last course a star or key was collected in
-
-### Lua Example
-`set_last_completed_course_num(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_last_completed_course_num(u8 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_last_completed_star_num](#get_last_completed_star_num)
-
-### Description
-Gets the last collected star's number (1-7)
-
-### Lua Example
-`local integerValue = get_last_completed_star_num()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u8 get_last_completed_star_num(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_last_completed_star_num](#set_last_completed_star_num)
-
-### Description
-Sets the last collected star's number (1-7)
-
-### Lua Example
-`set_last_completed_star_num(starNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| starNum | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_last_completed_star_num(u8 starNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_got_file_coin_hi_score](#get_got_file_coin_hi_score)
-
-### Description
-Checks if the save file's coin "HI SCORE" was obtained with the last star or key collection
-
-### Lua Example
-`local booleanValue = get_got_file_coin_hi_score()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool get_got_file_coin_hi_score(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_got_file_coin_hi_score](#set_got_file_coin_hi_score)
-
-### Description
-Sets if the save file's coin "HI SCORE" was obtained with the last star or key collection
-
-### Lua Example
-`set_got_file_coin_hi_score(value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_got_file_coin_hi_score(bool value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_save_file_modified](#get_save_file_modified)
-
-### Description
-Checks if the save file has been modified without saving
-
-### Lua Example
-`local booleanValue = get_save_file_modified()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool get_save_file_modified(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_save_file_modified](#set_save_file_modified)
-
-### Description
-Sets if the save file has been modified without saving
-
-### Lua Example
-`set_save_file_modified(value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_save_file_modified(bool value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_hide](#hud_hide)
-
-### Description
-Hides the HUD
-
-### Lua Example
-`hud_hide()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void hud_hide(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_show](#hud_show)
-
-### Description
-Shows the HUD
-
-### Lua Example
-`hud_show()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void hud_show(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_is_hidden](#hud_is_hidden)
-
-### Description
-Checks if the HUD is hidden
-
-### Lua Example
-`local booleanValue = hud_is_hidden()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool hud_is_hidden(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_get_value](#hud_get_value)
-
-### Description
-Gets a HUD display value
-
-### Lua Example
-`local integerValue = hud_get_value(type)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 hud_get_value(enum HudDisplayValue type);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_set_value](#hud_set_value)
-
-### Description
-Sets a HUD display value
-
-### Lua Example
-`hud_set_value(type, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void hud_set_value(enum HudDisplayValue type, s32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_render_power_meter](#hud_render_power_meter)
-
-### Description
-Renders a power meter on the HUD
-
-### Lua Example
-`hud_render_power_meter(health, x, y, width, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| health | `integer` |
-| x | `number` |
-| y | `number` |
-| width | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_render_power_meter_interpolated](#hud_render_power_meter_interpolated)
-
-### Description
-Renders an interpolated power meter on the HUD
-
-### Lua Example
-`hud_render_power_meter_interpolated(health, prevX, prevY, prevWidth, prevHeight, x, y, width, height)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| health | `integer` |
-| prevX | `number` |
-| prevY | `number` |
-| prevWidth | `number` |
-| prevHeight | `number` |
-| x | `number` |
-| y | `number` |
-| width | `number` |
-| height | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void hud_render_power_meter_interpolated(s32 health, f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_get_flash](#hud_get_flash)
-
-### Description
-Gets if the star counter on the HUD should flash
-
-### Lua Example
-`local integerValue = hud_get_flash()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s8 hud_get_flash(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [hud_set_flash](#hud_set_flash)
-
-### Description
-Sets if the star counter on the HUD should flash
-
-### Lua Example
-`hud_set_flash(value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void hud_set_flash(s8 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [act_select_hud_hide](#act_select_hud_hide)
-
-### Description
-Hides part of the Act Select HUD
-
-### Lua Example
-`act_select_hud_hide(part)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
-
-### Returns
-- None
-
-### C Prototype
-`void act_select_hud_hide(enum ActSelectHudPart part);`
-
-[:arrow_up_small:](#)
-
-
-
-## [act_select_hud_show](#act_select_hud_show)
-
-### Description
-Shows part of the Act Select HUD
-
-### Lua Example
-`act_select_hud_show(part)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
-
-### Returns
-- None
-
-### C Prototype
-`void act_select_hud_show(enum ActSelectHudPart part);`
-
-[:arrow_up_small:](#)
-
-
-
-## [act_select_hud_is_hidden](#act_select_hud_is_hidden)
-
-### Description
-Checks if part of the Act Select HUD is hidden
-
-### Lua Example
-`local booleanValue = act_select_hud_is_hidden(part)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool act_select_hud_is_hidden(enum ActSelectHudPart part);`
-
-[:arrow_up_small:](#)
-
-
-
-## [is_game_paused](#is_game_paused)
-
-### Description
-Checks if the game is paused
-
-### Lua Example
-`local booleanValue = is_game_paused()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool is_game_paused(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [is_transition_playing](#is_transition_playing)
-
-### Description
-Checks if a screen transition is playing
-
-### Lua Example
-`local booleanValue = is_transition_playing()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool is_transition_playing(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [allocate_mario_action](#allocate_mario_action)
-
-### Description
-Allocates an action ID with bitwise flags
-
-### Lua Example
-`local integerValue = allocate_mario_action(actFlags)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| actFlags | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`u32 allocate_mario_action(u32 actFlags);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
-
-### Description
-Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
-
-### Lua Example
-`local numberValue = get_hand_foot_pos_x(m, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| index | `integer` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_hand_foot_pos_y](#get_hand_foot_pos_y)
-
-### Description
-Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to note that the positions are not updated off-screen
-
-### Lua Example
-`local numberValue = get_hand_foot_pos_y(m, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| index | `integer` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_hand_foot_pos_z](#get_hand_foot_pos_z)
-
-### Description
-Gets the Z coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
-
-### Lua Example
-`local numberValue = get_hand_foot_pos_z(m, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| index | `integer` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_mario_anim_part_pos](#get_mario_anim_part_pos)
-
-### Description
-Retrieves the animated part position associated to `animPart` from the MarioState `m` and stores it into `pos`. Returns `true` on success or `false` on failure
-
-### Lua Example
-`local booleanValue = get_mario_anim_part_pos(m, animPart, pos)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| m | [MarioState](structs.md#MarioState) |
-| animPart | `integer` |
-| pos | [Vec3f](structs.md#Vec3f) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_current_save_file_num](#get_current_save_file_num)
-
-### Description
-Gets the current save file number (1-indexed)
-
-### Lua Example
-`local integerValue = get_current_save_file_num()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 get_current_save_file_num(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [save_file_get_using_backup_slot](#save_file_get_using_backup_slot)
-
-### Description
-Checks if the save file is using its backup slot
-
-### Lua Example
-`local booleanValue = save_file_get_using_backup_slot()`
-
-### Parameters
-- None
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool save_file_get_using_backup_slot(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [save_file_set_using_backup_slot](#save_file_set_using_backup_slot)
-
-### Description
-Sets if the save file should use its backup slot
-
-### Lua Example
-`save_file_set_using_backup_slot(usingBackupSlot)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| usingBackupSlot | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void save_file_set_using_backup_slot(bool usingBackupSlot);`
-
-[:arrow_up_small:](#)
-
-
-
-## [movtexqc_register](#movtexqc_register)
-
-### Description
-Registers a custom moving texture entry (used for vanilla water boxes)
-
-### Lua Example
-`movtexqc_register(name, level, area, type)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| name | `string` |
-| level | `integer` |
-| area | `integer` |
-| type | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void movtexqc_register(const char* name, s16 level, s16 area, s16 type);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_water_level](#get_water_level)
-
-### Description
-Gets the water level in an area corresponding to `index` (0-indexed)
-
-### Lua Example
-`local integerValue = get_water_level(index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 get_water_level(u8 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_water_level](#set_water_level)
-
-### Description
-Sets the water level in an area corresponding to `index` (0-indexed)
-
-### Lua Example
-`set_water_level(index, height, sync)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-| height | `integer` |
-| sync | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_water_level(u8 index, s16 height, bool sync);`
-
-[:arrow_up_small:](#)
-
-
-
-## [course_is_main_course](#course_is_main_course)
-
-### Description
-Checks if a course is a main course and not the castle or secret levels
-
-### Lua Example
-`local booleanValue = course_is_main_course(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool course_is_main_course(u16 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_ttc_speed_setting](#get_ttc_speed_setting)
-
-### Description
-Gets TTC's speed setting
-
-### Lua Example
-`local integerValue = get_ttc_speed_setting()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 get_ttc_speed_setting(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_ttc_speed_setting](#set_ttc_speed_setting)
-
-### Description
-Sets TTC's speed setting (TTC_SPEED_*)
-
-### Lua Example
-`set_ttc_speed_setting(speed)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| speed | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_ttc_speed_setting(s16 speed);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_time](#get_time)
-
-### Description
-Gets the Unix Timestamp
-
-### Lua Example
-`local integerValue = get_time()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s64 get_time(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_date_and_time](#get_date_and_time)
-
-### Description
-Gets the system clock's date and time
-
-### Lua Example
-`local DateTimeValue = get_date_and_time()`
-
-### Parameters
-- None
-
-### Returns
-[DateTime](structs.md#DateTime)
-
-### C Prototype
-`struct DateTime* get_date_and_time(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_envfx](#get_envfx)
-
-### Description
-Gets the non overridden environment effect (e.g. snow)
-
-### Lua Example
-`local integerValue = get_envfx()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u16 get_envfx(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_override_envfx](#set_override_envfx)
-
-### Description
-Sets the override environment effect (e.g. snow)
-
-### Lua Example
-`set_override_envfx(envfx)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| envfx | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_override_envfx(s32 envfx);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_global_timer](#get_global_timer)
-
-### Description
-Gets the global timer that has been ticking at 30 frames per second since game boot
-
-### Lua Example
-`local integerValue = get_global_timer()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`u32 get_global_timer(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_dialog_response](#get_dialog_response)
-
-### Description
-Gets the choice selected inside of a dialog box (0-1)
-
-### Lua Example
-`local integerValue = get_dialog_response()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 get_dialog_response(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_local_discord_id](#get_local_discord_id)
-
-### Description
-Gets the local discord ID if it isn't disabled, otherwise "0" is returned
-
-### Lua Example
-`local stringValue = get_local_discord_id()`
-
-### Parameters
-- None
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* get_local_discord_id(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_coopnet_id](#get_coopnet_id)
-
-### Description
-Gets the CoopNet ID of a player with `localIndex` if CoopNet is being used and the player is connected, otherwise "-1" is returned
-
-### Lua Example
-`local stringValue = get_coopnet_id(localIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| localIndex | `integer` |
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* get_coopnet_id(s8 localIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_volume_master](#get_volume_master)
-
-### Description
-Gets the master volume level
-
-### Lua Example
-`local numberValue = get_volume_master()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_volume_master(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_volume_level](#get_volume_level)
-
-### Description
-Gets the volume level of music
-
-### Lua Example
-`local numberValue = get_volume_level()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_volume_level(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_volume_sfx](#get_volume_sfx)
-
-### Description
-Gets the volume level of sound effects
-
-### Lua Example
-`local numberValue = get_volume_sfx()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_volume_sfx(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_volume_env](#get_volume_env)
-
-### Description
-Gets the volume level of environment sounds effects
-
-### Lua Example
-`local numberValue = get_volume_env()`
-
-### Parameters
-- None
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 get_volume_env(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_volume_master](#set_volume_master)
-
-### Description
-Sets the master volume level
-
-### Lua Example
-`set_volume_master(volume)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| volume | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_volume_master(f32 volume);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_volume_level](#set_volume_level)
-
-### Description
-Sets the volume level of music
-
-### Lua Example
-`set_volume_level(volume)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| volume | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_volume_level(f32 volume);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_volume_sfx](#set_volume_sfx)
-
-### Description
-Sets the volume level of sound effects
-
-### Lua Example
-`set_volume_sfx(volume)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| volume | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_volume_sfx(f32 volume);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_volume_env](#set_volume_env)
-
-### Description
-Sets the volume level of environment sounds effects
-
-### Lua Example
-`set_volume_env(volume)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| volume | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_volume_env(f32 volume);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_environment_region](#get_environment_region)
-
-### Description
-Gets an environment region (gas/water boxes) height value
-
-### Lua Example
-`local integerValue = get_environment_region(index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 get_environment_region(u8 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_environment_region](#set_environment_region)
-
-### Description
-Sets an environment region (gas/water boxes) height value
-
-### Lua Example
-`set_environment_region(index, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_environment_region(u8 index, s16 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [mod_file_exists](#mod_file_exists)
-
-### Description
-Checks if a file exists inside of a mod
-
-### Lua Example
-`local booleanValue = mod_file_exists(filename)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| filename | `string` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool mod_file_exists(const char* filename);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_active_mod](#get_active_mod)
-
-### Description
-Gets the mod currently being processed
-
-### Lua Example
-`local ModValue = get_active_mod()`
-
-### Parameters
-- None
-
-### Returns
-[Mod](structs.md#Mod)
-
-### C Prototype
-`struct Mod* get_active_mod(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_window_title](#set_window_title)
-
-### Description
-Sets the window title to a custom title
-
-### Lua Example
-`set_window_title(title)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| title | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_window_title(const char* title);`
-
-[:arrow_up_small:](#)
-
-
-
-## [reset_window_title](#reset_window_title)
-
-### Description
-Resets the window title
-
-### Lua Example
-`reset_window_title()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void reset_window_title(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_os_name](#get_os_name)
-
-### Description
-Gets the name of the operating system the game is running on
-
-### Lua Example
-`local stringValue = get_os_name()`
-
-### Parameters
-- None
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* get_os_name(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_root](#geo_get_current_root)
-
-### Description
-Gets the current GraphNodeRoot
-
-### Lua Example
-`local GraphNodeRootValue = geo_get_current_root()`
-
-### Parameters
-- None
-
-### Returns
-[GraphNodeRoot](structs.md#GraphNodeRoot)
-
-### C Prototype
-`struct GraphNodeRoot* geo_get_current_root(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_master_list](#geo_get_current_master_list)
-
-### Description
-Gets the current GraphNodeMasterList
-
-### Lua Example
-`local GraphNodeMasterListValue = geo_get_current_master_list()`
-
-### Parameters
-- None
-
-### Returns
-[GraphNodeMasterList](structs.md#GraphNodeMasterList)
-
-### C Prototype
-`struct GraphNodeMasterList* geo_get_current_master_list(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_perspective](#geo_get_current_perspective)
-
-### Description
-Gets the current GraphNodePerspective
-
-### Lua Example
-`local GraphNodePerspectiveValue = geo_get_current_perspective()`
-
-### Parameters
-- None
-
-### Returns
-[GraphNodePerspective](structs.md#GraphNodePerspective)
-
-### C Prototype
-`struct GraphNodePerspective* geo_get_current_perspective(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_camera](#geo_get_current_camera)
-
-### Description
-Gets the current GraphNodeCamera
-
-### Lua Example
-`local GraphNodeCameraValue = geo_get_current_camera()`
-
-### Parameters
-- None
-
-### Returns
-[GraphNodeCamera](structs.md#GraphNodeCamera)
-
-### C Prototype
-`struct GraphNodeCamera* geo_get_current_camera(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_held_object](#geo_get_current_held_object)
-
-### Description
-Gets the current GraphNodeHeldObject
-
-### Lua Example
-`local GraphNodeHeldObjectValue = geo_get_current_held_object()`
-
-### Parameters
-- None
-
-### Returns
-[GraphNodeHeldObject](structs.md#GraphNodeHeldObject)
-
-### C Prototype
-`struct GraphNodeHeldObject* geo_get_current_held_object(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [texture_to_lua_table](#texture_to_lua_table)
-
-### Description
-Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures.
-
-### Lua Example
-`texture_to_lua_table(tex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| tex | `Pointer` <`integer`> |
-
-### Returns
-- None
-
-### C Prototype
-`void texture_to_lua_table(const u8 *tex);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from smlua_model_utils.h
-
-
-
-
-## [smlua_model_util_get_id](#smlua_model_util_get_id)
-
-### Description
-Gets the extended model ID for the `name` of a `GeoLayout`
-
-### Lua Example
-`local enumValue = smlua_model_util_get_id(name)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| name | `string` |
-
-### Returns
-[enum ModelExtendedId](constants.md#enum-ModelExtendedId)
-
-### C Prototype
-`enum ModelExtendedId smlua_model_util_get_id(const char* name);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from smlua_obj_utils.h
-
-
-
-
-## [spawn_sync_object](#spawn_sync_object)
-
-### Description
-Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
-
-### Lua Example
-`local ObjectValue = spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-| objSetupFunction | `Lua Function` () |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);`
-
-[:arrow_up_small:](#)
-
-
-
-## [spawn_non_sync_object](#spawn_non_sync_object)
-
-### Description
-Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
-
-### Lua Example
-`local ObjectValue = spawn_non_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-| objSetupFunction | `Lua Function` () |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_has_behavior_id](#obj_has_behavior_id)
-
-### Description
-Checks if an object has `behaviorId`
-
-### Lua Example
-`local integerValue = obj_has_behavior_id(o, behaviorId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_has_model_extended](#obj_has_model_extended)
-
-### Description
-Checks if an object's model is equal to `modelId`
-
-### Lua Example
-`local integerValue = obj_has_model_extended(o, modelId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_model_id_extended](#obj_get_model_id_extended)
-
-### Description
-Returns an object's extended model id
-
-### Lua Example
-`local enumValue = obj_get_model_id_extended(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-[enum ModelExtendedId](constants.md#enum-ModelExtendedId)
-
-### C Prototype
-`enum ModelExtendedId obj_get_model_id_extended(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_model_extended](#obj_set_model_extended)
-
-### Description
-Sets an object's model to `modelId`
-
-### Lua Example
-`obj_set_model_extended(o, modelId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_trajectory](#get_trajectory)
-
-### Description
-Gets a trajectory by `name`
-
-### Lua Example
-`local PointerValue = get_trajectory(name)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| name | `string` |
-
-### Returns
-- `Pointer` <`Trajectory`>
-
-### C Prototype
-`Trajectory* get_trajectory(const char* name);`
-
-[:arrow_up_small:](#)
-
-
-
-## [geo_get_current_object](#geo_get_current_object)
-
-### Description
-When used in a geo function, retrieve the current processed object
-
-### Lua Example
-`local ObjectValue = geo_get_current_object()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *geo_get_current_object(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_current_object](#get_current_object)
-
-### Description
-Gets the object currently being processed
-
-### Lua Example
-`local ObjectValue = get_current_object()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *get_current_object(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_dialog_object](#get_dialog_object)
-
-### Description
-Gets the NPC object Mario is talking to
-
-### Lua Example
-`local ObjectValue = get_dialog_object()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *get_dialog_object(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_cutscene_focus](#get_cutscene_focus)
-
-### Description
-Gets the cutscene focus object
-
-### Lua Example
-`local ObjectValue = get_cutscene_focus()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *get_cutscene_focus(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_secondary_camera_focus](#get_secondary_camera_focus)
-
-### Description
-Gets the secondary camera focus object
-
-### Lua Example
-`local ObjectValue = get_secondary_camera_focus()`
-
-### Parameters
-- None
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *get_secondary_camera_focus(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_cutscene_focus](#set_cutscene_focus)
-
-### Description
-Sets the cutscene focus object
-
-### Lua Example
-`set_cutscene_focus(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void set_cutscene_focus(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_secondary_camera_focus](#set_secondary_camera_focus)
-
-### Description
-Sets the secondary camera focus object
-
-### Lua Example
-`set_secondary_camera_focus(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- None
-
-### C Prototype
-`void set_secondary_camera_focus(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_first](#obj_get_first)
-
-### Description
-Gets the first object in an object list
-
-### Lua Example
-`local ObjectValue = obj_get_first(objList)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| objList | [enum ObjectList](constants.md#enum-ObjectList) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_first(enum ObjectList objList);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_first_with_behavior_id](#obj_get_first_with_behavior_id)
-
-### Description
-Gets the first object loaded with `behaviorId`
-
-### Lua Example
-`local ObjectValue = obj_get_first_with_behavior_id(behaviorId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_first_with_behavior_id_and_field_s32](#obj_get_first_with_behavior_id_and_field_s32)
-
-### Description
-Gets the first object loaded with `behaviorId` and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
-
-### Lua Example
-`local ObjectValue = obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-| fieldIndex | `integer` |
-| value | `integer` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_first_with_behavior_id_and_field_f32](#obj_get_first_with_behavior_id_and_field_f32)
-
-### Description
-Gets the first object loaded with `behaviorId` and object float field (look in `object_fields.h` to get the index of a field)
-
-### Lua Example
-`local ObjectValue = obj_get_first_with_behavior_id_and_field_f32(behaviorId, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-| fieldIndex | `integer` |
-| value | `number` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_next](#obj_get_next)
-
-### Description
-Gets the next object in an object list
-
-### Lua Example
-`local ObjectValue = obj_get_next(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_next(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id)
-
-### Description
-Gets the next object loaded with the same behavior ID
-
-### Lua Example
-`local ObjectValue = obj_get_next_with_same_behavior_id(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_next_with_same_behavior_id(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32)
-
-### Description
-Gets the next object loaded with the same behavior ID and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
-
-### Lua Example
-`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_s32(o, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| value | `integer` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32)
-
-### Description
-Gets the next object loaded with the same behavior ID and object float field (look in `object_fields.h` to get the index of a field)
-
-### Lua Example
-`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_f32(o, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| value | `number` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id)
-
-### Description
-Gets the nearest object with `behaviorId` to `o`
-
-### Lua Example
-`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_count_objects_with_behavior_id](#obj_count_objects_with_behavior_id)
-
-### Description
-Counts every object with `behaviorId`
-
-### Lua Example
-`local integerValue = obj_count_objects_with_behavior_id(behaviorId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_collided_object](#obj_get_collided_object)
-
-### Description
-Gets the corresponding collided object to an index from `o`
-
-### Lua Example
-`local ObjectValue = obj_get_collided_object(o, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| index | `integer` |
-
-### Returns
-[Object](structs.md#Object)
-
-### C Prototype
-`struct Object *obj_get_collided_object(struct Object *o, s16 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_field_u32](#obj_get_field_u32)
-
-### Description
-Gets the unsigned 32-bit integer value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`local integerValue = obj_get_field_u32(o, fieldIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`u32 obj_get_field_u32(struct Object *o, s32 fieldIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_field_s32](#obj_get_field_s32)
-
-### Description
-Gets the signed 32-bit integer value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`local integerValue = obj_get_field_s32(o, fieldIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 obj_get_field_s32(struct Object *o, s32 fieldIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_field_f32](#obj_get_field_f32)
-
-### Description
-Sets the float value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`local numberValue = obj_get_field_f32(o, fieldIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 obj_get_field_f32(struct Object *o, s32 fieldIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_field_s16](#obj_get_field_s16)
-
-### Description
-Gets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex`
-
-### Lua Example
-`local integerValue = obj_get_field_s16(o, fieldIndex, fieldSubIndex)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| fieldSubIndex | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_field_u32](#obj_set_field_u32)
-
-### Description
-Sets the unsigned 32-bit integer value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`obj_set_field_u32(o, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_field_s32](#obj_set_field_s32)
-
-### Description
-Sets the signed 32-bit integer value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`obj_set_field_s32(o, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_field_f32](#obj_set_field_f32)
-
-### Description
-Sets the float value from the field corresponding to `fieldIndex`
-
-### Lua Example
-`obj_set_field_f32(o, fieldIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| value | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_field_s16](#obj_set_field_s16)
-
-### Description
-Sets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex`
-
-### Lua Example
-`obj_set_field_s16(o, fieldIndex, fieldSubIndex, value)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| fieldIndex | `integer` |
-| fieldSubIndex | `integer` |
-| value | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info)
-
-### Description
-Returns a temporary particle spawn info pointer with its model loaded in from `modelId`
-
-### Lua Example
-`local SpawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
-
-### Returns
-[SpawnParticlesInfo](structs.md#SpawnParticlesInfo)
-
-### C Prototype
-`struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [get_temp_object_hitbox](#get_temp_object_hitbox)
-
-### Description
-Returns a temporary object hitbox pointer
-
-### Lua Example
-`local ObjectHitboxValue = get_temp_object_hitbox()`
-
-### Parameters
-- None
-
-### Returns
-[ObjectHitbox](structs.md#ObjectHitbox)
-
-### C Prototype
-`struct ObjectHitbox* get_temp_object_hitbox(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_attackable](#obj_is_attackable)
-
-### Description
-Checks if `o` is attackable
-
-### Lua Example
-`local booleanValue = obj_is_attackable(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_attackable(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_breakable_object](#obj_is_breakable_object)
-
-### Description
-Checks if `o` is breakable
-
-### Lua Example
-`local booleanValue = obj_is_breakable_object(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_breakable_object(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_bully](#obj_is_bully)
-
-### Description
-Checks if `o` is a Bully
-
-### Lua Example
-`local booleanValue = obj_is_bully(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_bully(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_coin](#obj_is_coin)
-
-### Description
-Checks if `o` is a coin
-
-### Lua Example
-`local booleanValue = obj_is_coin(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_coin(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_exclamation_box](#obj_is_exclamation_box)
-
-### Description
-Checks if `o` is an exclamation box
-
-### Lua Example
-`local booleanValue = obj_is_exclamation_box(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_exclamation_box(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_grabbable](#obj_is_grabbable)
-
-### Description
-Checks if `o` is grabbable
-
-### Lua Example
-`local booleanValue = obj_is_grabbable(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_grabbable(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_mushroom_1up](#obj_is_mushroom_1up)
-
-### Description
-Checks if `o` is a 1-Up Mushroom
-
-### Lua Example
-`local booleanValue = obj_is_mushroom_1up(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_mushroom_1up(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_secret](#obj_is_secret)
-
-### Description
-Checks if `o` is a secret
-
-### Lua Example
-`local booleanValue = obj_is_secret(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_secret(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_is_valid_for_interaction](#obj_is_valid_for_interaction)
-
-### Description
-Checks if `o` is activated, tangible, and interactible
-
-### Lua Example
-`local booleanValue = obj_is_valid_for_interaction(o)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_is_valid_for_interaction(struct Object *o);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_check_hitbox_overlap](#obj_check_hitbox_overlap)
-
-### Description
-Checks if `o1`'s hitbox is colliding with `o2`'s hitbox
-
-### Lua Example
-`local booleanValue = obj_check_hitbox_overlap(o1, o2)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o1 | [Object](structs.md#Object) |
-| o2 | [Object](structs.md#Object) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_check_hitbox_overlap(struct Object *o1, struct Object *o2);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_check_overlap_with_hitbox_params](#obj_check_overlap_with_hitbox_params)
-
-### Description
-Checks if `o`'s hitbox is colliding with the parameters of a hitbox
-
-### Lua Example
-`local booleanValue = obj_check_overlap_with_hitbox_params(o, x, y, z, h, r, d)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-| h | `number` |
-| r | `number` |
-| d | `number` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool obj_check_overlap_with_hitbox_params(struct Object *o, f32 x, f32 y, f32 z, f32 h, f32 r, f32 d);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_set_vel](#obj_set_vel)
-
-### Description
-Sets an object's velocity to `vx`, `vy`, and `vz`
-
-### Lua Example
-`obj_set_vel(o, vx, vy, vz)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| vx | `number` |
-| vy | `number` |
-| vz | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_set_vel(struct Object *o, f32 vx, f32 vy, f32 vz);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_move_xyz](#obj_move_xyz)
-
-### Description
-Moves the object in the direction of `dx`, `dy`, and `dz`
-
-### Lua Example
-`obj_move_xyz(o, dx, dy, dz)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| dx | `number` |
-| dy | `number` |
-| dz | `number` |
-
-### Returns
-- None
-
-### C Prototype
-`void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_whirlpools](#set_whirlpools)
-
-### Description
-Sets the parameters of one of the two whirlpools (0-indexed) in an area
-
-### Lua Example
-`set_whirlpools(x, y, z, strength, area, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-| strength | `integer` |
-| area | `integer` |
-| index | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from smlua_text_utils.h
-
-
-
-
-## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all)
-
-### Description
-Resets every modified dialog back to vanilla
-
-### Lua Example
-`smlua_text_utils_reset_all()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_reset_all(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_dialog_get](#smlua_text_utils_dialog_get)
-
-### Description
-Gets the DialogEntry struct for the given `dialogId`
-
-### Lua Example
-`local DialogEntryValue = smlua_text_utils_dialog_get(dialogId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dialogId | [enum DialogId](constants.md#enum-DialogId) |
-
-### Returns
-[DialogEntry](structs.md#DialogEntry)
-
-### C Prototype
-`struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace)
-
-### Description
-Replaces `dialogId` with a custom one
-
-### Lua Example
-`smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffset, width, str)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dialogId | [enum DialogId](constants.md#enum-DialogId) |
-| unused | `integer` |
-| linesPerBox | `integer` |
-| leftOffset | `integer` |
-| width | `integer` |
-| str | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_dialog_restore](#smlua_text_utils_dialog_restore)
-
-### Description
-Restores a replaced DialogEntry to its original state.
-
-### Lua Example
-`smlua_text_utils_dialog_restore(dialogId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dialogId | [enum DialogId](constants.md#enum-DialogId) |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_dialog_restore(enum DialogId dialogId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced)
-
-### Description
-Returns whether the dialog with the given ID has been replaced
-
-### Lua Example
-`local booleanValue = smlua_text_utils_dialog_is_replaced(dialogId)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dialogId | [enum DialogId](constants.md#enum-DialogId) |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_allocate_dialog](#smlua_text_utils_allocate_dialog)
-
-### Description
-Allocates a new dialog entry
-
-### Lua Example
-`local integerValue = smlua_text_utils_allocate_dialog()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 smlua_text_utils_allocate_dialog(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace)
-
-### Description
-Replaces the act names of `courseNum`
-
-### Lua Example
-`smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2, act3, act4, act5, act6)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| courseName | `string` |
-| act1 | `string` |
-| act2 | `string` |
-| act3 | `string` |
-| act4 | `string` |
-| act5 | `string` |
-| act6 | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace)
-
-### Description
-Replaces the secret star course name of `courseNum` with `courseName`
-
-### Lua Example
-`smlua_text_utils_secret_star_replace(courseNum, courseName)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| courseName | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace)
-
-### Description
-Replaces the name of `courseNum` with `name`
-
-### Lua Example
-`smlua_text_utils_course_name_replace(courseNum, name)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| name | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get)
-
-### Description
-Gets the name of `courseNum`
-
-### Lua Example
-`local stringValue = smlua_text_utils_course_name_get(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* smlua_text_utils_course_name_get(s16 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index)
-
-### Description
-Gets the index of the mod that replaced the name of `courseNum`
-
-### Lua Example
-`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset)
-
-### Description
-Resets the name of `courseNum`
-
-### Lua Example
-`smlua_text_utils_course_name_reset(courseNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_course_name_reset(s16 courseNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace)
-
-### Description
-Replaces the act name of `actNum` in `courseNum` with `name`
-
-### Lua Example
-`smlua_text_utils_act_name_replace(courseNum, actNum, name)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| actNum | `integer` |
-| name | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get)
-
-### Description
-Gets the act name of `actNum` in `courseNum`
-
-### Lua Example
-`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| actNum | `integer` |
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_act_name_mod_index](#smlua_text_utils_act_name_mod_index)
-
-### Description
-Gets the index of the mod that replaced the act name of `actNum` in `courseNum`
-
-### Lua Example
-`local integerValue = smlua_text_utils_act_name_mod_index(courseNum, actNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| actNum | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 smlua_text_utils_act_name_mod_index(s16 courseNum, u8 actNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset)
-
-### Description
-Resets the act name of `actNum` in `courseNum`
-
-### Lua Example
-`smlua_text_utils_act_name_reset(courseNum, actNum)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| courseNum | `integer` |
-| actNum | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace)
-
-### Description
-Replaces the castle secret stars text with `name`
-
-### Lua Example
-`smlua_text_utils_castle_secret_stars_replace(name)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| name | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_castle_secret_stars_replace(const char* name);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_castle_secret_stars_get](#smlua_text_utils_castle_secret_stars_get)
-
-### Description
-Gets the castle secret stars text
-
-### Lua Example
-`local stringValue = smlua_text_utils_castle_secret_stars_get()`
-
-### Parameters
-- None
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* smlua_text_utils_castle_secret_stars_get();`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_castle_secret_stars_mod_index](#smlua_text_utils_castle_secret_stars_mod_index)
-
-### Description
-Gets the index of the mod that replaced the castle secret stars text
-
-### Lua Example
-`local integerValue = smlua_text_utils_castle_secret_stars_mod_index()`
-
-### Parameters
-- None
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 smlua_text_utils_castle_secret_stars_mod_index();`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_castle_secret_stars_reset](#smlua_text_utils_castle_secret_stars_reset)
-
-### Description
-Resets the castle secret stars text
-
-### Lua Example
-`smlua_text_utils_castle_secret_stars_reset()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_castle_secret_stars_reset();`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_extra_text_replace](#smlua_text_utils_extra_text_replace)
-
-### Description
-Replace extra text (e.g. one of the castle's secret stars) with `text`
-
-### Lua Example
-`smlua_text_utils_extra_text_replace(index, text)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-| text | `string` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_extra_text_replace(s16 index, const char* text);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_extra_text_get](#smlua_text_utils_extra_text_get)
-
-### Description
-Gets the extra text at `index`
-
-### Lua Example
-`local stringValue = smlua_text_utils_extra_text_get(index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* smlua_text_utils_extra_text_get(s16 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_extra_text_mod_index](#smlua_text_utils_extra_text_mod_index)
-
-### Description
-Gets the index of the mod that replaced the extra text at `index`
-
-### Lua Example
-`local integerValue = smlua_text_utils_extra_text_mod_index(index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 smlua_text_utils_extra_text_mod_index(s16 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_extra_text_reset](#smlua_text_utils_extra_text_reset)
-
-### Description
-Resets the extra text at `index`
-
-### Lua Example
-`smlua_text_utils_extra_text_reset(index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| index | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void smlua_text_utils_extra_text_reset(s16 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [smlua_text_utils_get_language](#smlua_text_utils_get_language)
-
-### Description
-Gets the current language
-
-### Lua Example
-`local stringValue = smlua_text_utils_get_language()`
-
-### Parameters
-- None
-
-### Returns
-- `string`
-
-### C Prototype
-`const char* smlua_text_utils_get_language(void);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from sound_init.h
-
-
-
-
-## [reset_volume](#reset_volume)
-
-### Description
-Resets if music volume has been lowered
-
-### Lua Example
-`reset_volume()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void reset_volume(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [raise_background_noise](#raise_background_noise)
-
-### Description
-Raises music volume back up to normal levels
-
-### Lua Example
-`raise_background_noise(a)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void raise_background_noise(s32 a);`
-
-[:arrow_up_small:](#)
-
-
-
-## [lower_background_noise](#lower_background_noise)
-
-### Description
-Lowers the volume of music by 40%
-
-### Lua Example
-`lower_background_noise(a)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void lower_background_noise(s32 a);`
-
-[:arrow_up_small:](#)
-
-
-
-## [disable_background_sound](#disable_background_sound)
-
-### Description
-Disables background soundbanks
-
-### Lua Example
-`disable_background_sound()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void disable_background_sound(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [enable_background_sound](#enable_background_sound)
-
-### Description
-Enables background soundbanks
-
-### Lua Example
-`enable_background_sound()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void enable_background_sound(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_menu_sounds](#play_menu_sounds)
-
-### Description
-Play menu sounds from `SOUND_MENU_FLAG_*` constants and queues rumble if `SOUND_MENU_FLAG_LETGOMARIOFACE` is one of the flags
-
-### Lua Example
-`play_menu_sounds(soundMenuFlags)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| soundMenuFlags | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void play_menu_sounds(s16 soundMenuFlags);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_painting_eject_sound](#play_painting_eject_sound)
-
-### Description
-Plays the painting eject sound effect if it has not already been played
-
-### Lua Example
-`play_painting_eject_sound()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void play_painting_eject_sound(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_infinite_stairs_music](#play_infinite_stairs_music)
-
-### Description
-Plays the infinite stairs music if you're in the endless stairs room and have less than `gLevelValues.infiniteStairsRequirement` stars
-
-### Lua Example
-`play_infinite_stairs_music()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void play_infinite_stairs_music(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_background_music](#set_background_music)
-
-### Description
-Sets the background music to `seqArgs` on sequence player `a` with a fade in time of `fadeTimer`
-
-### Lua Example
-`set_background_music(a, seqArgs, fadeTimer)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| a | `integer` |
-| seqArgs | `integer` |
-| fadeTimer | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_background_music(u16 a, u16 seqArgs, s16 fadeTimer);`
-
-[:arrow_up_small:](#)
-
-
-
-## [fadeout_music](#fadeout_music)
-
-### Description
-Fades out level, shell, and cap music
-
-### Lua Example
-`fadeout_music(fadeOutTime)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| fadeOutTime | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void fadeout_music(s16 fadeOutTime);`
-
-[:arrow_up_small:](#)
-
-
-
-## [fadeout_level_music](#fadeout_level_music)
-
-### Description
-Fades out the level sequence player
-
-### Lua Example
-`fadeout_level_music(fadeTimer)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| fadeTimer | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void fadeout_level_music(s16 fadeTimer);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_cutscene_music](#play_cutscene_music)
-
-### Description
-Plays and sets the current music to `seqArgs`
-
-### Lua Example
-`play_cutscene_music(seqArgs)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| seqArgs | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void play_cutscene_music(u16 seqArgs);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_shell_music](#play_shell_music)
-
-### Description
-Plays shell music
-
-### Lua Example
-`play_shell_music()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void play_shell_music(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [stop_shell_music](#stop_shell_music)
-
-### Description
-Stops shell music completely
-
-### Lua Example
-`stop_shell_music()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void stop_shell_music(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [play_cap_music](#play_cap_music)
-
-### Description
-Plays `seqArgs` as cap music
-
-### Lua Example
-`play_cap_music(seqArgs)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| seqArgs | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void play_cap_music(u16 seqArgs);`
-
-[:arrow_up_small:](#)
-
-
-
-## [fadeout_cap_music](#fadeout_cap_music)
-
-### Description
-Fades out cap music
-
-### Lua Example
-`fadeout_cap_music()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void fadeout_cap_music(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [stop_cap_music](#stop_cap_music)
-
-### Description
-Stops cap music completely
-
-### Lua Example
-`stop_cap_music()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void stop_cap_music(void);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from spawn_sound.h
-
-
-
-
-## [cur_obj_play_sound_1](#cur_obj_play_sound_1)
-
-### Description
-Plays a sound if the current object is visible
-
-### Lua Example
-`cur_obj_play_sound_1(soundMagic)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| soundMagic | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_play_sound_1(s32 soundMagic);`
-
-[:arrow_up_small:](#)
-
-
-
-## [cur_obj_play_sound_2](#cur_obj_play_sound_2)
-
-### Description
-Plays a sound if the current object is visible and queues rumble for specific sounds
-
-### Lua Example
-`cur_obj_play_sound_2(soundMagic)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| soundMagic | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void cur_obj_play_sound_2(s32 soundMagic);`
-
-[:arrow_up_small:](#)
-
-
-
-## [create_sound_spawner](#create_sound_spawner)
-
-### Description
-Create a sound spawner for objects that need a sound play once. (Breakable walls, King Bobomb exploding, etc)
-
-### Lua Example
-`create_sound_spawner(soundMagic)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| soundMagic | `integer` |
-
-### Returns
-- None
-
-### C Prototype
-`void create_sound_spawner(s32 soundMagic);`
-
-[:arrow_up_small:](#)
-
-
-
-## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1)
-
-### Description
-Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124. What an even more strange and confusing function
-
-### Lua Example
-`local integerValue = calc_dist_to_volume_range_1(distance)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| distance | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 calc_dist_to_volume_range_1(f32 distance);`
-
-[:arrow_up_small:](#)
-
-
-
-## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2)
-
-### Description
-Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127. What a strange and confusing function
-
-### Lua Example
-`local integerValue = calc_dist_to_volume_range_2(distance)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| distance | `number` |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 calc_dist_to_volume_range_2(f32 distance);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from surface_collision.h
-
-
-
-
-## [find_wall_collisions](#find_wall_collisions)
-
-### Description
-Detects wall collisions at a given position and adjusts the position based on the walls found. Returns the number of wall collisions detected
-
-### Lua Example
-`local integerValue = find_wall_collisions(colData)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| colData | [WallCollisionData](structs.md#WallCollisionData) |
-
-### Returns
-- `integer`
-
-### C Prototype
-`s32 find_wall_collisions(struct WallCollisionData *colData);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_ceil_height](#find_ceil_height)
-
-### Description
-Finds the height of the highest ceiling above a given position (x, y, z). If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default)
-
-### Lua Example
-`local numberValue = find_ceil_height(x, y, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 find_ceil_height(f32 x, f32 y, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_floor_height](#find_floor_height)
-
-### Description
-Finds the height of the highest floor below a given position (x, y, z). If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default)
-
-### Lua Example
-`local numberValue = find_floor_height(x, y, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `number` |
-| y | `number` |
-| z | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 find_floor_height(f32 x, f32 y, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_water_level](#find_water_level)
-
-### Description
-Finds the height of water at a given position (x, z), if the position is within a water region. If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
-
-### Lua Example
-`local numberValue = find_water_level(x, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `number` |
-| z | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 find_water_level(f32 x, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [find_poison_gas_level](#find_poison_gas_level)
-
-### Description
-Finds the height of the poison gas at a given position (x, z), if the position is within a gas region. If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
-
-### Lua Example
-`local numberValue = find_poison_gas_level(x, z)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| x | `number` |
-| z | `number` |
-
-### Returns
-- `number`
-
-### C Prototype
-`f32 find_poison_gas_level(f32 x, f32 z);`
-
-[:arrow_up_small:](#)
-
-
-
-## [set_find_wall_direction](#set_find_wall_direction)
-
-### Description
-Sets whether collision finding functions should check wall directions.
-
-### Lua Example
-`set_find_wall_direction(dir, active, airborne)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| dir | [Vec3f](structs.md#Vec3f) |
-| active | `boolean` |
-| airborne | `boolean` |
-
-### Returns
-- None
-
-### C Prototype
-`void set_find_wall_direction(Vec3f dir, bool active, bool airborne);`
-
-[:arrow_up_small:](#)
-
-
-
-## [closest_point_to_triangle](#closest_point_to_triangle)
-
-### Description
-Gets the closest point of the triangle to `src` and returns it in `out`.
-
-### Lua Example
-`closest_point_to_triangle(surf, src, out)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| surf | [Surface](structs.md#Surface) |
-| src | [Vec3f](structs.md#Vec3f) |
-| out | [Vec3f](structs.md#Vec3f) |
-
-### Returns
-- None
-
-### C Prototype
-`void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out);`
-
-[:arrow_up_small:](#)
-
-
-
----
-# functions from surface_load.h
-
-
-
-
-## [load_object_collision_model](#load_object_collision_model)
-
-### Description
-Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision
-
-### Lua Example
-`load_object_collision_model()`
-
-### Parameters
-- None
-
-### Returns
-- None
-
-### C Prototype
-`void load_object_collision_model(void);`
-
-[:arrow_up_small:](#)
-
-
-
-## [obj_get_surface_from_index](#obj_get_surface_from_index)
-
-### Description
-Gets a surface corresponding to `index` from the surface pool buffer
-
-### Lua Example
-`local SurfaceValue = obj_get_surface_from_index(o, index)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| o | [Object](structs.md#Object) |
-| index | `integer` |
-
-### Returns
-[Surface](structs.md#Surface)
-
-### C Prototype
-`struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);`
-
-[:arrow_up_small:](#)
-
-
-
-## [surface_has_force](#surface_has_force)
-
-### Description
-Checks if a surface has force
-
-### Lua Example
-`local booleanValue = surface_has_force(surfaceType)`
-
-### Parameters
-| Field | Type |
-| ----- | ---- |
-| surfaceType | `integer` |
-
-### Returns
-- `boolean`
-
-### C Prototype
-`bool surface_has_force(s16 surfaceType);`
-
-[:arrow_up_small:](#)
-
---
diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md
index bc3786df4..bfb92be17 100644
--- a/docs/lua/functions-7.md
+++ b/docs/lua/functions-7.md
@@ -5,6 +5,4787 @@
[< prev](functions-6.md) | [1](functions.md) | [2](functions-2.md) | [3](functions-3.md) | [4](functions-4.md) | [5](functions-5.md) | [6](functions-6.md) | 7]
+---
+# functions from smlua_level_utils.h
+
+
+
+
+## [smlua_level_util_change_area](#smlua_level_util_change_area)
+
+### Description
+Instantly changes the current area to `areaIndex`
+
+### Lua Example
+`smlua_level_util_change_area(areaIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| areaIndex | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_level_util_change_area(s32 areaIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_level_util_get_info](#smlua_level_util_get_info)
+
+### Description
+Gets information on a custom level from `levelNum`
+
+### Lua Example
+`local CustomLevelInfoValue = smlua_level_util_get_info(levelNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| levelNum | `integer` |
+
+### Returns
+[CustomLevelInfo](structs.md#CustomLevelInfo)
+
+### C Prototype
+`struct CustomLevelInfo* smlua_level_util_get_info(s16 levelNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_level_util_get_info_from_short_name](#smlua_level_util_get_info_from_short_name)
+
+### Description
+Gets information on a custom level from `shortName`
+
+### Lua Example
+`local CustomLevelInfoValue = smlua_level_util_get_info_from_short_name(shortName)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| shortName | `string` |
+
+### Returns
+[CustomLevelInfo](structs.md#CustomLevelInfo)
+
+### C Prototype
+`struct CustomLevelInfo* smlua_level_util_get_info_from_short_name(const char* shortName);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_level_util_get_info_from_course_num](#smlua_level_util_get_info_from_course_num)
+
+### Description
+Gets information on a custom level from `courseNum`
+
+### Lua Example
+`local CustomLevelInfoValue = smlua_level_util_get_info_from_course_num(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+[CustomLevelInfo](structs.md#CustomLevelInfo)
+
+### C Prototype
+`struct CustomLevelInfo* smlua_level_util_get_info_from_course_num(u8 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [level_register](#level_register)
+
+### Description
+Registers a fully custom level. Level ID begins at 50
+
+### Lua Example
+`local integerValue = level_register(scriptEntryName, courseNum, fullName, shortName, acousticReach, echoLevel1, echoLevel2, echoLevel3)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| scriptEntryName | `string` |
+| courseNum | `integer` |
+| fullName | `string` |
+| shortName | `string` |
+| acousticReach | `integer` |
+| echoLevel1 | `integer` |
+| echoLevel2 | `integer` |
+| echoLevel3 | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 level_register(const char* scriptEntryName, s16 courseNum, const char* fullName, const char* shortName, u32 acousticReach, u32 echoLevel1, u32 echoLevel2, u32 echoLevel3);`
+
+[:arrow_up_small:](#)
+
+
+
+## [level_is_vanilla_level](#level_is_vanilla_level)
+
+### Description
+Checks if `levelNum` is a vanilla level
+
+### Lua Example
+`local booleanValue = level_is_vanilla_level(levelNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| levelNum | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool level_is_vanilla_level(s16 levelNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_to_warpnode](#warp_to_warpnode)
+
+### Description
+Warps to `aWarpId` of `aArea` in `aLevel` during `aAct`
+
+### Lua Example
+`local booleanValue = warp_to_warpnode(aLevel, aArea, aAct, aWarpId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| aLevel | `integer` |
+| aArea | `integer` |
+| aAct | `integer` |
+| aWarpId | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_to_warpnode(s32 aLevel, s32 aArea, s32 aAct, s32 aWarpId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_to_level](#warp_to_level)
+
+### Description
+Warps to `aArea` of `aLevel` in `aAct`
+
+### Lua Example
+`local booleanValue = warp_to_level(aLevel, aArea, aAct)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| aLevel | `integer` |
+| aArea | `integer` |
+| aAct | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_to_level(s32 aLevel, s32 aArea, s32 aAct);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_restart_level](#warp_restart_level)
+
+### Description
+Restarts the current level
+
+### Lua Example
+`local booleanValue = warp_restart_level()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_restart_level(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_to_start_level](#warp_to_start_level)
+
+### Description
+Warps to the start level (Castle Grounds by default)
+
+### Lua Example
+`local booleanValue = warp_to_start_level()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_to_start_level(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_exit_level](#warp_exit_level)
+
+### Description
+Exits the current level after `aDelay`
+
+### Lua Example
+`local booleanValue = warp_exit_level(aDelay)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| aDelay | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_exit_level(s32 aDelay);`
+
+[:arrow_up_small:](#)
+
+
+
+## [warp_to_castle](#warp_to_castle)
+
+### Description
+Warps back to the castle from `aLevel`
+
+### Lua Example
+`local booleanValue = warp_to_castle(aLevel)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| aLevel | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool warp_to_castle(s32 aLevel);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from smlua_misc_utils.h
+
+
+
+
+## [get_network_area_timer](#get_network_area_timer)
+
+### Description
+Gets the current area's networked timer
+
+### Lua Example
+`local integerValue = get_network_area_timer()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u32 get_network_area_timer(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_area_update_counter](#get_area_update_counter)
+
+### Description
+Gets the area update counter incremented when objects are updated
+
+### Lua Example
+`local integerValue = get_area_update_counter()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u16 get_area_update_counter(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_temp_s32_pointer](#get_temp_s32_pointer)
+
+### Description
+Returns a temporary signed 32-bit integer pointer with its value set to `initialValue`
+
+### Lua Example
+`local PointerValue = get_temp_s32_pointer(initialValue)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| initialValue | `integer` |
+
+### Returns
+- `Pointer` <`integer`>
+
+### C Prototype
+`s32* get_temp_s32_pointer(s32 initialValue);`
+
+[:arrow_up_small:](#)
+
+
+
+## [deref_s32_pointer](#deref_s32_pointer)
+
+### Description
+Gets the signed 32-bit integer value from `pointer`
+
+### Lua Example
+`local integerValue = deref_s32_pointer(pointer)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| pointer | `Pointer` <`integer`> |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 deref_s32_pointer(s32* pointer);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_popup_create_global](#djui_popup_create_global)
+
+### Description
+Creates a DJUI popup that is broadcasted to every client
+
+### Lua Example
+`djui_popup_create_global(message, lines)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| message | `string` |
+| lines | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_popup_create_global(const char* message, int lines);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_is_popup_disabled](#djui_is_popup_disabled)
+
+### Description
+Returns if popups are disabled
+
+### Lua Example
+`local booleanValue = djui_is_popup_disabled()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool djui_is_popup_disabled(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_set_popup_disabled_override](#djui_set_popup_disabled_override)
+
+### Description
+Sets if popups are disabled
+
+### Lua Example
+`djui_set_popup_disabled_override(value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void djui_set_popup_disabled_override(bool value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_reset_popup_disabled_override](#djui_reset_popup_disabled_override)
+
+### Description
+Resets if popups are disabled
+
+### Lua Example
+`djui_reset_popup_disabled_override()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void djui_reset_popup_disabled_override(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_is_playerlist_open](#djui_is_playerlist_open)
+
+### Description
+Checks if the DJUI playerlist is open
+
+### Lua Example
+`local booleanValue = djui_is_playerlist_open()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool djui_is_playerlist_open(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_attempting_to_open_playerlist](#djui_attempting_to_open_playerlist)
+
+### Description
+Checks if the DJUI playerlist is attempting to be opened
+
+### Lua Example
+`local booleanValue = djui_attempting_to_open_playerlist()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool djui_attempting_to_open_playerlist(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_get_playerlist_page_index](#djui_get_playerlist_page_index)
+
+### Description
+Gets the DJUI playerlist's page index
+
+### Lua Example
+`local integerValue = djui_get_playerlist_page_index()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u8 djui_get_playerlist_page_index(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_menu_get_font](#djui_menu_get_font)
+
+### Description
+Gets the DJUI menu font
+
+### Lua Example
+`local enumValue = djui_menu_get_font()`
+
+### Parameters
+- None
+
+### Returns
+[enum DjuiFontType](constants.md#enum-DjuiFontType)
+
+### C Prototype
+`enum DjuiFontType djui_menu_get_font(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_menu_get_theme](#djui_menu_get_theme)
+
+### Description
+Gets the DJUI menu theme
+
+### Lua Example
+`local DjuiThemeValue = djui_menu_get_theme()`
+
+### Parameters
+- None
+
+### Returns
+[DjuiTheme](structs.md#DjuiTheme)
+
+### C Prototype
+`struct DjuiTheme* djui_menu_get_theme(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [djui_is_playerlist_ping_visible](#djui_is_playerlist_ping_visible)
+
+### Description
+Checks if the DJUI playerlist ping icon is visible
+
+### Lua Example
+`local booleanValue = djui_is_playerlist_ping_visible()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool djui_is_playerlist_ping_visible(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_dialog_box_state](#get_dialog_box_state)
+
+### Description
+Gets the current state of the dialog box
+
+### Lua Example
+`local integerValue = get_dialog_box_state()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s8 get_dialog_box_state(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_dialog_id](#get_dialog_id)
+
+### Description
+Gets the current dialog box ID
+
+### Lua Example
+`local integerValue = get_dialog_id()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 get_dialog_id(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_last_star_or_key](#get_last_star_or_key)
+
+### Description
+Gets if the last objective collected was a star (0) or a key (1)
+
+### Lua Example
+`local integerValue = get_last_star_or_key()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u8 get_last_star_or_key(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_last_star_or_key](#set_last_star_or_key)
+
+### Description
+Sets if the last objective collected was a star (0) or a key (1)
+
+### Lua Example
+`set_last_star_or_key(value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_last_star_or_key(u8 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_last_completed_course_num](#get_last_completed_course_num)
+
+### Description
+Gets the last course a star or key was collected in
+
+### Lua Example
+`local integerValue = get_last_completed_course_num()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u8 get_last_completed_course_num(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_last_completed_course_num](#set_last_completed_course_num)
+
+### Description
+Sets the last course a star or key was collected in
+
+### Lua Example
+`set_last_completed_course_num(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_last_completed_course_num(u8 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_last_completed_star_num](#get_last_completed_star_num)
+
+### Description
+Gets the last collected star's number (1-7)
+
+### Lua Example
+`local integerValue = get_last_completed_star_num()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u8 get_last_completed_star_num(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_last_completed_star_num](#set_last_completed_star_num)
+
+### Description
+Sets the last collected star's number (1-7)
+
+### Lua Example
+`set_last_completed_star_num(starNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| starNum | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_last_completed_star_num(u8 starNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_got_file_coin_hi_score](#get_got_file_coin_hi_score)
+
+### Description
+Checks if the save file's coin "HI SCORE" was obtained with the last star or key collection
+
+### Lua Example
+`local booleanValue = get_got_file_coin_hi_score()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool get_got_file_coin_hi_score(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_got_file_coin_hi_score](#set_got_file_coin_hi_score)
+
+### Description
+Sets if the save file's coin "HI SCORE" was obtained with the last star or key collection
+
+### Lua Example
+`set_got_file_coin_hi_score(value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_got_file_coin_hi_score(bool value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_save_file_modified](#get_save_file_modified)
+
+### Description
+Checks if the save file has been modified without saving
+
+### Lua Example
+`local booleanValue = get_save_file_modified()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool get_save_file_modified(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_save_file_modified](#set_save_file_modified)
+
+### Description
+Sets if the save file has been modified without saving
+
+### Lua Example
+`set_save_file_modified(value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_save_file_modified(bool value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_hide](#hud_hide)
+
+### Description
+Hides the HUD
+
+### Lua Example
+`hud_hide()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void hud_hide(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_show](#hud_show)
+
+### Description
+Shows the HUD
+
+### Lua Example
+`hud_show()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void hud_show(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_is_hidden](#hud_is_hidden)
+
+### Description
+Checks if the HUD is hidden
+
+### Lua Example
+`local booleanValue = hud_is_hidden()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool hud_is_hidden(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_get_value](#hud_get_value)
+
+### Description
+Gets a HUD display value
+
+### Lua Example
+`local integerValue = hud_get_value(type)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 hud_get_value(enum HudDisplayValue type);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_set_value](#hud_set_value)
+
+### Description
+Sets a HUD display value
+
+### Lua Example
+`hud_set_value(type, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| type | [enum HudDisplayValue](constants.md#enum-HudDisplayValue) |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void hud_set_value(enum HudDisplayValue type, s32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_render_power_meter](#hud_render_power_meter)
+
+### Description
+Renders a power meter on the HUD
+
+### Lua Example
+`hud_render_power_meter(health, x, y, width, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| health | `integer` |
+| x | `number` |
+| y | `number` |
+| width | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_render_power_meter_interpolated](#hud_render_power_meter_interpolated)
+
+### Description
+Renders an interpolated power meter on the HUD
+
+### Lua Example
+`hud_render_power_meter_interpolated(health, prevX, prevY, prevWidth, prevHeight, x, y, width, height)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| health | `integer` |
+| prevX | `number` |
+| prevY | `number` |
+| prevWidth | `number` |
+| prevHeight | `number` |
+| x | `number` |
+| y | `number` |
+| width | `number` |
+| height | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void hud_render_power_meter_interpolated(s32 health, f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_get_flash](#hud_get_flash)
+
+### Description
+Gets if the star counter on the HUD should flash
+
+### Lua Example
+`local integerValue = hud_get_flash()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s8 hud_get_flash(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [hud_set_flash](#hud_set_flash)
+
+### Description
+Sets if the star counter on the HUD should flash
+
+### Lua Example
+`hud_set_flash(value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void hud_set_flash(s8 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [act_select_hud_hide](#act_select_hud_hide)
+
+### Description
+Hides part of the Act Select HUD
+
+### Lua Example
+`act_select_hud_hide(part)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
+
+### Returns
+- None
+
+### C Prototype
+`void act_select_hud_hide(enum ActSelectHudPart part);`
+
+[:arrow_up_small:](#)
+
+
+
+## [act_select_hud_show](#act_select_hud_show)
+
+### Description
+Shows part of the Act Select HUD
+
+### Lua Example
+`act_select_hud_show(part)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
+
+### Returns
+- None
+
+### C Prototype
+`void act_select_hud_show(enum ActSelectHudPart part);`
+
+[:arrow_up_small:](#)
+
+
+
+## [act_select_hud_is_hidden](#act_select_hud_is_hidden)
+
+### Description
+Checks if part of the Act Select HUD is hidden
+
+### Lua Example
+`local booleanValue = act_select_hud_is_hidden(part)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| part | [enum ActSelectHudPart](constants.md#enum-ActSelectHudPart) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool act_select_hud_is_hidden(enum ActSelectHudPart part);`
+
+[:arrow_up_small:](#)
+
+
+
+## [is_game_paused](#is_game_paused)
+
+### Description
+Checks if the game is paused
+
+### Lua Example
+`local booleanValue = is_game_paused()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool is_game_paused(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [is_transition_playing](#is_transition_playing)
+
+### Description
+Checks if a screen transition is playing
+
+### Lua Example
+`local booleanValue = is_transition_playing()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool is_transition_playing(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [allocate_mario_action](#allocate_mario_action)
+
+### Description
+Allocates an action ID with bitwise flags
+
+### Lua Example
+`local integerValue = allocate_mario_action(actFlags)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| actFlags | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`u32 allocate_mario_action(u32 actFlags);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_hand_foot_pos_x](#get_hand_foot_pos_x)
+
+### Description
+Gets the X coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
+
+### Lua Example
+`local numberValue = get_hand_foot_pos_x(m, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| index | `integer` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_hand_foot_pos_x(struct MarioState* m, u8 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_hand_foot_pos_y](#get_hand_foot_pos_y)
+
+### Description
+Gets the Y coordinate of Mario's hand (0-1) or foot (2-3) but It is important to note that the positions are not updated off-screen
+
+### Lua Example
+`local numberValue = get_hand_foot_pos_y(m, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| index | `integer` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_hand_foot_pos_y(struct MarioState* m, u8 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_hand_foot_pos_z](#get_hand_foot_pos_z)
+
+### Description
+Gets the Z coordinate of Mario's hand (0-1) or foot (2-3) but it is important to note that the positions are not updated off-screen
+
+### Lua Example
+`local numberValue = get_hand_foot_pos_z(m, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| index | `integer` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_hand_foot_pos_z(struct MarioState* m, u8 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_mario_anim_part_pos](#get_mario_anim_part_pos)
+
+### Description
+Retrieves the animated part position associated to `animPart` from the MarioState `m` and stores it into `pos`. Returns `true` on success or `false` on failure
+
+### Lua Example
+`local booleanValue = get_mario_anim_part_pos(m, animPart, pos)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+| animPart | `integer` |
+| pos | [Vec3f](structs.md#Vec3f) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool get_mario_anim_part_pos(struct MarioState *m, u32 animPart, OUT Vec3f pos);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_current_save_file_num](#get_current_save_file_num)
+
+### Description
+Gets the current save file number (1-indexed)
+
+### Lua Example
+`local integerValue = get_current_save_file_num()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 get_current_save_file_num(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [save_file_get_using_backup_slot](#save_file_get_using_backup_slot)
+
+### Description
+Checks if the save file is using its backup slot
+
+### Lua Example
+`local booleanValue = save_file_get_using_backup_slot()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool save_file_get_using_backup_slot(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [save_file_set_using_backup_slot](#save_file_set_using_backup_slot)
+
+### Description
+Sets if the save file should use its backup slot
+
+### Lua Example
+`save_file_set_using_backup_slot(usingBackupSlot)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| usingBackupSlot | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void save_file_set_using_backup_slot(bool usingBackupSlot);`
+
+[:arrow_up_small:](#)
+
+
+
+## [movtexqc_register](#movtexqc_register)
+
+### Description
+Registers a custom moving texture entry (used for vanilla water boxes)
+
+### Lua Example
+`movtexqc_register(name, level, area, type)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| name | `string` |
+| level | `integer` |
+| area | `integer` |
+| type | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void movtexqc_register(const char* name, s16 level, s16 area, s16 type);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_water_level](#get_water_level)
+
+### Description
+Gets the water level in an area corresponding to `index` (0-indexed)
+
+### Lua Example
+`local integerValue = get_water_level(index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 get_water_level(u8 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_water_level](#set_water_level)
+
+### Description
+Sets the water level in an area corresponding to `index` (0-indexed)
+
+### Lua Example
+`set_water_level(index, height, sync)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+| height | `integer` |
+| sync | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_water_level(u8 index, s16 height, bool sync);`
+
+[:arrow_up_small:](#)
+
+
+
+## [course_is_main_course](#course_is_main_course)
+
+### Description
+Checks if a course is a main course and not the castle or secret levels
+
+### Lua Example
+`local booleanValue = course_is_main_course(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool course_is_main_course(u16 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_ttc_speed_setting](#get_ttc_speed_setting)
+
+### Description
+Gets TTC's speed setting
+
+### Lua Example
+`local integerValue = get_ttc_speed_setting()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 get_ttc_speed_setting(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_ttc_speed_setting](#set_ttc_speed_setting)
+
+### Description
+Sets TTC's speed setting (TTC_SPEED_*)
+
+### Lua Example
+`set_ttc_speed_setting(speed)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| speed | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_ttc_speed_setting(s16 speed);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_time](#get_time)
+
+### Description
+Gets the Unix Timestamp
+
+### Lua Example
+`local integerValue = get_time()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s64 get_time(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_date_and_time](#get_date_and_time)
+
+### Description
+Gets the system clock's date and time
+
+### Lua Example
+`local DateTimeValue = get_date_and_time()`
+
+### Parameters
+- None
+
+### Returns
+[DateTime](structs.md#DateTime)
+
+### C Prototype
+`struct DateTime* get_date_and_time(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_envfx](#get_envfx)
+
+### Description
+Gets the non overridden environment effect (e.g. snow)
+
+### Lua Example
+`local integerValue = get_envfx()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u16 get_envfx(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_override_envfx](#set_override_envfx)
+
+### Description
+Sets the override environment effect (e.g. snow)
+
+### Lua Example
+`set_override_envfx(envfx)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| envfx | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_override_envfx(s32 envfx);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_global_timer](#get_global_timer)
+
+### Description
+Gets the global timer that has been ticking at 30 frames per second since game boot
+
+### Lua Example
+`local integerValue = get_global_timer()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`u32 get_global_timer(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_dialog_response](#get_dialog_response)
+
+### Description
+Gets the choice selected inside of a dialog box (0-1)
+
+### Lua Example
+`local integerValue = get_dialog_response()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 get_dialog_response(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_local_discord_id](#get_local_discord_id)
+
+### Description
+Gets the local discord ID if it isn't disabled, otherwise "0" is returned
+
+### Lua Example
+`local stringValue = get_local_discord_id()`
+
+### Parameters
+- None
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* get_local_discord_id(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_coopnet_id](#get_coopnet_id)
+
+### Description
+Gets the CoopNet ID of a player with `localIndex` if CoopNet is being used and the player is connected, otherwise "-1" is returned
+
+### Lua Example
+`local stringValue = get_coopnet_id(localIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| localIndex | `integer` |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* get_coopnet_id(s8 localIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_master](#get_volume_master)
+
+### Description
+Gets the master volume level
+
+### Lua Example
+`local numberValue = get_volume_master()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_master(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_level](#get_volume_level)
+
+### Description
+Gets the volume level of music
+
+### Lua Example
+`local numberValue = get_volume_level()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_level(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_sfx](#get_volume_sfx)
+
+### Description
+Gets the volume level of sound effects
+
+### Lua Example
+`local numberValue = get_volume_sfx()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_sfx(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_env](#get_volume_env)
+
+### Description
+Gets the volume level of environment sounds effects
+
+### Lua Example
+`local numberValue = get_volume_env()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_env(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_master](#set_volume_master)
+
+### Description
+Sets the master volume level
+
+### Lua Example
+`set_volume_master(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_master(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_level](#set_volume_level)
+
+### Description
+Sets the volume level of music
+
+### Lua Example
+`set_volume_level(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_level(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_sfx](#set_volume_sfx)
+
+### Description
+Sets the volume level of sound effects
+
+### Lua Example
+`set_volume_sfx(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_sfx(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_env](#set_volume_env)
+
+### Description
+Sets the volume level of environment sounds effects
+
+### Lua Example
+`set_volume_env(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_env(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_environment_region](#get_environment_region)
+
+### Description
+Gets an environment region (gas/water boxes) height value
+
+### Lua Example
+`local integerValue = get_environment_region(index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 get_environment_region(u8 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_environment_region](#set_environment_region)
+
+### Description
+Sets an environment region (gas/water boxes) height value
+
+### Lua Example
+`set_environment_region(index, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_environment_region(u8 index, s16 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [mod_file_exists](#mod_file_exists)
+
+### Description
+Checks if a file exists inside of a mod
+
+### Lua Example
+`local booleanValue = mod_file_exists(filename)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| filename | `string` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool mod_file_exists(const char* filename);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_active_mod](#get_active_mod)
+
+### Description
+Gets the mod currently being processed
+
+### Lua Example
+`local ModValue = get_active_mod()`
+
+### Parameters
+- None
+
+### Returns
+[Mod](structs.md#Mod)
+
+### C Prototype
+`struct Mod* get_active_mod(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_window_title](#set_window_title)
+
+### Description
+Sets the window title to a custom title
+
+### Lua Example
+`set_window_title(title)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| title | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_window_title(const char* title);`
+
+[:arrow_up_small:](#)
+
+
+
+## [reset_window_title](#reset_window_title)
+
+### Description
+Resets the window title
+
+### Lua Example
+`reset_window_title()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void reset_window_title(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_os_name](#get_os_name)
+
+### Description
+Gets the name of the operating system the game is running on
+
+### Lua Example
+`local stringValue = get_os_name()`
+
+### Parameters
+- None
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* get_os_name(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_root](#geo_get_current_root)
+
+### Description
+Gets the current GraphNodeRoot
+
+### Lua Example
+`local GraphNodeRootValue = geo_get_current_root()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeRoot](structs.md#GraphNodeRoot)
+
+### C Prototype
+`struct GraphNodeRoot* geo_get_current_root(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_master_list](#geo_get_current_master_list)
+
+### Description
+Gets the current GraphNodeMasterList
+
+### Lua Example
+`local GraphNodeMasterListValue = geo_get_current_master_list()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeMasterList](structs.md#GraphNodeMasterList)
+
+### C Prototype
+`struct GraphNodeMasterList* geo_get_current_master_list(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_perspective](#geo_get_current_perspective)
+
+### Description
+Gets the current GraphNodePerspective
+
+### Lua Example
+`local GraphNodePerspectiveValue = geo_get_current_perspective()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodePerspective](structs.md#GraphNodePerspective)
+
+### C Prototype
+`struct GraphNodePerspective* geo_get_current_perspective(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_camera](#geo_get_current_camera)
+
+### Description
+Gets the current GraphNodeCamera
+
+### Lua Example
+`local GraphNodeCameraValue = geo_get_current_camera()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeCamera](structs.md#GraphNodeCamera)
+
+### C Prototype
+`struct GraphNodeCamera* geo_get_current_camera(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_held_object](#geo_get_current_held_object)
+
+### Description
+Gets the current GraphNodeHeldObject
+
+### Lua Example
+`local GraphNodeHeldObjectValue = geo_get_current_held_object()`
+
+### Parameters
+- None
+
+### Returns
+[GraphNodeHeldObject](structs.md#GraphNodeHeldObject)
+
+### C Prototype
+`struct GraphNodeHeldObject* geo_get_current_held_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [texture_to_lua_table](#texture_to_lua_table)
+
+### Description
+Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures
+
+### Lua Example
+`texture_to_lua_table(tex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| tex | `Pointer` <`Texture`> |
+
+### Returns
+- None
+
+### C Prototype
+`void texture_to_lua_table(const Texture *tex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_texture_name](#get_texture_name)
+
+### Description
+Gets the name of the provided texture pointer `tex`
+
+### Lua Example
+`local stringValue = get_texture_name(tex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| tex | `Pointer` <`Texture`> |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char *get_texture_name(const Texture *tex);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from smlua_model_utils.h
+
+
+
+
+## [smlua_model_util_get_id](#smlua_model_util_get_id)
+
+### Description
+Gets the extended model ID for the `name` of a `GeoLayout`
+
+### Lua Example
+`local enumValue = smlua_model_util_get_id(name)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| name | `string` |
+
+### Returns
+[enum ModelExtendedId](constants.md#enum-ModelExtendedId)
+
+### C Prototype
+`enum ModelExtendedId smlua_model_util_get_id(const char* name);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from smlua_obj_utils.h
+
+
+
+
+## [spawn_sync_object](#spawn_sync_object)
+
+### Description
+Spawns a synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
+
+### Lua Example
+`local ObjectValue = spawn_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+| objSetupFunction | `Lua Function` () |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object* spawn_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);`
+
+[:arrow_up_small:](#)
+
+
+
+## [spawn_non_sync_object](#spawn_non_sync_object)
+
+### Description
+Spawns a non-synchronized object at `x`, `y`, and `z` as a child object of the local Mario with his rotation. You can change the fields of the object in `objSetupFunction`
+
+### Lua Example
+`local ObjectValue = spawn_non_sync_object(behaviorId, modelId, x, y, z, objSetupFunction)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+| objSetupFunction | `Lua Function` () |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object* spawn_non_sync_object(enum BehaviorId behaviorId, enum ModelExtendedId modelId, f32 x, f32 y, f32 z, LuaFunction objSetupFunction);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_has_behavior_id](#obj_has_behavior_id)
+
+### Description
+Checks if an object has `behaviorId`
+
+### Lua Example
+`local integerValue = obj_has_behavior_id(o, behaviorId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_has_behavior_id(struct Object *o, enum BehaviorId behaviorId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_has_model_extended](#obj_has_model_extended)
+
+### Description
+Checks if an object's model is equal to `modelId`
+
+### Lua Example
+`local integerValue = obj_has_model_extended(o, modelId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_has_model_extended(struct Object *o, enum ModelExtendedId modelId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_model_id_extended](#obj_get_model_id_extended)
+
+### Description
+Returns an object's extended model id
+
+### Lua Example
+`local enumValue = obj_get_model_id_extended(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+[enum ModelExtendedId](constants.md#enum-ModelExtendedId)
+
+### C Prototype
+`enum ModelExtendedId obj_get_model_id_extended(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_model_extended](#obj_set_model_extended)
+
+### Description
+Sets an object's model to `modelId`
+
+### Lua Example
+`obj_set_model_extended(o, modelId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_model_extended(struct Object *o, enum ModelExtendedId modelId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_trajectory](#get_trajectory)
+
+### Description
+Gets a trajectory by `name`
+
+### Lua Example
+`local PointerValue = get_trajectory(name)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| name | `string` |
+
+### Returns
+- `Pointer` <`Trajectory`>
+
+### C Prototype
+`Trajectory* get_trajectory(const char* name);`
+
+[:arrow_up_small:](#)
+
+
+
+## [geo_get_current_object](#geo_get_current_object)
+
+### Description
+When used in a geo function, retrieve the current processed object
+
+### Lua Example
+`local ObjectValue = geo_get_current_object()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *geo_get_current_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_current_object](#get_current_object)
+
+### Description
+Gets the object currently being processed
+
+### Lua Example
+`local ObjectValue = get_current_object()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *get_current_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_dialog_object](#get_dialog_object)
+
+### Description
+Gets the NPC object Mario is talking to
+
+### Lua Example
+`local ObjectValue = get_dialog_object()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *get_dialog_object(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_cutscene_focus](#get_cutscene_focus)
+
+### Description
+Gets the cutscene focus object
+
+### Lua Example
+`local ObjectValue = get_cutscene_focus()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *get_cutscene_focus(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_secondary_camera_focus](#get_secondary_camera_focus)
+
+### Description
+Gets the secondary camera focus object
+
+### Lua Example
+`local ObjectValue = get_secondary_camera_focus()`
+
+### Parameters
+- None
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *get_secondary_camera_focus(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_cutscene_focus](#set_cutscene_focus)
+
+### Description
+Sets the cutscene focus object
+
+### Lua Example
+`set_cutscene_focus(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void set_cutscene_focus(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_secondary_camera_focus](#set_secondary_camera_focus)
+
+### Description
+Sets the secondary camera focus object
+
+### Lua Example
+`set_secondary_camera_focus(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- None
+
+### C Prototype
+`void set_secondary_camera_focus(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_first](#obj_get_first)
+
+### Description
+Gets the first object in an object list
+
+### Lua Example
+`local ObjectValue = obj_get_first(objList)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| objList | [enum ObjectList](constants.md#enum-ObjectList) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_first(enum ObjectList objList);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_first_with_behavior_id](#obj_get_first_with_behavior_id)
+
+### Description
+Gets the first object loaded with `behaviorId`
+
+### Lua Example
+`local ObjectValue = obj_get_first_with_behavior_id(behaviorId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_first_with_behavior_id(enum BehaviorId behaviorId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_first_with_behavior_id_and_field_s32](#obj_get_first_with_behavior_id_and_field_s32)
+
+### Description
+Gets the first object loaded with `behaviorId` and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
+
+### Lua Example
+`local ObjectValue = obj_get_first_with_behavior_id_and_field_s32(behaviorId, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+| fieldIndex | `integer` |
+| value | `integer` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_first_with_behavior_id_and_field_s32(enum BehaviorId behaviorId, s32 fieldIndex, s32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_first_with_behavior_id_and_field_f32](#obj_get_first_with_behavior_id_and_field_f32)
+
+### Description
+Gets the first object loaded with `behaviorId` and object float field (look in `object_fields.h` to get the index of a field)
+
+### Lua Example
+`local ObjectValue = obj_get_first_with_behavior_id_and_field_f32(behaviorId, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+| fieldIndex | `integer` |
+| value | `number` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_first_with_behavior_id_and_field_f32(enum BehaviorId behaviorId, s32 fieldIndex, f32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_next](#obj_get_next)
+
+### Description
+Gets the next object in an object list
+
+### Lua Example
+`local ObjectValue = obj_get_next(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_next(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_next_with_same_behavior_id](#obj_get_next_with_same_behavior_id)
+
+### Description
+Gets the next object loaded with the same behavior ID
+
+### Lua Example
+`local ObjectValue = obj_get_next_with_same_behavior_id(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_next_with_same_behavior_id(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_next_with_same_behavior_id_and_field_s32](#obj_get_next_with_same_behavior_id_and_field_s32)
+
+### Description
+Gets the next object loaded with the same behavior ID and object signed 32-bit integer field (look in `object_fields.h` to get the index of a field)
+
+### Lua Example
+`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_s32(o, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| value | `integer` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_next_with_same_behavior_id_and_field_s32(struct Object *o, s32 fieldIndex, s32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_next_with_same_behavior_id_and_field_f32](#obj_get_next_with_same_behavior_id_and_field_f32)
+
+### Description
+Gets the next object loaded with the same behavior ID and object float field (look in `object_fields.h` to get the index of a field)
+
+### Lua Example
+`local ObjectValue = obj_get_next_with_same_behavior_id_and_field_f32(o, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| value | `number` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_next_with_same_behavior_id_and_field_f32(struct Object *o, s32 fieldIndex, f32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_nearest_object_with_behavior_id](#obj_get_nearest_object_with_behavior_id)
+
+### Description
+Gets the nearest object with `behaviorId` to `o`
+
+### Lua Example
+`local ObjectValue = obj_get_nearest_object_with_behavior_id(o, behaviorId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_nearest_object_with_behavior_id(struct Object *o, enum BehaviorId behaviorId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_count_objects_with_behavior_id](#obj_count_objects_with_behavior_id)
+
+### Description
+Counts every object with `behaviorId`
+
+### Lua Example
+`local integerValue = obj_count_objects_with_behavior_id(behaviorId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| behaviorId | [enum BehaviorId](constants.md#enum-BehaviorId) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_count_objects_with_behavior_id(enum BehaviorId behaviorId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_collided_object](#obj_get_collided_object)
+
+### Description
+Gets the corresponding collided object to an index from `o`
+
+### Lua Example
+`local ObjectValue = obj_get_collided_object(o, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| index | `integer` |
+
+### Returns
+[Object](structs.md#Object)
+
+### C Prototype
+`struct Object *obj_get_collided_object(struct Object *o, s16 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_field_u32](#obj_get_field_u32)
+
+### Description
+Gets the unsigned 32-bit integer value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`local integerValue = obj_get_field_u32(o, fieldIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`u32 obj_get_field_u32(struct Object *o, s32 fieldIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_field_s32](#obj_get_field_s32)
+
+### Description
+Gets the signed 32-bit integer value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`local integerValue = obj_get_field_s32(o, fieldIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 obj_get_field_s32(struct Object *o, s32 fieldIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_field_f32](#obj_get_field_f32)
+
+### Description
+Sets the float value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`local numberValue = obj_get_field_f32(o, fieldIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 obj_get_field_f32(struct Object *o, s32 fieldIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_field_s16](#obj_get_field_s16)
+
+### Description
+Gets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex`
+
+### Lua Example
+`local integerValue = obj_get_field_s16(o, fieldIndex, fieldSubIndex)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| fieldSubIndex | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s16 obj_get_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_field_u32](#obj_set_field_u32)
+
+### Description
+Sets the unsigned 32-bit integer value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`obj_set_field_u32(o, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_field_u32(struct Object *o, s32 fieldIndex, u32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_field_s32](#obj_set_field_s32)
+
+### Description
+Sets the signed 32-bit integer value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`obj_set_field_s32(o, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_field_s32(struct Object *o, s32 fieldIndex, s32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_field_f32](#obj_set_field_f32)
+
+### Description
+Sets the float value from the field corresponding to `fieldIndex`
+
+### Lua Example
+`obj_set_field_f32(o, fieldIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| value | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_field_f32(struct Object *o, s32 fieldIndex, f32 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_field_s16](#obj_set_field_s16)
+
+### Description
+Sets the signed 32-bit integer value from the sub field corresponding to `fieldSubIndex` from the field corresponding to `fieldIndex`
+
+### Lua Example
+`obj_set_field_s16(o, fieldIndex, fieldSubIndex, value)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| fieldIndex | `integer` |
+| fieldSubIndex | `integer` |
+| value | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_field_s16(struct Object *o, s32 fieldIndex, s32 fieldSubIndex, s16 value);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_temp_spawn_particles_info](#obj_get_temp_spawn_particles_info)
+
+### Description
+Returns a temporary particle spawn info pointer with its model loaded in from `modelId`
+
+### Lua Example
+`local SpawnParticlesInfoValue = obj_get_temp_spawn_particles_info(modelId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| modelId | [enum ModelExtendedId](constants.md#enum-ModelExtendedId) |
+
+### Returns
+[SpawnParticlesInfo](structs.md#SpawnParticlesInfo)
+
+### C Prototype
+`struct SpawnParticlesInfo* obj_get_temp_spawn_particles_info(enum ModelExtendedId modelId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_temp_object_hitbox](#get_temp_object_hitbox)
+
+### Description
+Returns a temporary object hitbox pointer
+
+### Lua Example
+`local ObjectHitboxValue = get_temp_object_hitbox()`
+
+### Parameters
+- None
+
+### Returns
+[ObjectHitbox](structs.md#ObjectHitbox)
+
+### C Prototype
+`struct ObjectHitbox* get_temp_object_hitbox(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_attackable](#obj_is_attackable)
+
+### Description
+Checks if `o` is attackable
+
+### Lua Example
+`local booleanValue = obj_is_attackable(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_attackable(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_breakable_object](#obj_is_breakable_object)
+
+### Description
+Checks if `o` is breakable
+
+### Lua Example
+`local booleanValue = obj_is_breakable_object(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_breakable_object(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_bully](#obj_is_bully)
+
+### Description
+Checks if `o` is a Bully
+
+### Lua Example
+`local booleanValue = obj_is_bully(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_bully(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_coin](#obj_is_coin)
+
+### Description
+Checks if `o` is a coin
+
+### Lua Example
+`local booleanValue = obj_is_coin(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_coin(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_exclamation_box](#obj_is_exclamation_box)
+
+### Description
+Checks if `o` is an exclamation box
+
+### Lua Example
+`local booleanValue = obj_is_exclamation_box(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_exclamation_box(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_grabbable](#obj_is_grabbable)
+
+### Description
+Checks if `o` is grabbable
+
+### Lua Example
+`local booleanValue = obj_is_grabbable(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_grabbable(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_mushroom_1up](#obj_is_mushroom_1up)
+
+### Description
+Checks if `o` is a 1-Up Mushroom
+
+### Lua Example
+`local booleanValue = obj_is_mushroom_1up(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_mushroom_1up(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_secret](#obj_is_secret)
+
+### Description
+Checks if `o` is a secret
+
+### Lua Example
+`local booleanValue = obj_is_secret(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_secret(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_is_valid_for_interaction](#obj_is_valid_for_interaction)
+
+### Description
+Checks if `o` is activated, tangible, and interactible
+
+### Lua Example
+`local booleanValue = obj_is_valid_for_interaction(o)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_is_valid_for_interaction(struct Object *o);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_check_hitbox_overlap](#obj_check_hitbox_overlap)
+
+### Description
+Checks if `o1`'s hitbox is colliding with `o2`'s hitbox
+
+### Lua Example
+`local booleanValue = obj_check_hitbox_overlap(o1, o2)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o1 | [Object](structs.md#Object) |
+| o2 | [Object](structs.md#Object) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_check_hitbox_overlap(struct Object *o1, struct Object *o2);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_check_overlap_with_hitbox_params](#obj_check_overlap_with_hitbox_params)
+
+### Description
+Checks if `o`'s hitbox is colliding with the parameters of a hitbox
+
+### Lua Example
+`local booleanValue = obj_check_overlap_with_hitbox_params(o, x, y, z, h, r, d)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+| h | `number` |
+| r | `number` |
+| d | `number` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool obj_check_overlap_with_hitbox_params(struct Object *o, f32 x, f32 y, f32 z, f32 h, f32 r, f32 d);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_set_vel](#obj_set_vel)
+
+### Description
+Sets an object's velocity to `vx`, `vy`, and `vz`
+
+### Lua Example
+`obj_set_vel(o, vx, vy, vz)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| vx | `number` |
+| vy | `number` |
+| vz | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_set_vel(struct Object *o, f32 vx, f32 vy, f32 vz);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_move_xyz](#obj_move_xyz)
+
+### Description
+Moves the object in the direction of `dx`, `dy`, and `dz`
+
+### Lua Example
+`obj_move_xyz(o, dx, dy, dz)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| dx | `number` |
+| dy | `number` |
+| dz | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void obj_move_xyz(struct Object *o, f32 dx, f32 dy, f32 dz);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_whirlpools](#set_whirlpools)
+
+### Description
+Sets the parameters of one of the two whirlpools (0-indexed) in an area
+
+### Lua Example
+`set_whirlpools(x, y, z, strength, area, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+| strength | `integer` |
+| area | `integer` |
+| index | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_whirlpools(f32 x, f32 y, f32 z, s16 strength, s16 area, s32 index);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from smlua_text_utils.h
+
+
+
+
+## [smlua_text_utils_reset_all](#smlua_text_utils_reset_all)
+
+### Description
+Resets every modified dialog back to vanilla
+
+### Lua Example
+`smlua_text_utils_reset_all()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_reset_all(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_dialog_get](#smlua_text_utils_dialog_get)
+
+### Description
+Gets the DialogEntry struct for the given `dialogId`
+
+### Lua Example
+`local DialogEntryValue = smlua_text_utils_dialog_get(dialogId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dialogId | [enum DialogId](constants.md#enum-DialogId) |
+
+### Returns
+[DialogEntry](structs.md#DialogEntry)
+
+### C Prototype
+`struct DialogEntry* smlua_text_utils_dialog_get(enum DialogId dialogId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_dialog_replace](#smlua_text_utils_dialog_replace)
+
+### Description
+Replaces `dialogId` with a custom one
+
+### Lua Example
+`smlua_text_utils_dialog_replace(dialogId, unused, linesPerBox, leftOffset, width, str)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dialogId | [enum DialogId](constants.md#enum-DialogId) |
+| unused | `integer` |
+| linesPerBox | `integer` |
+| leftOffset | `integer` |
+| width | `integer` |
+| str | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_dialog_replace(enum DialogId dialogId, u32 unused, s8 linesPerBox, s16 leftOffset, s16 width, const char* str);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_dialog_restore](#smlua_text_utils_dialog_restore)
+
+### Description
+Restores a replaced DialogEntry to its original state.
+
+### Lua Example
+`smlua_text_utils_dialog_restore(dialogId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dialogId | [enum DialogId](constants.md#enum-DialogId) |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_dialog_restore(enum DialogId dialogId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_dialog_is_replaced](#smlua_text_utils_dialog_is_replaced)
+
+### Description
+Returns whether the dialog with the given ID has been replaced
+
+### Lua Example
+`local booleanValue = smlua_text_utils_dialog_is_replaced(dialogId)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dialogId | [enum DialogId](constants.md#enum-DialogId) |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_allocate_dialog](#smlua_text_utils_allocate_dialog)
+
+### Description
+Allocates a new dialog entry
+
+### Lua Example
+`local integerValue = smlua_text_utils_allocate_dialog()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_allocate_dialog(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_course_acts_replace](#smlua_text_utils_course_acts_replace)
+
+### Description
+Replaces the act names of `courseNum`
+
+### Lua Example
+`smlua_text_utils_course_acts_replace(courseNum, courseName, act1, act2, act3, act4, act5, act6)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| courseName | `string` |
+| act1 | `string` |
+| act2 | `string` |
+| act3 | `string` |
+| act4 | `string` |
+| act5 | `string` |
+| act6 | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_course_acts_replace(s16 courseNum, const char* courseName, const char* act1, const char* act2, const char* act3, const char* act4, const char* act5, const char* act6);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_secret_star_replace](#smlua_text_utils_secret_star_replace)
+
+### Description
+Replaces the secret star course name of `courseNum` with `courseName`
+
+### Lua Example
+`smlua_text_utils_secret_star_replace(courseNum, courseName)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| courseName | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_secret_star_replace(s16 courseNum, const char* courseName);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_course_name_replace](#smlua_text_utils_course_name_replace)
+
+### Description
+Replaces the name of `courseNum` with `name`
+
+### Lua Example
+`smlua_text_utils_course_name_replace(courseNum, name)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| name | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_course_name_replace(s16 courseNum, const char* name);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_course_name_get](#smlua_text_utils_course_name_get)
+
+### Description
+Gets the name of `courseNum`
+
+### Lua Example
+`local stringValue = smlua_text_utils_course_name_get(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* smlua_text_utils_course_name_get(s16 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_course_name_mod_index](#smlua_text_utils_course_name_mod_index)
+
+### Description
+Gets the index of the mod that replaced the name of `courseNum`
+
+### Lua Example
+`local integerValue = smlua_text_utils_course_name_mod_index(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_course_name_mod_index(s16 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_course_name_reset](#smlua_text_utils_course_name_reset)
+
+### Description
+Resets the name of `courseNum`
+
+### Lua Example
+`smlua_text_utils_course_name_reset(courseNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_course_name_reset(s16 courseNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_act_name_replace](#smlua_text_utils_act_name_replace)
+
+### Description
+Replaces the act name of `actNum` in `courseNum` with `name`
+
+### Lua Example
+`smlua_text_utils_act_name_replace(courseNum, actNum, name)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| actNum | `integer` |
+| name | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_act_name_replace(s16 courseNum, u8 actNum, const char* name);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_act_name_get](#smlua_text_utils_act_name_get)
+
+### Description
+Gets the act name of `actNum` in `courseNum`
+
+### Lua Example
+`local stringValue = smlua_text_utils_act_name_get(courseNum, actNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| actNum | `integer` |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* smlua_text_utils_act_name_get(s16 courseNum, u8 actNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_act_name_mod_index](#smlua_text_utils_act_name_mod_index)
+
+### Description
+Gets the index of the mod that replaced the act name of `actNum` in `courseNum`
+
+### Lua Example
+`local integerValue = smlua_text_utils_act_name_mod_index(courseNum, actNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| actNum | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_act_name_mod_index(s16 courseNum, u8 actNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_act_name_reset](#smlua_text_utils_act_name_reset)
+
+### Description
+Resets the act name of `actNum` in `courseNum`
+
+### Lua Example
+`smlua_text_utils_act_name_reset(courseNum, actNum)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| courseNum | `integer` |
+| actNum | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_act_name_reset(s16 courseNum, u8 actNum);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_castle_secret_stars_replace](#smlua_text_utils_castle_secret_stars_replace)
+
+### Description
+Replaces the castle secret stars text with `name`
+
+### Lua Example
+`smlua_text_utils_castle_secret_stars_replace(name)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| name | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_castle_secret_stars_replace(const char* name);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_castle_secret_stars_get](#smlua_text_utils_castle_secret_stars_get)
+
+### Description
+Gets the castle secret stars text
+
+### Lua Example
+`local stringValue = smlua_text_utils_castle_secret_stars_get()`
+
+### Parameters
+- None
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* smlua_text_utils_castle_secret_stars_get();`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_castle_secret_stars_mod_index](#smlua_text_utils_castle_secret_stars_mod_index)
+
+### Description
+Gets the index of the mod that replaced the castle secret stars text
+
+### Lua Example
+`local integerValue = smlua_text_utils_castle_secret_stars_mod_index()`
+
+### Parameters
+- None
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_castle_secret_stars_mod_index();`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_castle_secret_stars_reset](#smlua_text_utils_castle_secret_stars_reset)
+
+### Description
+Resets the castle secret stars text
+
+### Lua Example
+`smlua_text_utils_castle_secret_stars_reset()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_castle_secret_stars_reset();`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_extra_text_replace](#smlua_text_utils_extra_text_replace)
+
+### Description
+Replace extra text (e.g. one of the castle's secret stars) with `text`
+
+### Lua Example
+`smlua_text_utils_extra_text_replace(index, text)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+| text | `string` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_extra_text_replace(s16 index, const char* text);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_extra_text_get](#smlua_text_utils_extra_text_get)
+
+### Description
+Gets the extra text at `index`
+
+### Lua Example
+`local stringValue = smlua_text_utils_extra_text_get(index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* smlua_text_utils_extra_text_get(s16 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_extra_text_mod_index](#smlua_text_utils_extra_text_mod_index)
+
+### Description
+Gets the index of the mod that replaced the extra text at `index`
+
+### Lua Example
+`local integerValue = smlua_text_utils_extra_text_mod_index(index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 smlua_text_utils_extra_text_mod_index(s16 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_extra_text_reset](#smlua_text_utils_extra_text_reset)
+
+### Description
+Resets the extra text at `index`
+
+### Lua Example
+`smlua_text_utils_extra_text_reset(index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| index | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void smlua_text_utils_extra_text_reset(s16 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [smlua_text_utils_get_language](#smlua_text_utils_get_language)
+
+### Description
+Gets the current language
+
+### Lua Example
+`local stringValue = smlua_text_utils_get_language()`
+
+### Parameters
+- None
+
+### Returns
+- `string`
+
+### C Prototype
+`const char* smlua_text_utils_get_language(void);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from sound_init.h
+
+
+
+
+## [reset_volume](#reset_volume)
+
+### Description
+Resets if music volume has been lowered
+
+### Lua Example
+`reset_volume()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void reset_volume(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [raise_background_noise](#raise_background_noise)
+
+### Description
+Raises music volume back up to normal levels
+
+### Lua Example
+`raise_background_noise(a)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void raise_background_noise(s32 a);`
+
+[:arrow_up_small:](#)
+
+
+
+## [lower_background_noise](#lower_background_noise)
+
+### Description
+Lowers the volume of music by 40%
+
+### Lua Example
+`lower_background_noise(a)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void lower_background_noise(s32 a);`
+
+[:arrow_up_small:](#)
+
+
+
+## [disable_background_sound](#disable_background_sound)
+
+### Description
+Disables background soundbanks
+
+### Lua Example
+`disable_background_sound()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void disable_background_sound(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [enable_background_sound](#enable_background_sound)
+
+### Description
+Enables background soundbanks
+
+### Lua Example
+`enable_background_sound()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void enable_background_sound(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_menu_sounds](#play_menu_sounds)
+
+### Description
+Play menu sounds from `SOUND_MENU_FLAG_*` constants and queues rumble if `SOUND_MENU_FLAG_LETGOMARIOFACE` is one of the flags
+
+### Lua Example
+`play_menu_sounds(soundMenuFlags)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| soundMenuFlags | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void play_menu_sounds(s16 soundMenuFlags);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_painting_eject_sound](#play_painting_eject_sound)
+
+### Description
+Plays the painting eject sound effect if it has not already been played
+
+### Lua Example
+`play_painting_eject_sound()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void play_painting_eject_sound(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_infinite_stairs_music](#play_infinite_stairs_music)
+
+### Description
+Plays the infinite stairs music if you're in the endless stairs room and have less than `gLevelValues.infiniteStairsRequirement` stars
+
+### Lua Example
+`play_infinite_stairs_music()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void play_infinite_stairs_music(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_background_music](#set_background_music)
+
+### Description
+Sets the background music to `seqArgs` on sequence player `a` with a fade in time of `fadeTimer`
+
+### Lua Example
+`set_background_music(a, seqArgs, fadeTimer)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| a | `integer` |
+| seqArgs | `integer` |
+| fadeTimer | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_background_music(u16 a, u16 seqArgs, s16 fadeTimer);`
+
+[:arrow_up_small:](#)
+
+
+
+## [fadeout_music](#fadeout_music)
+
+### Description
+Fades out level, shell, and cap music
+
+### Lua Example
+`fadeout_music(fadeOutTime)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| fadeOutTime | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void fadeout_music(s16 fadeOutTime);`
+
+[:arrow_up_small:](#)
+
+
+
+## [fadeout_level_music](#fadeout_level_music)
+
+### Description
+Fades out the level sequence player
+
+### Lua Example
+`fadeout_level_music(fadeTimer)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| fadeTimer | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void fadeout_level_music(s16 fadeTimer);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_cutscene_music](#play_cutscene_music)
+
+### Description
+Plays and sets the current music to `seqArgs`
+
+### Lua Example
+`play_cutscene_music(seqArgs)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| seqArgs | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void play_cutscene_music(u16 seqArgs);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_shell_music](#play_shell_music)
+
+### Description
+Plays shell music
+
+### Lua Example
+`play_shell_music()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void play_shell_music(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [stop_shell_music](#stop_shell_music)
+
+### Description
+Stops shell music completely
+
+### Lua Example
+`stop_shell_music()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void stop_shell_music(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [play_cap_music](#play_cap_music)
+
+### Description
+Plays `seqArgs` as cap music
+
+### Lua Example
+`play_cap_music(seqArgs)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| seqArgs | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void play_cap_music(u16 seqArgs);`
+
+[:arrow_up_small:](#)
+
+
+
+## [fadeout_cap_music](#fadeout_cap_music)
+
+### Description
+Fades out cap music
+
+### Lua Example
+`fadeout_cap_music()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void fadeout_cap_music(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [stop_cap_music](#stop_cap_music)
+
+### Description
+Stops cap music completely
+
+### Lua Example
+`stop_cap_music()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void stop_cap_music(void);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from spawn_sound.h
+
+
+
+
+## [cur_obj_play_sound_1](#cur_obj_play_sound_1)
+
+### Description
+Plays a sound if the current object is visible
+
+### Lua Example
+`cur_obj_play_sound_1(soundMagic)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| soundMagic | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_play_sound_1(s32 soundMagic);`
+
+[:arrow_up_small:](#)
+
+
+
+## [cur_obj_play_sound_2](#cur_obj_play_sound_2)
+
+### Description
+Plays a sound if the current object is visible and queues rumble for specific sounds
+
+### Lua Example
+`cur_obj_play_sound_2(soundMagic)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| soundMagic | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void cur_obj_play_sound_2(s32 soundMagic);`
+
+[:arrow_up_small:](#)
+
+
+
+## [create_sound_spawner](#create_sound_spawner)
+
+### Description
+Create a sound spawner for objects that need a sound play once. (Breakable walls, King Bobomb exploding, etc)
+
+### Lua Example
+`create_sound_spawner(soundMagic)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| soundMagic | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void create_sound_spawner(s32 soundMagic);`
+
+[:arrow_up_small:](#)
+
+
+
+## [calc_dist_to_volume_range_1](#calc_dist_to_volume_range_1)
+
+### Description
+Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 500 then 127, if `distance` is greater than 1500 then 0, if `distance` is between 500 and 1500 then it ranges linearly from 60 to 124. What an even more strange and confusing function
+
+### Lua Example
+`local integerValue = calc_dist_to_volume_range_1(distance)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| distance | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 calc_dist_to_volume_range_1(f32 distance);`
+
+[:arrow_up_small:](#)
+
+
+
+## [calc_dist_to_volume_range_2](#calc_dist_to_volume_range_2)
+
+### Description
+Unused vanilla function, calculates a volume based on `distance`. If `distance` is less than 1300 then 127, if `distance` is greater than 2300 then 0, if `distance` is between 1300 and 2300 then it ranges linearly from 60 to 127. What a strange and confusing function
+
+### Lua Example
+`local integerValue = calc_dist_to_volume_range_2(distance)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| distance | `number` |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 calc_dist_to_volume_range_2(f32 distance);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from surface_collision.h
+
+
+
+
+## [find_wall_collisions](#find_wall_collisions)
+
+### Description
+Detects wall collisions at a given position and adjusts the position based on the walls found. Returns the number of wall collisions detected
+
+### Lua Example
+`local integerValue = find_wall_collisions(colData)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| colData | [WallCollisionData](structs.md#WallCollisionData) |
+
+### Returns
+- `integer`
+
+### C Prototype
+`s32 find_wall_collisions(struct WallCollisionData *colData);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_ceil_height](#find_ceil_height)
+
+### Description
+Finds the height of the highest ceiling above a given position (x, y, z). If no ceiling is found, returns the default height limit of `gLevelValues.cellHeightLimit`(20000 by default)
+
+### Lua Example
+`local numberValue = find_ceil_height(x, y, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 find_ceil_height(f32 x, f32 y, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_floor_height](#find_floor_height)
+
+### Description
+Finds the height of the highest floor below a given position (x, y, z). If no floor is found, returns the default floor height of `gLevelValues.floorLowerLimit`(-11000 by default)
+
+### Lua Example
+`local numberValue = find_floor_height(x, y, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| y | `number` |
+| z | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 find_floor_height(f32 x, f32 y, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_water_level](#find_water_level)
+
+### Description
+Finds the height of water at a given position (x, z), if the position is within a water region. If no water is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
+
+### Lua Example
+`local numberValue = find_water_level(x, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| z | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 find_water_level(f32 x, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [find_poison_gas_level](#find_poison_gas_level)
+
+### Description
+Finds the height of the poison gas at a given position (x, z), if the position is within a gas region. If no gas is found, returns the default height of `gLevelValues.floorLowerLimit`(-11000 by default)
+
+### Lua Example
+`local numberValue = find_poison_gas_level(x, z)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| x | `number` |
+| z | `number` |
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 find_poison_gas_level(f32 x, f32 z);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_find_wall_direction](#set_find_wall_direction)
+
+### Description
+Sets whether collision finding functions should check wall directions.
+
+### Lua Example
+`set_find_wall_direction(dir, active, airborne)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| dir | [Vec3f](structs.md#Vec3f) |
+| active | `boolean` |
+| airborne | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_find_wall_direction(Vec3f dir, bool active, bool airborne);`
+
+[:arrow_up_small:](#)
+
+
+
+## [closest_point_to_triangle](#closest_point_to_triangle)
+
+### Description
+Gets the closest point of the triangle to `src` and returns it in `out`.
+
+### Lua Example
+`closest_point_to_triangle(surf, src, out)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| surf | [Surface](structs.md#Surface) |
+| src | [Vec3f](structs.md#Vec3f) |
+| out | [Vec3f](structs.md#Vec3f) |
+
+### Returns
+- None
+
+### C Prototype
+`void closest_point_to_triangle(struct Surface* surf, Vec3f src, OUT Vec3f out);`
+
+[:arrow_up_small:](#)
+
+
+
+---
+# functions from surface_load.h
+
+
+
+
+## [load_object_collision_model](#load_object_collision_model)
+
+### Description
+Loads the object's collision data into dynamic collision. You must run this every frame in your object's behavior loop for it to have collision
+
+### Lua Example
+`load_object_collision_model()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void load_object_collision_model(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [load_static_object_collision](#load_static_object_collision)
+
+### Description
+Loads the object's collision data into static collision. You may run this only once to capture the object's collision at that frame.
+
+### Lua Example
+`local StaticObjectCollisionValue = load_static_object_collision()`
+
+### Parameters
+- None
+
+### Returns
+[StaticObjectCollision](structs.md#StaticObjectCollision)
+
+### C Prototype
+`struct StaticObjectCollision *load_static_object_collision();`
+
+[:arrow_up_small:](#)
+
+
+
+## [toggle_static_object_collision](#toggle_static_object_collision)
+
+### Description
+Toggles a collection of static object surfaces
+
+### Lua Example
+`toggle_static_object_collision(col, tangible)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| col | [StaticObjectCollision](structs.md#StaticObjectCollision) |
+| tangible | `boolean` |
+
+### Returns
+- None
+
+### C Prototype
+`void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_static_object_surface](#get_static_object_surface)
+
+### Description
+Gets a surface corresponding to `index` from the static object collision
+
+### Lua Example
+`local SurfaceValue = get_static_object_surface(col, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| col | [StaticObjectCollision](structs.md#StaticObjectCollision) |
+| index | `integer` |
+
+### Returns
+[Surface](structs.md#Surface)
+
+### C Prototype
+`struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [obj_get_surface_from_index](#obj_get_surface_from_index)
+
+### Description
+Gets a surface corresponding to `index` from the surface pool buffer
+
+### Lua Example
+`local SurfaceValue = obj_get_surface_from_index(o, index)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| o | [Object](structs.md#Object) |
+| index | `integer` |
+
+### Returns
+[Surface](structs.md#Surface)
+
+### C Prototype
+`struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);`
+
+[:arrow_up_small:](#)
+
+
+
+## [surface_has_force](#surface_has_force)
+
+### Description
+Checks if a surface has force
+
+### Lua Example
+`local booleanValue = surface_has_force(surfaceType)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| surfaceType | `integer` |
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool surface_has_force(s16 surfaceType);`
+
+[:arrow_up_small:](#)
+
+
+
---
# functions from sync_object.h
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 5683b3946..9fe4cc414 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1354,9 +1354,6 @@
- [mod_fs_get](functions-5.md#mod_fs_get)
- [mod_fs_reload](functions-5.md#mod_fs_reload)
- [mod_fs_create](functions-5.md#mod_fs_create)
- - [mod_fs_delete](functions-5.md#mod_fs_delete)
- - [mod_fs_save](functions-5.md#mod_fs_save)
- - [mod_fs_set_public](functions-5.md#mod_fs_set_public)
- [mod_fs_get_filename](functions-5.md#mod_fs_get_filename)
- [mod_fs_get_file](functions-5.md#mod_fs_get_file)
- [mod_fs_create_file](functions-5.md#mod_fs_create_file)
@@ -1364,6 +1361,9 @@
- [mod_fs_copy_file](functions-5.md#mod_fs_copy_file)
- [mod_fs_delete_file](functions-5.md#mod_fs_delete_file)
- [mod_fs_clear](functions-5.md#mod_fs_clear)
+ - [mod_fs_save](functions-5.md#mod_fs_save)
+ - [mod_fs_delete](functions-5.md#mod_fs_delete)
+ - [mod_fs_set_public](functions-5.md#mod_fs_set_public)
- [mod_fs_file_read_bool](functions-5.md#mod_fs_file_read_bool)
- [mod_fs_file_read_integer](functions-5.md#mod_fs_file_read_integer)
- [mod_fs_file_read_number](functions-5.md#mod_fs_file_read_number)
@@ -1377,9 +1377,11 @@
- [mod_fs_file_write_string](functions-5.md#mod_fs_file_write_string)
- [mod_fs_file_write_line](functions-5.md#mod_fs_file_write_line)
- [mod_fs_file_seek](functions-5.md#mod_fs_file_seek)
+ - [mod_fs_file_rewind](functions-5.md#mod_fs_file_rewind)
- [mod_fs_file_is_eof](functions-5.md#mod_fs_file_is_eof)
- [mod_fs_file_fill](functions-5.md#mod_fs_file_fill)
- [mod_fs_file_erase](functions-5.md#mod_fs_file_erase)
+ - [mod_fs_file_set_text_mode](functions-5.md#mod_fs_file_set_text_mode)
- [mod_fs_file_set_public](functions-5.md#mod_fs_file_set_public)
- [mod_fs_hide_errors](functions-5.md#mod_fs_hide_errors)
- [mod_fs_get_last_error](functions-5.md#mod_fs_get_last_error)
@@ -1393,6 +1395,7 @@
- [mod_storage_load](functions-5.md#mod_storage_load)
- [mod_storage_load_number](functions-5.md#mod_storage_load_number)
- [mod_storage_load_bool](functions-5.md#mod_storage_load_bool)
+ - [mod_storage_load_all](functions-5.md#mod_storage_load_all)
- [mod_storage_exists](functions-5.md#mod_storage_exists)
- [mod_storage_remove](functions-5.md#mod_storage_remove)
- [mod_storage_clear](functions-5.md#mod_storage_clear)
@@ -1516,232 +1519,232 @@
- object_helpers.c
- - [clear_move_flag](functions-5.md#clear_move_flag)
- - [set_room_override](functions-5.md#set_room_override)
- - [obj_update_pos_from_parent_transformation](functions-5.md#obj_update_pos_from_parent_transformation)
- - [obj_apply_scale_to_matrix](functions-5.md#obj_apply_scale_to_matrix)
- - [create_transformation_from_matrices](functions-5.md#create_transformation_from_matrices)
- - [obj_set_held_state](functions-5.md#obj_set_held_state)
- - [lateral_dist_between_objects](functions-5.md#lateral_dist_between_objects)
- - [dist_between_objects](functions-5.md#dist_between_objects)
- - [dist_between_object_and_point](functions-5.md#dist_between_object_and_point)
- - [cur_obj_forward_vel_approach_upward](functions-5.md#cur_obj_forward_vel_approach_upward)
- - [approach_f32_signed](functions-5.md#approach_f32_signed)
- - [approach_f32_symmetric](functions-5.md#approach_f32_symmetric)
- - [approach_s16_symmetric](functions-5.md#approach_s16_symmetric)
- - [cur_obj_rotate_yaw_toward](functions-5.md#cur_obj_rotate_yaw_toward)
- - [obj_angle_to_object](functions-5.md#obj_angle_to_object)
- - [obj_pitch_to_object](functions-5.md#obj_pitch_to_object)
- - [obj_angle_to_point](functions-5.md#obj_angle_to_point)
- - [obj_turn_toward_object](functions-5.md#obj_turn_toward_object)
- - [obj_set_parent_relative_pos](functions-5.md#obj_set_parent_relative_pos)
- - [obj_set_pos](functions-5.md#obj_set_pos)
- - [obj_set_angle](functions-5.md#obj_set_angle)
- - [obj_set_move_angle](functions-5.md#obj_set_move_angle)
- - [obj_set_face_angle](functions-5.md#obj_set_face_angle)
- - [obj_set_gfx_angle](functions-5.md#obj_set_gfx_angle)
- - [obj_set_gfx_pos](functions-5.md#obj_set_gfx_pos)
- - [obj_set_gfx_scale](functions-5.md#obj_set_gfx_scale)
- - [spawn_water_droplet](functions-5.md#spawn_water_droplet)
- - [obj_build_relative_transform](functions-5.md#obj_build_relative_transform)
- - [cur_obj_move_using_vel](functions-5.md#cur_obj_move_using_vel)
- - [obj_copy_graph_y_offset](functions-5.md#obj_copy_graph_y_offset)
- - [obj_copy_pos_and_angle](functions-5.md#obj_copy_pos_and_angle)
- - [obj_copy_pos](functions-5.md#obj_copy_pos)
- - [obj_copy_angle](functions-5.md#obj_copy_angle)
- - [obj_set_gfx_pos_from_pos](functions-5.md#obj_set_gfx_pos_from_pos)
- - [obj_init_animation](functions-5.md#obj_init_animation)
- - [linear_mtxf_mul_vec3f](functions-5.md#linear_mtxf_mul_vec3f)
- - [linear_mtxf_transpose_mul_vec3f](functions-5.md#linear_mtxf_transpose_mul_vec3f)
- - [obj_apply_scale_to_transform](functions-5.md#obj_apply_scale_to_transform)
- - [obj_copy_scale](functions-5.md#obj_copy_scale)
- - [obj_scale_xyz](functions-5.md#obj_scale_xyz)
- - [obj_scale](functions-5.md#obj_scale)
- - [cur_obj_scale](functions-5.md#cur_obj_scale)
- - [cur_obj_init_animation](functions-5.md#cur_obj_init_animation)
- - [cur_obj_init_animation_with_sound](functions-5.md#cur_obj_init_animation_with_sound)
- - [obj_init_animation_with_accel_and_sound](functions-5.md#obj_init_animation_with_accel_and_sound)
- - [cur_obj_init_animation_with_accel_and_sound](functions-5.md#cur_obj_init_animation_with_accel_and_sound)
- - [obj_init_animation_with_sound](functions-5.md#obj_init_animation_with_sound)
- - [cur_obj_enable_rendering_and_become_tangible](functions-5.md#cur_obj_enable_rendering_and_become_tangible)
- - [cur_obj_enable_rendering](functions-5.md#cur_obj_enable_rendering)
- - [cur_obj_disable_rendering_and_become_intangible](functions-5.md#cur_obj_disable_rendering_and_become_intangible)
- - [cur_obj_disable_rendering](functions-5.md#cur_obj_disable_rendering)
- - [cur_obj_unhide](functions-5.md#cur_obj_unhide)
- - [cur_obj_hide](functions-5.md#cur_obj_hide)
- - [cur_obj_set_pos_relative](functions-5.md#cur_obj_set_pos_relative)
- - [cur_obj_set_pos_relative_to_parent](functions-5.md#cur_obj_set_pos_relative_to_parent)
- - [cur_obj_enable_rendering_2](functions-5.md#cur_obj_enable_rendering_2)
- - [cur_obj_unused_init_on_floor](functions-5.md#cur_obj_unused_init_on_floor)
- - [obj_set_face_angle_to_move_angle](functions-5.md#obj_set_face_angle_to_move_angle)
- - [get_object_list_from_behavior](functions-5.md#get_object_list_from_behavior)
- - [cur_obj_nearest_object_with_behavior](functions-5.md#cur_obj_nearest_object_with_behavior)
- - [cur_obj_dist_to_nearest_object_with_behavior](functions-5.md#cur_obj_dist_to_nearest_object_with_behavior)
- - [cur_obj_find_nearest_pole](functions-5.md#cur_obj_find_nearest_pole)
- - [cur_obj_find_nearest_object_with_behavior](functions-5.md#cur_obj_find_nearest_object_with_behavior)
- - [cur_obj_count_objects_with_behavior](functions-5.md#cur_obj_count_objects_with_behavior)
- - [find_unimportant_object](functions-5.md#find_unimportant_object)
- - [count_unimportant_objects](functions-5.md#count_unimportant_objects)
- - [count_objects_with_behavior](functions-5.md#count_objects_with_behavior)
- - [find_object_with_behavior](functions-5.md#find_object_with_behavior)
- - [cur_obj_find_nearby_held_actor](functions-5.md#cur_obj_find_nearby_held_actor)
- - [cur_obj_reset_timer_and_subaction](functions-5.md#cur_obj_reset_timer_and_subaction)
- - [cur_obj_change_action](functions-5.md#cur_obj_change_action)
- - [cur_obj_set_vel_from_mario_vel](functions-5.md#cur_obj_set_vel_from_mario_vel)
- - [cur_obj_reverse_animation](functions-5.md#cur_obj_reverse_animation)
- - [cur_obj_extend_animation_if_at_end](functions-5.md#cur_obj_extend_animation_if_at_end)
- - [cur_obj_check_if_near_animation_end](functions-5.md#cur_obj_check_if_near_animation_end)
- - [cur_obj_check_if_at_animation_end](functions-5.md#cur_obj_check_if_at_animation_end)
- - [cur_obj_check_anim_frame](functions-5.md#cur_obj_check_anim_frame)
- - [cur_obj_check_anim_frame_in_range](functions-5.md#cur_obj_check_anim_frame_in_range)
- - [cur_obj_check_frame_prior_current_frame](functions-5.md#cur_obj_check_frame_prior_current_frame)
- - [mario_is_in_air_action](functions-5.md#mario_is_in_air_action)
- - [mario_is_dive_sliding](functions-5.md#mario_is_dive_sliding)
- - [cur_obj_set_y_vel_and_animation](functions-5.md#cur_obj_set_y_vel_and_animation)
- - [cur_obj_unrender_and_reset_state](functions-5.md#cur_obj_unrender_and_reset_state)
- - [cur_obj_move_after_thrown_or_dropped](functions-5.md#cur_obj_move_after_thrown_or_dropped)
- - [cur_obj_get_thrown_or_placed](functions-5.md#cur_obj_get_thrown_or_placed)
- - [cur_obj_get_dropped](functions-5.md#cur_obj_get_dropped)
- - [mario_set_flag](functions-5.md#mario_set_flag)
- - [cur_obj_clear_interact_status_flag](functions-5.md#cur_obj_clear_interact_status_flag)
- - [obj_mark_for_deletion](functions-5.md#obj_mark_for_deletion)
- - [cur_obj_disable](functions-5.md#cur_obj_disable)
- - [cur_obj_become_intangible](functions-5.md#cur_obj_become_intangible)
- - [cur_obj_become_tangible](functions-5.md#cur_obj_become_tangible)
- - [obj_become_tangible](functions-5.md#obj_become_tangible)
- - [cur_obj_update_floor_height](functions-5.md#cur_obj_update_floor_height)
- - [cur_obj_update_floor_height_and_get_floor](functions-5.md#cur_obj_update_floor_height_and_get_floor)
- - [apply_drag_to_value](functions-5.md#apply_drag_to_value)
- - [cur_obj_apply_drag_xz](functions-5.md#cur_obj_apply_drag_xz)
- - [cur_obj_move_xz](functions-5.md#cur_obj_move_xz)
- - [cur_obj_move_update_underwater_flags](functions-5.md#cur_obj_move_update_underwater_flags)
- - [cur_obj_move_update_ground_air_flags](functions-5.md#cur_obj_move_update_ground_air_flags)
- - [cur_obj_move_y_and_get_water_level](functions-5.md#cur_obj_move_y_and_get_water_level)
- - [cur_obj_move_y](functions-5.md#cur_obj_move_y)
- - [cur_obj_unused_resolve_wall_collisions](functions-5.md#cur_obj_unused_resolve_wall_collisions)
- - [abs_angle_diff](functions-5.md#abs_angle_diff)
- - [cur_obj_move_xz_using_fvel_and_yaw](functions-5.md#cur_obj_move_xz_using_fvel_and_yaw)
- - [cur_obj_move_y_with_terminal_vel](functions-5.md#cur_obj_move_y_with_terminal_vel)
- - [cur_obj_compute_vel_xz](functions-5.md#cur_obj_compute_vel_xz)
- - [increment_velocity_toward_range](functions-5.md#increment_velocity_toward_range)
- - [obj_check_if_collided_with_object](functions-5.md#obj_check_if_collided_with_object)
- - [cur_obj_set_behavior](functions-5.md#cur_obj_set_behavior)
- - [obj_set_behavior](functions-5.md#obj_set_behavior)
- - [cur_obj_has_behavior](functions-5.md#cur_obj_has_behavior)
- - [obj_has_behavior](functions-5.md#obj_has_behavior)
- - [cur_obj_lateral_dist_from_obj_to_home](functions-5.md#cur_obj_lateral_dist_from_obj_to_home)
- - [cur_obj_lateral_dist_from_mario_to_home](functions-5.md#cur_obj_lateral_dist_from_mario_to_home)
- - [cur_obj_lateral_dist_to_home](functions-5.md#cur_obj_lateral_dist_to_home)
- - [cur_obj_outside_home_square](functions-5.md#cur_obj_outside_home_square)
- - [cur_obj_outside_home_rectangle](functions-5.md#cur_obj_outside_home_rectangle)
- - [cur_obj_set_pos_to_home](functions-5.md#cur_obj_set_pos_to_home)
- - [cur_obj_set_pos_to_home_and_stop](functions-5.md#cur_obj_set_pos_to_home_and_stop)
- - [cur_obj_shake_y](functions-5.md#cur_obj_shake_y)
- - [cur_obj_start_cam_event](functions-5.md#cur_obj_start_cam_event)
- - [set_mario_interact_hoot_if_in_range](functions-5.md#set_mario_interact_hoot_if_in_range)
- - [obj_set_billboard](functions-5.md#obj_set_billboard)
- - [obj_set_cylboard](functions-5.md#obj_set_cylboard)
- - [cur_obj_set_billboard_if_vanilla_cam](functions-5.md#cur_obj_set_billboard_if_vanilla_cam)
- - [obj_set_hitbox_radius_and_height](functions-5.md#obj_set_hitbox_radius_and_height)
- - [obj_set_hurtbox_radius_and_height](functions-5.md#obj_set_hurtbox_radius_and_height)
- - [cur_obj_set_hitbox_radius_and_height](functions-5.md#cur_obj_set_hitbox_radius_and_height)
- - [cur_obj_set_hurtbox_radius_and_height](functions-5.md#cur_obj_set_hurtbox_radius_and_height)
- - [obj_spawn_loot_coins](functions-5.md#obj_spawn_loot_coins)
- - [obj_spawn_loot_blue_coins](functions-5.md#obj_spawn_loot_blue_coins)
- - [obj_spawn_loot_yellow_coins](functions-5.md#obj_spawn_loot_yellow_coins)
- - [cur_obj_spawn_loot_coin_at_mario_pos](functions-5.md#cur_obj_spawn_loot_coin_at_mario_pos)
- - [cur_obj_abs_y_dist_to_home](functions-5.md#cur_obj_abs_y_dist_to_home)
- - [cur_obj_advance_looping_anim](functions-5.md#cur_obj_advance_looping_anim)
- - [cur_obj_detect_steep_floor](functions-5.md#cur_obj_detect_steep_floor)
- - [cur_obj_resolve_wall_collisions](functions-5.md#cur_obj_resolve_wall_collisions)
- - [cur_obj_update_floor](functions-5.md#cur_obj_update_floor)
- - [cur_obj_update_floor_and_resolve_wall_collisions](functions-5.md#cur_obj_update_floor_and_resolve_wall_collisions)
- - [cur_obj_update_floor_and_walls](functions-5.md#cur_obj_update_floor_and_walls)
- - [cur_obj_move_standard](functions-5.md#cur_obj_move_standard)
- - [cur_obj_within_12k_bounds](functions-5.md#cur_obj_within_12k_bounds)
- - [cur_obj_move_using_vel_and_gravity](functions-5.md#cur_obj_move_using_vel_and_gravity)
- - [cur_obj_move_using_fvel_and_gravity](functions-5.md#cur_obj_move_using_fvel_and_gravity)
- - [obj_set_pos_relative](functions-5.md#obj_set_pos_relative)
- - [cur_obj_angle_to_home](functions-5.md#cur_obj_angle_to_home)
- - [obj_set_gfx_pos_at_obj_pos](functions-5.md#obj_set_gfx_pos_at_obj_pos)
- - [obj_translate_local](functions-5.md#obj_translate_local)
- - [obj_build_transform_from_pos_and_angle](functions-5.md#obj_build_transform_from_pos_and_angle)
- - [obj_set_throw_matrix_from_transform](functions-5.md#obj_set_throw_matrix_from_transform)
- - [obj_build_transform_relative_to_parent](functions-5.md#obj_build_transform_relative_to_parent)
- - [obj_create_transform_from_self](functions-5.md#obj_create_transform_from_self)
- - [cur_obj_rotate_move_angle_using_vel](functions-5.md#cur_obj_rotate_move_angle_using_vel)
- - [cur_obj_rotate_face_angle_using_vel](functions-5.md#cur_obj_rotate_face_angle_using_vel)
- - [cur_obj_set_face_angle_to_move_angle](functions-5.md#cur_obj_set_face_angle_to_move_angle)
- - [cur_obj_follow_path](functions-5.md#cur_obj_follow_path)
- - [chain_segment_init](functions-5.md#chain_segment_init)
- - [random_f32_around_zero](functions-5.md#random_f32_around_zero)
- - [obj_scale_random](functions-5.md#obj_scale_random)
- - [obj_translate_xyz_random](functions-5.md#obj_translate_xyz_random)
- - [obj_translate_xz_random](functions-5.md#obj_translate_xz_random)
- - [obj_build_vel_from_transform](functions-5.md#obj_build_vel_from_transform)
- - [cur_obj_set_pos_via_transform](functions-5.md#cur_obj_set_pos_via_transform)
- - [cur_obj_reflect_move_angle_off_wall](functions-5.md#cur_obj_reflect_move_angle_off_wall)
- - [cur_obj_spawn_particles](functions-5.md#cur_obj_spawn_particles)
- - [obj_set_hitbox](functions-5.md#obj_set_hitbox)
- - [signum_positive](functions-5.md#signum_positive)
- - [cur_obj_wait_then_blink](functions-5.md#cur_obj_wait_then_blink)
- - [cur_obj_is_mario_ground_pounding_platform](functions-5.md#cur_obj_is_mario_ground_pounding_platform)
- - [obj_is_mario_ground_pounding_platform](functions-5.md#obj_is_mario_ground_pounding_platform)
- - [spawn_mist_particles](functions-5.md#spawn_mist_particles)
- - [spawn_mist_particles_with_sound](functions-5.md#spawn_mist_particles_with_sound)
- - [cur_obj_push_mario_away](functions-5.md#cur_obj_push_mario_away)
- - [cur_obj_push_mario_away_from_cylinder](functions-5.md#cur_obj_push_mario_away_from_cylinder)
- - [bhv_dust_smoke_loop](functions-5.md#bhv_dust_smoke_loop)
- - [stub_obj_helpers_3](functions-5.md#stub_obj_helpers_3)
- - [cur_obj_scale_over_time](functions-5.md#cur_obj_scale_over_time)
- - [cur_obj_set_pos_to_home_with_debug](functions-5.md#cur_obj_set_pos_to_home_with_debug)
- - [stub_obj_helpers_4](functions-5.md#stub_obj_helpers_4)
- - [cur_obj_is_mario_on_platform](functions-5.md#cur_obj_is_mario_on_platform)
- - [cur_obj_is_any_player_on_platform](functions-5.md#cur_obj_is_any_player_on_platform)
- - [cur_obj_shake_y_until](functions-5.md#cur_obj_shake_y_until)
- - [cur_obj_move_up_and_down](functions-5.md#cur_obj_move_up_and_down)
- - [spawn_star_with_no_lvl_exit](functions-5.md#spawn_star_with_no_lvl_exit)
- - [spawn_base_star_with_no_lvl_exit](functions-5.md#spawn_base_star_with_no_lvl_exit)
- - [bit_shift_left](functions-5.md#bit_shift_left)
- - [cur_obj_mario_far_away](functions-5.md#cur_obj_mario_far_away)
- - [is_mario_moving_fast_or_in_air](functions-5.md#is_mario_moving_fast_or_in_air)
- - [is_item_in_array](functions-5.md#is_item_in_array)
- - [bhv_init_room](functions-5.md#bhv_init_room)
- - [cur_obj_enable_rendering_if_mario_in_room](functions-5.md#cur_obj_enable_rendering_if_mario_in_room)
- - [cur_obj_set_hitbox_and_die_if_attacked](functions-5.md#cur_obj_set_hitbox_and_die_if_attacked)
- - [obj_explode_and_spawn_coins](functions-5.md#obj_explode_and_spawn_coins)
- - [cur_obj_if_hit_wall_bounce_away](functions-5.md#cur_obj_if_hit_wall_bounce_away)
- - [cur_obj_hide_if_mario_far_away_y](functions-5.md#cur_obj_hide_if_mario_far_away_y)
- - [obj_is_hidden](functions-5.md#obj_is_hidden)
- - [enable_time_stop](functions-5.md#enable_time_stop)
- - [enable_time_stop_if_alone](functions-5.md#enable_time_stop_if_alone)
- - [disable_time_stop](functions-5.md#disable_time_stop)
- - [set_time_stop_flags](functions-5.md#set_time_stop_flags)
- - [set_time_stop_flags_if_alone](functions-5.md#set_time_stop_flags_if_alone)
- - [clear_time_stop_flags](functions-5.md#clear_time_stop_flags)
- - [cur_obj_can_mario_activate_textbox](functions-5.md#cur_obj_can_mario_activate_textbox)
- - [cur_obj_can_mario_activate_textbox_2](functions-5.md#cur_obj_can_mario_activate_textbox_2)
- - [cur_obj_end_dialog](functions-5.md#cur_obj_end_dialog)
- - [cur_obj_has_model](functions-5.md#cur_obj_has_model)
- - [cur_obj_align_gfx_with_floor](functions-5.md#cur_obj_align_gfx_with_floor)
- - [mario_is_within_rectangle](functions-5.md#mario_is_within_rectangle)
- - [cur_obj_shake_screen](functions-5.md#cur_obj_shake_screen)
- - [obj_attack_collided_from_other_object](functions-5.md#obj_attack_collided_from_other_object)
- - [cur_obj_was_attacked_or_ground_pounded](functions-5.md#cur_obj_was_attacked_or_ground_pounded)
- - [obj_copy_behavior_params](functions-5.md#obj_copy_behavior_params)
- - [cur_obj_init_animation_and_anim_frame](functions-5.md#cur_obj_init_animation_and_anim_frame)
- - [cur_obj_init_animation_and_check_if_near_end](functions-5.md#cur_obj_init_animation_and_check_if_near_end)
- - [cur_obj_init_animation_and_extend_if_at_end](functions-5.md#cur_obj_init_animation_and_extend_if_at_end)
- - [cur_obj_check_grabbed_mario](functions-5.md#cur_obj_check_grabbed_mario)
- - [player_performed_grab_escape_action](functions-5.md#player_performed_grab_escape_action)
- - [cur_obj_unused_play_footstep_sound](functions-5.md#cur_obj_unused_play_footstep_sound)
- - [enable_time_stop_including_mario](functions-5.md#enable_time_stop_including_mario)
- - [disable_time_stop_including_mario](functions-5.md#disable_time_stop_including_mario)
- - [cur_obj_check_interacted](functions-5.md#cur_obj_check_interacted)
- - [cur_obj_spawn_loot_blue_coin](functions-5.md#cur_obj_spawn_loot_blue_coin)
- - [cur_obj_spawn_star_at_y_offset](functions-5.md#cur_obj_spawn_star_at_y_offset)
- - [cur_obj_set_home_once](functions-5.md#cur_obj_set_home_once)
- - [get_trajectory_length](functions-5.md#get_trajectory_length)
+ - [clear_move_flag](functions-6.md#clear_move_flag)
+ - [set_room_override](functions-6.md#set_room_override)
+ - [obj_update_pos_from_parent_transformation](functions-6.md#obj_update_pos_from_parent_transformation)
+ - [obj_apply_scale_to_matrix](functions-6.md#obj_apply_scale_to_matrix)
+ - [create_transformation_from_matrices](functions-6.md#create_transformation_from_matrices)
+ - [obj_set_held_state](functions-6.md#obj_set_held_state)
+ - [lateral_dist_between_objects](functions-6.md#lateral_dist_between_objects)
+ - [dist_between_objects](functions-6.md#dist_between_objects)
+ - [dist_between_object_and_point](functions-6.md#dist_between_object_and_point)
+ - [cur_obj_forward_vel_approach_upward](functions-6.md#cur_obj_forward_vel_approach_upward)
+ - [approach_f32_signed](functions-6.md#approach_f32_signed)
+ - [approach_f32_symmetric](functions-6.md#approach_f32_symmetric)
+ - [approach_s16_symmetric](functions-6.md#approach_s16_symmetric)
+ - [cur_obj_rotate_yaw_toward](functions-6.md#cur_obj_rotate_yaw_toward)
+ - [obj_angle_to_object](functions-6.md#obj_angle_to_object)
+ - [obj_pitch_to_object](functions-6.md#obj_pitch_to_object)
+ - [obj_angle_to_point](functions-6.md#obj_angle_to_point)
+ - [obj_turn_toward_object](functions-6.md#obj_turn_toward_object)
+ - [obj_set_parent_relative_pos](functions-6.md#obj_set_parent_relative_pos)
+ - [obj_set_pos](functions-6.md#obj_set_pos)
+ - [obj_set_angle](functions-6.md#obj_set_angle)
+ - [obj_set_move_angle](functions-6.md#obj_set_move_angle)
+ - [obj_set_face_angle](functions-6.md#obj_set_face_angle)
+ - [obj_set_gfx_angle](functions-6.md#obj_set_gfx_angle)
+ - [obj_set_gfx_pos](functions-6.md#obj_set_gfx_pos)
+ - [obj_set_gfx_scale](functions-6.md#obj_set_gfx_scale)
+ - [spawn_water_droplet](functions-6.md#spawn_water_droplet)
+ - [obj_build_relative_transform](functions-6.md#obj_build_relative_transform)
+ - [cur_obj_move_using_vel](functions-6.md#cur_obj_move_using_vel)
+ - [obj_copy_graph_y_offset](functions-6.md#obj_copy_graph_y_offset)
+ - [obj_copy_pos_and_angle](functions-6.md#obj_copy_pos_and_angle)
+ - [obj_copy_pos](functions-6.md#obj_copy_pos)
+ - [obj_copy_angle](functions-6.md#obj_copy_angle)
+ - [obj_set_gfx_pos_from_pos](functions-6.md#obj_set_gfx_pos_from_pos)
+ - [obj_init_animation](functions-6.md#obj_init_animation)
+ - [linear_mtxf_mul_vec3f](functions-6.md#linear_mtxf_mul_vec3f)
+ - [linear_mtxf_transpose_mul_vec3f](functions-6.md#linear_mtxf_transpose_mul_vec3f)
+ - [obj_apply_scale_to_transform](functions-6.md#obj_apply_scale_to_transform)
+ - [obj_copy_scale](functions-6.md#obj_copy_scale)
+ - [obj_scale_xyz](functions-6.md#obj_scale_xyz)
+ - [obj_scale](functions-6.md#obj_scale)
+ - [cur_obj_scale](functions-6.md#cur_obj_scale)
+ - [cur_obj_init_animation](functions-6.md#cur_obj_init_animation)
+ - [cur_obj_init_animation_with_sound](functions-6.md#cur_obj_init_animation_with_sound)
+ - [obj_init_animation_with_accel_and_sound](functions-6.md#obj_init_animation_with_accel_and_sound)
+ - [cur_obj_init_animation_with_accel_and_sound](functions-6.md#cur_obj_init_animation_with_accel_and_sound)
+ - [obj_init_animation_with_sound](functions-6.md#obj_init_animation_with_sound)
+ - [cur_obj_enable_rendering_and_become_tangible](functions-6.md#cur_obj_enable_rendering_and_become_tangible)
+ - [cur_obj_enable_rendering](functions-6.md#cur_obj_enable_rendering)
+ - [cur_obj_disable_rendering_and_become_intangible](functions-6.md#cur_obj_disable_rendering_and_become_intangible)
+ - [cur_obj_disable_rendering](functions-6.md#cur_obj_disable_rendering)
+ - [cur_obj_unhide](functions-6.md#cur_obj_unhide)
+ - [cur_obj_hide](functions-6.md#cur_obj_hide)
+ - [cur_obj_set_pos_relative](functions-6.md#cur_obj_set_pos_relative)
+ - [cur_obj_set_pos_relative_to_parent](functions-6.md#cur_obj_set_pos_relative_to_parent)
+ - [cur_obj_enable_rendering_2](functions-6.md#cur_obj_enable_rendering_2)
+ - [cur_obj_unused_init_on_floor](functions-6.md#cur_obj_unused_init_on_floor)
+ - [obj_set_face_angle_to_move_angle](functions-6.md#obj_set_face_angle_to_move_angle)
+ - [get_object_list_from_behavior](functions-6.md#get_object_list_from_behavior)
+ - [cur_obj_nearest_object_with_behavior](functions-6.md#cur_obj_nearest_object_with_behavior)
+ - [cur_obj_dist_to_nearest_object_with_behavior](functions-6.md#cur_obj_dist_to_nearest_object_with_behavior)
+ - [cur_obj_find_nearest_pole](functions-6.md#cur_obj_find_nearest_pole)
+ - [cur_obj_find_nearest_object_with_behavior](functions-6.md#cur_obj_find_nearest_object_with_behavior)
+ - [cur_obj_count_objects_with_behavior](functions-6.md#cur_obj_count_objects_with_behavior)
+ - [find_unimportant_object](functions-6.md#find_unimportant_object)
+ - [count_unimportant_objects](functions-6.md#count_unimportant_objects)
+ - [count_objects_with_behavior](functions-6.md#count_objects_with_behavior)
+ - [find_object_with_behavior](functions-6.md#find_object_with_behavior)
+ - [cur_obj_find_nearby_held_actor](functions-6.md#cur_obj_find_nearby_held_actor)
+ - [cur_obj_reset_timer_and_subaction](functions-6.md#cur_obj_reset_timer_and_subaction)
+ - [cur_obj_change_action](functions-6.md#cur_obj_change_action)
+ - [cur_obj_set_vel_from_mario_vel](functions-6.md#cur_obj_set_vel_from_mario_vel)
+ - [cur_obj_reverse_animation](functions-6.md#cur_obj_reverse_animation)
+ - [cur_obj_extend_animation_if_at_end](functions-6.md#cur_obj_extend_animation_if_at_end)
+ - [cur_obj_check_if_near_animation_end](functions-6.md#cur_obj_check_if_near_animation_end)
+ - [cur_obj_check_if_at_animation_end](functions-6.md#cur_obj_check_if_at_animation_end)
+ - [cur_obj_check_anim_frame](functions-6.md#cur_obj_check_anim_frame)
+ - [cur_obj_check_anim_frame_in_range](functions-6.md#cur_obj_check_anim_frame_in_range)
+ - [cur_obj_check_frame_prior_current_frame](functions-6.md#cur_obj_check_frame_prior_current_frame)
+ - [mario_is_in_air_action](functions-6.md#mario_is_in_air_action)
+ - [mario_is_dive_sliding](functions-6.md#mario_is_dive_sliding)
+ - [cur_obj_set_y_vel_and_animation](functions-6.md#cur_obj_set_y_vel_and_animation)
+ - [cur_obj_unrender_and_reset_state](functions-6.md#cur_obj_unrender_and_reset_state)
+ - [cur_obj_move_after_thrown_or_dropped](functions-6.md#cur_obj_move_after_thrown_or_dropped)
+ - [cur_obj_get_thrown_or_placed](functions-6.md#cur_obj_get_thrown_or_placed)
+ - [cur_obj_get_dropped](functions-6.md#cur_obj_get_dropped)
+ - [mario_set_flag](functions-6.md#mario_set_flag)
+ - [cur_obj_clear_interact_status_flag](functions-6.md#cur_obj_clear_interact_status_flag)
+ - [obj_mark_for_deletion](functions-6.md#obj_mark_for_deletion)
+ - [cur_obj_disable](functions-6.md#cur_obj_disable)
+ - [cur_obj_become_intangible](functions-6.md#cur_obj_become_intangible)
+ - [cur_obj_become_tangible](functions-6.md#cur_obj_become_tangible)
+ - [obj_become_tangible](functions-6.md#obj_become_tangible)
+ - [cur_obj_update_floor_height](functions-6.md#cur_obj_update_floor_height)
+ - [cur_obj_update_floor_height_and_get_floor](functions-6.md#cur_obj_update_floor_height_and_get_floor)
+ - [apply_drag_to_value](functions-6.md#apply_drag_to_value)
+ - [cur_obj_apply_drag_xz](functions-6.md#cur_obj_apply_drag_xz)
+ - [cur_obj_move_xz](functions-6.md#cur_obj_move_xz)
+ - [cur_obj_move_update_underwater_flags](functions-6.md#cur_obj_move_update_underwater_flags)
+ - [cur_obj_move_update_ground_air_flags](functions-6.md#cur_obj_move_update_ground_air_flags)
+ - [cur_obj_move_y_and_get_water_level](functions-6.md#cur_obj_move_y_and_get_water_level)
+ - [cur_obj_move_y](functions-6.md#cur_obj_move_y)
+ - [cur_obj_unused_resolve_wall_collisions](functions-6.md#cur_obj_unused_resolve_wall_collisions)
+ - [abs_angle_diff](functions-6.md#abs_angle_diff)
+ - [cur_obj_move_xz_using_fvel_and_yaw](functions-6.md#cur_obj_move_xz_using_fvel_and_yaw)
+ - [cur_obj_move_y_with_terminal_vel](functions-6.md#cur_obj_move_y_with_terminal_vel)
+ - [cur_obj_compute_vel_xz](functions-6.md#cur_obj_compute_vel_xz)
+ - [increment_velocity_toward_range](functions-6.md#increment_velocity_toward_range)
+ - [obj_check_if_collided_with_object](functions-6.md#obj_check_if_collided_with_object)
+ - [cur_obj_set_behavior](functions-6.md#cur_obj_set_behavior)
+ - [obj_set_behavior](functions-6.md#obj_set_behavior)
+ - [cur_obj_has_behavior](functions-6.md#cur_obj_has_behavior)
+ - [obj_has_behavior](functions-6.md#obj_has_behavior)
+ - [cur_obj_lateral_dist_from_obj_to_home](functions-6.md#cur_obj_lateral_dist_from_obj_to_home)
+ - [cur_obj_lateral_dist_from_mario_to_home](functions-6.md#cur_obj_lateral_dist_from_mario_to_home)
+ - [cur_obj_lateral_dist_to_home](functions-6.md#cur_obj_lateral_dist_to_home)
+ - [cur_obj_outside_home_square](functions-6.md#cur_obj_outside_home_square)
+ - [cur_obj_outside_home_rectangle](functions-6.md#cur_obj_outside_home_rectangle)
+ - [cur_obj_set_pos_to_home](functions-6.md#cur_obj_set_pos_to_home)
+ - [cur_obj_set_pos_to_home_and_stop](functions-6.md#cur_obj_set_pos_to_home_and_stop)
+ - [cur_obj_shake_y](functions-6.md#cur_obj_shake_y)
+ - [cur_obj_start_cam_event](functions-6.md#cur_obj_start_cam_event)
+ - [set_mario_interact_hoot_if_in_range](functions-6.md#set_mario_interact_hoot_if_in_range)
+ - [obj_set_billboard](functions-6.md#obj_set_billboard)
+ - [obj_set_cylboard](functions-6.md#obj_set_cylboard)
+ - [cur_obj_set_billboard_if_vanilla_cam](functions-6.md#cur_obj_set_billboard_if_vanilla_cam)
+ - [obj_set_hitbox_radius_and_height](functions-6.md#obj_set_hitbox_radius_and_height)
+ - [obj_set_hurtbox_radius_and_height](functions-6.md#obj_set_hurtbox_radius_and_height)
+ - [cur_obj_set_hitbox_radius_and_height](functions-6.md#cur_obj_set_hitbox_radius_and_height)
+ - [cur_obj_set_hurtbox_radius_and_height](functions-6.md#cur_obj_set_hurtbox_radius_and_height)
+ - [obj_spawn_loot_coins](functions-6.md#obj_spawn_loot_coins)
+ - [obj_spawn_loot_blue_coins](functions-6.md#obj_spawn_loot_blue_coins)
+ - [obj_spawn_loot_yellow_coins](functions-6.md#obj_spawn_loot_yellow_coins)
+ - [cur_obj_spawn_loot_coin_at_mario_pos](functions-6.md#cur_obj_spawn_loot_coin_at_mario_pos)
+ - [cur_obj_abs_y_dist_to_home](functions-6.md#cur_obj_abs_y_dist_to_home)
+ - [cur_obj_advance_looping_anim](functions-6.md#cur_obj_advance_looping_anim)
+ - [cur_obj_detect_steep_floor](functions-6.md#cur_obj_detect_steep_floor)
+ - [cur_obj_resolve_wall_collisions](functions-6.md#cur_obj_resolve_wall_collisions)
+ - [cur_obj_update_floor](functions-6.md#cur_obj_update_floor)
+ - [cur_obj_update_floor_and_resolve_wall_collisions](functions-6.md#cur_obj_update_floor_and_resolve_wall_collisions)
+ - [cur_obj_update_floor_and_walls](functions-6.md#cur_obj_update_floor_and_walls)
+ - [cur_obj_move_standard](functions-6.md#cur_obj_move_standard)
+ - [cur_obj_within_12k_bounds](functions-6.md#cur_obj_within_12k_bounds)
+ - [cur_obj_move_using_vel_and_gravity](functions-6.md#cur_obj_move_using_vel_and_gravity)
+ - [cur_obj_move_using_fvel_and_gravity](functions-6.md#cur_obj_move_using_fvel_and_gravity)
+ - [obj_set_pos_relative](functions-6.md#obj_set_pos_relative)
+ - [cur_obj_angle_to_home](functions-6.md#cur_obj_angle_to_home)
+ - [obj_set_gfx_pos_at_obj_pos](functions-6.md#obj_set_gfx_pos_at_obj_pos)
+ - [obj_translate_local](functions-6.md#obj_translate_local)
+ - [obj_build_transform_from_pos_and_angle](functions-6.md#obj_build_transform_from_pos_and_angle)
+ - [obj_set_throw_matrix_from_transform](functions-6.md#obj_set_throw_matrix_from_transform)
+ - [obj_build_transform_relative_to_parent](functions-6.md#obj_build_transform_relative_to_parent)
+ - [obj_create_transform_from_self](functions-6.md#obj_create_transform_from_self)
+ - [cur_obj_rotate_move_angle_using_vel](functions-6.md#cur_obj_rotate_move_angle_using_vel)
+ - [cur_obj_rotate_face_angle_using_vel](functions-6.md#cur_obj_rotate_face_angle_using_vel)
+ - [cur_obj_set_face_angle_to_move_angle](functions-6.md#cur_obj_set_face_angle_to_move_angle)
+ - [cur_obj_follow_path](functions-6.md#cur_obj_follow_path)
+ - [chain_segment_init](functions-6.md#chain_segment_init)
+ - [random_f32_around_zero](functions-6.md#random_f32_around_zero)
+ - [obj_scale_random](functions-6.md#obj_scale_random)
+ - [obj_translate_xyz_random](functions-6.md#obj_translate_xyz_random)
+ - [obj_translate_xz_random](functions-6.md#obj_translate_xz_random)
+ - [obj_build_vel_from_transform](functions-6.md#obj_build_vel_from_transform)
+ - [cur_obj_set_pos_via_transform](functions-6.md#cur_obj_set_pos_via_transform)
+ - [cur_obj_reflect_move_angle_off_wall](functions-6.md#cur_obj_reflect_move_angle_off_wall)
+ - [cur_obj_spawn_particles](functions-6.md#cur_obj_spawn_particles)
+ - [obj_set_hitbox](functions-6.md#obj_set_hitbox)
+ - [signum_positive](functions-6.md#signum_positive)
+ - [cur_obj_wait_then_blink](functions-6.md#cur_obj_wait_then_blink)
+ - [cur_obj_is_mario_ground_pounding_platform](functions-6.md#cur_obj_is_mario_ground_pounding_platform)
+ - [obj_is_mario_ground_pounding_platform](functions-6.md#obj_is_mario_ground_pounding_platform)
+ - [spawn_mist_particles](functions-6.md#spawn_mist_particles)
+ - [spawn_mist_particles_with_sound](functions-6.md#spawn_mist_particles_with_sound)
+ - [cur_obj_push_mario_away](functions-6.md#cur_obj_push_mario_away)
+ - [cur_obj_push_mario_away_from_cylinder](functions-6.md#cur_obj_push_mario_away_from_cylinder)
+ - [bhv_dust_smoke_loop](functions-6.md#bhv_dust_smoke_loop)
+ - [stub_obj_helpers_3](functions-6.md#stub_obj_helpers_3)
+ - [cur_obj_scale_over_time](functions-6.md#cur_obj_scale_over_time)
+ - [cur_obj_set_pos_to_home_with_debug](functions-6.md#cur_obj_set_pos_to_home_with_debug)
+ - [stub_obj_helpers_4](functions-6.md#stub_obj_helpers_4)
+ - [cur_obj_is_mario_on_platform](functions-6.md#cur_obj_is_mario_on_platform)
+ - [cur_obj_is_any_player_on_platform](functions-6.md#cur_obj_is_any_player_on_platform)
+ - [cur_obj_shake_y_until](functions-6.md#cur_obj_shake_y_until)
+ - [cur_obj_move_up_and_down](functions-6.md#cur_obj_move_up_and_down)
+ - [spawn_star_with_no_lvl_exit](functions-6.md#spawn_star_with_no_lvl_exit)
+ - [spawn_base_star_with_no_lvl_exit](functions-6.md#spawn_base_star_with_no_lvl_exit)
+ - [bit_shift_left](functions-6.md#bit_shift_left)
+ - [cur_obj_mario_far_away](functions-6.md#cur_obj_mario_far_away)
+ - [is_mario_moving_fast_or_in_air](functions-6.md#is_mario_moving_fast_or_in_air)
+ - [is_item_in_array](functions-6.md#is_item_in_array)
+ - [bhv_init_room](functions-6.md#bhv_init_room)
+ - [cur_obj_enable_rendering_if_mario_in_room](functions-6.md#cur_obj_enable_rendering_if_mario_in_room)
+ - [cur_obj_set_hitbox_and_die_if_attacked](functions-6.md#cur_obj_set_hitbox_and_die_if_attacked)
+ - [obj_explode_and_spawn_coins](functions-6.md#obj_explode_and_spawn_coins)
+ - [cur_obj_if_hit_wall_bounce_away](functions-6.md#cur_obj_if_hit_wall_bounce_away)
+ - [cur_obj_hide_if_mario_far_away_y](functions-6.md#cur_obj_hide_if_mario_far_away_y)
+ - [obj_is_hidden](functions-6.md#obj_is_hidden)
+ - [enable_time_stop](functions-6.md#enable_time_stop)
+ - [enable_time_stop_if_alone](functions-6.md#enable_time_stop_if_alone)
+ - [disable_time_stop](functions-6.md#disable_time_stop)
+ - [set_time_stop_flags](functions-6.md#set_time_stop_flags)
+ - [set_time_stop_flags_if_alone](functions-6.md#set_time_stop_flags_if_alone)
+ - [clear_time_stop_flags](functions-6.md#clear_time_stop_flags)
+ - [cur_obj_can_mario_activate_textbox](functions-6.md#cur_obj_can_mario_activate_textbox)
+ - [cur_obj_can_mario_activate_textbox_2](functions-6.md#cur_obj_can_mario_activate_textbox_2)
+ - [cur_obj_end_dialog](functions-6.md#cur_obj_end_dialog)
+ - [cur_obj_has_model](functions-6.md#cur_obj_has_model)
+ - [cur_obj_align_gfx_with_floor](functions-6.md#cur_obj_align_gfx_with_floor)
+ - [mario_is_within_rectangle](functions-6.md#mario_is_within_rectangle)
+ - [cur_obj_shake_screen](functions-6.md#cur_obj_shake_screen)
+ - [obj_attack_collided_from_other_object](functions-6.md#obj_attack_collided_from_other_object)
+ - [cur_obj_was_attacked_or_ground_pounded](functions-6.md#cur_obj_was_attacked_or_ground_pounded)
+ - [obj_copy_behavior_params](functions-6.md#obj_copy_behavior_params)
+ - [cur_obj_init_animation_and_anim_frame](functions-6.md#cur_obj_init_animation_and_anim_frame)
+ - [cur_obj_init_animation_and_check_if_near_end](functions-6.md#cur_obj_init_animation_and_check_if_near_end)
+ - [cur_obj_init_animation_and_extend_if_at_end](functions-6.md#cur_obj_init_animation_and_extend_if_at_end)
+ - [cur_obj_check_grabbed_mario](functions-6.md#cur_obj_check_grabbed_mario)
+ - [player_performed_grab_escape_action](functions-6.md#player_performed_grab_escape_action)
+ - [cur_obj_unused_play_footstep_sound](functions-6.md#cur_obj_unused_play_footstep_sound)
+ - [enable_time_stop_including_mario](functions-6.md#enable_time_stop_including_mario)
+ - [disable_time_stop_including_mario](functions-6.md#disable_time_stop_including_mario)
+ - [cur_obj_check_interacted](functions-6.md#cur_obj_check_interacted)
+ - [cur_obj_spawn_loot_blue_coin](functions-6.md#cur_obj_spawn_loot_blue_coin)
+ - [cur_obj_spawn_star_at_y_offset](functions-6.md#cur_obj_spawn_star_at_y_offset)
+ - [cur_obj_set_home_once](functions-6.md#cur_obj_set_home_once)
+ - [get_trajectory_length](functions-6.md#get_trajectory_length)
@@ -1934,6 +1937,7 @@
- [gfx_get_vertex_buffer](functions-6.md#gfx_get_vertex_buffer)
- [gfx_get_vertex_count](functions-6.md#gfx_get_vertex_count)
- [gfx_get_texture](functions-6.md#gfx_get_texture)
+ - [gfx_get_name](functions-6.md#gfx_get_name)
- [gfx_get_length](functions-6.md#gfx_get_length)
- [gfx_get_command](functions-6.md#gfx_get_command)
- [gfx_get_next_command](functions-6.md#gfx_get_next_command)
@@ -1942,6 +1946,7 @@
- [gfx_resize](functions-6.md#gfx_resize)
- [gfx_delete](functions-6.md#gfx_delete)
- [gfx_delete_all](functions-6.md#gfx_delete_all)
+ - [vtx_get_name](functions-6.md#vtx_get_name)
- [vtx_get_count](functions-6.md#vtx_get_count)
- [vtx_get_vertex](functions-6.md#vtx_get_vertex)
- [vtx_get_next_vertex](functions-6.md#vtx_get_next_vertex)
@@ -1954,240 +1959,244 @@
- smlua_level_utils.h
- - [smlua_level_util_change_area](functions-6.md#smlua_level_util_change_area)
- - [smlua_level_util_get_info](functions-6.md#smlua_level_util_get_info)
- - [smlua_level_util_get_info_from_short_name](functions-6.md#smlua_level_util_get_info_from_short_name)
- - [smlua_level_util_get_info_from_course_num](functions-6.md#smlua_level_util_get_info_from_course_num)
- - [level_register](functions-6.md#level_register)
- - [level_is_vanilla_level](functions-6.md#level_is_vanilla_level)
- - [warp_to_warpnode](functions-6.md#warp_to_warpnode)
- - [warp_to_level](functions-6.md#warp_to_level)
- - [warp_restart_level](functions-6.md#warp_restart_level)
- - [warp_to_start_level](functions-6.md#warp_to_start_level)
- - [warp_exit_level](functions-6.md#warp_exit_level)
- - [warp_to_castle](functions-6.md#warp_to_castle)
+ - [smlua_level_util_change_area](functions-7.md#smlua_level_util_change_area)
+ - [smlua_level_util_get_info](functions-7.md#smlua_level_util_get_info)
+ - [smlua_level_util_get_info_from_short_name](functions-7.md#smlua_level_util_get_info_from_short_name)
+ - [smlua_level_util_get_info_from_course_num](functions-7.md#smlua_level_util_get_info_from_course_num)
+ - [level_register](functions-7.md#level_register)
+ - [level_is_vanilla_level](functions-7.md#level_is_vanilla_level)
+ - [warp_to_warpnode](functions-7.md#warp_to_warpnode)
+ - [warp_to_level](functions-7.md#warp_to_level)
+ - [warp_restart_level](functions-7.md#warp_restart_level)
+ - [warp_to_start_level](functions-7.md#warp_to_start_level)
+ - [warp_exit_level](functions-7.md#warp_exit_level)
+ - [warp_to_castle](functions-7.md#warp_to_castle)
- smlua_misc_utils.h
- - [get_network_area_timer](functions-6.md#get_network_area_timer)
- - [get_area_update_counter](functions-6.md#get_area_update_counter)
- - [get_temp_s32_pointer](functions-6.md#get_temp_s32_pointer)
- - [deref_s32_pointer](functions-6.md#deref_s32_pointer)
- - [djui_popup_create_global](functions-6.md#djui_popup_create_global)
- - [djui_is_popup_disabled](functions-6.md#djui_is_popup_disabled)
- - [djui_set_popup_disabled_override](functions-6.md#djui_set_popup_disabled_override)
- - [djui_reset_popup_disabled_override](functions-6.md#djui_reset_popup_disabled_override)
- - [djui_is_playerlist_open](functions-6.md#djui_is_playerlist_open)
- - [djui_attempting_to_open_playerlist](functions-6.md#djui_attempting_to_open_playerlist)
- - [djui_get_playerlist_page_index](functions-6.md#djui_get_playerlist_page_index)
- - [djui_menu_get_font](functions-6.md#djui_menu_get_font)
- - [djui_menu_get_theme](functions-6.md#djui_menu_get_theme)
- - [djui_is_playerlist_ping_visible](functions-6.md#djui_is_playerlist_ping_visible)
- - [get_dialog_box_state](functions-6.md#get_dialog_box_state)
- - [get_dialog_id](functions-6.md#get_dialog_id)
- - [get_last_star_or_key](functions-6.md#get_last_star_or_key)
- - [set_last_star_or_key](functions-6.md#set_last_star_or_key)
- - [get_last_completed_course_num](functions-6.md#get_last_completed_course_num)
- - [set_last_completed_course_num](functions-6.md#set_last_completed_course_num)
- - [get_last_completed_star_num](functions-6.md#get_last_completed_star_num)
- - [set_last_completed_star_num](functions-6.md#set_last_completed_star_num)
- - [get_got_file_coin_hi_score](functions-6.md#get_got_file_coin_hi_score)
- - [set_got_file_coin_hi_score](functions-6.md#set_got_file_coin_hi_score)
- - [get_save_file_modified](functions-6.md#get_save_file_modified)
- - [set_save_file_modified](functions-6.md#set_save_file_modified)
- - [hud_hide](functions-6.md#hud_hide)
- - [hud_show](functions-6.md#hud_show)
- - [hud_is_hidden](functions-6.md#hud_is_hidden)
- - [hud_get_value](functions-6.md#hud_get_value)
- - [hud_set_value](functions-6.md#hud_set_value)
- - [hud_render_power_meter](functions-6.md#hud_render_power_meter)
- - [hud_render_power_meter_interpolated](functions-6.md#hud_render_power_meter_interpolated)
- - [hud_get_flash](functions-6.md#hud_get_flash)
- - [hud_set_flash](functions-6.md#hud_set_flash)
- - [act_select_hud_hide](functions-6.md#act_select_hud_hide)
- - [act_select_hud_show](functions-6.md#act_select_hud_show)
- - [act_select_hud_is_hidden](functions-6.md#act_select_hud_is_hidden)
- - [is_game_paused](functions-6.md#is_game_paused)
- - [is_transition_playing](functions-6.md#is_transition_playing)
- - [allocate_mario_action](functions-6.md#allocate_mario_action)
- - [get_hand_foot_pos_x](functions-6.md#get_hand_foot_pos_x)
- - [get_hand_foot_pos_y](functions-6.md#get_hand_foot_pos_y)
- - [get_hand_foot_pos_z](functions-6.md#get_hand_foot_pos_z)
- - [get_mario_anim_part_pos](functions-6.md#get_mario_anim_part_pos)
- - [get_current_save_file_num](functions-6.md#get_current_save_file_num)
- - [save_file_get_using_backup_slot](functions-6.md#save_file_get_using_backup_slot)
- - [save_file_set_using_backup_slot](functions-6.md#save_file_set_using_backup_slot)
- - [movtexqc_register](functions-6.md#movtexqc_register)
- - [get_water_level](functions-6.md#get_water_level)
- - [set_water_level](functions-6.md#set_water_level)
- - [course_is_main_course](functions-6.md#course_is_main_course)
- - [get_ttc_speed_setting](functions-6.md#get_ttc_speed_setting)
- - [set_ttc_speed_setting](functions-6.md#set_ttc_speed_setting)
- - [get_time](functions-6.md#get_time)
- - [get_date_and_time](functions-6.md#get_date_and_time)
- - [get_envfx](functions-6.md#get_envfx)
- - [set_override_envfx](functions-6.md#set_override_envfx)
- - [get_global_timer](functions-6.md#get_global_timer)
- - [get_dialog_response](functions-6.md#get_dialog_response)
- - [get_local_discord_id](functions-6.md#get_local_discord_id)
- - [get_coopnet_id](functions-6.md#get_coopnet_id)
- - [get_volume_master](functions-6.md#get_volume_master)
- - [get_volume_level](functions-6.md#get_volume_level)
- - [get_volume_sfx](functions-6.md#get_volume_sfx)
- - [get_volume_env](functions-6.md#get_volume_env)
- - [set_volume_master](functions-6.md#set_volume_master)
- - [set_volume_level](functions-6.md#set_volume_level)
- - [set_volume_sfx](functions-6.md#set_volume_sfx)
- - [set_volume_env](functions-6.md#set_volume_env)
- - [get_environment_region](functions-6.md#get_environment_region)
- - [set_environment_region](functions-6.md#set_environment_region)
- - [mod_file_exists](functions-6.md#mod_file_exists)
- - [get_active_mod](functions-6.md#get_active_mod)
- - [set_window_title](functions-6.md#set_window_title)
- - [reset_window_title](functions-6.md#reset_window_title)
- - [get_os_name](functions-6.md#get_os_name)
- - [geo_get_current_root](functions-6.md#geo_get_current_root)
- - [geo_get_current_master_list](functions-6.md#geo_get_current_master_list)
- - [geo_get_current_perspective](functions-6.md#geo_get_current_perspective)
- - [geo_get_current_camera](functions-6.md#geo_get_current_camera)
- - [geo_get_current_held_object](functions-6.md#geo_get_current_held_object)
- - [texture_to_lua_table](functions-6.md#texture_to_lua_table)
+ - [get_network_area_timer](functions-7.md#get_network_area_timer)
+ - [get_area_update_counter](functions-7.md#get_area_update_counter)
+ - [get_temp_s32_pointer](functions-7.md#get_temp_s32_pointer)
+ - [deref_s32_pointer](functions-7.md#deref_s32_pointer)
+ - [djui_popup_create_global](functions-7.md#djui_popup_create_global)
+ - [djui_is_popup_disabled](functions-7.md#djui_is_popup_disabled)
+ - [djui_set_popup_disabled_override](functions-7.md#djui_set_popup_disabled_override)
+ - [djui_reset_popup_disabled_override](functions-7.md#djui_reset_popup_disabled_override)
+ - [djui_is_playerlist_open](functions-7.md#djui_is_playerlist_open)
+ - [djui_attempting_to_open_playerlist](functions-7.md#djui_attempting_to_open_playerlist)
+ - [djui_get_playerlist_page_index](functions-7.md#djui_get_playerlist_page_index)
+ - [djui_menu_get_font](functions-7.md#djui_menu_get_font)
+ - [djui_menu_get_theme](functions-7.md#djui_menu_get_theme)
+ - [djui_is_playerlist_ping_visible](functions-7.md#djui_is_playerlist_ping_visible)
+ - [get_dialog_box_state](functions-7.md#get_dialog_box_state)
+ - [get_dialog_id](functions-7.md#get_dialog_id)
+ - [get_last_star_or_key](functions-7.md#get_last_star_or_key)
+ - [set_last_star_or_key](functions-7.md#set_last_star_or_key)
+ - [get_last_completed_course_num](functions-7.md#get_last_completed_course_num)
+ - [set_last_completed_course_num](functions-7.md#set_last_completed_course_num)
+ - [get_last_completed_star_num](functions-7.md#get_last_completed_star_num)
+ - [set_last_completed_star_num](functions-7.md#set_last_completed_star_num)
+ - [get_got_file_coin_hi_score](functions-7.md#get_got_file_coin_hi_score)
+ - [set_got_file_coin_hi_score](functions-7.md#set_got_file_coin_hi_score)
+ - [get_save_file_modified](functions-7.md#get_save_file_modified)
+ - [set_save_file_modified](functions-7.md#set_save_file_modified)
+ - [hud_hide](functions-7.md#hud_hide)
+ - [hud_show](functions-7.md#hud_show)
+ - [hud_is_hidden](functions-7.md#hud_is_hidden)
+ - [hud_get_value](functions-7.md#hud_get_value)
+ - [hud_set_value](functions-7.md#hud_set_value)
+ - [hud_render_power_meter](functions-7.md#hud_render_power_meter)
+ - [hud_render_power_meter_interpolated](functions-7.md#hud_render_power_meter_interpolated)
+ - [hud_get_flash](functions-7.md#hud_get_flash)
+ - [hud_set_flash](functions-7.md#hud_set_flash)
+ - [act_select_hud_hide](functions-7.md#act_select_hud_hide)
+ - [act_select_hud_show](functions-7.md#act_select_hud_show)
+ - [act_select_hud_is_hidden](functions-7.md#act_select_hud_is_hidden)
+ - [is_game_paused](functions-7.md#is_game_paused)
+ - [is_transition_playing](functions-7.md#is_transition_playing)
+ - [allocate_mario_action](functions-7.md#allocate_mario_action)
+ - [get_hand_foot_pos_x](functions-7.md#get_hand_foot_pos_x)
+ - [get_hand_foot_pos_y](functions-7.md#get_hand_foot_pos_y)
+ - [get_hand_foot_pos_z](functions-7.md#get_hand_foot_pos_z)
+ - [get_mario_anim_part_pos](functions-7.md#get_mario_anim_part_pos)
+ - [get_current_save_file_num](functions-7.md#get_current_save_file_num)
+ - [save_file_get_using_backup_slot](functions-7.md#save_file_get_using_backup_slot)
+ - [save_file_set_using_backup_slot](functions-7.md#save_file_set_using_backup_slot)
+ - [movtexqc_register](functions-7.md#movtexqc_register)
+ - [get_water_level](functions-7.md#get_water_level)
+ - [set_water_level](functions-7.md#set_water_level)
+ - [course_is_main_course](functions-7.md#course_is_main_course)
+ - [get_ttc_speed_setting](functions-7.md#get_ttc_speed_setting)
+ - [set_ttc_speed_setting](functions-7.md#set_ttc_speed_setting)
+ - [get_time](functions-7.md#get_time)
+ - [get_date_and_time](functions-7.md#get_date_and_time)
+ - [get_envfx](functions-7.md#get_envfx)
+ - [set_override_envfx](functions-7.md#set_override_envfx)
+ - [get_global_timer](functions-7.md#get_global_timer)
+ - [get_dialog_response](functions-7.md#get_dialog_response)
+ - [get_local_discord_id](functions-7.md#get_local_discord_id)
+ - [get_coopnet_id](functions-7.md#get_coopnet_id)
+ - [get_volume_master](functions-7.md#get_volume_master)
+ - [get_volume_level](functions-7.md#get_volume_level)
+ - [get_volume_sfx](functions-7.md#get_volume_sfx)
+ - [get_volume_env](functions-7.md#get_volume_env)
+ - [set_volume_master](functions-7.md#set_volume_master)
+ - [set_volume_level](functions-7.md#set_volume_level)
+ - [set_volume_sfx](functions-7.md#set_volume_sfx)
+ - [set_volume_env](functions-7.md#set_volume_env)
+ - [get_environment_region](functions-7.md#get_environment_region)
+ - [set_environment_region](functions-7.md#set_environment_region)
+ - [mod_file_exists](functions-7.md#mod_file_exists)
+ - [get_active_mod](functions-7.md#get_active_mod)
+ - [set_window_title](functions-7.md#set_window_title)
+ - [reset_window_title](functions-7.md#reset_window_title)
+ - [get_os_name](functions-7.md#get_os_name)
+ - [geo_get_current_root](functions-7.md#geo_get_current_root)
+ - [geo_get_current_master_list](functions-7.md#geo_get_current_master_list)
+ - [geo_get_current_perspective](functions-7.md#geo_get_current_perspective)
+ - [geo_get_current_camera](functions-7.md#geo_get_current_camera)
+ - [geo_get_current_held_object](functions-7.md#geo_get_current_held_object)
+ - [texture_to_lua_table](functions-7.md#texture_to_lua_table)
+ - [get_texture_name](functions-7.md#get_texture_name)
- smlua_model_utils.h
- - [smlua_model_util_get_id](functions-6.md#smlua_model_util_get_id)
+ - [smlua_model_util_get_id](functions-7.md#smlua_model_util_get_id)
- smlua_obj_utils.h
- - [spawn_sync_object](functions-6.md#spawn_sync_object)
- - [spawn_non_sync_object](functions-6.md#spawn_non_sync_object)
- - [obj_has_behavior_id](functions-6.md#obj_has_behavior_id)
- - [obj_has_model_extended](functions-6.md#obj_has_model_extended)
- - [obj_get_model_id_extended](functions-6.md#obj_get_model_id_extended)
- - [obj_set_model_extended](functions-6.md#obj_set_model_extended)
- - [get_trajectory](functions-6.md#get_trajectory)
- - [geo_get_current_object](functions-6.md#geo_get_current_object)
- - [get_current_object](functions-6.md#get_current_object)
- - [get_dialog_object](functions-6.md#get_dialog_object)
- - [get_cutscene_focus](functions-6.md#get_cutscene_focus)
- - [get_secondary_camera_focus](functions-6.md#get_secondary_camera_focus)
- - [set_cutscene_focus](functions-6.md#set_cutscene_focus)
- - [set_secondary_camera_focus](functions-6.md#set_secondary_camera_focus)
- - [obj_get_first](functions-6.md#obj_get_first)
- - [obj_get_first_with_behavior_id](functions-6.md#obj_get_first_with_behavior_id)
- - [obj_get_first_with_behavior_id_and_field_s32](functions-6.md#obj_get_first_with_behavior_id_and_field_s32)
- - [obj_get_first_with_behavior_id_and_field_f32](functions-6.md#obj_get_first_with_behavior_id_and_field_f32)
- - [obj_get_next](functions-6.md#obj_get_next)
- - [obj_get_next_with_same_behavior_id](functions-6.md#obj_get_next_with_same_behavior_id)
- - [obj_get_next_with_same_behavior_id_and_field_s32](functions-6.md#obj_get_next_with_same_behavior_id_and_field_s32)
- - [obj_get_next_with_same_behavior_id_and_field_f32](functions-6.md#obj_get_next_with_same_behavior_id_and_field_f32)
- - [obj_get_nearest_object_with_behavior_id](functions-6.md#obj_get_nearest_object_with_behavior_id)
- - [obj_count_objects_with_behavior_id](functions-6.md#obj_count_objects_with_behavior_id)
- - [obj_get_collided_object](functions-6.md#obj_get_collided_object)
- - [obj_get_field_u32](functions-6.md#obj_get_field_u32)
- - [obj_get_field_s32](functions-6.md#obj_get_field_s32)
- - [obj_get_field_f32](functions-6.md#obj_get_field_f32)
- - [obj_get_field_s16](functions-6.md#obj_get_field_s16)
- - [obj_set_field_u32](functions-6.md#obj_set_field_u32)
- - [obj_set_field_s32](functions-6.md#obj_set_field_s32)
- - [obj_set_field_f32](functions-6.md#obj_set_field_f32)
- - [obj_set_field_s16](functions-6.md#obj_set_field_s16)
- - [obj_get_temp_spawn_particles_info](functions-6.md#obj_get_temp_spawn_particles_info)
- - [get_temp_object_hitbox](functions-6.md#get_temp_object_hitbox)
- - [obj_is_attackable](functions-6.md#obj_is_attackable)
- - [obj_is_breakable_object](functions-6.md#obj_is_breakable_object)
- - [obj_is_bully](functions-6.md#obj_is_bully)
- - [obj_is_coin](functions-6.md#obj_is_coin)
- - [obj_is_exclamation_box](functions-6.md#obj_is_exclamation_box)
- - [obj_is_grabbable](functions-6.md#obj_is_grabbable)
- - [obj_is_mushroom_1up](functions-6.md#obj_is_mushroom_1up)
- - [obj_is_secret](functions-6.md#obj_is_secret)
- - [obj_is_valid_for_interaction](functions-6.md#obj_is_valid_for_interaction)
- - [obj_check_hitbox_overlap](functions-6.md#obj_check_hitbox_overlap)
- - [obj_check_overlap_with_hitbox_params](functions-6.md#obj_check_overlap_with_hitbox_params)
- - [obj_set_vel](functions-6.md#obj_set_vel)
- - [obj_move_xyz](functions-6.md#obj_move_xyz)
- - [set_whirlpools](functions-6.md#set_whirlpools)
+ - [spawn_sync_object](functions-7.md#spawn_sync_object)
+ - [spawn_non_sync_object](functions-7.md#spawn_non_sync_object)
+ - [obj_has_behavior_id](functions-7.md#obj_has_behavior_id)
+ - [obj_has_model_extended](functions-7.md#obj_has_model_extended)
+ - [obj_get_model_id_extended](functions-7.md#obj_get_model_id_extended)
+ - [obj_set_model_extended](functions-7.md#obj_set_model_extended)
+ - [get_trajectory](functions-7.md#get_trajectory)
+ - [geo_get_current_object](functions-7.md#geo_get_current_object)
+ - [get_current_object](functions-7.md#get_current_object)
+ - [get_dialog_object](functions-7.md#get_dialog_object)
+ - [get_cutscene_focus](functions-7.md#get_cutscene_focus)
+ - [get_secondary_camera_focus](functions-7.md#get_secondary_camera_focus)
+ - [set_cutscene_focus](functions-7.md#set_cutscene_focus)
+ - [set_secondary_camera_focus](functions-7.md#set_secondary_camera_focus)
+ - [obj_get_first](functions-7.md#obj_get_first)
+ - [obj_get_first_with_behavior_id](functions-7.md#obj_get_first_with_behavior_id)
+ - [obj_get_first_with_behavior_id_and_field_s32](functions-7.md#obj_get_first_with_behavior_id_and_field_s32)
+ - [obj_get_first_with_behavior_id_and_field_f32](functions-7.md#obj_get_first_with_behavior_id_and_field_f32)
+ - [obj_get_next](functions-7.md#obj_get_next)
+ - [obj_get_next_with_same_behavior_id](functions-7.md#obj_get_next_with_same_behavior_id)
+ - [obj_get_next_with_same_behavior_id_and_field_s32](functions-7.md#obj_get_next_with_same_behavior_id_and_field_s32)
+ - [obj_get_next_with_same_behavior_id_and_field_f32](functions-7.md#obj_get_next_with_same_behavior_id_and_field_f32)
+ - [obj_get_nearest_object_with_behavior_id](functions-7.md#obj_get_nearest_object_with_behavior_id)
+ - [obj_count_objects_with_behavior_id](functions-7.md#obj_count_objects_with_behavior_id)
+ - [obj_get_collided_object](functions-7.md#obj_get_collided_object)
+ - [obj_get_field_u32](functions-7.md#obj_get_field_u32)
+ - [obj_get_field_s32](functions-7.md#obj_get_field_s32)
+ - [obj_get_field_f32](functions-7.md#obj_get_field_f32)
+ - [obj_get_field_s16](functions-7.md#obj_get_field_s16)
+ - [obj_set_field_u32](functions-7.md#obj_set_field_u32)
+ - [obj_set_field_s32](functions-7.md#obj_set_field_s32)
+ - [obj_set_field_f32](functions-7.md#obj_set_field_f32)
+ - [obj_set_field_s16](functions-7.md#obj_set_field_s16)
+ - [obj_get_temp_spawn_particles_info](functions-7.md#obj_get_temp_spawn_particles_info)
+ - [get_temp_object_hitbox](functions-7.md#get_temp_object_hitbox)
+ - [obj_is_attackable](functions-7.md#obj_is_attackable)
+ - [obj_is_breakable_object](functions-7.md#obj_is_breakable_object)
+ - [obj_is_bully](functions-7.md#obj_is_bully)
+ - [obj_is_coin](functions-7.md#obj_is_coin)
+ - [obj_is_exclamation_box](functions-7.md#obj_is_exclamation_box)
+ - [obj_is_grabbable](functions-7.md#obj_is_grabbable)
+ - [obj_is_mushroom_1up](functions-7.md#obj_is_mushroom_1up)
+ - [obj_is_secret](functions-7.md#obj_is_secret)
+ - [obj_is_valid_for_interaction](functions-7.md#obj_is_valid_for_interaction)
+ - [obj_check_hitbox_overlap](functions-7.md#obj_check_hitbox_overlap)
+ - [obj_check_overlap_with_hitbox_params](functions-7.md#obj_check_overlap_with_hitbox_params)
+ - [obj_set_vel](functions-7.md#obj_set_vel)
+ - [obj_move_xyz](functions-7.md#obj_move_xyz)
+ - [set_whirlpools](functions-7.md#set_whirlpools)
- smlua_text_utils.h
- - [smlua_text_utils_reset_all](functions-6.md#smlua_text_utils_reset_all)
- - [smlua_text_utils_dialog_get](functions-6.md#smlua_text_utils_dialog_get)
- - [smlua_text_utils_dialog_replace](functions-6.md#smlua_text_utils_dialog_replace)
- - [smlua_text_utils_dialog_restore](functions-6.md#smlua_text_utils_dialog_restore)
- - [smlua_text_utils_dialog_is_replaced](functions-6.md#smlua_text_utils_dialog_is_replaced)
- - [smlua_text_utils_allocate_dialog](functions-6.md#smlua_text_utils_allocate_dialog)
- - [smlua_text_utils_course_acts_replace](functions-6.md#smlua_text_utils_course_acts_replace)
- - [smlua_text_utils_secret_star_replace](functions-6.md#smlua_text_utils_secret_star_replace)
- - [smlua_text_utils_course_name_replace](functions-6.md#smlua_text_utils_course_name_replace)
- - [smlua_text_utils_course_name_get](functions-6.md#smlua_text_utils_course_name_get)
- - [smlua_text_utils_course_name_mod_index](functions-6.md#smlua_text_utils_course_name_mod_index)
- - [smlua_text_utils_course_name_reset](functions-6.md#smlua_text_utils_course_name_reset)
- - [smlua_text_utils_act_name_replace](functions-6.md#smlua_text_utils_act_name_replace)
- - [smlua_text_utils_act_name_get](functions-6.md#smlua_text_utils_act_name_get)
- - [smlua_text_utils_act_name_mod_index](functions-6.md#smlua_text_utils_act_name_mod_index)
- - [smlua_text_utils_act_name_reset](functions-6.md#smlua_text_utils_act_name_reset)
- - [smlua_text_utils_castle_secret_stars_replace](functions-6.md#smlua_text_utils_castle_secret_stars_replace)
- - [smlua_text_utils_castle_secret_stars_get](functions-6.md#smlua_text_utils_castle_secret_stars_get)
- - [smlua_text_utils_castle_secret_stars_mod_index](functions-6.md#smlua_text_utils_castle_secret_stars_mod_index)
- - [smlua_text_utils_castle_secret_stars_reset](functions-6.md#smlua_text_utils_castle_secret_stars_reset)
- - [smlua_text_utils_extra_text_replace](functions-6.md#smlua_text_utils_extra_text_replace)
- - [smlua_text_utils_extra_text_get](functions-6.md#smlua_text_utils_extra_text_get)
- - [smlua_text_utils_extra_text_mod_index](functions-6.md#smlua_text_utils_extra_text_mod_index)
- - [smlua_text_utils_extra_text_reset](functions-6.md#smlua_text_utils_extra_text_reset)
- - [smlua_text_utils_get_language](functions-6.md#smlua_text_utils_get_language)
+ - [smlua_text_utils_reset_all](functions-7.md#smlua_text_utils_reset_all)
+ - [smlua_text_utils_dialog_get](functions-7.md#smlua_text_utils_dialog_get)
+ - [smlua_text_utils_dialog_replace](functions-7.md#smlua_text_utils_dialog_replace)
+ - [smlua_text_utils_dialog_restore](functions-7.md#smlua_text_utils_dialog_restore)
+ - [smlua_text_utils_dialog_is_replaced](functions-7.md#smlua_text_utils_dialog_is_replaced)
+ - [smlua_text_utils_allocate_dialog](functions-7.md#smlua_text_utils_allocate_dialog)
+ - [smlua_text_utils_course_acts_replace](functions-7.md#smlua_text_utils_course_acts_replace)
+ - [smlua_text_utils_secret_star_replace](functions-7.md#smlua_text_utils_secret_star_replace)
+ - [smlua_text_utils_course_name_replace](functions-7.md#smlua_text_utils_course_name_replace)
+ - [smlua_text_utils_course_name_get](functions-7.md#smlua_text_utils_course_name_get)
+ - [smlua_text_utils_course_name_mod_index](functions-7.md#smlua_text_utils_course_name_mod_index)
+ - [smlua_text_utils_course_name_reset](functions-7.md#smlua_text_utils_course_name_reset)
+ - [smlua_text_utils_act_name_replace](functions-7.md#smlua_text_utils_act_name_replace)
+ - [smlua_text_utils_act_name_get](functions-7.md#smlua_text_utils_act_name_get)
+ - [smlua_text_utils_act_name_mod_index](functions-7.md#smlua_text_utils_act_name_mod_index)
+ - [smlua_text_utils_act_name_reset](functions-7.md#smlua_text_utils_act_name_reset)
+ - [smlua_text_utils_castle_secret_stars_replace](functions-7.md#smlua_text_utils_castle_secret_stars_replace)
+ - [smlua_text_utils_castle_secret_stars_get](functions-7.md#smlua_text_utils_castle_secret_stars_get)
+ - [smlua_text_utils_castle_secret_stars_mod_index](functions-7.md#smlua_text_utils_castle_secret_stars_mod_index)
+ - [smlua_text_utils_castle_secret_stars_reset](functions-7.md#smlua_text_utils_castle_secret_stars_reset)
+ - [smlua_text_utils_extra_text_replace](functions-7.md#smlua_text_utils_extra_text_replace)
+ - [smlua_text_utils_extra_text_get](functions-7.md#smlua_text_utils_extra_text_get)
+ - [smlua_text_utils_extra_text_mod_index](functions-7.md#smlua_text_utils_extra_text_mod_index)
+ - [smlua_text_utils_extra_text_reset](functions-7.md#smlua_text_utils_extra_text_reset)
+ - [smlua_text_utils_get_language](functions-7.md#smlua_text_utils_get_language)
- sound_init.h
- - [reset_volume](functions-6.md#reset_volume)
- - [raise_background_noise](functions-6.md#raise_background_noise)
- - [lower_background_noise](functions-6.md#lower_background_noise)
- - [disable_background_sound](functions-6.md#disable_background_sound)
- - [enable_background_sound](functions-6.md#enable_background_sound)
- - [play_menu_sounds](functions-6.md#play_menu_sounds)
- - [play_painting_eject_sound](functions-6.md#play_painting_eject_sound)
- - [play_infinite_stairs_music](functions-6.md#play_infinite_stairs_music)
- - [set_background_music](functions-6.md#set_background_music)
- - [fadeout_music](functions-6.md#fadeout_music)
- - [fadeout_level_music](functions-6.md#fadeout_level_music)
- - [play_cutscene_music](functions-6.md#play_cutscene_music)
- - [play_shell_music](functions-6.md#play_shell_music)
- - [stop_shell_music](functions-6.md#stop_shell_music)
- - [play_cap_music](functions-6.md#play_cap_music)
- - [fadeout_cap_music](functions-6.md#fadeout_cap_music)
- - [stop_cap_music](functions-6.md#stop_cap_music)
+ - [reset_volume](functions-7.md#reset_volume)
+ - [raise_background_noise](functions-7.md#raise_background_noise)
+ - [lower_background_noise](functions-7.md#lower_background_noise)
+ - [disable_background_sound](functions-7.md#disable_background_sound)
+ - [enable_background_sound](functions-7.md#enable_background_sound)
+ - [play_menu_sounds](functions-7.md#play_menu_sounds)
+ - [play_painting_eject_sound](functions-7.md#play_painting_eject_sound)
+ - [play_infinite_stairs_music](functions-7.md#play_infinite_stairs_music)
+ - [set_background_music](functions-7.md#set_background_music)
+ - [fadeout_music](functions-7.md#fadeout_music)
+ - [fadeout_level_music](functions-7.md#fadeout_level_music)
+ - [play_cutscene_music](functions-7.md#play_cutscene_music)
+ - [play_shell_music](functions-7.md#play_shell_music)
+ - [stop_shell_music](functions-7.md#stop_shell_music)
+ - [play_cap_music](functions-7.md#play_cap_music)
+ - [fadeout_cap_music](functions-7.md#fadeout_cap_music)
+ - [stop_cap_music](functions-7.md#stop_cap_music)
- spawn_sound.h
- - [cur_obj_play_sound_1](functions-6.md#cur_obj_play_sound_1)
- - [cur_obj_play_sound_2](functions-6.md#cur_obj_play_sound_2)
- - [create_sound_spawner](functions-6.md#create_sound_spawner)
- - [calc_dist_to_volume_range_1](functions-6.md#calc_dist_to_volume_range_1)
- - [calc_dist_to_volume_range_2](functions-6.md#calc_dist_to_volume_range_2)
+ - [cur_obj_play_sound_1](functions-7.md#cur_obj_play_sound_1)
+ - [cur_obj_play_sound_2](functions-7.md#cur_obj_play_sound_2)
+ - [create_sound_spawner](functions-7.md#create_sound_spawner)
+ - [calc_dist_to_volume_range_1](functions-7.md#calc_dist_to_volume_range_1)
+ - [calc_dist_to_volume_range_2](functions-7.md#calc_dist_to_volume_range_2)
- surface_collision.h
- - [find_wall_collisions](functions-6.md#find_wall_collisions)
- - [find_ceil_height](functions-6.md#find_ceil_height)
- - [find_floor_height](functions-6.md#find_floor_height)
- - [find_water_level](functions-6.md#find_water_level)
- - [find_poison_gas_level](functions-6.md#find_poison_gas_level)
- - [set_find_wall_direction](functions-6.md#set_find_wall_direction)
- - [closest_point_to_triangle](functions-6.md#closest_point_to_triangle)
+ - [find_wall_collisions](functions-7.md#find_wall_collisions)
+ - [find_ceil_height](functions-7.md#find_ceil_height)
+ - [find_floor_height](functions-7.md#find_floor_height)
+ - [find_water_level](functions-7.md#find_water_level)
+ - [find_poison_gas_level](functions-7.md#find_poison_gas_level)
+ - [set_find_wall_direction](functions-7.md#set_find_wall_direction)
+ - [closest_point_to_triangle](functions-7.md#closest_point_to_triangle)
- surface_load.h
- - [load_object_collision_model](functions-6.md#load_object_collision_model)
- - [obj_get_surface_from_index](functions-6.md#obj_get_surface_from_index)
- - [surface_has_force](functions-6.md#surface_has_force)
+ - [load_object_collision_model](functions-7.md#load_object_collision_model)
+ - [load_static_object_collision](functions-7.md#load_static_object_collision)
+ - [toggle_static_object_collision](functions-7.md#toggle_static_object_collision)
+ - [get_static_object_surface](functions-7.md#get_static_object_surface)
+ - [obj_get_surface_from_index](functions-7.md#obj_get_surface_from_index)
+ - [surface_has_force](functions-7.md#surface_has_force)
diff --git a/docs/lua/guides/lighting-engine.md b/docs/lua/guides/lighting-engine.md
index 54c5963cf..1805a4201 100644
--- a/docs/lua/guides/lighting-engine.md
+++ b/docs/lua/guides/lighting-engine.md
@@ -1,3 +1,5 @@
+## [:rewind: Lua Reference](../lua.md)
+
# How to use the Lighting Engine
## Section 1: Preparation
diff --git a/docs/lua/guides/mario-state.md b/docs/lua/guides/mario-state.md
index 7b215e650..f24cd0dd0 100644
--- a/docs/lua/guides/mario-state.md
+++ b/docs/lua/guides/mario-state.md
@@ -1,3 +1,5 @@
+## [:rewind: Lua Reference](../lua.md)
+
# How to use `gMarioStates`
## Section 1: What is `gMarioStates`?
diff --git a/docs/lua/guides/modfs.md b/docs/lua/guides/modfs.md
new file mode 100644
index 000000000..41be978bb
--- /dev/null
+++ b/docs/lua/guides/modfs.md
@@ -0,0 +1,272 @@
+## [:rewind: Lua Reference](../lua.md)
+
+# ModFS
+
+`ModFS` enables a small, sandboxed file system for mods. It allows to store and retrieve binary and text files, no matter their content.
+Each mod has its own file system, and can allow other mods to read its files.
+
+
+
+## Specs
+
+### File system
+
+Each ModFS file system:
+- Has a maximum size of **32 MB** (`MOD_FS_MAX_SIZE`). Files can be any size, as long as the cumulative sum of file sizes doesn't exceed this limit.
+- Can store at most **512 files** (`MOD_FS_MAX_FILES`).
+- Is stored on disk as a `.modfs` file, which is a ZIP file, containing all files written in it.
+
+The ModFS files are located in the `sav` directory at the usual save file location:
+- Windows: `%appdata%/sm64coopdx`
+- Linux: `~/.local/share/sm64coopdx`
+- MacOS: `~/Library/Application Support/sm64coopdx`
+
+### Files
+
+- The maximum filepath length is **256 characters** (`MOD_FS_MAX_PATH`), including the NUL terminator.
+- Filepaths have the following restrictions:
+ - Cannot start, end or have two or more consecutive `/`
+ - Can contain only valid ASCII characters, no `*` or `\`
+ - Cannot be called `properties.json` (this name is reserved for ModFS internal properties)
+ - Only the following extensions (and extension-less files) are allowed:
+ - text: `.txt`, `.json`, `.ini`, `.sav`
+ - actors: `.bin`, `.col`
+ - behaviors: `.bhv`
+ - textures: `.tex`, `.png`
+ - levels: `.lvl`
+ - audio: `.m64`, `.aiff`, `.mp3`, `.ogg`
+
+
+
+## [`ModFs`](../structs.md#ModFs)
+
+The object holding the file system of the mod.
+
+### Fields
+
+All fields are immutable.
+
+| Name | Type |
+| ----- | ---- |
+| mod | [Mod](../structs.md#Mod) |
+| modPath | `string` |
+| numFiles | `integer` |
+| totalSize | `integer` |
+| isPublic | `boolean` |
+
+Fields can be accessed in Lua with the dot `.` character:
+```lua
+print("The ModFS " .. modFs.modPath .. " contains " .. modFs.numFiles .. " files.")
+```
+
+### Methods
+
+| Name | Reference |
+| ---- | --------- |
+| get_filename | [`mod_fs_get_filename`](../functions-5.md#mod_fs_get_filename) |
+| get_file | [`mod_fs_get_file`](../functions-5.md#mod_fs_get_file) |
+| create_file | [`mod_fs_create_file`](../functions-5.md#mod_fs_create_file) |
+| move_file | [`mod_fs_move_file`](../functions-5.md#mod_fs_move_file) |
+| copy_file | [`mod_fs_copy_file`](../functions-5.md#mod_fs_copy_file) |
+| delete_file | [`mod_fs_delete_file`](../functions-5.md#mod_fs_delete_file) |
+| clear | [`mod_fs_clear`](../functions-5.md#mod_fs_clear) |
+| save | [`mod_fs_save`](../functions-5.md#mod_fs_save) |
+| delete | [`mod_fs_delete`](../functions-5.md#mod_fs_delete) |
+| set_public | [`mod_fs_set_public`](../functions-5.md#mod_fs_set_public) |
+
+Methods can be called in Lua with the colon `:` character:
+```lua
+print("The first file of ModFS " .. modFs.modPath .. " is named " .. modFs:get_filename(0) .. ".")
+```
+
+
+
+## [`ModFsFile`](../structs.md#ModFsFile)
+
+A handle to a ModFS file.
+
+### Fields
+
+All fields are immutable.
+
+| Field | Type |
+| ----- | ---- |
+| modFs | [ModFs](../structs.md#ModFs) |
+| filepath | `string` |
+| size | `integer` |
+| offset | `integer` |
+| isText | `boolean` |
+| isPublic | `boolean` |
+
+Fields can be accessed in Lua with the dot `.` character:
+```lua
+print("The ModFS file " .. file.filepath .. " is " .. file.size .. " bytes long.")
+```
+
+### Methods
+
+| Name | Reference |
+| ---- | --------- |
+| read_bool | [`mod_fs_file_read_bool`](../functions-5.md#mod_fs_file_read_bool) |
+| read_integer | [`mod_fs_file_read_integer`](../functions-5.md#mod_fs_file_read_integer) |
+| read_number | [`mod_fs_file_read_number`](../functions-5.md#mod_fs_file_read_number) |
+| read_bytes | [`mod_fs_file_read_bytes`](../functions-5.md#mod_fs_file_read_bytes) |
+| read_string | [`mod_fs_file_read_string`](../functions-5.md#mod_fs_file_read_string) |
+| read_line | [`mod_fs_file_read_line`](../functions-5.md#mod_fs_file_read_line) |
+| write_bool | [`mod_fs_file_write_bool`](../functions-5.md#mod_fs_file_write_bool) |
+| write_integer | [`mod_fs_file_write_integer`](../functions-5.md#mod_fs_file_write_integer) |
+| write_number | [`mod_fs_file_write_number`](../functions-5.md#mod_fs_file_write_number) |
+| write_bytes | [`mod_fs_file_write_bytes`](../functions-5.md#mod_fs_file_write_bytes) |
+| write_string | [`mod_fs_file_write_string`](../functions-5.md#mod_fs_file_write_string) |
+| write_line | [`mod_fs_file_write_line`](../functions-5.md#mod_fs_file_write_line) |
+| seek | [`mod_fs_file_seek`](../functions-5.md#mod_fs_file_seek) |
+| rewind | [`mod_fs_file_rewind`](../functions-5.md#mod_fs_file_rewind) |
+| is_eof | [`mod_fs_file_is_eof`](../functions-5.md#mod_fs_file_is_eof) |
+| fill | [`mod_fs_file_fill`](../functions-5.md#mod_fs_file_fill) |
+| erase | [`mod_fs_file_erase`](../functions-5.md#mod_fs_file_erase) |
+| set_text_mode | [`mod_fs_file_set_text_mode`](../functions-5.md#mod_fs_file_set_text_mode) |
+| set_public | [`mod_fs_file_set_public`](../functions-5.md#mod_fs_file_set_public) |
+
+Methods can be called in Lua with the colon `:` character:
+```lua
+file:erase(file.size)
+print("The ModFS file " .. file.filepath .. " is now empty.")
+```
+
+
+
+## Error handling
+
+All errors coming from ModFS functions are not blocking. However, they appear in the console and raise the "Mod has script errors" message.
+
+- The function [`mod_fs_hide_errors`](../functions-5.md#mod_fs_hide_errors) can suppress the ModFS errors from the console.
+- Use the function [`mod_fs_get_last_error`](../functions-5.md#mod_fs_get_last_error) to retrieve the last error raised by ModFS. This function always return an error message if an error occurred, even if errors are hidden.
+
+
+
+## Usage with other sm64coopdx features
+
+One of the strengths of this feature is its interactions with other existing features of sm64coopdx:
+- Load models with `smlua_model_util_get_id`
+- Load textures with `get_texture_info`
+- Load collisions with `smlua_collision_util_get`
+- Load sequences with `smlua_audio_utils_replace_sequence`
+- Load audio streams with `audio_stream_load`
+- Load audio samples with `audio_sample_load`
+
+These functions can take a **ModFS URI** as argument instead of a resource name.
+Generate a ModFS URI from a `ModFs` object with the following code:
+```lua
+local uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "")
+```
+
+Here are some examples:
+
+```lua
+-- Models
+local custom_geo_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_geo.bin")
+local E_MODEL_CUSTOM = smlua_model_util_get_id(custom_geo_uri)
+
+-- Textures (both PNG and TEX)
+local texture_png_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "texture.png")
+local TEXTURE_PNG = get_texture_info(texture_png_uri)
+local texture_tex_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "texture.tex")
+local TEXTURE_TEX = get_texture_info(texture_tex_uri)
+
+-- Collisions
+local custom_col_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_col.col")
+local COL_CUSTOM = smlua_collision_util_get(custom_col_uri)
+
+-- Sequences
+local custom_m64_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom.m64")
+smlua_audio_utils_replace_sequence(SEQ_LEVEL_GRASS, 0x11, 0x80, custom_m64_uri)
+
+-- Streams
+local custom_stream_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_stream.mp3")
+local custom_stream = audio_stream_load(custom_stream_uri)
+
+-- Samples
+local custom_sample_uri = string.format(MOD_FS_URI_FORMAT, modFs.modPath, "custom_sample.mp3")
+local custom_sample = audio_sample_load(custom_sample_uri)
+```
+
+
+
+## Good practices
+
+### Always valid `ModFs` object
+
+Use the following piece of code to always retrieve a valid `ModFs` object:
+```lua
+local modFs = mod_fs_get() or mod_fs_create()
+```
+If the ModFS for the current mod doesn't exist, it will create one.
+
+
+
+### Always valid `ModFsFile` object
+
+Use the following piece of code to always retrieve a valid `ModFsFile` object:
+```lua
+local file = modFs:get_file("myfile.txt") or modFs:create_file("myfile.txt", true)
+```
+Like previously, if the file doesn't exist, it will create one.
+
+To make sure the file is empty when requested, add the following line to clear the existing file content.
+```lua
+file:erase(file.size)
+```
+
+
+
+### Correctly initialize a file
+
+The `get_file` method of a `ModFs` object opens a file only if the file is not loaded yet. Subsequent calls with the same filename will return the file handle without resetting its offset or mode.
+For example, one function could write to a file while another could read from the same file, so it's better to set the appropriate file offset and mode when it's needed before starting reading/writing:
+```lua
+local file = modFs:get_file("myfile.txt")
+file:set_text_mode(true) -- Set mode to text
+file:rewind() -- Reset offset to the beginning of the file
+```
+
+
+
+### Methods over functions
+
+Always use `ModFs` and `ModFsFile` objects methods over regular functions.
+It's more clear that way and helps to reduce errors:
+```lua
+-- Don't
+local file = mod_fs_create_file(modFs, "myfile.txt", true)
+
+-- Do
+local file = modFs:create_file("myfile.txt", true)
+```
+```lua
+-- Don't
+mod_fs_file_write_string(file, "some text")
+
+-- Do
+file:write_string("some text")
+```
+
+
+
+### Handle possible failures
+
+In addition to error messages that can be retrieved with [`mod_fs_get_last_error`](../functions-5.md#mod_fs_get_last_error), almost all ModFS functions have a boolean return value indicating if the function succeeded or failed.
+```lua
+if not modFs:delete_file("somefile") then
+ print(mod_fs_get_last_error())
+end
+```
+
+
+
+### Don't forget to save
+
+ModFS are not saved automatically when writing to files.
+The mod has to explicitly call the method `save` to save its ModFS on the disk.
+```lua
+modFs:save()
+```
diff --git a/docs/lua/guides/object-lists.md b/docs/lua/guides/object-lists.md
index 3a9ab5fbe..1d8a77ed8 100644
--- a/docs/lua/guides/object-lists.md
+++ b/docs/lua/guides/object-lists.md
@@ -1,3 +1,5 @@
+## [:rewind: Lua Reference](../lua.md)
+
# Every Behavior's Object List
| Behavior | Object List |
diff --git a/docs/lua/lua.md b/docs/lua/lua.md
index 05d165769..553659b33 100644
--- a/docs/lua/lua.md
+++ b/docs/lua/lua.md
@@ -34,6 +34,8 @@ Save file locations:
- [Hooks](guides/hooks.md)
- [gMarioStates](guides/mario-state.md)
- [Behavior Object Lists](guides/object-lists.md)
+- [Lighting Engine](guides/lighting-engine.md)
+- [ModFS](guides/modfs.md)
## Important notes on player indices
@@ -69,7 +71,11 @@ All of this is a holdover from when there were only two players. It was a reason
- [Custom HUD Texture](examples/custom-hud-texture)
- [Custom Audio Test](examples/audio-test)
- [Custom Texture Overriding](examples/texture-override)
+- [Custom Animations (DynOS)](examples/custom-animations-dynos)
+- [Custom Animations (Lua)](examples/custom-animations-lua)
- [Bytestring Packet Example](examples/bytestring-packet-example.lua)
+- [Gfx/Vtx Demo](examples/gfx-vtx-demo)
+- [Lighting Engine Demo](examples/lighting-engine-demo)
## Example Lua mods (large)
- [Hide and Seek Gamemode](../../mods/hide-and-seek.lua)
diff --git a/docs/lua/structs.md b/docs/lua/structs.md
index e603068cb..e11caf9f4 100644
--- a/docs/lua/structs.md
+++ b/docs/lua/structs.md
@@ -105,6 +105,7 @@
- [SpawnParticlesInfo](#SpawnParticlesInfo)
- [StarPositions](#StarPositions)
- [StarsNeededForDialog](#StarsNeededForDialog)
+- [StaticObjectCollision](#StaticObjectCollision)
- [Surface](#Surface)
- [TextureInfo](#TextureInfo)
- [TransitionInfo](#TransitionInfo)
@@ -1955,7 +1956,7 @@
| Field | Type | Access |
| ----- | ---- | ------ |
-| file | [ModFile](structs.md#ModFile) | |
+| filepath | `string` | read-only |
| isStream | `boolean` | read-only |
| baseVolume | `number` | |
| loaded | `boolean` | read-only |
@@ -2001,6 +2002,21 @@
| totalSize | `integer` | read-only |
| isPublic | `boolean` | read-only |
+**Functions:**
+
+| Name | Reference |
+| ---- | --------- |
+| get_filename | [`mod_fs_get_filename`](functions-5.md#mod_fs_get_filename) |
+| get_file | [`mod_fs_get_file`](functions-5.md#mod_fs_get_file) |
+| create_file | [`mod_fs_create_file`](functions-5.md#mod_fs_create_file) |
+| move_file | [`mod_fs_move_file`](functions-5.md#mod_fs_move_file) |
+| copy_file | [`mod_fs_copy_file`](functions-5.md#mod_fs_copy_file) |
+| delete_file | [`mod_fs_delete_file`](functions-5.md#mod_fs_delete_file) |
+| clear | [`mod_fs_clear`](functions-5.md#mod_fs_clear) |
+| save | [`mod_fs_save`](functions-5.md#mod_fs_save) |
+| delete | [`mod_fs_delete`](functions-5.md#mod_fs_delete) |
+| set_public | [`mod_fs_set_public`](functions-5.md#mod_fs_set_public) |
+
[:arrow_up_small:](#)
@@ -2016,6 +2032,30 @@
| isText | `boolean` | read-only |
| isPublic | `boolean` | read-only |
+**Functions:**
+
+| Name | Reference |
+| ---- | --------- |
+| read_bool | [`mod_fs_file_read_bool`](functions-5.md#mod_fs_file_read_bool) |
+| read_integer | [`mod_fs_file_read_integer`](functions-5.md#mod_fs_file_read_integer) |
+| read_number | [`mod_fs_file_read_number`](functions-5.md#mod_fs_file_read_number) |
+| read_bytes | [`mod_fs_file_read_bytes`](functions-5.md#mod_fs_file_read_bytes) |
+| read_string | [`mod_fs_file_read_string`](functions-5.md#mod_fs_file_read_string) |
+| read_line | [`mod_fs_file_read_line`](functions-5.md#mod_fs_file_read_line) |
+| write_bool | [`mod_fs_file_write_bool`](functions-5.md#mod_fs_file_write_bool) |
+| write_integer | [`mod_fs_file_write_integer`](functions-5.md#mod_fs_file_write_integer) |
+| write_number | [`mod_fs_file_write_number`](functions-5.md#mod_fs_file_write_number) |
+| write_bytes | [`mod_fs_file_write_bytes`](functions-5.md#mod_fs_file_write_bytes) |
+| write_string | [`mod_fs_file_write_string`](functions-5.md#mod_fs_file_write_string) |
+| write_line | [`mod_fs_file_write_line`](functions-5.md#mod_fs_file_write_line) |
+| seek | [`mod_fs_file_seek`](functions-5.md#mod_fs_file_seek) |
+| rewind | [`mod_fs_file_rewind`](functions-5.md#mod_fs_file_rewind) |
+| is_eof | [`mod_fs_file_is_eof`](functions-5.md#mod_fs_file_is_eof) |
+| fill | [`mod_fs_file_fill`](functions-5.md#mod_fs_file_fill) |
+| erase | [`mod_fs_file_erase`](functions-5.md#mod_fs_file_erase) |
+| set_text_mode | [`mod_fs_file_set_text_mode`](functions-5.md#mod_fs_file_set_text_mode) |
+| set_public | [`mod_fs_file_set_public`](functions-5.md#mod_fs_file_set_public) |
+
[:arrow_up_small:](#)
@@ -2947,10 +2987,9 @@
| rippleTimer | `number` | |
| rippleX | `number` | |
| rippleY | `number` | |
-| normalDisplayList | `Pointer` <`Gfx`> | read-only |
+| textureArray | `Array` <`Pointer` <`Texture`>> | read-only |
| textureWidth | `integer` | read-only |
| textureHeight | `integer` | read-only |
-| rippleDisplayList | `Pointer` <`Gfx`> | read-only |
| rippleTrigger | `integer` | |
| alpha | `integer` | |
| marioWasUnder | `integer` | |
@@ -3211,6 +3250,17 @@
+## [StaticObjectCollision](#StaticObjectCollision)
+
+| Field | Type | Access |
+| ----- | ---- | ------ |
+| index | `integer` | read-only |
+| length | `integer` | read-only |
+
+[:arrow_up_small:](#)
+
+
+
## [Surface](#Surface)
| Field | Type | Access |
@@ -3240,7 +3290,7 @@
| Field | Type | Access |
| ----- | ---- | ------ |
-| texture | `Pointer` <`integer`> | read-only |
+| texture | `Pointer` <`Texture`> | read-only |
| name | `string` | read-only |
| width | `integer` | read-only |
| height | `integer` | read-only |
diff --git a/include/PR/gbi_extension.h b/include/PR/gbi_extension.h
index 1ea2d51b7..1aba0aa61 100644
--- a/include/PR/gbi_extension.h
+++ b/include/PR/gbi_extension.h
@@ -7,6 +7,9 @@
#define G_LIGHT_MAP_EXT 0x00000800
#define G_LIGHTING_ENGINE_EXT 0x00004000
#define G_PACKED_NORMALS_EXT 0x00000080
+#define G_CULL_INVERT_EXT 0x00000100
+#define G_FRESNEL_COLOR_EXT 0x00000040
+#define G_FRESNEL_ALPHA_EXT 0x00400000
//////////
// DJUI //
@@ -118,3 +121,50 @@
(_SHIFTL(G_PPARTTOCOLOR, 24, 8)) | (_SHIFTL(color, 16, 8)), \
((2 * ((part) + 1)) + 1 + offset) \
}}
+
+////////////////////
+//// G_MOVEWORD ////
+////////////////////
+
+#define G_MW_FX 0x00 /* replaces G_MW_MATRIX which is no longer supported */
+#define G_MWO_FRESNEL 0x0C
+
+/**
+ * Fresnel - Feature suggested by thecozies
+ * Enabled with the G_FRESNEL bit in geometry mode.
+ * The dot product between a vertex normal and the vector from the vertex to the
+ * camera is computed. The offset and scale here convert this to a shade alpha
+ * value. This is useful for making surfaces fade between transparent when
+ * viewed straight-on and opaque when viewed at a large angle, or for applying a
+ * fake "outline" around the border of meshes.
+ *
+ * If using Fresnel, you need to set the camera world position whenever you set
+ * the VP matrix, viewport, etc. See SPCameraWorld.
+ *
+ * The RSP does:
+ * s16 dotProduct = dot(vertex normal, camera pos - vertex pos);
+ * dotProduct = abs(dotProduct); // 0 = points to side, 7FFF = points at or away
+ * s32 factor = ((scale * dotProduct) >> 15) + offset;
+ * s16 result = clamp(factor << 8, 0, 7FFF);
+ * color_or_alpha = result >> 7;
+ *
+ * At dotMax, color_or_alpha = FF, result = 7F80, factor = 7F
+ * At dotMin, color_or_alpha = 00, result = 0, factor = 0
+ * 7F = ((scale * dotMax) >> 15) + offset
+ * 00 = ((scale * dotMin) >> 15) + offset
+ * Subtract: 7F = (scale * (dotMax - dotMin)) >> 15
+ * 3F8000 = scale * (dotMax - dotMin)
+ * scale = 3F8000 / (dotMax - dotMin) <--
+ * offset = -(((3F8000 / (dotMax - dotMin)) * dotMin) >> 15)
+ * offset = -((7F * dotMin) / (dotMax - dotMin)) <--
+ *
+ * To convert in the opposite direction:
+ * ((7F - offset) << 15) / scale = dotMax
+ * ((00 - offset) << 15) / scale = dotMin
+ */
+#define gSPFresnel(pkt, scale, offset) \
+ gMoveWd(pkt, G_MW_FX, G_MWO_FRESNEL, \
+ (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16)))
+#define gsSPFresnel(scale, offset) \
+ gsMoveWd(G_MW_FX, G_MWO_FRESNEL, \
+ (_SHIFTL((scale), 16, 16) | _SHIFTL((offset), 0, 16)))
diff --git a/include/gfx_symbols.h b/include/gfx_symbols.h
index 0c8801995..a12858e8d 100644
--- a/include/gfx_symbols.h
+++ b/include/gfx_symbols.h
@@ -56,6 +56,7 @@ define_gfx_symbol(gsMoveWd, 3, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GF
define_gfx_symbol(gsSPLoadGeometryMode, 1, false, GFX_PARAM_TYPE_INT);
define_gfx_symbol(gsSPVertexNonGlobal, 3, true, GFX_PARAM_TYPE_VTX, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT);
define_gfx_symbol(gsSPCopyPlayerPartToColor, 3, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT);
+define_gfx_symbol(gsSPFresnel, 2, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT);
define_gfx_symbol_manual(gsSPTexture, 5, false, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT, GFX_PARAM_TYPE_INT);
define_gfx_symbol_manual(gsSPSetGeometryMode, 1, false, GFX_PARAM_TYPE_INT);
diff --git a/include/level_commands.h b/include/level_commands.h
index 659c94425..b0258661c 100644
--- a/include/level_commands.h
+++ b/include/level_commands.h
@@ -30,6 +30,34 @@
#define WHIRLPOOL_COND_BOWSER2_BEATEN 2
#define WHIRLPOOL_COND_AT_LEAST_SECOND_STAR 3
+#define OBJECT_EXT_LUA_MODEL (1 << 0)
+#define OBJECT_EXT_LUA_POS_X (1 << 1)
+#define OBJECT_EXT_LUA_POS_Y (1 << 2)
+#define OBJECT_EXT_LUA_POS_Z (1 << 3)
+#define OBJECT_EXT_LUA_ANGLE_X (1 << 4)
+#define OBJECT_EXT_LUA_ANGLE_Y (1 << 5)
+#define OBJECT_EXT_LUA_ANGLE_Z (1 << 6)
+#define OBJECT_EXT_LUA_BEH_PARAMS (1 << 7)
+#define OBJECT_EXT_LUA_BEHAVIOR (1 << 8)
+#define OBJECT_EXT_LUA_ACTS (1 << 9)
+
+#define OBJECT_EXT_LUA_MODEL_OFFSET(type) (type == 0x3F ? 3 : (type == 0x40 ? 20 : 4))
+#define OBJECT_EXT_LUA_POS_X_OFFSET(type) (type == 0x3F ? 4 : (type == 0x40 ? 4 : 8))
+#define OBJECT_EXT_LUA_POS_Y_OFFSET(type) (type == 0x3F ? 6 : (type == 0x40 ? 6 : 12))
+#define OBJECT_EXT_LUA_POS_Z_OFFSET(type) (type == 0x3F ? 8 : (type == 0x40 ? 8 : 16))
+#define OBJECT_EXT_LUA_ANGLE_X_OFFSET(type) (type == 0x3F ? 10 : (type == 0x40 ? 10 : 20))
+#define OBJECT_EXT_LUA_ANGLE_Y_OFFSET(type) (type == 0x3F ? 12 : (type == 0x40 ? 12 : 24))
+#define OBJECT_EXT_LUA_ANGLE_Z_OFFSET(type) (type == 0x3F ? 14 : (type == 0x40 ? 14 : 28))
+#define OBJECT_EXT_LUA_BEH_PARAMS_OFFSET(type) (type == 0x3F ? 16 : (type == 0x40 ? 16 : 32))
+#define OBJECT_EXT_LUA_BEHAVIOR_OFFSET(type) (type == 0x3F ? 20 : (type == 0x40 ? 24 : 36))
+#define OBJECT_EXT_LUA_ACTS_OFFSET(type) (type == 0x3F ? 2 : (type == 0x40 ? 2 : 40))
+
+#define SHOW_DIALOG_EXT_LUA_INDEX (1 << 0)
+#define SHOW_DIALOG_EXT_LUA_DIALOG (1 << 1)
+
+#define SHOW_DIALOG_EXT_LUA_INDEX_OFFSET(type) (4)
+#define SHOW_DIALOG_EXT_LUA_DIALOG_OFFSET(type) (8)
+
// Head defines
#define REGULAR_FACE 0x0002
#define DIZZY_FACE 0x0003
@@ -324,6 +352,30 @@
CMD_W(arg), \
CMD_PTR(target)
+// This command is used when parameters are Lua variables.
+// The flags parameter describes which parameter is a Lua variable.
+// See OBJECT_EXT_LUA flags at the top of this file.
+#define OBJECT_EXT_LUA_PARAMS(flags, model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, acts) \
+ CMD_BBH(0x43, 0x2C, flags), \
+ CMD_PTR(model), \
+ CMD_PTR(posX), \
+ CMD_PTR(posY), \
+ CMD_PTR(posZ), \
+ CMD_PTR(angleX), \
+ CMD_PTR(angleY), \
+ CMD_PTR(angleZ), \
+ CMD_PTR(behParam), \
+ CMD_PTR(beh), \
+ CMD_PTR(acts)
+
+// This command is used when parameters are Lua variables.
+// The flags parameter describes which parameter is a Lua variable.
+// See SHOW_DIALOG_EXT flags at the top of this file.
+#define SHOW_DIALOG_EXT(flags, index, dialogId) \
+ CMD_BBBB(0x44, 0x0C, flags, 0x00), \
+ CMD_PTR(index), \
+ CMD_PTR(dialogId)
+
// README //
// README //
// README //
diff --git a/include/surface_terrains.h b/include/surface_terrains.h
index 091ed64d4..c43924a5f 100644
--- a/include/surface_terrains.h
+++ b/include/surface_terrains.h
@@ -163,6 +163,7 @@
#define SURFACE_FLAG_DYNAMIC (1 << 0)
#define SURFACE_FLAG_NO_CAM_COLLISION (1 << 1)
+#define SURFACE_FLAG_INTANGIBLE (1 << 2)
#define SURFACE_FLAG_X_PROJECTION (1 << 3)
#define HAZARD_TYPE_LAVA_FLOOR 1
diff --git a/include/types.h b/include/types.h
index 70c697636..53f07d508 100644
--- a/include/types.h
+++ b/include/types.h
@@ -577,7 +577,7 @@ struct MarioState
struct TextureInfo
{
- u8 *texture;
+ Texture *texture;
const char *name;
u32 width;
u32 height;
diff --git a/levels/castle_inside/painting.inc.c b/levels/castle_inside/painting.inc.c
index fac982371..c12f799bc 100644
--- a/levels/castle_inside/painting.inc.c
+++ b/levels/castle_inside/painting.inc.c
@@ -1255,57 +1255,57 @@ static const Gfx inside_castle_seg7_painting_dl_070235B8[] = {
gsSPBranchList(inside_castle_seg7_painting_dl_07023580),
};
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235C0[] = {
- inside_castle_seg7_texture_0700B800, inside_castle_seg7_texture_0700A800,
-};
+#define inside_castle_seg7_painting_textures_070235C0 { \
+ inside_castle_seg7_texture_0700B800, inside_castle_seg7_texture_0700A800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235C8[] = {
- inside_castle_seg7_texture_0700D800, inside_castle_seg7_texture_0700C800,
-};
+#define inside_castle_seg7_painting_textures_070235C8 { \
+ inside_castle_seg7_texture_0700D800, inside_castle_seg7_texture_0700C800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235D0[] = {
- inside_castle_seg7_texture_0700F800, inside_castle_seg7_texture_0700E800,
-};
+#define inside_castle_seg7_painting_textures_070235D0 { \
+ inside_castle_seg7_texture_0700F800, inside_castle_seg7_texture_0700E800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235D8[] = {
- inside_castle_seg7_texture_07011800, inside_castle_seg7_texture_07010800,
-};
+#define inside_castle_seg7_painting_textures_070235D8 { \
+ inside_castle_seg7_texture_07011800, inside_castle_seg7_texture_07010800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235E0[] = {
- inside_castle_seg7_texture_07012800, inside_castle_seg7_texture_07013800,
-};
+#define inside_castle_seg7_painting_textures_070235E0 { \
+ inside_castle_seg7_texture_07012800, inside_castle_seg7_texture_07013800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235E8[] = {
- inside_castle_seg7_texture_07015800, inside_castle_seg7_texture_07014800,
-};
+#define inside_castle_seg7_painting_textures_070235E8 { \
+ inside_castle_seg7_texture_07015800, inside_castle_seg7_texture_07014800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F0[] = {
- inside_castle_seg7_texture_07016800,
-};
+#define inside_castle_seg7_painting_textures_070235F0 { \
+ inside_castle_seg7_texture_07016800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F4[] = {
- inside_castle_seg7_texture_07017000,
-};
+#define inside_castle_seg7_painting_textures_070235F4 { \
+ inside_castle_seg7_texture_07017000, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_070235F8[] = {
- inside_castle_seg7_texture_07018800, inside_castle_seg7_texture_07017800,
-};
+#define inside_castle_seg7_painting_textures_070235F8 { \
+ inside_castle_seg7_texture_07018800, inside_castle_seg7_texture_07017800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023600[] = {
- inside_castle_seg7_texture_0701A800, inside_castle_seg7_texture_07019800,
-};
+#define inside_castle_seg7_painting_textures_07023600 { \
+ inside_castle_seg7_texture_0701A800, inside_castle_seg7_texture_07019800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023608[] = {
- inside_castle_seg7_texture_0701C800, inside_castle_seg7_texture_0701B800,
-};
+#define inside_castle_seg7_painting_textures_07023608 { \
+ inside_castle_seg7_texture_0701C800, inside_castle_seg7_texture_0701B800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023610[] = {
- inside_castle_seg7_texture_0701E800, inside_castle_seg7_texture_0701D800,
-};
+#define inside_castle_seg7_painting_textures_07023610 { \
+ inside_castle_seg7_texture_0701E800, inside_castle_seg7_texture_0701D800, \
+}
-ALIGNED8 const Texture *const inside_castle_seg7_painting_textures_07023618[] = {
- inside_castle_seg7_texture_07020800, inside_castle_seg7_texture_0701F800,
-};
+#define inside_castle_seg7_painting_textures_07023618 { \
+ inside_castle_seg7_texture_07020800, inside_castle_seg7_texture_0701F800, \
+}
// 0x07023620 - 0x07023698
struct Painting bob_painting = {
diff --git a/levels/hmc/areas/1/painting.inc.c b/levels/hmc/areas/1/painting.inc.c
index ebad311eb..871750397 100644
--- a/levels/hmc/areas/1/painting.inc.c
+++ b/levels/hmc/areas/1/painting.inc.c
@@ -505,9 +505,9 @@ static const Gfx hmc_seg7_painting_dl_070254E0[] = {
};
// 0x07025518 - 0x07025594
-const Texture *const hmc_seg7_painting_textures_07025518[] = {
- hmc_seg7_texture_07024CE0,
-};
+#define hmc_seg7_painting_textures_07025518 { \
+ hmc_seg7_texture_07024CE0, \
+}
// 0x0702551C (PaintingData)
struct Painting cotmc_painting = {
diff --git a/levels/ttm/areas/1/painting.inc.c b/levels/ttm/areas/1/painting.inc.c
index fea728990..2ae5d05db 100644
--- a/levels/ttm/areas/1/painting.inc.c
+++ b/levels/ttm/areas/1/painting.inc.c
@@ -537,9 +537,9 @@ static const Gfx ttm_seg7_painting_dl_07012E98[] = {
};
// 0x07012EF8 - 0x07012F78
-ALIGNED8 const Texture *const ttm_seg7_painting_textures_07012EF8[] = {
- ttm_seg7_texture_07004000, ttm_seg7_texture_07003000,
-};
+#define ttm_seg7_painting_textures_07012EF8 { \
+ ttm_seg7_texture_07004000, ttm_seg7_texture_07003000, \
+}
// 0x07012F00 (PaintingData)
struct Painting ttm_slide_painting = {
diff --git a/mods/char-select-the-originals/main.lua b/mods/char-select-the-originals/main.lua
index ff18a8bc5..916691565 100644
--- a/mods/char-select-the-originals/main.lua
+++ b/mods/char-select-the-originals/main.lua
@@ -99,51 +99,95 @@ local PALETTE_FL_WALUIGI = {
-- Sounds --
-local DJ_TOAD_SOUNDS = {
- SOUND_MARIO_YAH_WAH_HOO,
- SOUND_MARIO_HOOHOO,
- SOUND_MARIO_YAHOO,
- SOUND_MARIO_UH,
- SOUND_MARIO_HRMM,
- SOUND_MARIO_WAH2,
- SOUND_MARIO_WHOA,
- SOUND_MARIO_EEUH,
- SOUND_MARIO_ATTACKED,
- SOUND_MARIO_OOOF,
- SOUND_MARIO_OOOF2,
- SOUND_MARIO_HERE_WE_GO,
- SOUND_MARIO_YAWNING,
- SOUND_MARIO_SNORING1,
- SOUND_MARIO_SNORING2,
- SOUND_MARIO_WAAAOOOW,
- SOUND_MARIO_HAHA,
- SOUND_MARIO_HAHA_2,
- SOUND_MARIO_UH2,
- SOUND_MARIO_UH2_2,
- SOUND_MARIO_ON_FIRE,
- SOUND_MARIO_DYING,
- SOUND_MARIO_PANTING_COLD,
- SOUND_MARIO_PANTING,
- SOUND_MARIO_COUGHING1,
- SOUND_MARIO_COUGHING2,
- SOUND_MARIO_COUGHING3,
- SOUND_MARIO_PUNCH_YAH,
- SOUND_MARIO_PUNCH_HOO,
- SOUND_MARIO_MAMA_MIA,
- SOUND_MARIO_GROUND_POUND_WAH,
- SOUND_MARIO_DROWNING,
- SOUND_MARIO_PUNCH_WAH,
- SOUND_MARIO_YAHOO_WAHA_YIPPEE,
- SOUND_MARIO_DOH,
- SOUND_MARIO_GAME_OVER,
- SOUND_MARIO_HELLO,
- SOUND_MARIO_PRESS_START_TO_PLAY,
- SOUND_MARIO_TWIRL_BOUNCE,
- SOUND_MARIO_SNORING3,
- SOUND_MARIO_SO_LONGA_BOWSER,
- SOUND_MARIO_IMA_TIRED,
- SOUND_MARIO_LETS_A_GO,
- SOUND_MARIO_OKEY_DOKEY
+local MARIO_SOUNDS = {
+ [CHAR_SOUND_OKEY_DOKEY] = SOUND_MARIO_OKEY_DOKEY,
+ [CHAR_SOUND_LETS_A_GO] = SOUND_MARIO_LETS_A_GO,
+ [CHAR_SOUND_PUNCH_YAH] = SOUND_MARIO_PUNCH_YAH,
+ [CHAR_SOUND_PUNCH_WAH] = SOUND_MARIO_PUNCH_WAH,
+ [CHAR_SOUND_WAH2] = SOUND_MARIO_WAH2,
+ [CHAR_SOUND_PUNCH_HOO] = SOUND_MARIO_PUNCH_HOO,
+ [CHAR_SOUND_YAH_WAH_HOO] = SOUND_MARIO_YAH_WAH_HOO,
+ [CHAR_SOUND_HOOHOO] = SOUND_MARIO_HOOHOO,
+ [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = SOUND_MARIO_YAHOO_WAHA_YIPPEE,
+ [CHAR_SOUND_UH] = SOUND_MARIO_UH,
+ [CHAR_SOUND_UH2] = SOUND_MARIO_UH2,
+ [CHAR_SOUND_UH2_2] = SOUND_MARIO_UH2_2,
+ [CHAR_SOUND_HAHA] = SOUND_MARIO_HAHA,
+ [CHAR_SOUND_HAHA_2] = SOUND_MARIO_HAHA_2,
+ [CHAR_SOUND_YAHOO] = SOUND_MARIO_YAHOO,
+ [CHAR_SOUND_DOH] = SOUND_MARIO_DOH,
+ [CHAR_SOUND_WHOA] = SOUND_MARIO_WHOA,
+ [CHAR_SOUND_EEUH] = SOUND_MARIO_EEUH,
+ [CHAR_SOUND_WAAAOOOW] = SOUND_MARIO_WAAAOOOW,
+ [CHAR_SOUND_TWIRL_BOUNCE] = SOUND_MARIO_TWIRL_BOUNCE,
+ [CHAR_SOUND_GROUND_POUND_WAH] = SOUND_MARIO_GROUND_POUND_WAH,
+ [CHAR_SOUND_HRMM] = SOUND_MARIO_HRMM,
+ [CHAR_SOUND_HERE_WE_GO] = SOUND_MARIO_HERE_WE_GO,
+ [CHAR_SOUND_SO_LONGA_BOWSER] = SOUND_MARIO_SO_LONGA_BOWSER,
+ [CHAR_SOUND_OOOF] = SOUND_MARIO_OOOF,
+ [CHAR_SOUND_OOOF2] = SOUND_MARIO_OOOF2,
+ [CHAR_SOUND_ATTACKED] = SOUND_MARIO_ATTACKED,
+ [CHAR_SOUND_PANTING] = SOUND_MARIO_PANTING,
+ [CHAR_SOUND_PANTING_COLD] = SOUND_MARIO_PANTING_COLD,
+ [CHAR_SOUND_ON_FIRE] = SOUND_MARIO_ON_FIRE,
+ [CHAR_SOUND_IMA_TIRED] = SOUND_MARIO_IMA_TIRED,
+ [CHAR_SOUND_YAWNING] = SOUND_MARIO_YAWNING,
+ [CHAR_SOUND_SNORING1] = SOUND_MARIO_SNORING1,
+ [CHAR_SOUND_SNORING2] = SOUND_MARIO_SNORING2,
+ [CHAR_SOUND_SNORING3] = SOUND_MARIO_SNORING3,
+ [CHAR_SOUND_COUGHING1] = SOUND_MARIO_COUGHING1,
+ [CHAR_SOUND_COUGHING2] = SOUND_MARIO_COUGHING2,
+ [CHAR_SOUND_COUGHING3] = SOUND_MARIO_COUGHING3,
+ [CHAR_SOUND_DYING] = SOUND_MARIO_DYING,
+ [CHAR_SOUND_DROWNING] = SOUND_MARIO_DROWNING,
+ [CHAR_SOUND_MAMA_MIA] = SOUND_MARIO_MAMA_MIA,
+ [CHAR_SOUND_GAME_OVER] = SOUND_MARIO_GAME_OVER,
+ [CHAR_SOUND_HELLO] = SOUND_MARIO_HELLO,
+ [CHAR_SOUND_PRESS_START_TO_PLAY] = SOUND_MARIO_PRESS_START_TO_PLAY
+}
+
+local VOICETABLE_CJ_LUIGI = {
+ [CHAR_SOUND_OKEY_DOKEY] = '0B_cj_luigi_okey_dokey.aiff',
+ [CHAR_SOUND_LETS_A_GO] = '1A_cj_luigi_lets_a_go.aiff',
+ [CHAR_SOUND_PUNCH_YAH] = '08_cj_luigi_punch_yah.aiff',
+ [CHAR_SOUND_PUNCH_WAH] = '01_cj_luigi_jump_wah.aiff',
+ [CHAR_SOUND_WAH2] = '07_cj_luigi_wah2.aiff',
+ [CHAR_SOUND_PUNCH_HOO] = '09_cj_luigi_punch_hoo.aiff',
+ [CHAR_SOUND_YAH_WAH_HOO] = { '00_cj_luigi_jump_hoo.aiff', '01_cj_luigi_jump_wah.aiff', '02_cj_luigi_yah.aiff' },
+ [CHAR_SOUND_HOOHOO] = '01_cj_luigi_hoohoo.aiff',
+ [CHAR_SOUND_YAHOO_WAHA_YIPPEE] = { '04_cj_luigi_yahoo.aiff', '18_cj_luigi_waha.aiff', '19_cj_luigi_yippee.aiff' },
+ [CHAR_SOUND_UH] = '05_cj_luigi_uh.aiff',
+ [CHAR_SOUND_UH2] = '05_cj_luigi_uh2.aiff',
+ [CHAR_SOUND_UH2_2] = '05_cj_luigi_uh2.aiff',
+ [CHAR_SOUND_HAHA] = '03_cj_luigi_haha.aiff',
+ [CHAR_SOUND_HAHA_2] = '03_cj_luigi_haha.aiff',
+ [CHAR_SOUND_YAHOO] = '04_cj_luigi_yahoo.aiff',
+ [CHAR_SOUND_DOH] = '10_cj_luigi_doh.aiff',
+ [CHAR_SOUND_WHOA] = '08_cj_luigi_whoa.aiff',
+ [CHAR_SOUND_EEUH] = '09_cj_luigi_eeuh.aiff',
+ [CHAR_SOUND_WAAAOOOW] = '00_cj_luigi_waaaooow.aiff',
+ [CHAR_SOUND_TWIRL_BOUNCE] = '14_cj_luigi_twirl_bounce.aiff',
+ [CHAR_SOUND_GROUND_POUND_WAH] = '07_cj_luigi_wah2.aiff',
+ [CHAR_SOUND_HRMM] = '06_cj_luigi_hrmm.aiff',
+ [CHAR_SOUND_HERE_WE_GO] = '0C_cj_luigi_here_we_go.aiff',
+ [CHAR_SOUND_SO_LONGA_BOWSER] = '16_cj_luigi_so_longa_bowser.aiff',
+ [CHAR_SOUND_OOOF] = '0B_cj_luigi_ooof.aiff',
+ [CHAR_SOUND_OOOF2] = '0B_cj_luigi_ooof.aiff',
+ [CHAR_SOUND_ATTACKED] = '0A_cj_luigi_attacked.aiff',
+ [CHAR_SOUND_PANTING] = '02_cj_luigi_panting.aiff',
+ [CHAR_SOUND_PANTING_COLD] = '02_cj_luigi_panting.aiff',
+ [CHAR_SOUND_ON_FIRE] = '04_cj_luigi_on_fire.aiff',
+ [CHAR_SOUND_IMA_TIRED] = '17_cj_luigi_ima_tired.aiff',
+ [CHAR_SOUND_YAWNING] = '0D_cj_luigi_yawning.aiff',
+ [CHAR_SOUND_SNORING1] = '0E_cj_luigi_snoring1.aiff',
+ [CHAR_SOUND_SNORING2] = '0F_cj_luigi_snoring2.aiff',
+ [CHAR_SOUND_SNORING3] = '15_cj_luigi_snoring3.aiff',
+ [CHAR_SOUND_COUGHING1] = '06_cj_luigi_coughing.aiff',
+ [CHAR_SOUND_COUGHING2] = '06_cj_luigi_coughing.aiff',
+ [CHAR_SOUND_COUGHING3] = '06_cj_luigi_coughing.aiff',
+ [CHAR_SOUND_DYING] = '03_cj_luigi_dying.aiff',
+ [CHAR_SOUND_DROWNING] = '0C_cj_luigi_drowning.aiff',
+ [CHAR_SOUND_MAMA_MIA] = '0A_cj_luigi_mama_mia.aiff'
}
-- Loading Characters --
@@ -161,14 +205,24 @@ local function on_character_select_load()
charSelect.character_add_palette_preset(E_MODEL_FLUFFA_WARIO, PALETTE_FL_WARIO)
charSelect.character_add_palette_preset(E_MODEL_KEEB_WALUIGI, PALETTE_KB_WALUIGI)
charSelect.character_add_palette_preset(E_MODEL_FLUFFA_WALUIGI, PALETTE_FL_WALUIGI)
+ charSelect.character_add_voice(E_MODEL_CJ_LUIGI, VOICETABLE_CJ_LUIGI)
+ charSelect.config_character_sounds()
end
--- Djoslin Toad Sound
+
--- @param m MarioState
--- @param sound CharacterSound
+--- Pitched up Mario voice
+local MODEL_FREQ_TABLE = {
+ [E_MODEL_DJOSLIN_TOAD] = 1.25,
+ [E_MODEL_VL_TONE_LUIGI] = 1.1
+}
+
local function character_sound(m, sound)
- if obj_get_model_id_extended(m.marioObj) == E_MODEL_DJOSLIN_TOAD then
- play_sound_with_freq_scale(DJ_TOAD_SOUNDS[sound + 1], m.marioObj.header.gfx.cameraToObject, 1.25)
+ local extendedModelId = obj_get_model_id_extended(m.marioObj)
+ local freqScale = MODEL_FREQ_TABLE[extendedModelId]
+ if freqScale then
+ play_sound_with_freq_scale(MARIO_SOUNDS[sound], m.marioObj.header.gfx.cameraToObject, freqScale)
return NO_SOUND
end
end
diff --git a/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff b/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff
new file mode 100644
index 000000000..b3eeeee0f
Binary files /dev/null and b/mods/char-select-the-originals/sound/00_cj_luigi_jump_hoo.aiff differ
diff --git a/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff b/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff
new file mode 100644
index 000000000..35850afde
Binary files /dev/null and b/mods/char-select-the-originals/sound/00_cj_luigi_waaaooow.aiff differ
diff --git a/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff b/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff
new file mode 100644
index 000000000..588ab78cd
Binary files /dev/null and b/mods/char-select-the-originals/sound/01_cj_luigi_hoohoo.aiff differ
diff --git a/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff b/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff
new file mode 100644
index 000000000..f2ffc0377
Binary files /dev/null and b/mods/char-select-the-originals/sound/01_cj_luigi_jump_wah.aiff differ
diff --git a/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff b/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff
new file mode 100644
index 000000000..c1f3ac196
Binary files /dev/null and b/mods/char-select-the-originals/sound/02_cj_luigi_panting.aiff differ
diff --git a/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff b/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff
new file mode 100644
index 000000000..ab47bd20c
Binary files /dev/null and b/mods/char-select-the-originals/sound/02_cj_luigi_yah.aiff differ
diff --git a/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff b/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff
new file mode 100644
index 000000000..025fe4a09
Binary files /dev/null and b/mods/char-select-the-originals/sound/03_cj_luigi_dying.aiff differ
diff --git a/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff b/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff
new file mode 100644
index 000000000..1990f5f5d
Binary files /dev/null and b/mods/char-select-the-originals/sound/03_cj_luigi_haha.aiff differ
diff --git a/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff b/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff
new file mode 100644
index 000000000..6863fa2b4
Binary files /dev/null and b/mods/char-select-the-originals/sound/04_cj_luigi_on_fire.aiff differ
diff --git a/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff b/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff
new file mode 100644
index 000000000..40f6b29a4
Binary files /dev/null and b/mods/char-select-the-originals/sound/04_cj_luigi_yahoo.aiff differ
diff --git a/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff b/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff
new file mode 100644
index 000000000..21b91ba85
Binary files /dev/null and b/mods/char-select-the-originals/sound/05_cj_luigi_uh.aiff differ
diff --git a/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff b/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff
new file mode 100644
index 000000000..1bc018711
Binary files /dev/null and b/mods/char-select-the-originals/sound/05_cj_luigi_uh2.aiff differ
diff --git a/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff b/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff
new file mode 100644
index 000000000..f7d0715ed
Binary files /dev/null and b/mods/char-select-the-originals/sound/06_cj_luigi_coughing.aiff differ
diff --git a/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff b/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff
new file mode 100644
index 000000000..78342ae2b
Binary files /dev/null and b/mods/char-select-the-originals/sound/06_cj_luigi_hrmm.aiff differ
diff --git a/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff b/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff
new file mode 100644
index 000000000..a20c73b8c
Binary files /dev/null and b/mods/char-select-the-originals/sound/07_cj_luigi_wah2.aiff differ
diff --git a/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff b/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff
new file mode 100644
index 000000000..ba4e1d8b3
Binary files /dev/null and b/mods/char-select-the-originals/sound/08_cj_luigi_punch_yah.aiff differ
diff --git a/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff b/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff
new file mode 100644
index 000000000..52d9c5093
Binary files /dev/null and b/mods/char-select-the-originals/sound/08_cj_luigi_whoa.aiff differ
diff --git a/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff b/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff
new file mode 100644
index 000000000..865b487f3
Binary files /dev/null and b/mods/char-select-the-originals/sound/09_cj_luigi_eeuh.aiff differ
diff --git a/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff b/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff
new file mode 100644
index 000000000..8503de5d3
Binary files /dev/null and b/mods/char-select-the-originals/sound/09_cj_luigi_punch_hoo.aiff differ
diff --git a/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff b/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff
new file mode 100644
index 000000000..3af9e773b
Binary files /dev/null and b/mods/char-select-the-originals/sound/0A_cj_luigi_attacked.aiff differ
diff --git a/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff b/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff
new file mode 100644
index 000000000..e78894012
Binary files /dev/null and b/mods/char-select-the-originals/sound/0A_cj_luigi_mama_mia.aiff differ
diff --git a/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff b/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff
new file mode 100644
index 000000000..3bd01f030
Binary files /dev/null and b/mods/char-select-the-originals/sound/0B_cj_luigi_okey_dokey.aiff differ
diff --git a/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff b/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff
new file mode 100644
index 000000000..0ad4c08e9
Binary files /dev/null and b/mods/char-select-the-originals/sound/0B_cj_luigi_ooof.aiff differ
diff --git a/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff b/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff
new file mode 100644
index 000000000..cc2de392c
Binary files /dev/null and b/mods/char-select-the-originals/sound/0C_cj_luigi_drowning.aiff differ
diff --git a/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff b/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff
new file mode 100644
index 000000000..0f6610c16
Binary files /dev/null and b/mods/char-select-the-originals/sound/0C_cj_luigi_here_we_go.aiff differ
diff --git a/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff b/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff
new file mode 100644
index 000000000..b4cd11ab7
Binary files /dev/null and b/mods/char-select-the-originals/sound/0D_cj_luigi_yawning.aiff differ
diff --git a/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff b/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff
new file mode 100644
index 000000000..aed9d630d
Binary files /dev/null and b/mods/char-select-the-originals/sound/0E_cj_luigi_snoring1.aiff differ
diff --git a/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff b/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff
new file mode 100644
index 000000000..81afa3b4b
Binary files /dev/null and b/mods/char-select-the-originals/sound/0F_cj_luigi_snoring2.aiff differ
diff --git a/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff b/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff
new file mode 100644
index 000000000..4f76c269f
Binary files /dev/null and b/mods/char-select-the-originals/sound/10_cj_luigi_doh.aiff differ
diff --git a/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff b/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff
new file mode 100644
index 000000000..7e65bbbca
Binary files /dev/null and b/mods/char-select-the-originals/sound/11_cj_luigi_game_over.aiff differ
diff --git a/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff b/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff
new file mode 100644
index 000000000..6654130a7
Binary files /dev/null and b/mods/char-select-the-originals/sound/12_cj_luigi_hello.aiff differ
diff --git a/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff b/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff
new file mode 100644
index 000000000..4384d9569
Binary files /dev/null and b/mods/char-select-the-originals/sound/13_cj_luigi_press_start_to_play.aiff differ
diff --git a/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff b/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff
new file mode 100644
index 000000000..8169c964d
Binary files /dev/null and b/mods/char-select-the-originals/sound/14_cj_luigi_twirl_bounce.aiff differ
diff --git a/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff b/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff
new file mode 100644
index 000000000..c78fd31be
Binary files /dev/null and b/mods/char-select-the-originals/sound/15_cj_luigi_snoring3.aiff differ
diff --git a/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff b/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff
new file mode 100644
index 000000000..ac78fab09
Binary files /dev/null and b/mods/char-select-the-originals/sound/16_cj_luigi_so_longa_bowser.aiff differ
diff --git a/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff b/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff
new file mode 100644
index 000000000..806dcb55f
Binary files /dev/null and b/mods/char-select-the-originals/sound/17_cj_luigi_ima_tired.aiff differ
diff --git a/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff b/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff
new file mode 100644
index 000000000..db50b250c
Binary files /dev/null and b/mods/char-select-the-originals/sound/18_cj_luigi_waha.aiff differ
diff --git a/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff b/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff
new file mode 100644
index 000000000..8b1e6b3a6
Binary files /dev/null and b/mods/char-select-the-originals/sound/19_cj_luigi_yippee.aiff differ
diff --git a/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff b/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff
new file mode 100644
index 000000000..27465f9d8
Binary files /dev/null and b/mods/char-select-the-originals/sound/1A_cj_luigi_lets_a_go.aiff differ
diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h
index c044fa548..7e61e9f4c 100644
--- a/src/engine/graph_node.h
+++ b/src/engine/graph_node.h
@@ -20,6 +20,7 @@
// Extra, custom, flags
#define GRAPH_EXTRA_FORCE_3D (1 << 0)
+#define GRAPH_EXTRA_ROTATE_HELD (1 << 1)
// Whether the node type has a function pointer of type GraphNodeFunc
#define GRAPH_NODE_TYPE_FUNCTIONAL 0x100
diff --git a/src/engine/level_script.c b/src/engine/level_script.c
index 7d7129cbc..bb955dce6 100644
--- a/src/engine/level_script.c
+++ b/src/engine/level_script.c
@@ -18,6 +18,7 @@
#include "goddard/renderer.h"
#include "geo_layout.h"
#include "graph_node.h"
+#include "level_commands.h"
#include "level_script.h"
#include "level_misc_macros.h"
#include "macro_presets.h"
@@ -501,8 +502,7 @@ static void level_cmd_23(void) {
}
static void level_cmd_init_mario(void) {
- u32 behaviorArg = CMD_GET(u32, 4);
- behaviorArg = behaviorArg;
+ UNUSED u32 behaviorArg = CMD_GET(u32, 4);
void* behaviorScript = CMD_GET(void*, 8);
u16 slot = CMD_GET(u8, 3);
struct GraphNode* unk18 = dynos_model_get_geo(slot);
@@ -918,124 +918,94 @@ static void level_cmd_cleardemoptr(void)
sCurrentCmd = CMD_NEXT;
}
+//
// coop
-static void level_cmd_place_object_ext(void) {
- u8 val7 = 1 << (gCurrActNum - 1);
- struct SpawnInfo *spawnInfo;
+//
- u16 modIndex = gLevelScriptModIndex;
- const char* behStr = dynos_level_get_token(CMD_GET(u32, 20));
+static bool find_lua_param(uintptr_t *param, u32 offset, u32 luaParams, u32 luaParamFlag) {
+ *param = CMD_GET(uintptr_t, offset);
+ if (luaParams & luaParamFlag) {
+ if (gLevelScriptModIndex == -1) {
+ LOG_ERROR("Could not find level script mod index");
+ return false;
+ }
- if (gLevelScriptModIndex == -1) {
- LOG_ERROR("Could not find level script mod index");
- sCurrentCmd = CMD_NEXT;
- return;
- }
-
- gSmLuaConvertSuccess = true;
- enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr);
-
- if (!gSmLuaConvertSuccess) {
+ const char *paramStr = dynos_level_get_token(*param);
gSmLuaConvertSuccess = true;
- behId = smlua_get_any_integer_mod_variable(behStr);
+ *param = smlua_get_integer_mod_variable(gLevelScriptModIndex, paramStr);
+
+ if (!gSmLuaConvertSuccess) {
+ gSmLuaConvertSuccess = true;
+ *param = smlua_get_any_integer_mod_variable(paramStr);
+ }
+
+ if (!gSmLuaConvertSuccess) {
+ LOG_LUA("Failed to execute level command, could not find parameter '%s'", paramStr);
+ return false;
+ }
}
-
- if (!gSmLuaConvertSuccess) {
- LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr);
- sCurrentCmd = CMD_NEXT;
- return;
- }
-
- if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
- u16 model = CMD_GET(u8, 3);
- spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo));
-
- spawnInfo->startPos[0] = CMD_GET(s16, 4);
- spawnInfo->startPos[1] = CMD_GET(s16, 6);
- spawnInfo->startPos[2] = CMD_GET(s16, 8);
-
- spawnInfo->startAngle[0] = CMD_GET(s16, 10) * 0x8000 / 180;
- spawnInfo->startAngle[1] = CMD_GET(s16, 12) * 0x8000 / 180;
- spawnInfo->startAngle[2] = CMD_GET(s16, 14) * 0x8000 / 180;
-
- spawnInfo->areaIndex = sCurrAreaIndex;
- spawnInfo->activeAreaIndex = sCurrAreaIndex;
-
- spawnInfo->behaviorArg = CMD_GET(u32, 16);
-
- spawnInfo->behaviorScript = (BehaviorScript*)get_behavior_from_id(behId);
- spawnInfo->unk18 = dynos_model_get_geo(model);
- spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos;
-
- spawnInfo->syncID = spawnInfo->next
- ? spawnInfo->next->syncID + 10
- : 10;
-
- gAreas[sCurrAreaIndex].objectSpawnInfos = spawnInfo;
- area_check_red_coin_or_secret(spawnInfo->behaviorScript, false);
- }
-
- sCurrentCmd = CMD_NEXT;
+ return true;
}
-static void level_cmd_place_object_ext2(void) {
+#define get_lua_param(name, type, flag) \
+ uintptr_t name##Param; \
+ if (!find_lua_param(&name##Param, flag##_OFFSET(cmdType), luaParams, flag)) { \
+ sCurrentCmd = CMD_NEXT; \
+ return; \
+ } \
+ type name = (type) name##Param;
+
+static void level_cmd_place_object_ext_lua_params(void) {
u8 val7 = 1 << (gCurrActNum - 1);
struct SpawnInfo *spawnInfo;
- u16 modIndex = gLevelScriptModIndex;
- const char* modelStr = dynos_level_get_token(CMD_GET(u32, 20));
- const char* behStr = dynos_level_get_token(CMD_GET(u32, 24));
+ u8 cmdType = sCurrentCmd->type;
+ u16 luaParams = (
+ cmdType == 0x3F ? OBJECT_EXT_LUA_BEHAVIOR : (
+ cmdType == 0x40 ? OBJECT_EXT_LUA_BEHAVIOR | OBJECT_EXT_LUA_MODEL : (
+ CMD_GET(u16, 2)
+ )));
- if (gLevelScriptModIndex == -1) {
- LOG_ERROR("Could not find level script mod index");
- sCurrentCmd = CMD_NEXT;
- return;
- }
+ get_lua_param(acts, u8, OBJECT_EXT_LUA_ACTS);
- gSmLuaConvertSuccess = true;
- enum ModelExtendedId modelId = smlua_get_integer_mod_variable(modIndex, modelStr);
- if (!gSmLuaConvertSuccess) {
- gSmLuaConvertSuccess = true;
- modelId = smlua_get_any_integer_mod_variable(modelStr);
- }
- if (!gSmLuaConvertSuccess) {
- LOG_LUA("Failed to place custom object, could not find model '%s'", modelStr);
- sCurrentCmd = CMD_NEXT;
- return;
- }
-
- gSmLuaConvertSuccess = true;
- enum BehaviorId behId = smlua_get_integer_mod_variable(modIndex, behStr);
- if (!gSmLuaConvertSuccess) {
- gSmLuaConvertSuccess = true;
- behId = smlua_get_any_integer_mod_variable(behStr);
- }
-
- if (!gSmLuaConvertSuccess) {
- LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr);
- sCurrentCmd = CMD_NEXT;
- return;
- }
-
- if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
+ if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (acts & val7) || acts == 0x1F)) {
spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo));
- spawnInfo->startPos[0] = CMD_GET(s16, 4);
- spawnInfo->startPos[1] = CMD_GET(s16, 6);
- spawnInfo->startPos[2] = CMD_GET(s16, 8);
+ get_lua_param(modelId, u32, OBJECT_EXT_LUA_MODEL);
+ get_lua_param(posX, s16, OBJECT_EXT_LUA_POS_X);
+ get_lua_param(posY, s16, OBJECT_EXT_LUA_POS_Y);
+ get_lua_param(posZ, s16, OBJECT_EXT_LUA_POS_Z);
+ get_lua_param(angleX, s16, OBJECT_EXT_LUA_ANGLE_X);
+ get_lua_param(angleY, s16, OBJECT_EXT_LUA_ANGLE_Y);
+ get_lua_param(angleZ, s16, OBJECT_EXT_LUA_ANGLE_Z);
+ get_lua_param(behParam, u32, OBJECT_EXT_LUA_BEH_PARAMS);
+ get_lua_param(behavior, uintptr_t, OBJECT_EXT_LUA_BEHAVIOR);
- spawnInfo->startAngle[0] = CMD_GET(s16, 10) * 0x8000 / 180;
- spawnInfo->startAngle[1] = CMD_GET(s16, 12) * 0x8000 / 180;
- spawnInfo->startAngle[2] = CMD_GET(s16, 14) * 0x8000 / 180;
+ spawnInfo->startPos[0] = posX;
+ spawnInfo->startPos[1] = posY;
+ spawnInfo->startPos[2] = posZ;
+ spawnInfo->startAngle[0] = (angleX * 0x8000) / 180;
+ spawnInfo->startAngle[1] = (angleY * 0x8000) / 180;
+ spawnInfo->startAngle[2] = (angleZ * 0x8000) / 180;
spawnInfo->areaIndex = sCurrAreaIndex;
spawnInfo->activeAreaIndex = sCurrAreaIndex;
- spawnInfo->behaviorArg = CMD_GET(u32, 16);
+ spawnInfo->behaviorArg = behParam;
+
+ if (luaParams & OBJECT_EXT_LUA_MODEL) {
+ u16 slot = smlua_model_util_load((enum ModelExtendedId) modelId);
+ spawnInfo->unk18 = dynos_model_get_geo(slot);
+ } else {
+ spawnInfo->unk18 = dynos_model_get_geo(modelId);
+ }
+
+ if (luaParams & OBJECT_EXT_LUA_BEHAVIOR) {
+ spawnInfo->behaviorScript = (BehaviorScript *) get_behavior_from_id((enum BehaviorId) behavior);
+ } else {
+ spawnInfo->behaviorScript = (BehaviorScript *) behavior;
+ }
- spawnInfo->behaviorScript = (BehaviorScript*)get_behavior_from_id(behId);
- u16 slot = smlua_model_util_load(modelId);
- spawnInfo->unk18 = dynos_model_get_geo(slot);
spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos;
spawnInfo->syncID = spawnInfo->next
@@ -1064,6 +1034,21 @@ static void level_cmd_jump_area_ext(void) {
}
}
+static void level_cmd_show_dialog_ext(void) {
+ if (sCurrAreaIndex != -1 && !gDjuiInMainMenu) {
+ u8 luaParams = CMD_GET(u8, 2);
+
+ get_lua_param(index, u8, SHOW_DIALOG_EXT_LUA_INDEX);
+ get_lua_param(dialogId, s32, SHOW_DIALOG_EXT_LUA_DIALOG);
+
+ if (index < 2) {
+ gAreas[sCurrAreaIndex].dialog[index] = dialogId;
+ }
+ }
+
+ sCurrentCmd = CMD_NEXT;
+}
+
static void (*LevelScriptJumpTable[])(void) = {
/*00*/ level_cmd_load_and_execute,
/*01*/ level_cmd_exit_and_execute,
@@ -1130,10 +1115,12 @@ static void (*LevelScriptJumpTable[])(void) = {
/*3E*/ level_cmd_cleardemoptr,
// coop
- /*3F*/ level_cmd_place_object_ext,
- /*40*/ level_cmd_place_object_ext2,
+ /*3F*/ level_cmd_place_object_ext_lua_params,
+ /*40*/ level_cmd_place_object_ext_lua_params,
/*41*/ level_cmd_load_model_from_geo_ext,
/*42*/ level_cmd_jump_area_ext,
+ /*43*/ level_cmd_place_object_ext_lua_params,
+ /*44*/ level_cmd_show_dialog_ext
};
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {
diff --git a/src/engine/math_util.c b/src/engine/math_util.c
index fc3562799..a5a82e602 100644
--- a/src/engine/math_util.c
+++ b/src/engine/math_util.c
@@ -233,6 +233,30 @@ OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result) {
return hasEnded;
}
+ ///////////
+ // Vec2f //
+///////////
+
+Vec2f gVec2fZero = { 0.0f, 0.0f };
+
+Vec2f gVec2fOne = { 1.0f, 1.0f };
+
+ ///////////
+ // Vec2i //
+///////////
+
+Vec2i gVec2iZero = { 0, 0 };
+
+Vec2i gVec2iOne = { 1, 1 };
+
+ ///////////
+ // Vec2s //
+///////////
+
+Vec2s gVec2sZero = { 0, 0 };
+
+Vec2s gVec2sOne = { 1, 1 };
+
///////////
// Vec3f //
///////////
diff --git a/src/engine/math_util.h b/src/engine/math_util.h
index 72ead474d..16e30eba2 100644
--- a/src/engine/math_util.h
+++ b/src/engine/math_util.h
@@ -87,6 +87,12 @@ extern f32 gCosineTable[];
#endif
+extern Vec2f gVec2fZero;
+extern Vec2i gVec2iZero;
+extern Vec2s gVec2sZero;
+extern Vec2f gVec2fOne;
+extern Vec2i gVec2iOne;
+extern Vec2s gVec2sOne;
extern Vec3f gVec3fZero;
extern Vec3i gVec3iZero;
extern Vec3s gVec3sZero;
@@ -143,6 +149,24 @@ Advances the spline-based animation associated with `m` and stores the current i
|descriptionEnd| */
OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, OUT Vec3f result);
+ ///////////
+ // Vec2f //
+///////////
+
+#include "math_util_vec2f.inl"
+
+ ///////////
+ // Vec2i //
+///////////
+
+#include "math_util_vec2i.inl"
+
+ ///////////
+ // Vec2s //
+///////////
+
+#include "math_util_vec2s.inl"
+
///////////
// Vec3f //
///////////
diff --git a/src/engine/math_util_vec2.tmpl b/src/engine/math_util_vec2.tmpl
new file mode 100644
index 000000000..bfb24f14a
--- /dev/null
+++ b/src/engine/math_util_vec2.tmpl
@@ -0,0 +1,157 @@
+#pragma once
+
+/* |description|
+Sets the components of the 2D {{desc}} vector `v` to 0
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_zero(OUT Vec2{{suffix}} v) {
+ memset(v, 0, sizeof(Vec2{{suffix}}));
+ return v;
+}
+
+/* |description|
+Copies the contents of a 2D {{desc}} vector (`src`) into another 2D {{desc}} vector (`dest`)
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_copy(OUT Vec2{{suffix}} dest, Vec2{{suffix}} src) {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ return dest;
+}
+
+/* |description|
+Sets the values of the 2D {{desc}} vector `dest` to the given x and y values
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set(OUT Vec2{{suffix}} dest, {{type}} x, {{type}} y) {
+ dest[0] = x;
+ dest[1] = y;
+ return dest;
+}
+
+/* |description|
+Adds the components of the 2D {{desc}} vector `a` to `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_add(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) {
+ dest[0] += a[0];
+ dest[1] += a[1];
+ return dest;
+}
+
+/* |description|
+Adds the components of two 2D {{desc}} vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sum(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) {
+ dest[0] = a[0] + b[0];
+ dest[1] = a[1] + b[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D {{desc}} vector `a` from `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_sub(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) {
+ dest[0] -= a[0];
+ dest[1] -= a[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D {{desc}} vector `b` from the components of `a` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_dif(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) {
+ dest[0] = a[0] - b[0];
+ dest[1] = a[1] - b[1];
+ return dest;
+}
+
+/* |description|
+Multiplies each component of the 2D {{desc}} vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mul(OUT Vec2{{suffix}} dest, f32 a) {
+ dest[0] *= a;
+ dest[1] *= a;
+ return dest;
+}
+
+/* |description|
+Multiplies the components of the 2D {{desc}} vector `dest` with the components of `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_mult(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a) {
+ dest[0] *= a[0];
+ dest[1] *= a[1];
+ return dest;
+}
+
+/* |description|
+Multiplies the components of two 2D {{desc}} vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_prod(OUT Vec2{{suffix}} dest, Vec2{{suffix}} a, Vec2{{suffix}} b) {
+ dest[0] = a[0] * b[0];
+ dest[1] = a[1] * b[1];
+ return dest;
+}
+
+/* |description|
+Divides each component of the 2D {{desc}} vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_div(OUT Vec2{{suffix}} dest, f32 a) {
+ if (a == 0) { return dest; }
+ dest[0] /= a;
+ dest[1] /= a;
+ return dest;
+}
+
+/* |description|
+Calculates the length (magnitude) of the 2D {{desc}} vector `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_length(Vec2{{suffix}} a) {
+ return sqrtf(a[0] * a[0] + a[1] * a[1]);
+}
+
+/* |description|
+Normalizes the 2D {{desc}} vector `v` so that its length (magnitude) becomes 1, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_normalize(OUT Vec2{{suffix}} v) {
+ f32 mag = vec2{{suffix}}_length(v);
+ vec2{{suffix}}_div(v, mag);
+ return v;
+}
+
+/* |description|
+Sets the length (magnitude) of 2D {{desc}} vector `v`, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_set_magnitude(OUT Vec2{{suffix}} v, f32 mag) {
+ vec2{{suffix}}_normalize(v);
+ vec2{{suffix}}_mul(v, mag);
+ return v;
+}
+
+/* |description|
+Computes the dot product of the two 2D {{desc}} vectors `a` and `b`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_dot(Vec2{{suffix}} a, Vec2{{suffix}} b) {
+ return (f32) (a[0] * b[0] + a[1] * b[1]);
+}
+
+/* |description|
+Takes two 2D {{desc}} vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2{{suffix}}p vec2{{suffix}}_combine(OUT Vec2{{suffix}} dest, Vec2{{suffix}} vecA, Vec2{{suffix}} vecB, f32 sclA, f32 sclB) {
+ dest[0] = vecA[0] * sclA + vecB[0] * sclB;
+ dest[1] = vecA[1] * sclA + vecB[1] * sclB;
+ return dest;
+}
+
+/* |description|
+Calculates the distance between two 2D {{desc}} vectors `v1` and `v2`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2{{suffix}}_dist(Vec2{{suffix}} v1, Vec2{{suffix}} v2) {
+ Vec2{{suffix}} diff;
+ vec2{{suffix}}_dif(diff, v1, v2);
+ return vec2{{suffix}}_length(diff);
+}
+
+/* |description|
+Returns `true` if all components of the 2D {{desc}} vector `v` are zero
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 bool vec2{{suffix}}_is_zero(Vec2{{suffix}} v) {
+ return memcmp(v, gVec2{{suffix}}Zero, sizeof(Vec2{{suffix}})) == 0;
+}
diff --git a/src/engine/math_util_vec2f.inl b/src/engine/math_util_vec2f.inl
new file mode 100644
index 000000000..edea0385b
--- /dev/null
+++ b/src/engine/math_util_vec2f.inl
@@ -0,0 +1,178 @@
+/* THIS FILE IS AUTO-GENERATED */
+/* DO NOT EDIT IT MANUALLY */
+
+#pragma once
+
+/* |description|
+Sets the components of the 2D floating-point vector `v` to 0
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_zero(OUT Vec2f v) {
+ memset(v, 0, sizeof(Vec2f));
+ return v;
+}
+
+/* |description|
+Copies the contents of a 2D floating-point vector (`src`) into another 2D floating-point vector (`dest`)
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_copy(OUT Vec2f dest, Vec2f src) {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ return dest;
+}
+
+/* |description|
+Sets the values of the 2D floating-point vector `dest` to the given x and y values
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_set(OUT Vec2f dest, f32 x, f32 y) {
+ dest[0] = x;
+ dest[1] = y;
+ return dest;
+}
+
+/* |description|
+Adds the components of the 2D floating-point vector `a` to `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_add(OUT Vec2f dest, Vec2f a) {
+ dest[0] += a[0];
+ dest[1] += a[1];
+ return dest;
+}
+
+/* |description|
+Adds the components of two 2D floating-point vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_sum(OUT Vec2f dest, Vec2f a, Vec2f b) {
+ dest[0] = a[0] + b[0];
+ dest[1] = a[1] + b[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D floating-point vector `a` from `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_sub(OUT Vec2f dest, Vec2f a) {
+ dest[0] -= a[0];
+ dest[1] -= a[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D floating-point vector `b` from the components of `a` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_dif(OUT Vec2f dest, Vec2f a, Vec2f b) {
+ dest[0] = a[0] - b[0];
+ dest[1] = a[1] - b[1];
+ return dest;
+}
+
+/* |description|
+Multiplies each component of the 2D floating-point vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_mul(OUT Vec2f dest, f32 a) {
+ dest[0] *= a;
+ dest[1] *= a;
+ return dest;
+}
+
+/* |description|
+Multiplies the components of the 2D floating-point vector `dest` with the components of `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_mult(OUT Vec2f dest, Vec2f a) {
+ dest[0] *= a[0];
+ dest[1] *= a[1];
+ return dest;
+}
+
+/* |description|
+Multiplies the components of two 2D floating-point vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_prod(OUT Vec2f dest, Vec2f a, Vec2f b) {
+ dest[0] = a[0] * b[0];
+ dest[1] = a[1] * b[1];
+ return dest;
+}
+
+/* |description|
+Divides each component of the 2D floating-point vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_div(OUT Vec2f dest, f32 a) {
+ if (a == 0) { return dest; }
+ dest[0] /= a;
+ dest[1] /= a;
+ return dest;
+}
+
+/* |description|
+Calculates the length (magnitude) of the 2D floating-point vector `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2f_length(Vec2f a) {
+ return sqrtf(a[0] * a[0] + a[1] * a[1]);
+}
+
+/* |description|
+Normalizes the 2D floating-point vector `v` so that its length (magnitude) becomes 1, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_normalize(OUT Vec2f v) {
+ f32 mag = vec2f_length(v);
+ vec2f_div(v, mag);
+ return v;
+}
+
+/* |description|
+Sets the length (magnitude) of 2D floating-point vector `v`, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_set_magnitude(OUT Vec2f v, f32 mag) {
+ vec2f_normalize(v);
+ vec2f_mul(v, mag);
+ return v;
+}
+
+/* |description|
+Computes the dot product of the two 2D floating-point vectors `a` and `b`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2f_dot(Vec2f a, Vec2f b) {
+ return (f32) (a[0] * b[0] + a[1] * b[1]);
+}
+
+/* |description|
+Takes two 2D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2f_combine(OUT Vec2f dest, Vec2f vecA, Vec2f vecB, f32 sclA, f32 sclB) {
+ dest[0] = vecA[0] * sclA + vecB[0] * sclB;
+ dest[1] = vecA[1] * sclA + vecB[1] * sclB;
+ return dest;
+}
+
+/* |description|
+Calculates the distance between two 2D floating-point vectors `v1` and `v2`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2f_dist(Vec2f v1, Vec2f v2) {
+ Vec2f diff;
+ vec2f_dif(diff, v1, v2);
+ return vec2f_length(diff);
+}
+
+/* |description|
+Returns `true` if all components of the 2D floating-point vector `v` are zero
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 bool vec2f_is_zero(Vec2f v) {
+ return memcmp(v, gVec2fZero, sizeof(Vec2f)) == 0;
+}
+
+/* |description|
+Converts a 2D floating-point vector `a` into a 2D integer vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2f_to_vec2i(OUT Vec2i dest, Vec2f a) {
+ dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
+ dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
+ return dest;
+}
+
+/* |description|
+Converts a 2D floating-point vector `a` into a 2D short integer vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2f_to_vec2s(OUT Vec2s dest, Vec2f a) {
+ dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
+ dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
+ return dest;
+}
diff --git a/src/engine/math_util_vec2i.inl b/src/engine/math_util_vec2i.inl
new file mode 100644
index 000000000..774bedb38
--- /dev/null
+++ b/src/engine/math_util_vec2i.inl
@@ -0,0 +1,178 @@
+/* THIS FILE IS AUTO-GENERATED */
+/* DO NOT EDIT IT MANUALLY */
+
+#pragma once
+
+/* |description|
+Sets the components of the 2D integer vector `v` to 0
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_zero(OUT Vec2i v) {
+ memset(v, 0, sizeof(Vec2i));
+ return v;
+}
+
+/* |description|
+Copies the contents of a 2D integer vector (`src`) into another 2D integer vector (`dest`)
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_copy(OUT Vec2i dest, Vec2i src) {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ return dest;
+}
+
+/* |description|
+Sets the values of the 2D integer vector `dest` to the given x and y values
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_set(OUT Vec2i dest, s32 x, s32 y) {
+ dest[0] = x;
+ dest[1] = y;
+ return dest;
+}
+
+/* |description|
+Adds the components of the 2D integer vector `a` to `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_add(OUT Vec2i dest, Vec2i a) {
+ dest[0] += a[0];
+ dest[1] += a[1];
+ return dest;
+}
+
+/* |description|
+Adds the components of two 2D integer vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_sum(OUT Vec2i dest, Vec2i a, Vec2i b) {
+ dest[0] = a[0] + b[0];
+ dest[1] = a[1] + b[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D integer vector `a` from `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_sub(OUT Vec2i dest, Vec2i a) {
+ dest[0] -= a[0];
+ dest[1] -= a[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D integer vector `b` from the components of `a` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_dif(OUT Vec2i dest, Vec2i a, Vec2i b) {
+ dest[0] = a[0] - b[0];
+ dest[1] = a[1] - b[1];
+ return dest;
+}
+
+/* |description|
+Multiplies each component of the 2D integer vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_mul(OUT Vec2i dest, f32 a) {
+ dest[0] *= a;
+ dest[1] *= a;
+ return dest;
+}
+
+/* |description|
+Multiplies the components of the 2D integer vector `dest` with the components of `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_mult(OUT Vec2i dest, Vec2i a) {
+ dest[0] *= a[0];
+ dest[1] *= a[1];
+ return dest;
+}
+
+/* |description|
+Multiplies the components of two 2D integer vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_prod(OUT Vec2i dest, Vec2i a, Vec2i b) {
+ dest[0] = a[0] * b[0];
+ dest[1] = a[1] * b[1];
+ return dest;
+}
+
+/* |description|
+Divides each component of the 2D integer vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_div(OUT Vec2i dest, f32 a) {
+ if (a == 0) { return dest; }
+ dest[0] /= a;
+ dest[1] /= a;
+ return dest;
+}
+
+/* |description|
+Calculates the length (magnitude) of the 2D integer vector `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2i_length(Vec2i a) {
+ return sqrtf(a[0] * a[0] + a[1] * a[1]);
+}
+
+/* |description|
+Normalizes the 2D integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_normalize(OUT Vec2i v) {
+ f32 mag = vec2i_length(v);
+ vec2i_div(v, mag);
+ return v;
+}
+
+/* |description|
+Sets the length (magnitude) of 2D integer vector `v`, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_set_magnitude(OUT Vec2i v, f32 mag) {
+ vec2i_normalize(v);
+ vec2i_mul(v, mag);
+ return v;
+}
+
+/* |description|
+Computes the dot product of the two 2D integer vectors `a` and `b`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2i_dot(Vec2i a, Vec2i b) {
+ return (f32) (a[0] * b[0] + a[1] * b[1]);
+}
+
+/* |description|
+Takes two 2D integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2i_combine(OUT Vec2i dest, Vec2i vecA, Vec2i vecB, f32 sclA, f32 sclB) {
+ dest[0] = vecA[0] * sclA + vecB[0] * sclB;
+ dest[1] = vecA[1] * sclA + vecB[1] * sclB;
+ return dest;
+}
+
+/* |description|
+Calculates the distance between two 2D integer vectors `v1` and `v2`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2i_dist(Vec2i v1, Vec2i v2) {
+ Vec2i diff;
+ vec2i_dif(diff, v1, v2);
+ return vec2i_length(diff);
+}
+
+/* |description|
+Returns `true` if all components of the 2D integer vector `v` are zero
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 bool vec2i_is_zero(Vec2i v) {
+ return memcmp(v, gVec2iZero, sizeof(Vec2i)) == 0;
+}
+
+/* |description|
+Converts a 2D integer vector `a` into a 2D floating-point vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2i_to_vec2f(OUT Vec2f dest, Vec2i a) {
+ dest[0] = a[0];
+ dest[1] = a[1];
+ return dest;
+}
+
+/* |description|
+Converts a 2D integer vector `a` into a 2D short integer vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2i_to_vec2s(OUT Vec2s dest, Vec2i a) {
+ dest[0] = a[0];
+ dest[1] = a[1];
+ return dest;
+}
diff --git a/src/engine/math_util_vec2s.inl b/src/engine/math_util_vec2s.inl
new file mode 100644
index 000000000..2dde2fdbd
--- /dev/null
+++ b/src/engine/math_util_vec2s.inl
@@ -0,0 +1,178 @@
+/* THIS FILE IS AUTO-GENERATED */
+/* DO NOT EDIT IT MANUALLY */
+
+#pragma once
+
+/* |description|
+Sets the components of the 2D short integer vector `v` to 0
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_zero(OUT Vec2s v) {
+ memset(v, 0, sizeof(Vec2s));
+ return v;
+}
+
+/* |description|
+Copies the contents of a 2D short integer vector (`src`) into another 2D short integer vector (`dest`)
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_copy(OUT Vec2s dest, Vec2s src) {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ return dest;
+}
+
+/* |description|
+Sets the values of the 2D short integer vector `dest` to the given x and y values
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_set(OUT Vec2s dest, s16 x, s16 y) {
+ dest[0] = x;
+ dest[1] = y;
+ return dest;
+}
+
+/* |description|
+Adds the components of the 2D short integer vector `a` to `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_add(OUT Vec2s dest, Vec2s a) {
+ dest[0] += a[0];
+ dest[1] += a[1];
+ return dest;
+}
+
+/* |description|
+Adds the components of two 2D short integer vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_sum(OUT Vec2s dest, Vec2s a, Vec2s b) {
+ dest[0] = a[0] + b[0];
+ dest[1] = a[1] + b[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D short integer vector `a` from `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_sub(OUT Vec2s dest, Vec2s a) {
+ dest[0] -= a[0];
+ dest[1] -= a[1];
+ return dest;
+}
+
+/* |description|
+Subtracts the components of the 2D short integer vector `b` from the components of `a` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_dif(OUT Vec2s dest, Vec2s a, Vec2s b) {
+ dest[0] = a[0] - b[0];
+ dest[1] = a[1] - b[1];
+ return dest;
+}
+
+/* |description|
+Multiplies each component of the 2D short integer vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_mul(OUT Vec2s dest, f32 a) {
+ dest[0] *= a;
+ dest[1] *= a;
+ return dest;
+}
+
+/* |description|
+Multiplies the components of the 2D short integer vector `dest` with the components of `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_mult(OUT Vec2s dest, Vec2s a) {
+ dest[0] *= a[0];
+ dest[1] *= a[1];
+ return dest;
+}
+
+/* |description|
+Multiplies the components of two 2D short integer vectors `a` and `b` and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_prod(OUT Vec2s dest, Vec2s a, Vec2s b) {
+ dest[0] = a[0] * b[0];
+ dest[1] = a[1] * b[1];
+ return dest;
+}
+
+/* |description|
+Divides each component of the 2D short integer vector `dest` by the scalar value `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_div(OUT Vec2s dest, f32 a) {
+ if (a == 0) { return dest; }
+ dest[0] /= a;
+ dest[1] /= a;
+ return dest;
+}
+
+/* |description|
+Calculates the length (magnitude) of the 2D short integer vector `a`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2s_length(Vec2s a) {
+ return sqrtf(a[0] * a[0] + a[1] * a[1]);
+}
+
+/* |description|
+Normalizes the 2D short integer vector `v` so that its length (magnitude) becomes 1, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_normalize(OUT Vec2s v) {
+ f32 mag = vec2s_length(v);
+ vec2s_div(v, mag);
+ return v;
+}
+
+/* |description|
+Sets the length (magnitude) of 2D short integer vector `v`, while retaining its direction
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_set_magnitude(OUT Vec2s v, f32 mag) {
+ vec2s_normalize(v);
+ vec2s_mul(v, mag);
+ return v;
+}
+
+/* |description|
+Computes the dot product of the two 2D short integer vectors `a` and `b`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2s_dot(Vec2s a, Vec2s b) {
+ return (f32) (a[0] * b[0] + a[1] * b[1]);
+}
+
+/* |description|
+Takes two 2D short integer vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, adds the scaled vectors together and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2sp vec2s_combine(OUT Vec2s dest, Vec2s vecA, Vec2s vecB, f32 sclA, f32 sclB) {
+ dest[0] = vecA[0] * sclA + vecB[0] * sclB;
+ dest[1] = vecA[1] * sclA + vecB[1] * sclB;
+ return dest;
+}
+
+/* |description|
+Calculates the distance between two 2D short integer vectors `v1` and `v2`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 f32 vec2s_dist(Vec2s v1, Vec2s v2) {
+ Vec2s diff;
+ vec2s_dif(diff, v1, v2);
+ return vec2s_length(diff);
+}
+
+/* |description|
+Returns `true` if all components of the 2D short integer vector `v` are zero
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 bool vec2s_is_zero(Vec2s v) {
+ return memcmp(v, gVec2sZero, sizeof(Vec2s)) == 0;
+}
+
+/* |description|
+Converts a 2D short integer vector `a` into a 2D floating-point vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2fp vec2s_to_vec2f(OUT Vec2f dest, Vec2s a) {
+ dest[0] = a[0];
+ dest[1] = a[1];
+ return dest;
+}
+
+/* |description|
+Converts a 2D short integer vector `a` into a 2D integer vector and stores the result in `dest`
+|descriptionEnd| */
+INLINE OPTIMIZE_O3 Vec2ip vec2s_to_vec2i(OUT Vec2i dest, Vec2s a) {
+ dest[0] = a[0];
+ dest[1] = a[1];
+ return dest;
+}
diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c
index 96ef6cfcb..1e34afd7f 100644
--- a/src/engine/surface_collision.c
+++ b/src/engine/surface_collision.c
@@ -137,9 +137,8 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
surfaceNode = surfaceNode->next;
// Exclude a large number of walls immediately to optimize.
- if (y < surf->lowerY || y > surf->upperY) {
- continue;
- }
+ if (y < surf->lowerY || y > surf->upperY) { continue; }
+ if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; }
if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners && !gFindWallDirectionAirborne) {
// Check AABB to exclude walls before doing expensive triangle check
@@ -399,6 +398,8 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
surf = surfaceNode->surface;
surfaceNode = surfaceNode->next;
+ if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; }
+
x1 = surf->vertex1[0];
z1 = surf->vertex1[2];
z2 = surf->vertex2[2];
@@ -622,7 +623,8 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32
if (surf == NULL) { break; }
surfaceNode = surfaceNode->next;
interpolate = gInterpolatingSurfaces;
-
+
+ if (surf->flags & SURFACE_FLAG_INTANGIBLE) { continue; }
if (gCheckingSurfaceCollisionsForObject != NULL) {
if (surf->object != gCheckingSurfaceCollisionsForObject) {
continue;
diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h
index d954b847b..ff5257a57 100644
--- a/src/engine/surface_collision.h
+++ b/src/engine/surface_collision.h
@@ -38,6 +38,12 @@ struct FloorGeometry
f32 originOffset;
};
+struct StaticObjectCollision
+{
+ u32 index;
+ u16 length;
+};
+
extern Vec3f gFindWallDirection;
extern u8 gFindWallDirectionActive;
extern u8 gFindWallDirectionAirborne;
diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c
index f74eb8110..e5296490e 100644
--- a/src/engine/surface_load.c
+++ b/src/engine/surface_load.c
@@ -28,12 +28,48 @@
SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
+/**
+ * The total number of surface nodes allocated (a node is allocated for each
+ * spatial partition cell that a surface intersects).
+ */
+s32 gSurfaceNodesAllocated;
+
+/**
+ * The total number of surfaces allocated.
+ */
+s32 gSurfacesAllocated;
+
+/**
+ * The number of nodes that have been created for static surfaces.
+ */
+s32 gNumStaticSurfaceNodes;
+
+/**
+ * The number of static surfaces in the pool.
+ */
+s32 gNumStaticSurfaces;
+
+/**
+ * The number of nodes that have been created for static object collision surfaces.
+ */
+s32 gNumSOCSurfaceNodes;
+
+/**
+ * The number of static object collision surfaces in the pool.
+ */
+s32 gNumSOCSurfaces;
+
/**
* Pools of data to contain either surface nodes or surfaces.
*/
static struct GrowingArray *sSurfaceNodePool = NULL;
static struct GrowingArray *sSurfacePool = NULL;
+/**
+ * Pool of data for static object collisions.
+ */
+static struct GrowingArray *sSOCPool = NULL;
+
/**
* Allocate the part of the surface node pool to contain a surface node.
*/
@@ -51,6 +87,10 @@ static struct Surface *alloc_surface(void) {
return growing_array_alloc(sSurfacePool, sizeof(struct Surface));
}
+static struct StaticObjectCollision *alloc_static_object_collision(void) {
+ return growing_array_alloc(sSOCPool, sizeof(struct StaticObjectCollision));
+}
+
/**
* Iterates through the entire partition, clearing the surfaces.
*/
@@ -71,6 +111,7 @@ static void clear_spatial_partition(SpatialPartitionCell *cells) {
*/
static void clear_static_surfaces(void) {
clear_spatial_partition(&gStaticSurfacePartition[0][0]);
+ sSOCPool = growing_array_init(sSOCPool, 0x100, malloc, smlua_free_soc);
}
/**
@@ -479,6 +520,8 @@ void alloc_surface_pools(void) {
gSurfacesAllocated = 0;
gNumStaticSurfaceNodes = 0;
gNumStaticSurfaces = 0;
+ gNumSOCSurfaceNodes = 0;
+ gNumSOCSurfaces = 0;
gCCMEnteredSlide = 0;
reset_red_coins_collected();
@@ -586,6 +629,8 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
gNumStaticSurfaces = gSurfacesAllocated;
+ gNumSOCSurfaceNodes = 0;
+ gNumSOCSurfaces = 0;
}
/**
@@ -593,8 +638,8 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
*/
void clear_dynamic_surfaces(void) {
if (!(gTimeStopState & TIME_STOP_ACTIVE)) {
- gSurfacesAllocated = gNumStaticSurfaces;
- gSurfaceNodesAllocated = gNumStaticSurfaceNodes;
+ gSurfacesAllocated = gNumStaticSurfaces + gNumSOCSurfaces;
+ gSurfaceNodesAllocated = gNumStaticSurfaceNodes + gNumSOCSurfaceNodes;
clear_spatial_partition(&gDynamicSurfacePartition[0][0]);
@@ -650,7 +695,7 @@ void transform_object_vertices(s16 **data, s16 *vertexData) {
/**
* Load in the surfaces for the gCurrentObject. This includes setting the flags, exertion, and room.
*/
-void load_object_surfaces(s16** data, s16* vertexData) {
+void load_object_surfaces(s16** data, s16* vertexData, bool isSOC) {
if (!gCurrentObject) { return; }
s32 surfaceType;
s32 i;
@@ -682,15 +727,16 @@ void load_object_surfaces(s16** data, s16* vertexData) {
struct Surface* surface = read_surface_data(vertexData, data);
if (surface != NULL) {
-
- // Set index of first surface
- if (gCurrentObject->firstSurface == 0) {
- gCurrentObject->firstSurface = gSurfacesAllocated - 1;
+ if (!isSOC) {
+ // Set index of first surface
+ if (gCurrentObject->firstSurface == 0) {
+ gCurrentObject->firstSurface = gSurfacesAllocated - 1;
+ }
+
+ // Increase surface count
+ gCurrentObject->numSurfaces++;
}
- // Increase surface count
- gCurrentObject->numSurfaces++;
-
surface->object = gCurrentObject;
surface->type = surfaceType;
@@ -702,7 +748,7 @@ void load_object_surfaces(s16** data, s16* vertexData) {
surface->flags |= flags;
surface->room = (s8)room;
- add_surface(surface, TRUE);
+ add_surface(surface, !isSOC);
}
if (hasForce) {
@@ -716,9 +762,12 @@ void load_object_surfaces(s16** data, s16* vertexData) {
/**
* Transform an object's vertices, reload them, and render the object.
*/
-void load_object_collision_model(void) {
+static void load_object_collision_model_internal(bool isSOC) {
+ static bool sIsLoadingCollision = false;
+
if (!gCurrentObject) { return; }
if (gCurrentObject->collisionData == NULL) { return; }
+ if (sIsLoadingCollision) { return; }
s32 numVertices = 64;
if (gCurrentObject->collisionData[0] == COL_INIT()) {
@@ -736,6 +785,9 @@ void load_object_collision_model(void) {
static s32 sVertexDataCount = 0;
static s16* sVertexData = NULL;
+ // start loading collision
+ sIsLoadingCollision = true;
+
// allocate vertex data
if (numVertices > sVertexDataCount || sVertexData == NULL) {
if (sVertexData) { free(sVertexData); }
@@ -746,39 +798,99 @@ void load_object_collision_model(void) {
}
s16* collisionData = gCurrentObject->collisionData;
- f32 tangibleDist = gCurrentObject->oCollisionDistance;
u8 anyPlayerInTangibleRange = FALSE;
- for (s32 i = 0; i < MAX_PLAYERS; i++) {
- f32 dist = dist_between_objects(gCurrentObject, gMarioStates[i].marioObj);
- if (dist < tangibleDist) { anyPlayerInTangibleRange = TRUE; }
+ if (!isSOC) {
+ f32 tangibleDist = gCurrentObject->oCollisionDistance;
+
+ for (s32 i = 0; i < MAX_PLAYERS; i++) {
+ f32 dist = dist_between_objects(gCurrentObject, gMarioStates[i].marioObj);
+ if (dist < tangibleDist) { anyPlayerInTangibleRange = TRUE; }
+ }
+
+ // If the object collision is supposed to be loaded more than the
+ // drawing distance of 4000, extend the drawing range.
+ if (gCurrentObject->oCollisionDistance > 4000.0f) {
+ gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance;
+ }
}
- // If the object collision is supposed to be loaded more than the
- // drawing distance of 4000, extend the drawing range.
- if (gCurrentObject->oCollisionDistance > 4000.0f) {
- gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance;
- }
-
- // Update if no Time Stop, in range, and in the current room.
- if (!(gTimeStopState & TIME_STOP_ACTIVE)
+ // Update if no Time Stop, in range, and in the current room. (or if static)
+ if (isSOC ||
+ (!(gTimeStopState & TIME_STOP_ACTIVE)
&& (anyPlayerInTangibleRange)
- && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
+ && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM))
+ ) {
collisionData++;
transform_object_vertices(&collisionData, sVertexData);
// TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data.
while (*collisionData != TERRAIN_LOAD_CONTINUE) {
- load_object_surfaces(&collisionData, sVertexData);
+ load_object_surfaces(&collisionData, sVertexData, isSOC);
}
}
- f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj);
- if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
- gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
- } else {
- gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
+ if (!isSOC) {
+ f32 marioDist = dist_between_objects(gCurrentObject, gMarioStates[0].marioObj);
+ if (marioDist < gCurrentObject->oDrawingDistance * draw_distance_scalar()) {
+ gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
+ } else {
+ gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
+ }
}
+
+ // stop loading collision
+ sIsLoadingCollision = false;
+}
+
+void load_object_collision_model(void) {
+ load_object_collision_model_internal(false);
+}
+
+struct StaticObjectCollision *load_static_object_collision() {
+ struct StaticObjectCollision *col;
+ u32 lastSurfaceIndex = gSurfacesAllocated;
+ u32 lastSurfaceNodeIndex = gSurfaceNodesAllocated;
+ u32 lastSOCSurfaceIndex = gNumStaticSurfaces + gNumSOCSurfaces;
+ u32 lastSOCSurfaceNodeIndex = gNumStaticSurfaceNodes + gNumSOCSurfaceNodes;
+
+ load_object_collision_model_internal(true);
+
+ // Reorder surfaces and nodes and update SOC variables
+ u32 addedSurfaces = gSurfacesAllocated - lastSurfaceIndex;
+ u32 addedSurfaceNodes = gSurfaceNodesAllocated - lastSurfaceNodeIndex;
+ if (addedSurfaces > 0) {
+ growing_array_move(sSurfacePool, lastSurfaceIndex, lastSOCSurfaceIndex, addedSurfaces);
+ gNumSOCSurfaces += addedSurfaces;
+ }
+ if (addedSurfaceNodes > 0) {
+ growing_array_move(sSurfaceNodePool, lastSurfaceNodeIndex, lastSOCSurfaceNodeIndex, addedSurfaceNodes);
+ gNumSOCSurfaceNodes += addedSurfaceNodes;
+ }
+
+ col = alloc_static_object_collision();
+ col->index = lastSOCSurfaceIndex;
+ col->length = addedSurfaces;
+
+ return col;
+}
+
+void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible) {
+ for (s32 i = 0; i < col->length; i++) {
+ struct Surface *surf = sSurfacePool->buffer[col->index + i];
+ if (tangible) {
+ surf->flags &= ~SURFACE_FLAG_INTANGIBLE;
+ } else {
+ surf->flags |= SURFACE_FLAG_INTANGIBLE;
+ }
+ }
+}
+
+struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index) {
+ if (!col) { return NULL; }
+ if (index >= col->length) { return NULL; }
+ struct Surface *surf = sSurfacePool->buffer[col->index + index];
+ return surf;
}
struct Surface *obj_get_surface_from_index(struct Object *o, u32 index) {
diff --git a/src/engine/surface_load.h b/src/engine/surface_load.h
index 262958423..d0f2db1ad 100644
--- a/src/engine/surface_load.h
+++ b/src/engine/surface_load.h
@@ -27,6 +27,13 @@ typedef struct SurfaceNode SpatialPartitionCell[3];
extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
+extern s32 gSurfaceNodesAllocated;
+extern s32 gSurfacesAllocated;
+extern s32 gNumStaticSurfaceNodes;
+extern s32 gNumStaticSurfaces;
+extern s32 gNumSOCSurfaceNodes;
+extern s32 gNumSOCSurfaces;
+
void alloc_surface_pools(void);
u32 get_area_terrain_size(s16 *data);
@@ -38,6 +45,15 @@ Loads the object's collision data into dynamic collision.
You must run this every frame in your object's behavior loop for it to have collision
|descriptionEnd| */
void load_object_collision_model(void);
+/* |description|
+Loads the object's collision data into static collision.
+You may run this only once to capture the object's collision at that frame.
+|descriptionEnd| */
+struct StaticObjectCollision *load_static_object_collision();
+/* |description|Toggles a collection of static object surfaces|descriptionEnd| */
+void toggle_static_object_collision(struct StaticObjectCollision *col, bool tangible);
+/* |description|Gets a surface corresponding to `index` from the static object collision|descriptionEnd| */
+struct Surface *get_static_object_surface(struct StaticObjectCollision *col, u32 index);
/* |description|Gets a surface corresponding to `index` from the surface pool buffer|descriptionEnd| */
struct Surface *obj_get_surface_from_index(struct Object *o, u32 index);
/* |description|Checks if a surface has force|descriptionEnd| */
diff --git a/src/game/area.h b/src/game/area.h
index 0fe0b45c6..d5340fdee 100644
--- a/src/game/area.h
+++ b/src/game/area.h
@@ -79,9 +79,9 @@ struct Area
/*0x24*/ struct Camera *camera;
/*0x28*/ struct UnusedArea28 *unused28; // Filled by level script 0x3A, but is unused.
/*0x2C*/ struct Whirlpool *whirlpools[2];
- /*0x34*/ u8 dialog[2]; // Level start dialog number (set by level script cmd 0x30)
- /*0x36*/ u16 musicParam;
- /*0x38*/ u16 musicParam2;
+ /*0x34*/ s32 dialog[2]; // Level start dialog number (set by level script cmd 0x30 and 0x44)
+ /*0x3C*/ u16 musicParam;
+ /*0x40*/ u16 musicParam2;
/*????*/ u32 localAreaTimer;
/*????*/ u8 *macroObjectsAltered;
/*????*/ u8 numRedCoins;
diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h
index 995b81686..5a81b42b8 100644
--- a/src/game/bettercamera.inc.h
+++ b/src/game/bettercamera.inc.h
@@ -101,7 +101,7 @@ inline static s16 newcam_adjust_value(f32 var, f32 val, f32 limit) {
inline static s32 newcam_ivrt(u8 axis) {
return (
axis == 0 ?
- (gNewCamera.invertX ? 1 : -1) :
+ (gNewCamera.invertX ? -1 : 1) :
(gNewCamera.invertY ? -1 : 1)
);
}
@@ -313,7 +313,7 @@ static void newcam_zoom_button(void) {
// When you press L, set the flag for centering the camera. Afterwards, start setting the yaw to the Player's yaw at the time.
if (gNewCamera.LCentering && (gPlayer1Controller->buttonDown & L_TRIG)) {
- gNewCamera.yawTarget = -gMarioState->faceAngle[1] - 0x4000;
+ gNewCamera.yawTarget = -gMarioState->statusForCamera->faceAngle[1] - 0x4000;
gNewCamera.centering = true;
}
@@ -346,24 +346,24 @@ static void newcam_update_values(void) {
if (gNewCamera.turnWait > 0 && gMarioState->vel[1] == 0) {
gNewCamera.turnWait--;
} else if (gMarioState->intendedMag > 0 && gMarioState->vel[1] == 0) {
- gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->faceAngle[1] - 0x4000, ((gNewCamera.aggression * (ABS(gPlayer1Controller->rawStickX / 10.f))) * (gMarioState->forwardVel / 32.f)));
+ gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->statusForCamera->faceAngle[1] - 0x4000, ((gNewCamera.aggression * (ABS(gPlayer1Controller->rawStickX / 10.f))) * (gMarioState->forwardVel / 32.f)));
} else {
gNewCamera.turnWait = 10;
}
// During slide actions in slide levels, force centering
if (gNewCamera.isSlide && (
- gMarioState->action == ACT_BUTT_SLIDE ||
- gMarioState->action == ACT_STOMACH_SLIDE ||
- gMarioState->action == ACT_HOLD_BUTT_SLIDE ||
- gMarioState->action == ACT_HOLD_STOMACH_SLIDE)
+ gMarioState->statusForCamera->action == ACT_BUTT_SLIDE ||
+ gMarioState->statusForCamera->action == ACT_STOMACH_SLIDE ||
+ gMarioState->statusForCamera->action == ACT_HOLD_BUTT_SLIDE ||
+ gMarioState->statusForCamera->action == ACT_HOLD_STOMACH_SLIDE)
) {
centering = (gMarioState->forwardVel > 8);
ycentering = false;
}
// Force centering when flying
- if ((gMarioState->action & ACT_FLAG_FLYING) == ACT_FLAG_FLYING) {
+ if ((gMarioState->statusForCamera->action & ACT_FLAG_FLYING) == ACT_FLAG_FLYING) {
centering = true;
}
@@ -371,12 +371,12 @@ static void newcam_update_values(void) {
// Place the camera behind Mario during the ACT_SHOT_FROM_CANNON action
static u32 sLastAction = 0;
static bool sForceCentering = false;
- if (sLastAction != gMarioState->action) {
- sLastAction = gMarioState->action;
+ if (sLastAction != gMarioState->statusForCamera->action) {
+ sLastAction = gMarioState->statusForCamera->action;
sForceCentering = true;
- switch (gMarioState->action) {
+ switch (gMarioState->statusForCamera->action) {
case ACT_SHOT_FROM_CANNON:
- gNewCamera.yaw = -gMarioState->faceAngle[1] - 0x4000;
+ gNewCamera.yaw = -gMarioState->statusForCamera->faceAngle[1] - 0x4000;
break;
}
}
@@ -392,14 +392,14 @@ static void newcam_update_values(void) {
}
// Force centering during non-still swimming actions
- if (gMarioState->action & ACT_FLAG_SWIMMING && gMarioState->forwardVel > 2) {
+ if (gMarioState->statusForCamera->action & ACT_FLAG_SWIMMING && gMarioState->forwardVel > 2) {
centering = true;
}
if (centering) {
- gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->faceAngle[1] - 0x4000, gMarioState->forwardVel * 128);
+ gNewCamera.yaw = approach_s16_symmetric(gNewCamera.yaw, -gMarioState->statusForCamera->faceAngle[1] - 0x4000, gMarioState->forwardVel * 128);
if (gMarioState->forwardVel > 1 && ycentering) {
- gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, (-gMarioState->faceAngle[0] * 0.8f) + NEWCAM_TILT_CENTERING, gMarioState->forwardVel * 32);
+ gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, (-gMarioState->statusForCamera->faceAngle[0] * 0.8f) + NEWCAM_TILT_CENTERING, gMarioState->forwardVel * 32);
} else {
gNewCamera.tilt = approach_s16_symmetric(gNewCamera.tilt, NEWCAM_TILT_CENTERING, 32);
}
@@ -508,12 +508,12 @@ static void newcam_set_pan(void) {
}
// Apply panning values based on Mario's direction.
- if (gMarioState->action != ACT_HOLDING_BOWSER &&
- gMarioState->action != ACT_SLEEPING &&
- gMarioState->action != ACT_START_SLEEPING
+ if (gMarioState->statusForCamera->action != ACT_HOLDING_BOWSER &&
+ gMarioState->statusForCamera->action != ACT_SLEEPING &&
+ gMarioState->statusForCamera->action != ACT_START_SLEEPING
) {
- approach_f32_asymptotic_bool(&gNewCamera.panX, newcam_lengthdir_x((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->faceAngle[1] - 0x4000), 0.05f);
- approach_f32_asymptotic_bool(&gNewCamera.panZ, newcam_lengthdir_y((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->faceAngle[1] - 0x4000), 0.05f);
+ approach_f32_asymptotic_bool(&gNewCamera.panX, newcam_lengthdir_x((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->statusForCamera->faceAngle[1] - 0x4000), 0.05f);
+ approach_f32_asymptotic_bool(&gNewCamera.panZ, newcam_lengthdir_y((160.f * gNewCamera.panLevel) / 100.f, -gMarioState->statusForCamera->faceAngle[1] - 0x4000), 0.05f);
} else {
approach_f32_asymptotic_bool(&gNewCamera.panX, 0, 0.05f);
approach_f32_asymptotic_bool(&gNewCamera.panZ, 0, 0.05f);
@@ -538,7 +538,7 @@ static void newcam_level_bounds(void) {
static void newcam_position_cam(void) {
f32 floorY = 0;
f32 floorY2 = 0;
- if (!(gMarioState->action & ACT_FLAG_SWIMMING)) {
+ if (!(gMarioState->statusForCamera->action & ACT_FLAG_SWIMMING)) {
calc_y_to_curr_floor(&floorY, 1.f, 200.f, &floorY2, 0.9f, 200.f);
}
@@ -549,9 +549,9 @@ static void newcam_position_cam(void) {
// Fetch Mario's current position.
// Not hardcoded just for the sake of flexibility, though this specific bit is temp,
// because it won't always want to be focusing on Mario.
- gNewCamera.posTarget[0] = gMarioState->pos[0];
- gNewCamera.posTarget[1] = gMarioState->pos[1] + NEWCAM_MARIO_HEIGHT;
- gNewCamera.posTarget[2] = gMarioState->pos[2];
+ gNewCamera.posTarget[0] = gMarioState->statusForCamera->pos[0];
+ gNewCamera.posTarget[1] = gMarioState->statusForCamera->pos[1] + NEWCAM_MARIO_HEIGHT;
+ gNewCamera.posTarget[2] = gMarioState->statusForCamera->pos[2];
// These will set the position of the camera to where Mario is supposed to be,
// minus adjustments for where the camera should be, on top of.
@@ -607,7 +607,7 @@ static void newcam_apply_values(struct Camera *c) {
// The ingame cutscene system is such a spaghetti mess I actually have to resort to something as stupid as this to cover every base.
static void newcam_update_camera_yaw(struct Camera *c, bool useMarioYaw) {
if (useMarioYaw) {
- gNewCamera.yaw = -gMarioState->faceAngle[1] - 0x4000;
+ gNewCamera.yaw = -gMarioState->statusForCamera->faceAngle[1] - 0x4000;
} else {
gNewCamera.yaw = -c->yaw + 0x4000;
}
diff --git a/src/game/camera.c b/src/game/camera.c
index d455ef7fe..15de4b863 100644
--- a/src/game/camera.c
+++ b/src/game/camera.c
@@ -10947,10 +10947,12 @@ void cutscene_palette_editor(struct Camera *c) {
return;
}
+ bool capMissing = !(m->flags & (MARIO_CAP_ON_HEAD | MARIO_CAP_IN_HAND));
+
// Press the Z bind to toggle cap
static bool pressed = false;
if (gInteractablePad.button & PAD_BUTTON_Z) {
- if (!pressed && m->action == ACT_IDLE) {
+ if (!capMissing && !pressed && m->action == ACT_IDLE) {
set_mario_action(m, ACT_PALETTE_EDITOR_CAP, (m->flags & MARIO_CAP_ON_HEAD) != 0);
}
pressed = true;
@@ -10962,8 +10964,10 @@ void cutscene_palette_editor(struct Camera *c) {
if (gDjuiPaletteToggle) {
djui_base_set_visible(
&gDjuiPaletteToggle->base,
- m->action == ACT_IDLE ||
- m->action == ACT_PALETTE_EDITOR_CAP
+ (
+ m->action == ACT_IDLE ||
+ m->action == ACT_PALETTE_EDITOR_CAP
+ ) && !capMissing
);
}
@@ -12249,7 +12253,7 @@ static u8 rom_hack_cam_can_see_mario(Vec3f desiredPos) {
f32 mDist;
s16 mPitch;
s16 mYaw;
- vec3f_get_dist_and_angle(desiredPos, gMarioStates[0].pos, &mDist, &mPitch, &mYaw);
+ vec3f_get_dist_and_angle(desiredPos, sMarioCamState->pos, &mDist, &mPitch, &mYaw);
s16 degreeMult = sRomHackZoom ? 7 : 5;
@@ -12379,7 +12383,7 @@ void mode_rom_hack_camera(struct Camera *c) {
// Thank you hackersm64
if (gRomhackCameraSettings.dpad) {
if (gMarioStates[0].controller->buttonPressed & U_JPAD) {
- sRomHackYaw = DEGREES(180 + 90) - gMarioStates[0].faceAngle[1];
+ sRomHackYaw = DEGREES(180 + 90) - sMarioCamState->faceAngle[1];
} else if (gMarioStates[0].controller->buttonDown & L_JPAD) {
sRomHackYaw -= DEGREES(0.5) * (camera_config_is_x_inverted() ? 1 : -1);
} else if (gMarioStates[0].controller->buttonDown & R_JPAD) {
@@ -12408,7 +12412,7 @@ void mode_rom_hack_camera(struct Camera *c) {
// figure out desired position
f32 desiredDist = sRomHackZoom ? gRomhackCameraSettings.zoomedInDist : gRomhackCameraSettings.zoomedOutDist;
f32 desiredHeight = sRomHackZoom ? gRomhackCameraSettings.zoomedInHeight : gRomhackCameraSettings.zoomedOutHeight;
- f32* mPos = &gMarioStates[0].pos[0];
+ f32* mPos = &sMarioCamState->pos[0];
pos[0] = mPos[0] + coss(sRomHackYaw) * desiredDist;
pos[1] = mPos[1] + desiredHeight;
pos[2] = mPos[2] + sins(sRomHackYaw) * desiredDist;
@@ -12443,9 +12447,9 @@ void mode_rom_hack_camera(struct Camera *c) {
vec3f_normalize(dir);
// start at mario
- c->pos[0] = gMarioStates[0].pos[0];
- c->pos[1] = gMarioStates[0].pos[1] + 150;
- c->pos[2] = gMarioStates[0].pos[2];
+ c->pos[0] = sMarioCamState->pos[0];
+ c->pos[1] = sMarioCamState->pos[1] + 150;
+ c->pos[2] = sMarioCamState->pos[2];
rom_hack_cam_walk(c->pos, dir, desiredDist);
}
@@ -12489,8 +12493,8 @@ s32 update_rom_hack_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
// if rom hack camera was just set, figure out the yaw to use
if (!sRomHackIsUpdate) {
sRomHackYaw = DEGREES(90) - atan2s(
- c->pos[2] - gMarioStates[0].pos[2],
- c->pos[0] - gMarioStates[0].pos[0]);
+ c->pos[2] - sMarioCamState->pos[2],
+ c->pos[0] - sMarioCamState->pos[0]);
sRomHackYaw = (sRomHackYaw / DEGREES(45)) * DEGREES(45);
}
diff --git a/src/game/characters.c b/src/game/characters.c
index 4c0fce483..d751fba7d 100644
--- a/src/game/characters.c
+++ b/src/game/characters.c
@@ -35,7 +35,7 @@ struct Character gCharacters[CT_MAX] = {
.type = CT_MARIO,
.name = "Mario",
.hudHead = '(',
- .hudHeadTexture = { .texture = (u8*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_mario_head" },
+ .hudHeadTexture = { .texture = (Texture*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_mario_head" },
.cameraHudHead = GLYPH_CAM_MARIO_HEAD,
.modelId = MODEL_MARIO,
.capModelId = MODEL_MARIOS_CAP,
@@ -101,7 +101,7 @@ struct Character gCharacters[CT_MAX] = {
.type = CT_LUIGI,
.name = "Luigi",
.hudHead = ')',
- .hudHeadTexture = { .texture = (u8*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_luigi_head" },
+ .hudHeadTexture = { .texture = (Texture*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_luigi_head" },
.cameraHudHead = GLYPH_CAM_LUIGI_HEAD,
.modelId = MODEL_LUIGI,
.capModelId = MODEL_LUIGIS_CAP,
@@ -167,7 +167,7 @@ struct Character gCharacters[CT_MAX] = {
.type = CT_TOAD,
.name = "Toad",
.hudHead = '|',
- .hudHeadTexture = { .texture = (u8*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_toad_head" },
+ .hudHeadTexture = { .texture = (Texture*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_toad_head" },
.cameraHudHead = GLYPH_CAM_TOAD_HEAD,
.modelId = MODEL_TOAD_PLAYER,
.capModelId = MODEL_TOADS_CAP,
@@ -233,7 +233,7 @@ struct Character gCharacters[CT_MAX] = {
.type = CT_WALUIGI,
.name = "Waluigi",
.hudHead = ']',
- .hudHeadTexture = { .texture = (u8*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_waluigi_head" },
+ .hudHeadTexture = { .texture = (Texture*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_waluigi_head" },
.cameraHudHead = GLYPH_CAM_WALUIGI_HEAD,
.modelId = MODEL_WALUIGI,
.capModelId = MODEL_WALUIGIS_CAP,
@@ -299,7 +299,7 @@ struct Character gCharacters[CT_MAX] = {
.type = CT_WARIO,
.name = "Wario",
.hudHead = '[',
- .hudHeadTexture = { .texture = (u8*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_wario_head" },
+ .hudHeadTexture = { .texture = (Texture*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16, .name = "texture_hud_char_wario_head" },
.cameraHudHead = GLYPH_CAM_WARIO_HEAD,
.modelId = MODEL_WARIO,
.capModelId = MODEL_WARIOS_CAP,
diff --git a/src/game/hud.c b/src/game/hud.c
index 3397dc2bd..245edd56b 100644
--- a/src/game/hud.c
+++ b/src/game/hud.c
@@ -305,7 +305,7 @@ void render_hud_power_meter(void) {
#define HUD_TOP_Y 209
#endif
-void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) {
+void render_hud_icon(Vtx *vtx, const Texture *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH) {
create_dl_ortho_matrix();
if (!vtx) {
vtx = alloc_display_list(sizeof(Vtx) * 4);
diff --git a/src/game/hud.h b/src/game/hud.h
index 766c81312..e57031349 100644
--- a/src/game/hud.h
+++ b/src/game/hud.h
@@ -27,7 +27,7 @@ enum CameraHUDLut {
extern u8 gOverrideHideHud;
-void render_hud_icon(Vtx *vtx, const u8 *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH);
+void render_hud_icon(Vtx *vtx, const Texture *texture, u32 fmt, u32 siz, s32 texW, s32 texH, s32 x, s32 y, s32 w, s32 h, s32 tileX, s32 tileY, s32 tileW, s32 tileH);
s16 get_hud_camera_status(void);
void set_hud_camera_status(s16 status);
diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c
index 05334b243..8fe099c85 100644
--- a/src/game/mario_actions_stationary.c
+++ b/src/game/mario_actions_stationary.c
@@ -1162,13 +1162,20 @@ s32 act_first_person(struct MarioState *m) {
}
s32 mario_exit_palette_editor(struct MarioState *m, struct Camera *c) {
+ if (!(m->flags & (MARIO_CAP_ON_HEAD | MARIO_CAP_IN_HAND))) {
+ return FALSE;
+ }
+
switch (c->paletteEditorCapState) {
case 0: return FALSE;
case 1: cutscene_put_cap_on(m); break;
case 2: cutscene_take_cap_off(m); break;
}
c->paletteEditorCapState = 0;
- return set_mario_action(m, ACT_IDLE, 0);
+ if (m->action == ACT_PALETTE_EDITOR_CAP) {
+ set_mario_action(m, ACT_IDLE, 0);
+ }
+ return TRUE;
}
s32 act_palette_editor_cap(struct MarioState *m) {
diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c
index 2163116da..f2e742d69 100644
--- a/src/game/mario_misc.c
+++ b/src/game/mario_misc.c
@@ -788,8 +788,11 @@ static Gfx *geo_mario_create_player_colors_dl(s32 index, Gfx *capEnemyGfx, Gfx *
if (gfx) {
Gfx *gfxp = gfx;
for (s32 part = 0; part != PLAYER_PART_MAX; ++part) {
- gSPLight(gfxp++, &gNetworkPlayerColors[index].parts[part].l, (2 * (part + 1)) + 1);
- gSPLight(gfxp++, &gNetworkPlayerColors[index].parts[part].a, (2 * (part + 1)) + 2);
+ Lights1 *light = alloc_display_list(sizeof(Lights1));
+ if (!light) { return NULL; }
+ *light = gNetworkPlayerColors[index].parts[part];
+ gSPLight(gfxp++, &light->l, (2 * (part + 1)) + 1);
+ gSPLight(gfxp++, &light->a, (2 * (part + 1)) + 2);
}
if (capEnemyGfx) { gSPDisplayList(gfxp++, capEnemyGfx); }
if (capEnemyDecalGfx) { gSPDisplayList(gfxp++, capEnemyDecalGfx); }
diff --git a/src/game/memory.c b/src/game/memory.c
index 6018a6e33..feca24fd1 100644
--- a/src/game/memory.c
+++ b/src/game/memory.c
@@ -220,6 +220,32 @@ void *growing_array_alloc(struct GrowingArray *array, u32 size) {
return NULL;
}
+void growing_array_move(struct GrowingArray *array, u32 from, u32 to, u32 count) {
+ if (array && array->buffer && count > 0 &&
+ (to < from || to > from + count) &&
+ (from + count) <= array->count && to <= array->count) {
+
+ void **temp = malloc(sizeof(void *) * count);
+ if (!temp) { return; }
+
+ // Copy elements to move to temporary buffer
+ memcpy(temp, array->buffer + from, sizeof(void *) * count);
+
+ // Remove copied elements from the array
+ memmove(array->buffer + from, array->buffer + (from + count), sizeof(void *) * (array->count - (from + count)));
+
+ // Make place for the copied elements
+ // If moving left to right, account for the removed elements
+ if (to > from) { to -= count; }
+ memmove(array->buffer + (to + count), array->buffer + to, sizeof(void *) * (array->count - (to + count)));
+
+ // Insert copied elements
+ memcpy(array->buffer + to, temp, sizeof(void *) * count);
+
+ free(temp);
+ }
+}
+
void growing_array_free(struct GrowingArray **array) {
if (*array) {
for (u32 i = 0; i != (*array)->capacity; ++i) {
diff --git a/src/game/memory.h b/src/game/memory.h
index dba8f7535..d8f469814 100644
--- a/src/game/memory.h
+++ b/src/game/memory.h
@@ -77,6 +77,7 @@ void growing_pool_free_pool(struct GrowingPool *pool);
struct GrowingArray *growing_array_init(struct GrowingArray *array, u32 capacity, GrowingArrayAllocFunc alloc, GrowingArrayFreeFunc free);
void *growing_array_alloc(struct GrowingArray *array, u32 size);
+void growing_array_move(struct GrowingArray *array, u32 from, u32 to, u32 count);
void growing_array_free(struct GrowingArray **array);
void growing_array_debug_print(struct GrowingArray *array, const char *name, s32 x, s32 y);
diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c
index 3e901bdc7..1752ae7b4 100644
--- a/src/game/object_list_processor.c
+++ b/src/game/object_list_processor.c
@@ -122,27 +122,6 @@ const BehaviorScript *gCurBhvCommand;
*/
s16 gPrevFrameObjectCount;
-/**
- * The total number of surface nodes allocated (a node is allocated for each
- * spatial partition cell that a surface intersects).
- */
-s32 gSurfaceNodesAllocated;
-
-/**
- * The total number of surfaces allocated.
- */
-s32 gSurfacesAllocated;
-
-/**
- * The number of nodes that have been created for surfaces.
- */
-s32 gNumStaticSurfaceNodes;
-
-/**
- * The number of surfaces in the pool.
- */
-s32 gNumStaticSurfaces;
-
struct Object* gCheckingSurfaceCollisionsForObject = NULL;
s16 gCheckingSurfaceCollisionsForCamera;
s16 gFindFloorIncludeSurfaceIntangible;
diff --git a/src/game/object_list_processor.h b/src/game/object_list_processor.h
index 24a1acf27..98cb25a95 100644
--- a/src/game/object_list_processor.h
+++ b/src/game/object_list_processor.h
@@ -91,11 +91,6 @@ extern struct Object *gCurrentObject;
extern const BehaviorScript *gCurBhvCommand;
extern s16 gPrevFrameObjectCount;
-extern s32 gSurfaceNodesAllocated;
-extern s32 gSurfacesAllocated;
-extern s32 gNumStaticSurfaceNodes;
-extern s32 gNumStaticSurfaces;
-
extern struct Object* gCheckingSurfaceCollisionsForObject;
extern s16 gCheckingSurfaceCollisionsForCamera;
extern s16 gFindFloorIncludeSurfaceIntangible;
diff --git a/src/game/paintings.c b/src/game/paintings.c
index 574e6bc45..071337531 100644
--- a/src/game/paintings.c
+++ b/src/game/paintings.c
@@ -20,6 +20,7 @@
#include "obj_behaviors.h"
#include "level_update.h"
#include "pc/network/network_player.h"
+#include "pc/lua/utils/smlua_gfx_utils.h"
#include "print.h"
#include "hardcoded.h"
@@ -1537,6 +1538,31 @@ Gfx *display_painting_rippling(struct Painting *painting) {
return dlist;
}
+static Gfx *get_painting_normal_display_list(struct Painting *painting) {
+ const Gfx *normalDisplayList = painting->normalDisplayList;
+ if (!normalDisplayList) {
+ return NULL;
+ }
+
+ u32 dlistLength = gfx_get_length_no_sentinel(normalDisplayList);
+ Gfx *dlist = alloc_display_list(dlistLength * sizeof(Gfx));
+ if (!dlist) {
+ return NULL;
+ }
+
+ Gfx *gfx = dlist;
+ s8 textureIndex = 0;
+ for (u32 i = 0; i < dlistLength; ++i, gfx++, normalDisplayList++) {
+ *gfx = *normalDisplayList;
+
+ // Replace the texture pointer by the painting's corresponding texture
+ if (GFX_OP(normalDisplayList) == G_SETTIMG && textureIndex < painting->imageCount) {
+ gfx->words.w1 = (uintptr_t) painting->textureArray[textureIndex++];
+ }
+ }
+ return dlist;
+}
+
/**
* Render a normal painting.
*/
@@ -1547,8 +1573,14 @@ Gfx *display_painting_not_rippling(struct Painting *painting) {
if (dlist == NULL) {
return dlist;
}
+
+ Gfx *normalDisplayList = get_painting_normal_display_list(painting);
+ if (!normalDisplayList) {
+ return NULL;
+ }
+
gSPDisplayList(gfx++, painting_model_view_transform(painting));
- gSPDisplayList(gfx++, painting->normalDisplayList);
+ gSPDisplayList(gfx++, normalDisplayList);
gSPPopMatrix(gfx++, G_MTX_MODELVIEW);
gSPEndDisplayList(gfx);
return dlist;
diff --git a/src/game/paintings.h b/src/game/paintings.h
index 086c9fafd..98fe85fd8 100644
--- a/src/game/paintings.h
+++ b/src/game/paintings.h
@@ -109,7 +109,7 @@ struct Painting
const s16 *const *textureMaps;
// Texture data
- const Texture *const *textureArray;
+ const Texture *textureArray[2];
s16 textureWidth;
s16 textureHeight;
diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c
index 0edbfbf2f..c2a44de59 100644
--- a/src/game/rendering_graph_node.c
+++ b/src/game/rendering_graph_node.c
@@ -718,14 +718,12 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
mtxf_copy(gCamera->mtx, gMatStack[gMatStackIndex]);
}
- // compute inverse matrix for lighting engine
- if (le_is_enabled()) {
- Mat4 invCameraMatrix;
- if (mtxf_inverse_non_affine(invCameraMatrix, gCamera->mtx)) {
- Mtx *invMtx = alloc_display_list(sizeof(Mtx));
- mtxf_to_mtx(invMtx, invCameraMatrix);
- gSPMatrix(gDisplayListHead++, invMtx, G_MTX_INVERSE_CAMERA_EXT);
- }
+ // compute inverse matrix for lighting engine and fresnel
+ Mat4 invCameraMatrix;
+ if (mtxf_inverse_non_affine(invCameraMatrix, gCamera->mtx)) {
+ Mtx *invMtx = alloc_display_list(sizeof(Mtx));
+ mtxf_to_mtx(invMtx, invCameraMatrix);
+ gSPMatrix(gDisplayListHead++, invMtx, G_MTX_INVERSE_CAMERA_EXT);
}
if (node->fnNode.node.children != 0) {
@@ -1630,6 +1628,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
Mat4 mat;
Vec3f translation;
Vec3f scalePrev;
+ Vec3s anglePrev;
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB\.
if ((gMatStackIndex + 1) >= MATRIX_STACK_SIZE) { LOG_ERROR("Preventing attempt to exceed the maximum size %i for our matrix stack with size of %i.", MATRIX_STACK_SIZE - 1, gMatStackIndex); return; }
@@ -1650,19 +1649,29 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
if (gGlobalTimer == node->objNode->header.gfx.prevScaleTimestamp + 1) {
vec3f_copy(scalePrev, node->objNode->header.gfx.prevScale);
+ vec3s_copy(anglePrev, node->objNode->header.gfx.prevAngle);
} else {
vec3f_copy(scalePrev, node->objNode->header.gfx.scale);
+ vec3s_copy(anglePrev, node->objNode->header.gfx.angle);
}
vec3f_copy(node->objNode->header.gfx.prevScale, node->objNode->header.gfx.scale);
node->objNode->header.gfx.prevScaleTimestamp = gGlobalTimer;
- mtxf_translate(mat, translation);
+ if (node->objNode->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_ROTATE_HELD) {
+ vec3s_copy(node->objNode->header.gfx.prevAngle, node->objNode->header.gfx.angle);
+ mtxf_rotate_zxy_and_translate(mat, translation, node->objNode->header.gfx.angle);
+ } else {
+ mtxf_translate(mat, translation);
+ }
mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix);
gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0];
gMatStack[gMatStackIndex + 1][3][1] = gMatStack[gMatStackIndex][3][1];
gMatStack[gMatStackIndex + 1][3][2] = gMatStack[gMatStackIndex][3][2];
mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]);
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->objNode->header.gfx.scale);
+ if (node->objNode->header.gfx.sharedChild->extraFlags & GRAPH_EXTRA_ROTATE_HELD) {
+ mtxf_rotate_zxy_and_translate(mat, translation, anglePrev);
+ }
mtxf_copy(gMatStackPrev[gMatStackIndex + 1], (void *) gCurGraphNodeObject->throwMatrixPrev);
gMatStackPrev[gMatStackIndex + 1][3][0] = gMatStackPrev[gMatStackIndex][3][0];
gMatStackPrev[gMatStackIndex + 1][3][1] = gMatStackPrev[gMatStackIndex][3][1];
@@ -2005,4 +2014,4 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
gCurGraphNodeRoot = NULL;
}
-}
\ No newline at end of file
+}
diff --git a/src/pc/chat_commands.c b/src/pc/chat_commands.c
index 40d132b7d..adb2bec1e 100644
--- a/src/pc/chat_commands.c
+++ b/src/pc/chat_commands.c
@@ -8,6 +8,7 @@
#include "pc/network/moderator_list.h"
#include "pc/debuglog.h"
#include "pc/lua/utils/smlua_level_utils.h"
+#include "pc/mods/mods_utils.h"
#include "level_table.h"
#ifdef DEVELOPMENT
#include "pc/dev/chat.h"
@@ -39,10 +40,6 @@ static struct NetworkPlayer* chat_get_network_player(const char* name) {
return NULL;
}
-static bool str_starts_with(const char* pre, const char* str) {
- return strncmp(pre, str, strlen(pre)) == 0;
-}
-
static void chat_construct_player_message(struct NetworkPlayer* np, char* msg) {
char built[256] = { 0 };
snprintf(built, 256, "\\#fff982\\");
@@ -124,7 +121,7 @@ bool exec_chat_command(char* command) {
return true;
}
- if (str_starts_with("/kick ", command)) {
+ if (str_starts_with(command, "/kick ")) {
if (gNetworkType != NT_SERVER && !npl->moderator) {
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
return true;
@@ -152,7 +149,7 @@ bool exec_chat_command(char* command) {
return true;
}
- if (str_starts_with("/ban ", command)) {
+ if (str_starts_with(command, "/ban ")) {
if (gNetworkType != NT_SERVER && !npl->moderator) {
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
return true;
@@ -180,7 +177,7 @@ bool exec_chat_command(char* command) {
return true;
}
- if (str_starts_with("/permban ", command)) {
+ if (str_starts_with(command, "/permban ")) {
if (gNetworkType != NT_SERVER && !npl->moderator) {
djui_chat_message_create(DLANG(CHAT, NO_PERMS));
return true;
@@ -208,7 +205,7 @@ bool exec_chat_command(char* command) {
return true;
}
- if (str_starts_with("/moderator ", command)) {
+ if (str_starts_with(command, "/moderator ")) {
if (gNetworkType != NT_SERVER) {
djui_chat_message_create(DLANG(CHAT, SERVER_ONLY));
return true;
@@ -237,7 +234,7 @@ bool exec_chat_command(char* command) {
return true;
}
- if (str_starts_with("/nametags ", command)) {
+ if (str_starts_with(command, "/nametags ")) {
char *option = &command[10];
if (strcmp("show-tag", option) == 0) {
gNametagsSettings.showSelfTag = !gNametagsSettings.showSelfTag;
diff --git a/src/pc/dev/chat.c b/src/pc/dev/chat.c
index dc5a08fc1..7118c4665 100644
--- a/src/pc/dev/chat.c
+++ b/src/pc/dev/chat.c
@@ -8,15 +8,12 @@
#include "pc/network/moderator_list.h"
#include "pc/debuglog.h"
#include "pc/lua/utils/smlua_level_utils.h"
+#include "pc/mods/mods_utils.h"
#include "level_table.h"
#include "game/save_file.h"
#ifdef DEVELOPMENT
-static bool str_starts_with(const char* pre, char* str) {
- return strncmp(pre, str, strlen(pre)) == 0;
-}
-
// For case insensitivity
static const char *upper(char *str) {
static char buffer[50];
@@ -74,7 +71,7 @@ bool exec_dev_chat_command(char* command) {
return true;
}
- if (str_starts_with("/warp ", command)) {
+ if (str_starts_with(command, "/warp ")) {
static const struct { const char *name; s32 num; } sLevelNumByName[] = {
#undef STUB_LEVEL
#undef DEFINE_LEVEL
@@ -169,7 +166,7 @@ bool exec_dev_chat_command(char* command) {
return true;
}
- if (str_starts_with("/lua ", command)) {
+ if (str_starts_with(command, "/lua ")) {
smlua_exec_str(&command[5]);
return true;
}
@@ -179,7 +176,7 @@ bool exec_dev_chat_command(char* command) {
return true;
}
- if (str_starts_with("/luaf ", command)) {
+ if (str_starts_with(command, "/luaf ")) {
smlua_exec_file(&command[6]);
return true;
}
diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c
index 5a9d2bbcf..6e347b8e3 100644
--- a/src/pc/djui/djui_gfx.c
+++ b/src/pc/djui/djui_gfx.c
@@ -123,13 +123,13 @@ static u8 djui_gfx_power_of_two(u32 value) {
}
}
-void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize, bool filter) {
+void djui_gfx_render_texture(const Texture* texture, u32 w, u32 h, u32 bitSize, bool filter) {
gDPSetTextureFilter(gDisplayListHead++, filter ? G_TF_BILERP : G_TF_POINT);
gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize);
gSPDisplayList(gDisplayListHead++, dl_djui_image);
}
-void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font) {
+void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font) {
if (!gDisplayListHead) {
LOG_ERROR("Retrieved a null displaylist head");
return;
diff --git a/src/pc/djui/djui_gfx.h b/src/pc/djui/djui_gfx.h
index a49227983..93622d0ad 100644
--- a/src/pc/djui/djui_gfx.h
+++ b/src/pc/djui/djui_gfx.h
@@ -15,8 +15,8 @@ void djui_gfx_displaylist_end(void);
f32 djui_gfx_get_scale(void);
-void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize, bool filter);
-void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font);
+void djui_gfx_render_texture(const Texture* texture, u32 w, u32 h, u32 bitSize, bool filter);
+void djui_gfx_render_texture_tile(const Texture* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH, bool filter, bool font);
void gfx_get_dimensions(u32* width, u32* height);
diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c
index 7fe351d93..ae2485891 100644
--- a/src/pc/djui/djui_hud_utils.c
+++ b/src/pc/djui/djui_hud_utils.c
@@ -51,20 +51,20 @@ extern ALIGNED8 const u8 texture_hud_char_apostrophe[];
extern ALIGNED8 const u8 texture_hud_char_double_quote[];
struct GlobalTextures gGlobalTextures = {
- .camera = { .texture = (u8*)texture_hud_char_camera, "texture_hud_char_camera", .width = 16, .height = 16, .bitSize = 8 },
- .lakitu = { .texture = (u8*)texture_hud_char_lakitu, "texture_hud_char_lakitu", .width = 16, .height = 16, .bitSize = 8 },
- .no_camera = { .texture = (u8*)texture_hud_char_no_camera, "texture_hud_char_no_camera", .width = 16, .height = 16, .bitSize = 8 },
- .arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, "texture_hud_char_arrow_up", .width = 8, .height = 8, .bitSize = 8 },
- .arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, "texture_hud_char_arrow_down", .width = 8, .height = 8, .bitSize = 8 },
- .coin = { .texture = (u8*)texture_hud_char_coin, "texture_hud_char_coin", .width = 16, .height = 16, .bitSize = 8 },
- .star = { .texture = (u8*)texture_hud_char_star, "texture_hud_char_star", .width = 16, .height = 16, .bitSize = 8 },
- .apostrophe = { .texture = (u8*)texture_hud_char_apostrophe, "texture_hud_char_apostrophe", .width = 16, .height = 16, .bitSize = 8 },
- .double_quote = { .texture = (u8*)texture_hud_char_double_quote, "texture_hud_char_double_quote", .width = 16, .height = 16, .bitSize = 8 },
- .mario_head = { .texture = (u8*)texture_hud_char_mario_head, "texture_hud_char_mario_head", .width = 16, .height = 16, .bitSize = 8 },
- .luigi_head = { .texture = (u8*)texture_hud_char_luigi_head, "texture_hud_char_luigi_head", .width = 16, .height = 16, .bitSize = 8 },
- .toad_head = { .texture = (u8*)texture_hud_char_toad_head, "texture_hud_char_toad_head", .width = 16, .height = 16, .bitSize = 8 },
- .waluigi_head = { .texture = (u8*)texture_hud_char_waluigi_head, "texture_hud_char_waluigi_head", .width = 16, .height = 16, .bitSize = 8 },
- .wario_head = { .texture = (u8*)texture_hud_char_wario_head, "texture_hud_char_wario_head", .width = 16, .height = 16, .bitSize = 8 }
+ .camera = { .texture = (Texture*)texture_hud_char_camera, "texture_hud_char_camera", .width = 16, .height = 16, .bitSize = 8 },
+ .lakitu = { .texture = (Texture*)texture_hud_char_lakitu, "texture_hud_char_lakitu", .width = 16, .height = 16, .bitSize = 8 },
+ .no_camera = { .texture = (Texture*)texture_hud_char_no_camera, "texture_hud_char_no_camera", .width = 16, .height = 16, .bitSize = 8 },
+ .arrow_up = { .texture = (Texture*)texture_hud_char_arrow_up, "texture_hud_char_arrow_up", .width = 8, .height = 8, .bitSize = 8 },
+ .arrow_down = { .texture = (Texture*)texture_hud_char_arrow_down, "texture_hud_char_arrow_down", .width = 8, .height = 8, .bitSize = 8 },
+ .coin = { .texture = (Texture*)texture_hud_char_coin, "texture_hud_char_coin", .width = 16, .height = 16, .bitSize = 8 },
+ .star = { .texture = (Texture*)texture_hud_char_star, "texture_hud_char_star", .width = 16, .height = 16, .bitSize = 8 },
+ .apostrophe = { .texture = (Texture*)texture_hud_char_apostrophe, "texture_hud_char_apostrophe", .width = 16, .height = 16, .bitSize = 8 },
+ .double_quote = { .texture = (Texture*)texture_hud_char_double_quote, "texture_hud_char_double_quote", .width = 16, .height = 16, .bitSize = 8 },
+ .mario_head = { .texture = (Texture*)texture_hud_char_mario_head, "texture_hud_char_mario_head", .width = 16, .height = 16, .bitSize = 8 },
+ .luigi_head = { .texture = (Texture*)texture_hud_char_luigi_head, "texture_hud_char_luigi_head", .width = 16, .height = 16, .bitSize = 8 },
+ .toad_head = { .texture = (Texture*)texture_hud_char_toad_head, "texture_hud_char_toad_head", .width = 16, .height = 16, .bitSize = 8 },
+ .waluigi_head = { .texture = (Texture*)texture_hud_char_waluigi_head, "texture_hud_char_waluigi_head", .width = 16, .height = 16, .bitSize = 8 },
+ .wario_head = { .texture = (Texture*)texture_hud_char_wario_head, "texture_hud_char_wario_head", .width = 16, .height = 16, .bitSize = 8 }
};
static void djui_hud_position_translate(f32* x, f32* y) {
@@ -495,7 +495,7 @@ static inline bool is_power_of_two(u32 n) {
return (n > 0) && ((n & (n - 1)) == 0);
}
-void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH) {
+void djui_hud_render_texture_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH) {
if (!is_power_of_two(width) || !is_power_of_two(height)) {
LOG_LUA_LINE("Tried to render DJUI HUD texture with NPOT width or height");
return;
@@ -534,7 +534,7 @@ void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
}
-void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) {
+void djui_hud_render_texture_tile_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) {
if (!texture) { return; }
gDjuiHudUtilsZ += 0.01f;
diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h
index 2e2748be4..13efed6c8 100644
--- a/src/pc/djui/djui_hud_utils.h
+++ b/src/pc/djui/djui_hud_utils.h
@@ -121,10 +121,10 @@ void djui_hud_print_text(const char* message, f32 x, f32 y, f32 scale);
void djui_hud_print_text_interpolated(const char* message, f32 prevX, f32 prevY, f32 prevScale, f32 x, f32 y, f32 scale);
/* |description|Renders a DJUI HUD texture onto the screen|descriptionEnd| */
void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH);
-void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH);
+void djui_hud_render_texture_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH);
/* |description|Renders a DJUI HUD texture tile onto the screen|descriptionEnd| */
void djui_hud_render_texture_tile(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH);
-void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH);
+void djui_hud_render_texture_tile_raw(const Texture* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH);
/* |description|Renders an interpolated DJUI HUD texture onto the screen|descriptionEnd| */
void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH);
/* |description|Renders an interpolated DJUI HUD texture tile onto the screen|descriptionEnd| */
diff --git a/src/pc/djui/djui_image.c b/src/pc/djui/djui_image.c
index f227421c7..fa1101bc7 100644
--- a/src/pc/djui/djui_image.c
+++ b/src/pc/djui/djui_image.c
@@ -6,7 +6,7 @@
// properties //
////////////////
-void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
+void djui_image_set_image(struct DjuiImage* image, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
image->texture = texture;
image->textureWidth = textureWidth;
image->textureHeight = textureHeight;
@@ -48,7 +48,7 @@ static void djui_image_destroy(struct DjuiBase* base) {
free(image);
}
-struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
+struct DjuiImage* djui_image_create(struct DjuiBase* parent, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize) {
struct DjuiImage* image = calloc(1, sizeof(struct DjuiImage));
struct DjuiBase* base = &image->base;
diff --git a/src/pc/djui/djui_image.h b/src/pc/djui/djui_image.h
index 84ffb35da..88b2d0b7d 100644
--- a/src/pc/djui/djui_image.h
+++ b/src/pc/djui/djui_image.h
@@ -3,12 +3,12 @@
struct DjuiImage {
struct DjuiBase base;
- const u8* texture;
+ const Texture* texture;
u16 textureWidth;
u16 textureHeight;
u16 textureBitSize;
};
-void djui_image_set_image(struct DjuiImage* image, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
+void djui_image_set_image(struct DjuiImage* image, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
-struct DjuiImage* djui_image_create(struct DjuiBase* parent, const u8* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
+struct DjuiImage* djui_image_create(struct DjuiBase* parent, const Texture* texture, u16 textureWidth, u16 textureHeight, u16 textureBitSize);
diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c
index 21329aca6..9c1a6b62e 100644
--- a/src/pc/gfx/gfx_pc.c
+++ b/src/pc/gfx/gfx_pc.c
@@ -61,6 +61,7 @@ static struct RSP {
uint32_t geometry_mode;
int16_t fog_mul, fog_offset;
+ int16_t fresnel_scale, fresnel_offset;
struct {
// U0.16
@@ -850,6 +851,33 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
d->color.b *= vtxB;
}
+ if (rsp.geometry_mode & (G_FRESNEL_COLOR_EXT | G_FRESNEL_ALPHA_EXT)) {
+ Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
+ Vec3f vnormal = { nx / 255.0f, ny / 255.0f, nz / 255.0f };
+ // transform vpos and vnormal to world space
+ gfx_local_to_world_space(vpos, vnormal);
+
+ Vec3f viewDir = {
+ sInverseCameraMatrix[3][0] - vpos[0],
+ sInverseCameraMatrix[3][1] - vpos[1],
+ sInverseCameraMatrix[3][2] - vpos[2]
+ };
+ vec3f_normalize(viewDir);
+ vec3f_normalize(vnormal);
+
+ int32_t dot = (int32_t) (fabsf(vec3f_dot(vnormal, viewDir)) * 32767.0f);
+ int32_t factor = ((rsp.fresnel_scale * dot) >> 15) + rsp.fresnel_offset;
+ int32_t fresnel = clamp(factor << 8, 0, 0x7FFF);
+ uint8_t result = (uint8_t) (fresnel >> 7);
+
+ if (rsp.geometry_mode & G_FRESNEL_COLOR_EXT) {
+ d->color.r = d->color.g = d->color.b = result;
+ }
+ if (rsp.geometry_mode & G_FRESNEL_ALPHA_EXT) {
+ d->color.a = result;
+ }
+ }
+
if (rsp.geometry_mode & G_TEXTURE_GEN) {
float dotx = 0, doty = 0;
dotx += nx * rsp.current_lookat_coeffs[0][0];
@@ -970,8 +998,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
if (fog_z > 255) fog_z = 255;
d->fog_z = fog_z;
}
-
- d->color.a = v->cn[3];
+ if (!(rsp.geometry_mode & G_FRESNEL_ALPHA_EXT)) {
+ d->color.a = v->cn[3];
+ }
}
}
@@ -999,6 +1028,11 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t
cross = -cross;
}
+ // Invert culling: back becomes front and front becomes back
+ if (rsp.geometry_mode & G_CULL_INVERT_EXT) {
+ cross = -cross;
+ }
+
switch (rsp.geometry_mode & G_CULL_BOTH) {
case G_CULL_FRONT:
if (cross <= 0) return;
@@ -1297,7 +1331,7 @@ static void gfx_sp_copymem(uint8_t idx, uint16_t dstofs, uint16_t srcofs, UNUSED
}
#endif
-static void gfx_sp_moveword(uint8_t index, UNUSED uint16_t offset, uint32_t data) {
+static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) {
switch (index) {
case G_MW_NUMLIGHT:
#ifdef F3DEX_GBI_2
@@ -1319,6 +1353,22 @@ static void gfx_sp_moveword(uint8_t index, UNUSED uint16_t offset, uint32_t data
sDepthZSub = gProjectionVanillaNearValue;
break;
+ case G_MW_FX:
+ if (offset == G_MWO_FRESNEL) {
+ rsp.fresnel_scale = (int16_t)(data >> 16);
+ rsp.fresnel_offset = (int16_t)data;
+ }
+ break;
+ case G_MW_LIGHTCOL: {
+ int lightNum = offset / 24;
+ // data = packed color
+ if (lightNum >= 0 && lightNum <= MAX_LIGHTS) {
+ rsp.current_lights[lightNum].col[0] = (uint8_t)(data >> 24);
+ rsp.current_lights[lightNum].col[1] = (uint8_t)(data >> 16);
+ rsp.current_lights[lightNum].col[2] = (uint8_t)(data >> 8);
+ }
+ break;
+ }
}
}
diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c
index b93b5679a..cd2502050 100644
--- a/src/pc/lua/smlua.c
+++ b/src/pc/lua/smlua.c
@@ -4,6 +4,8 @@
#include "game/hardcoded.h"
#include "pc/mods/mods.h"
#include "pc/mods/mods_utils.h"
+#include "pc/mods/mod_storage.h"
+#include "pc/mods/mod_fs.h"
#include "pc/crash_handler.h"
#include "pc/lua/utils/smlua_text_utils.h"
#include "pc/lua/utils/smlua_audio_utils.h"
@@ -352,7 +354,7 @@ void smlua_init(void) {
for (int j = 0; j < mod->fileCount; j++) {
struct ModFile* file = &mod->files[j];
// skip loading non-lua files
- if (!(str_ends_with(file->relativePath, ".lua") || str_ends_with(file->relativePath, ".luac"))) {
+ if (!(path_ends_with(file->relativePath, ".lua") || path_ends_with(file->relativePath, ".luac"))) {
continue;
}
@@ -362,7 +364,19 @@ void smlua_init(void) {
}
gLuaActiveModFile = file;
- smlua_load_script(mod, file, i, true);
+
+ // file has been required by some module before this
+ if (!smlua_get_cached_module_result(L, mod, file)) {
+ smlua_mark_module_as_loading(L, mod, file);
+
+ s32 prevTop = lua_gettop(L);
+ int rc = smlua_load_script(mod, file, i, true);
+
+ if (rc == LUA_OK) {
+ smlua_cache_module_result(L, mod, file, prevTop);
+ }
+ }
+
lua_settop(L, 0);
}
gLuaActiveMod = NULL;
@@ -406,6 +420,8 @@ void smlua_shutdown(void) {
smlua_model_util_clear();
smlua_level_util_reset();
smlua_anim_util_reset();
+ mod_storage_shutdown();
+ mod_fs_shutdown();
lua_State* L = gLuaState;
if (L != NULL) {
lua_close(L);
diff --git a/src/pc/lua/smlua_autogen.h b/src/pc/lua/smlua_autogen.h
index 53b49e5ed..5267c76e6 100644
--- a/src/pc/lua/smlua_autogen.h
+++ b/src/pc/lua/smlua_autogen.h
@@ -13,4 +13,7 @@
// Optional parameters must be contiguous until the last parameter (a mandatory parameter following an optional parameter is not allowed)
#define OPTIONAL
+// A macro to tell autogen the field `name` is a function member of the struct that calls `c_function`
+#define FUNCTION(name, c_function)
+
#endif // SMLUA_AUTOGEN_H
diff --git a/src/pc/lua/smlua_cobject.c b/src/pc/lua/smlua_cobject.c
index 67b47ecf4..4f7da423a 100644
--- a/src/pc/lua/smlua_cobject.c
+++ b/src/pc/lua/smlua_cobject.c
@@ -68,7 +68,7 @@ bool smlua_valid_lvt(u16 lvt) {
return (lvt < LVT_MAX);
}
-const char *sLuaLvtNames[] = {
+static const char *sLuaLvtNames[] = {
[LVT_BOOL] = "bool",
[LVT_BOOL_P] = "bool Pointer",
[LVT_U8] = "u8",
@@ -91,18 +91,16 @@ const char *sLuaLvtNames[] = {
[LVT_COBJECT_P] = "CObject Pointer",
[LVT_STRING] = "string",
[LVT_STRING_P] = "string Pointer",
- [LVT_BEHAVIORSCRIPT] = "BehaviorScript",
[LVT_BEHAVIORSCRIPT_P] = "BehaviorScript Pointer",
- [LVT_OBJECTANIMPOINTER] = "ObjectAnimPointer",
[LVT_OBJECTANIMPOINTER_P] = "ObjectAnimPointer Pointer",
- [LVT_COLLISION] = "Collision",
[LVT_COLLISION_P] = "Collision Pointer",
- [LVT_LEVELSCRIPT] = "LevelScript",
[LVT_LEVELSCRIPT_P] = "LevelScript Pointer",
- [LVT_TRAJECTORY] = "Trajectory",
[LVT_TRAJECTORY_P] = "Trajectory Pointer",
+ [LVT_TEXTURE_P] = "Texture Pointer",
[LVT_LUAFUNCTION] = "LuaFunction",
+ [LVT_LUATABLE] = "LuaTable",
[LVT_POINTER] = "Pointer",
+ [LVT_FUNCTION] = "Function",
[LVT_MAX] = "Max",
};
@@ -373,24 +371,19 @@ struct LuaObjectField* smlua_get_custom_field(lua_State* L, u32 lot, int keyInde
static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) {
switch (data->valueType) {
- case LVT_BOOL: lua_pushboolean(L, *(u8* )p); break;
- case LVT_U8: lua_pushinteger(L, *(u8* )p); break;
- case LVT_U16: lua_pushinteger(L, *(u16*)p); break;
- case LVT_U32: lua_pushinteger(L, *(u32*)p); break;
- case LVT_S8: lua_pushinteger(L, *(s8* )p); break;
- case LVT_S16: lua_pushinteger(L, *(s16*)p); break;
- case LVT_S32: lua_pushinteger(L, *(s32*)p); break;
- case LVT_F32: lua_pushnumber( L, *(f32*)p); break;
- case LVT_U64: lua_pushinteger(L, *(u64*)p); break;
- case LVT_COBJECT: smlua_push_object(L, data->lot, p, NULL); break;
- case LVT_COBJECT_P: smlua_push_object(L, data->lot, *(u8**)p, NULL); break;
- case LVT_STRING: lua_pushstring(L, (char*)p); break;
- case LVT_STRING_P: lua_pushstring(L, *(char**)p); break;
- case LVT_BEHAVIORSCRIPT: lua_pushinteger(L, *(s32*)p); break;
- case LVT_OBJECTANIMPOINTER: lua_pushinteger(L, *(s32*)p); break;
- case LVT_COLLISION: lua_pushinteger(L, *(s32*)p); break;
- case LVT_LEVELSCRIPT: lua_pushinteger(L, *(s32*)p); break;
- case LVT_TRAJECTORY: lua_pushinteger(L, *(s16*)p); break;
+ case LVT_BOOL: lua_pushboolean(L, *(u8* )p); break;
+ case LVT_U8: lua_pushinteger(L, *(u8* )p); break;
+ case LVT_U16: lua_pushinteger(L, *(u16*)p); break;
+ case LVT_U32: lua_pushinteger(L, *(u32*)p); break;
+ case LVT_S8: lua_pushinteger(L, *(s8* )p); break;
+ case LVT_S16: lua_pushinteger(L, *(s16*)p); break;
+ case LVT_S32: lua_pushinteger(L, *(s32*)p); break;
+ case LVT_F32: lua_pushnumber( L, *(f32*)p); break;
+ case LVT_U64: lua_pushinteger(L, *(u64*)p); break;
+ case LVT_COBJECT: smlua_push_object(L, data->lot, p, NULL); break;
+ case LVT_COBJECT_P: smlua_push_object(L, data->lot, *(u8**)p, NULL); break;
+ case LVT_STRING: lua_pushstring(L, (char*)p); break;
+ case LVT_STRING_P: lua_pushstring(L, *(char**)p); break;
// pointers
case LVT_BOOL_P:
@@ -407,6 +400,7 @@ static bool smlua_push_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_COLLISION_P:
case LVT_LEVELSCRIPT_P:
case LVT_TRAJECTORY_P:
+ case LVT_TEXTURE_P:
smlua_push_pointer(L, data->valueType, *(u8**)p, NULL);
break;
@@ -453,7 +447,9 @@ static bool smlua_set_field(lua_State* L, u8* p, struct LuaObjectField *data) {
case LVT_BEHAVIORSCRIPT_P:
case LVT_OBJECTANIMPOINTER_P:
case LVT_COLLISION_P:
+ case LVT_LEVELSCRIPT_P:
case LVT_TRAJECTORY_P:
+ case LVT_TEXTURE_P:
if (lua_isnil(L, 3)) {
*(u8**)p = NULL;
break;
@@ -555,6 +551,14 @@ static int smlua__get_field(lua_State* L) {
return 0;
}
+ // CObject function members
+ if (data->valueType == LVT_FUNCTION) {
+ const char *function = (const char *) data->valueOffset;
+ lua_getglobal(L, function);
+ LUA_STACK_CHECK_END(L);
+ return 1;
+ }
+
u8* p = ((u8*)(intptr_t)pointer) + data->valueOffset;
if (data->count == 1) {
if (smlua_push_field(L, p, data)) {
@@ -656,6 +660,12 @@ int smlua__eq(lua_State *L) {
return 1;
}
+int smlua__bnot(lua_State *L) {
+ const CObject *a = lua_touserdata(L, 1);
+ lua_pushboolean(L, !a || a->freed);
+ return 1;
+}
+
static int smlua_cpointer_get(lua_State* L) {
const CPointer *cptr = lua_touserdata(L, 1);
const char *key = lua_tostring(L, 2);
@@ -696,6 +706,7 @@ void smlua_cobject_init_globals(void) {
{ "__index", smlua__get_field },
{ "__newindex", smlua__set_field },
{ "__eq", smlua__eq },
+ { "__bnot", smlua__bnot },
{ "__metatable", NULL },
{ NULL, NULL }
};
@@ -706,6 +717,7 @@ void smlua_cobject_init_globals(void) {
{ "__index", smlua_cpointer_get },
{ "__newindex", smlua_cpointer_set },
{ "__eq", smlua__eq },
+ { "__bnot", smlua__bnot },
{ "__metatable", NULL },
{ NULL, NULL }
};
diff --git a/src/pc/lua/smlua_cobject.h b/src/pc/lua/smlua_cobject.h
index 403f4e828..83cac836d 100644
--- a/src/pc/lua/smlua_cobject.h
+++ b/src/pc/lua/smlua_cobject.h
@@ -1,6 +1,8 @@
#ifndef SMLUA_COBJECT_H
#define SMLUA_COBJECT_H
+#include "lua.h"
+
enum LuaValueType {
LVT_BOOL,
LVT_BOOL_P,
@@ -24,18 +26,16 @@ enum LuaValueType {
LVT_COBJECT_P,
LVT_STRING,
LVT_STRING_P,
- LVT_BEHAVIORSCRIPT,
LVT_BEHAVIORSCRIPT_P,
- LVT_OBJECTANIMPOINTER,
LVT_OBJECTANIMPOINTER_P,
- LVT_COLLISION,
LVT_COLLISION_P,
- LVT_LEVELSCRIPT,
LVT_LEVELSCRIPT_P,
- LVT_TRAJECTORY,
LVT_TRAJECTORY_P,
+ LVT_TEXTURE_P,
LVT_LUAFUNCTION,
+ LVT_LUATABLE,
LVT_POINTER,
+ LVT_FUNCTION,
LVT_MAX,
};
diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c
index 0fb70f2a1..aeec902f6 100644
--- a/src/pc/lua/smlua_cobject_autogen.c
+++ b/src/pc/lua/smlua_cobject_autogen.c
@@ -201,7 +201,7 @@ static struct LuaObjectField sAnimationTableFields[LUA_ANIMATION_TABLE_FIELD_COU
#define LUA_AREA_FIELD_COUNT 21
static struct LuaObjectField sAreaFields[LUA_AREA_FIELD_COUNT] = {
{ "camera", LVT_COBJECT_P, offsetof(struct Area, camera), false, LOT_CAMERA, 1, sizeof(struct Camera*) },
- { "dialog", LVT_U8, offsetof(struct Area, dialog), false, LOT_NONE, 2, sizeof(u8) },
+ { "dialog", LVT_S32, offsetof(struct Area, dialog), false, LOT_NONE, 2, sizeof(s32) },
{ "flags", LVT_S8, offsetof(struct Area, flags), false, LOT_NONE, 1, sizeof(s8) },
{ "index", LVT_S8, offsetof(struct Area, index), false, LOT_NONE, 1, sizeof(s8) },
{ "instantWarps", LVT_COBJECT_P, offsetof(struct Area, instantWarps), false, LOT_INSTANTWARP, 1, sizeof(struct InstantWarp*) },
@@ -1607,10 +1607,10 @@ static struct LuaObjectField sModFields[LUA_MOD_FIELD_COUNT] = {
#define LUA_MOD_AUDIO_FIELD_COUNT 4
static struct LuaObjectField sModAudioFields[LUA_MOD_AUDIO_FIELD_COUNT] = {
- { "baseVolume", LVT_F32, offsetof(struct ModAudio, baseVolume), false, LOT_NONE, 1, sizeof(f32) },
- { "file", LVT_COBJECT_P, offsetof(struct ModAudio, file), false, LOT_MODFILE, 1, sizeof(struct ModFile*) },
- { "isStream", LVT_BOOL, offsetof(struct ModAudio, isStream), true, LOT_NONE, 1, sizeof(bool) },
- { "loaded", LVT_BOOL, offsetof(struct ModAudio, loaded), true, LOT_NONE, 1, sizeof(bool) },
+ { "baseVolume", LVT_F32, offsetof(struct ModAudio, baseVolume), false, LOT_NONE, 1, sizeof(f32) },
+ { "filepath", LVT_STRING_P, offsetof(struct ModAudio, filepath), true, LOT_NONE, 1, sizeof(const char*) },
+ { "isStream", LVT_BOOL, offsetof(struct ModAudio, isStream), true, LOT_NONE, 1, sizeof(bool) },
+ { "loaded", LVT_BOOL, offsetof(struct ModAudio, loaded), true, LOT_NONE, 1, sizeof(bool) },
};
#define LUA_MOD_AUDIO_SAMPLE_COPIES_FIELD_COUNT 3
@@ -1634,23 +1634,83 @@ static struct LuaObjectField sModFileFields[LUA_MOD_FILE_FIELD_COUNT] = {
{ "wroteBytes", LVT_U64, offsetof(struct ModFile, wroteBytes), true, LOT_NONE, 1, sizeof(u64) },
};
-#define LUA_MOD_FS_FIELD_COUNT 5
+static const char FUNCTION__mod_fs_clear[] = "mod_fs_clear";
+static const char FUNCTION__mod_fs_copy_file[] = "mod_fs_copy_file";
+static const char FUNCTION__mod_fs_create_file[] = "mod_fs_create_file";
+static const char FUNCTION__mod_fs_delete[] = "mod_fs_delete";
+static const char FUNCTION__mod_fs_delete_file[] = "mod_fs_delete_file";
+static const char FUNCTION__mod_fs_get_file[] = "mod_fs_get_file";
+static const char FUNCTION__mod_fs_get_filename[] = "mod_fs_get_filename";
+static const char FUNCTION__mod_fs_move_file[] = "mod_fs_move_file";
+static const char FUNCTION__mod_fs_save[] = "mod_fs_save";
+static const char FUNCTION__mod_fs_set_public[] = "mod_fs_set_public";
+
+#define LUA_MOD_FS_FIELD_COUNT 15
static struct LuaObjectField sModFsFields[LUA_MOD_FS_FIELD_COUNT] = {
- { "isPublic", LVT_BOOL, offsetof(struct ModFs, isPublic), true, LOT_NONE, 1, sizeof(bool) },
- { "mod", LVT_COBJECT_P, offsetof(struct ModFs, mod), true, LOT_MOD, 1, sizeof(struct Mod*) },
- { "modPath", LVT_STRING, offsetof(struct ModFs, modPath), true, LOT_NONE, 1, sizeof(char) },
- { "numFiles", LVT_U16, offsetof(struct ModFs, numFiles), true, LOT_NONE, 1, sizeof(u16) },
- { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) },
+ { "clear", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_clear, true, LOT_NONE, 1, sizeof(const char *) },
+ { "copy_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_copy_file, true, LOT_NONE, 1, sizeof(const char *) },
+ { "create_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_create_file, true, LOT_NONE, 1, sizeof(const char *) },
+ { "delete", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_delete, true, LOT_NONE, 1, sizeof(const char *) },
+ { "delete_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_delete_file, true, LOT_NONE, 1, sizeof(const char *) },
+ { "get_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_get_file, true, LOT_NONE, 1, sizeof(const char *) },
+ { "get_filename", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_get_filename, true, LOT_NONE, 1, sizeof(const char *) },
+ { "isPublic", LVT_BOOL, offsetof(struct ModFs, isPublic), true, LOT_NONE, 1, sizeof(bool) },
+ { "mod", LVT_COBJECT_P, offsetof(struct ModFs, mod), true, LOT_MOD, 1, sizeof(struct Mod*) },
+ { "modPath", LVT_STRING, offsetof(struct ModFs, modPath), true, LOT_NONE, 1, sizeof(char) },
+ { "move_file", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_move_file, true, LOT_NONE, 1, sizeof(const char *) },
+ { "numFiles", LVT_U16, offsetof(struct ModFs, numFiles), true, LOT_NONE, 1, sizeof(u16) },
+ { "save", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_save, true, LOT_NONE, 1, sizeof(const char *) },
+ { "set_public", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_set_public, true, LOT_NONE, 1, sizeof(const char *) },
+ { "totalSize", LVT_U32, offsetof(struct ModFs, totalSize), true, LOT_NONE, 1, sizeof(u32) },
};
-#define LUA_MOD_FS_FILE_FIELD_COUNT 6
+static const char FUNCTION__mod_fs_file_erase[] = "mod_fs_file_erase";
+static const char FUNCTION__mod_fs_file_fill[] = "mod_fs_file_fill";
+static const char FUNCTION__mod_fs_file_is_eof[] = "mod_fs_file_is_eof";
+static const char FUNCTION__mod_fs_file_read_bool[] = "mod_fs_file_read_bool";
+static const char FUNCTION__mod_fs_file_read_bytes[] = "mod_fs_file_read_bytes";
+static const char FUNCTION__mod_fs_file_read_integer[] = "mod_fs_file_read_integer";
+static const char FUNCTION__mod_fs_file_read_line[] = "mod_fs_file_read_line";
+static const char FUNCTION__mod_fs_file_read_number[] = "mod_fs_file_read_number";
+static const char FUNCTION__mod_fs_file_read_string[] = "mod_fs_file_read_string";
+static const char FUNCTION__mod_fs_file_rewind[] = "mod_fs_file_rewind";
+static const char FUNCTION__mod_fs_file_seek[] = "mod_fs_file_seek";
+static const char FUNCTION__mod_fs_file_set_public[] = "mod_fs_file_set_public";
+static const char FUNCTION__mod_fs_file_set_text_mode[] = "mod_fs_file_set_text_mode";
+static const char FUNCTION__mod_fs_file_write_bool[] = "mod_fs_file_write_bool";
+static const char FUNCTION__mod_fs_file_write_bytes[] = "mod_fs_file_write_bytes";
+static const char FUNCTION__mod_fs_file_write_integer[] = "mod_fs_file_write_integer";
+static const char FUNCTION__mod_fs_file_write_line[] = "mod_fs_file_write_line";
+static const char FUNCTION__mod_fs_file_write_number[] = "mod_fs_file_write_number";
+static const char FUNCTION__mod_fs_file_write_string[] = "mod_fs_file_write_string";
+
+#define LUA_MOD_FS_FILE_FIELD_COUNT 25
static struct LuaObjectField sModFsFileFields[LUA_MOD_FS_FILE_FIELD_COUNT] = {
- { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(char) },
- { "isPublic", LVT_BOOL, offsetof(struct ModFsFile, isPublic), true, LOT_NONE, 1, sizeof(bool) },
- { "isText", LVT_BOOL, offsetof(struct ModFsFile, isText), true, LOT_NONE, 1, sizeof(bool) },
- { "modFs", LVT_COBJECT_P, offsetof(struct ModFsFile, modFs), true, LOT_MODFS, 1, sizeof(struct ModFs*) },
- { "offset", LVT_U32, offsetof(struct ModFsFile, offset), true, LOT_NONE, 1, sizeof(u32) },
- { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) },
+ { "erase", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_erase, true, LOT_NONE, 1, sizeof(const char *) },
+ { "filepath", LVT_STRING, offsetof(struct ModFsFile, filepath), true, LOT_NONE, 1, sizeof(char) },
+ { "fill", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_fill, true, LOT_NONE, 1, sizeof(const char *) },
+ { "isPublic", LVT_BOOL, offsetof(struct ModFsFile, isPublic), true, LOT_NONE, 1, sizeof(bool) },
+ { "isText", LVT_BOOL, offsetof(struct ModFsFile, isText), true, LOT_NONE, 1, sizeof(bool) },
+ { "is_eof", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_is_eof, true, LOT_NONE, 1, sizeof(const char *) },
+ { "modFs", LVT_COBJECT_P, offsetof(struct ModFsFile, modFs), true, LOT_MODFS, 1, sizeof(struct ModFs*) },
+ { "offset", LVT_U32, offsetof(struct ModFsFile, offset), true, LOT_NONE, 1, sizeof(u32) },
+ { "read_bool", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_bool, true, LOT_NONE, 1, sizeof(const char *) },
+ { "read_bytes", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_bytes, true, LOT_NONE, 1, sizeof(const char *) },
+ { "read_integer", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_integer, true, LOT_NONE, 1, sizeof(const char *) },
+ { "read_line", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_line, true, LOT_NONE, 1, sizeof(const char *) },
+ { "read_number", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_number, true, LOT_NONE, 1, sizeof(const char *) },
+ { "read_string", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_read_string, true, LOT_NONE, 1, sizeof(const char *) },
+ { "rewind", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_rewind, true, LOT_NONE, 1, sizeof(const char *) },
+ { "seek", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_seek, true, LOT_NONE, 1, sizeof(const char *) },
+ { "set_public", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_set_public, true, LOT_NONE, 1, sizeof(const char *) },
+ { "set_text_mode", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_set_text_mode, true, LOT_NONE, 1, sizeof(const char *) },
+ { "size", LVT_U32, offsetof(struct ModFsFile, size), true, LOT_NONE, 1, sizeof(u32) },
+ { "write_bool", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_bool, true, LOT_NONE, 1, sizeof(const char *) },
+ { "write_bytes", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_bytes, true, LOT_NONE, 1, sizeof(const char *) },
+ { "write_integer", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_integer, true, LOT_NONE, 1, sizeof(const char *) },
+ { "write_line", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_line, true, LOT_NONE, 1, sizeof(const char *) },
+ { "write_number", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_number, true, LOT_NONE, 1, sizeof(const char *) },
+ { "write_string", LVT_FUNCTION, (size_t) FUNCTION__mod_fs_file_write_string, true, LOT_NONE, 1, sizeof(const char *) },
};
#define LUA_MODE_TRANSITION_INFO_FIELD_COUNT 6
@@ -2521,48 +2581,44 @@ static struct LuaObjectField sOffsetSizePairFields[LUA_OFFSET_SIZE_PAIR_FIELD_CO
{ "size", LVT_U32, offsetof(struct OffsetSizePair, size), false, LOT_NONE, 1, sizeof(u32) },
};
-#define LUA_PAINTING_FIELD_COUNT 37
+#define LUA_PAINTING_FIELD_COUNT 36
static struct LuaObjectField sPaintingFields[LUA_PAINTING_FIELD_COUNT] = {
- { "alpha", LVT_U8, offsetof(struct Painting, alpha), false, LOT_NONE, 1, sizeof(u8) },
- { "currFloor", LVT_S8, offsetof(struct Painting, currFloor), false, LOT_NONE, 1, sizeof(s8) },
- { "currRippleMag", LVT_F32, offsetof(struct Painting, currRippleMag), false, LOT_NONE, 1, sizeof(f32) },
- { "currRippleRate", LVT_F32, offsetof(struct Painting, currRippleRate), false, LOT_NONE, 1, sizeof(f32) },
- { "dispersionFactor", LVT_F32, offsetof(struct Painting, dispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
- { "entryDispersionFactor", LVT_F32, offsetof(struct Painting, entryDispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
- { "entryRippleDecay", LVT_F32, offsetof(struct Painting, entryRippleDecay), false, LOT_NONE, 1, sizeof(f32) },
- { "entryRippleMag", LVT_F32, offsetof(struct Painting, entryRippleMag), false, LOT_NONE, 1, sizeof(f32) },
- { "entryRippleRate", LVT_F32, offsetof(struct Painting, entryRippleRate), false, LOT_NONE, 1, sizeof(f32) },
- { "floorEntered", LVT_S8, offsetof(struct Painting, floorEntered), false, LOT_NONE, 1, sizeof(s8) },
- { "id", LVT_S16, offsetof(struct Painting, id), true, LOT_NONE, 1, sizeof(s16) },
- { "imageCount", LVT_S8, offsetof(struct Painting, imageCount), true, LOT_NONE, 1, sizeof(s8) },
- { "lastFloor", LVT_S8, offsetof(struct Painting, lastFloor), false, LOT_NONE, 1, sizeof(s8) },
- { "marioIsUnder", LVT_S8, offsetof(struct Painting, marioIsUnder), false, LOT_NONE, 1, sizeof(s8) },
- { "marioWasUnder", LVT_S8, offsetof(struct Painting, marioWasUnder), false, LOT_NONE, 1, sizeof(s8) },
- { "marioWentUnder", LVT_S8, offsetof(struct Painting, marioWentUnder), false, LOT_NONE, 1, sizeof(s8) },
- { "normalDisplayList", LVT_COBJECT_P, offsetof(struct Painting, normalDisplayList), true, LOT_GFX, 1, sizeof(const Gfx*) },
- { "passiveDispersionFactor", LVT_F32, offsetof(struct Painting, passiveDispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
- { "passiveRippleDecay", LVT_F32, offsetof(struct Painting, passiveRippleDecay), false, LOT_NONE, 1, sizeof(f32) },
- { "passiveRippleMag", LVT_F32, offsetof(struct Painting, passiveRippleMag), false, LOT_NONE, 1, sizeof(f32) },
- { "passiveRippleRate", LVT_F32, offsetof(struct Painting, passiveRippleRate), false, LOT_NONE, 1, sizeof(f32) },
- { "pitch", LVT_F32, offsetof(struct Painting, pitch), false, LOT_NONE, 1, sizeof(f32) },
- { "posX", LVT_F32, offsetof(struct Painting, posX), false, LOT_NONE, 1, sizeof(f32) },
- { "posY", LVT_F32, offsetof(struct Painting, posY), false, LOT_NONE, 1, sizeof(f32) },
- { "posZ", LVT_F32, offsetof(struct Painting, posZ), false, LOT_NONE, 1, sizeof(f32) },
- { "rippleDecay", LVT_F32, offsetof(struct Painting, rippleDecay), false, LOT_NONE, 1, sizeof(f32) },
- { "rippleDisplayList", LVT_COBJECT_P, offsetof(struct Painting, rippleDisplayList), true, LOT_GFX, 1, sizeof(const Gfx*) },
- { "rippleTimer", LVT_F32, offsetof(struct Painting, rippleTimer), false, LOT_NONE, 1, sizeof(f32) },
- { "rippleTrigger", LVT_S8, offsetof(struct Painting, rippleTrigger), false, LOT_NONE, 1, sizeof(s8) },
- { "rippleX", LVT_F32, offsetof(struct Painting, rippleX), false, LOT_NONE, 1, sizeof(f32) },
- { "rippleY", LVT_F32, offsetof(struct Painting, rippleY), false, LOT_NONE, 1, sizeof(f32) },
-// { "ripples", LVT_???, offsetof(struct Painting, ripples), false, LOT_???, 1, sizeof(struct { ... }) }, <--- UNIMPLEMENTED
- { "size", LVT_F32, offsetof(struct Painting, size), false, LOT_NONE, 1, sizeof(f32) },
- { "state", LVT_S8, offsetof(struct Painting, state), false, LOT_NONE, 1, sizeof(s8) },
-// { "textureArray", LVT_???, offsetof(struct Painting, textureArray), true, LOT_???, 1, sizeof(const Texture *const*) }, <--- UNIMPLEMENTED
- { "textureHeight", LVT_S16, offsetof(struct Painting, textureHeight), true, LOT_NONE, 1, sizeof(s16) },
-// { "textureMaps", LVT_???, offsetof(struct Painting, textureMaps), true, LOT_???, 1, sizeof(const s16 *const*) }, <--- UNIMPLEMENTED
- { "textureType", LVT_S8, offsetof(struct Painting, textureType), true, LOT_NONE, 1, sizeof(s8) },
- { "textureWidth", LVT_S16, offsetof(struct Painting, textureWidth), true, LOT_NONE, 1, sizeof(s16) },
- { "yaw", LVT_F32, offsetof(struct Painting, yaw), false, LOT_NONE, 1, sizeof(f32) },
+ { "alpha", LVT_U8, offsetof(struct Painting, alpha), false, LOT_NONE, 1, sizeof(u8) },
+ { "currFloor", LVT_S8, offsetof(struct Painting, currFloor), false, LOT_NONE, 1, sizeof(s8) },
+ { "currRippleMag", LVT_F32, offsetof(struct Painting, currRippleMag), false, LOT_NONE, 1, sizeof(f32) },
+ { "currRippleRate", LVT_F32, offsetof(struct Painting, currRippleRate), false, LOT_NONE, 1, sizeof(f32) },
+ { "dispersionFactor", LVT_F32, offsetof(struct Painting, dispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
+ { "entryDispersionFactor", LVT_F32, offsetof(struct Painting, entryDispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
+ { "entryRippleDecay", LVT_F32, offsetof(struct Painting, entryRippleDecay), false, LOT_NONE, 1, sizeof(f32) },
+ { "entryRippleMag", LVT_F32, offsetof(struct Painting, entryRippleMag), false, LOT_NONE, 1, sizeof(f32) },
+ { "entryRippleRate", LVT_F32, offsetof(struct Painting, entryRippleRate), false, LOT_NONE, 1, sizeof(f32) },
+ { "floorEntered", LVT_S8, offsetof(struct Painting, floorEntered), false, LOT_NONE, 1, sizeof(s8) },
+ { "id", LVT_S16, offsetof(struct Painting, id), true, LOT_NONE, 1, sizeof(s16) },
+ { "imageCount", LVT_S8, offsetof(struct Painting, imageCount), true, LOT_NONE, 1, sizeof(s8) },
+ { "lastFloor", LVT_S8, offsetof(struct Painting, lastFloor), false, LOT_NONE, 1, sizeof(s8) },
+ { "marioIsUnder", LVT_S8, offsetof(struct Painting, marioIsUnder), false, LOT_NONE, 1, sizeof(s8) },
+ { "marioWasUnder", LVT_S8, offsetof(struct Painting, marioWasUnder), false, LOT_NONE, 1, sizeof(s8) },
+ { "marioWentUnder", LVT_S8, offsetof(struct Painting, marioWentUnder), false, LOT_NONE, 1, sizeof(s8) },
+ { "passiveDispersionFactor", LVT_F32, offsetof(struct Painting, passiveDispersionFactor), false, LOT_NONE, 1, sizeof(f32) },
+ { "passiveRippleDecay", LVT_F32, offsetof(struct Painting, passiveRippleDecay), false, LOT_NONE, 1, sizeof(f32) },
+ { "passiveRippleMag", LVT_F32, offsetof(struct Painting, passiveRippleMag), false, LOT_NONE, 1, sizeof(f32) },
+ { "passiveRippleRate", LVT_F32, offsetof(struct Painting, passiveRippleRate), false, LOT_NONE, 1, sizeof(f32) },
+ { "pitch", LVT_F32, offsetof(struct Painting, pitch), false, LOT_NONE, 1, sizeof(f32) },
+ { "posX", LVT_F32, offsetof(struct Painting, posX), false, LOT_NONE, 1, sizeof(f32) },
+ { "posY", LVT_F32, offsetof(struct Painting, posY), false, LOT_NONE, 1, sizeof(f32) },
+ { "posZ", LVT_F32, offsetof(struct Painting, posZ), false, LOT_NONE, 1, sizeof(f32) },
+ { "rippleDecay", LVT_F32, offsetof(struct Painting, rippleDecay), false, LOT_NONE, 1, sizeof(f32) },
+ { "rippleTimer", LVT_F32, offsetof(struct Painting, rippleTimer), false, LOT_NONE, 1, sizeof(f32) },
+ { "rippleTrigger", LVT_S8, offsetof(struct Painting, rippleTrigger), false, LOT_NONE, 1, sizeof(s8) },
+ { "rippleX", LVT_F32, offsetof(struct Painting, rippleX), false, LOT_NONE, 1, sizeof(f32) },
+ { "rippleY", LVT_F32, offsetof(struct Painting, rippleY), false, LOT_NONE, 1, sizeof(f32) },
+ { "size", LVT_F32, offsetof(struct Painting, size), false, LOT_NONE, 1, sizeof(f32) },
+ { "state", LVT_S8, offsetof(struct Painting, state), false, LOT_NONE, 1, sizeof(s8) },
+ { "textureArray", LVT_TEXTURE_P, offsetof(struct Painting, textureArray), true, LOT_POINTER, 2, sizeof(const Texture*) },
+ { "textureHeight", LVT_S16, offsetof(struct Painting, textureHeight), true, LOT_NONE, 1, sizeof(s16) },
+ { "textureType", LVT_S8, offsetof(struct Painting, textureType), true, LOT_NONE, 1, sizeof(s8) },
+ { "textureWidth", LVT_S16, offsetof(struct Painting, textureWidth), true, LOT_NONE, 1, sizeof(s16) },
+ { "yaw", LVT_F32, offsetof(struct Painting, yaw), false, LOT_NONE, 1, sizeof(f32) },
};
#define LUA_PAINTING_MESH_VERTEX_FIELD_COUNT 2
@@ -2746,6 +2802,12 @@ static struct LuaObjectField sStarsNeededForDialogFields[LUA_STARS_NEEDED_FOR_DI
{ "dialog6", LVT_U16, offsetof(struct StarsNeededForDialog, dialog6), false, LOT_NONE, 1, sizeof(u16) },
};
+#define LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT 2
+static struct LuaObjectField sStaticObjectCollisionFields[LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT] = {
+ { "index", LVT_U32, offsetof(struct StaticObjectCollision, index), true, LOT_NONE, 1, sizeof(u32) },
+ { "length", LVT_U16, offsetof(struct StaticObjectCollision, length), true, LOT_NONE, 1, sizeof(u16) },
+};
+
#define LUA_SURFACE_FIELD_COUNT 16
static struct LuaObjectField sSurfaceFields[LUA_SURFACE_FIELD_COUNT] = {
{ "flags", LVT_S8, offsetof(struct Surface, flags), false, LOT_NONE, 1, sizeof(s8) },
@@ -2768,11 +2830,11 @@ static struct LuaObjectField sSurfaceFields[LUA_SURFACE_FIELD_COUNT] = {
#define LUA_TEXTURE_INFO_FIELD_COUNT 5
static struct LuaObjectField sTextureInfoFields[LUA_TEXTURE_INFO_FIELD_COUNT] = {
- { "bitSize", LVT_U8, offsetof(struct TextureInfo, bitSize), true, LOT_NONE, 1, sizeof(u8) },
- { "height", LVT_U32, offsetof(struct TextureInfo, height), true, LOT_NONE, 1, sizeof(u32) },
- { "name", LVT_STRING_P, offsetof(struct TextureInfo, name), true, LOT_NONE, 1, sizeof(const char*) },
- { "texture", LVT_U8_P, offsetof(struct TextureInfo, texture), true, LOT_POINTER, 1, sizeof(u8*) },
- { "width", LVT_U32, offsetof(struct TextureInfo, width), true, LOT_NONE, 1, sizeof(u32) },
+ { "bitSize", LVT_U8, offsetof(struct TextureInfo, bitSize), true, LOT_NONE, 1, sizeof(u8) },
+ { "height", LVT_U32, offsetof(struct TextureInfo, height), true, LOT_NONE, 1, sizeof(u32) },
+ { "name", LVT_STRING_P, offsetof(struct TextureInfo, name), true, LOT_NONE, 1, sizeof(const char*) },
+ { "texture", LVT_TEXTURE_P, offsetof(struct TextureInfo, texture), true, LOT_POINTER, 1, sizeof(Texture*) },
+ { "width", LVT_U32, offsetof(struct TextureInfo, width), true, LOT_NONE, 1, sizeof(u32) },
};
#define LUA_TRANSITION_INFO_FIELD_COUNT 9
@@ -2984,6 +3046,7 @@ struct LuaObjectTable sLuaObjectAutogenTable[LOT_AUTOGEN_MAX - LOT_AUTOGEN_MIN]
{ LOT_SPAWNPARTICLESINFO, sSpawnParticlesInfoFields, LUA_SPAWN_PARTICLES_INFO_FIELD_COUNT },
{ LOT_STARPOSITIONS, sStarPositionsFields, LUA_STAR_POSITIONS_FIELD_COUNT },
{ LOT_STARSNEEDEDFORDIALOG, sStarsNeededForDialogFields, LUA_STARS_NEEDED_FOR_DIALOG_FIELD_COUNT },
+ { LOT_STATICOBJECTCOLLISION, sStaticObjectCollisionFields, LUA_STATIC_OBJECT_COLLISION_FIELD_COUNT },
{ LOT_SURFACE, sSurfaceFields, LUA_SURFACE_FIELD_COUNT },
{ LOT_TEXTUREINFO, sTextureInfoFields, LUA_TEXTURE_INFO_FIELD_COUNT },
{ LOT_TRANSITIONINFO, sTransitionInfoFields, LUA_TRANSITION_INFO_FIELD_COUNT },
@@ -3114,6 +3177,7 @@ const char *sLuaLotNames[] = {
[LOT_SPAWNPARTICLESINFO] = "SpawnParticlesInfo",
[LOT_STARPOSITIONS] = "StarPositions",
[LOT_STARSNEEDEDFORDIALOG] = "StarsNeededForDialog",
+ [LOT_STATICOBJECTCOLLISION] = "StaticObjectCollision",
[LOT_SURFACE] = "Surface",
[LOT_TEXTUREINFO] = "TextureInfo",
[LOT_TRANSITIONINFO] = "TransitionInfo",
diff --git a/src/pc/lua/smlua_cobject_autogen.h b/src/pc/lua/smlua_cobject_autogen.h
index b5ec35d19..a79378a98 100644
--- a/src/pc/lua/smlua_cobject_autogen.h
+++ b/src/pc/lua/smlua_cobject_autogen.h
@@ -123,6 +123,7 @@ enum LuaObjectAutogenType {
LOT_SPAWNPARTICLESINFO,
LOT_STARPOSITIONS,
LOT_STARSNEEDEDFORDIALOG,
+ LOT_STATICOBJECTCOLLISION,
LOT_SURFACE,
LOT_TEXTUREINFO,
LOT_TRANSITIONINFO,
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index f4ebbea66..3f2c1b199 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -1544,6 +1544,7 @@ char gSmluaConstants[] = ""
"GRAPH_RENDER_CYLBOARD=(1 << 6)\n"
"GRAPH_RENDER_PLAYER=(1 << 7)\n"
"GRAPH_EXTRA_FORCE_3D=(1 << 0)\n"
+"GRAPH_EXTRA_ROTATE_HELD=(1 << 1)\n"
"GRAPH_NODE_TYPE_FUNCTIONAL=0x100\n"
"GRAPH_NODE_TYPE_400=0x400\n"
"GRAPH_NODE_TYPE_ROOT=0x001\n"
@@ -2238,9 +2239,11 @@ char gSmluaConstants[] = ""
"GRAB_POS_LIGHT_OBJ=1\n"
"GRAB_POS_HEAVY_OBJ=2\n"
"GRAB_POS_BOWSER=3\n"
-"MOD_FS_MAX_SIZE=0x1000000\n"
-"MOD_FS_MAX_FILES=0x100\n"
+"MOD_FS_MAX_SIZE=0x2000000\n"
+"MOD_FS_MAX_FILES=0x200\n"
"MOD_FS_MAX_PATH=0x100\n"
+"MOD_FS_URI_PREFIX='modfs:/'\n"
+"MOD_FS_URI_FORMAT='modfs:/%s/%s'\n"
"INT_TYPE_U8=0\n"
"INT_TYPE_U16=1\n"
"INT_TYPE_U32=2\n"
@@ -2977,6 +2980,7 @@ char gSmluaConstants[] = ""
"L_CBUTTONS=CONT_C\n"
"R_CBUTTONS=CONT_F\n"
"D_CBUTTONS=CONT_D\n"
+"PALETTES_DIRECTORY='palettes'\n"
"MAX_PRESET_PALETTES=128\n"
"PANTS=0\n"
"SHIRT=1\n"
@@ -4542,6 +4546,7 @@ char gSmluaConstants[] = ""
"SURFACE_CLASS_NOT_SLIPPERY=0x0015\n"
"SURFACE_FLAG_DYNAMIC=(1 << 0)\n"
"SURFACE_FLAG_NO_CAM_COLLISION=(1 << 1)\n"
+"SURFACE_FLAG_INTANGIBLE=(1 << 2)\n"
"SURFACE_FLAG_X_PROJECTION=(1 << 3)\n"
"HAZARD_TYPE_LAVA_FLOOR=1\n"
"HAZARD_TYPE_LAVA_WALL=2\n"
@@ -4619,5 +4624,7 @@ char gSmluaConstants[] = ""
"VERSION_TEXT='v'\n"
"VERSION_NUMBER=41\n"
"MINOR_VERSION_NUMBER=0\n"
+"GAME_NAME='sm64coopdx'\n"
+"WINDOW_NAME='Super Mario 64 Coop Deluxe'\n"
"MAX_VERSION_LENGTH=128\n"
;
\ No newline at end of file
diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c
index 1aba4cb47..aae860717 100644
--- a/src/pc/lua/smlua_functions.c
+++ b/src/pc/lua/smlua_functions.c
@@ -10,6 +10,7 @@
#include "game/mario_actions_stationary.h"
#include "audio/external.h"
#include "object_fields.h"
+#include "level_commands.h"
#include "engine/math_util.h"
#include "engine/level_script.h"
#include "pc/djui/djui_hud_utils.h"
@@ -433,7 +434,7 @@ int smlua_func_get_texture_info(lua_State* L) {
lua_newtable(L);
lua_pushstring(L, "texture");
- smlua_push_pointer(L, LVT_U8_P, texInfo.texture, NULL);
+ smlua_push_pointer(L, LVT_TEXTURE_P, texInfo.texture, NULL);
lua_settable(L, -3);
lua_pushstring(L, "bitSize");
@@ -492,6 +493,30 @@ struct LuaLevelScriptParse {
struct LuaLevelScriptParse sLevelScriptParse = { 0 };
+static bool smlua_func_level_find_lua_param(u64 *param, void *cmd, u32 offset, u32 luaParams, u32 luaParamFlag) {
+ *param = dynos_level_cmd_get(cmd, offset);
+ if (luaParams & luaParamFlag) {
+ const char *paramStr = dynos_level_get_token(*param);
+ gSmLuaConvertSuccess = true;
+ *param = smlua_get_integer_mod_variable(gLevelScriptModIndex, paramStr);
+ if (!gSmLuaConvertSuccess) {
+ gSmLuaConvertSuccess = true;
+ *param = smlua_get_any_integer_mod_variable(paramStr);
+ }
+ if (!gSmLuaConvertSuccess) {
+ return false;
+ }
+ }
+ return true;
+}
+
+#define smlua_func_level_get_lua_param(name, ptype, flag) \
+ u64 name##Param; \
+ if (!smlua_func_level_find_lua_param(&name##Param, cmd, flag##_OFFSET(type), luaParams, flag)) { \
+ break; \
+ } \
+ ptype name = (ptype) name##Param;
+
s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
u32 areaIndex, bhvId, bhvArgs, bhvModelId;
s16 bhvPosX, bhvPosY, bhvPosZ;
@@ -513,7 +538,7 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
const BehaviorScript *bhvPtr = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
if (bhvPtr) {
bhvId = get_id_from_behavior(bhvPtr);
- if (bhvId == id_bhv1Up) {
+ if (bhvId == id_bhv_max_count) {
bhvId = get_id_from_vanilla_behavior(bhvPtr); // for behaviors with no id in the script (e.g. bhvInstantActiveWarp)
}
bhvArgs = dynos_level_cmd_get(cmd, 16);
@@ -529,54 +554,46 @@ s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
} break;
// OBJECT_EXT, OBJECT_WITH_ACTS_EXT
- case 0x3F: {
- if (gLevelScriptModIndex != -1) {
- const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20));
- if (bhvStr) {
- gSmLuaConvertSuccess = true;
- bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
- if (!gSmLuaConvertSuccess) {
- gSmLuaConvertSuccess = true;
- bhvId = smlua_get_any_integer_mod_variable(bhvStr);
- }
- if (gSmLuaConvertSuccess) {
- bhvArgs = dynos_level_cmd_get(cmd, 16);
- bhvModelId = dynos_level_cmd_get(cmd, 3);
- bhvPosX = dynos_level_cmd_get(cmd, 4);
- bhvPosY = dynos_level_cmd_get(cmd, 6);
- bhvPosZ = dynos_level_cmd_get(cmd, 8);
- bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180;
- bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180;
- bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180;
- bhv = true;
- }
- }
- }
- } break;
-
// OBJECT_EXT2, OBJECT_WITH_ACTS_EXT2
- case 0x40: {
+ // OBJECT_EXT_LUA_PARAMS
+ case 0x3F:
+ case 0x40:
+ case 0x43: {
if (gLevelScriptModIndex != -1) {
- const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24));
- if (bhvStr) {
- gSmLuaConvertSuccess = true;
- bhvId = smlua_get_integer_mod_variable(gLevelScriptModIndex, bhvStr);
- if (!gSmLuaConvertSuccess) {
- gSmLuaConvertSuccess = true;
- bhvId = smlua_get_any_integer_mod_variable(bhvStr);
- }
- if (gSmLuaConvertSuccess) {
- bhvArgs = dynos_level_cmd_get(cmd, 16);
- bhvModelId = dynos_level_cmd_get(cmd, 3);
- bhvPosX = dynos_level_cmd_get(cmd, 4);
- bhvPosY = dynos_level_cmd_get(cmd, 6);
- bhvPosZ = dynos_level_cmd_get(cmd, 8);
- bhvPitch = (dynos_level_cmd_get(cmd, 10) * 0x8000) / 180;
- bhvYaw = (dynos_level_cmd_get(cmd, 12) * 0x8000) / 180;
- bhvRoll = (dynos_level_cmd_get(cmd, 14) * 0x8000) / 180;
- bhv = true;
+ u16 luaParams = (
+ type == 0x3F ? OBJECT_EXT_LUA_BEHAVIOR : (
+ type == 0x40 ? OBJECT_EXT_LUA_BEHAVIOR | OBJECT_EXT_LUA_MODEL : (
+ dynos_level_cmd_get(cmd, 2)
+ )));
+
+ smlua_func_level_get_lua_param(modelId, u32, OBJECT_EXT_LUA_MODEL);
+ smlua_func_level_get_lua_param(posX, s16, OBJECT_EXT_LUA_POS_X);
+ smlua_func_level_get_lua_param(posY, s16, OBJECT_EXT_LUA_POS_Y);
+ smlua_func_level_get_lua_param(posZ, s16, OBJECT_EXT_LUA_POS_Z);
+ smlua_func_level_get_lua_param(angleX, s16, OBJECT_EXT_LUA_ANGLE_X);
+ smlua_func_level_get_lua_param(angleY, s16, OBJECT_EXT_LUA_ANGLE_Y);
+ smlua_func_level_get_lua_param(angleZ, s16, OBJECT_EXT_LUA_ANGLE_Z);
+ smlua_func_level_get_lua_param(behParam, u32, OBJECT_EXT_LUA_BEH_PARAMS);
+ smlua_func_level_get_lua_param(behavior, uintptr_t, OBJECT_EXT_LUA_BEHAVIOR);
+
+ bhvArgs = behParam;
+ bhvModelId = modelId;
+ bhvPosX = posX;
+ bhvPosY = posY;
+ bhvPosZ = posZ;
+ bhvPitch = angleX;
+ bhvYaw = angleY;
+ bhvRoll = angleZ;
+ if (luaParams & OBJECT_EXT_LUA_BEHAVIOR) {
+ bhvId = (u32) behavior;
+ } else {
+ bhvId = get_id_from_behavior((const BehaviorScript *) behavior);
+ if (bhvId == id_bhv_max_count) {
+ bhvId = get_id_from_vanilla_behavior((const BehaviorScript *) behavior);
}
}
+
+ bhv = true;
}
} break;
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 521a08a18..a76b089fb 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -22481,53 +22481,6 @@ int smlua_func_mod_fs_create(UNUSED lua_State* L) {
return 1;
}
-int smlua_func_mod_fs_delete(UNUSED lua_State* L) {
- if (L == NULL) { return 0; }
-
- int top = lua_gettop(L);
- if (top != 0) {
- LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_delete", 0, top);
- return 0;
- }
-
-
- lua_pushboolean(L, mod_fs_delete());
-
- return 1;
-}
-
-int smlua_func_mod_fs_save(UNUSED lua_State* L) {
- if (L == NULL) { return 0; }
-
- int top = lua_gettop(L);
- if (top != 0) {
- LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_save", 0, top);
- return 0;
- }
-
-
- lua_pushboolean(L, mod_fs_save());
-
- return 1;
-}
-
-int smlua_func_mod_fs_set_public(lua_State* L) {
- if (L == NULL) { return 0; }
-
- int top = lua_gettop(L);
- if (top != 1) {
- LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_set_public", 1, top);
- return 0;
- }
-
- bool pub = smlua_to_boolean(L, 1);
- if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_set_public"); return 0; }
-
- lua_pushboolean(L, mod_fs_set_public(pub));
-
- return 1;
-}
-
int smlua_func_mod_fs_get_filename(lua_State* L) {
if (L == NULL) { return 0; }
@@ -22669,6 +22622,59 @@ int smlua_func_mod_fs_clear(lua_State* L) {
return 1;
}
+int smlua_func_mod_fs_save(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_save", 1, top);
+ return 0;
+ }
+
+ struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_save"); return 0; }
+
+ lua_pushboolean(L, mod_fs_save(modFs));
+
+ return 1;
+}
+
+int smlua_func_mod_fs_delete(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_delete", 1, top);
+ return 0;
+ }
+
+ struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_delete"); return 0; }
+
+ lua_pushboolean(L, mod_fs_delete(modFs));
+
+ return 1;
+}
+
+int smlua_func_mod_fs_set_public(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_set_public", 2, top);
+ return 0;
+ }
+
+ struct ModFs* modFs = (struct ModFs*)smlua_to_cobject(L, 1, LOT_MODFS);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_set_public"); return 0; }
+ bool pub = smlua_to_boolean(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mod_fs_set_public"); return 0; }
+
+ lua_pushboolean(L, mod_fs_set_public(modFs, pub));
+
+ return 1;
+}
+
int smlua_func_mod_fs_file_read_bool(lua_State* L) {
if (L == NULL) { return 0; }
@@ -22916,6 +22922,23 @@ int smlua_func_mod_fs_file_seek(lua_State* L) {
return 1;
}
+int smlua_func_mod_fs_file_rewind(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_file_rewind", 1, top);
+ return 0;
+ }
+
+ struct ModFsFile* file = (struct ModFsFile*)smlua_to_cobject(L, 1, LOT_MODFSFILE);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_file_rewind"); return 0; }
+
+ lua_pushboolean(L, mod_fs_file_rewind(file));
+
+ return 1;
+}
+
int smlua_func_mod_fs_file_is_eof(lua_State* L) {
if (L == NULL) { return 0; }
@@ -22973,6 +22996,25 @@ int smlua_func_mod_fs_file_erase(lua_State* L) {
return 1;
}
+int smlua_func_mod_fs_file_set_text_mode(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_fs_file_set_text_mode", 2, top);
+ return 0;
+ }
+
+ struct ModFsFile* file = (struct ModFsFile*)smlua_to_cobject(L, 1, LOT_MODFSFILE);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "mod_fs_file_set_text_mode"); return 0; }
+ bool text = smlua_to_boolean(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mod_fs_file_set_text_mode"); return 0; }
+
+ lua_pushboolean(L, mod_fs_file_set_text_mode(file, text));
+
+ return 1;
+}
+
int smlua_func_mod_fs_file_set_public(lua_State* L) {
if (L == NULL) { return 0; }
@@ -23136,6 +23178,21 @@ int smlua_func_mod_storage_load_bool(lua_State* L) {
return 1;
}
+int smlua_func_mod_storage_load_all(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "mod_storage_load_all", 0, top);
+ return 0;
+ }
+
+
+ smlua_push_lua_table(L, mod_storage_load_all());
+
+ return 1;
+}
+
int smlua_func_mod_storage_exists(lua_State* L) {
if (L == NULL) { return 0; }
@@ -32473,7 +32530,24 @@ int smlua_func_gfx_get_texture(lua_State* L) {
Gfx * cmd = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_texture"); return 0; }
- smlua_push_pointer(L, LVT_U8_P, (void*)gfx_get_texture(cmd), NULL);
+ smlua_push_pointer(L, LVT_TEXTURE_P, (void*)gfx_get_texture(cmd), NULL);
+
+ return 1;
+}
+
+int smlua_func_gfx_get_name(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "gfx_get_name", 1, top);
+ return 0;
+ }
+
+ Gfx * gfx = (Gfx *)smlua_to_cobject(L, 1, LOT_GFX);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "gfx_get_name"); return 0; }
+
+ lua_pushstring(L, gfx_get_name(gfx));
return 1;
}
@@ -32622,6 +32696,23 @@ int smlua_func_gfx_delete_all(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_vtx_get_name(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "vtx_get_name", 1, top);
+ return 0;
+ }
+
+ Vtx * vtx = (Vtx *)smlua_to_cobject(L, 1, LOT_VTX);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "vtx_get_name"); return 0; }
+
+ lua_pushstring(L, vtx_get_name(vtx));
+
+ return 1;
+}
+
int smlua_func_vtx_get_count(lua_State* L) {
if (L == NULL) { return 0; }
@@ -34367,7 +34458,7 @@ int smlua_func_texture_to_lua_table(lua_State* L) {
return 0;
}
- u8 * tex = (u8 *)smlua_to_cpointer(L, 1, LVT_U8_P);
+ Texture * tex = (Texture *)smlua_to_cpointer(L, 1, LVT_TEXTURE_P);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "texture_to_lua_table"); return 0; }
texture_to_lua_table(tex);
@@ -34375,6 +34466,23 @@ int smlua_func_texture_to_lua_table(lua_State* L) {
return 1;
}
+int smlua_func_get_texture_name(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_texture_name", 1, top);
+ return 0;
+ }
+
+ Texture * tex = (Texture *)smlua_to_cpointer(L, 1, LVT_TEXTURE_P);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_texture_name"); return 0; }
+
+ lua_pushstring(L, get_texture_name(tex));
+
+ return 1;
+}
+
/////////////////////////
// smlua_model_utils.h //
/////////////////////////
@@ -36434,6 +36542,59 @@ int smlua_func_load_object_collision_model(UNUSED lua_State* L) {
return 1;
}
+int smlua_func_load_static_object_collision(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "load_static_object_collision", 0, top);
+ return 0;
+ }
+
+
+ smlua_push_object(L, LOT_STATICOBJECTCOLLISION, load_static_object_collision(), NULL);
+
+ return 1;
+}
+
+int smlua_func_toggle_static_object_collision(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "toggle_static_object_collision", 2, top);
+ return 0;
+ }
+
+ struct StaticObjectCollision* col = (struct StaticObjectCollision*)smlua_to_cobject(L, 1, LOT_STATICOBJECTCOLLISION);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "toggle_static_object_collision"); return 0; }
+ bool tangible = smlua_to_boolean(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "toggle_static_object_collision"); return 0; }
+
+ toggle_static_object_collision(col, tangible);
+
+ return 1;
+}
+
+int smlua_func_get_static_object_surface(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 2) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_static_object_surface", 2, top);
+ return 0;
+ }
+
+ struct StaticObjectCollision* col = (struct StaticObjectCollision*)smlua_to_cobject(L, 1, LOT_STATICOBJECTCOLLISION);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "get_static_object_surface"); return 0; }
+ u32 index = smlua_to_integer(L, 2);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "get_static_object_surface"); return 0; }
+
+ smlua_push_object(L, LOT_SURFACE, get_static_object_surface(col, index), NULL);
+
+ return 1;
+}
+
int smlua_func_obj_get_surface_from_index(lua_State* L) {
if (L == NULL) { return 0; }
@@ -37800,9 +37961,6 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "mod_fs_get", smlua_func_mod_fs_get);
smlua_bind_function(L, "mod_fs_reload", smlua_func_mod_fs_reload);
smlua_bind_function(L, "mod_fs_create", smlua_func_mod_fs_create);
- smlua_bind_function(L, "mod_fs_delete", smlua_func_mod_fs_delete);
- smlua_bind_function(L, "mod_fs_save", smlua_func_mod_fs_save);
- smlua_bind_function(L, "mod_fs_set_public", smlua_func_mod_fs_set_public);
smlua_bind_function(L, "mod_fs_get_filename", smlua_func_mod_fs_get_filename);
smlua_bind_function(L, "mod_fs_get_file", smlua_func_mod_fs_get_file);
smlua_bind_function(L, "mod_fs_create_file", smlua_func_mod_fs_create_file);
@@ -37810,6 +37968,9 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "mod_fs_copy_file", smlua_func_mod_fs_copy_file);
smlua_bind_function(L, "mod_fs_delete_file", smlua_func_mod_fs_delete_file);
smlua_bind_function(L, "mod_fs_clear", smlua_func_mod_fs_clear);
+ smlua_bind_function(L, "mod_fs_save", smlua_func_mod_fs_save);
+ smlua_bind_function(L, "mod_fs_delete", smlua_func_mod_fs_delete);
+ smlua_bind_function(L, "mod_fs_set_public", smlua_func_mod_fs_set_public);
smlua_bind_function(L, "mod_fs_file_read_bool", smlua_func_mod_fs_file_read_bool);
smlua_bind_function(L, "mod_fs_file_read_integer", smlua_func_mod_fs_file_read_integer);
smlua_bind_function(L, "mod_fs_file_read_number", smlua_func_mod_fs_file_read_number);
@@ -37823,9 +37984,11 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "mod_fs_file_write_string", smlua_func_mod_fs_file_write_string);
smlua_bind_function(L, "mod_fs_file_write_line", smlua_func_mod_fs_file_write_line);
smlua_bind_function(L, "mod_fs_file_seek", smlua_func_mod_fs_file_seek);
+ smlua_bind_function(L, "mod_fs_file_rewind", smlua_func_mod_fs_file_rewind);
smlua_bind_function(L, "mod_fs_file_is_eof", smlua_func_mod_fs_file_is_eof);
smlua_bind_function(L, "mod_fs_file_fill", smlua_func_mod_fs_file_fill);
smlua_bind_function(L, "mod_fs_file_erase", smlua_func_mod_fs_file_erase);
+ smlua_bind_function(L, "mod_fs_file_set_text_mode", smlua_func_mod_fs_file_set_text_mode);
smlua_bind_function(L, "mod_fs_file_set_public", smlua_func_mod_fs_file_set_public);
smlua_bind_function(L, "mod_fs_hide_errors", smlua_func_mod_fs_hide_errors);
smlua_bind_function(L, "mod_fs_get_last_error", smlua_func_mod_fs_get_last_error);
@@ -37837,6 +38000,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "mod_storage_load", smlua_func_mod_storage_load);
smlua_bind_function(L, "mod_storage_load_number", smlua_func_mod_storage_load_number);
smlua_bind_function(L, "mod_storage_load_bool", smlua_func_mod_storage_load_bool);
+ smlua_bind_function(L, "mod_storage_load_all", smlua_func_mod_storage_load_all);
smlua_bind_function(L, "mod_storage_exists", smlua_func_mod_storage_exists);
smlua_bind_function(L, "mod_storage_remove", smlua_func_mod_storage_remove);
smlua_bind_function(L, "mod_storage_clear", smlua_func_mod_storage_clear);
@@ -38365,6 +38529,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "gfx_get_vertex_buffer", smlua_func_gfx_get_vertex_buffer);
smlua_bind_function(L, "gfx_get_vertex_count", smlua_func_gfx_get_vertex_count);
smlua_bind_function(L, "gfx_get_texture", smlua_func_gfx_get_texture);
+ smlua_bind_function(L, "gfx_get_name", smlua_func_gfx_get_name);
smlua_bind_function(L, "gfx_get_length", smlua_func_gfx_get_length);
smlua_bind_function(L, "gfx_get_command", smlua_func_gfx_get_command);
smlua_bind_function(L, "gfx_get_next_command", smlua_func_gfx_get_next_command);
@@ -38373,6 +38538,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "gfx_resize", smlua_func_gfx_resize);
smlua_bind_function(L, "gfx_delete", smlua_func_gfx_delete);
smlua_bind_function(L, "gfx_delete_all", smlua_func_gfx_delete_all);
+ smlua_bind_function(L, "vtx_get_name", smlua_func_vtx_get_name);
smlua_bind_function(L, "vtx_get_count", smlua_func_vtx_get_count);
smlua_bind_function(L, "vtx_get_vertex", smlua_func_vtx_get_vertex);
smlua_bind_function(L, "vtx_get_next_vertex", smlua_func_vtx_get_next_vertex);
@@ -38480,6 +38646,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "geo_get_current_camera", smlua_func_geo_get_current_camera);
smlua_bind_function(L, "geo_get_current_held_object", smlua_func_geo_get_current_held_object);
smlua_bind_function(L, "texture_to_lua_table", smlua_func_texture_to_lua_table);
+ smlua_bind_function(L, "get_texture_name", smlua_func_get_texture_name);
// smlua_model_utils.h
smlua_bind_function(L, "smlua_model_util_get_id", smlua_func_smlua_model_util_get_id);
@@ -38603,6 +38770,9 @@ void smlua_bind_functions_autogen(void) {
// surface_load.h
smlua_bind_function(L, "load_object_collision_model", smlua_func_load_object_collision_model);
+ smlua_bind_function(L, "load_static_object_collision", smlua_func_load_static_object_collision);
+ smlua_bind_function(L, "toggle_static_object_collision", smlua_func_toggle_static_object_collision);
+ smlua_bind_function(L, "get_static_object_surface", smlua_func_get_static_object_surface);
smlua_bind_function(L, "obj_get_surface_from_index", smlua_func_obj_get_surface_from_index);
smlua_bind_function(L, "surface_has_force", smlua_func_surface_has_force);
diff --git a/src/pc/lua/smlua_hook_events_autogen.inl b/src/pc/lua/smlua_hook_events_autogen.inl
index 84fe42ee5..eb2b7647f 100644
--- a/src/pc/lua/smlua_hook_events_autogen.inl
+++ b/src/pc/lua/smlua_hook_events_autogen.inl
@@ -1082,13 +1082,13 @@ bool smlua_call_event_hooks_HOOK_ON_DIALOG(s32 dialogID, bool *openDialogBox, co
hookResult = true;
// return openDialogBox
- if (lua_type(L, -1) == LUA_TBOOLEAN) {
- *openDialogBox = smlua_to_boolean(L, -1);
+ if (lua_type(L, -2) == LUA_TBOOLEAN) {
+ *openDialogBox = smlua_to_boolean(L, -2);
}
// return dialogTextOverride
- if (lua_type(L, -2) == LUA_TSTRING) {
- *dialogTextOverride = smlua_to_string(L, -2);
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ *dialogTextOverride = smlua_to_string(L, -1);
}
lua_settop(L, prevTop);
diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c
index f08e156d3..6ec341c05 100644
--- a/src/pc/lua/smlua_hooks.c
+++ b/src/pc/lua/smlua_hooks.c
@@ -41,10 +41,10 @@ struct LuaHookedEvent {
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
static const char* sLuaHookedEventTypeName[] = {
-#define SMLUA_EVENT_HOOK(hookEventType, ...) #hookEventType,
+#define SMLUA_EVENT_HOOK(hookEventType, ...) [hookEventType] = #hookEventType,
#include "smlua_hook_events.inl"
#undef SMLUA_EVENT_HOOK
- "HOOK_MAX"
+ [HOOK_MAX] = "HOOK_MAX"
};
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile) {
@@ -100,6 +100,7 @@ int smlua_hook_event(lua_State* L) {
hook->reference[hook->count] = ref;
hook->mod[hook->count] = gLuaActiveMod;
+ hook->modFile[hook->count] = gLuaActiveModFile;
hook->count++;
return 1;
diff --git a/src/pc/lua/smlua_live_reload.c b/src/pc/lua/smlua_live_reload.c
index 809572f4d..2b967bfdd 100644
--- a/src/pc/lua/smlua_live_reload.c
+++ b/src/pc/lua/smlua_live_reload.c
@@ -1,5 +1,6 @@
#include
#include "smlua.h"
+#include "smlua_require.h"
#include "pc/mods/mods.h"
#include "pc/mods/mods_utils.h"
@@ -343,16 +344,8 @@ static void smlua_reload_module(lua_State *L, struct Mod* mod, struct ModFile *f
// only handle loaded Lua modules
if (!file->isLoadedLuaModule) { return; }
- // build registry key for this mod's loaded table
- char registryKey[SYS_MAX_PATH + 16];
- snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", mod->relativePath);
-
// get per-mod "loaded" table
- lua_getfield(L, LUA_REGISTRYINDEX, registryKey); // ..., loadedTable
- if (!lua_istable(L, -1)) {
- lua_pop(L, 1);
- return;
- }
+ smlua_get_or_create_mod_loaded_table(L, mod);
// get the old module table: loadedTable[file->relativePath]
lua_getfield(L, -1, file->relativePath); // ..., loadedTable, oldMod
diff --git a/src/pc/lua/smlua_require.c b/src/pc/lua/smlua_require.c
index 196f8cb76..5852ac54a 100644
--- a/src/pc/lua/smlua_require.c
+++ b/src/pc/lua/smlua_require.c
@@ -4,47 +4,89 @@
#include "pc/mods/mods_utils.h"
#include "pc/fs/fmem.h"
+#define LOADING_SENTINEL ((void*)-1)
+
// table to track loaded modules per mod
-static void smlua_init_mod_loaded_table(lua_State* L, const char* modPath) {
- // Create a unique registry key for this mod's loaded table
- char registryKey[SYS_MAX_PATH + 16];
- snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", modPath);
+void smlua_get_or_create_mod_loaded_table(lua_State* L, struct Mod* mod) {
+ char registryKey[SYS_MAX_PATH + 16] = "";
+ snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", mod->relativePath);
lua_getfield(L, LUA_REGISTRYINDEX, registryKey);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
+ lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, registryKey);
- } else {
- lua_pop(L, 1);
}
}
+bool smlua_get_cached_module_result(lua_State* L, struct Mod* mod, struct ModFile* file) {
+ smlua_get_or_create_mod_loaded_table(L, mod);
+ lua_getfield(L, -1, file->relativePath);
+
+ if (lua_touserdata(L, -1) == LOADING_SENTINEL) {
+ LOG_LUA_LINE("loop or previous error loading module '%s'", file->relativePath);
+ lua_pop(L, 1); // pop sentinel
+ lua_pushnil(L);
+
+ return true;
+ }
+
+ if (lua_isnil(L, -1)) {
+ // not cached
+ lua_pop(L, 2); // pop nil and loaded table
+ return false;
+ }
+
+ // cached, remove loaded table and leave value on top
+ lua_remove(L, -2);
+ return true;
+}
+
+void smlua_mark_module_as_loading(lua_State* L, struct Mod* mod, struct ModFile* file) {
+ smlua_get_or_create_mod_loaded_table(L, mod);
+ lua_pushlightuserdata(L, LOADING_SENTINEL);
+ lua_setfield(L, -2, file->relativePath);
+ lua_pop(L, 1); // pop loaded table
+}
+
+void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* file, s32 prevTop) {
+ if (lua_gettop(L) == prevTop) {
+ lua_pushboolean(L, 1);
+ } else if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ lua_pushboolean(L, 1);
+ }
+
+ smlua_get_or_create_mod_loaded_table(L, mod);
+
+ lua_pushvalue(L, -2); // duplicate result
+ lua_setfield(L, -2, file->relativePath); // loaded[file->relativePath] = result
+ lua_pop(L, 1); // pop loaded table
+}
+
static struct ModFile* smlua_find_mod_file(const char* moduleName) {
- char relativeDir[SYS_MAX_PATH] = "";
+ char basePath[SYS_MAX_PATH] = "";
+ char absolutePath[SYS_MAX_PATH] = "";
if (!gLuaActiveMod) {
return NULL;
}
+ // get the directory of the current file
if (gLuaActiveModFile) {
- path_get_folder(gLuaActiveModFile->relativePath, relativeDir);
+ path_get_folder(gLuaActiveModFile->relativePath, basePath);
}
- bool hasRelativeDir = strlen(relativeDir) > 0;
+ // resolve moduleName to a path relative to mod root
+ resolve_relative_path(basePath, moduleName, absolutePath);
- struct ModFile* bestPick = NULL;
- int bestRelativeDepth = INT_MAX;
- int bestTotalDepth = INT_MAX;
- bool foundRelativeFile = false;
-
- char rawName[SYS_MAX_PATH] = "";
char luaName[SYS_MAX_PATH] = "";
char luacName[SYS_MAX_PATH] = "";
- snprintf(rawName, SYS_MAX_PATH, "/%s", moduleName);
- snprintf(luaName, SYS_MAX_PATH, "/%s.lua", moduleName);
- snprintf(luacName, SYS_MAX_PATH, "/%s.luac", moduleName);
+ snprintf(luaName, SYS_MAX_PATH, "%s.lua", absolutePath);
+ snprintf(luacName, SYS_MAX_PATH, "%s.luac", absolutePath);
+ // since mods' relativePaths are relative to the mod's root, we can do a direct comparison
for (int i = 0; i < gLuaActiveMod->fileCount; i++) {
struct ModFile* file = &gLuaActiveMod->files[i];
@@ -54,41 +96,17 @@ static struct ModFile* smlua_find_mod_file(const char* moduleName) {
}
// only consider lua files
- if (!str_ends_with(file->relativePath, ".lua") && !str_ends_with(file->relativePath, ".luac")) {
+ if (!path_ends_with(file->relativePath, ".lua") && !path_ends_with(file->relativePath, ".luac")) {
continue;
}
// check for match
- if (!str_ends_with(file->relativePath, rawName) && !str_ends_with(file->relativePath, luaName) && !str_ends_with(file->relativePath, luacName)) {
- continue;
- }
-
- // get total path depth
- int totalDepth = path_depth(file->relativePath);
-
- // make sure we never load the old-style lua files with require()
- if (totalDepth < 1) {
- continue;
- }
-
- // get relative path depth
- int relativeDepth = INT_MAX;
- if (hasRelativeDir && path_is_relative_to(file->relativePath, relativeDir)) {
- relativeDepth = path_depth(file->relativePath + strlen(relativeDir));
- foundRelativeFile = true;
- }
-
- // pick new best
- // relative files will always win against absolute files
- // other than that, shallower files will win
- if (relativeDepth < bestRelativeDepth || (!foundRelativeFile && totalDepth < bestTotalDepth)) {
- bestPick = file;
- bestRelativeDepth = relativeDepth;
- bestTotalDepth = totalDepth;
+ if (!strcmp(file->relativePath, luaName) || !strcmp(file->relativePath, luacName)) {
+ return file;
}
}
- return bestPick;
+ return NULL;
}
static int smlua_custom_require(lua_State* L) {
@@ -96,69 +114,47 @@ static int smlua_custom_require(lua_State* L) {
struct Mod* activeMod = gLuaActiveMod;
if (!activeMod) {
- LOG_LUA("require() called outside of mod context");
+ LOG_LUA_LINE("require() called outside of mod context");
return 0;
}
- // create registry key for this mod's loaded table
- char registryKey[SYS_MAX_PATH + 16] = "";
- snprintf(registryKey, sizeof(registryKey), "mod_loaded_%s", activeMod->relativePath);
-
- // get or create the mod's loaded table
- lua_getfield(L, LUA_REGISTRYINDEX, registryKey);
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1);
- lua_newtable(L);
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, registryKey);
+ if (path_ends_with(moduleName, "/") || path_ends_with(moduleName, "\\")) {
+ LOG_LUA_LINE("cannot require a directory");
+ return 0;
}
// find the file in mod files
struct ModFile* file = smlua_find_mod_file(moduleName);
if (!file) {
- LOG_LUA("module '%s' not found in mod files", moduleName);
- lua_pop(L, 1); // pop table
+ LOG_LUA_LINE("module '%s' not found in mod files", moduleName);
return 0;
}
- // check if module is already loaded
- lua_getfield(L, -1, file->relativePath);
- if (!lua_isnil(L, -1)) {
- // module already loaded, return it
- return 1;
- }
- lua_pop(L, 1); // pop nil value
-
- // mark module as "loading" to prevent recursion
- lua_pushboolean(L, 1);
- lua_setfield(L, -2, file->relativePath);
-
- // cache the previous mod file
- struct ModFile* prevModFile = gLuaActiveModFile;
- s32 prevTop = lua_gettop(L);
-
// tag it as a loaded lua module
file->isLoadedLuaModule = true;
- // load and execute
- gLuaActiveModFile = file;
- smlua_load_script(activeMod, file, activeMod->index, false);
- gLuaActiveModFile = prevModFile;
-
- // if the module didn't return anything, use true
- if (prevTop == lua_gettop(L)) {
- lua_pushboolean(L, 1);
- } else if (lua_isnil(L, -1)) {
- lua_pop(L, 1);
- lua_pushboolean(L, 1);
+ // check cache first
+ if (smlua_get_cached_module_result(L, activeMod, file)) {
+ return 1;
}
- // store in loaded table
- lua_pushvalue(L, -1); // duplicate return value
- lua_setfield(L, -3, file->relativePath); // loaded[file->relativePath] = return_value
+ // mark module as "loading" to prevent recursion
+ smlua_mark_module_as_loading(L, activeMod, file);
- // clean up stack
- lua_remove(L, -2);
+ // cache the previous mod file
+ struct ModFile* prevModFile = gLuaActiveModFile;
+
+ // load and execute
+ gLuaActiveModFile = file;
+ s32 prevTop = lua_gettop(L);
+
+ int rc = smlua_load_script(activeMod, file, activeMod->index, false);
+
+ if (rc == LUA_OK) {
+ smlua_cache_module_result(L, activeMod, file, prevTop);
+ }
+
+ gLuaActiveModFile = prevModFile;
return 1; // return the module value
}
@@ -179,6 +175,7 @@ void smlua_init_require_system(void) {
// initialize loaded tables for each mod
for (int i = 0; i < gActiveMods.entryCount; i++) {
struct Mod* mod = gActiveMods.entries[i];
- smlua_init_mod_loaded_table(L, mod->relativePath);
+ smlua_get_or_create_mod_loaded_table(L, mod);
+ lua_pop(L, 1); // pop loaded table
}
-}
\ No newline at end of file
+}
diff --git a/src/pc/lua/smlua_require.h b/src/pc/lua/smlua_require.h
index dcb8891cb..bb1b38df1 100644
--- a/src/pc/lua/smlua_require.h
+++ b/src/pc/lua/smlua_require.h
@@ -3,9 +3,11 @@
#include "smlua.h"
-void smlua_require_update(lua_State* L);
void smlua_bind_custom_require(lua_State* L);
-void smlua_reload_module(lua_State *L, struct Mod* mod, struct ModFile *file);
+void smlua_get_or_create_mod_loaded_table(lua_State* L, struct Mod* mod);
+bool smlua_get_cached_module_result(lua_State* L, struct Mod* mod, struct ModFile* file);
+void smlua_mark_module_as_loading(lua_State* L, struct Mod* mod, struct ModFile* file);
+void smlua_cache_module_result(lua_State* L, struct Mod* mod, struct ModFile* file, s32 prevTop);
void smlua_init_require_system(void);
#endif
\ No newline at end of file
diff --git a/src/pc/lua/smlua_sync_table.c b/src/pc/lua/smlua_sync_table.c
index 9fb2ec293..bd3c64f28 100644
--- a/src/pc/lua/smlua_sync_table.c
+++ b/src/pc/lua/smlua_sync_table.c
@@ -144,7 +144,6 @@ static void smlua_sync_table_call_hook(int syncTableIndex, int keyIndex, int pre
// call hook
struct Mod* prevActiveMod = gLuaActiveMod;
- struct ModFile* prevActiveModFile = gLuaActiveModFile;
gLuaActiveMod = mod;
gLuaActiveModFile = NULL;
@@ -156,7 +155,6 @@ static void smlua_sync_table_call_hook(int syncTableIndex, int keyIndex, int pre
}
gLuaActiveMod = prevActiveMod;
- prevActiveModFile = prevActiveModFile;
}
lua_pop(L, 1); // pop _hook_on_changed's value
@@ -181,12 +179,11 @@ static bool smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al
}
// get key
- struct LSTNetworkType lntKey = smlua_to_lnt(L, keyIndex);
+ smlua_to_lnt(L, keyIndex);
if (!gSmLuaConvertSuccess) {
LOG_LUA_LINE("Error: tried to alter sync table with an invalid key");
return false;
}
- lntKey = lntKey;
////////////////
diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c
index 4018b6f16..496afb87b 100644
--- a/src/pc/lua/smlua_utils.c
+++ b/src/pc/lua/smlua_utils.c
@@ -156,6 +156,22 @@ LuaFunction smlua_to_lua_function(lua_State* L, int index) {
return luaL_ref(L, LUA_REGISTRYINDEX);
}
+LuaTable smlua_to_lua_table(lua_State* L, int index) {
+ if (lua_type(L, index) == LUA_TNIL) {
+ return 0;
+ }
+
+ if (lua_type(L, index) != LUA_TTABLE) {
+ LOG_LUA_LINE("smlua_to_lua_table received improper type '%s'", luaL_typename(L, index));
+ gSmLuaConvertSuccess = false;
+ return 0;
+ }
+
+ gSmLuaConvertSuccess = true;
+ lua_pushvalue(L, index);
+ return luaL_ref(L, LUA_REGISTRYINDEX);
+}
+
bool smlua_is_cobject(lua_State* L, int index, UNUSED u16 lot) {
return lua_isuserdata(L, index);
}
@@ -288,7 +304,7 @@ struct TextureInfo *smlua_to_texture_info(lua_State *L, int index) {
lua_pushstring(L, "texture");
lua_gettable(L, top + 1);
- const u8 *texPtr = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P);
+ const Texture *texPtr = smlua_to_cpointer(L, lua_gettop(L), LVT_TEXTURE_P);
lua_pop(L, 1);
if (!gSmLuaConvertSuccess) { return NULL; }
@@ -497,6 +513,14 @@ void smlua_push_table_field(int index, const char* name) {
///////////////////////////////////////////////////////////////////////////////////////////
+void smlua_push_lua_table(lua_State* L, LuaTable table) {
+ if (table != 0) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, table);
+ } else {
+ lua_pushnil(L);
+ }
+}
+
void smlua_push_bytestring(lua_State* L, ByteString bytestring) {
if (bytestring.bytes) {
lua_pushlstring(L, bytestring.bytes, bytestring.length);
diff --git a/src/pc/lua/smlua_utils.h b/src/pc/lua/smlua_utils.h
index f64286392..6324fc57f 100644
--- a/src/pc/lua/smlua_utils.h
+++ b/src/pc/lua/smlua_utils.h
@@ -1,10 +1,12 @@
#ifndef SMLUA_UTILS_H
#define SMLUA_UTILS_H
+#include "smlua.h"
#include "src/pc/network/packets/packet.h"
extern u8 gSmLuaConvertSuccess;
typedef int LuaFunction;
+typedef int LuaTable;
typedef struct ByteString {
const char *bytes;
@@ -26,6 +28,7 @@ lua_Number smlua_to_number(lua_State* L, int index);
const char* smlua_to_string(lua_State* L, int index);
ByteString smlua_to_bytestring(lua_State* L, int index);
LuaFunction smlua_to_lua_function(lua_State* L, int index);
+LuaTable smlua_to_lua_table(lua_State* L, int index);
bool smlua_is_cobject(lua_State* L, int index, u16 lot);
void* smlua_to_cobject(lua_State* L, int index, u16 lot);
void* smlua_to_cpointer(lua_State* L, int index, u16 lvt);
@@ -43,6 +46,7 @@ void smlua_push_string_field(int index, const char* name, const char* val);
void smlua_push_nil_field(int index, const char* name);
void smlua_push_table_field(int index, const char* name);
+void smlua_push_lua_table(lua_State* L, LuaTable table);
void smlua_push_bytestring(lua_State* L, ByteString bytestring);
void smlua_push_lnt(struct LSTNetworkType* lnt);
@@ -68,5 +72,6 @@ void smlua_free(void *ptr, u16 lot);
static inline void smlua_free_##name(void *ptr) { smlua_free(ptr, lot); }
smlua_free_lot(surface, LOT_SURFACE);
+smlua_free_lot(soc, LOT_STATICOBJECTCOLLISION);
#endif
\ No newline at end of file
diff --git a/src/pc/lua/utils/smlua_audio_utils.c b/src/pc/lua/utils/smlua_audio_utils.c
index 2345b0878..03d0fa60c 100644
--- a/src/pc/lua/utils/smlua_audio_utils.c
+++ b/src/pc/lua/utils/smlua_audio_utils.c
@@ -10,6 +10,7 @@
#include "game/camera.h"
#include "engine/math_util.h"
#include "pc/mods/mods.h"
+#include "pc/mods/mod_fs.h"
#include "pc/lua/smlua.h"
#include "pc/lua/utils/smlua_audio_utils.h"
#include "pc/mods/mods_utils.h"
@@ -78,27 +79,37 @@ bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData) {
return true;
}
- static u8* buffer = NULL;
- static long int length = 0;
+ u8* buffer = NULL;
+ u32 length = 0;
- FILE* fp = f_open_r(override->filename);
- if (!fp) { return false; }
- f_seek(fp, 0L, SEEK_END);
- length = f_tell(fp);
+ if (is_mod_fs_file(override->filename)) {
+ if (!mod_fs_read_file_from_uri(override->filename, (void **) &buffer, &length)) {
+ return false;
+ }
+ } else {
+ FILE* fp = f_open_r(override->filename);
+ if (!fp) { return false; }
+ f_seek(fp, 0L, SEEK_END);
+ length = f_tell(fp);
+
+ buffer = malloc(length+1);
+ if (buffer == NULL) {
+ LOG_ERROR("Failed to malloc m64 sound file");
+ f_close(fp);
+ f_delete(fp);
+ return false;
+ }
+
+ f_seek(fp, 0L, SEEK_SET);
+ f_read(buffer, length, 1, fp);
- buffer = malloc(length+1);
- if (buffer == NULL) {
- LOG_ERROR("Failed to malloc m64 sound file");
f_close(fp);
f_delete(fp);
- return false;
}
- f_seek(fp, 0L, SEEK_SET);
- f_read(buffer, length, 1, fp);
-
- f_close(fp);
- f_delete(fp);
+ if (!buffer || !length) {
+ return false;
+ }
// cache
override->loaded = true;
@@ -110,6 +121,17 @@ bool smlua_audio_utils_override(u8 sequenceId, s32* bankId, void** seqData) {
return true;
}
+static void smlua_audio_utils_create_audio_override(u8 sequenceId, u8 bankId, u8 defaultVolume, const char *filepath) {
+ struct AudioOverride* override = &sAudioOverrides[sequenceId];
+ if (override->enabled) { audio_init(); }
+ smlua_audio_utils_reset(override);
+ LOG_INFO("Loading audio: %s", filepath);
+ override->filename = strdup(filepath);
+ override->enabled = true;
+ override->bank = bankId;
+ sound_set_background_music_default_volume(sequenceId, defaultVolume);
+}
+
void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolume, const char* m64Name) {
if (gLuaActiveMod == NULL) { return; }
if (sequenceId >= MAX_AUDIO_OVERRIDE) {
@@ -122,6 +144,11 @@ void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolu
return;
}
+ if (is_mod_fs_file(m64Name)) {
+ smlua_audio_utils_create_audio_override(sequenceId, bankId, defaultVolume, m64Name);
+ return;
+ }
+
char m64path[SYS_MAX_PATH] = { 0 };
if (snprintf(m64path, SYS_MAX_PATH-1, "sound/%s.m64", m64Name) < 0) {
LOG_LUA_LINE("Could not concat m64path: %s", m64path);
@@ -134,19 +161,8 @@ void smlua_audio_utils_replace_sequence(u8 sequenceId, u8 bankId, u8 defaultVolu
char relPath[SYS_MAX_PATH] = { 0 };
snprintf(relPath, SYS_MAX_PATH-1, "%s", file->relativePath);
normalize_path(relPath);
- if (str_ends_with(relPath, m64path)) {
- struct AudioOverride* override = &sAudioOverrides[sequenceId];
- if (override->enabled) { audio_init(); }
- smlua_audio_utils_reset(override);
- LOG_INFO("Loading audio: %s", file->cachedPath);
- override->filename = strdup(file->cachedPath);
- override->enabled = true;
- override->bank = bankId;
-#ifdef VERSION_EU
- //sBackgroundMusicDefaultVolume[sequenceId] = defaultVolume;
-#else
- sound_set_background_music_default_volume(sequenceId, defaultVolume);
-#endif
+ if (path_ends_with(relPath, m64path)) {
+ smlua_audio_utils_create_audio_override(sequenceId, bankId, defaultVolume, file->cachedPath);
return;
}
}
@@ -174,12 +190,12 @@ static void smlua_audio_custom_init(void) {
}
}
-static struct ModAudio* find_mod_audio(struct ModFile* file) {
+static struct ModAudio* find_mod_audio(const char *filepath) {
struct DynamicPoolNode* node = sModAudioPool->tail;
while (node) {
struct DynamicPoolNode* prev = node->prev;
struct ModAudio* audio = node->ptr;
- if (audio->file == file) { return audio; }
+ if (strcmp(filepath, audio->filepath) == 0) { return audio; }
node = prev;
}
return NULL;
@@ -209,7 +225,7 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) {
const char* fileTypes[] = { ".mp3", ".aiff", ".ogg", NULL };
const char** ft = fileTypes;
while (*ft != NULL) {
- if (str_ends_with((char*)filename, (char*)*ft)) {
+ if (path_ends_with(filename, *ft)) {
validFileType = true;
break;
}
@@ -220,25 +236,30 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) {
return NULL;
}
- // find mod file in mod list
- bool foundModFile = false;
- struct ModFile* modFile = NULL;
- u16 fileCount = gLuaActiveMod->fileCount;
- for (u16 i = 0; i < fileCount; i++) {
- struct ModFile* file = &gLuaActiveMod->files[i];
- if(str_ends_with(file->relativePath, (char*)filename)) {
- foundModFile = true;
- modFile = file;
- break;
+ const char *filepath = filename;
+ if (!is_mod_fs_file(filename)) {
+
+ // find mod file in mod list
+ bool foundModFile = false;
+ struct ModFile* modFile = NULL;
+ u16 fileCount = gLuaActiveMod->fileCount;
+ for (u16 i = 0; i < fileCount; i++) {
+ struct ModFile* file = &gLuaActiveMod->files[i];
+ if(path_ends_with(file->relativePath, filename)) {
+ foundModFile = true;
+ modFile = file;
+ break;
+ }
}
- }
- if (!foundModFile) {
- LOG_LUA_LINE("Could not find audio file: '%s'", filename);
- return NULL;
+ if (!foundModFile) {
+ LOG_LUA_LINE("Could not find audio file: '%s'", filename);
+ return NULL;
+ }
+ filepath = modFile->cachedPath;
}
// find stream in ModAudio list
- struct ModAudio* audio = find_mod_audio(modFile);
+ struct ModAudio* audio = find_mod_audio(filepath);
if (audio) {
if (isStream == audio->isStream) {
return audio;
@@ -261,36 +282,52 @@ struct ModAudio* audio_load_internal(const char* filename, bool isStream) {
}
// remember file
- audio->file = modFile;
+ audio->filepath = strdup(filepath);
- // load audio
- FILE *f = f_open_r(modFile->cachedPath);
- if (!f) {
- LOG_ERROR("failed to load audio file '%s': file not found", filename);
- return NULL;
- }
+ void *buffer = NULL;
+ u32 size = 0;
- f_seek(f, 0, SEEK_END);
- u32 size = f_tell(f);
- f_rewind(f);
- void *buffer = calloc(size, 1);
- if (!buffer) {
+ if (is_mod_fs_file(filepath)) {
+ if (!mod_fs_read_file_from_uri(filepath, &buffer, &size)) {
+ LOG_ERROR("failed to load audio file '%s': an error occurred with modfs", filename);
+ return NULL;
+ }
+ } else {
+
+ // load audio
+ FILE *f = f_open_r(filepath);
+ if (!f) {
+ LOG_ERROR("failed to load audio file '%s': file not found", filename);
+ return NULL;
+ }
+
+ f_seek(f, 0, SEEK_END);
+ size = f_tell(f);
+ f_rewind(f);
+ buffer = calloc(size, 1);
+ if (!buffer) {
+ f_close(f);
+ f_delete(f);
+ LOG_ERROR("failed to load audio file '%s': cannot allocate buffer of size: %d", filename, size);
+ return NULL;
+ }
+
+ // read the audio buffer
+ if (f_read(buffer, 1, size, f) < size) {
+ free(buffer);
+ f_close(f);
+ f_delete(f);
+ LOG_ERROR("failed to load audio file '%s': cannot read audio buffer of size: %d", filename, size);
+ return NULL;
+ }
f_close(f);
f_delete(f);
- LOG_ERROR("failed to load audio file '%s': cannot allocate buffer of size: %d", filename, size);
- return NULL;
}
- // read the audio buffer
- if (f_read(buffer, 1, size, f) < size) {
- free(buffer);
- f_close(f);
- f_delete(f);
- LOG_ERROR("failed to load audio file '%s': cannot read audio buffer of size: %d", filename, size);
+ if (!buffer || !size) {
+ LOG_ERROR("failed to load audio file '%s': failed to read audio data", filename);
return NULL;
}
- f_close(f);
- f_delete(f);
// decode the audio buffer
ma_result result = ma_decoder_init_memory(buffer, size, NULL, &audio->decoder);
@@ -604,6 +641,7 @@ void audio_custom_shutdown(void) {
audio_sample_destroy_copies(audio);
}
ma_sound_uninit(&audio->sound);
+ free((void *) audio->filepath);
}
dynamic_pool_free(sModAudioPool, audio);
node = prev;
diff --git a/src/pc/lua/utils/smlua_audio_utils.h b/src/pc/lua/utils/smlua_audio_utils.h
index 4fc276548..deca8b0d0 100644
--- a/src/pc/lua/utils/smlua_audio_utils.h
+++ b/src/pc/lua/utils/smlua_audio_utils.h
@@ -22,7 +22,7 @@ struct ModAudioSampleCopies {
};
struct ModAudio {
- struct ModFile* file;
+ const char *filepath;
ma_sound sound;
ma_decoder decoder;
void *buffer;
diff --git a/src/pc/lua/utils/smlua_gfx_utils.c b/src/pc/lua/utils/smlua_gfx_utils.c
index b9d663481..821b42696 100644
--- a/src/pc/lua/utils/smlua_gfx_utils.c
+++ b/src/pc/lua/utils/smlua_gfx_utils.c
@@ -238,13 +238,19 @@ u16 gfx_get_vertex_count(Gfx *cmd) {
return C0(cmd, 12, 8);
}
-u8 *gfx_get_texture(Gfx *cmd) {
+Texture *gfx_get_texture(Gfx *cmd) {
if (!cmd) { return 0; }
u32 op = GFX_OP(cmd);
if (op != G_SETCIMG && op != G_SETZIMG && op != G_SETTIMG) { return 0; }
if (cmd->words.w1 == 0) { return 0; }
- return (u8 *) cmd->words.w1;
+ return (Texture *) cmd->words.w1;
+}
+
+const char *gfx_get_name(Gfx *gfx) {
+ if (!gfx) { return NULL; }
+
+ return dynos_gfx_get_name(gfx);
}
u32 gfx_get_length(Gfx *gfx) {
@@ -349,6 +355,12 @@ void gfx_delete_all() {
dynos_gfx_delete_all();
}
+const char *vtx_get_name(Vtx *vtx) {
+ if (!vtx) { return NULL; }
+
+ return dynos_vtx_get_name(vtx);
+}
+
u32 vtx_get_count(Vtx *vtx) {
if (!vtx) { return 0; }
diff --git a/src/pc/lua/utils/smlua_gfx_utils.h b/src/pc/lua/utils/smlua_gfx_utils.h
index 331dcc456..4175188b3 100644
--- a/src/pc/lua/utils/smlua_gfx_utils.h
+++ b/src/pc/lua/utils/smlua_gfx_utils.h
@@ -67,8 +67,10 @@ Vtx *gfx_get_vertex_buffer(Gfx *cmd);
/* |description|Gets the number of vertices from a display list command if it has the op `G_VTX`|descriptionEnd| */
u16 gfx_get_vertex_count(Gfx *cmd);
/* |description|Gets the texture from a display list command if it has an image related op|descriptionEnd| */
-u8 *gfx_get_texture(Gfx *cmd);
+Texture *gfx_get_texture(Gfx *cmd);
+/* |description|Gets the name of a display list|descriptionEnd| */
+const char *gfx_get_name(Gfx *gfx);
/* |description|Gets the max length of a display list|descriptionEnd| */
u32 gfx_get_length(Gfx *gfx);
/* |description|Gets a command of a display list at position `offset`|descriptionEnd| */
@@ -86,6 +88,8 @@ void gfx_delete(Gfx *gfx);
/* |description|Deletes all display lists created by `gfx_create`|descriptionEnd| */
void gfx_delete_all();
+/* |description|Gets the name of a vertex buffer|descriptionEnd| */
+const char *vtx_get_name(Vtx *vtx);
/* |description|Gets the max count of vertices of a vertex buffer|descriptionEnd| */
u32 vtx_get_count(Vtx *vtx);
/* |description|Gets a vertex of a vertex buffer at position `offset`|descriptionEnd| */
diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c
index c57c06d3f..7a469db0a 100644
--- a/src/pc/lua/utils/smlua_misc_utils.c
+++ b/src/pc/lua/utils/smlua_misc_utils.c
@@ -241,16 +241,16 @@ extern const u8 texture_power_meter_two_segments[];
extern const u8 texture_power_meter_one_segments[];
static struct TextureInfo sPowerMeterTexturesInfo[] = {
- { (u8*)texture_power_meter_left_side, "texture_power_meter_left_side", 32, 64, 8 },
- { (u8*)texture_power_meter_right_side, "texture_power_meter_right_side", 32, 64, 8 },
- { (u8*)texture_power_meter_one_segments, "texture_power_meter_one_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_two_segments, "texture_power_meter_two_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_three_segments, "texture_power_meter_three_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_four_segments, "texture_power_meter_four_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_five_segments, "texture_power_meter_five_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_six_segments, "texture_power_meter_six_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_seven_segments, "texture_power_meter_seven_segments", 32, 32, 8 },
- { (u8*)texture_power_meter_full, "texture_power_meter_full", 32, 32, 8 },
+ { (Texture*)texture_power_meter_left_side, "texture_power_meter_left_side", 32, 64, 8 },
+ { (Texture*)texture_power_meter_right_side, "texture_power_meter_right_side", 32, 64, 8 },
+ { (Texture*)texture_power_meter_one_segments, "texture_power_meter_one_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_two_segments, "texture_power_meter_two_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_three_segments, "texture_power_meter_three_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_four_segments, "texture_power_meter_four_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_five_segments, "texture_power_meter_five_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_six_segments, "texture_power_meter_six_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_seven_segments, "texture_power_meter_seven_segments", 32, 32, 8 },
+ { (Texture*)texture_power_meter_full, "texture_power_meter_full", 32, 32, 8 },
};
void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height) {
@@ -539,9 +539,17 @@ void set_environment_region(u8 index, s16 value) {
bool mod_file_exists(const char* filename) {
if (gLuaActiveMod == NULL) { return false; }
+ char normPath[SYS_MAX_PATH] = { 0 };
+
+ if (snprintf(normPath, sizeof(normPath), "%s", filename) < 0) {
+ LOG_ERROR("Failed to copy filename for normalization: %s", filename);
+ }
+
+ normalize_path(normPath);
+
for (s32 i = 0; i < gLuaActiveMod->fileCount; i++) {
struct ModFile* file = &gLuaActiveMod->files[i];
- if (!strcmp(file->relativePath, filename)) {
+ if (!strcmp(file->relativePath, normPath)) {
return true;
}
}
@@ -603,7 +611,7 @@ struct GraphNodeHeldObject* geo_get_current_held_object(void) {
return gCurGraphNodeHeldObject;
}
-void texture_to_lua_table(const u8 *tex) {
+void texture_to_lua_table(const Texture *tex) {
lua_State *L = gLuaState;
if (!L || !tex) { return; }
@@ -614,7 +622,7 @@ void texture_to_lua_table(const u8 *tex) {
if (bpp != 16 && bpp != 32) { return; }
u32 bytesPerPixel = bpp / 8;
- const u8 *data = texInfo.texture;
+ const Texture *data = texInfo.texture;
u32 texSize = texInfo.width * texInfo.height * bytesPerPixel;
lua_newtable(L);
@@ -642,3 +650,11 @@ void texture_to_lua_table(const u8 *tex) {
lua_rawseti(L, -2, i / bytesPerPixel + 1);
}
}
+
+const char *get_texture_name(const Texture *tex) {
+ struct TextureInfo texInfo;
+ if (dynos_texture_get_from_data(tex, &texInfo)) {
+ return texInfo.name;
+ }
+ return NULL;
+}
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index b8b5b198b..8332a2d48 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -252,7 +252,10 @@ struct GraphNodeCamera* geo_get_current_camera(void);
/* |description|Gets the current GraphNodeHeldObject|descriptionEnd|*/
struct GraphNodeHeldObject* geo_get_current_held_object(void);
-/* |description|Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures.|descriptionEnd|*/
-void texture_to_lua_table(const u8 *tex);
+/* |description|Converts a texture's pixels to a Lua table. Returns nil if failed. Otherwise, returns a table as a pure memory buffer. Supports rgba16 and rgba32 textures|descriptionEnd|*/
+void texture_to_lua_table(const Texture *tex);
+
+/* |description|Gets the name of the provided texture pointer `tex`|descriptionEnd|*/
+const char *get_texture_name(const Texture *tex);
#endif
diff --git a/src/pc/mods/mod.c b/src/pc/mods/mod.c
index a0e5c817b..aca944c85 100644
--- a/src/pc/mods/mod.c
+++ b/src/pc/mods/mod.c
@@ -23,7 +23,7 @@ size_t mod_get_lua_size(struct Mod* mod) {
for (int i = 0; i < mod->fileCount; i++) {
struct ModFile* file = &mod->files[i];
- if (!(str_ends_with(file->relativePath, ".lua") || str_ends_with(file->relativePath, ".luac"))) { continue; }
+ if (!(path_ends_with(file->relativePath, ".lua") || path_ends_with(file->relativePath, ".luac"))) { continue; }
size += file->size;
}
@@ -161,19 +161,19 @@ void mod_activate(struct Mod* mod) {
mod_cache_update(mod, file);
}
- if (str_ends_with(file->relativePath, ".bin")) {
+ if (path_ends_with(file->relativePath, ".bin")) {
mod_activate_bin(mod, file);
}
- if (str_ends_with(file->relativePath, ".col")) {
+ if (path_ends_with(file->relativePath, ".col")) {
mod_activate_col(file);
}
- if (str_ends_with(file->relativePath, ".lvl")) {
+ if (path_ends_with(file->relativePath, ".lvl")) {
mod_activate_lvl(mod, file);
}
- if (str_ends_with(file->relativePath, ".bhv")) {
+ if (path_ends_with(file->relativePath, ".bhv")) {
mod_activate_bhv(mod, file);
}
- if (str_ends_with(file->relativePath, ".tex")) {
+ if (path_ends_with(file->relativePath, ".tex")) {
mod_activate_tex(file);
}
}
@@ -245,15 +245,22 @@ static struct ModFile* mod_allocate_file(struct Mod* mod, char* relativePath) {
memset(file, 0, sizeof(struct ModFile));
// set relative path
- if (snprintf(file->relativePath, SYS_MAX_PATH - 1, "%s", relativePath) < 0) {
- LOG_ERROR("Failed to remember relative path '%s'", relativePath);
+ char normPath[SYS_MAX_PATH] = { 0 };
+ if (snprintf(normPath, sizeof(normPath), "%s", relativePath) < 0) {
+ LOG_ERROR("Failed to copy relative path for normalization: %s", relativePath);
+ }
+
+ normalize_path(normPath);
+
+ if (snprintf(file->relativePath, SYS_MAX_PATH - 1, "%s", normPath) < 0) {
+ LOG_ERROR("Failed to remember relative path '%s'", normPath);
return NULL;
}
// figure out full path
char fullPath[SYS_MAX_PATH] = { 0 };
if (!mod_file_full_path(fullPath, mod, file)) {
- LOG_ERROR("Failed to concat path: '%s' + '%s'", mod->basePath, relativePath);
+ LOG_ERROR("Failed to concat path: '%s' + '%s'", mod->basePath, normPath);
return NULL;
}
@@ -330,7 +337,7 @@ static bool mod_load_files_dir(struct Mod* mod, char* fullPath, const char* subD
bool fileTypeMatch = false;
const char** ft = fileTypes;
while (*ft != NULL) {
- if (str_ends_with(path, (char*)*ft)) {
+ if (path_ends_with(path, (char*)*ft)) {
fileTypeMatch = true;
}
ft++;
@@ -555,7 +562,7 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
bool isDirectory = fs_sys_dir_exists(fullPath);
// make sure mod is valid
- if (str_ends_with(modName, ".lua")) {
+ if (path_ends_with(modName, ".lua")) {
valid = true;
} else if (fs_sys_dir_exists(fullPath)) {
char tmpPath[SYS_MAX_PATH] = { 0 };
diff --git a/src/pc/mods/mod_fs.cpp b/src/pc/mods/mod_fs.cpp
index c141e64e0..1dcfb4305 100644
--- a/src/pc/mods/mod_fs.cpp
+++ b/src/pc/mods/mod_fs.cpp
@@ -2,20 +2,38 @@ extern "C" {
#include "mod_fs.h"
#include "src/pc/fs/fs.h"
#include "src/pc/mods/mods_utils.h"
+#include "pc/utils/miniz/miniz.h"
}
#include
#include
#include
#include