@@ -8,6 +8,7 @@ use petgraph::{
88use crate :: {
99 collision:: { point_segment_collision, segment_collision, PointCollision , SegmentCollision } ,
1010 layer,
11+ level:: Obstacle ,
1112 lines:: { possible_lines, Axis } ,
1213 sim:: SimulationState ,
1314 spawn_road_segment, theme, Collider , ColliderLayer , DrawingInteraction , DrawingMouseMovement ,
@@ -344,6 +345,7 @@ fn not_drawing_mouse_movement_system(
344345 selected_tool : Res < SelectedTool > ,
345346 mouse_snapped : Res < MouseSnappedPos > ,
346347 q_colliders : Query < ( & ChildOf , & Collider , & ColliderLayer ) > ,
348+ q_obstacles : Query < ( ) , With < Obstacle > > ,
347349) {
348350 if !matches ! ( selected_tool. 0 , Tool :: LineDrawing ) {
349351 return ;
@@ -359,12 +361,11 @@ fn not_drawing_mouse_movement_system(
359361
360362 let bad = q_colliders
361363 . iter ( )
362- . any ( |( _parent , collider, layer ) | match collider {
364+ . any ( |( child_of , collider, _layer ) | match collider {
363365 Collider :: Segment ( segment) => {
364366 match point_segment_collision ( mouse_snapped. 0 , segment. 0 , segment. 1 ) {
365367 PointCollision :: None => false ,
366- // TODO (I think) this is a hack to check if the collider is an obstacle
367- _ => layer. 0 == 0 ,
368+ _ => q_obstacles. get ( child_of. parent ( ) ) . is_ok ( ) ,
368369 }
369370 }
370371 _ => false ,
@@ -382,6 +383,7 @@ fn drawing_mouse_movement_system(
382383 sim_state : Res < SimulationState > ,
383384 mouse_snapped : Res < MouseSnappedPos > ,
384385 q_colliders : Query < ( & ChildOf , & Collider , & ColliderLayer ) > ,
386+ q_obstacles : Query < ( ) , With < Obstacle > > ,
385387) {
386388 if !road_state. drawing {
387389 return ;
@@ -448,27 +450,37 @@ fn drawing_mouse_movement_system(
448450 Collider :: Segment ( s) => {
449451 let collision = segment_collision ( s. 0 , s. 1 , * a, * b) ;
450452
453+ // If there's no collision, there's no problem.
454+ if matches ! ( collision, SegmentCollision :: None ) {
455+ continue ;
456+ } ;
457+
458+ let parent = child_of. parent ( ) ;
459+ let is_obstacle = q_obstacles. get ( parent) . is_ok ( ) ;
460+ if is_obstacle {
461+ ok = false ;
462+ break ;
463+ }
464+
451465 match collision {
466+ // This variant is covered above.
467+ SegmentCollision :: None => { }
468+ // We are allowed to cross over road segments on other layers,
469+ // but not obstacles.
452470 SegmentCollision :: Intersecting => {
453- if layer. 0 == road_state. layer || layer . 0 == 0 {
471+ if layer. 0 == road_state. layer {
454472 ok = false ;
455473 break ;
456474 }
457475 }
476+ // Overlapping a road segment is never okay.
458477 SegmentCollision :: Overlapping => {
459478 ok = false ;
460479 break ;
461480 }
481+ // "Touching" collisions are allowed only if they are the
482+ // start or end of the line we are currently drawing.
462483 SegmentCollision :: Touching ( intersection_point) => {
463- // "Touching" collisions are allowed only if they are the
464- // start or end of the line we are currently drawing.
465-
466- // TODO (I think) this is a hack to check if the collider is an obstacle
467- if layer. 0 == 0 {
468- ok = false ;
469- break ;
470- }
471-
472484 let start_touching = intersection_point == road_state. start ;
473485 let end_touching = intersection_point == road_state. end ;
474486
@@ -500,29 +512,18 @@ fn drawing_mouse_movement_system(
500512 }
501513
502514 if start_touching {
503- connections
504- . 0
505- . push ( SegmentConnection :: Split ( child_of. parent ( ) ) ) ;
515+ connections. 0 . push ( SegmentConnection :: Split ( parent) ) ;
506516 split_layers. 0 . insert ( layer. 0 ) ;
507517 }
508518 if end_touching {
509- connections
510- . 1
511- . push ( SegmentConnection :: Split ( child_of. parent ( ) ) ) ;
519+ connections. 1 . push ( SegmentConnection :: Split ( parent) ) ;
512520 split_layers. 1 . insert ( layer. 0 ) ;
513521 }
514522 }
523+ // "Connecting" collisions are allowed only if they are the
524+ // start or end of the line we are currently drawing.
515525 SegmentCollision :: Connecting ( intersection_point)
516526 | SegmentCollision :: ConnectingParallel ( intersection_point) => {
517- // "Connecting" collisions are allowed only if they are the
518- // start or end of the line we are currently drawing.
519-
520- // TODO (I think) this is a hack to check if the collider is an obstacle
521- if layer. 0 == 0 {
522- ok = false ;
523- break ;
524- }
525-
526527 let start_touching = intersection_point == road_state. start ;
527528 let end_touching = intersection_point == road_state. end ;
528529
@@ -537,13 +538,9 @@ fn drawing_mouse_movement_system(
537538 if matches ! ( collision, SegmentCollision :: ConnectingParallel ( _) )
538539 && layer. 0 == road_state. layer
539540 {
540- connections
541- . 0
542- . push ( SegmentConnection :: TryExtend ( child_of. parent ( ) ) ) ;
541+ connections. 0 . push ( SegmentConnection :: TryExtend ( parent) ) ;
543542 } else {
544- connections
545- . 0
546- . push ( SegmentConnection :: Add ( child_of. parent ( ) ) ) ;
543+ connections. 0 . push ( SegmentConnection :: Add ( parent) ) ;
547544 }
548545 }
549546 if ( road_state. start == * b && start_touching)
@@ -552,23 +549,18 @@ fn drawing_mouse_movement_system(
552549 if matches ! ( collision, SegmentCollision :: ConnectingParallel ( _) )
553550 && layer. 0 == road_state. layer
554551 {
555- connections
556- . 1
557- . push ( SegmentConnection :: TryExtend ( child_of. parent ( ) ) ) ;
552+ connections. 1 . push ( SegmentConnection :: TryExtend ( parent) ) ;
558553 } else {
559- connections
560- . 1
561- . push ( SegmentConnection :: Add ( child_of. parent ( ) ) ) ;
554+ connections. 1 . push ( SegmentConnection :: Add ( parent) ) ;
562555 }
563556 }
564557 }
565- SegmentCollision :: None => { }
566558 }
567559 }
560+ // The only point colliders that exist right now are for termini
568561 Collider :: Point ( p) => match point_segment_collision ( * p, * a, * b) {
562+ // Don't allow the midpoint of the line to connect to a terminus.
569563 PointCollision :: Middle => {
570- // don't allow the midpoint of the line to connect to a
571- // terminus
572564 ok = false ;
573565 break ;
574566 }
@@ -578,19 +570,19 @@ fn drawing_mouse_movement_system(
578570 break ;
579571 }
580572
573+ // Exit drawing mode if the player is connecting a road to a
574+ // terminus.
581575 if * p == road_state. end {
582576 stop = true ;
583577 }
584578
579+ let parent = child_of. parent ( ) ;
580+
585581 if * a == * p {
586- connections
587- . 0
588- . push ( SegmentConnection :: Add ( child_of. parent ( ) ) ) ;
582+ connections. 0 . push ( SegmentConnection :: Add ( parent) ) ;
589583 }
590584 if * b == * p {
591- connections
592- . 1
593- . push ( SegmentConnection :: Add ( child_of. parent ( ) ) ) ;
585+ connections. 1 . push ( SegmentConnection :: Add ( parent) ) ;
594586 }
595587 }
596588 PointCollision :: None => { }
0 commit comments