diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index cbb93852f..eb9dbbe4f 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -629,7 +629,8 @@ --- @field public exitCastleArea integer --- @field public exitCastleLevel LevelNum --- @field public exitCastleWarpNode integer ---- @field public fixCollisionBugs integer +--- @field public fixCollisionBugs boolean +--- @field public fixVanishFloors boolean --- @field public floorLowerLimit integer --- @field public floorLowerLimitMisc integer --- @field public floorLowerLimitShadow integer diff --git a/docs/lua/structs.md b/docs/lua/structs.md index fdc74c427..de2630f6e 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -924,7 +924,8 @@ | exitCastleArea | `integer` | | | exitCastleLevel | [enum LevelNum](constants.md#enum-LevelNum) | | | exitCastleWarpNode | `integer` | | -| fixCollisionBugs | `integer` | | +| fixCollisionBugs | `boolean` | | +| fixVanishFloors | `boolean` | | | floorLowerLimit | `integer` | | | floorLowerLimitMisc | `integer` | | | floorLowerLimitShadow | `integer` | | diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c index 5d14dd007..da49d2d6b 100644 --- a/src/engine/surface_collision.c +++ b/src/engine/surface_collision.c @@ -263,7 +263,7 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, if (gCurrentObject != NULL && gCurrentObject == gMarioStates[i].marioObj && (gMarioStates[i].flags & MARIO_VANISH_CAP)) { passThroughWall = TRUE; - continue; + break; } } if (passThroughWall) { continue; } @@ -414,9 +414,30 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32 continue; } } - // Ignore camera only surfaces. - else if (surf->type == SURFACE_CAMERA_BOUNDARY || surf->type == SURFACE_RAYCAST) { - continue; + else { + // Ignore camera only surfaces. + if (surf->type == SURFACE_CAMERA_BOUNDARY || surf->type == SURFACE_RAYCAST) { + continue; + } + + // If an object can pass through a vanish cap surface, pass through. + if (gLevelValues.fixVanishFloors && surf->type == SURFACE_VANISH_CAP_WALLS) { + if (gCurrentObject != NULL + && (gCurrentObject->activeFlags & ACTIVE_FLAG_MOVE_THROUGH_GRATE)) { + continue; + } + + // If Mario has a vanish cap, pass through the vanish cap surface. + u8 passThrough = FALSE; + for (s32 i = 0; i < MAX_PLAYERS; i++) { + if (gCurrentObject != NULL && gCurrentObject == gMarioStates[i].marioObj + && (gMarioStates[i].flags & MARIO_VANISH_CAP)) { + passThrough = TRUE; + break; + } + } + if (passThrough) { continue; } + } } { @@ -642,11 +663,31 @@ static struct Surface *find_floor_from_list(struct SurfaceNode *surfaceNode, s32 continue; } } - // If we are not checking for the camera, ignore camera only floors. - else if (surf->type == SURFACE_CAMERA_BOUNDARY || surf->type == SURFACE_RAYCAST) { - continue; - } + else { + // If we are not checking for the camera, ignore camera only floors. + if (surf->type == SURFACE_CAMERA_BOUNDARY || surf->type == SURFACE_RAYCAST) { + continue; + } + // If an object can pass through a vanish cap surface, pass through. + if (gLevelValues.fixVanishFloors && surf->type == SURFACE_VANISH_CAP_WALLS) { + if (gCurrentObject != NULL + && (gCurrentObject->activeFlags & ACTIVE_FLAG_MOVE_THROUGH_GRATE)) { + continue; + } + + // If Mario has a vanish cap, pass through the vanish cap surface. + u8 passThrough = FALSE; + for (s32 i = 0; i < MAX_PLAYERS; i++) { + if (gCurrentObject != NULL && gCurrentObject == gMarioStates[i].marioObj + && (gMarioStates[i].flags & MARIO_VANISH_CAP)) { + passThrough = TRUE; + break; + } + } + if (passThrough) { continue; } + } + } if (interpolate) { f32 y1, y2, y3; diff --git a/src/game/hardcoded.c b/src/game/hardcoded.c index a3d9bf339..d1d888cd6 100644 --- a/src/game/hardcoded.c +++ b/src/game/hardcoded.c @@ -43,6 +43,7 @@ extern Trajectory sThiTinyMetalBallTraj[]; struct LevelValues gDefaultLevelValues = { .fixCollisionBugs = 0, + .fixVanishFloors = 0, .entryLevel = LEVEL_CASTLE_GROUNDS, .exitCastleLevel = LEVEL_CASTLE, .exitCastleArea = 1, diff --git a/src/game/hardcoded.h b/src/game/hardcoded.h index 56510c64d..3b2101573 100644 --- a/src/game/hardcoded.h +++ b/src/game/hardcoded.h @@ -37,7 +37,8 @@ struct StarPositions { }; struct LevelValues { - u8 fixCollisionBugs; + bool fixCollisionBugs; + bool fixVanishFloors; enum LevelNum entryLevel; enum LevelNum exitCastleLevel; s16 exitCastleArea; @@ -228,4 +229,4 @@ extern struct BehaviorValues gBehaviorValues; void hardcoded_reset_default_values(void); -#endif \ No newline at end of file +#endif diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index 10e19735a..ee99cb0da 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -726,7 +726,7 @@ static struct LuaObjectField sLakituStateFields[LUA_LAKITU_STATE_FIELD_COUNT] = { "yaw", LVT_S16, offsetof(struct LakituState, yaw), false, LOT_NONE }, }; -#define LUA_LEVEL_VALUES_FIELD_COUNT 20 +#define LUA_LEVEL_VALUES_FIELD_COUNT 21 static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { { "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE }, { "coinsRequiredForCoinStar", LVT_S16, offsetof(struct LevelValues, coinsRequiredForCoinStar), false, LOT_NONE }, @@ -734,7 +734,8 @@ static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { "exitCastleArea", LVT_S16, offsetof(struct LevelValues, exitCastleArea), false, LOT_NONE }, { "exitCastleLevel", LVT_S32, offsetof(struct LevelValues, exitCastleLevel), false, LOT_NONE }, { "exitCastleWarpNode", LVT_U8, offsetof(struct LevelValues, exitCastleWarpNode), false, LOT_NONE }, - { "fixCollisionBugs", LVT_U8, offsetof(struct LevelValues, fixCollisionBugs), false, LOT_NONE }, + { "fixCollisionBugs", LVT_BOOL, offsetof(struct LevelValues, fixCollisionBugs), false, LOT_NONE }, + { "fixVanishFloors", LVT_BOOL, offsetof(struct LevelValues, fixVanishFloors), false, LOT_NONE }, { "floorLowerLimit", LVT_S16, offsetof(struct LevelValues, floorLowerLimit), false, LOT_NONE }, { "floorLowerLimitMisc", LVT_S16, offsetof(struct LevelValues, floorLowerLimitMisc), false, LOT_NONE }, { "floorLowerLimitShadow", LVT_S16, offsetof(struct LevelValues, floorLowerLimitShadow), false, LOT_NONE },