diff --git a/src/entities/item/container.rs b/src/entities/item/container.rs index 9c8df04..4c653f8 100644 --- a/src/entities/item/container.rs +++ b/src/entities/item/container.rs @@ -2,15 +2,10 @@ use bevy::prelude::*; #[derive(Component, Debug)] pub struct Container { - // Maximum weight this container can hold pub max_weight: u32, - // Maximum number of items (None = unlimited) pub max_items: Option, - // Current weight of contents pub current_weight: u32, - // List of item entities contained pub contents: Vec, // TODO - move away from Entity - // Whether the container is currently open/accessible pub is_open: bool, } diff --git a/src/entities/item/core.rs b/src/entities/item/core.rs index fef4cbe..ae434a9 100644 --- a/src/entities/item/core.rs +++ b/src/entities/item/core.rs @@ -8,14 +8,10 @@ use crate::entities::item::types::ItemType; #[derive(Component, Debug)] #[require(Transform, Visibility)] pub struct Item { - // How worn/damaged the item is (0-255, where 255 is completely destroyed) pub wear: u8, - // The quality of craftsmanship for the base item pub quality: Quality, - // Time until stains fade (in game ticks/turns), pub stain_time: u16, - // Temperature of the item (for hot/cold items) - pub temperature: i16, // Can be negative for very cold items + pub temperature: i16, // Can be negative for cold items } impl Default for Item { @@ -52,27 +48,19 @@ impl Item { let total_weight = base_weight + decoration_weight; - // Convert to u32 (multiply by 1000 to get grams if density was in kg/unit) - (total_weight * 1000.0) as u32 + // Convert to u32 + (total_weight) as u32 } - // Calculate total value considering all factors pub fn calculate_value( &self, item_type: &ItemType, base_material: &Material, decorations: Option<&ItemDecorations>, ) -> u32 { - // Base value from item type and material let base_value = item_type.base_value() + base_material.base_value(); - - // Apply quality multiplier to base let quality_modified_value = base_value as f32 * self.quality.value_multiplier(); - - // Additional value from decorations let decoration_value = decorations.map(|d| d.total_decoration_value()).unwrap_or(0); - - // Reduce value based on wear let wear_multiplier = (255 - self.wear) as f32 / 255.0; let total_value = (quality_modified_value + decoration_value as f32) * wear_multiplier; @@ -80,33 +68,27 @@ impl Item { total_value as u32 } - // Check if the item is destroyed due to wear pub fn is_destroyed(&self) -> bool { self.wear >= 255 } - // Apply wear to the item pub fn add_wear(&mut self, wear_amount: u8) { self.wear = self.wear.saturating_add(wear_amount); } - // Check if item has any stains pub fn has_stains(&self) -> bool { self.stain_time > 0 } - // Reduce stain time (call this periodically to fade stains) pub fn reduce_stain_time(&mut self, amount: u16) { self.stain_time = self.stain_time.saturating_sub(amount); } - // Add staining to the item pub fn add_stain(&mut self, duration: u16) { self.stain_time = self.stain_time.saturating_add(duration); } } -// Bundle for creating item entities #[derive(Bundle)] pub struct ItemBundle { pub item: Item, @@ -118,12 +100,9 @@ pub struct ItemBundle { pub sprite: Sprite, } -// Component for items that have names (can be generated or custom) #[derive(Component, Debug, Clone)] pub struct ItemName { - // The base name of the item type pub base_name: String, - // Custom name given by player or generated pub custom_name: Option, } @@ -144,25 +123,20 @@ impl ItemName { ) -> String { let mut parts = Vec::new(); - // Quality prefix let quality_name = item.quality.display_name(); if !quality_name.is_empty() { parts.push(quality_name.to_string()); } - // Base material parts.push(base_material.name()); - // Item name parts.push(self.base_name.clone()); let mut result = parts.join(" "); - // Add decorations to the description if let Some(decorations) = decorations { let mut decoration_parts = Vec::new(); - // Gem encrustings for gem in &decorations.gem_encrustings { let quality_prefix = if gem.quality != Quality::Ordinary { format!("{} ", gem.quality.display_name()) @@ -176,7 +150,6 @@ impl ItemName { )); } - // Trim materials for trim in &decorations.trim_materials { let quality_prefix = if trim.quality != Quality::Ordinary { format!("{} ", trim.quality.display_name()) @@ -191,7 +164,6 @@ impl ItemName { decoration_parts.push(format!("with {} trim", trim_name)); } - // Engravings for engraving in &decorations.engravings { let quality_prefix = if engraving.quality != Quality::Ordinary { format!("{} ", engraving.quality.display_name()) @@ -209,7 +181,6 @@ impl ItemName { } } - // Custom name if let Some(custom) = &self.custom_name { result = format!("\"{}\" {}", custom, result); } diff --git a/src/entities/item/decorations.rs b/src/entities/item/decorations.rs index 28a9f8c..79d6187 100644 --- a/src/entities/item/decorations.rs +++ b/src/entities/item/decorations.rs @@ -5,11 +5,8 @@ use crate::entities::item::quality::Quality; #[derive(Component, Debug, Clone)] pub struct ItemDecorations { - // Gems encrusted on the item pub gem_encrustings: Vec, - // Metal trim/bands pub trim_materials: Vec, - // Engravings on the item pub engravings: Vec, } @@ -28,7 +25,6 @@ impl ItemDecorations { Self::default() } - // Calculate total additional weight from decorations pub fn total_decoration_weight(&self) -> f32 { let gem_weight: f32 = self .gem_encrustings @@ -42,11 +38,9 @@ impl ItemDecorations { .map(|trim| trim.material.density() * trim.amount) .sum(); - // Engravings don't add weight, they remove material gem_weight + trim_weight } - // Calculate total additional value from decorations pub fn total_decoration_value(&self) -> u32 { let gem_value: f32 = self .gem_encrustings @@ -97,26 +91,26 @@ impl ItemDecorations { #[derive(Debug, Clone)] pub struct GemEncrusting { pub material: Material, // Should be a gem, but using material to gain access to its wider functions - pub size: f32, // Size of the gem (affects weight and value) - pub quality: Quality, // Quality of the gem cut + pub size: f32, + pub quality: Quality, } #[derive(Debug, Clone)] pub struct TrimMaterial { pub material: Material, // Usually metal for bands/trim - pub amount: f32, // Amount of material used - pub quality: Quality, // Quality of the trim work + pub amount: f32, + pub quality: Quality, } #[derive(Debug, Clone)] pub struct Engraving { - pub subject: String, // What the engraving depicts - pub quality: Quality, // Quality of the engraving + pub subject: String, + pub quality: Quality, } impl Engraving { pub fn base_value(&self) -> f32 { - // Base value for engravings (they're pure craftsmanship) + // Base value for engravings (they're pure craftsmanship so a static value is fine) 20.0 } } diff --git a/src/entities/item/material.rs b/src/entities/item/material.rs index 37a15e1..87568ca 100644 --- a/src/entities/item/material.rs +++ b/src/entities/item/material.rs @@ -17,7 +17,7 @@ pub enum Material { } impl Material { - // Weight per unit volume (arbitrary units - adjust as needed) + // Weight per unit volume (arbitrary units - TODO: Adjust later) pub fn density(&self) -> f32 { match self { Material::NA => 1.0, diff --git a/src/entities/item/perishable.rs b/src/entities/item/perishable.rs index 5bb82c1..3d254c5 100644 --- a/src/entities/item/perishable.rs +++ b/src/entities/item/perishable.rs @@ -6,18 +6,15 @@ use crate::entities::item::Item; #[derive(Component, Debug)] pub struct Perishable { - // How much the item has decayed (0-255) pub decay: u8, - // How fast this item decays per tick pub decay_rate: u8, - // What happens when fully decayed pub decay_result: DecayResult, } #[derive(Debug, Clone)] pub enum DecayResult { Disappear, - Transform(ItemType, Material), // Transform into another item type with different material + Transform(ItemType, Material), // Transform into another item type with different material (fish -> rotten fish) } pub fn decay_system( @@ -26,18 +23,14 @@ pub fn decay_system( mut commands: Commands, ) { for (entity, mut perishable, item, item_type, base_material) in perishable_items.iter_mut() { - // Simple decay - you might want to make this more sophisticated if time.elapsed_secs_f64() as u32 % 60 == 0 { - // Decay every 60 seconds perishable.decay = perishable.decay.saturating_add(perishable.decay_rate); - if perishable.decay >= 255 { match &perishable.decay_result { DecayResult::Disappear => { commands.entity(entity).despawn(); } DecayResult::Transform(new_item_type, new_material) => { - // Transform the item commands .entity(entity) .insert(new_item_type.clone()) diff --git a/src/entities/item/prefabs/misc/misc_prefabs.rs b/src/entities/item/prefabs/misc/misc_prefabs.rs index 7ec7840..de76d34 100644 --- a/src/entities/item/prefabs/misc/misc_prefabs.rs +++ b/src/entities/item/prefabs/misc/misc_prefabs.rs @@ -1,9 +1,9 @@ use bevy::prelude::*; use crate::entities::item::{Item, ItemBundle, ItemDecorations, ItemType, Material, Quality}; +use crate::world::tiles::tilemap; use crate::world::VisibleGameEntity; -// Enum for misc item prefabs #[derive(Debug, Clone, Copy)] pub enum MiscPrefab { RawMeat, @@ -12,11 +12,13 @@ pub enum MiscPrefab { // Spawns a misc prefab at a given position. // These are all likely temporary to speed up development but will be replaced by semi-custom items everywhere. +// As well as acting as demonstration of how to spawn items for the future. pub fn spawn_prefab( commands: &mut Commands, asset_server: &Res, prefab: MiscPrefab, position: Vec3, + tilemap: &mut ResMut, ) -> Entity { match prefab { MiscPrefab::RawMeat => { @@ -37,7 +39,16 @@ pub fn spawn_prefab( }, }) .id(); - commands.entity(meat).insert(VisibleGameEntity).id() + let mut items = tilemap + .item_tiles + .get(&position.as_ivec3()) + .unwrap_or(&Vec::new()) + .clone(); + items.push(meat.index()); + tilemap + .item_tiles + .insert(position.as_ivec3(), items.clone()); + return commands.entity(meat).insert(VisibleGameEntity).id(); } MiscPrefab::Coin => { let coin = commands @@ -57,6 +68,15 @@ pub fn spawn_prefab( }, }) .id(); + let mut items = tilemap + .item_tiles + .get(&position.as_ivec3()) + .unwrap_or(&Vec::new()) + .clone(); + items.push(coin.index()); + tilemap + .item_tiles + .insert(position.as_ivec3(), items.clone()); commands.entity(coin).insert(VisibleGameEntity).id() } } diff --git a/src/entities/item/quality.rs b/src/entities/item/quality.rs index b7a5bd0..d2f32d0 100644 --- a/src/entities/item/quality.rs +++ b/src/entities/item/quality.rs @@ -9,7 +9,7 @@ pub enum Quality { Superior = 3, Exceptional = 4, Masterwork = 5, - // Special artifact quality + // Special artifact quality (created through moments of genius or madness) Artifact = 10, } diff --git a/src/entities/item/systems.rs b/src/entities/item/systems.rs index 044bee5..698789e 100644 --- a/src/entities/item/systems.rs +++ b/src/entities/item/systems.rs @@ -8,9 +8,7 @@ use crate::entities::item::Item; use crate::entities::item::ItemBundle; use crate::entities::item::ItemName; -// System to reduce stain time over time pub fn stain_fade_system(time: Res