sm64pc/src/game/behaviors/ttc_pendulum.inc.c

87 lines
2.9 KiB
C

/**
* Behavior for bhvTTCPendulum. This is not the pendulum inside the clock in the
* castle, but rather the one in TTC itself.
*/
/**
* Initial angle acceleration.
*/
static f32 sTTCPendulumInitialAccels[] = {
/* TTC_SPEED_SLOW */ 13.0f,
/* TTC_SPEED_FAST */ 22.0f,
/* TTC_SPEED_RANDOM */ 13.0f,
/* TTC_SPEED_STOPPED */ 0.0f,
};
/**
* Init function for bhvTTCPendulum.
*/
void bhv_ttc_pendulum_init(void) {
if (gTTCSpeedSetting != TTC_SPEED_STOPPED) {
o->oTTCPendulumAngleAccel = sTTCPendulumInitialAccels[gTTCSpeedSetting];
o->oTTCPendulumAngle = 6500.0f;
} else {
o->oTTCPendulumAngle = 6371.5557f;
}
}
/**
* Update function for bhvTTCPendulum.
*/
void bhv_ttc_pendulum_update(void) {
if (gTTCSpeedSetting != TTC_SPEED_STOPPED) {
UNUSED f32 startVel = o->oTTCPendulumAngleVel;
// Play sound
if (o->oTTCPendulumSoundTimer != 0) {
if (--o->oTTCPendulumSoundTimer == 0) {
cur_obj_play_sound_2(SOUND_GENERAL_PENDULUM_SWING);
}
}
// Stay still for a while
if (o->oTTCPendulumDelay != 0) {
o->oTTCPendulumDelay -= 1;
} else {
// Accelerate in the direction that moves angle to zero
if (o->oTTCPendulumAngle * o->oTTCPendulumAccelDir > 0.0f) {
o->oTTCPendulumAccelDir = -o->oTTCPendulumAccelDir;
}
o->oTTCPendulumAngleVel += o->oTTCPendulumAngleAccel * o->oTTCPendulumAccelDir;
// Ignoring floating point imprecision, angle vel should always be
// a multiple of angle accel, and so it will eventually reach zero
//! If the pendulum is moving fast enough, the vel could fail to
// be a multiple of angle accel, and so the pendulum would continue
// oscillating forever
if (o->oTTCPendulumAngleVel == 0.0f) {
if (gTTCSpeedSetting == TTC_SPEED_RANDOM) {
// Select a new acceleration
//! By manipulating this, we can cause the pendulum to reach
// extreme angles and speeds
if (random_u16() % 3 != 0) {
o->oTTCPendulumAngleAccel = 13.0f;
} else {
o->oTTCPendulumAngleAccel = 42.0f;
}
// Pick a random delay
if (random_u16() % 2 == 0) {
o->oTTCPendulumDelay = random_linear_offset(5, 30);
}
}
// Play the sound 15 frames after beginning to move
o->oTTCPendulumSoundTimer = o->oTTCPendulumDelay + 15;
}
o->oTTCPendulumAngle += o->oTTCPendulumAngleVel;
}
} else {
}
o->oFaceAngleRoll = (s32) o->oTTCPendulumAngle;
// Note: no platform displacement
}