From ab67e3246f72fbfa423c14a0a8b494892010fe6a Mon Sep 17 00:00:00 2001 From: ryankopf Date: Fri, 18 Aug 2023 14:48:31 -0500 Subject: [PATCH] Working towards item generation and construction --- src/components.rs | 144 +++++++++++++-------------- src/initializations/biome.rs | 4 +- src/initializations/startup.rs | 2 +- src/interface/game_ui.rs | 30 ++++-- src/objects.rs | 61 ++++++++++-- src/prelude.rs | 2 +- src/resources.rs | 6 +- src/selection_systems.rs | 7 +- src/task_system/personality.rs | 18 +++- src/task_system/personality/human.rs | 26 +++++ src/task_system/plant.rs | 5 +- src/unitgenerator_system.rs | 6 +- 12 files changed, 203 insertions(+), 108 deletions(-) create mode 100644 src/task_system/personality/human.rs diff --git a/src/components.rs b/src/components.rs index fb0a525..97701be 100644 --- a/src/components.rs +++ b/src/components.rs @@ -570,7 +570,7 @@ pub enum PersonalityTrait { // Traits for People Adventurous, Ambitious, Analytical, Airheaded, Artistic, Brave, Calm, Charismatic, Confident, Cowardly, Creative, Curious, Charitable, Cynical, Dumb, Eccentric, Energetic, Empath, Empathetic, Enthusiastic, - Fearless, Friendly, Greedy, Impulsive, Jinxed, Loyal, Logical, Lucky, Mean, Mischievous, + Fearless, Friendly, Greedy, Human, Impulsive, Jinxed, Loyal, Logical, Lucky, Mean, Mischievous, Nice, Optimistic, Patient, Pessimistic, Rebellious, Reliable, Sensitive, Shy, Smart, Stupid, Technophile, Timid, Tolerant, Trusting, Violent, Weak, Workaholic, Witty, Outgoing, // Traits for Creatures @@ -597,7 +597,7 @@ pub struct GiveMeAName; #[derive(Component)] pub struct Plant { pub growth: f32, - pub plant_type: PlantType, + pub plant_type: ItemType, } impl HoverNote for Plant { fn hover_note(&self) -> String { @@ -615,16 +615,14 @@ pub struct ZoneMarker; #[derive(Component)] pub struct Zone { pub zone_type: ZoneType, - pub plant_type: Option, - pub item_type: Option, + pub item_type: ItemType, } impl Default for Zone { fn default() -> Self { Zone { zone_type: ZoneType::Farm, - plant_type: Some(PlantType::Cabbage), - item_type: None, + item_type: ItemType::Cabbage } } } @@ -637,7 +635,7 @@ pub struct NearestEntity { #[derive(Component, PartialEq, Copy, Clone, Debug)] pub enum ZoneType { - Farm, Pasture, Storage, Fishing, Hospital, Party, Meeting + Farm, Pasture, Storage, Fishing, Hospital, Party, Meeting, Construction } @@ -651,72 +649,72 @@ pub enum Motivation { // Sorted in order of prioritization. Crisis, Rage, Order, Danger, Hunger, Thirst, Tired, Injured, Sick, Bored, Happy, Sad, Angry, Lonely, Love, Fear, Hate, Work, Personality, Meander, Idle } -#[derive(Component, PartialEq, Copy, Clone, Debug)] -pub enum PlantType { - Aloe, - Azalea, - Bush, - Cabbage, - CactusRound, - CactusUp, - Carrot, - CedarTree, - FlowerBush, - PineTree, - OakTree, - ThornBush, - Vine, - Weed, -} - -impl PlantType { - pub fn is_edible(&self) -> bool { - matches!(self, PlantType::Cabbage) - } - pub fn sprite_row_and_col(&self) -> (usize, usize) { - match self { - PlantType::Aloe => (67, 57), - PlantType::Azalea => (67, 57), - PlantType::Bush => (67, 57), - PlantType::Cabbage => (94, 32), - PlantType::CactusRound => (67, 57), - PlantType::CactusUp => (67, 57), - PlantType::Carrot => (94, 31), - PlantType::CedarTree => (13, 15), - PlantType::PineTree => (13, 13), - PlantType::OakTree => (13, 14), - PlantType::ThornBush => (67, 57), - PlantType::FlowerBush => (67, 57), - PlantType::Vine => (67, 57), - PlantType::Weed => (67, 57), - } - } - pub fn sprite_index(&self) -> usize { - let (row, col) = self.sprite_row_and_col(); - row * 64 + col - } - pub fn growth_speed(&self) -> f32 { - match self { - PlantType::Cabbage => 0.001, - _ => 0.01 - } - } - pub fn is_forageable(&self) -> (Option, i32, ForageType) { - match self { - PlantType::Cabbage => (Some(ItemType::Cabbage), 1, ForageType::Once), - PlantType::Carrot => (Some(ItemType::Carrot), 1, ForageType::Once), - _ => (None, 0, ForageType::Once), - } - } - pub fn is_choppable(&self) -> (Option, i32) { - match self { - PlantType::PineTree => (Some(ItemType::PineLog), 1), - PlantType::OakTree => (Some(ItemType::OakLog), 1), - PlantType::CedarTree => (Some(ItemType::CedarLog), 1), - _ => (None, 0), - } - } -} +// #[derive(Component, PartialEq, Copy, Clone, Debug)] +// pub enum PlantType { +// Aloe, +// Azalea, +// Bush, +// Cabbage, +// CactusRound, +// CactusUp, +// Carrot, +// CedarTree, +// FlowerBush, +// PineTree, +// OakTree, +// ThornBush, +// Vine, +// Weed, +// } + +// impl PlantType { +// pub fn is_edible(&self) -> bool { +// matches!(self, PlantType::Cabbage) +// } +// pub fn sprite_row_and_col(&self) -> (usize, usize) { +// match self { +// PlantType::Aloe => (67, 57), +// PlantType::Azalea => (67, 57), +// PlantType::Bush => (67, 57), +// PlantType::Cabbage => (94, 32), +// PlantType::CactusRound => (67, 57), +// PlantType::CactusUp => (67, 57), +// PlantType::Carrot => (94, 31), +// PlantType::CedarTree => (13, 15), +// PlantType::PineTree => (13, 13), +// PlantType::OakTree => (13, 14), +// PlantType::ThornBush => (67, 57), +// PlantType::FlowerBush => (67, 57), +// PlantType::Vine => (67, 57), +// PlantType::Weed => (67, 57), +// } +// } +// pub fn sprite_index(&self) -> usize { +// let (row, col) = self.sprite_row_and_col(); +// row * 64 + col +// } +// pub fn growth_speed(&self) -> f32 { +// match self { +// PlantType::Cabbage => 0.001, +// _ => 0.01 +// } +// } +// pub fn is_forageable(&self) -> (Option, i32, ForageType) { +// match self { +// PlantType::Cabbage => (Some(ItemType::Cabbage), 1, ForageType::Once), +// PlantType::Carrot => (Some(ItemType::Carrot), 1, ForageType::Once), +// _ => (None, 0, ForageType::Once), +// } +// } +// pub fn is_choppable(&self) -> (Option, i32) { +// match self { +// PlantType::PineTree => (Some(ItemType::PineLog), 1), +// PlantType::OakTree => (Some(ItemType::OakLog), 1), +// PlantType::CedarTree => (Some(ItemType::CedarLog), 1), +// _ => (None, 0), +// } +// } +// } #[derive(Component, PartialEq, Copy, Clone, Debug)] pub enum ForageType { diff --git a/src/initializations/biome.rs b/src/initializations/biome.rs index af0d952..17be6fb 100644 --- a/src/initializations/biome.rs +++ b/src/initializations/biome.rs @@ -14,8 +14,8 @@ impl Plugin for BiomePlugin { pub fn starting_biome() -> Biome { Biome { name: "Forest".to_string(), - plants: vec![PlantType::Cabbage, PlantType::Carrot, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, - PlantType::CedarTree, PlantType::ThornBush, PlantType::Weed, PlantType::CactusRound], + plants: vec![ItemType::Cabbage, ItemType::Carrot, ItemType::PineTree, ItemType::PineTree, ItemType::PineTree, ItemType::PineTree, ItemType::PineTree, + ItemType::CedarTree, ItemType::ThornBush, ItemType::Weed, ItemType::CactusRound], plant_scarcity: vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1], plant_overall_scarcity: 10, tiles: vec![TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, diff --git a/src/initializations/startup.rs b/src/initializations/startup.rs index 7c944eb..c943b11 100644 --- a/src/initializations/startup.rs +++ b/src/initializations/startup.rs @@ -89,7 +89,7 @@ pub fn startup( if plant_type.is_forageable().0.is_some() && growth > 0.5 { commands.entity(plant).insert(Foragable); } - if [PlantType::OakTree,PlantType::PineTree].contains(&plant_type) && growth > 0.5 { + if plant_type.is_choppable().0.is_some() && growth > 0.5 { commands.entity(plant).insert(Choppable); } } diff --git a/src/interface/game_ui.rs b/src/interface/game_ui.rs index 0075942..0dadf03 100644 --- a/src/interface/game_ui.rs +++ b/src/interface/game_ui.rs @@ -213,31 +213,49 @@ pub fn game_ui_click( 2 => { dragging.looking_for = SelectableType::Zoning; dragging.zone_type = ZoneType::Farm; - dragging.plant_type = PlantType::Cabbage; + dragging.item_type = ItemType::Cabbage; }, 3 => { dragging.looking_for = SelectableType::Zoning; dragging.zone_type = ZoneType::Farm; - dragging.plant_type = PlantType::PineTree; + dragging.item_type = ItemType::PineTree; }, 4 => { dragging.looking_for = SelectableType::Zoning; dragging.zone_type = ZoneType::Farm; - dragging.plant_type = PlantType::OakTree; + dragging.item_type = ItemType::OakTree; }, 5 => { dragging.looking_for = SelectableType::Zoning; dragging.zone_type = ZoneType::Farm; - dragging.plant_type = PlantType::CedarTree; + dragging.item_type = ItemType::CedarTree; }, _ => { }, } } MenuStates::Zone => { - menu_state.state = MenuStates::Home; + match button_index { + _ => { + dragging.looking_for = SelectableType::Nothing; + menu_state.state = MenuStates::Home; + }, + } } MenuStates::Build => { - menu_state.state = MenuStates::Home; + match button_index { + 1 => { + dragging.looking_for = SelectableType::Unzoning; + }, + 2 => { + dragging.looking_for = SelectableType::Zoning; + dragging.zone_type = ZoneType::Construction; + dragging.item_type = ItemType::WallWood; + }, + _ => { + dragging.looking_for = SelectableType::Nothing; + menu_state.state = MenuStates::Home; + }, + } } MenuStates::Craft => { menu_state.state = MenuStates::Home; diff --git a/src/objects.rs b/src/objects.rs index 493162b..802be79 100644 --- a/src/objects.rs +++ b/src/objects.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use crate::prelude::*; #[derive(Component)] pub struct Object { @@ -20,8 +21,6 @@ enum ItemGroup { #[derive(Component, PartialEq, Copy, Clone, Debug)] pub enum ItemType { - Cabbage, - Carrot, CedarLog, PineLog, OakLog, @@ -80,13 +79,25 @@ pub enum ItemType { LeafyDebris3, LeafyDebris4, WallWood, + Aloe, + Azalea, + Bush, + Cabbage, + CactusRound, + CactusUp, + Carrot, + CedarTree, + FlowerBush, + PineTree, + OakTree, + ThornBush, + Vine, + Weed, } impl ItemType { pub fn sprite_row_and_col(&self) -> (usize, usize) { match self { - ItemType::Cabbage => (94, 33), - ItemType::Carrot => (94, 24), ItemType::CedarLog => (94, 30), ItemType::PineLog => (94, 30), ItemType::OakLog => (94, 30), @@ -145,12 +156,47 @@ impl ItemType { ItemType::LeafyDebris3 => (50, 17), ItemType::LeafyDebris4 => (50, 18), ItemType::WallWood => (16, 3), + ItemType::Aloe => (67, 57), + ItemType::Azalea => (67, 57), + ItemType::Bush => (67, 57), + ItemType::Cabbage => (94, 32), + ItemType::CactusRound => (67, 57), + ItemType::CactusUp => (67, 57), + ItemType::Carrot => (94, 31), + ItemType::CedarTree => (13, 15), + ItemType::PineTree => (13, 13), + ItemType::OakTree => (13, 14), + ItemType::ThornBush => (67, 57), + ItemType::FlowerBush => (67, 57), + ItemType::Vine => (67, 57), + ItemType::Weed => (67, 57), } } pub fn sprite_index(&self) -> usize { let (row, col) = self.sprite_row_and_col(); row * 64 + col } + pub fn growth_speed(&self) -> f32 { + match self { + ItemType::Cabbage => 0.001, + _ => 0.01 + } + } + pub fn is_forageable(&self) -> (Option, i32, ForageType) { + match self { + ItemType::Cabbage => (Some(ItemType::Cabbage), 1, ForageType::Once), + ItemType::Carrot => (Some(ItemType::Carrot), 1, ForageType::Once), + _ => (None, 0, ForageType::Once), + } + } + pub fn is_choppable(&self) -> (Option, i32) { + match self { + ItemType::PineTree => (Some(ItemType::PineLog), 1), + ItemType::OakTree => (Some(ItemType::OakLog), 1), + ItemType::CedarTree => (Some(ItemType::CedarLog), 1), + _ => (None, 0), + } + } pub fn nutrition(&self) -> f32 { match self { ItemType::Cabbage => 10.0, @@ -158,13 +204,6 @@ impl ItemType { _ => 0.0, } } - // pub fn spoilage(&self) -> f32 { - // match self { - // ItemType::Cabbage => 1.0, - // ItemType::Carrot => 1.0, - // _ => 0.0, - // } - // } pub fn spoilage_rate(&self) -> f32 { match self { ItemType::Cabbage => 0.1, diff --git a/src/prelude.rs b/src/prelude.rs index d05ac6f..6f8d041 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -4,7 +4,7 @@ pub use super::components::{ GiveMeAName, HasName, HasNameShown, HighlightBox, Highlighted, HoverNote, InfoPanel, InGameButton, IsName, Logs, MainMenuOverlay, MapTile, MenuStates, MonsterGenerator, Motivation, MoveRandom, MoveTowardsNearestAttackable, MoveTowardsTarget, NearestEntity, Need, Nest, - Order, Pathing, PauseOverlay, PersonalityTrait, PhysicalBody, Plant, PlantType, Position, + Order, Pathing, PauseOverlay, PersonalityTrait, PhysicalBody, Plant, Position, SelectableType, SetNest, Skillset, Skill, SizeXYZ, StrikeType, Targeting, Task, TemporaryVisualElement, TextName, TileType, WorkMarker, WorkTarget, Zone, ZoneMarker, ZoneType, }; diff --git a/src/resources.rs b/src/resources.rs index 228e5d0..6e780c1 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -12,7 +12,7 @@ pub struct SpriteSheet(pub Handle); #[derive(Resource)] pub struct Biome { pub name: String, - pub plants: Vec, + pub plants: Vec, pub plant_scarcity: Vec, pub plant_overall_scarcity: i32, pub tiles: Vec, @@ -27,7 +27,7 @@ pub struct Dragging { pub start_position: Option, pub looking_for: SelectableType, pub zone_type: ZoneType, - pub plant_type: PlantType, + pub item_type: ItemType, } impl Default for Dragging { @@ -37,7 +37,7 @@ impl Default for Dragging { start_position: None, looking_for: SelectableType::Foragable, zone_type: ZoneType::Farm, - plant_type: PlantType::Cabbage, + item_type: ItemType::WallWood, } } } diff --git a/src/selection_systems.rs b/src/selection_systems.rs index abaf0ab..e1ff608 100644 --- a/src/selection_systems.rs +++ b/src/selection_systems.rs @@ -97,7 +97,12 @@ pub fn select_zoning( 'outer: for (entity, selection_reason) in query.iter() { for zoned in zoned.iter() { if zoned == entity { continue 'outer; } } // Don't zone tiles that already have a zone. if selection_reason.is_some() { - commands.entity(entity).insert(Zone { zone_type: dragging.zone_type, plant_type: Some(dragging.plant_type), ..default() } ); + commands.entity(entity).insert( + Zone { + zone_type: dragging.zone_type, + item_type: dragging.item_type + } + ); let zonemarker = commands.spawn( (SpriteBundle { sprite: Sprite { color: Color::rgba(0.8, 0.8, 1.0, 0.1), diff --git a/src/task_system/personality.rs b/src/task_system/personality.rs index ad091b3..af7c6ed 100644 --- a/src/task_system/personality.rs +++ b/src/task_system/personality.rs @@ -1,6 +1,7 @@ use crate::prelude::*; -pub mod territorial; +pub mod human; pub mod nopersonality; +pub mod territorial; pub mod vicious; pub struct PersonalityPlugin; @@ -18,12 +19,18 @@ impl Plugin for PersonalityPlugin { } pub fn personalities( - mut entities: Query<(Entity, &mut Brain, &mut PhysicalBody, &Position, Option<&Nest>)> + mut entities: Query<(Entity, &mut Brain, &mut PhysicalBody, &Position, Option<&Nest>, Option<&Targeting>)>, + mut objects: Query<(Entity, &Object, &Position)>, ) { let potential_targets = entities.iter() - .map(|(entity, _, _, position, _)| (entity, *position)) // Clone the Position data + .map(|(entity, _, _, position, _, _)| (entity, *position)) // Clone the Position data .collect::>(); - for (entity, mut brain, mut physical_body, position, nest) in entities.iter_mut() { + let already_targeted = entities + .iter() + .filter(|(_, _, _, _, _, targeting)| targeting.is_some()) + .map(|(_, _, _, _, _, targeting)| targeting.unwrap().target) + .collect::>(); + for (entity, mut brain, mut physical_body, position, nest, targeting) in entities.iter_mut() { if brain.task != Some(Task::Personality) { continue; } let next_trait = brain.get_next_personality_trait(); match next_trait { @@ -33,6 +40,9 @@ pub fn personalities( Some(PersonalityTrait::Territorial) => { territorial::territorial(entity, brain, physical_body, position, nest, &potential_targets); }, + Some(PersonalityTrait::Human) => { + human::human(entity, brain, physical_body, position, nest, &objects, &already_targeted); + }, _ => { nopersonality::nopersonality(entity, brain, physical_body, position, nest); }, diff --git a/src/task_system/personality/human.rs b/src/task_system/personality/human.rs new file mode 100644 index 0000000..9cd0417 --- /dev/null +++ b/src/task_system/personality/human.rs @@ -0,0 +1,26 @@ +use crate::prelude::*; + +pub fn human( + entity: Entity, + mut brain: Mut, + mut physical_body: Mut, + _position: &Position, + nest: Option<&Nest>, + potential_targets: &Query<(Entity, &Object, &Position)>, + already_targeted: &Vec, +) { + if brain.task != Some(Task::Personality) { return; } + if !brain.personality.contains(&PersonalityTrait::Human) { return; } + + // Anything to defend against? + for (target_entity, target_object, target_position) in potential_targets.iter() { + // if entity == *target_entity { continue; } + // if target_position.distance(&nest.position) < 10 { + // physical_body.danger = Some(Danger { danger_type: DangerType::Attacked, danger_source: Some(*target_entity) }); + // brain.remotivate(); + // break; + // } + } + brain.motivation = Some(Motivation::Meander); + brain.task = None; +} \ No newline at end of file diff --git a/src/task_system/plant.rs b/src/task_system/plant.rs index 44a8994..fcd2bd6 100644 --- a/src/task_system/plant.rs +++ b/src/task_system/plant.rs @@ -15,7 +15,6 @@ pub fn task_system_plant( let mut nearest_entity: Option = None; 'targets: for (targetable_entity, targetable_position, zone) in targetables.iter() { if zone.zone_type != ZoneType::Farm { continue; } - if zone.plant_type.is_none() { continue; } for (e, obstacle) in obstacles.iter() { if (obstacle == targetable_position) && (entity != e) { continue 'targets; } } // Don't plant on top of obstacles. @@ -51,7 +50,7 @@ fn spawn_plant( zone: &Zone, ) { // commands.entity(foragable_entity).remove::(); - let sprite = TextureAtlasSprite::new(zone.plant_type.unwrap().sprite_index()); + let sprite = TextureAtlasSprite::new(zone.item_type.sprite_index()); commands.spawn(SpriteSheetBundle { sprite, texture_atlas: sprite_sheet.0.clone(), @@ -64,6 +63,6 @@ fn spawn_plant( }) .insert(*position) .insert(position.to_transform_layer(0.5)) - .insert(Plant { growth: 0.4, plant_type: zone.plant_type.unwrap() }) + .insert(Plant { growth: 0.4, plant_type: zone.item_type }) ; } \ No newline at end of file diff --git a/src/unitgenerator_system.rs b/src/unitgenerator_system.rs index ea8602c..74f6b90 100644 --- a/src/unitgenerator_system.rs +++ b/src/unitgenerator_system.rs @@ -104,7 +104,7 @@ impl UnitTemplate { food_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), entertainment_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), sleep_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), - personality: vec![], + personality: vec![PersonalityTrait::Human], skillset: Self::random_skillset_humanoid(), attributes: Self::random_attributeset_humanoid(), afflictions: random_afflictions.to_vec(), @@ -121,7 +121,7 @@ impl UnitTemplate { food_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), entertainment_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), sleep_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), - personality: vec![], + personality: vec![PersonalityTrait::Human], skillset: Self::random_skillset_humanoid(), attributes: Self::random_attributeset_humanoid(), afflictions: random_afflictions.to_vec(), @@ -138,7 +138,7 @@ impl UnitTemplate { food_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), entertainment_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), sleep_need: Some(NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }), - personality: vec![], + personality: vec![PersonalityTrait::Human], skillset: Self::random_skillset_humanoid(), attributes: Self::random_attributeset_humanoid(), afflictions: random_afflictions.to_vec(),