diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua
index 5a708ed9..701ff3dc 100644
--- a/autogen/lua_definitions/constants.lua
+++ b/autogen/lua_definitions/constants.lua
@@ -4404,7 +4404,7 @@ PLAYER_INTERACTIONS_SOLID = 1
PLAYER_INTERACTIONS_PVP = 2
--- @type integer
-MAX_RX_SEQ_IDS = 16
+MAX_RX_SEQ_IDS = 64
--- @type integer
NETWORK_PLAYER_TIMEOUT = 10
@@ -7849,7 +7849,10 @@ HOOK_ON_SET_CAMERA_MODE = 18
HOOK_ON_OBJECT_RENDER = 19
--- @type LuaHookedEventType
-HOOK_MAX = 20
+HOOK_ON_DEATH = 20
+
+--- @type LuaHookedEventType
+HOOK_MAX = 21
--- @class ModelExtendedId
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 277ab463..73bbd5f7 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -3930,6 +3930,12 @@ function hurt_and_set_mario_action(m, action, actionArg, hurtCounter)
-- ...
end
+--- @param m MarioState
+--- @return nil
+function init_single_mario(m)
+ -- ...
+end
+
--- @param m MarioState
--- @return integer
function is_anim_at_end(m)
diff --git a/docs/lua/constants.md b/docs/lua/constants.md
index 816ee8a2..0532526c 100644
--- a/docs/lua/constants.md
+++ b/docs/lua/constants.md
@@ -2754,7 +2754,8 @@
| HOOK_GET_STAR_COLLECTION_DIALOG | 17 |
| HOOK_ON_SET_CAMERA_MODE | 18 |
| HOOK_ON_OBJECT_RENDER | 19 |
-| HOOK_MAX | 20 |
+| HOOK_ON_DEATH | 20 |
+| HOOK_MAX | 21 |
[:arrow_up_small:](#)
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 3794259e..584fede3 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -765,6 +765,7 @@
- [find_mario_anim_flags_and_translation](#find_mario_anim_flags_and_translation)
- [force_idle_state](#force_idle_state)
- [hurt_and_set_mario_action](#hurt_and_set_mario_action)
+ - [init_single_mario](#init_single_mario)
- [is_anim_at_end](#is_anim_at_end)
- [is_anim_past_end](#is_anim_past_end)
- [is_anim_past_frame](#is_anim_past_frame)
@@ -14941,6 +14942,26 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
+## [init_single_mario](#init_single_mario)
+
+### Lua Example
+`init_single_mario(m)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| m | [MarioState](structs.md#MarioState) |
+
+### Returns
+- None
+
+### C Prototype
+`void init_single_mario(struct MarioState* m);`
+
+[:arrow_up_small:](#)
+
+
+
## [is_anim_at_end](#is_anim_at_end)
### Lua Example
diff --git a/docs/lua/hooks.md b/docs/lua/hooks.md
index 6b8dd65d..07021327 100644
--- a/docs/lua/hooks.md
+++ b/docs/lua/hooks.md
@@ -106,6 +106,7 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
| HOOK_GET_STAR_COLLECTION_DIALOG | Called when the local player collects a star, return a [DialogId](constants.md#enum-DialogId) to show a message | None |
| HOOK_ON_SET_CAMERA_MODE | Called when the camera mode gets set, return `false` to prevent the camera mode from being set | [Camera](structs.md#Camera), `integer` mode, `integer` frames |
| HOOK_ON_OBJECT_RENDER | Called right before an object is rendered. **Note:** You must set the `hookRender` field of the object to a non-zero value | [Object](structs.md#Object) |
+| HOOK_ON_DEATH | Called when the local player dies, return `false` to prevent normal death sequence | [MarioState](structs.md#MarioState) |
### Parameters
diff --git a/src/engine/level_script.c b/src/engine/level_script.c
index 45412c8f..57f5788c 100644
--- a/src/engine/level_script.c
+++ b/src/engine/level_script.c
@@ -858,16 +858,24 @@ static void level_cmd_place_object_ext(void) {
u16 modIndex = gLevelScriptModIndex;
const char* behStr = dynos_level_get_token(CMD_GET(u32, 20));
+ if (gLevelScriptModIndex == -1) {
+ LOG_ERROR("Could not find level script mod index");
+ sCurrentCmd = CMD_NEXT;
+ return;
+ }
+
gSmLuaConvertSuccess = true;
+ gSmLuaSuppressErrors = true;
enum BehaviorId behId = smlua_get_mod_variable(modIndex, behStr);
+ gSmLuaSuppressErrors = false;
if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true;
behId = smlua_get_any_mod_variable(behStr);
}
- if ((gLevelScriptModIndex == -1) || !gSmLuaConvertSuccess) {
- LOG_ERROR("Failed to place custom object: %u :: %s", behId, behStr);
+ if (!gSmLuaConvertSuccess) {
+ LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr);
sCurrentCmd = CMD_NEXT;
return;
}
@@ -907,22 +915,37 @@ static void level_cmd_place_object_ext2(void) {
const char* modelStr = dynos_level_get_token(CMD_GET(u32, 20));
const char* behStr = dynos_level_get_token(CMD_GET(u32, 24));
+ if (gLevelScriptModIndex == -1) {
+ LOG_ERROR("Could not find level script mod index");
+ sCurrentCmd = CMD_NEXT;
+ return;
+ }
+
gSmLuaConvertSuccess = true;
+ gSmLuaSuppressErrors = true;
enum ModelExtendedId modelId = smlua_get_mod_variable(modIndex, modelStr);
+ gSmLuaSuppressErrors = false;
if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true;
modelId = smlua_get_any_mod_variable(modelStr);
}
+ if (!gSmLuaConvertSuccess) {
+ LOG_LUA("Failed to place custom object, could not find model '%s'", modelStr);
+ sCurrentCmd = CMD_NEXT;
+ return;
+ }
gSmLuaConvertSuccess = true;
+ gSmLuaSuppressErrors = true;
enum BehaviorId behId = smlua_get_mod_variable(modIndex, behStr);
+ gSmLuaSuppressErrors = false;
if (!gSmLuaConvertSuccess) {
gSmLuaConvertSuccess = true;
behId = smlua_get_any_mod_variable(behStr);
}
- if ((gLevelScriptModIndex == -1) || !gSmLuaConvertSuccess) {
- LOG_ERROR("Failed to place custom object: %u, %u", modelId, behId);
+ if (!gSmLuaConvertSuccess) {
+ LOG_LUA("Failed to place custom object, could not find behavior '%s'", behStr);
sCurrentCmd = CMD_NEXT;
return;
}
diff --git a/src/game/interaction.c b/src/game/interaction.c
index c02ad828..3f842227 100644
--- a/src/game/interaction.c
+++ b/src/game/interaction.c
@@ -2209,6 +2209,10 @@ void check_death_barrier(struct MarioState *m) {
if (m->playerIndex != 0) { return; }
if (m->pos[1] < m->floorHeight + 2048.0f) {
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return; }
+
if (mario_can_bubble(m)) {
switch (gCurrCourseNum) {
case COURSE_COTMC: // (20) Cavern of the Metal Cap
diff --git a/src/game/mario.c b/src/game/mario.c
index 2b6f8848..376017c0 100644
--- a/src/game/mario.c
+++ b/src/game/mario.c
@@ -2107,7 +2107,7 @@ s32 force_idle_state(struct MarioState* m) {
* INITIALIZATION *
**************************************************/
-static void init_single_mario(struct MarioState* m) {
+void init_single_mario(struct MarioState* m) {
u16 playerIndex = m->playerIndex;
struct SpawnInfo* spawnInfo = &gPlayerSpawnInfos[playerIndex];
diff --git a/src/game/mario.h b/src/game/mario.h
index 0407d291..67aa916a 100644
--- a/src/game/mario.h
+++ b/src/game/mario.h
@@ -54,6 +54,7 @@ s32 transition_submerged_to_walking(struct MarioState *m);
s32 set_water_plunge_action(struct MarioState *m);
s32 execute_mario_action(UNUSED struct Object *o);
s32 force_idle_state(struct MarioState* m);
+void init_single_mario(struct MarioState* m);
void init_mario(void);
void init_mario_from_save_file(void);
diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c
index 2281d91b..3c64c3ed 100644
--- a/src/game/mario_actions_airborne.c
+++ b/src/game/mario_actions_airborne.c
@@ -1576,11 +1576,20 @@ s32 act_lava_boost(struct MarioState *m) {
if (m != &gMarioStates[0]) {
// never kill remote marios
m->health = 0x100;
- } else if (mario_can_bubble(m)) {
- m->health = 0xFF;
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) {
+ reset_rumble_timers(m);
+ return FALSE;
+ }
+
+ if (mario_can_bubble(m)) {
+ m->health = 0xFF;
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c
index eafe1ddc..bed82c7a 100644
--- a/src/game/mario_actions_cutscene.c
+++ b/src/game/mario_actions_cutscene.c
@@ -35,6 +35,7 @@
#include "pc/configfile.h"
#include "pc/network/network.h"
#include "pc/lua/smlua.h"
+#include "pc/lua/smlua_hooks.h"
// TODO: put this elsewhere
enum SaveOption { SAVE_OPT_SAVE_AND_CONTINUE = 1, /*SAVE_OPT_SAVE_AND_QUIT, SAVE_OPT_SAVE_EXIT_GAME,*/ SAVE_OPT_CONTINUE_DONT_SAVE };
@@ -777,10 +778,16 @@ s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWa
if (animFrame == frameToDeathWarp) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return animFrame; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
@@ -842,12 +849,18 @@ s32 act_quicksand_death(struct MarioState *m) {
if ((m->quicksandDepth += 5.0f) >= 180.0f) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ m->actionState = 2;
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
- m->actionState = 2;
}
}
stationary_ground_step(m);
@@ -862,11 +875,17 @@ s32 act_eaten_by_bubba(struct MarioState *m) {
if (m->actionTimer++ == 60) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- m->health = 0xFF;
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ m->health = 0xFF;
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
@@ -1743,15 +1762,21 @@ s32 act_squished(struct MarioState *m) {
if (m->playerIndex != 0) {
// never kill remote marios
m->health = 0x100;
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- // 0 units of health
- m->health = 0x00FF;
- m->hurtCounter = 0;
- level_trigger_warp(m, WARP_OP_DEATH);
- // woosh, he's gone!
- set_mario_action(m, ACT_DISAPPEARED, 0);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ // 0 units of health
+ m->health = 0x00FF;
+ m->hurtCounter = 0;
+ level_trigger_warp(m, WARP_OP_DEATH);
+ // woosh, he's gone!
+ set_mario_action(m, ACT_DISAPPEARED, 0);
+ }
}
}
stop_and_set_height_to_floor(m);
diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c
index 1a007997..9e48096c 100644
--- a/src/game/mario_actions_submerged.c
+++ b/src/game/mario_actions_submerged.c
@@ -20,6 +20,7 @@
#include "pc/configfile.h"
#include "pc/network/network.h"
#include "pc/lua/smlua.h"
+#include "pc/lua/smlua_hooks.h"
#define MIN_SWIM_STRENGTH 160
#define MIN_SWIM_SPEED 16.0f
@@ -944,10 +945,16 @@ static s32 act_drowning(struct MarioState *m) {
if (m->marioObj->header.gfx.animInfo.animFrame == 30) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
break;
@@ -972,10 +979,16 @@ static s32 act_water_death(struct MarioState *m) {
if (set_mario_animation(m, MARIO_ANIM_WATER_DYING) == 35) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
@@ -1090,10 +1103,16 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) {
if (distance < 16.1f && m->actionTimer++ == 16) {
if (m->playerIndex != 0) {
// do nothing
- } else if (mario_can_bubble(m)) {
- mario_set_bubbled(m);
} else {
- level_trigger_warp(m, WARP_OP_DEATH);
+ bool allowDeath = true;
+ smlua_call_event_hooks_mario_param_ret_bool(HOOK_ON_DEATH, m, &allowDeath);
+ if (!allowDeath) { reset_rumble_timers(m); return FALSE; }
+
+ if (mario_can_bubble(m)) {
+ mario_set_bubbled(m);
+ } else {
+ level_trigger_warp(m, WARP_OP_DEATH);
+ }
}
}
}
diff --git a/src/pc/lua/smlua.c b/src/pc/lua/smlua.c
index 47049385..a7b9342c 100644
--- a/src/pc/lua/smlua.c
+++ b/src/pc/lua/smlua.c
@@ -8,6 +8,7 @@
lua_State* gLuaState = NULL;
u8 gLuaInitializingScript = 0;
+u8 gSmLuaSuppressErrors = 0;
struct Mod* gLuaLoadingMod = NULL;
struct Mod* gLuaActiveMod = NULL;
struct Mod* gLuaLastHookMod = NULL;
diff --git a/src/pc/lua/smlua.h b/src/pc/lua/smlua.h
index 26a6d4db..92de306f 100644
--- a/src/pc/lua/smlua.h
+++ b/src/pc/lua/smlua.h
@@ -19,7 +19,7 @@
#include "pc/debuglog.h"
-#define LOG_LUA(...) ( _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error() )
+#define LOG_LUA(...) { if (!gSmLuaSuppressErrors) { _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error(); } }
#ifdef DEVELOPMENT
#define LUA_STACK_CHECK_BEGIN() int __LUA_STACK_TOP = lua_gettop(gLuaState)
@@ -31,6 +31,7 @@
extern lua_State* gLuaState;
extern u8 gLuaInitializingScript;
+extern u8 gSmLuaSuppressErrors;
extern struct Mod* gLuaLoadingMod;
extern struct Mod* gLuaActiveMod;
extern struct Mod* gLuaLastHookMod;
diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c
index 93407df0..330865de 100644
--- a/src/pc/lua/smlua_constants_autogen.c
+++ b/src/pc/lua/smlua_constants_autogen.c
@@ -1656,7 +1656,7 @@ char gSmluaConstants[] = ""
"UNKNOWN_GLOBAL_INDEX = (-1)\n"
"UNKNOWN_NETWORK_INDEX = (-1)\n"
"NETWORK_PLAYER_TIMEOUT = 10\n"
-"MAX_RX_SEQ_IDS = 16\n"
+"MAX_RX_SEQ_IDS = 64\n"
"NPT_UNKNOWN = 0\n"
"NPT_LOCAL = 1\n"
"NPT_SERVER = 2\n"
@@ -2797,7 +2797,8 @@ char gSmluaConstants[] = ""
"HOOK_GET_STAR_COLLECTION_DIALOG = 17\n"
"HOOK_ON_SET_CAMERA_MODE = 18\n"
"HOOK_ON_OBJECT_RENDER = 19\n"
-"HOOK_MAX = 20\n"
+"HOOK_ON_DEATH = 20\n"
+"HOOK_MAX = 21\n"
"E_MODEL_NONE = 0\n"
"E_MODEL_MARIO = 1\n"
"E_MODEL_SMOKE = 2\n"
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index a4d246d9..e633dbf8 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -8026,6 +8026,17 @@ int smlua_func_hurt_and_set_mario_action(lua_State* L) {
return 1;
}
+int smlua_func_init_single_mario(lua_State* L) {
+ if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
+
+ struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE);
+ if (!gSmLuaConvertSuccess) { return 0; }
+
+ init_single_mario(m);
+
+ return 1;
+}
+
int smlua_func_is_anim_at_end(lua_State* L) {
if(!smlua_functions_valid_param_count(L, 1)) { return 0; }
@@ -16549,6 +16560,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "find_mario_anim_flags_and_translation", smlua_func_find_mario_anim_flags_and_translation);
smlua_bind_function(L, "force_idle_state", smlua_func_force_idle_state);
smlua_bind_function(L, "hurt_and_set_mario_action", smlua_func_hurt_and_set_mario_action);
+ smlua_bind_function(L, "init_single_mario", smlua_func_init_single_mario);
smlua_bind_function(L, "is_anim_at_end", smlua_func_is_anim_at_end);
smlua_bind_function(L, "is_anim_past_end", smlua_func_is_anim_past_end);
smlua_bind_function(L, "is_anim_past_frame", smlua_func_is_anim_past_frame);
diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c
index bea50c2b..6d06ea0d 100644
--- a/src/pc/lua/smlua_hooks.c
+++ b/src/pc/lua/smlua_hooks.c
@@ -223,6 +223,37 @@ void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct
}
}
+void smlua_call_event_hooks_mario_param_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, bool* returnValue) {
+ lua_State* L = gLuaState;
+ if (L == NULL) { return; }
+ struct LuaHookedEvent* hook = &sHookedEvents[hookType];
+ for (int i = 0; i < hook->count; i++) {
+ s32 prevTop = lua_gettop(L);
+
+ // push the callback onto the stack
+ lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
+
+ // push mario state
+ lua_getglobal(L, "gMarioStates");
+ lua_pushinteger(L, m->playerIndex);
+ lua_gettable(L, -2);
+ lua_remove(L, -2);
+
+ // call the callback
+ if (0 != smlua_call_hook(L, 1, 1, 0, hook->mod[i])) {
+ LOG_LUA("Failed to call the callback: %u, %s", hookType, lua_tostring(L, -1));
+ smlua_logline();
+ continue;
+ }
+
+ // output the return value
+ if (lua_type(L, -1) == LUA_TBOOLEAN) {
+ *returnValue = smlua_to_boolean(L, -1);
+ }
+ lua_settop(L, prevTop);
+ }
+}
+
void smlua_call_event_hooks_mario_params(enum LuaHookedEventType hookType, struct MarioState* m1, struct MarioState* m2) {
lua_State* L = gLuaState;
if (L == NULL) { return; }
diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h
index e6e8d3c7..b0804df8 100644
--- a/src/pc/lua/smlua_hooks.h
+++ b/src/pc/lua/smlua_hooks.h
@@ -28,6 +28,7 @@ enum LuaHookedEventType {
HOOK_GET_STAR_COLLECTION_DIALOG,
HOOK_ON_SET_CAMERA_MODE,
HOOK_ON_OBJECT_RENDER,
+ HOOK_ON_DEATH,
HOOK_MAX,
};
@@ -52,6 +53,7 @@ static char* LuaHookedEventTypeName[] = {
"HOOK_GET_STAR_COLLECTION_DIALOG",
"HOOK_ON_SET_CAMERA_MODE",
"HOOK_ON_OBJECT_RENDER",
+ "HOOK_ON_DEATH",
"HOOK_MAX"
};
@@ -61,6 +63,7 @@ void smlua_call_event_hooks(enum LuaHookedEventType hookType);
void smlua_call_event_hooks_bool_param(enum LuaHookedEventType hookType, bool value);
void smlua_call_event_hooks_bool_param_ret_bool(enum LuaHookedEventType hookType, bool value, bool* returnValue);
void smlua_call_event_hooks_mario_param(enum LuaHookedEventType hookType, struct MarioState* m);
+void smlua_call_event_hooks_mario_param_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, bool* returnValue);
void smlua_call_event_hooks_mario_params(enum LuaHookedEventType hookType, struct MarioState* m1, struct MarioState* m2);
void smlua_call_event_hooks_mario_params_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m1, struct MarioState* m2, bool* returnValue);
void smlua_call_event_hooks_interact_params(enum LuaHookedEventType hookType, struct MarioState* m, struct Object* obj, u32 interactType, bool interactValue);
diff --git a/src/pc/lua/smlua_utils.c b/src/pc/lua/smlua_utils.c
index 97cd4ef1..8db9df13 100644
--- a/src/pc/lua/smlua_utils.c
+++ b/src/pc/lua/smlua_utils.c
@@ -397,6 +397,7 @@ s64 smlua_get_mod_variable(u16 modIndex, const char* variable) {
s64 smlua_get_any_mod_variable(const char* variable) {
lua_State* L = gLuaState;
+ u8 prevSuppress = gSmLuaSuppressErrors;
s64 value = 0;
for (s32 i = 0; i < gActiveMods.entryCount; i++) {
@@ -406,15 +407,18 @@ s64 smlua_get_any_mod_variable(const char* variable) {
int prevTop = lua_gettop(L);
lua_getglobal(L, "_G"); // get global table
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table
+ gSmLuaSuppressErrors = true;
value = smlua_get_integer_field(-1, (char*)variable);
lua_settop(L, prevTop);
if (gSmLuaConvertSuccess) {
+ gSmLuaSuppressErrors = prevSuppress;
return value;
}
}
// return variable
+ gSmLuaSuppressErrors = prevSuppress;
return value;
}