fix(physics): preserve record layer and kick fields
Carry the recovered +0x49 layer mask through every static line/circle and select the original upper/lower scan layer from the previous Y coordinate. Restore negative auxiliary thresholds and kick coefficients for bumpers and records 55, 74, and 107, including weak-hit scoring, rail sound, and tilt suppression. Test Plan: - cargo test --all-targets - cargo clippy --all-targets --all-features -- -D warnings - rumdl check CHANGELOG.md RECONSTRUCTION.md README.md - git diff --check
This commit is contained in:
@@ -18,9 +18,12 @@ pub struct TableSegment {
|
||||
pub segment: Segment,
|
||||
pub normal_rebound: f32,
|
||||
pub tangent_coupling: f32,
|
||||
pub response_auxiliary: f32,
|
||||
pub response_kick: f32,
|
||||
pub score: u32,
|
||||
pub flags: u16,
|
||||
pub contact_group: u8,
|
||||
pub layer_mask: u8,
|
||||
}
|
||||
|
||||
impl TableSegment {
|
||||
@@ -69,14 +72,22 @@ impl TableSegment {
|
||||
118..=120 => 118,
|
||||
_ => 0,
|
||||
};
|
||||
let (response_auxiliary, response_kick) = match id {
|
||||
55 | 74 => (-0.40, 0.40),
|
||||
107 => (-0.40, 0.30),
|
||||
_ => (0.0, 0.0),
|
||||
};
|
||||
Self {
|
||||
id,
|
||||
segment: Segment::new(start, end, normal_rebound),
|
||||
normal_rebound,
|
||||
tangent_coupling,
|
||||
response_auxiliary,
|
||||
response_kick,
|
||||
score,
|
||||
flags,
|
||||
contact_group,
|
||||
layer_mask: layer_mask_for_record(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,6 +100,7 @@ pub struct StaticCircle {
|
||||
pub normal_rebound: f32,
|
||||
pub tangent_coupling: f32,
|
||||
pub normal_kick: f32,
|
||||
pub layer_mask: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -139,10 +151,19 @@ impl StaticCircle {
|
||||
normal_rebound,
|
||||
tangent_coupling,
|
||||
normal_kick,
|
||||
layer_mask: layer_mask_for_record(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fn layer_mask_for_record(id: u8) -> u8 {
|
||||
match id {
|
||||
11 | 24 | 49 | 84..=120 | 167..=175 => 0x03,
|
||||
1..=10 | 25 | 50 | 54..=83 | 153 | 154 => 0x02,
|
||||
_ => 0x01,
|
||||
}
|
||||
}
|
||||
|
||||
/// Active type-2 objects after later registrations overwrite objects 169 and
|
||||
/// 170. Object 2 is the drain sensor and object 25 is the shooter stop; callers
|
||||
/// apply their special behavior after detecting contact.
|
||||
@@ -347,6 +368,32 @@ mod tests {
|
||||
assert_eq!(BUMPERS.len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recovered_layer_masks_cover_upper_lower_and_shared_records() {
|
||||
assert_eq!(layer_mask_for_record(48), 0x01);
|
||||
assert_eq!(layer_mask_for_record(50), 0x02);
|
||||
assert_eq!(layer_mask_for_record(49), 0x03);
|
||||
assert_eq!(layer_mask_for_record(89), 0x03);
|
||||
assert_eq!(layer_mask_for_record(140), 0x01);
|
||||
assert_eq!(layer_mask_for_record(153), 0x02);
|
||||
assert_eq!(layer_mask_for_record(174), 0x03);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recovered_auxiliary_kick_records_keep_both_coefficients() {
|
||||
for (id, expected_kick) in [(55, 0.40_f32), (74, 0.40), (107, 0.30)] {
|
||||
let wall = WALLS
|
||||
.iter()
|
||||
.find(|wall| wall.id == id)
|
||||
.expect("the kicked line record must be present");
|
||||
assert_eq!(wall.response_auxiliary.to_bits(), (-0.40_f32).to_bits());
|
||||
assert_eq!(wall.response_kick.to_bits(), expected_kick.to_bits());
|
||||
}
|
||||
for bumper in BUMPERS {
|
||||
assert_eq!(bumper.normal_kick.to_bits(), 0.40_f32.to_bits());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recovered_landmarks_match_the_visible_table() {
|
||||
let left_flipper_post = PASSIVE_CIRCLES
|
||||
|
||||
Reference in New Issue
Block a user