fix(scoring): preserve bumper sound precedence
Bumper flags are dispatched before the variable bumper award in the original collision response. Rust duplicated the primary- and secondary-ball rule path and appended WAVE 2006 after score mutation, which hid WAVE 2007 whenever that award crossed a media/extra-ball threshold. Share one bumper-rule helper for both ball slots, arm the five-callback visual countdown, dispatch WAVE 2006, and only then add the weak or kicked bumper score. An exact event-order regression keeps the threshold sound as the final audible sample. Test Plan: - `cargo test --workspace --all-targets --all-features` -- 116 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:
+47
-28
@@ -835,20 +835,8 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(index) = hit_circle
|
||||
.and_then(|circle_id| BUMPERS.iter().position(|bumper| bumper.id == circle_id))
|
||||
&& !self.tilted
|
||||
{
|
||||
let points = self
|
||||
.player()
|
||||
.bumper_value
|
||||
.saturating_sub(if auxiliary_fired { 0 } else { 1_000 });
|
||||
if points != 0 {
|
||||
self.add_score(points, events);
|
||||
}
|
||||
self.record_countdowns[usize::from(BUMPERS[index].id)] = 5;
|
||||
events.push(Event::Bumper);
|
||||
events.push(Event::Sound(2006));
|
||||
if let Some(circle_id) = hit_circle {
|
||||
self.apply_bumper_rule(circle_id, auxiliary_fired, events);
|
||||
}
|
||||
|
||||
match scan.action {
|
||||
@@ -1237,20 +1225,8 @@ impl Game {
|
||||
if auxiliary_fired && matches!(object_id, 55 | 74 | 107) {
|
||||
events.push(Event::Sound(2019));
|
||||
}
|
||||
} else if let Some((object_id, false)) = hit
|
||||
&& let Some(index) = BUMPERS.iter().position(|bumper| bumper.id == object_id)
|
||||
&& !self.tilted
|
||||
{
|
||||
let points = self
|
||||
.player()
|
||||
.bumper_value
|
||||
.saturating_sub(if auxiliary_fired { 0 } else { 1_000 });
|
||||
if points != 0 {
|
||||
self.add_score(points, events);
|
||||
}
|
||||
self.record_countdowns[usize::from(BUMPERS[index].id)] = 5;
|
||||
events.push(Event::Bumper);
|
||||
events.push(Event::Sound(2006));
|
||||
} else if let Some((object_id, false)) = hit {
|
||||
self.apply_bumper_rule(object_id, auxiliary_fired, events);
|
||||
}
|
||||
match scan.action {
|
||||
BallAction::Keep | BallAction::Suspend => self.secondary_ball = Some(ball),
|
||||
@@ -1259,6 +1235,27 @@ impl Game {
|
||||
collided || scan.action == BallAction::Suspend
|
||||
}
|
||||
|
||||
fn apply_bumper_rule(
|
||||
&mut self,
|
||||
object_id: u8,
|
||||
auxiliary_fired: bool,
|
||||
events: &mut Vec<Event>,
|
||||
) {
|
||||
if self.tilted || !BUMPERS.iter().any(|bumper| bumper.id == object_id) {
|
||||
return;
|
||||
}
|
||||
self.record_countdowns[usize::from(object_id)] = 5;
|
||||
events.push(Event::Bumper);
|
||||
events.push(Event::Sound(2006));
|
||||
let points = self
|
||||
.player()
|
||||
.bumper_value
|
||||
.saturating_sub(if auxiliary_fired { 0 } else { 1_000 });
|
||||
if points != 0 {
|
||||
self.add_score(points, events);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_wall_rule(&mut self, object_id: u8, events: &mut Vec<Event>) {
|
||||
if self.tilted {
|
||||
return;
|
||||
@@ -2692,6 +2689,28 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bumper_sound_precedes_a_crossed_media_marker() {
|
||||
let mut game = Game::new(1);
|
||||
game.players[0].score = 139_000;
|
||||
let mut events = Vec::new();
|
||||
|
||||
game.apply_bumper_rule(51, true, &mut events);
|
||||
|
||||
assert_eq!(game.record_countdown(51), 5);
|
||||
assert_eq!(game.player().score, 140_000);
|
||||
assert_eq!(
|
||||
events,
|
||||
[
|
||||
Event::Bumper,
|
||||
Event::Sound(2006),
|
||||
Event::Media,
|
||||
Event::ExtraBall,
|
||||
Event::Sound(2007),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_reset_arms_effect_seven_multiball() {
|
||||
let mut game = Game::new_with_seed(1, 7);
|
||||
|
||||
Reference in New Issue
Block a user