diff --git a/include/surface_terrains.h b/include/surface_terrains.h index 908a73eb..155ed250 100644 --- a/include/surface_terrains.h +++ b/include/surface_terrains.h @@ -13,7 +13,7 @@ enum SurfaceTypes { SURFACE_0004, // 0x0004 // Unused, has no function and has parameters SURFACE_HANGABLE, // 0x0005 // Ceiling that Mario can climb on SURFACE_0006, // 0x0006 // Unused - SURFACE_0007, // 0x0007 // Unused + SURFACE_SUPER_SLIPPERY, // 0x0007 // Super slippery surface, good for delimiting your level SURFACE_0008, // 0x0008 // Unused SURFACE_SLOW, // 0x0009 // Slow down Mario, unused SURFACE_DEATH_PLANE, // 0x000A // Death floor. Warps to ID of force parameter's second byte if set, otherwise warps to 0xF3 if it exists, otherwise defaults to ID 0xF1. diff --git a/src/game/mario.c b/src/game/mario.c index fcf9eafb..c3e743f1 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -404,6 +404,7 @@ s32 mario_get_floor_class(struct MarioState *m) { floorClass = SURFACE_CLASS_SLIPPERY; break; + case SURFACE_SUPER_SLIPPERY: case SURFACE_VERY_SLIPPERY: case SURFACE_ICE: case SURFACE_HARD_VERY_SLIPPERY: @@ -482,6 +483,7 @@ u32 mario_get_terrain_sound_addend(struct MarioState *m) { floorSoundType = 2; break; + case SURFACE_SUPER_SLIPPERY: case SURFACE_VERY_SLIPPERY: case SURFACE_ICE: case SURFACE_HARD_VERY_SLIPPERY: @@ -512,6 +514,10 @@ u32 mario_get_terrain_sound_addend(struct MarioState *m) { * Determines if Mario is facing "downhill." */ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) { + // Forces Mario to do a belly slide rather than a butt slide when on a super slippery floor, no matter his angle, so that the player can't jump. + if (m->floor && m->floor->type == SURFACE_SUPER_SLIPPERY) + return FALSE; + s16 faceAngleYaw = m->faceAngle[1]; // This is never used in practice, as turnYaw is @@ -531,7 +537,7 @@ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) { u32 mario_floor_is_slippery(struct MarioState *m) { f32 normY; - if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE && m->floor->normal.y < COS1) { + if (((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE && m->floor->normal.y < COS1) || (m->floor->type == SURFACE_SUPER_SLIPPERY)) { return TRUE; } @@ -551,8 +557,8 @@ u32 mario_floor_is_slippery(struct MarioState *m) { s32 mario_floor_is_slope(struct MarioState *m) { f32 normY; - if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE - && m->floor->normal.y < COS1) { + if (((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE + && m->floor->normal.y < COS1) || (m->floor->type == SURFACE_SUPER_SLIPPERY)) { return TRUE; } @@ -571,6 +577,8 @@ s32 mario_floor_is_slope(struct MarioState *m) { */ s32 mario_floor_is_steep(struct MarioState *m) { f32 normY; + if (m->floor->type == SURFACE_SUPER_SLIPPERY) + return TRUE; #ifdef JUMP_KICK_FIX if (m->floor->type == SURFACE_NOT_SLIPPERY) { diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 23dc7a87..902a1823 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -470,10 +470,11 @@ void update_walking_speed(struct MarioState *m) { s32 should_begin_sliding(struct MarioState *m) { if (m->input & INPUT_ABOVE_SLIDE) { + s32 superSlippery = (m->floor != NULL) && (m->floor->type == SURFACE_SUPER_SLIPPERY); s32 slideLevel = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE; s32 movingBackward = m->forwardVel <= -1.0f; - if (slideLevel || movingBackward || mario_facing_downhill(m, FALSE)) { + if (superSlippery || slideLevel || movingBackward || mario_facing_downhill(m, FALSE)) { return TRUE; } }