//! In-system gameplay module. //! //! Handles the system-scale view where the player is docked at a station //! within their selected starting system. This is the entry point to actual //! gameplay after onboarding. mod actions; mod docked; mod flight; mod flight_ui; mod operations; mod scene; mod target; mod ui; use bevy::prelude::*; use crate::state::AppState; pub use docked::{DockedState, UndockEvent}; pub use flight::{FlightState, FlightControlsPlugin}; pub use scene::ActiveSystem; pub use target::{Targetable, TargetKind, SelectedTarget, TargetSelectionPlugin}; pub use actions::{ContextualActionPlugin, ActionType, ActionTriggeredEvent}; pub use operations::{TimedOperationPlugin, OperationKind, ActiveOperation}; pub struct InSystemPlugin; impl Plugin for InSystemPlugin { fn build(&self, app: &mut App) { app.init_resource::() .init_resource::() .add_event::() .add_plugins(FlightControlsPlugin) .add_plugins(TargetSelectionPlugin) .add_plugins(ContextualActionPlugin) .add_plugins(TimedOperationPlugin) .add_systems( OnEnter(AppState::InGame), ( scene::setup_in_system_view, // UI removed - no longer needed // ui::setup_docked_ui, add_targetable_to_pois, ).chain(), ) .add_systems( OnExit(AppState::InGame), ( // UI removed - no longer needed // ui::despawn_docked_ui, // flight_ui::despawn_flight_ui, scene::despawn_in_system_scene, ).chain(), ) .add_systems( Update, ( // UI removed - no longer needed // ui::refresh_docked_ui, // ui::undock_button_handler, // flight_ui::update_flight_ui, handle_action_triggered, ) .chain() .run_if(in_state(AppState::InGame)), ); } } /// Handle action triggered events from the action buttons. fn handle_action_triggered( mut commands: Commands, mut events: EventReader, player_query: Query>, durations: Res, mut operation_events: EventWriter, selected_target_query: Query<&SelectedTarget, With>, ) { let Ok(player_entity) = player_query.single() else { return; }; for event in events.read() { bevy::log::info!("Action triggered: {:?}", event.action_type); match event.action_type { ActionType::Undock => { operations::start_undocking(&mut commands, player_entity, &durations, &mut operation_events); } ActionType::Approach => { // Get selected target if let Ok(selected) = selected_target_query.single() { operations::start_travel(&mut commands, player_entity, selected.name.clone(), &durations, &mut operation_events); } } ActionType::Dock => { // TODO: Implement docking operation bevy::log::info!("Dock action triggered"); } ActionType::StartMining => { // TODO: Implement mining operation bevy::log::info!("Start mining action triggered"); } _ => { bevy::log::info!("Other action: {:?}", event.action_type); } } } } /// Add Targetable components to spawned POIs (stations and asteroid belts) /// so they can be selected by the target selection system. fn add_targetable_to_pois( mut commands: Commands, station_query: Query<(Entity, &crate::gameplay::galaxy::Identifiable), (With, Without)>, belt_query: Query<(Entity, &crate::gameplay::galaxy::Identifiable), (With, Without)>, ) { // Add Targetable to stations for (entity, identifiable) in station_query.iter() { bevy::log::debug!("Adding Targetable component to station: {}", identifiable.display_name); commands.entity(entity).insert(Targetable { kind: TargetKind::Station, name: identifiable.display_name.clone(), }); } // Add Targetable to asteroid belts for (entity, identifiable) in belt_query.iter() { bevy::log::debug!("Adding Targetable component to asteroid belt: {}", identifiable.display_name); commands.entity(entity).insert(Targetable { kind: TargetKind::AsteroidBelt, name: identifiable.display_name.clone(), }); } }