diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 575885f72..318179181 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -9260,7 +9260,10 @@ HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37 HOOK_MIRROR_MARIO_RENDER = 38 --- @type LuaHookedEventType -HOOK_MAX = 39 +HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED = 39 + +--- @type LuaHookedEventType +HOOK_MAX = 40 --- @class HudDisplayFlags diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 9bc69ceb4..11ce4f2eb 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -3319,7 +3319,8 @@ | HOOK_ON_HUD_RENDER_BEHIND | 36 | | HOOK_ON_COLLIDE_LEVEL_BOUNDS | 37 | | HOOK_MIRROR_MARIO_RENDER | 38 | -| HOOK_MAX | 39 | +| HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED | 39 | +| HOOK_MAX | 40 | [:arrow_up_small:](#) diff --git a/docs/lua/guides/hooks.md b/docs/lua/guides/hooks.md index c42639a7a..65a9f2ec5 100644 --- a/docs/lua/guides/hooks.md +++ b/docs/lua/guides/hooks.md @@ -124,8 +124,9 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh | HOOK_ON_DIALOG | Called when a dialog appears. Return `false` to prevent it from appearing | `integer` dialogId | | HOOK_ON_EXIT | Called before the game shuts down | None | | HOOK_DIALOG_SOUND | Called when a dialog box sound is going to play, return a `DS_*` constant to override the sound | `integer` dialogSound | -| HOOK_ON_COLLIDE_LEVEL_BOUNDS | Called when a mario collides with the level boundaries | [MarioState](structs.md#MarioState)mario | -| HOOK_MIRROR_MARIO_RENDER | Called when a Mirror Mario is rendered. | [GraphNodeObject](structs.md#GraphNodeObject) mirrorMario | `integer` mirrorMarioIndex | +| HOOK_ON_COLLIDE_LEVEL_BOUNDS | Called when a mario collides with the level boundaries | [MarioState](structs.md#MarioState) mario | +| HOOK_MIRROR_MARIO_RENDER | Called when a Mirror Mario is rendered | [GraphNodeObject](structs.md#GraphNodeObject) mirrorMario | `integer` mirrorMarioIndex | +| HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED | Called when slope defacto speed for walking is being calculated, overrides the floor normal in the equation | [MarioState](structs.md#MarioState) mario | ### Parameters diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 3ade058de..0c5c41d99 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -362,8 +362,12 @@ s32 perform_ground_step(struct MarioState *m) { for (i = 0; i < 4; i++) { Vec3f step = { 0 }; if (m->floor) { - step[0] = m->floor->normal.y * (m->vel[0] / 4.0f); - step[2] = m->floor->normal.y * (m->vel[2] / 4.0f); + f32 floorNormal; + if (!smlua_call_event_hooks_mario_param_ret_float(HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED, m, &floorNormal)) { + floorNormal = m->floor->normal.y; + } + step[0] = floorNormal * (m->vel[0] / 4.0f); + step[2] = floorNormal * (m->vel[2] / 4.0f); } intendedPos[0] = m->pos[0] + step[0]; diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index ffe6702ce..965260b23 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -3280,7 +3280,8 @@ char gSmluaConstants[] = "" "HOOK_ON_HUD_RENDER_BEHIND = 36\n" "HOOK_ON_COLLIDE_LEVEL_BOUNDS = 37\n" "HOOK_MIRROR_MARIO_RENDER = 38\n" -"HOOK_MAX = 39\n" +"HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED = 39\n" +"HOOK_MAX = 40\n" "ACTION_HOOK_EVERY_FRAME = 0\n" "ACTION_HOOK_GRAVITY = 1\n" "ACTION_HOOK_MAX = 2\n" diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 4e289fe98..b58f195b6 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -877,6 +877,40 @@ bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType return false; } +bool smlua_call_event_hooks_mario_param_ret_float(enum LuaHookedEventType hookType, struct MarioState* m, f32* returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return false; } + 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", hookType); + continue; + } + + // output the return value + if (lua_type(L, -1) == LUA_TNUMBER) { + *returnValue = smlua_to_number(L, -1); + } + lua_settop(L, prevTop); + + return true; + } + + return false; +} + bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue) { lua_State* L = gLuaState; if (L == NULL) { return false; } diff --git a/src/pc/lua/smlua_hooks.h b/src/pc/lua/smlua_hooks.h index 9eb2903a7..7f47cfd18 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -50,6 +50,7 @@ enum LuaHookedEventType { HOOK_ON_HUD_RENDER_BEHIND, HOOK_ON_COLLIDE_LEVEL_BOUNDS, HOOK_MIRROR_MARIO_RENDER, + HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED, HOOK_MAX, }; @@ -93,6 +94,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_ON_HUD_RENDER_BEHIND", "HOOK_ON_COLLIDE_LEVEL_BOUNDS", "HOOK_MIRROR_MARIO_RENDER", + "HOOK_OVERRIDE_PHYS_STEP_DEFACTO_SPEED", "HOOK_MAX" }; @@ -137,6 +139,7 @@ bool smlua_call_event_hooks_mario_character_sound_param_ret_int(enum LuaHookedEv void smlua_call_event_hooks_mario_action_params_ret_int(enum LuaHookedEventType hookType, struct MarioState *m, u32 action, u32* returnValue); void smlua_call_event_hooks_mario_param_and_int_ret_bool(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, bool* returnValue); bool smlua_call_event_hooks_mario_param_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, s32* returnValue); +bool smlua_call_event_hooks_mario_param_ret_float(enum LuaHookedEventType hookType, struct MarioState* m, f32* returnValue); bool smlua_call_event_hooks_mario_param_and_int_and_int_ret_int(enum LuaHookedEventType hookType, struct MarioState* m, s32 param, u32 args, s32* returnValue); void smlua_call_event_hooks_graph_node_object_and_int_param(enum LuaHookedEventType hookType, struct GraphNodeObject* node, s32 param);