mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 12:05:11 +00:00
Adjust wall normal when colliding with multiple walls
This commit is contained in:
parent
bd7974a544
commit
3e46cc1161
6 changed files with 42 additions and 16 deletions
|
@ -387,6 +387,7 @@ struct MarioState
|
||||||
/*????*/ f32 curAnimOffset;
|
/*????*/ f32 curAnimOffset;
|
||||||
/*????*/ u8 knockbackTimer;
|
/*????*/ u8 knockbackTimer;
|
||||||
/*????*/ u8 specialTripleJump;
|
/*????*/ u8 specialTripleJump;
|
||||||
|
/*????*/ Vec3f wallNormal;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureInfo
|
struct TextureInfo
|
||||||
|
|
|
@ -2264,4 +2264,26 @@ void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear) {
|
||||||
} else {
|
} else {
|
||||||
m->particleFlags |= flags;
|
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(void);
|
||||||
void init_mario_from_save_file(void);
|
void init_mario_from_save_file(void);
|
||||||
void set_mario_particle_flags(struct MarioState* m, u32 flags, u8 clear);
|
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
|
#endif // MARIO_H
|
||||||
|
|
|
@ -52,7 +52,7 @@ void play_knockback_sound(struct MarioState *m) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s32 lava_boost_on_wall(struct MarioState *m) {
|
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) {
|
if (m->forwardVel < 24.0f) {
|
||||||
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) {
|
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];
|
dWallAngle = wallAngle - m->faceAngle[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,7 +1407,7 @@ void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32
|
||||||
#endif
|
#endif
|
||||||
slide_bonk(m, ACT_GROUND_BONK, endAction);
|
slide_bonk(m, ACT_GROUND_BONK, endAction);
|
||||||
} else if (m->wall != NULL) {
|
} 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);
|
f32 slideSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
|
||||||
|
|
||||||
if ((slideSpeed *= 0.9) < 4.0f) {
|
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) {
|
void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) {
|
||||||
if (m->wall != NULL) {
|
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);
|
m->faceAngle[1] = wallAngle - (s16)(m->faceAngle[1] - wallAngle);
|
||||||
|
|
||||||
play_sound((m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_BONK : SOUND_ACTION_BONK,
|
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]);
|
waterLevel = find_water_level(nextPos[0], nextPos[2]);
|
||||||
|
|
||||||
m->wall = (upperWcd.numWalls > 0)
|
mario_update_wall(m, &upperWcd);
|
||||||
? upperWcd.walls[upperWcd.numWalls - 1]
|
|
||||||
: NULL;
|
|
||||||
|
|
||||||
if (floor == NULL) {
|
if (floor == NULL) {
|
||||||
return GROUND_STEP_HIT_WALL_STOP_QSTEPS;
|
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;
|
m->floorHeight = floorHeight;
|
||||||
|
|
||||||
if (upperWcd.numWalls > 0) {
|
if (upperWcd.numWalls > 0) {
|
||||||
|
mario_update_wall(m, &upperWcd);
|
||||||
|
|
||||||
for (u8 i = 0; i < upperWcd.numWalls; i++) {
|
for (u8 i = 0; i < upperWcd.numWalls; i++) {
|
||||||
if (!gServerSettings.fixCollisionBugs) {
|
if (!gServerSettings.fixCollisionBugs) {
|
||||||
i = (upperWcd.numWalls - 1);
|
i = (upperWcd.numWalls - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Surface* wall = upperWcd.walls[i];
|
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 (wall->type == SURFACE_BURNING) {
|
||||||
|
m->wall = wall;
|
||||||
if (m->wall->type == SURFACE_BURNING) {
|
|
||||||
return AIR_STEP_HIT_LAVA_WALL;
|
return AIR_STEP_HIT_LAVA_WALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
||||||
|
m->wall = wall;
|
||||||
m->flags |= MARIO_UNKNOWN_30;
|
m->flags |= MARIO_UNKNOWN_30;
|
||||||
return AIR_STEP_HIT_WALL;
|
return AIR_STEP_HIT_WALL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (lowerWcd.numWalls > 0) {
|
} else if (lowerWcd.numWalls > 0) {
|
||||||
|
mario_update_wall(m, &lowerWcd);
|
||||||
|
|
||||||
for (u8 i = 0; i < lowerWcd.numWalls; i++) {
|
for (u8 i = 0; i < lowerWcd.numWalls; i++) {
|
||||||
if (!gServerSettings.fixCollisionBugs) {
|
if (!gServerSettings.fixCollisionBugs) {
|
||||||
i = (lowerWcd.numWalls - 1);
|
i = (lowerWcd.numWalls - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Surface* wall = lowerWcd.walls[i];
|
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 (wall->type == SURFACE_BURNING) {
|
||||||
|
m->wall = wall;
|
||||||
if (m->wall->type == SURFACE_BURNING) {
|
|
||||||
return AIR_STEP_HIT_LAVA_WALL;
|
return AIR_STEP_HIT_LAVA_WALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
if (wallDYaw < -0x6000 || wallDYaw > 0x6000) {
|
||||||
|
m->wall = wall;
|
||||||
m->flags |= MARIO_UNKNOWN_30;
|
m->flags |= MARIO_UNKNOWN_30;
|
||||||
return AIR_STEP_HIT_WALL;
|
return AIR_STEP_HIT_WALL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue