From 97090abf28b120c97e177bb874ae8e49a342d3a4 Mon Sep 17 00:00:00 2001 From: Sunk <69110309+Sunketchupm@users.noreply.github.com> Date: Sun, 30 Oct 2022 20:25:56 -0400 Subject: [PATCH] Added HOOK_ALLOW_HAZARD_SURFACE and various fixes (#209) * Fixed naming from ceil to cell * Added HOOK_ON_QUICKSAND * Modified hook and removed weird newlines * Renamed hook and increased usage HOOK_ALLOW_QUICKSAND -> HOOK_ALLOW_HAZARD_SURFACE Now also works on lavaboost. Suggestion by Agent X. May add this hook to the death barrier check. * Autogen * Fixed downwarping to quicksand upon popping As a side effect though, Mario will no longer snap to the floor upon being popped. --- autogen/lua_definitions/constants.lua | 5 ++++- autogen/lua_definitions/structs.lua | 2 +- docs/lua/constants.md | 3 ++- docs/lua/structs.md | 2 +- src/engine/surface_collision.c | 6 +++--- src/engine/surface_collision.h | 2 +- src/game/camera.c | 22 +++++++++++----------- src/game/hardcoded.c | 2 +- src/game/hardcoded.h | 2 +- src/game/interaction.c | 4 +++- src/game/mario_actions_airborne.c | 4 +++- src/game/mario_actions_automatic.c | 3 ++- src/game/mario_step.c | 4 +++- src/pc/lua/smlua_cobject_autogen.c | 2 +- src/pc/lua/smlua_constants_autogen.c | 3 ++- src/pc/lua/smlua_hooks.c | 26 ++++++++++++++++++++++++++ src/pc/lua/smlua_hooks.h | 3 +++ 17 files changed, 68 insertions(+), 27 deletions(-) diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index 06e82cec8..e5744b8a8 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -8119,7 +8119,10 @@ HOOK_ON_CHANGE_CAMERA_ANGLE = 24 HOOK_ON_SCREEN_TRANSITION = 25 --- @type LuaHookedEventType -HOOK_MAX = 26 +HOOK_ALLOW_HAZARD_SURFACE = 26 + +--- @type LuaHookedEventType +HOOK_MAX = 27 --- @class HudDisplayFlags diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index f67e0da96..e5029e920 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -623,7 +623,7 @@ --- @field public yaw integer --- @class LevelValues ---- @field public ceilHeightLimit integer +--- @field public cellHeightLimit integer --- @field public coinsRequiredForCoinStar integer --- @field public entryLevel LevelNum --- @field public exitCastleArea integer diff --git a/docs/lua/constants.md b/docs/lua/constants.md index f842ca628..7e88176ca 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -2875,7 +2875,8 @@ | HOOK_USE_ACT_SELECT | 23 | | HOOK_ON_CHANGE_CAMERA_ANGLE | 24 | | HOOK_ON_SCREEN_TRANSITION | 25 | -| HOOK_MAX | 26 | +| HOOK_ALLOW_HAZARD_SURFACE | 26 | +| HOOK_MAX | 27 | [:arrow_up_small:](#) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index aaa3d3ff0..1dc20ea19 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -918,7 +918,7 @@ | Field | Type | Access | | ----- | ---- | ------ | -| ceilHeightLimit | `integer` | | +| cellHeightLimit | `integer` | | | coinsRequiredForCoinStar | `integer` | | | entryLevel | [enum LevelNum](constants.md#enum-LevelNum) | | | exitCastleArea | `integer` | | diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 9434b9f08..5d14dd007 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -380,7 +380,7 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 // set pheight to highest value if (gLevelValues.fixCollisionBugs) { - *pheight = gLevelValues.ceilHeightLimit; + *pheight = gLevelValues.cellHeightLimit; } // Stay in this loop until out of ceilings. @@ -468,8 +468,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) { s16 cellZ, cellX; struct Surface *ceil, *dynamicCeil; struct SurfaceNode *surfaceList; - f32 height = gLevelValues.ceilHeightLimit; - f32 dynamicHeight = gLevelValues.ceilHeightLimit; + f32 height = gLevelValues.cellHeightLimit; + f32 dynamicHeight = gLevelValues.cellHeightLimit; s16 x, y, z; //! (Parallel Universes) Because position is casted to an s16, reaching higher diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index d831cc3ee..67f5c6f23 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -8,7 +8,7 @@ #include "engine/extended_bounds.h" -#define CEIL_HEIGHT_LIMIT 20000 +#define CELL_HEIGHT_LIMIT 20000 #define FLOOR_LOWER_LIMIT -11000 #define FLOOR_LOWER_LIMIT_MISC (FLOOR_LOWER_LIMIT + 1000) // same as FLOOR_LOWER_LIMIT_MISC, explicitly for shadow.c diff --git a/src/game/camera.c b/src/game/camera.c index 51e774003..4c91be394 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -806,10 +806,10 @@ void set_camera_height(struct Camera *c, f32 goalHeight) { } } approach_camera_height(c, goalHeight, 20.f); - if (camCeilHeight != gLevelValues.ceilHeightLimit) { + if (camCeilHeight != gLevelValues.cellHeightLimit) { camCeilHeight -= baseOff; if ((c->pos[1] > camCeilHeight && sMarioGeometry.currFloorHeight + baseOff < camCeilHeight) - || (sMarioGeometry.currCeilHeight != gLevelValues.ceilHeightLimit + || (sMarioGeometry.currCeilHeight != gLevelValues.cellHeightLimit && sMarioGeometry.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) { c->pos[1] = camCeilHeight; } @@ -1515,7 +1515,7 @@ s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) { } ceilHeight = find_ceil(c->pos[0], goalHeight - 100.f, c->pos[2], &ceiling); - if (ceilHeight != gLevelValues.ceilHeightLimit) { + if (ceilHeight != gLevelValues.cellHeightLimit) { if (goalHeight > (ceilHeight -= 125.f)) { goalHeight = ceilHeight; } @@ -1614,7 +1614,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { // When C-Down is not active, this vec3f_set_dist_and_angle(focus, pos, focusDistance, 0x1000, yaw); // Find the floor of the arena - pos[1] = find_floor(c->areaCenX, gLevelValues.ceilHeightLimit, c->areaCenZ, &floor); + pos[1] = find_floor(c->areaCenX, gLevelValues.cellHeightLimit, c->areaCenZ, &floor); if (floor != NULL) { nx = floor->normal.x; ny = floor->normal.y; @@ -2351,7 +2351,7 @@ s16 update_default_camera(struct Camera *c) { if (c->mode == CAMERA_MODE_FREE_ROAM) { camFloorHeight -= 100.f; } - ceilHeight = gLevelValues.ceilHeightLimit; + ceilHeight = gLevelValues.cellHeightLimit; vec3f_copy(c->focus, sMarioCamState->pos); } @@ -2360,7 +2360,7 @@ s16 update_default_camera(struct Camera *c) { if (sMarioCamState->pos[1] - 100.f > camFloorHeight) { camFloorHeight = sMarioCamState->pos[1] - 100.f; } - ceilHeight = gLevelValues.ceilHeightLimit; + ceilHeight = gLevelValues.cellHeightLimit; vec3f_copy(c->focus, sMarioCamState->pos); } if (camFloorHeight != gLevelValues.floorLowerLimit) { @@ -2385,7 +2385,7 @@ s16 update_default_camera(struct Camera *c) { vec3f_set_dist_and_angle(c->focus, c->pos, dist, tempPitch, tempYaw); } } - if (ceilHeight != gLevelValues.ceilHeightLimit) { + if (ceilHeight != gLevelValues.cellHeightLimit) { if (c->pos[1] > (ceilHeight -= 150.f) && (avoidStatus = is_range_behind_surface(c->pos, sMarioCamState->pos, ceil, 0, -1)) == 1) { c->pos[1] = ceilHeight; @@ -6826,19 +6826,19 @@ void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f lastGood) { floorY = find_floor(pos[0], pos[1] + 50.f, pos[2], &surf); ceilY = find_ceil(pos[0], pos[1] - 50.f, pos[2], &surf); - if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.ceilHeightLimit == ceilY)) { + if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.cellHeightLimit == ceilY)) { if (pos[1] < (floorY += 125.f)) { pos[1] = floorY; } } - if ((gLevelValues.floorLowerLimit == floorY) && (gLevelValues.ceilHeightLimit != ceilY)) { + if ((gLevelValues.floorLowerLimit == floorY) && (gLevelValues.cellHeightLimit != ceilY)) { if (pos[1] > (ceilY -= 125.f)) { pos[1] = ceilY; } } - if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.ceilHeightLimit != ceilY)) { + if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.cellHeightLimit != ceilY)) { floorY += 125.f; ceilY -= 125.f; @@ -6972,7 +6972,7 @@ void find_mario_floor_and_ceil(struct PlayerGeometry *pg) { } if (find_ceil(sMarioCamState->pos[0], sMarioCamState->pos[1] - 10.f, - sMarioCamState->pos[2], &surf) != gLevelValues.ceilHeightLimit) { + sMarioCamState->pos[2], &surf) != gLevelValues.cellHeightLimit) { pg->currCeilType = surf->type; } else { pg->currCeilType = 0; diff --git a/src/game/hardcoded.c b/src/game/hardcoded.c index 0d73808d8..a3d9bf339 100644 --- a/src/game/hardcoded.c +++ b/src/game/hardcoded.c @@ -89,7 +89,7 @@ struct LevelValues gDefaultLevelValues = { .UnagiStarPos = { 6833.0f, -3654.0f, 2230.0f }, .JetstreamRingStarPos = { 3400.0f, -3200.0f, -500.0f }, }, - .ceilHeightLimit = CEIL_HEIGHT_LIMIT, + .cellHeightLimit = CELL_HEIGHT_LIMIT, .floorLowerLimit = FLOOR_LOWER_LIMIT, .floorLowerLimitMisc = FLOOR_LOWER_LIMIT_MISC, .floorLowerLimitShadow = FLOOR_LOWER_LIMIT_SHADOW, diff --git a/src/game/hardcoded.h b/src/game/hardcoded.h index 0f7ff8907..3b6326e12 100644 --- a/src/game/hardcoded.h +++ b/src/game/hardcoded.h @@ -53,7 +53,7 @@ struct LevelValues { u16 metalCapDurationCotmc; u16 vanishCapDurationVcutm; struct StarPositions starPositions; - s16 ceilHeightLimit; + s16 cellHeightLimit; s16 floorLowerLimit; s16 floorLowerLimitMisc; s16 floorLowerLimitShadow; diff --git a/src/game/interaction.c b/src/game/interaction.c index db4f05e79..477dc72e2 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -2261,7 +2261,9 @@ void check_death_barrier(struct MarioState *m) { } void check_lava_boost(struct MarioState *m) { - if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode)) { return; } + bool allow = true; + smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); + if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode) || (!allow)) { return; } if (!(m->action & ACT_FLAG_RIDING_SHELL) && m->pos[1] < m->floorHeight + 10.0f) { 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 b0fb16103..d1b4c057c 100644 --- a/src/game/mario_actions_airborne.c +++ b/src/game/mario_actions_airborne.c @@ -53,7 +53,9 @@ void play_knockback_sound(struct MarioState *m) { #endif s32 lava_boost_on_wall(struct MarioState *m) { - if (Cheats.enabled && Cheats.godMode) { return FALSE; } + bool allow = true; + smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); + if ((Cheats.enabled && Cheats.godMode) || (!allow)) { return FALSE; } m->faceAngle[1] = atan2s(m->wallNormal[2], m->wallNormal[0]); if (m->forwardVel < 24.0f) { diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index f3c2d542c..d14d4283c 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -1049,7 +1049,8 @@ s32 act_bubbled(struct MarioState* m) { if (m->playerIndex == 0) { soft_reset_camera(m->area->camera); } - return force_idle_state(m); + u8 underWater = (m->pos[1] < ((f32)m->waterLevel)); + return set_mario_action(m, underWater ? ACT_WATER_IDLE : ACT_FREEFALL, 0); } return FALSE; diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 7fbce03eb..d188f9de9 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -109,7 +109,9 @@ void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) { } u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { - if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode)) { + bool allow = true; + smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow); + if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode) || (!allow)) { m->quicksandDepth = 0.0f; } else { if (m->quicksandDepth < 1.1f) { diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index b6bab7908..d48994f7c 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -728,7 +728,7 @@ static struct LuaObjectField sLakituStateFields[LUA_LAKITU_STATE_FIELD_COUNT] = #define LUA_LEVEL_VALUES_FIELD_COUNT 20 static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { - { "ceilHeightLimit", LVT_S16, offsetof(struct LevelValues, ceilHeightLimit), false, LOT_NONE }, + { "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE }, { "coinsRequiredForCoinStar", LVT_S16, offsetof(struct LevelValues, coinsRequiredForCoinStar), false, LOT_NONE }, { "entryLevel", LVT_S32, offsetof(struct LevelValues, entryLevel), false, LOT_NONE }, { "exitCastleArea", LVT_S16, offsetof(struct LevelValues, exitCastleArea), false, LOT_NONE }, diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index a583abbfb..b9939812b 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -2882,7 +2882,8 @@ char gSmluaConstants[] = "" "HOOK_USE_ACT_SELECT = 23\n" "HOOK_ON_CHANGE_CAMERA_ANGLE = 24\n" "HOOK_ON_SCREEN_TRANSITION = 25\n" -"HOOK_MAX = 26\n" +"HOOK_ALLOW_HAZARD_SURFACE = 26\n" +"HOOK_MAX = 27\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 72d518436..590a21700 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -424,6 +424,32 @@ bool smlua_call_event_hooks_ret_int(enum LuaHookedEventType hookType, s32* retur return false; } +void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, bool* returnValue) { + lua_State* L = gLuaState; + if (L == NULL) { return; } + *returnValue = true; + + 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]); + + // call the callback + if (0 != smlua_call_hook(L, 0, 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_TBOOLEAN && *returnValue) { + *returnValue = smlua_to_boolean(L, -1); + } + lua_settop(L, prevTop); + } +} + void smlua_call_event_hooks_network_player_param(enum LuaHookedEventType hookType, struct NetworkPlayer* np) { 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 c7c6a54ca..86873e7d7 100644 --- a/src/pc/lua/smlua_hooks.h +++ b/src/pc/lua/smlua_hooks.h @@ -37,6 +37,7 @@ enum LuaHookedEventType { HOOK_USE_ACT_SELECT, HOOK_ON_CHANGE_CAMERA_ANGLE, HOOK_ON_SCREEN_TRANSITION, + HOOK_ALLOW_HAZARD_SURFACE, HOOK_MAX, }; @@ -67,6 +68,7 @@ static const char* LuaHookedEventTypeName[] = { "HOOK_USE_ACT_SELECT", "HOOK_ON_CHANGE_CAMERA_ANGLE", "HOOK_ON_SCREEN_TRANSITION", + "HOOK_ALLOW_HAZARD_SURFACE", "HOOK_MAX" }; @@ -101,6 +103,7 @@ void smlua_call_event_hooks_set_camera_mode_params(enum LuaHookedEventType hookT void smlua_call_event_hooks_int_params_ret_bool(enum LuaHookedEventType hookType, s16 param, bool* returnValue); void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex); void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int value, bool* foundHook, bool* returnValue); +void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, bool* returnValue); enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior); const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);