fix(multiball): clear record 148 contact on respawn
The required-effect word at 1028:399a is record 148's +0x43 contact field. The original special respawn clears that exact word before suppressing the capture gate. Rust reset only its derived multiball state and left contact 2 behind, allowing a synthetic type-three rim candidate after respawn. Clear record_contacts[148] with the derived state. Extend both armed and active multiball respawn regressions to begin with the binary's contact sentinel and prove that the transition removes it. 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 CHANGELOG.md` -- passed - `git diff --cached --check` -- passed
This commit is contained in:
@@ -19,8 +19,9 @@ and this project adheres to
|
||||
full normal velocity instead of always subtracting 1,000.
|
||||
- Restore `1000:ae6e`'s required-ball special respawn: armed or completed
|
||||
effect-seven play grants one final `(17,23)/(0,3040)` ball without consuming
|
||||
a marker, clears required state, and suppresses record 148 until the next
|
||||
broadphase-active type-4 record reenables it.
|
||||
a marker, clears required state including record 148's contact word, and
|
||||
suppresses record 148 until the next broadphase-active type-4 record
|
||||
reenables it.
|
||||
- Replace the invented post-move `y>470` fallback with the original pre-scan
|
||||
prediction bounds `x<=0 || x>340000 || y<=0 || y>460000`, including
|
||||
one-slot removal during multiball and next-substep handling after a response.
|
||||
|
||||
@@ -2054,6 +2054,7 @@ impl Game {
|
||||
capture_age: 0,
|
||||
};
|
||||
self.multiball_state = MultiballState::Unavailable;
|
||||
self.record_contacts[148] = 0;
|
||||
self.wheel_reset_gate = WheelResetGate::Suppressed;
|
||||
return;
|
||||
}
|
||||
@@ -2747,6 +2748,7 @@ mod tests {
|
||||
let mut game = Game::new_with_seed(1, 7);
|
||||
let mut events = Vec::new();
|
||||
game.multiball_state = MultiballState::Ready;
|
||||
game.record_contacts[148] = 2;
|
||||
game.apply_wall_rule(84, &mut events);
|
||||
assert_eq!(game.target_effect, 7);
|
||||
|
||||
@@ -2789,6 +2791,7 @@ mod tests {
|
||||
MilliVec { x: 0, y: 3_040 }
|
||||
);
|
||||
assert_eq!(game.multiball_state, MultiballState::Unavailable);
|
||||
assert_eq!(game.record_contacts[148], 0);
|
||||
assert_eq!(game.wheel_reset_gate, WheelResetGate::Suppressed);
|
||||
|
||||
game.fixed_update(&mut events);
|
||||
@@ -2847,6 +2850,7 @@ mod tests {
|
||||
fn armed_effect_seven_also_special_respawns_before_multiball_starts() {
|
||||
let mut game = Game::new(1);
|
||||
game.multiball_state = MultiballState::Ready;
|
||||
game.record_contacts[148] = 2;
|
||||
let balls = game.player().balls;
|
||||
let mut events = Vec::new();
|
||||
|
||||
@@ -2856,6 +2860,7 @@ mod tests {
|
||||
assert_eq!(game.player().balls, balls);
|
||||
assert_eq!(game.ball.position, vec2(17.0, 23.0));
|
||||
assert_eq!(game.multiball_state, MultiballState::Unavailable);
|
||||
assert_eq!(game.record_contacts[148], 0);
|
||||
assert_eq!(game.wheel_reset_gate, WheelResetGate::Suppressed);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user