From 9acb632b8ec9fd6aba212c1b272ba91be29c3ea9 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:15:27 -0400 Subject: [PATCH] Fix HOOK_ALLOW_HAZARD_SURFACE and expose `SURFACE_IS_*` macros (#865) * Fix HOOK_ALLOW_HAZARD_SURFACE * Peachy's suggestions * Exposed `surface_is_*` macros --- autogen/lua_definitions/functions.lua | 21 ++++++++ docs/lua/functions-6.md | 69 ++++++++++++++++++++++++ docs/lua/functions.md | 3 ++ include/surface_terrains.h | 2 +- src/game/interaction.c | 8 +-- src/game/mario_actions_airborne.c | 12 ++--- src/game/mario_step.c | 33 ++++++++---- src/pc/lua/smlua_functions_autogen.c | 54 +++++++++++++++++++ src/pc/lua/utils/smlua_collision_utils.c | 15 ++++++ src/pc/lua/utils/smlua_collision_utils.h | 7 +++ 10 files changed, 203 insertions(+), 21 deletions(-) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index ce8adeb06..c0b532b10 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -10223,6 +10223,27 @@ function smlua_collision_util_find_surface_types(data) -- ... end +--- @param surf Surface +--- @return boolean +--- Checks if the surface is quicksand +function surface_is_quicksand(surf) + -- ... +end + +--- @param surf Surface +--- @return boolean +--- Checks if the surface is not a hard surface +function surface_is_not_hard(surf) + -- ... +end + +--- @param surf Surface +--- @return boolean +--- Checks if the surface is a painting warp +function surface_is_painting_warp(surf) + -- ... +end + --- @param fov number --- Sets the override FOV function set_override_fov(fov) diff --git a/docs/lua/functions-6.md b/docs/lua/functions-6.md index c87745a38..46f2aef50 100644 --- a/docs/lua/functions-6.md +++ b/docs/lua/functions-6.md @@ -2112,6 +2112,75 @@ Gets a table of the surface types from `data`
+## [surface_is_quicksand](#surface_is_quicksand) + +### Description +Checks if the surface is quicksand + +### Lua Example +`local booleanValue = surface_is_quicksand(surf)` + +### Parameters +| Field | Type | +| ----- | ---- | +| surf | [Surface](structs.md#Surface) | + +### Returns +- `boolean` + +### C Prototype +`bool surface_is_quicksand(struct Surface* surf);` + +[:arrow_up_small:](#) + +
+ +## [surface_is_not_hard](#surface_is_not_hard) + +### Description +Checks if the surface is not a hard surface + +### Lua Example +`local booleanValue = surface_is_not_hard(surf)` + +### Parameters +| Field | Type | +| ----- | ---- | +| surf | [Surface](structs.md#Surface) | + +### Returns +- `boolean` + +### C Prototype +`bool surface_is_not_hard(struct Surface* surf);` + +[:arrow_up_small:](#) + +
+ +## [surface_is_painting_warp](#surface_is_painting_warp) + +### Description +Checks if the surface is a painting warp + +### Lua Example +`local booleanValue = surface_is_painting_warp(surf)` + +### Parameters +| Field | Type | +| ----- | ---- | +| surf | [Surface](structs.md#Surface) | + +### Returns +- `boolean` + +### C Prototype +`bool surface_is_painting_warp(struct Surface* surf);` + +[:arrow_up_small:](#) + +
+ --- # functions from smlua_deprecated.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 10d832f15..bbef2c349 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1843,6 +1843,9 @@ - [smlua_collision_util_get_current_terrain_collision](functions-6.md#smlua_collision_util_get_current_terrain_collision) - [smlua_collision_util_get_level_collision](functions-6.md#smlua_collision_util_get_level_collision) - [smlua_collision_util_find_surface_types](functions-6.md#smlua_collision_util_find_surface_types) + - [surface_is_quicksand](functions-6.md#surface_is_quicksand) + - [surface_is_not_hard](functions-6.md#surface_is_not_hard) + - [surface_is_painting_warp](functions-6.md#surface_is_painting_warp)
diff --git a/include/surface_terrains.h b/include/surface_terrains.h index d020cd45c..091ed64d4 100644 --- a/include/surface_terrains.h +++ b/include/surface_terrains.h @@ -151,7 +151,7 @@ #define SURFACE_WOBBLING_WARP 0x00FD // Pool warp (HMC & DDD) #define SURFACE_TRAPDOOR 0x00FF // Bowser Left trapdoor, has no action defined -#define SURFACE_IS_QUICKSAND(cmd) (cmd >= 0x21 && cmd < 0x28) // Doesn't include SURFACE_INSTANT_MOVING_QUICKSAND +#define SURFACE_IS_QUICKSAND(cmd) ((cmd >= 0x21 && cmd < 0x28) || cmd == SURFACE_INSTANT_MOVING_QUICKSAND) #define SURFACE_IS_NOT_HARD(cmd) (cmd != SURFACE_HARD && \ !(cmd >= 0x35 && cmd <= 0x37)) #define SURFACE_IS_PAINTING_WARP(cmd) (cmd >= 0xD3 && cmd < 0xFD) diff --git a/src/game/interaction.c b/src/game/interaction.c index 3ea2ef1bd..9c963673c 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -2460,10 +2460,12 @@ void check_death_barrier(struct MarioState *m) { void check_lava_boost(struct MarioState *m) { if (!m) { return; } - bool allowHazard = true; - smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_LAVA_FLOOR, &allowHazard); - if (m->action == ACT_BUBBLED || (!allowHazard)) { return; } + if (m->action == ACT_BUBBLED) { return; } if (!(m->action & ACT_FLAG_RIDING_SHELL) && m->pos[1] < m->floorHeight + 10.0f) { + bool allowHazard = true; + smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_LAVA_FLOOR, &allowHazard); + if (!allowHazard) { return; } + if (!(m->flags & MARIO_METAL_CAP)) { m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18; } diff --git a/src/game/mario_actions_airborne.c b/src/game/mario_actions_airborne.c index 1865d465c..8c368a4ea 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -206,16 +206,16 @@ s32 check_horizontal_wind(struct MarioState *m) { struct Surface *floor; f32 speed; s16 pushAngle; - bool allowHazard = true; - smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_HORIZONTAL_WIND, &allowHazard); - if (!allowHazard) { - return FALSE; - } floor = m->floor; - if (floor && floor->type == SURFACE_HORIZONTAL_WIND) { + bool allowHazard = true; + smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_HORIZONTAL_WIND, &allowHazard); + if (!allowHazard) { + return FALSE; + } + pushAngle = floor->force << 8; m->slideVelX += 1.2f * sins(pushAngle); diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 16be3e767..5f8a84145 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -123,10 +123,8 @@ void mario_bonk_reflection(struct MarioState *m, u8 negateSpeed) { u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { if (!m) { return 0; } - bool allowHazard = true; - smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_QUICKSAND, &allowHazard); extern bool gDjuiInMainMenu; - if (m->action & ACT_FLAG_RIDING_SHELL || (!allowHazard) || gDjuiInMainMenu) { + if (m->action & ACT_FLAG_RIDING_SHELL || gDjuiInMainMenu) { m->quicksandDepth = 0.0f; } else { if (m->quicksandDepth < 1.1f) { @@ -135,6 +133,16 @@ u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { u32 floorType = m->floor ? m->floor->type : SURFACE_DEFAULT; + // Only run the hook if the player is actually on quicksand + if (SURFACE_IS_QUICKSAND(floorType)) { + bool allowHazard = true; + smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_QUICKSAND, &allowHazard); + if (!allowHazard) { + m->quicksandDepth = 0; + return FALSE; + } + } + switch (floorType) { case SURFACE_SHALLOW_QUICKSAND: if ((m->quicksandDepth += sinkingSpeed) >= 10.0f) { @@ -217,14 +225,15 @@ u32 mario_update_windy_ground(struct MarioState *m) { if (!m) { return 0; } struct Surface *floor = m->floor; if (!floor) { return 0; } - bool allowHazard = true; - smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_HORIZONTAL_WIND, &allowHazard); - if (!allowHazard) { - return FALSE; - } extern bool gDjuiInMainMenu; if (floor->type == SURFACE_HORIZONTAL_WIND && !gDjuiInMainMenu) { + bool allowHazard = true; + smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_HORIZONTAL_WIND, &allowHazard); + if (!allowHazard) { + return FALSE; + } + f32 pushSpeed; s16 pushAngle = floor->force << 8; @@ -721,12 +730,14 @@ void apply_vertical_wind(struct MarioState *m) { if (!m) { return; } f32 maxVelY; f32 offsetY; - bool allowHazard = true; - smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_VERTICAL_WIND, &allowHazard); - if (m->action != ACT_GROUND_POUND && allowHazard) { + if (m->action != ACT_GROUND_POUND) { offsetY = m->pos[1] - -1500.0f; if (m->floor && m->floor->type == SURFACE_VERTICAL_WIND && -3000.0f < offsetY && offsetY < 2000.0f) { + bool allowHazard = true; + smlua_call_event_hooks(HOOK_ALLOW_HAZARD_SURFACE, m, HAZARD_TYPE_VERTICAL_WIND, &allowHazard); + if (!allowHazard) { return; } + if (offsetY >= 0.0f) { maxVelY = 10000.0f / (offsetY + 200.0f); } else { diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 2bf3ba87c..16f3e16d5 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -30898,6 +30898,57 @@ int smlua_func_smlua_collision_util_find_surface_types(lua_State* L) { return 1; } +int smlua_func_surface_is_quicksand(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", "surface_is_quicksand", 1, top); + return 0; + } + + struct Surface* surf = (struct Surface*)smlua_to_cobject(L, 1, LOT_SURFACE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "surface_is_quicksand"); return 0; } + + lua_pushboolean(L, surface_is_quicksand(surf)); + + return 1; +} + +int smlua_func_surface_is_not_hard(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", "surface_is_not_hard", 1, top); + return 0; + } + + struct Surface* surf = (struct Surface*)smlua_to_cobject(L, 1, LOT_SURFACE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "surface_is_not_hard"); return 0; } + + lua_pushboolean(L, surface_is_not_hard(surf)); + + return 1; +} + +int smlua_func_surface_is_painting_warp(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", "surface_is_painting_warp", 1, top); + return 0; + } + + struct Surface* surf = (struct Surface*)smlua_to_cobject(L, 1, LOT_SURFACE); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "surface_is_painting_warp"); return 0; } + + lua_pushboolean(L, surface_is_painting_warp(surf)); + + return 1; +} + //////////////////////// // smlua_deprecated.h // //////////////////////// @@ -37033,6 +37084,9 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "smlua_collision_util_get_current_terrain_collision", smlua_func_smlua_collision_util_get_current_terrain_collision); smlua_bind_function(L, "smlua_collision_util_get_level_collision", smlua_func_smlua_collision_util_get_level_collision); smlua_bind_function(L, "smlua_collision_util_find_surface_types", smlua_func_smlua_collision_util_find_surface_types); + smlua_bind_function(L, "surface_is_quicksand", smlua_func_surface_is_quicksand); + smlua_bind_function(L, "surface_is_not_hard", smlua_func_surface_is_not_hard); + smlua_bind_function(L, "surface_is_painting_warp", smlua_func_surface_is_painting_warp); // smlua_deprecated.h smlua_bind_function(L, "djui_hud_set_render_behind_hud", smlua_func_djui_hud_set_render_behind_hud); diff --git a/src/pc/lua/utils/smlua_collision_utils.c b/src/pc/lua/utils/smlua_collision_utils.c index 7e9bafb0f..0a83bc172 100644 --- a/src/pc/lua/utils/smlua_collision_utils.c +++ b/src/pc/lua/utils/smlua_collision_utils.c @@ -237,3 +237,18 @@ void smlua_collision_util_find_surface_types(Collision* data) { // Couldn't find anything lua_pushnil(L); } + +bool surface_is_quicksand(struct Surface* surf) { + if (surf == NULL) { return FALSE; } + return SURFACE_IS_QUICKSAND(surf->type); +} + +bool surface_is_not_hard(struct Surface* surf) { + if (surf == NULL) { return FALSE; } + return SURFACE_IS_NOT_HARD(surf->type); +} + +bool surface_is_painting_warp(struct Surface* surf) { + if (surf == NULL) { return FALSE; } + return SURFACE_IS_PAINTING_WARP(surf->type); +} \ No newline at end of file diff --git a/src/pc/lua/utils/smlua_collision_utils.h b/src/pc/lua/utils/smlua_collision_utils.h index 8782fc37e..8836a7162 100644 --- a/src/pc/lua/utils/smlua_collision_utils.h +++ b/src/pc/lua/utils/smlua_collision_utils.h @@ -142,4 +142,11 @@ Collision *smlua_collision_util_get_level_collision(u32 level, u16 area); /* |description|Gets a table of the surface types from `data`|descriptionEnd| */ void smlua_collision_util_find_surface_types(Collision* data); +/* |description|Checks if the surface is quicksand|descriptionEnd| */ +bool surface_is_quicksand(struct Surface* surf); +/* |description|Checks if the surface is not a hard surface|descriptionEnd| */ +bool surface_is_not_hard(struct Surface* surf); +/* |description|Checks if the surface is a painting warp|descriptionEnd| */ +bool surface_is_painting_warp(struct Surface* surf); + #endif