From 0e2da454f0202d5aea3a98143811bcc00467f405 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Sun, 5 Apr 2026 12:41:30 -0500 Subject: [PATCH] feat: recipe list config + basis for ui --- crates/unified/Cargo.toml | 1 + crates/unified/assets/config/recipes.rc.toml | 7 +++ crates/unified/src/client/crafting/ui.rs | 57 +++++++++++++++++++- crates/unified/src/config/mod.rs | 1 + crates/unified/src/config/recipe.rs | 16 ++++++ crates/unified/src/ecs.rs | 1 + crates/unified/src/server/player/join.rs | 7 ++- crates/unified/src/shared_plugins.rs | 2 + 8 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 crates/unified/assets/config/recipes.rc.toml create mode 100644 crates/unified/src/config/recipe.rs diff --git a/crates/unified/Cargo.toml b/crates/unified/Cargo.toml index 9be95d1eeb64a820e9f3ffc186b2e2382a435bdc..ac319e8f60b6765e6064e7eb8efae15932f8e06c 100644 --- a/crates/unified/Cargo.toml +++ b/crates/unified/Cargo.toml @@ -27,6 +27,7 @@ bevy = { version = "0.18", default-features = false, features = [ "default_font", "png", "bevy_gizmos", + "bevy_gizmos_render", "bevy_post_process", "bevy_anti_alias", "bevy_sprite_render", diff --git a/crates/unified/assets/config/recipes.rc.toml b/crates/unified/assets/config/recipes.rc.toml new file mode 100644 index 0000000000000000000000000000000000000000..f80bdae66ecaccc1f5943c0eef47a1cb830676dc --- /dev/null +++ b/crates/unified/assets/config/recipes.rc.toml @@ -0,0 +1,7 @@ +[recipes] +Frame = [ + { Silicon = 10 } +] +Thruster = [ + { Silicon = 20, Carbon = 20 } +] diff --git a/crates/unified/src/client/crafting/ui.rs b/crates/unified/src/client/crafting/ui.rs index 94f71fe47f0226eeb2f6fb25bf942564c3f7f8da..de3bd2afac00fcf893513027e279169b83c492f7 100644 --- a/crates/unified/src/client/crafting/ui.rs +++ b/crates/unified/src/client/crafting/ui.rs @@ -1,8 +1,11 @@ use bevy::{input_focus::{AutoFocus, InputFocus}, ui::RelativeCursorPosition}; -use crate::{attachment::PartInShip, client::colors, ecs::{CanCraft, CraftingUi, Drill, MainCamera, Me, Part, SingleStorage, ToggleDrillEvent}, prelude::*}; +use crate::{attachment::PartInShip, client::colors, config::recipe::RecipesConfig, ecs::{CanCraft, CraftingUi, Drill, MainCamera, Me, Part, SingleStorage, ToggleDrillEvent}, prelude::*}; pub fn crafting_ui_plugin(app: &mut App) { + app.init_resource::(); + app.add_systems(Startup, load_recipes); + app.add_systems(PreUpdate, (initial_create_recipe_list, update_recipe_list)); app.add_systems(Update, (close_button, drill_button, drill_state_change, single_storage_display)); } @@ -14,6 +17,18 @@ struct PreviousInteraction(Interaction); struct DrillButton(Entity); // stores corresponding part #[derive(Component)] struct SingleStorageDisplay(Entity); // stores corresponding part +#[derive(Component)] +struct RecipesHolder; +#[derive(Component)] +struct PendingRecipesHolder; +#[derive(Resource, Default)] +struct RecipeCollection { + handle: Option>, +} + +fn load_recipes(asset_server: Res, mut recipe_collection: ResMut) { + recipe_collection.handle = Some(asset_server.load("config/recipes.rc.toml")); +} pub fn open_crafting_ui( ev: On>, @@ -125,9 +140,49 @@ fn setup_ui( SingleStorageDisplay(parent_part), )); } + // assume CanCraft for now (THIS WILL CHANGE) + parent.spawn(( + Node { + ..Default::default() + }, + PendingRecipesHolder, + )); }); } +fn initial_create_recipe_list( + mut commands: Commands, + added_recipes_holders: Query>, + recipe_collection: ResMut, + recipes_config: Res>, +) { + if let Some(strong_recipes_config) = recipes_config.get(&recipe_collection.handle.clone().unwrap()) { + for recipe_holder in &added_recipes_holders { + let mut recipe_holder = commands.get_entity(recipe_holder).unwrap(); + debug!("{:?}", strong_recipes_config); + recipe_holder + .insert(RecipesHolder) + .remove::(); + } + } +} +fn update_recipe_list( + mut ev_config: MessageReader>, + recipe_collection: ResMut, +) { + let Some(handle) = recipe_collection.handle.as_ref() else { + return + }; + + for ev in ev_config.read() { + if let AssetEvent::Modified { id } = ev { + if *id == handle.id() { + debug!("recipe list config modified - reloading lists"); + } + } + } +} + fn drill_button( mut interaction_query: Query< ( diff --git a/crates/unified/src/config/mod.rs b/crates/unified/src/config/mod.rs index 4702097c3cdff582ce6fd9d5262bade70b74c74a..df8e85bc8a445f5a001c18578dfd6f867939d591 100644 --- a/crates/unified/src/config/mod.rs +++ b/crates/unified/src/config/mod.rs @@ -1,3 +1,4 @@ pub mod part; pub mod planet; pub mod world; +pub mod recipe; diff --git a/crates/unified/src/config/recipe.rs b/crates/unified/src/config/recipe.rs new file mode 100644 index 0000000000000000000000000000000000000000..18337f58792f359505a60bb9935f59ecf26823bd --- /dev/null +++ b/crates/unified/src/config/recipe.rs @@ -0,0 +1,16 @@ +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; + +use crate::prelude::*; + +#[derive(Deserialize, Asset, TypePath, Component, Serialize, Clone, Debug)] +#[require(Replicated)] +pub struct RecipesConfig { + pub recipes: HashMap>>, +} + +/*#[derive(Deserialize, TypePath, Component, Serialize, Clone, Debug)] +pub struct Recipe { + pub inputs: HashMap, +}*/ diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index fd95382d6bd3938dbd3efab071013e94c2b8d767..5b14bb5866c94884277e22632a3d66173bf24df7 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -113,6 +113,7 @@ pub struct Hi { } #[derive(Component, Serialize, Deserialize, Debug)] +#[require(Replicated)] pub struct CanCraft; #[derive(Component, Serialize, Deserialize, Debug)] pub struct CraftingUi; diff --git a/crates/unified/src/server/player/join.rs b/crates/unified/src/server/player/join.rs index 66cb73174db97b64b76271922ce67bd7ce4910a0..8a2bf31f43afd3e99c5015cce04aa7e7dc7096d6 100644 --- a/crates/unified/src/server/player/join.rs +++ b/crates/unified/src/server/player/join.rs @@ -33,10 +33,9 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo info!(?new_transform, ?joined_player, "set player's position!"); - let mut entity = commands - .entity(joined_player); - let id = entity.id(); - entity.insert(new_transform) + commands + .entity(joined_player) + .insert(new_transform) .insert(SpawnPartRequest( asset_server.load("config/parts/hearty.part.toml"), )) diff --git a/crates/unified/src/shared_plugins.rs b/crates/unified/src/shared_plugins.rs index 2b90f5bf741a8133d342e2881d2953265cd67626..74f262fe9dcc8db3792ca409abbbe0e1bbdb04a1 100644 --- a/crates/unified/src/shared_plugins.rs +++ b/crates/unified/src/shared_plugins.rs @@ -1,5 +1,6 @@ use crate::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint}; use crate::config::planet::{Planet, PlanetConfigCollection}; +use crate::config::recipe::RecipesConfig; use crate::ecs::{CanCraft, DragRequestEvent, Drill, Hi, Part, Particles, Player, PlayerStorage, SingleStorage, Temperature, ToggleDrillEvent}; use bevy::app::{App, PluginGroup, PluginGroupBuilder}; use bevy_common_assets::toml::TomlAssetPlugin; @@ -28,6 +29,7 @@ impl PluginGroup for SharedPluginGroup { .add(TomlAssetPlugin::::new(&["wc.toml"])) .add(TomlAssetPlugin::::new(&["pc.toml"])) .add(TomlAssetPlugin::::new(&["part.toml"])) + .add(TomlAssetPlugin::::new(&["rc.toml"])) } }