Added water surface type patch

This commit is contained in:
thecozies
2021-03-03 08:05:11 -06:00
parent 545eb58102
commit 571bae013e
11 changed files with 230 additions and 22 deletions

View File

@@ -1167,6 +1167,24 @@ s32 transition_submerged_to_walking(struct MarioState *m) {
}
}
/**
* Transitions Mario from a submerged action to an airborne action.
* You may want to change these actions to fit your hack
*/
s32 transition_submerged_to_airborne(struct MarioState *m) {
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
vec3s_set(m->angleVel, 0, 0, 0);
if (m->heldObj == NULL) {
if (m->input & INPUT_A_DOWN) return set_mario_action(m, ACT_DIVE, 0);
else return set_mario_action(m, ACT_FREEFALL, 0);
} else {
if (m->input & INPUT_A_DOWN) return set_mario_action(m, ACT_HOLD_JUMP, 0);
else return set_mario_action(m, ACT_HOLD_FREEFALL, 0);
}
}
/**
* This is the transition function typically for entering a submerged action for a
* non-submerged action. This also applies the water surface camera preset.
@@ -1175,7 +1193,8 @@ s32 set_water_plunge_action(struct MarioState *m) {
m->forwardVel = m->forwardVel / 4.0f;
m->vel[1] = m->vel[1] / 2.0f;
m->pos[1] = m->waterLevel - 100;
// !BUG: Causes waterbox upwarp
// m->pos[1] = m->waterLevel - 100;
m->faceAngle[2] = 0;

View File

@@ -46,6 +46,7 @@ s32 hurt_and_set_mario_action(struct MarioState *m, u32 action, u32 actionArg, s
s32 check_common_action_exits(struct MarioState *m);
s32 check_common_hold_action_exits(struct MarioState *m);
s32 transition_submerged_to_walking(struct MarioState *m);
s32 transition_submerged_to_airborne(struct MarioState *m);
s32 set_water_plunge_action(struct MarioState *m);
s32 execute_mario_action(UNUSED struct Object *o);
void init_mario(void);

View File

@@ -1497,7 +1497,8 @@ static s32 act_hold_metal_water_fall_land(struct MarioState *m) {
static s32 check_common_submerged_cancels(struct MarioState *m) {
if (m->pos[1] > m->waterLevel - 80) {
if (m->waterLevel - 80 > m->floorHeight) {
m->pos[1] = m->waterLevel - 80;
// m->pos[1] = m->waterLevel - 80; //! BUG: Downwarp swimming out of waterfalls
return transition_submerged_to_airborne(m);
} else {
//! If you press B to throw the shell, there is a ~5 frame window
// where your held object is the shell, but you are not in the

View File

@@ -696,7 +696,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
gMatStackFixed[gMatStackIndex] = mtx;
if (gShadowAboveWaterOrLava == TRUE) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 4);
} else if (gMarioOnIceOrCarpet == 1) {
} else if (gMarioOnIceOrCarpet == 1 || gShadowAboveCustomWater == 1) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 5);
} else {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 6);

View File

@@ -102,6 +102,7 @@ shadowRectangle rectangles[2] = {
// See shadow.h for documentation.
s8 gShadowAboveWaterOrLava;
s8 gShadowAboveCustomWater;
s8 gMarioOnIceOrCarpet;
s8 sMarioOnFlyingCarpet;
s16 sSurfaceTypeBelowShadow;
@@ -177,14 +178,15 @@ u8 dim_shadow_with_distance(u8 solidity, f32 distFromFloor) {
* Return the water level below a shadow, or 0 if the water level is below
* -10,000.
*/
f32 get_water_level_below_shadow(struct Shadow *s) {
f32 waterLevel = find_water_level(s->parentX, s->parentZ);
f32 get_water_level_below_shadow(struct Shadow *s, struct Surface **waterFloor) {
f32 waterLevel = find_water_level_and_floor(s->parentX, s->parentZ, waterFloor);
if (waterLevel < FLOOR_LOWER_LIMIT_SHADOW) {
return 0;
} else if (s->parentY >= waterLevel && s->floorHeight <= waterLevel) {
gShadowAboveWaterOrLava = TRUE;
return waterLevel;
}
return waterLevel;
//! @bug Missing return statement. This compiles to return `waterLevel`
//! incidentally.
}
@@ -201,6 +203,7 @@ s8 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
f32 waterLevel;
f32 floorSteepness;
struct FloorGeometry *floorGeometry;
struct Surface *waterFloor = NULL;
s->parentX = xPos;
s->parentY = yPos;
@@ -208,18 +211,33 @@ s8 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
s->floorHeight = find_floor_height_and_data(s->parentX, s->parentY, s->parentZ, &floorGeometry);
if (gEnvironmentRegions != 0) {
waterLevel = get_water_level_below_shadow(s);
}
waterLevel = get_water_level_below_shadow(s, &waterFloor);
// if (gEnvironmentRegions != 0) {
// waterLevel = get_water_level_below_shadow(s);
// }
if (gShadowAboveWaterOrLava) {
//! @bug Use of potentially undefined variable `waterLevel`
s->floorHeight = waterLevel;
// Assume that the water is flat.
s->floorNormalX = 0;
s->floorNormalY = 1.0;
s->floorNormalZ = 0;
s->floorOriginOffset = -waterLevel;
if (waterFloor != NULL) {
s->floorNormalX = waterFloor->normal.x;
s->floorNormalY = waterFloor->normal.y;
s->floorNormalZ = waterFloor->normal.z;
s->floorOriginOffset = waterFloor->originOffset;
gShadowAboveWaterOrLava = FALSE;
gShadowAboveCustomWater = TRUE;
s->solidity = 200;
} else {
gShadowAboveCustomWater = FALSE;
// Assume that the water is flat.
s->floorNormalX = 0;
s->floorNormalY = 1.0;
s->floorNormalZ = 0;
s->floorOriginOffset = -waterLevel;
}
} else {
// Don't draw a shadow if the floor is lower than expected possible,
// or if the y-normal is negative (an unexpected result).
@@ -853,6 +871,7 @@ Gfx *create_shadow_below_xyz(f32 xPos, f32 yPos, f32 zPos, s16 shadowScale, u8 s
find_floor(xPos, yPos, zPos, &pfloor);
gShadowAboveWaterOrLava = FALSE;
gShadowAboveCustomWater = FALSE;
gMarioOnIceOrCarpet = 0;
sMarioOnFlyingCarpet = 0;
if (pfloor != NULL) {

View File

@@ -38,6 +38,7 @@ extern s16 sSurfaceTypeBelowShadow;
* Flag for if the current shadow is above water or lava.
*/
extern s8 gShadowAboveWaterOrLava;
extern s8 gShadowAboveCustomWater;
/**
* Flag for if Mario is on ice or a flying carpet.