From daf8de5d783872d9f6af89febbe1a5117da3ba5c Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Wed, 17 Jun 2026 19:35:30 -0500 Subject: [PATCH] ship editor feat: spawn hearty & eventually other parts --- .../unified/assets/config/ship_editor.se.toml | 3 ++ .../unified/src/shared/config/ship_editor.rs | 6 +++ crates/unified/src/ship_editor/components.rs | 17 ++++++- crates/unified/src/ship_editor/mod.rs | 48 +++++++++++++++++-- crates/unified/src/ship_editor/ui.rs | 10 +--- 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/crates/unified/assets/config/ship_editor.se.toml b/crates/unified/assets/config/ship_editor.se.toml index dbd40b35073bfe6e36410cd606968dbb8f681218..50006f9113d22e4058cd165fd73090293802960b 100644 --- a/crates/unified/assets/config/ship_editor.se.toml +++ b/crates/unified/assets/config/ship_editor.se.toml @@ -1,3 +1,6 @@ +[general] +player_part = "Hearty" + [part_list] Hub = { order = 0 } Basic_Thruster = { order = 1 } diff --git a/crates/unified/src/shared/config/ship_editor.rs b/crates/unified/src/shared/config/ship_editor.rs index 74b4c1d2e2a90d4442c839e903d0f8bc264b743d..b333f15a76348ef8530ffb44b06a258f8aa4b894 100644 --- a/crates/unified/src/shared/config/ship_editor.rs +++ b/crates/unified/src/shared/config/ship_editor.rs @@ -3,9 +3,15 @@ use crate::prelude::*; #[derive(Deserialize, Asset, TypePath, Component, Serialize, Clone, Debug)] pub struct ShipEditorConfig { + pub general: GeneralShipEditor, pub part_list: HashMap, } +#[derive(Deserialize, TypePath, Component, Serialize, Clone, Debug)] +pub struct GeneralShipEditor { + pub player_part: String, +} + #[derive(Deserialize, TypePath, Component, Serialize, Clone, Debug)] pub struct PartIcon { pub order: usize, diff --git a/crates/unified/src/ship_editor/components.rs b/crates/unified/src/ship_editor/components.rs index c18fdc0a74553601c24a5c6e8a97c284398ee705..5f6587e6d105561ecf6efc2d95a08a409cca87e1 100644 --- a/crates/unified/src/ship_editor/components.rs +++ b/crates/unified/src/ship_editor/components.rs @@ -1,5 +1,7 @@ use bevy::camera::visibility::RenderLayers; -use crate::prelude::Component; +use crate::prelude::{Component, Handle, Resource}; +use crate::shared::config::part::PartConfig; +use crate::shared::config::ship_editor::ShipEditorConfig; pub const MAIN_RENDER_LAYER: RenderLayers = RenderLayers::layer(0); pub const GHOST_RENDER_LAYER: RenderLayers = RenderLayers::layer(1); @@ -10,4 +12,15 @@ pub struct GhostModule; #[derive(Component)] pub struct MainCamera; #[derive(Component)] -pub struct GhostCamera; \ No newline at end of file +pub struct GhostCamera; +#[derive(Component)] +pub struct PlayerPartRequest; +#[derive(Component)] +pub struct SpawnPartRequest(pub Handle); +#[derive(Component)] +pub struct Part(pub PartConfig); + +#[derive(Resource, Default)] +pub struct ShipEditorConfigHolder { + pub handle: Option>, +} \ No newline at end of file diff --git a/crates/unified/src/ship_editor/mod.rs b/crates/unified/src/ship_editor/mod.rs index 775de90b52a1393b0283b17a06576186b44c4f80..b910e4445edc1233c5bf05a94ce176ab407c4b7f 100644 --- a/crates/unified/src/ship_editor/mod.rs +++ b/crates/unified/src/ship_editor/mod.rs @@ -6,9 +6,11 @@ pub mod components; use bevy::input_focus::InputFocus; use crate::client::colors; use crate::prelude::*; -use crate::ship_editor::components::{GhostCamera, MainCamera, GHOST_RENDER_LAYER, MAIN_RENDER_LAYER}; +use crate::shared::config::part::PartConfig; +use crate::shared::config::ship_editor::ShipEditorConfig; +use crate::ship_editor::components::{GhostCamera, MainCamera, Part, PlayerPartRequest, ShipEditorConfigHolder, SpawnPartRequest, GHOST_RENDER_LAYER, MAIN_RENDER_LAYER}; use crate::ship_editor::input::input_plugin; -use crate::ship_editor::ui::ui_plugin; +use crate::ship_editor::ui::{ui_plugin, PendingPart}; pub struct ShipEditorPlugin; @@ -17,6 +19,7 @@ impl Plugin for ShipEditorPlugin { app .init_resource::() .add_systems(Startup, setup) + .add_systems(Update, (spawn_player_part_request, spawn_parts)) .add_plugins(input_plugin) .add_plugins(ui_plugin); } @@ -50,8 +53,43 @@ fn setup( )); let rectangle = meshes.add(Rectangle::new(50.0, 50.0)); commands.spawn(( - Mesh2d(rectangle), - MeshMaterial2d(materials.add(Color::linear_rgb(0.0, 0.0, 0.0))), - Transform::from_xyz(0.0, 0.0, 0.0) + PlayerPartRequest, + Transform::from_xyz(0.0, 0.0, 0.0), )); +} + +fn spawn_player_part_request( + player_part_request_query: Query>, + ship_editor_config_holder: Res, + ship_editor_config: Res>, + mut commands: Commands, + asset_server: Res, +) { + let Some(handle) = ship_editor_config_holder.handle.clone() else { return }; + if let Some(strong_ship_editor_config) = ship_editor_config.get(&handle) { + let player_part = &strong_ship_editor_config.general.player_part; + for entity in player_part_request_query { + commands.entity(entity) + .insert(SpawnPartRequest(asset_server.load(format!("config/parts/{}.part.toml", player_part.to_lowercase())))) + .remove::(); + } + } +} +fn spawn_parts( + spawn_part_query: Query<(Entity, &SpawnPartRequest)>, + part_config: Res>, + asset_server: Res, + mut commands: Commands, +) { + for (entity, request) in spawn_part_query.iter() { + if let Some(strong_part_config) = part_config.get(&request.0) { + let mut sprite = Sprite::from_image(asset_server.load(strong_part_config.part.sprite_connected.clone())); + sprite.custom_size = Some(vec2(strong_part_config.physics.width as f32, strong_part_config.physics.height as f32)); + + commands.entity(entity) + .insert(sprite) + .insert(Part(strong_part_config.clone())) + .remove::(); + } + } } \ No newline at end of file diff --git a/crates/unified/src/ship_editor/ui.rs b/crates/unified/src/ship_editor/ui.rs index 2a6e6002a9244734b2f6fa8f0ce671f92012d7f3..69361892962e7c95312e2cb84c5a5d42c43bfb48 100644 --- a/crates/unified/src/ship_editor/ui.rs +++ b/crates/unified/src/ship_editor/ui.rs @@ -1,11 +1,8 @@ -use bevy::input_focus::InputFocus; use crate::client::colors; use bevy::prelude::*; -use bevy::ui::FocusPolicy; -use bevy::ui::widget::ImageNodeSize; use crate::shared::config::part::PartConfig; -use crate::shared::config::recipe::RecipesConfig; use crate::shared::config::ship_editor::ShipEditorConfig; +use crate::ship_editor::components::ShipEditorConfigHolder; pub fn ui_plugin(app: &mut App) { app @@ -23,11 +20,6 @@ pub struct PartList; #[derive(Component)] pub struct PartEntry(pub PartConfig); -#[derive(Resource, Default)] -struct ShipEditorConfigHolder { - handle: Option>, -} - fn load_ship_editor_config( mut config: ResMut, asset_server: Res,