✨ feat(gameplay): implement in-system gameplay with camera modes and flight controls
Add comprehensive in-system gameplay features including: Camera System: - Orbit mode for galaxy/inspection views - Follow mode for tracking player ship during flight - Cinematic mode for docked/cutscene views - Smooth interpolation and orbit controls In-System Gameplay: - Docked state at stations with undock functionality - Flight mode with velocity and target-based navigation - Point-and-click movement via ground plane projection - Target selection system for POIs Flight Controls: - Flight state tracking with speed monitoring - Automatic camera transitions between modes - Flight HUD with speed indicator and status panel - Contextual action system for approach/dock/mining UI Updates: - Docked station panel with system information - Flight mode controls and hints - Dynamic population display This implementation provides the foundation for tactical space gameplay with smooth camera transitions and intuitive point-and-click navigation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,13 @@
|
||||
//! 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::*;
|
||||
@@ -13,7 +18,11 @@ 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;
|
||||
|
||||
@@ -22,14 +31,23 @@ impl Plugin for InSystemPlugin {
|
||||
app.init_resource::<DockedState>()
|
||||
.init_resource::<ActiveSystem>()
|
||||
.add_event::<UndockEvent>()
|
||||
.add_plugins(FlightControlsPlugin)
|
||||
.add_plugins(TargetSelectionPlugin)
|
||||
.add_plugins(ContextualActionPlugin)
|
||||
.add_plugins(TimedOperationPlugin)
|
||||
.add_systems(
|
||||
OnEnter(AppState::InGame),
|
||||
(scene::setup_in_system_view, ui::setup_docked_ui).chain(),
|
||||
(
|
||||
scene::setup_in_system_view,
|
||||
ui::setup_docked_ui,
|
||||
add_targetable_to_pois,
|
||||
).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
OnExit(AppState::InGame),
|
||||
(
|
||||
ui::despawn_docked_ui,
|
||||
flight_ui::despawn_flight_ui,
|
||||
scene::despawn_in_system_scene,
|
||||
).chain(),
|
||||
)
|
||||
@@ -38,9 +56,78 @@ impl Plugin for InSystemPlugin {
|
||||
(
|
||||
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<ActionTriggeredEvent>,
|
||||
player_query: Query<Entity, With<scene::PlayerShip>>,
|
||||
durations: Res<operations::OperationDurations>,
|
||||
mut operation_events: EventWriter<operations::OperationStartedEvent>,
|
||||
selected_target_query: Query<&SelectedTarget, With<scene::PlayerShip>>,
|
||||
) {
|
||||
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<crate::gameplay::galaxy::Station>, Without<Targetable>)>,
|
||||
belt_query: Query<(Entity, &crate::gameplay::galaxy::Identifiable), (With<crate::gameplay::galaxy::AsteroidBelt>, Without<Targetable>)>,
|
||||
) {
|
||||
// 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(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user