diff --git a/crates/gc-formats/src/occlusion.rs b/crates/gc-formats/src/occlusion.rs index 8074370..d176999 100644 --- a/crates/gc-formats/src/occlusion.rs +++ b/crates/gc-formats/src/occlusion.rs @@ -68,11 +68,15 @@ impl Occlusion { /// Is an object with these occlusion bits visible from this mask? /// - /// The bits are `byte << 8 | 1 << bit`, folded at level load. The test is - /// the game's: `mask[byte] & bit == 0` means skip. + /// The bits are `byte << 8 | 1 << bit`, folded at level load: the high + /// byte selects the mask byte and the low byte is *already* the shifted + /// bit, not an index. Shifting the low byte again is both wrong and a + /// panic, since any byte above 8 overflows a `u8` shift. + /// + /// The test is the game's: `mask[byte] & bit == 0` means skip. pub fn visible(&self, mask_index: u16, bits: u16) -> bool { let byte = (bits >> 8) as usize; - let bit = 1u8 << (bits & 0xff); + let bit = (bits & 0xff) as u8; self.masks .get(mask_index as usize) .is_some_and(|m| byte < MASK_BYTES && m[byte] & bit != 0)