diff --git a/cosmos_client/src/crafting/blocks/basic_fabricator/ui.rs b/cosmos_client/src/crafting/blocks/basic_fabricator/ui.rs index ab3db573..c5060770 100644 --- a/cosmos_client/src/crafting/blocks/basic_fabricator/ui.rs +++ b/cosmos_client/src/crafting/blocks/basic_fabricator/ui.rs @@ -4,8 +4,8 @@ use bevy::{ core::Name, log::{error, info}, prelude::{ - in_state, resource_exists, Added, App, BuildChildren, Commands, Component, Entity, Event, - EventReader, IntoSystemConfigs, NodeBundle, Query, Res, TextBundle, With, + in_state, resource_exists, Added, App, BuildChildren, Commands, Component, Entity, Event, EventReader, IntoSystemConfigs, + NodeBundle, Query, Res, TextBundle, With, }, text::{Text, TextStyle}, ui::{AlignItems, BackgroundColor, FlexDirection, JustifyContent, Style, TargetCamera, UiRect, Val}, @@ -157,18 +157,16 @@ fn populate_menu( let mut slot_ents = vec![]; ecmds.with_children(|p| { - p.spawn( - ScrollBundle { - node_bundle: NodeBundle { - style: Style { - flex_grow: 1.0, - ..Default::default() - }, + p.spawn(ScrollBundle { + node_bundle: NodeBundle { + style: Style { + flex_grow: 1.0, ..Default::default() }, ..Default::default() }, - ) + ..Default::default() + }) .with_children(|p| { for recipe in crafting_recipes.iter() { p.spawn(( @@ -228,21 +226,18 @@ fn populate_menu( ..Default::default() }); - p.spawn( - NodeBundle { - style: Style { - flex_direction: FlexDirection::Row, - width: Val::Percent(100.0), - ..Default::default() - }, + p.spawn(NodeBundle { + style: Style { + flex_direction: FlexDirection::Row, + width: Val::Percent(100.0), ..Default::default() }, - ) + ..Default::default() + }) .with_children(|p| { for item in recipe.inputs.iter() { let item_id = match item.item { RecipeItem::Item(i) => i, - RecipeItem::Category(_) => todo!("Categories"), }; p.spawn(( @@ -263,10 +258,6 @@ fn populate_menu( p.spawn(( Name::new("Item recipe qty"), TextNeedsTopRoot, - InventoryCount { - item_id, - recipe_amt: item.quantity, - }, TextBundle { text: Text::from_section(format!("{}", item.quantity), text_style.clone()), ..Default::default() @@ -350,12 +341,6 @@ fn populate_menu( } } -#[derive(Component, Debug)] -struct InventoryCount { - recipe_amt: u16, - item_id: u16, -} - fn on_select_item( mut commands: Commands, mut evr_select_item: EventReader, diff --git a/cosmos_client/src/crafting/mod.rs b/cosmos_client/src/crafting/mod.rs index 7a436531..df195251 100644 --- a/cosmos_client/src/crafting/mod.rs +++ b/cosmos_client/src/crafting/mod.rs @@ -1,3 +1,5 @@ +//! Client crafting logic + use bevy::prelude::App; mod blocks; diff --git a/cosmos_client/src/inventory/mod.rs b/cosmos_client/src/inventory/mod.rs index 649aa791..f1f96d92 100644 --- a/cosmos_client/src/inventory/mod.rs +++ b/cosmos_client/src/inventory/mod.rs @@ -101,11 +101,18 @@ fn close_button_system( } #[derive(Debug, Clone)] +/// Instructions on how to render this inventory. pub struct CustomInventoryRender { slots: Vec<(usize, Entity)>, } impl CustomInventoryRender { + /// The slots should be a Vec<(slot_index, slot_entity)>. + /// + /// Each `slot_index` should be based off the slots in the inventory you wish to render. + /// + /// Each `slot_entity` should be a UI node that will be filled in to be an interactable item + /// slot. pub fn new(slots: Vec<(usize, Entity)>) -> Self { Self { slots } } @@ -114,7 +121,11 @@ impl CustomInventoryRender { #[derive(Component, Debug, Clone)] /// Add this to an inventory you want displayed, and remove this component when you want to hide the inventory pub enum InventoryNeedsDisplayed { + /// A standard inventory rendering with no custom rendering. This Will be rendered like a chest + /// or player's inventory. Normal(InventorySide), + /// You dictate where and which inventory slots should be rendered. See + /// [`CustomInventoryRender::new`] Custom(CustomInventoryRender), } diff --git a/cosmos_core/src/crafting/blocks/basic_fabricator.rs b/cosmos_core/src/crafting/blocks/basic_fabricator.rs index c6299c31..38775935 100644 --- a/cosmos_core/src/crafting/blocks/basic_fabricator.rs +++ b/cosmos_core/src/crafting/blocks/basic_fabricator.rs @@ -1,3 +1,5 @@ +//! Contains logic for the basic fabricator block + use bevy::prelude::{App, Event}; use serde::{Deserialize, Serialize}; @@ -8,6 +10,7 @@ use crate::{ }; #[derive(Event, Debug, Clone, Copy, Serialize, Deserialize)] +/// Sent by the server to the client to instruct them to open a basic fabricator. pub struct OpenBasicFabricatorEvent(pub StructureBlock); impl IdentifiableEvent for OpenBasicFabricatorEvent { @@ -23,9 +26,15 @@ impl NettyEvent for OpenBasicFabricatorEvent { } #[derive(Event, Debug, Clone, Serialize, Deserialize)] +/// Sent by the client to the server to request crafting a specific recipe. pub struct CraftBasicFabricatorRecipeEvent { + /// The block that contains the fabricator the client is using pub block: StructureBlock, + /// The recipe to use. Note that this MUST match one of the recipes the server contains or it + /// will be ignored by the server. pub recipe: BasicFabricatorRecipe, + /// The quantity they wish to craft. If more is requested than can be crafted, the maximum + /// amount that can be fabricated will be created. pub quantity: u32, } diff --git a/cosmos_core/src/crafting/blocks/mod.rs b/cosmos_core/src/crafting/blocks/mod.rs index 060a4ee7..cd652ffe 100644 --- a/cosmos_core/src/crafting/blocks/mod.rs +++ b/cosmos_core/src/crafting/blocks/mod.rs @@ -1,3 +1,5 @@ +//! Contains logic for blocks that are used for crafting + use bevy::prelude::App; pub mod basic_fabricator; diff --git a/cosmos_core/src/crafting/mod.rs b/cosmos_core/src/crafting/mod.rs index 89115435..a5ef99ab 100644 --- a/cosmos_core/src/crafting/mod.rs +++ b/cosmos_core/src/crafting/mod.rs @@ -1,3 +1,5 @@ +//! Shared logic for all forms of crafting + use bevy::prelude::App; pub mod blocks; diff --git a/cosmos_core/src/crafting/recipes/basic_fabricator.rs b/cosmos_core/src/crafting/recipes/basic_fabricator.rs index b8fdba62..fb7ee387 100644 --- a/cosmos_core/src/crafting/recipes/basic_fabricator.rs +++ b/cosmos_core/src/crafting/recipes/basic_fabricator.rs @@ -1,3 +1,5 @@ +//! Shared logic for Basic Fabricator recipes. + use bevy::{ prelude::{App, Event, Resource}, utils::HashMap, @@ -14,40 +16,55 @@ use crate::{ use super::RecipeItem; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +/// An item that can be used as an input for a basic fabricator recipe pub struct FabricatorItemInput { + /// The amount of this item required pub quantity: u16, + /// The type of item required pub item: RecipeItem, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +/// The output of the fabricator recipe pub struct FabricatorItemOutput { + /// The quantity output pub quantity: u16, + /// The item output pub item: u16, } impl FabricatorItemInput { + /// Creates a new fabricator item input pub fn new(item: RecipeItem, quantity: u16) -> Self { Self { item, quantity } } } impl FabricatorItemOutput { + /// Creates a new fabricator item output pub fn new(item: &Item, quantity: u16) -> Self { Self { item: item.id(), quantity } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +/// A recipe for the basic fabricator. pub struct BasicFabricatorRecipe { + /// All inputs for this recipe pub inputs: Vec, + /// The output for this recipe pub output: FabricatorItemOutput, } impl BasicFabricatorRecipe { + /// Creates a new recipe pub fn new(output: FabricatorItemOutput, inputs: Vec) -> Self { Self { output, inputs } } + /// Computes the maximum amount of items this recipe can prodce, with the given items. + /// + /// The `items` iterator can contain items unrelated to the recipe. pub fn max_can_create<'a>(&self, items: impl Iterator) -> u32 { let mut unique_item_counts = HashMap::new(); for item in items { @@ -57,7 +74,6 @@ impl BasicFabricatorRecipe { for input in &self.inputs { let id = match input.item { RecipeItem::Item(id) => id, - RecipeItem::Category(_) => todo!(), }; unique_item_counts.entry(id).or_insert(0); } @@ -67,7 +83,6 @@ impl BasicFabricatorRecipe { .flat_map(|(item_id, quantity)| { let Some(input) = self.inputs.iter().find(|x| match x.item { RecipeItem::Item(id) => id == item_id, - RecipeItem::Category(_) => todo!(), }) else { return None; }; @@ -81,23 +96,34 @@ impl BasicFabricatorRecipe { } #[derive(Debug, Clone, Serialize, Deserialize, Default, Resource)] +/// Contains all the Basic Fabricator recipes. +/// +/// Recipes should be registered with this to be considered active. pub struct BasicFabricatorRecipes(Vec); impl BasicFabricatorRecipes { + /// Returns true if this is a valid recipe contained in this registry pub fn contains(&self, recipe: &BasicFabricatorRecipe) -> bool { self.iter().any(|x| x == recipe) } + /// Adds a recipe to the registry. This will not add duplicates. pub fn add_recipe(&mut self, recipe: BasicFabricatorRecipe) { + if self.contains(&recipe) { + return; + } self.0.push(recipe); } + /// Iterates over every recipe pub fn iter(&self) -> impl Iterator { self.0.iter() } } #[derive(Event, Serialize, Deserialize, Debug)] +/// Used to sync all recipes to the connecting clients. Sent when a client joins after they have +/// loaded all the recipes. pub struct SyncBasicFabricatorRecipesEvent(pub BasicFabricatorRecipes); impl IdentifiableEvent for SyncBasicFabricatorRecipesEvent { diff --git a/cosmos_core/src/crafting/recipes/mod.rs b/cosmos_core/src/crafting/recipes/mod.rs index 99062169..cc6ba91e 100644 --- a/cosmos_core/src/crafting/recipes/mod.rs +++ b/cosmos_core/src/crafting/recipes/mod.rs @@ -1,12 +1,16 @@ +//! Contains logic for the different types of recipes + use bevy::prelude::App; use serde::{Deserialize, Serialize}; pub mod basic_fabricator; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +/// An item that is used in a recipe pub enum RecipeItem { + /// A single item's numberic id Item(u16), - Category(u16), + // Category(u16), } pub(super) fn register(app: &mut App) { diff --git a/cosmos_core/src/inventory/itemstack.rs b/cosmos_core/src/inventory/itemstack.rs index 7c1e8d1a..7b11060f 100644 --- a/cosmos_core/src/inventory/itemstack.rs +++ b/cosmos_core/src/inventory/itemstack.rs @@ -393,6 +393,8 @@ impl ItemStack { } } + /// Returns the maximum amount of items that can be inserted into this itemstack without going + /// over the maximum stack size. pub fn max_quantity_can_be_inserted(&self) -> u16 { self.max_stack_size() - self.quantity } diff --git a/cosmos_server/src/crafting/blocks/basic_fabricator.rs b/cosmos_server/src/crafting/blocks/basic_fabricator.rs index ec363a70..8c0161eb 100644 --- a/cosmos_server/src/crafting/blocks/basic_fabricator.rs +++ b/cosmos_server/src/crafting/blocks/basic_fabricator.rs @@ -126,7 +126,6 @@ fn monitor_craft_event( for input in ev.recipe.inputs.iter() { let item = match input.item { RecipeItem::Item(item_id) => item_id, - RecipeItem::Category(_) => todo!(), }; let item = items.from_numeric_id(item); let (leftover, _) = fab_inv.take_and_remove_item(item, input.quantity as usize * input_multiplier as usize, &mut commands);