Properly determine the correct wall between multiple, turn off rounded corners in the air

This commit is contained in:
MysterD 2023-06-22 20:00:43 -07:00
parent 2ad4cfceaa
commit 3fa5823578
5 changed files with 32 additions and 6 deletions

View file

@ -26,7 +26,6 @@ gBehaviorValues.dialogs.KoopaQuickBobWinDialog = DIALOG_031
gBehaviorValues.dialogs.KoopaQuickThiWinDialog = DIALOG_031
gLevelValues.fixCollisionBugs = 1
gLevelValues.fixCollisionBugsRoundedCorners = 0
--------------
-- movtexs --

View file

@ -15,6 +15,7 @@
Vec3f gFindWallDirection = { 0 };
u8 gFindWallDirectionActive = false;
u8 gFindWallDirectionAirborne = false;
#define CLAMP(_val, _min, _max) MAX(MIN((_val), _max), _min)
@ -134,7 +135,7 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
continue;
}
if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners) {
if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners && !gFindWallDirectionAirborne) {
// Check AABB to exclude walls before doing expensive triangle check
f32 minX = MIN(MIN(surf->vertex1[0], surf->vertex2[0]), surf->vertex3[0]) - radius;
f32 minZ = MIN(MIN(surf->vertex1[2], surf->vertex2[2]), surf->vertex3[2]) - radius;
@ -277,7 +278,7 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode,
//! (Wall Overlaps) Because this doesn't update the x and z local variables,
// multiple walls can push mario more than is required.
// <Fixed when gLevelValues.fixCollisionBugs != 0>
if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners) {
if (gLevelValues.fixCollisionBugs && gLevelValues.fixCollisionBugsRoundedCorners && !gFindWallDirectionAirborne) {
data->x = cPos[0] + cNorm[0] * radius;
data->z = cPos[2] + cNorm[2] * radius;
x = data->x;

View file

@ -40,6 +40,7 @@ struct FloorGeometry
extern Vec3f gFindWallDirection;
extern u8 gFindWallDirectionActive;
extern u8 gFindWallDirectionAirborne;
s32 f32_find_wall_collision(f32 *xPtr, f32 *yPtr, f32 *zPtr, f32 offsetY, f32 radius);
s32 find_wall_collisions(struct WallCollisionData *colData);

View file

@ -2385,9 +2385,32 @@ void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear) {
void mario_update_wall(struct MarioState* m, struct WallCollisionData* wcd) {
if (!m || !wcd) { return; }
if (gLevelValues.fixCollisionBugs) {
// turn face angle into a direction vector
Vec3f faceAngle;
faceAngle[0] = coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
faceAngle[1] = sins(m->faceAngle[0]);
faceAngle[2] = coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
vec3f_normalize(faceAngle);
// reset wall
m->wall = NULL;
for (int i = 0; i < wcd->numWalls; i++) {
if (m->wall == NULL) {
m->wall = wcd->walls[i];
continue;
}
// find the wall that is most "facing away"
if (vec3f_dist((f32*)&m->wall->normal.x, (f32*)faceAngle) < vec3f_dist((f32*)&wcd->walls[i]->normal.x, (f32*)faceAngle)) {
m->wall = wcd->walls[i];
}
}
} else {
m->wall = (wcd->numWalls > 0)
? wcd->walls[wcd->numWalls - 1]
: NULL;
}
if (gLevelValues.fixCollisionBugs && wcd->normalCount > 0) {
vec3f_set(m->wallNormal,

View file

@ -741,7 +741,9 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) {
vec3f_copy(gFindWallDirection, step);
gFindWallDirectionActive = true;
gFindWallDirectionAirborne = true;
quarterStepResult = perform_air_quarter_step(m, intendedPos, stepArg);
gFindWallDirectionAirborne = false;
gFindWallDirectionActive = false;
//! On one qf, hit OOB/ceil/wall to store the 2 return value, and continue