Skip to main content

traaains/editor/train/placing/
observers.rs

1use bevy::{
2    ecs::{
3        component::Component,
4        entity::Entity,
5        event::EntityEvent,
6        observer::On,
7        query::With,
8        system::{Query, Res, ResMut, Single},
9    },
10    picking::events::{PointerEnter, PointerLeave, PointerMove},
11    state::state::NextState,
12    transform::components::Transform,
13};
14use bezier::Bezier;
15
16use crate::{
17    editor::train::placing::{CurrentPlacingDir, VirtualTrain, states::hovering::HoveringTrack},
18    game::cursor::CursorPos,
19    sim::track::{pos::TrackPos, segment::TrackSegment},
20};
21
22#[derive(Component)]
23pub struct PlacingTrainObserver;
24
25pub fn on_segment_pointer_enter(
26    e: On<PointerEnter>,
27    q_segments: Query<Entity, With<TrackSegment>>,
28    mut next_state: ResMut<NextState<HoveringTrack>>,
29) {
30    if let Ok(segment) = q_segments.get(e.event_target()) {
31        next_state.set(HoveringTrack(Some(segment)));
32    }
33}
34
35pub fn on_segment_pointer_leave(
36    e: On<PointerLeave>,
37    q_segments: Query<Entity, With<TrackSegment>>,
38    mut next_state: ResMut<NextState<HoveringTrack>>,
39) {
40    if q_segments.get(e.event_target()).is_ok() {
41        next_state.set(HoveringTrack(None));
42    }
43}
44
45/// Observer which when a pointer moves inside a segment updates the corresponding train track pos
46pub fn on_segment_pointer_move(
47    e: On<PointerMove>,
48    q_segments: Query<(Entity, &TrackSegment, &Transform)>,
49    mut virtual_train: Single<&mut TrackPos, With<VirtualTrain>>,
50    cursor_pos: Res<CursorPos>,
51    current_dir: Res<CurrentPlacingDir>,
52) {
53    let Ok((ts, ts_segment, ts_transform)) = q_segments.get(e.event_target()) else {
54        return;
55    };
56
57    let local_cursor = cursor_pos.0 - ts_transform.translation.truncate();
58    let curr_idx = ts_segment.shape.project(local_cursor);
59
60    virtual_train.segment = ts;
61    virtual_train.idx = curr_idx;
62    virtual_train.dir = Some(current_dir.0);
63}