From 8e95947f6252a575472917dfb7cbc23956035f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=2E=20Mj=C3=A5land?= Date: Tue, 29 Apr 2025 22:10:21 +0200 Subject: [PATCH 1/2] separate out input handling from brush handler --- crates/designations/src/designations.rs | 52 ++++++++++++++++++------- crates/work/src/lib.rs | 12 ++---- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/crates/designations/src/designations.rs b/crates/designations/src/designations.rs index 91817fd..313ba23 100644 --- a/crates/designations/src/designations.rs +++ b/crates/designations/src/designations.rs @@ -1,6 +1,8 @@ use bevy::{prelude::*, window::PrimaryWindow}; use camera::CameraLayer; -use common::{functions::world_position_to_world_coordinates, states::AppState}; +use common::{ + functions::world_position_to_world_coordinates, states::AppState, types::WorldCoordinates, +}; use leafwing_input_manager::{ Actionlike, InputManagerBundle, plugin::InputManagerPlugin, @@ -18,6 +20,11 @@ pub(crate) enum MouseActions { Dig, } +#[derive(Event)] +enum BrushInputEvent { + Designated(WorldCoordinates), +} + #[derive(Default, Reflect, Resource)] #[reflect(Resource)] pub(crate) struct BrushSettings { @@ -27,10 +34,16 @@ pub(crate) struct BrushSettings { pub fn plugin(app: &mut App) { app.insert_resource(BrushSettings::default()) .add_plugins(InputManagerPlugin::::default()) + .add_event::() .add_systems(OnEnter(AppState::MainGame), setup_brush) .add_systems( Update, - (handle_brush, ui::brushes).run_if(in_state(AppState::MainGame)), + ( + handle_brush_input, + handle_brush.after(handle_brush_input), + ui::brushes, + ) + .run_if(in_state(AppState::MainGame)), ); } @@ -51,14 +64,11 @@ fn setup_brush(mut commands: Commands) { )); } -fn handle_brush( - brush_settings: Res, - world_map: Res, - work_order_queue: Res, +fn handle_brush_input( query: Single<&ActionState>, window: Single<&Window, With>, camera: Single<(&Camera, &GlobalTransform, &CameraLayer), With>, - mut commands: Commands, + mut brush_event_writer: EventWriter, ) { let window = window.into_inner(); let action_state = query.into_inner(); @@ -69,18 +79,32 @@ fn handle_brush( .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor).ok()) .map(|ray| ray.origin.truncate()) { - #[allow(clippy::single_match)] + let world_coordinates = + world_position_to_world_coordinates(world_position.extend(layer.0 as f32)); + brush_event_writer.write(BrushInputEvent::Designated(world_coordinates)); + } + } +} + +fn handle_brush( + brush_settings: Res, + world_map: Res, + work_order_queue: Res, + mut brush_event_reader: EventReader, + mut commands: Commands, +) { + for brush_input_event in brush_event_reader.read() { + #[allow(irrefutable_let_patterns)] + if let BrushInputEvent::Designated(world_coordinate) = brush_input_event { match brush_settings.current_action { MouseActions::Dig => { - let world_coordinates = - world_position_to_world_coordinates(world_position.extend(layer.0 as f32)); - if !work_order_queue.contains(&WorkOrder::Dig(world_coordinates)) - && world_map.get_block(world_coordinates).is_some() + if !work_order_queue.contains(&WorkOrder::Dig(*world_coordinate)) + && world_map.get_block(*world_coordinate).is_some() { - commands.spawn(WorkOrder::dig(world_position.extend(layer.0 as f32))); + commands.spawn(WorkOrder::dig(*world_coordinate)); } } - _ => (), + MouseActions::None => (), } } } diff --git a/crates/work/src/lib.rs b/crates/work/src/lib.rs index a1a2e1b..9f49274 100644 --- a/crates/work/src/lib.rs +++ b/crates/work/src/lib.rs @@ -1,8 +1,5 @@ use bevy::prelude::*; -use common::{ - constants::TILE_SIZE, functions::world_position_to_world_coordinates, - traits::SpawnNamedObserver, types::WorldCoordinates, -}; +use common::{constants::TILE_SIZE, traits::SpawnNamedObserver, types::WorldCoordinates}; use tasks::{Task, TaskEvent, TaskQueue}; use work_order_queue::WorkOrderQueue; @@ -24,13 +21,10 @@ pub enum WorkOrder { impl WorkOrder { /// Creates a digging work order for the given world position - pub fn dig(world_position: Vec3) -> impl Bundle { - let world_coordinates = world_position_to_world_coordinates(world_position); + pub fn dig(world_coordinates: WorldCoordinates) -> impl Bundle { ( Name::new(format!("WorkOrder - Dig {}", world_coordinates.0)), - Transform::from_translation( - (world_position / TILE_SIZE.extend(1.0)).round() * TILE_SIZE.extend(1.0), - ), + Transform::from_translation(world_coordinates.0.as_vec3() * TILE_SIZE.extend(1.0)), WorkOrder::Dig(world_coordinates), ) } From 5a6044dd4d791afff79da3925b3c383d6683998d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=2E=20Mj=C3=A5land?= Date: Tue, 29 Apr 2025 22:14:08 +0200 Subject: [PATCH 2/2] don't handle input if it interacts with an egui element --- crates/designations/src/designations.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/designations/src/designations.rs b/crates/designations/src/designations.rs index 313ba23..d4379cf 100644 --- a/crates/designations/src/designations.rs +++ b/crates/designations/src/designations.rs @@ -1,4 +1,5 @@ use bevy::{prelude::*, window::PrimaryWindow}; +use bevy_inspector_egui::bevy_egui::EguiContexts; use camera::CameraLayer; use common::{ functions::world_position_to_world_coordinates, states::AppState, types::WorldCoordinates, @@ -69,7 +70,14 @@ fn handle_brush_input( window: Single<&Window, With>, camera: Single<(&Camera, &GlobalTransform, &CameraLayer), With>, mut brush_event_writer: EventWriter, + mut contexts: EguiContexts, ) { + // Skip pointer events that are captured by egui + let ctx = contexts.ctx_mut(); + if ctx.wants_pointer_input() { + return; + } + let window = window.into_inner(); let action_state = query.into_inner(); let (camera, camera_transform, layer) = camera.into_inner();