Multiple options for turn radius fix

This commit is contained in:
Arceveti
2021-09-25 22:10:28 -07:00
parent 3d6725bfa1
commit 159e137c84
2 changed files with 34 additions and 12 deletions

View File

@@ -63,7 +63,12 @@
// Makes Mario face the direction of the analog stick directly while hanging from a ceiling, without doing "semicircles"
#define TIGHTER_HANGING_CONTROLS
// Fixes Mario's turn radius by making it dependent on forward speed.
//#define FIX_GROUND_TURN_RADIUS
// Modes:
// 0 is vanilla behavior.
// 1 is similar to vanilla, but prevents Mario from moving in the wrong direction, and allows finer control with the analog stick.
// 2 is similar to mode 1, but a bit further from vanilla, and allows instant turnaround if Mario is moving slower than a certain threshold.
// 3 is instant turning to the intended direction regardless of speed and angle.
#define GROUND_TURN_MODE 0
// Disables fall damage
#define NO_FALL_DAMAGE
// Disables the scream that mario makes when falling off a great height (this is separate from actual fall damage)

View File

@@ -435,13 +435,12 @@ s32 update_decelerating_speed(struct MarioState *m) {
}
s32 analog_stick_held_back(struct MarioState *m) {
s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
return intendedDYaw < -0x471C || intendedDYaw > 0x471C;
s16 intendedDYaw = (m->intendedYaw - m->faceAngle[1]);
return ((intendedDYaw < -0x471C) || (intendedDYaw > 0x471C));
}
void update_walking_speed(struct MarioState *m) {
f32 maxTargetSpeed;
f32 targetSpeed;
if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
maxTargetSpeed = 24.0f;
@@ -449,7 +448,7 @@ void update_walking_speed(struct MarioState *m) {
maxTargetSpeed = 32.0f;
}
targetSpeed = m->intendedMag < maxTargetSpeed ? m->intendedMag : maxTargetSpeed;
f32 targetSpeed = m->intendedMag < maxTargetSpeed ? m->intendedMag : maxTargetSpeed;
if (m->quicksandDepth > 10.0f) {
targetSpeed *= 6.25 / m->quicksandDepth;
@@ -467,28 +466,46 @@ void update_walking_speed(struct MarioState *m) {
m->forwardVel = 48.0f;
}
#ifdef FIX_GROUND_TURN_RADIUS
#if GROUND_TURN_MODE == 0 // Vanilla behavior.
m->faceAngle[1] = approach_angle(m->faceAngle[1], m->intendedYaw, 0x800);
#elif GROUND_TURN_MODE == 1 // Similar to vanilla, but prevents Mario from moving in the wrong direction when turning around, and allows finer control with the analog stick.
s16 turnRange = 0x800;
s16 dYaw = abs_angle_diff(m->faceAngle[1], m->intendedYaw); // 0x0 is turning forwards, 0x8000 is turning backwards
if (m->forwardVel < 0.0f) { // Don't modify Mario's speed and turn radius if Mario is moving backwards
// Flip controls when moving backwards so Mario still moves towards intendedYaw
m->intendedYaw += 0x8000;
} else if (dYaw > 0x4000) { // Only modify Mario's speed and turn radius if Mario is turning around
// Reduce Mario's forward speed by the turn amount, so Mario won't move off sideward from the intended angle when turning around.
m->forwardVel *= ((coss(dYaw) + 1.0f) / 2.0f); // 1.0f is turning forwards, 0.0f is turning backwards
// Increase turn speed if forwardVel is lower and intendedMag is higher
turnRange *= (2.0f - (ABSF(m->forwardVel) / MAX(m->intendedMag, __FLT_EPSILON__))); // 1.0f front, 2.0f back
}
m->faceAngle[1] = approach_angle(m->faceAngle[1], m->intendedYaw, turnRange);
#elif GROUND_TURN_MODE == 2 // similar to mode 1, but a bit further from vanilla, and allows instant turnaround if Mario is moving slower than a certain threshold.
if ((m->forwardVel < 0.0f) && (m->heldObj == NULL) && !(m->action & ACT_FLAG_SHORT_HITBOX)) {
// Flip Mario if he is moving backwards
m->faceAngle[1] += 0x8000;
m->forwardVel *= -1.0f;
}
if (analog_stick_held_back(m) && (m->heldObj == NULL) && !(m->action & ACT_FLAG_SHORT_HITBOX)) {
// Turn around instantly
set_mario_action(m, ACT_TURNING_AROUND, 0);
if (m->forwardVel < 10.0f) {
m->faceAngle[1] = m->intendedYaw;
}
} else {
s16 turnRange = (0xFFF - (m->forwardVel * 0x20));
// Scale the turn radius by forwardVel
s16 turnRange = (0x1000 - (m->forwardVel * 0x20));
if (turnRange < 0x800) {
turnRange = 0x800;
turnRange = 0x800; // Clamp the minimum radius (vanilla radius, 0x800)
set_mario_action(m, ACT_TURNING_AROUND, 0);
} else if (turnRange > 0xFFF) {
turnRange = 0xFFF;
} else if (turnRange > 0x1000) {
turnRange = 0x1000; // Clamp the maximum radius (0x1000)
}
m->faceAngle[1] = approach_angle(m->faceAngle[1], m->intendedYaw, turnRange);
}
#else
m->faceAngle[1] = approach_angle(m->faceAngle[1], m->intendedYaw, 0x800);
#elif GROUND_TURN_MODE == 3 // Instant turn.
m->faceAngle[1] = m->intendedYaw;
#endif
apply_slope_accel(m);
}