1515use std:: collections:: HashSet ;
1616use std:: sync:: { Arc , RwLock } ;
1717
18- use crate :: engine:: DEFAULT_ENGINE ;
18+ use crate :: engine:: { canonical_edge , DEFAULT_ENGINE } ;
1919use crate :: map_grid:: UnionFind ;
2020
2121/// Unified interface for collision detection backends. Kept as a trait so
@@ -153,10 +153,13 @@ pub struct HybridCollisionMap {
153153 map_size : usize ,
154154 /// Canonical `(lo, hi)` cell-index pairs where the broad-phase walk is
155155 /// allowed to step between two cells that the union-find considers to be
156- /// in different rooms. Populated by the engine from its `door_edges`
157- /// overlay — a door dissolves the wall only along its own cell-edges, not
158- /// across the entire room boundary (which is what a UF union would do).
159- door_cell_edges : HashSet < ( usize , usize ) > ,
156+ /// in different rooms. Populated by the engine from its edge overrides —
157+ /// a door dissolves the wall only along its own cell-edges, not across
158+ /// the entire room boundary (which is what a UF union would do).
159+ pass_cell_edges : HashSet < ( usize , usize ) > ,
160+ /// Inverse of `pass_cell_edges`: cell-pairs the walk may NOT step across
161+ /// even within one room (a closed door sealing a same-room edge).
162+ block_cell_edges : HashSet < ( usize , usize ) > ,
160163}
161164
162165impl HybridCollisionMap {
@@ -166,7 +169,8 @@ impl HybridCollisionMap {
166169 union_find : Arc :: new ( RwLock :: new ( uf) ) ,
167170 pixel_map : PixelCollisionMap :: new ( map_size as u16 , map_size as u16 ) ,
168171 map_size,
169- door_cell_edges : HashSet :: new ( ) ,
172+ pass_cell_edges : HashSet :: new ( ) ,
173+ block_cell_edges : HashSet :: new ( ) ,
170174 }
171175 }
172176
@@ -181,11 +185,16 @@ impl HybridCollisionMap {
181185 & mut self . pixel_map
182186 }
183187
184- /// Replace the set of open door cell-edges. Each entry is a canonical
185- /// `(lo, hi)` cell-index pair flagging "the broad-phase walk may step
186- /// across these two cells even though they are in different rooms".
187- pub fn set_door_cell_edges ( & mut self , edges : HashSet < ( usize , usize ) > ) {
188- self . door_cell_edges = edges;
188+ /// Replace both cell-edge override sets (canonical `(lo, hi)` pairs).
189+ /// `pass`: the broad-phase walk may step across despite a room boundary.
190+ /// `block`: it may not, despite sharing a room.
191+ pub fn set_edge_cell_overrides (
192+ & mut self ,
193+ pass : HashSet < ( usize , usize ) > ,
194+ block : HashSet < ( usize , usize ) > ,
195+ ) {
196+ self . pass_cell_edges = pass;
197+ self . block_cell_edges = block;
189198 }
190199
191200 pub fn pixel_map ( & self ) -> & PixelCollisionMap {
@@ -230,14 +239,18 @@ impl CollisionDetector for HybridCollisionMap {
230239 let next_idx = ( py * size + px) as usize ;
231240 let next_room = uf. find ( next_idx) ;
232241 if next_room != current_room {
233- let pair = if prev_idx <= next_idx {
234- ( prev_idx, next_idx)
235- } else {
236- ( next_idx, prev_idx)
237- } ;
238- if !self . door_cell_edges . contains ( & pair) {
242+ if !self
243+ . pass_cell_edges
244+ . contains ( & canonical_edge ( prev_idx, next_idx) )
245+ {
239246 return true ;
240247 }
248+ } else if !self . block_cell_edges . is_empty ( )
249+ && self
250+ . block_cell_edges
251+ . contains ( & canonical_edge ( prev_idx, next_idx) )
252+ {
253+ return true ;
241254 }
242255 current_idx = next_idx;
243256 current_room = next_room;
@@ -252,7 +265,8 @@ impl CollisionDetector for HybridCollisionMap {
252265 * uf = UnionFind :: new ( vec ! [ 0 ; self . map_size * self . map_size] , self . map_size ) ;
253266 }
254267 self . pixel_map . clear ( ) ;
255- self . door_cell_edges . clear ( ) ;
268+ self . pass_cell_edges . clear ( ) ;
269+ self . block_cell_edges . clear ( ) ;
256270 }
257271
258272 fn as_any ( & self ) -> & dyn std:: any:: Any {
0 commit comments