diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 8c368a4ea..60ac72ffe 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -2328,7 +2328,7 @@ Dispatches to the appropriate action function, such as jump, double jump, freefa |descriptionEnd| */ s32 mario_execute_airborne_action(struct MarioState *m) { if (!m) { return FALSE; } - u32 cancel; + s32 cancel; if (check_common_airborne_cancels(m)) { return TRUE; @@ -2336,7 +2336,7 @@ s32 mario_execute_airborne_action(struct MarioState *m) { play_far_fall_sound(m); - if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, (s32*)&cancel)) { + if (!smlua_call_action_hook(ACTION_HOOK_EVERY_FRAME, m, &cancel)) { /* clang-format off */ switch (m->action) { case ACT_JUMP: cancel = act_jump(m); break; @@ -2387,7 +2387,7 @@ s32 mario_execute_airborne_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_FREEFALL, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 535d94110..bb3ea807f 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -1221,7 +1221,7 @@ s32 mario_execute_automatic_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 51026b681..694e86352 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -3192,7 +3192,7 @@ s32 mario_execute_cutscene_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index c22f2a631..400d30cad 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -2264,7 +2264,7 @@ s32 mario_execute_moving_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_object.c b/src/game/mario_actions_object.c index ca66da1db..3da4ac87e 100644 --- a/src/game/mario_actions_object.c +++ b/src/game/mario_actions_object.c @@ -536,7 +536,7 @@ s32 mario_execute_object_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_stationary.c b/src/game/mario_actions_stationary.c index 8fe099c85..d9df47584 100644 --- a/src/game/mario_actions_stationary.c +++ b/src/game/mario_actions_stationary.c @@ -1302,7 +1302,7 @@ s32 mario_execute_stationary_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index e573613c1..08faaf044 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -1712,7 +1712,7 @@ s32 mario_execute_submerged_action(struct MarioState *m) { default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); set_mario_action(m, ACT_WATER_IDLE, 0); - return false; + return FALSE; } /* clang-format on */ } diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 5f8a84145..a01154ba8 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -675,11 +675,13 @@ u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) { void apply_gravity(struct MarioState *m) { if (!m) { return; } - s32 result; - if (smlua_call_action_hook(ACTION_HOOK_GRAVITY, m, &result)) { - - } else if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) { + UNUSED s32 cancel; + if (smlua_call_action_hook(ACTION_HOOK_GRAVITY, m, &cancel)) { + return; + } + + if (m->action == ACT_TWIRLING && m->vel[1] < 0.0f) { apply_twirl_gravity(m); } else if (m->action == ACT_SHOT_FROM_CANNON) { m->vel[1] -= 1.0f; diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 6ec341c05..db87bd8f4 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -324,7 +324,7 @@ int smlua_hook_mario_action(lua_State* L) { return 1; } -bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue) { +bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* cancel) { lua_State* L = gLuaState; if (L == NULL) { return false; } @@ -348,13 +348,31 @@ bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* } // output the return value - *returnValue = false; - if (lua_type(L, -1) == LUA_TBOOLEAN || lua_type(L, -1) == LUA_TNUMBER) { - *returnValue = smlua_to_integer(L, -1); + // returning a negative value allows to continue the execution, useful when overriding vanilla actions + bool stopActionHook = true; + *cancel = FALSE; + + switch (lua_type(L, -1)) { + case LUA_TBOOLEAN: { + *cancel = smlua_to_boolean(L, -1) ? TRUE : FALSE; + } break; + + case LUA_TNUMBER: { + s32 returnValue = (s32) smlua_to_integer(L, -1); + if (returnValue > 0) { + *cancel = TRUE; + } else if (returnValue == 0) { + *cancel = FALSE; + } else { + stopActionHook = false; + } + } break; } lua_pop(L, 1); - return true; + if (stopActionHook) { + return true; + } } } diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 12a8af6dc..6e1c9d296 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -143,7 +143,7 @@ const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id); bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before); int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod, struct ModFile* activeModFile); -bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* returnValue); +bool smlua_call_action_hook(enum LuaActionHookType hookType, struct MarioState* m, s32* cancel); u32 smlua_get_action_interaction_type(struct MarioState* m); bool smlua_call_chat_command_hook(char* command);