fix(rules): retain active target rotation across drains
The original timer advances DAT600 target rotation only from active_ball_tick. A normal ball end does not clear its phase, so a pending rotation pauses while the next ball waits in the launcher and resumes after launch. Rust advanced the phase during launcher idle and then discarded it on drain. Gate rotation updates with the active-ball state and stop clearing rotation, panel, or claw mechanism state in the normal drain path where the binary leaves them untouched. Seed the deterministic target scenario with an active ball so it continues to exercise all six recovered phases. Test Plan: - `cargo test --workspace --all-targets --all-features` -- 118 passed - `cargo clippy --workspace --all-targets --all-features -- -D warnings` -- passed - `rumdl check --flavor commonmark RECONSTRUCTION.md CHANGELOG.md` -- passed - `git diff --cached --check` -- passed
This commit is contained in:
+20
-4
@@ -525,8 +525,8 @@ impl Game {
|
||||
self.update_claw(elapsed, events);
|
||||
if !self.ball.in_launcher {
|
||||
self.update_record_countdowns();
|
||||
self.update_target_rotation(events);
|
||||
}
|
||||
self.update_target_rotation(events);
|
||||
let panel_active = self.update_panel_completion(events);
|
||||
if !self.claw.ball_suspended && !panel_active {
|
||||
let had_secondary_ball = self.secondary_ball.is_some();
|
||||
@@ -2075,9 +2075,6 @@ impl Game {
|
||||
}
|
||||
self.tilted = false;
|
||||
self.tilt_counter = 0;
|
||||
self.target_rotation_state = None;
|
||||
self.panel_frame = None;
|
||||
self.claw = Claw::default();
|
||||
self.flipper_inputs = Flippers::default();
|
||||
self.flippers = Flippers::default();
|
||||
self.pending_flipper_edges.fill(0);
|
||||
@@ -4084,6 +4081,7 @@ mod tests {
|
||||
#[test]
|
||||
fn target_rotation_uses_six_callbacks_and_rotates_player_state() {
|
||||
let mut game = Game::new(1);
|
||||
game.ball.in_launcher = false;
|
||||
game.wheel_holes = [true, false, true, false, false];
|
||||
game.record_contacts[129..=133].copy_from_slice(&[11, 22, 33, 44, 55]);
|
||||
game.target_rotation_state = Some(0);
|
||||
@@ -4101,6 +4099,24 @@ mod tests {
|
||||
assert_eq!(game.target_rotation_state, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_rotation_pauses_in_launcher_and_survives_normal_drain() {
|
||||
let mut game = Game::new(1);
|
||||
game.target_rotation_state = Some(2);
|
||||
|
||||
game.timer_tick(0.030, 0, &mut Vec::new());
|
||||
assert_eq!(game.target_rotation_state, Some(2));
|
||||
|
||||
game.ball.in_launcher = false;
|
||||
game.timer_tick(0.030, 0, &mut Vec::new());
|
||||
assert_eq!(game.target_rotation_state, Some(3));
|
||||
|
||||
game.drain(&mut Vec::new());
|
||||
assert_eq!(game.target_rotation_state, Some(3));
|
||||
game.timer_tick(0.030, 0, &mut Vec::new());
|
||||
assert_eq!(game.target_rotation_state, Some(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn record_countdowns_advance_once_per_active_timer_callback() {
|
||||
let mut game = Game::new(1);
|
||||
|
||||
Reference in New Issue
Block a user