fix(rules): restore ninth-diamond completion order
The reconstructed collision response dispatches record flags before adding the selected record's static score. Rust previously scored first and delayed the permanent-double transition until a later completed bank, leaving the three magnetic records inactive and producing the wrong ninth-bank total. Apply flag-driven rules first, keep the 24,464 completion award at the old single multiplier, then activate permanent double scoring and records 153, 6, and 154 before the final 1,500-point collision score. Subsequent completed banks now immediately add 100,000 to the per-player secondary score. Update the regression test and reconstruction notes with the observable order. Test Plan: - `cargo test --workspace --all-targets --all-features` -- 114 passed - `cargo clippy --workspace --all-targets --all-features -- -D warnings` -- passed - `bash original/tools/test_reconstructed_c.sh` -- passed - `python3 original/tools/audit_reconstruction.py --require-complete` -- passed - `rumdl check --flavor commonmark RECONSTRUCTION.md CHANGELOG.md` -- passed - `git diff --cached --check` -- passed - `cargo +nightly fmt -- --check` -- reports pre-existing whole-project diffs
This commit is contained in:
+39
-17
@@ -1260,14 +1260,6 @@ impl Game {
|
||||
.iter()
|
||||
.find(|wall| wall.id == object_id)
|
||||
.expect("a wall collision id must reference a recovered wall");
|
||||
if wall.score != 0 {
|
||||
self.add_score(wall.score, events);
|
||||
events.push(if object_id == 121 {
|
||||
Event::Wheel
|
||||
} else {
|
||||
Event::Target
|
||||
});
|
||||
}
|
||||
|
||||
if wall.flags & 0x0002 != 0 {
|
||||
let group = usize::from(wall.contact_group);
|
||||
@@ -1314,6 +1306,12 @@ impl Game {
|
||||
u32::from(segments + 1) * 10_000
|
||||
};
|
||||
self.add_score(award, events);
|
||||
if segments == 8 {
|
||||
self.players[self.current_player].double_score = true;
|
||||
for object_id in [153, 6, 154] {
|
||||
self.object_active[object_id] = true;
|
||||
}
|
||||
}
|
||||
events.push(Event::Sound(2017));
|
||||
} else {
|
||||
let player = &mut self.players[self.current_player];
|
||||
@@ -1353,6 +1351,24 @@ impl Game {
|
||||
}
|
||||
self.object_active[usize::from(EFFECT_SENSOR.id)] = true;
|
||||
}
|
||||
|
||||
// 1000:91eb dispatches b476's flag-driven rules before it adds the
|
||||
// selected record's static score. This is observable when the ninth
|
||||
// diamond enables permanent double scoring: that collision's 1,500
|
||||
// points are already doubled, while the preceding 24,464 award is not.
|
||||
self.apply_static_wall_score(object_id, wall.score, events);
|
||||
}
|
||||
|
||||
fn apply_static_wall_score(&mut self, object_id: u8, score: u32, events: &mut Vec<Event>) {
|
||||
if score == 0 {
|
||||
return;
|
||||
}
|
||||
self.add_score(score, events);
|
||||
events.push(if object_id == 121 {
|
||||
Event::Wheel
|
||||
} else {
|
||||
Event::Target
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -2471,25 +2487,31 @@ mod tests {
|
||||
game.players[0].diamond_segments = 8;
|
||||
let mut events = Vec::new();
|
||||
|
||||
assert!(!game.player().double_score);
|
||||
assert!(!game.magnetic_field_active(153));
|
||||
assert!(!game.magnetic_field_active(6));
|
||||
assert!(!game.magnetic_field_active(154));
|
||||
|
||||
for object_id in [109, 112, 115, 118] {
|
||||
game.apply_wall_rule(object_id, &mut events);
|
||||
}
|
||||
assert_eq!(game.player().diamond_segments, 9);
|
||||
assert_eq!(game.player().score, 4 * 1_500 + 24_464);
|
||||
assert!(!game.player().double_score);
|
||||
|
||||
for object_id in [109, 112, 115, 118] {
|
||||
game.apply_wall_rule(object_id, &mut events);
|
||||
}
|
||||
assert_eq!(game.player().score, 3 * 1_500 + 24_464 + 2 * 1_500);
|
||||
assert!(game.player().double_score);
|
||||
let score = game.player().score;
|
||||
game.add_score(1_000, &mut events);
|
||||
assert_eq!(game.player().score, score + 2_000);
|
||||
assert!(game.magnetic_field_active(153));
|
||||
assert!(game.magnetic_field_active(6));
|
||||
assert!(game.magnetic_field_active(154));
|
||||
|
||||
for object_id in [109, 112, 115, 118] {
|
||||
game.apply_wall_rule(object_id, &mut events);
|
||||
}
|
||||
assert_eq!(game.player().score, 3 * 1_500 + 24_464 + 10 * 1_500);
|
||||
assert_eq!(game.player().secondary_score, 100_000);
|
||||
|
||||
for object_id in [109, 112, 115, 118] {
|
||||
game.apply_wall_rule(object_id, &mut events);
|
||||
}
|
||||
assert_eq!(game.player().secondary_score, 200_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user