example item
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 110 B |
Binary file not shown.
|
After Width: | Height: | Size: 270 B |
@@ -0,0 +1,54 @@
|
|||||||
|
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<u32>,
|
||||||
|
// Current weight of contents
|
||||||
|
pub current_weight: u32,
|
||||||
|
// List of item entities contained
|
||||||
|
pub contents: Vec<Entity>, // TODO - move away from Entity
|
||||||
|
// Whether the container is currently open/accessible
|
||||||
|
pub is_open: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Container {
|
||||||
|
pub fn new(max_weight: u32, max_items: Option<u32>) -> Self {
|
||||||
|
Self {
|
||||||
|
max_weight,
|
||||||
|
max_items,
|
||||||
|
current_weight: 0,
|
||||||
|
contents: Vec::new(),
|
||||||
|
is_open: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_fit(&self, weight: u32) -> bool {
|
||||||
|
self.current_weight + weight <= self.max_weight
|
||||||
|
&& self
|
||||||
|
.max_items
|
||||||
|
.map_or(true, |max| self.contents.len() < max as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_item(&mut self, item_entity: Entity, weight: u32) -> bool {
|
||||||
|
if self.can_fit(weight) {
|
||||||
|
self.contents.push(item_entity);
|
||||||
|
self.current_weight += weight;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_item(&mut self, item_entity: Entity, weight: u32) -> bool {
|
||||||
|
if let Some(pos) = self.contents.iter().position(|&e| e == item_entity) {
|
||||||
|
self.contents.remove(pos);
|
||||||
|
self.current_weight = self.current_weight.saturating_sub(weight);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::item::decorations::ItemDecorations;
|
||||||
|
use crate::entities::item::material::Material;
|
||||||
|
use crate::entities::item::quality::Quality;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Item {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
wear: 0,
|
||||||
|
quality: Quality::default(),
|
||||||
|
stain_time: 0,
|
||||||
|
temperature: 20, // Room temperature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Item {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate weight based on materials and decorations
|
||||||
|
pub fn calculate_weight(
|
||||||
|
&self,
|
||||||
|
item_type: &ItemType,
|
||||||
|
base_material: &Material,
|
||||||
|
decorations: Option<&ItemDecorations>,
|
||||||
|
) -> u32 {
|
||||||
|
// Base weight from primary material
|
||||||
|
let base_volume = item_type.base_volume();
|
||||||
|
let base_weight = base_material.density() * base_volume;
|
||||||
|
|
||||||
|
// Additional weight from decorations
|
||||||
|
let decoration_weight = decorations
|
||||||
|
.map(|d| d.total_decoration_weight())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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,
|
||||||
|
pub item_type: ItemType,
|
||||||
|
pub base_material: Material,
|
||||||
|
pub decorations: ItemDecorations,
|
||||||
|
pub transform: Transform,
|
||||||
|
pub visibility: Visibility,
|
||||||
|
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<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemName {
|
||||||
|
pub fn new(base_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
base_name,
|
||||||
|
custom_name: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate full display name including materials and decorations
|
||||||
|
pub fn display_name(
|
||||||
|
&self,
|
||||||
|
item: &Item,
|
||||||
|
base_material: &Material,
|
||||||
|
decorations: Option<&ItemDecorations>,
|
||||||
|
) -> 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())
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
decoration_parts.push(format!(
|
||||||
|
"encrusted with {}{}",
|
||||||
|
quality_prefix,
|
||||||
|
gem.material.name()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim materials
|
||||||
|
for trim in &decorations.trim_materials {
|
||||||
|
let quality_prefix = if trim.quality != Quality::Ordinary {
|
||||||
|
format!("{} ", trim.quality.display_name())
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
let trim_name = if quality_prefix.is_empty() {
|
||||||
|
trim.material.name()
|
||||||
|
} else {
|
||||||
|
format!("{} {}", quality_prefix, trim.material.name())
|
||||||
|
};
|
||||||
|
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())
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
decoration_parts.push(format!(
|
||||||
|
"engraved with {}images of {}",
|
||||||
|
quality_prefix, engraving.subject
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !decoration_parts.is_empty() {
|
||||||
|
result = format!("{}, {}", result, decoration_parts.join(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom name
|
||||||
|
if let Some(custom) = &self.custom_name {
|
||||||
|
result = format!("\"{}\" {}", custom, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::item::material::Material;
|
||||||
|
use crate::entities::item::quality::Quality;
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Clone)]
|
||||||
|
pub struct ItemDecorations {
|
||||||
|
// Gems encrusted on the item
|
||||||
|
pub gem_encrustings: Vec<GemEncrusting>,
|
||||||
|
// Metal trim/bands
|
||||||
|
pub trim_materials: Vec<TrimMaterial>,
|
||||||
|
// Engravings on the item
|
||||||
|
pub engravings: Vec<Engraving>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ItemDecorations {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
gem_encrustings: Vec::new(),
|
||||||
|
trim_materials: Vec::new(),
|
||||||
|
engravings: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemDecorations {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate total additional weight from decorations
|
||||||
|
pub fn total_decoration_weight(&self) -> f32 {
|
||||||
|
let gem_weight: f32 = self
|
||||||
|
.gem_encrustings
|
||||||
|
.iter()
|
||||||
|
.map(|gem| gem.material.density() * gem.size)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
let trim_weight: f32 = self
|
||||||
|
.trim_materials
|
||||||
|
.iter()
|
||||||
|
.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
|
||||||
|
.iter()
|
||||||
|
.map(|gem| gem.material.base_value() as f32 * gem.size * gem.quality.value_multiplier())
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
let trim_value: f32 = self
|
||||||
|
.trim_materials
|
||||||
|
.iter()
|
||||||
|
.map(|trim| {
|
||||||
|
trim.material.base_value() as f32 * trim.amount * trim.quality.value_multiplier()
|
||||||
|
})
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
let engraving_value: f32 = self
|
||||||
|
.engravings
|
||||||
|
.iter()
|
||||||
|
.map(|engraving| engraving.base_value() * engraving.quality.value_multiplier())
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
(gem_value + trim_value + engraving_value) as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_gem_encrusting(&mut self, material: Material, size: f32, quality: Quality) {
|
||||||
|
if let Material::Gem(_) = material {
|
||||||
|
self.gem_encrustings.push(GemEncrusting {
|
||||||
|
material,
|
||||||
|
size,
|
||||||
|
quality,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_trim(&mut self, material: Material, amount: f32, quality: Quality) {
|
||||||
|
self.trim_materials.push(TrimMaterial {
|
||||||
|
material,
|
||||||
|
amount,
|
||||||
|
quality,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_engraving(&mut self, subject: String, quality: Quality) {
|
||||||
|
self.engravings.push(Engraving { subject, quality });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Engraving {
|
||||||
|
pub subject: String, // What the engraving depicts
|
||||||
|
pub quality: Quality, // Quality of the engraving
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Engraving {
|
||||||
|
pub fn base_value(&self) -> f32 {
|
||||||
|
// Base value for engravings (they're pure craftsmanship)
|
||||||
|
20.0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum Material {
|
||||||
|
NA,
|
||||||
|
Wood(WoodType),
|
||||||
|
Stone(StoneType),
|
||||||
|
Metal(MetalType),
|
||||||
|
Cloth(ClothType),
|
||||||
|
Leather(LeatherType),
|
||||||
|
Bone,
|
||||||
|
Shell,
|
||||||
|
Glass,
|
||||||
|
Ceramic,
|
||||||
|
Gem(GemType),
|
||||||
|
Wax,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Material {
|
||||||
|
// Weight per unit volume (arbitrary units - adjust as needed)
|
||||||
|
pub fn density(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
Material::NA => 1.0,
|
||||||
|
Material::Wood(wood) => match wood {
|
||||||
|
WoodType::Oak => 0.7,
|
||||||
|
WoodType::Pine => 0.5,
|
||||||
|
WoodType::Birch => 0.6,
|
||||||
|
WoodType::Ironwood => 1.2,
|
||||||
|
},
|
||||||
|
Material::Stone(stone) => match stone {
|
||||||
|
StoneType::Granite => 2.7,
|
||||||
|
StoneType::Marble => 2.6,
|
||||||
|
StoneType::Sandstone => 2.2,
|
||||||
|
StoneType::Obsidian => 2.4,
|
||||||
|
},
|
||||||
|
Material::Metal(metal) => match metal {
|
||||||
|
MetalType::Iron => 7.9,
|
||||||
|
MetalType::Steel => 7.8,
|
||||||
|
MetalType::Copper => 8.9,
|
||||||
|
MetalType::Silver => 10.5,
|
||||||
|
MetalType::Gold => 19.3,
|
||||||
|
MetalType::Platinum => 21.5,
|
||||||
|
},
|
||||||
|
Material::Cloth(_) => 0.3,
|
||||||
|
Material::Leather(_) => 0.8,
|
||||||
|
Material::Bone => 1.8,
|
||||||
|
Material::Shell => 2.0,
|
||||||
|
Material::Glass => 2.5,
|
||||||
|
Material::Ceramic => 2.3,
|
||||||
|
Material::Gem(gem) => match gem {
|
||||||
|
GemType::Diamond => 3.5,
|
||||||
|
GemType::Ruby => 4.0,
|
||||||
|
GemType::Emerald => 2.7,
|
||||||
|
GemType::Sapphire => 4.0,
|
||||||
|
},
|
||||||
|
Material::Wax => 0.1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base value per unit (before quality modifiers)
|
||||||
|
pub fn base_value(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
Material::NA => 1,
|
||||||
|
Material::Wood(_) => 1,
|
||||||
|
Material::Stone(_) => 2,
|
||||||
|
Material::Metal(metal) => match metal {
|
||||||
|
MetalType::Iron => 5,
|
||||||
|
MetalType::Steel => 8,
|
||||||
|
MetalType::Copper => 3,
|
||||||
|
MetalType::Silver => 15,
|
||||||
|
MetalType::Gold => 30,
|
||||||
|
MetalType::Platinum => 40,
|
||||||
|
},
|
||||||
|
Material::Cloth(_) => 2,
|
||||||
|
Material::Leather(_) => 3,
|
||||||
|
Material::Bone => 1,
|
||||||
|
Material::Shell => 2,
|
||||||
|
Material::Glass => 4,
|
||||||
|
Material::Ceramic => 3,
|
||||||
|
Material::Gem(gem) => match gem {
|
||||||
|
GemType::Diamond => 200,
|
||||||
|
GemType::Ruby => 150,
|
||||||
|
GemType::Emerald => 100,
|
||||||
|
GemType::Sapphire => 120,
|
||||||
|
},
|
||||||
|
Material::Wax => 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Material::NA => "N/A".to_string(),
|
||||||
|
Material::Wood(wood) => format!("{:?}", wood).to_lowercase(),
|
||||||
|
Material::Stone(stone) => format!("{:?}", stone).to_lowercase(),
|
||||||
|
Material::Metal(metal) => format!("{:?}", metal).to_lowercase(),
|
||||||
|
Material::Cloth(cloth) => format!("{:?}", cloth).to_lowercase(),
|
||||||
|
Material::Leather(leather) => {
|
||||||
|
format!("{} leather", format!("{:?}", leather).to_lowercase())
|
||||||
|
}
|
||||||
|
Material::Bone => "bone".to_string(),
|
||||||
|
Material::Shell => "shell".to_string(),
|
||||||
|
Material::Glass => "glass".to_string(),
|
||||||
|
Material::Ceramic => "ceramic".to_string(),
|
||||||
|
Material::Gem(gem) => format!("{:?}", gem).to_lowercase(),
|
||||||
|
Material::Wax => "wax".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum WoodType {
|
||||||
|
Oak,
|
||||||
|
Pine,
|
||||||
|
Birch,
|
||||||
|
Ironwood,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum StoneType {
|
||||||
|
Granite,
|
||||||
|
Marble,
|
||||||
|
Sandstone,
|
||||||
|
Obsidian,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum MetalType {
|
||||||
|
Iron,
|
||||||
|
Steel,
|
||||||
|
Copper,
|
||||||
|
Silver,
|
||||||
|
Gold,
|
||||||
|
Platinum,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ClothType {
|
||||||
|
Cotton,
|
||||||
|
Silk,
|
||||||
|
Wool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum LeatherType {
|
||||||
|
Cow,
|
||||||
|
Pig,
|
||||||
|
Dragon,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum GemType {
|
||||||
|
Diamond,
|
||||||
|
Ruby,
|
||||||
|
Emerald,
|
||||||
|
Sapphire,
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
pub mod container;
|
||||||
|
pub mod core;
|
||||||
|
pub mod decorations;
|
||||||
|
pub mod material;
|
||||||
|
pub mod perishable;
|
||||||
|
pub mod prefabs;
|
||||||
|
pub mod quality;
|
||||||
|
pub mod systems;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
|
pub use container::*;
|
||||||
|
pub use core::*;
|
||||||
|
pub use decorations::*;
|
||||||
|
pub use material::*;
|
||||||
|
pub use perishable::*;
|
||||||
|
pub use prefabs::*;
|
||||||
|
pub use quality::*;
|
||||||
|
pub use systems::*;
|
||||||
|
pub use types::*;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::item::material::Material;
|
||||||
|
use crate::entities::item::types::ItemType;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decay_system(
|
||||||
|
time: Res<Time>,
|
||||||
|
mut perishable_items: Query<(Entity, &mut Perishable, &Item, &ItemType, &Material)>,
|
||||||
|
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())
|
||||||
|
.insert(new_material.clone())
|
||||||
|
.remove::<Perishable>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::item::{Item, ItemBundle, ItemDecorations, ItemType, Material, Quality};
|
||||||
|
use crate::world::VisibleGameEntity;
|
||||||
|
|
||||||
|
// Enum for misc item prefabs
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum MiscPrefab {
|
||||||
|
RawMeat,
|
||||||
|
Coin,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
pub fn spawn_prefab(
|
||||||
|
commands: &mut Commands,
|
||||||
|
asset_server: &Res<AssetServer>,
|
||||||
|
prefab: MiscPrefab,
|
||||||
|
position: Vec3,
|
||||||
|
) -> Entity {
|
||||||
|
match prefab {
|
||||||
|
MiscPrefab::RawMeat => {
|
||||||
|
let meat = commands
|
||||||
|
.spawn(ItemBundle {
|
||||||
|
item: Item {
|
||||||
|
quality: Quality::Ordinary,
|
||||||
|
..Item::default()
|
||||||
|
},
|
||||||
|
item_type: ItemType::Food(crate::entities::item::FoodType::Meat),
|
||||||
|
base_material: Material::NA,
|
||||||
|
decorations: ItemDecorations::new(),
|
||||||
|
transform: Transform::from_translation(position - Vec3::new(0.0, 0.0, 0.1)),
|
||||||
|
visibility: Visibility::Visible,
|
||||||
|
sprite: Sprite {
|
||||||
|
image: asset_server.load("raw_meat.png"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.id();
|
||||||
|
commands.entity(meat).insert(VisibleGameEntity).id()
|
||||||
|
}
|
||||||
|
MiscPrefab::Coin => {
|
||||||
|
let coin = commands
|
||||||
|
.spawn(ItemBundle {
|
||||||
|
item: Item {
|
||||||
|
quality: Quality::Ordinary,
|
||||||
|
..Item::default()
|
||||||
|
},
|
||||||
|
item_type: ItemType::Coin,
|
||||||
|
base_material: Material::Metal(crate::entities::item::MetalType::Copper),
|
||||||
|
decorations: ItemDecorations::new(),
|
||||||
|
transform: Transform::from_translation(position - Vec3::new(0.0, 0.0, 0.1)),
|
||||||
|
visibility: Visibility::Visible,
|
||||||
|
sprite: Sprite {
|
||||||
|
image: asset_server.load("coin.png"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.id();
|
||||||
|
commands.entity(coin).insert(VisibleGameEntity).id()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod misc_prefabs;
|
||||||
|
|
||||||
|
pub use misc_prefabs::*;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod misc; // miscellaneous items (raw meat, coins, etc.)
|
||||||
|
|
||||||
|
pub use misc::*; // re-export misc prefabs for easier access
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum Quality {
|
||||||
|
// Standard qualities
|
||||||
|
Ordinary = 0,
|
||||||
|
WellCrafted = 1,
|
||||||
|
FinelyCrafted = 2,
|
||||||
|
Superior = 3,
|
||||||
|
Exceptional = 4,
|
||||||
|
Masterwork = 5,
|
||||||
|
// Special artifact quality
|
||||||
|
Artifact = 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Quality {
|
||||||
|
pub fn value_multiplier(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
Quality::Ordinary => 1.0,
|
||||||
|
Quality::WellCrafted => 1.2,
|
||||||
|
Quality::FinelyCrafted => 1.5,
|
||||||
|
Quality::Superior => 2.0,
|
||||||
|
Quality::Exceptional => 3.0,
|
||||||
|
Quality::Masterwork => 5.0,
|
||||||
|
Quality::Artifact => 10.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display_name(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Quality::Ordinary => "",
|
||||||
|
Quality::WellCrafted => "well-crafted",
|
||||||
|
Quality::FinelyCrafted => "finely-crafted",
|
||||||
|
Quality::Superior => "superior",
|
||||||
|
Quality::Exceptional => "exceptional",
|
||||||
|
Quality::Masterwork => "masterwork",
|
||||||
|
Quality::Artifact => "artifact",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Quality {
|
||||||
|
fn default() -> Self {
|
||||||
|
Quality::Ordinary
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::item::decorations::ItemDecorations;
|
||||||
|
use crate::entities::item::material::{GemType, Material, MetalType};
|
||||||
|
use crate::entities::item::quality::Quality;
|
||||||
|
use crate::entities::item::types::ItemType;
|
||||||
|
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<Time>, mut items: Query<&mut Item>) {
|
||||||
|
// Fade stains every 10 seconds
|
||||||
|
if time.elapsed_secs_f64() as u32 % 10 == 0 {
|
||||||
|
for mut item in items.iter_mut() {
|
||||||
|
item.reduce_stain_time(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to create a decorated item
|
||||||
|
pub fn create_decorated_item(
|
||||||
|
commands: &mut Commands,
|
||||||
|
item_type: ItemType,
|
||||||
|
base_material: Material,
|
||||||
|
quality: Quality,
|
||||||
|
position: Vec3,
|
||||||
|
sprite: Sprite,
|
||||||
|
) -> Entity {
|
||||||
|
let mut decorations = ItemDecorations::new();
|
||||||
|
|
||||||
|
// Example: Add a ruby encrusting to valuable items
|
||||||
|
if quality >= Quality::Superior {
|
||||||
|
decorations.add_gem_encrusting(
|
||||||
|
Material::Gem(GemType::Ruby),
|
||||||
|
0.5, // Small gem
|
||||||
|
Quality::WellCrafted,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example: Add silver trim to masterwork items
|
||||||
|
if quality >= Quality::Masterwork {
|
||||||
|
decorations.add_trim(
|
||||||
|
Material::Metal(MetalType::Silver),
|
||||||
|
0.2, // Small amount of trim
|
||||||
|
quality,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example: Add engraving to exceptional+ items
|
||||||
|
if quality >= Quality::Exceptional {
|
||||||
|
decorations.add_engraving("a majestic dorf holding a pickaxe".to_string(), quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
commands
|
||||||
|
.spawn(ItemBundle {
|
||||||
|
item: Item {
|
||||||
|
quality,
|
||||||
|
..Item::default()
|
||||||
|
},
|
||||||
|
item_type: item_type.clone(),
|
||||||
|
base_material,
|
||||||
|
decorations,
|
||||||
|
transform: Transform::from_translation(position),
|
||||||
|
visibility: Visibility::Visible,
|
||||||
|
sprite: sprite,
|
||||||
|
})
|
||||||
|
.insert(ItemName::new(item_type.name()))
|
||||||
|
.id()
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ItemType {
|
||||||
|
// Weapons
|
||||||
|
Weapon(WeaponType),
|
||||||
|
// Armor/Clothing
|
||||||
|
Armor(ArmorType),
|
||||||
|
// Tools
|
||||||
|
Tool(ToolType),
|
||||||
|
// Consumables
|
||||||
|
Food(FoodType),
|
||||||
|
Drink(DrinkType),
|
||||||
|
Medicine,
|
||||||
|
// Crafting materials
|
||||||
|
RawMaterial,
|
||||||
|
// Trade goods
|
||||||
|
Gem,
|
||||||
|
Coin,
|
||||||
|
// Misc
|
||||||
|
Container,
|
||||||
|
Book,
|
||||||
|
Toy,
|
||||||
|
Decoration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemType {
|
||||||
|
// Base volume for this item type (used for weight calculation)
|
||||||
|
pub fn base_volume(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
ItemType::Weapon(weapon) => match weapon {
|
||||||
|
WeaponType::Sword => 2.0,
|
||||||
|
WeaponType::Axe => 1.5,
|
||||||
|
WeaponType::Hammer => 3.0,
|
||||||
|
WeaponType::Spear => 1.8,
|
||||||
|
WeaponType::Bow => 0.8,
|
||||||
|
WeaponType::Crossbow => 2.5,
|
||||||
|
WeaponType::Dagger => 0.3,
|
||||||
|
},
|
||||||
|
ItemType::Armor(armor) => match armor {
|
||||||
|
ArmorType::Helmet => 1.0,
|
||||||
|
ArmorType::Chestplate => 4.0,
|
||||||
|
ArmorType::Leggings => 2.5,
|
||||||
|
ArmorType::Boots => 0.8,
|
||||||
|
ArmorType::Gloves => 0.4,
|
||||||
|
ArmorType::Shield => 2.0,
|
||||||
|
ArmorType::Cloak => 0.5,
|
||||||
|
ArmorType::Shirt => 0.3,
|
||||||
|
ArmorType::Pants => 0.4,
|
||||||
|
},
|
||||||
|
ItemType::Tool(tool) => match tool {
|
||||||
|
ToolType::Pickaxe => 2.0,
|
||||||
|
ToolType::Shovel => 1.5,
|
||||||
|
ToolType::Axe => 1.75,
|
||||||
|
ToolType::Hammer => 1.0,
|
||||||
|
ToolType::Anvil => 50.0, // Heavy!
|
||||||
|
ToolType::Furnace => 100.0, // Very heavy!
|
||||||
|
},
|
||||||
|
ItemType::Food(_) => 0.2,
|
||||||
|
ItemType::Drink(_) => 0.3,
|
||||||
|
ItemType::Medicine => 0.1,
|
||||||
|
ItemType::RawMaterial => 0.5,
|
||||||
|
ItemType::Gem => 0.1,
|
||||||
|
ItemType::Coin => 0.01,
|
||||||
|
ItemType::Container => 1.0,
|
||||||
|
ItemType::Book => 0.5,
|
||||||
|
ItemType::Toy => 0.2,
|
||||||
|
ItemType::Decoration => 0.3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base value for this item type
|
||||||
|
pub fn base_value(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
ItemType::Weapon(_) => 50,
|
||||||
|
ItemType::Armor(_) => 30,
|
||||||
|
ItemType::Tool(_) => 25,
|
||||||
|
ItemType::Food(_) => 2,
|
||||||
|
ItemType::Drink(_) => 3,
|
||||||
|
ItemType::Medicine => 10,
|
||||||
|
ItemType::RawMaterial => 1,
|
||||||
|
ItemType::Gem => 100,
|
||||||
|
ItemType::Coin => 1,
|
||||||
|
ItemType::Container => 15,
|
||||||
|
ItemType::Book => 20,
|
||||||
|
ItemType::Toy => 5,
|
||||||
|
ItemType::Decoration => 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
match self {
|
||||||
|
ItemType::Weapon(weapon) => format!("{:?}", weapon).to_lowercase(),
|
||||||
|
ItemType::Armor(armor) => format!("{:?}", armor).to_lowercase(),
|
||||||
|
ItemType::Tool(tool) => format!("{:?}", tool).to_lowercase(),
|
||||||
|
ItemType::Food(food) => format!("{:?}", food).to_lowercase(),
|
||||||
|
ItemType::Drink(drink) => format!("{:?}", drink).to_lowercase(),
|
||||||
|
ItemType::Medicine => "medicine".to_string(),
|
||||||
|
ItemType::RawMaterial => "raw material".to_string(),
|
||||||
|
ItemType::Gem => "gem".to_string(),
|
||||||
|
ItemType::Coin => "coin".to_string(),
|
||||||
|
ItemType::Container => "container".to_string(),
|
||||||
|
ItemType::Book => "book".to_string(),
|
||||||
|
ItemType::Toy => "toy".to_string(),
|
||||||
|
ItemType::Decoration => "decoration".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum WeaponType {
|
||||||
|
Sword,
|
||||||
|
Axe,
|
||||||
|
Hammer,
|
||||||
|
Spear,
|
||||||
|
Bow,
|
||||||
|
Crossbow,
|
||||||
|
Dagger,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ArmorType {
|
||||||
|
Helmet,
|
||||||
|
Chestplate,
|
||||||
|
Leggings,
|
||||||
|
Boots,
|
||||||
|
Gloves,
|
||||||
|
Shield,
|
||||||
|
Cloak,
|
||||||
|
Shirt,
|
||||||
|
Pants,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ToolType {
|
||||||
|
Pickaxe,
|
||||||
|
Shovel,
|
||||||
|
Axe,
|
||||||
|
Hammer,
|
||||||
|
Anvil,
|
||||||
|
Furnace,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum FoodType {
|
||||||
|
Meat,
|
||||||
|
Vegetable,
|
||||||
|
Fruit,
|
||||||
|
Grain,
|
||||||
|
Prepared, // cooked meals
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum DrinkType {
|
||||||
|
Water,
|
||||||
|
Juice,
|
||||||
|
Ale,
|
||||||
|
Wine,
|
||||||
|
Spirits,
|
||||||
|
}
|
||||||
@@ -1,17 +1,24 @@
|
|||||||
use crate::constants::TILE_SIZE;
|
use crate::constants::TILE_SIZE;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
|
use crate::entities::item::{
|
||||||
|
create_decorated_item, spawn_prefab, FoodType, Item, ItemBundle, ItemDecorations, ItemType,
|
||||||
|
Material, MiscPrefab, Quality, WoodType,
|
||||||
|
};
|
||||||
use crate::entities::shared_components::Ambulatory;
|
use crate::entities::shared_components::Ambulatory;
|
||||||
use crate::world::VisibleGameEntity;
|
use crate::world::VisibleGameEntity;
|
||||||
|
use bevy::ecs::spawn;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rand::prelude::*;
|
use bevy_rand::prelude::*;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
|
// Pig bundle
|
||||||
#[derive(Bundle)]
|
#[derive(Bundle)]
|
||||||
pub struct Pig {
|
pub struct Pig {
|
||||||
ambulatory: Ambulatory,
|
ambulatory: Ambulatory,
|
||||||
sprite: Sprite,
|
sprite: Sprite,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
|
drop_timer: PigDropTimer, // NEW
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pig {
|
impl Pig {
|
||||||
@@ -31,19 +38,24 @@ impl Pig {
|
|||||||
},
|
},
|
||||||
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
|
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
|
||||||
visibility: Visibility::Hidden,
|
visibility: Visibility::Hidden,
|
||||||
|
drop_timer: PigDropTimer(Timer::from_seconds(5.0, TimerMode::Repeating)), // NEW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Timer component for pigs dropping items
|
||||||
|
#[derive(Component, Deref, DerefMut)]
|
||||||
|
pub struct PigDropTimer(pub Timer);
|
||||||
|
|
||||||
|
// Spawn a handful of pigs
|
||||||
pub fn spawn_pigs(
|
pub fn spawn_pigs(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut rng_q: Query<&mut Entropy<WyRand>, With<Global>>,
|
mut rng_q: Query<&mut Entropy<WyRand>, With<Global>>,
|
||||||
) {
|
) {
|
||||||
if let Ok(mut rng) = rng_q.single_mut() {
|
if let Ok(mut rng) = rng_q.single_mut() {
|
||||||
// Spawn a handful of pigs
|
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
let cit = commands
|
let pig = commands
|
||||||
.spawn(Pig::new(
|
.spawn(Pig::new(
|
||||||
&asset_server,
|
&asset_server,
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
@@ -53,7 +65,29 @@ pub fn spawn_pigs(
|
|||||||
) * TILE_SIZE,
|
) * TILE_SIZE,
|
||||||
))
|
))
|
||||||
.id();
|
.id();
|
||||||
commands.entity(cit).insert(VisibleGameEntity);
|
commands.entity(pig).insert(VisibleGameEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// System: make pigs drop items every 5 seconds
|
||||||
|
pub fn pig_drop_system(
|
||||||
|
mut commands: Commands,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
time: Res<Time>,
|
||||||
|
mut pigs: Query<(&mut PigDropTimer, &Transform)>,
|
||||||
|
) {
|
||||||
|
for (mut timer, transform) in &mut pigs {
|
||||||
|
timer.tick(time.delta());
|
||||||
|
|
||||||
|
if timer.just_finished() {
|
||||||
|
// Example: pig drops raw meat
|
||||||
|
spawn_prefab(
|
||||||
|
&mut commands,
|
||||||
|
&asset_server,
|
||||||
|
MiscPrefab::RawMeat,
|
||||||
|
transform.translation,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ pub fn spawn_rabbits(
|
|||||||
if let Ok(mut rng) = rng_q.single_mut() {
|
if let Ok(mut rng) = rng_q.single_mut() {
|
||||||
// Spawn a handful of rabbits
|
// Spawn a handful of rabbits
|
||||||
for _ in 0..15 {
|
for _ in 0..15 {
|
||||||
let cit = commands
|
let rab = commands
|
||||||
.spawn(Rabbit::new(
|
.spawn(Rabbit::new(
|
||||||
&asset_server,
|
&asset_server,
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
@@ -53,7 +53,7 @@ pub fn spawn_rabbits(
|
|||||||
) * TILE_SIZE,
|
) * TILE_SIZE,
|
||||||
))
|
))
|
||||||
.id();
|
.id();
|
||||||
commands.entity(cit).insert(VisibleGameEntity);
|
commands.entity(rab).insert(VisibleGameEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod item;
|
||||||
pub mod livestock;
|
pub mod livestock;
|
||||||
pub mod sentient;
|
pub mod sentient;
|
||||||
pub mod shared_components;
|
pub mod shared_components;
|
||||||
|
|||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
#[require(Sprite, Transform, Visibility)]
|
|
||||||
pub struct Item {
|
|
||||||
wear: u8,
|
|
||||||
quality: u8,
|
|
||||||
weight: u8,
|
|
||||||
stain_time: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Item {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
wear: 0,
|
|
||||||
quality: 0,
|
|
||||||
weight: 0,
|
|
||||||
stain_time: 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Item {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Bundle)]
|
|
||||||
pub struct ItemBundle {
|
|
||||||
pub item: Item,
|
|
||||||
pub transform: Transform,
|
|
||||||
pub sprite: Sprite,
|
|
||||||
pub visibility: Visibility,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Nameable {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct Decaying {
|
|
||||||
decay: u8,
|
|
||||||
}
|
|
||||||
+3
-1
@@ -1,12 +1,13 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rand::prelude::*;
|
use bevy_rand::prelude::*;
|
||||||
|
|
||||||
|
use crate::entities::livestock::pig::pig_drop_system;
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod entities;
|
mod entities;
|
||||||
mod game;
|
mod game;
|
||||||
mod item;
|
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -54,5 +55,6 @@ fn main() {
|
|||||||
cursor::move_cursor,
|
cursor::move_cursor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.add_systems(Update, pig_drop_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user