feat(gameplay): implement in-system onboarding with docked station view
Implement the final onboarding step where the player loads into their selected starting system docked at a station. New features: - Create in_system module for system-scale gameplay - Spawn player ship docked at highest-population station - Display station info panel with undock button - Position camera for cinematic docked view with orbit controls Implementation details: - in_system/mod.rs: Plugin setup with DockedState and ActiveSystem resources - in_system/scene.rs: System/POI spawning and player ship docked positioning - in_system/docked.rs: Docked state management and UndockEvent - in_system/ui.rs: Docked UI with station details and undock button - Reuse existing POI spawning patterns from galaxy/contents.rs - Select docking station by highest population (better for new players) Modified files: - Add in_system module exports to gameplay/mod.rs - Register InSystemPlugin in main.rs - Update orbit camera control for InGame state - Re-export GeneratedStation and STARTING_SHIPS for use by in_system The player now completes onboarding by loading into a system view with their ship docked at a station, ready for gameplay. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,33 +9,40 @@ mod ui;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::gameplay::galaxy::StartingBaseCandidate;
|
||||
use crate::gameplay::galaxy::{StartingBaseCandidate, orbits};
|
||||
use crate::state::AppState;
|
||||
|
||||
// Public exports for POI spawning
|
||||
pub use scene::{SpawnedPoiSystem, StartingBasePoi};
|
||||
|
||||
pub struct StartingBasePlugin;
|
||||
|
||||
impl Plugin for StartingBasePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<StartingBaseDraft>()
|
||||
.init_resource::<StartingBaseFocusGoal>()
|
||||
.init_resource::<scene::SpawnedPoiSystem>()
|
||||
.add_systems(
|
||||
OnEnter(AppState::StartingBaseSelection),
|
||||
(scene::setup_starting_base_scene, ui::setup_starting_base_ui).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
OnExit(AppState::StartingBaseSelection),
|
||||
despawn_starting_base_ui,
|
||||
(despawn_starting_base_ui, scene::despawn_pois_on_exit).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
escape_to_character_creation,
|
||||
scene::starting_base_orbit_camera_control,
|
||||
scene::select_starting_base_on_click,
|
||||
ui::candidate_button_handler,
|
||||
scene::focus_starting_base_camera,
|
||||
scene::animate_starting_base_selection,
|
||||
ui::scroll_starting_base_panels,
|
||||
ui::candidate_button_handler,
|
||||
ui::refresh_starting_base_ui,
|
||||
ui::action_button_handler,
|
||||
scene::spawn_selected_pois,
|
||||
orbits::advance_orbital_paths,
|
||||
)
|
||||
.chain()
|
||||
.run_if(in_state(AppState::StartingBaseSelection)),
|
||||
@@ -57,6 +64,27 @@ pub struct StartingBaseSelection {
|
||||
pub security: f32,
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, Clone, Copy)]
|
||||
pub struct StartingBaseFocusRequest {
|
||||
pub candidate_index: usize,
|
||||
}
|
||||
|
||||
/// Resolved focus target the starting-base camera tweens toward. Set by
|
||||
/// [`crate::gameplay::starting_base::scene::focus_starting_base_camera`] when a
|
||||
/// candidate is selected, then approached gradually by the orbit control
|
||||
/// system, which clears `active` once the camera arrives (or the user takes
|
||||
/// manual control by dragging / scrolling).
|
||||
///
|
||||
/// Persistent rather than inserted/removed on demand so the consumer can mutate
|
||||
/// it via a single `ResMut` and keep the orbit control system's parameter count
|
||||
/// manageable.
|
||||
#[derive(Resource, Debug, Clone, Copy, Default)]
|
||||
pub struct StartingBaseFocusGoal {
|
||||
pub target: Vec3,
|
||||
pub distance: f32,
|
||||
pub active: bool,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct StartingBaseSpawned;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user