Adjust wall normal when colliding with multiple walls
This commit is contained in:
parent
bd7974a544
commit
3e46cc1161
|
@ -387,6 +387,7 @@ struct MarioState
|
|||
/*????*/ f32 curAnimOffset;
|
||||
/*????*/ u8 knockbackTimer;
|
||||
/*????*/ u8 specialTripleJump;
|
||||
/*????*/ Vec3f wallNormal;
|
||||
};
|
||||
|
||||
struct TextureInfo
|
||||
|
|
|
@ -2264,4 +2264,26 @@ void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear) {
|
|||
} else {
|
||||
m->particleFlags |= flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mario_update_wall(struct MarioState* m, struct WallCollisionData* wcd) {
|
||||
if (!m || !wcd) { return; }
|
||||
|
||||
m->wall = (wcd->numWalls > 0)
|
||||
? wcd->walls[wcd->numWalls - 1]
|
||||
: NULL;
|
||||
|
||||
vec3f_set(m->wallNormal, 0, 0, 0);
|
||||
for (u8 i = 0; i < wcd->numWalls; i++) {
|
||||
if (!gServerSettings.fixCollisionBugs) {
|
||||
i = (wcd->numWalls - 1);
|
||||
}
|
||||
struct Surface* wall = wcd->walls[i];
|
||||
Vec3f normal = { wall->normal.x, wall->normal.y, wall->normal.z };
|
||||
vec3f_add(m->wallNormal, normal);
|
||||
}
|
||||
|
||||
if (m->wall) {
|
||||
vec3f_normalize(m->wallNormal);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,5 +60,6 @@ void init_single_mario(struct MarioState* m);
|
|||
void init_mario(void);
|
||||
void init_mario_from_save_file(void);
|
||||
void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear);
|
||||
void mario_update_wall(struct MarioState* m, struct WallCollisionData* wcd);
|
||||
|
||||
#endif // MARIO_H
|
||||
|
|
|
@ -52,7 +52,7 @@ void play_knockback_sound(struct MarioState *m) {
|
|||
#endif
|
||||
|
||||
s32 lava_boost_on_wall(struct MarioState *m) {
|
||||
m->faceAngle[1] = atan2s(m->wall->normal.z, m->wall->normal.x);
|
||||
m->faceAngle[1] = atan2s(m->wallNormal[2], m->wallNormal[0]);
|
||||
|
||||
if (m->forwardVel < 24.0f) {
|
||||
m->forwardVel = 24.0f;
|
||||
|
|
|
@ -695,7 +695,7 @@ void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
|
|||
}
|
||||
|
||||
if (m->wall != NULL) {
|
||||
wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
|
||||
wallAngle = atan2s(m->wallNormal[2], m->wallNormal[0]);
|
||||
dWallAngle = wallAngle - m->faceAngle[1];
|
||||
}
|
||||
|
||||
|
@ -1407,7 +1407,7 @@ void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32
|
|||
#endif
|
||||
slide_bonk(m, ACT_GROUND_BONK, endAction);
|
||||
} else if (m->wall != NULL) {
|
||||
s16 wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
|
||||
s16 wallAngle = atan2s(m->wallNormal[2], m->wallNormal[0]);
|
||||
f32 slideSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
|
||||
|
||||
if ((slideSpeed *= 0.9) < 4.0f) {
|
||||
|
|
|
@ -90,7 +90,7 @@ BAD_RETURN(s32) init_bully_collision_data(struct BullyCollisionData *data, f32 p
|
|||
|
||||
void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) {
|
||||
if (m->wall != NULL) {
|
||||
s16 wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
|
||||
s16 wallAngle = atan2s(m->wallNormal[2], m->wallNormal[0]);
|
||||
m->faceAngle[1] = wallAngle - (s16)(m->faceAngle[1] - wallAngle);
|
||||
|
||||
play_sound((m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_BONK : SOUND_ACTION_BONK,
|
||||
|
@ -274,9 +274,7 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) {
|
|||
|
||||
waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||
|
||||
m->wall = (upperWcd.numWalls > 0)
|
||||
? upperWcd.walls[upperWcd.numWalls - 1]
|
||||
: NULL;
|
||||
mario_update_wall(m, &upperWcd);
|
||||
|
||||
if (floor == NULL) {
|
||||
return GROUND_STEP_HIT_WALL_STOP_QSTEPS;
|
||||
|
@ -501,41 +499,45 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr
|
|||
m->floorHeight = floorHeight;
|
||||
|
||||
if (upperWcd.numWalls > 0) {
|
||||
mario_update_wall(m, &upperWcd);
|
||||
|
||||
for (u8 i = 0; i < upperWcd.numWalls; i++) {
|
||||
if (!gServerSettings.fixCollisionBugs) {
|
||||
i = (upperWcd.numWalls - 1);
|
||||
}
|
||||
|
||||
struct Surface* wall = upperWcd.walls[i];
|
||||
m->wall = wall;
|
||||
wallDYaw = atan2s(wall->normal.z, wall->normal.x) - m->faceAngle[1];
|
||||
|
||||
wallDYaw = atan2s(m->wall->normal.z, m->wall->normal.x) - m->faceAngle[1];
|
||||
|
||||
if (m->wall->type == SURFACE_BURNING) {
|
||||
if (wall->type == SURFACE_BURNING) {
|
||||
m->wall = wall;
|
||||
return AIR_STEP_HIT_LAVA_WALL;
|
||||
}
|
||||
|
||||
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
||||
m->wall = wall;
|
||||
m->flags |= MARIO_UNKNOWN_30;
|
||||
return AIR_STEP_HIT_WALL;
|
||||
}
|
||||
}
|
||||
} else if (lowerWcd.numWalls > 0) {
|
||||
mario_update_wall(m, &lowerWcd);
|
||||
|
||||
for (u8 i = 0; i < lowerWcd.numWalls; i++) {
|
||||
if (!gServerSettings.fixCollisionBugs) {
|
||||
i = (lowerWcd.numWalls - 1);
|
||||
}
|
||||
|
||||
struct Surface* wall = lowerWcd.walls[i];
|
||||
m->wall = wall;
|
||||
wallDYaw = atan2s(wall->normal.z, wall->normal.x) - m->faceAngle[1];
|
||||
|
||||
wallDYaw = atan2s(m->wall->normal.z, m->wall->normal.x) - m->faceAngle[1];
|
||||
|
||||
if (m->wall->type == SURFACE_BURNING) {
|
||||
if (wall->type == SURFACE_BURNING) {
|
||||
m->wall = wall;
|
||||
return AIR_STEP_HIT_LAVA_WALL;
|
||||
}
|
||||
|
||||
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
||||
m->wall = wall;
|
||||
m->flags |= MARIO_UNKNOWN_30;
|
||||
return AIR_STEP_HIT_WALL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue