feat(gameplay): add starting base module and refine galaxy/character creation systems

Co-Authored-By: Oz <oz-agent@warp.dev>
This commit is contained in:
2026-06-12 23:40:33 -04:00
parent 71c6d18817
commit d139dc08d9
20 changed files with 1789 additions and 310 deletions

View File

@@ -0,0 +1,89 @@
//! Starting base selection scene.
//!
//! After character creation, the player chooses a starting base from generated
//! outer-galaxy systems. The choice is kept in a resource until persistence is
//! wired into the game client.
mod scene;
mod ui;
use bevy::prelude::*;
use crate::gameplay::galaxy::StartingBaseCandidate;
use crate::state::AppState;
pub struct StartingBasePlugin;
impl Plugin for StartingBasePlugin {
fn build(&self, app: &mut App) {
app.init_resource::<StartingBaseDraft>()
.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,
)
.add_systems(
Update,
(
escape_to_character_creation,
scene::starting_base_orbit_camera_control,
scene::select_starting_base_on_click,
scene::animate_starting_base_selection,
ui::scroll_starting_base_panels,
ui::candidate_button_handler,
ui::refresh_starting_base_ui,
ui::action_button_handler,
)
.chain()
.run_if(in_state(AppState::StartingBaseSelection)),
);
}
}
#[derive(Resource, Default)]
pub struct StartingBaseDraft {
pub candidates: Vec<StartingBaseCandidate>,
pub selected_index: Option<usize>,
}
#[derive(Resource, Debug, Clone)]
pub struct StartingBaseSelection {
pub system_id: String,
pub system_name: String,
pub faction: &'static str,
pub security: f32,
}
#[derive(Component)]
pub struct StartingBaseSpawned;
#[derive(Component)]
pub struct StartingBaseInputBlocker;
#[derive(Component, Clone, Copy)]
pub enum StartingBaseButton {
Candidate(usize),
Confirm,
Back,
}
fn despawn_starting_base_ui(
mut commands: Commands,
query: Query<Entity, With<StartingBaseSpawned>>,
) {
for entity in &query {
commands.entity(entity).despawn();
}
}
fn escape_to_character_creation(
keys: Res<ButtonInput<KeyCode>>,
mut next_state: ResMut<NextState<AppState>>,
) {
if keys.just_pressed(KeyCode::Escape) {
next_state.set(AppState::CharacterCreation);
}
}