From 11962f6f6fe174234cc56c9d23c2aef69860a5ad Mon Sep 17 00:00:00 2001 From: ryankopf Date: Mon, 7 Aug 2023 19:09:12 -0500 Subject: [PATCH] Organizing. --- src/combat_system/melee.rs | 44 +++++++++++++++---- src/components.rs | 15 ++++++- src/initializations.rs | 6 +++ src/{ => initializations}/biome.rs | 15 +------ src/{ => initializations}/load.rs | 3 +- src/{ => initializations}/map.rs | 2 +- src/interface.rs | 4 +- src/{ => interface}/pause.rs | 2 +- src/main.rs | 13 +----- src/resources.rs | 1 + src/startup.rs | 19 ++++---- src/unitgenerator_system.rs | 69 ++++++++++++++++++++++-------- 12 files changed, 129 insertions(+), 64 deletions(-) create mode 100644 src/initializations.rs rename src/{ => initializations}/biome.rs (59%) rename src/{ => initializations}/load.rs (87%) rename src/{ => initializations}/map.rs (99%) rename src/{ => interface}/pause.rs (97%) diff --git a/src/combat_system/melee.rs b/src/combat_system/melee.rs index 6a9c5ab..474b72e 100644 --- a/src/combat_system/melee.rs +++ b/src/combat_system/melee.rs @@ -2,11 +2,11 @@ use crate::prelude::*; pub fn combat_system_melee( mut commands: Commands, - mut entities_that_might_fight: Query<(Entity, &mut Brain, &Position, Option<&mut Pathing>, Option<&Targeting>)>, - attackables: Query<(Entity, &Position), With>, + mut entities_that_might_fight: Query<(Entity, &mut Brain, &mut PhysicalBody, &Position, Option<&mut Pathing>, Option<&Targeting>)>, + attackables: Query<(Entity, &Position), With>, sprite_sheet: Res, ) { - for (e, mut brain, position, pathing, targeting) in entities_that_might_fight.iter_mut() { + for (e, mut brain, mut physical_body, position, pathing, targeting) in entities_that_might_fight.iter_mut() { if brain.task != Some(Task::Fight) { continue; } if let Some(targeting) = targeting { let mut entity_found = false; @@ -42,7 +42,6 @@ pub fn combat_system_melee( } } if !entity_found { - println!("No entity found"); commands.entity(e).remove::(); brain.remotivate(); } @@ -51,18 +50,45 @@ pub fn combat_system_melee( // Humans might find a target based on if they're hunting or defending. // Animals might find a target based on if they're hungry or defending. // For now just find the nearest physical body and make that the target. + if let Some(danger) = &physical_body.danger { + if danger.danger_type == DangerType::Attacked { + // If we're being attacked, we should attack back. + // Error: What happens after you win the fight? Or if the attacker no longer exists? + if let Some(danger_source) = danger.danger_source { + // check if attackables contains danger_source + let mut danger_source_found = false; + for (entity, _target_position) in attackables.iter() { + if entity == danger_source { + danger_source_found = true; + break; + } + } + if !danger_source_found { + // The danger source no longer exists. We should stop attacking. + brain.remotivate(); + physical_body.danger = None; + continue; + } + commands.entity(e).insert(Targeting { target: danger_source }); + continue; + } + } + } let mut closest_distance = 9999; let mut closest_target = None; + let mut closest_position = None; for (attackable, attackable_position) in attackables.iter() { + if attackable == e { continue; } let distance = position.distance(attackable_position); if distance < closest_distance { closest_distance = distance; closest_target = Some(attackable); + closest_position = Some(attackable_position); } } if let Some(closest_target) = closest_target { commands.entity(e).insert(Targeting { target: closest_target }); - let target_position = attackables.get(closest_target).unwrap().1; + let target_position = closest_position.unwrap(); commands.entity(e).insert( Pathing { path: vec![], destination: *target_position, ..default() }); } else { // Nothing to attack. Now what? @@ -79,8 +105,11 @@ fn do_melee_damage( body1: &PhysicalBody, body2: &mut PhysicalBody, ) { - body2.attributes.health -= 1 + body1.attributes.strength; - println!("Health: {}", body2.attributes.health); + body2.attributes.health -= + 1 + + (body1.attributes.strength - body2.attributes.constitution).max(0).min(20) + + (body1.skillset.brawling.level()).max(0).min(20) + ; if body2.attributes.health <= 0 { commands.entity(attacked_entity).despawn_recursive(); } @@ -95,7 +124,6 @@ pub fn attacked_entities_system( mut physical_bodies: Query<(Entity, &mut PhysicalBody)>, ) { for (attacked_entity, attack_info) in attacked_query.iter() { - println!("Attacked"); commands.entity(attacked_entity).remove::(); let mut attacker_physical_body: Option = None; let mut attacker_entity = None; diff --git a/src/components.rs b/src/components.rs index 3a87a2d..ca5fab6 100644 --- a/src/components.rs +++ b/src/components.rs @@ -216,6 +216,17 @@ pub struct Skill { pub experience: i32, pub exp_lost: i32, // Forgetting/atrophied skills. Easier to regain. } +impl Skill { + pub fn level(&self) -> i32 { + if self.experience < 10000 { + //0, 100, 400, 900, 1600, 2500, 3600, 6400, 8100, 10000 + (self.experience as f32 / 100.0).sqrt() as i32 + } else { + // 12000, 14000, 18000, 26000, 42000, 74000, 138000, 266000, 513000, 10250000 + 10 + ((self.experience-10000) as f32 / 1000.0).log2() as i32 + } + } +} #[derive(Component, Clone, Copy)] pub struct Attributeset { @@ -325,6 +336,7 @@ pub struct Affliction { #[derive(Component, Clone, Copy)] pub struct Skillset { pub animal_raising: Skill, + pub brawling: Skill, pub construction: Skill, pub cooking: Skill, pub crafting: Skill, @@ -341,6 +353,7 @@ impl Default for Skillset { fn default() -> Self { Skillset { animal_raising: Skill { experience: 0, exp_lost: 0 }, + brawling: Skill { experience: 0, exp_lost: 0 }, construction: Skill { experience: 0, exp_lost: 0 }, cooking: Skill { experience: 0, exp_lost: 0 }, crafting: Skill { experience: 0, exp_lost: 0 }, @@ -356,7 +369,7 @@ impl Default for Skillset { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum DangerType { Attacked, Fire, diff --git a/src/initializations.rs b/src/initializations.rs new file mode 100644 index 0000000..82a9f1e --- /dev/null +++ b/src/initializations.rs @@ -0,0 +1,6 @@ +pub mod biome; +pub use biome::*; +pub mod load; +pub use load::*; +pub mod map; +pub use map::*; \ No newline at end of file diff --git a/src/biome.rs b/src/initializations/biome.rs similarity index 59% rename from src/biome.rs rename to src/initializations/biome.rs index d8b8f8c..b0709bd 100644 --- a/src/biome.rs +++ b/src/initializations/biome.rs @@ -1,4 +1,4 @@ -use super::prelude::*; +use crate::prelude::*; // Make Plugin pub struct BiomePlugin; @@ -6,25 +6,14 @@ pub struct BiomePlugin; impl Plugin for BiomePlugin { fn build(&self, app: &mut App) { app - //.add_startup_system_to_stage(StartupStage::PreStartup, initialize_biome) .insert_resource(starting_biome()) ; } } -// pub fn initialize_biome( -// mut biome: ResMut, -// ) { -// *biome = Biome { -// // name: "Forest".to_string(), -// plants: vec![PlantType::Cabbage, PlantType::PineTree, PlantType::PineTree], -// tiles: vec![TileType::Grass, TileType::Grass, TileType::Grass, TileType::Dirt, TileType::Gravel], -// }; -// } - pub fn starting_biome() -> Biome { Biome { - // name: "Forest".to_string(), + name: "Forest".to_string(), plants: vec![PlantType::Cabbage, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, PlantType::PineTree, PlantType::CedarTree, PlantType::ThornBush, PlantType::Weed, PlantType::CactusRound], tiles: vec![TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, TileType::Grass, diff --git a/src/load.rs b/src/initializations/load.rs similarity index 87% rename from src/load.rs rename to src/initializations/load.rs index ddee723..800bddf 100644 --- a/src/load.rs +++ b/src/initializations/load.rs @@ -1,11 +1,10 @@ -use super::prelude::*; +use crate::prelude::*; pub fn load_sprites( mut commands: Commands, asset_server: Res, mut texture_atlases: ResMut>, ) { - // let texture_handle = asset_server.load("sprites.png"); let texture_handle = asset_server.load("AllSprites.png"); let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(32.0, 32.0), 64, 95, None, None); let texture_atlas_handle = texture_atlases.add(texture_atlas); diff --git a/src/map.rs b/src/initializations/map.rs similarity index 99% rename from src/map.rs rename to src/initializations/map.rs index 29006cd..5b2fb0e 100644 --- a/src/map.rs +++ b/src/initializations/map.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use super::prelude::*; +use crate::prelude::*; #[derive(Default)] pub struct Map { diff --git a/src/interface.rs b/src/interface.rs index c4eeba4..3b75829 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -5,4 +5,6 @@ pub use game_ui::*; mod click; pub use click::*; mod input; -pub use input::*; \ No newline at end of file +pub use input::*; +mod pause; +pub use pause::*; \ No newline at end of file diff --git a/src/pause.rs b/src/interface/pause.rs similarity index 97% rename from src/pause.rs rename to src/interface/pause.rs index 2d02a0b..5f14732 100644 --- a/src/pause.rs +++ b/src/interface/pause.rs @@ -1,4 +1,4 @@ -use super::prelude::*; +use crate::prelude::*; pub fn on_pause( mut commands: Commands, diff --git a/src/main.rs b/src/main.rs index 53d535e..8f55fde 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,24 +31,18 @@ pub use crate::prelude::*; // unitgenerator_system, // window_system // )] -mod biome; -use biome::*; mod button_system; use button_system::*; mod combat_system; use combat_system::*; mod components; -// use components::*; mod constants; -// use constants::*; +mod initializations; +use initializations::*; mod interface; use interface::*; -mod load; -use load::*; mod main_menu; use main_menu::*; -mod map; -use map::*; mod monstergenerator_system; use monstergenerator_system::*; mod moverandom_system; @@ -61,10 +55,7 @@ mod names_system; use names_system::*; mod needs; use needs::*; -mod pause; -use pause::*; mod resources; -// use resources::*; mod seasons; use seasons::*; mod selection_systems; diff --git a/src/resources.rs b/src/resources.rs index e39a675..41407a6 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -11,6 +11,7 @@ pub struct SpriteSheet(pub Handle); #[derive(Resource)] pub struct Biome { + pub name: String, pub plants: Vec, pub tiles: Vec, } diff --git a/src/startup.rs b/src/startup.rs index 45bc563..9f7aa97 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -24,14 +24,17 @@ pub fn startup( // GENERATE UNITS for i in 1..6 { let position = Position { x: 3, y: 3*i, z: 0 }; - // let actor_type = match i { - // 1 => ActorType::Man2, - // 2 => ActorType::Dwarf, - // _ => ActorType::Man - // }; - // let sprite = TextureAtlasSprite::new(actor_type.sprite_index()); - // spawn_unit(&mut commands, position, &sprite_sheet, actor_type, 21.0, 21.0, 21.0); - spawn_unit_from_template(&mut commands, position, &sprite_sheet, &UnitTemplate::human()); + match i { + 1 => { + spawn_unit_from_template(&mut commands, position, &sprite_sheet, &UnitTemplate::elf()); + }, + 2 => { + spawn_unit_from_template(&mut commands, position, &sprite_sheet, &UnitTemplate::dwarf()); + }, + _ => { + spawn_unit_from_template(&mut commands, position, &sprite_sheet, &UnitTemplate::human()); + } + } } let position = Position { x: 10, y: 10, z: 0 }; diff --git a/src/unitgenerator_system.rs b/src/unitgenerator_system.rs index 7cb7b0b..79adc81 100644 --- a/src/unitgenerator_system.rs +++ b/src/unitgenerator_system.rs @@ -100,6 +100,32 @@ impl UnitTemplate { attributes: Self::random_attributeset_humanoid(), } } + pub fn elf() -> Self { + let actor_type = ActorType::Elf; + let random_afflictions = Self::random_afflictions_humanoid(); + Self { + actor_type, + food_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + entertainment_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + sleep_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + afflictions: random_afflictions.to_vec(), + skillset: Self::random_skillset_humanoid(), + attributes: Self::random_attributeset_humanoid(), + } + } + pub fn dwarf() -> Self { + let actor_type = ActorType::Dwarf; + let random_afflictions = Self::random_afflictions_humanoid(); + Self { + actor_type, + food_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + entertainment_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + sleep_need: NeedExample { current: 90.0, max: 100.0, rate: 0.1, low: 10.0, normal: 25.0, high: 80.0, variance: 5.0 }, + afflictions: random_afflictions.to_vec(), + skillset: Self::random_skillset_humanoid(), + attributes: Self::random_attributeset_humanoid(), + } + } pub fn random_afflictions_humanoid() -> Vec { //////////////////////////// // Select some Afflictions @@ -190,31 +216,38 @@ impl UnitTemplate { selected_afflictions.to_vec() } pub fn random_skillset_humanoid() -> Skillset { + let mut rng = rand::thread_rng(); + let ranges = [5000..7000, 5000..7000, 3000..4000, 2000..3000, 1000..2000, 500..1000, 500..1000, 400..800, 300..600, 300..600, 200..500, 200..500, 100..300]; + let mut values: Vec = ranges.iter().map(|range| rng.gen_range(range.clone())).collect(); + let losses = [1000..2000, 1000..2000, 200..500, 200..500, 100..300, 100..300, 100..300, 100..300, 100..300, 100..300, 100..300, 100..300, 100..300]; + let mut loss_values: Vec = losses.iter().map(|range| rng.gen_range(range.clone())).collect(); + values.shuffle(&mut rng); Skillset { - animal_raising: Skill { experience: 100, exp_lost: 0 }, - construction: Skill { experience: 50, exp_lost: 10 }, - cooking: Skill { experience: 75, exp_lost: 5 }, - crafting: Skill { experience: 60, exp_lost: 8 }, - doctoring: Skill { experience: 90, exp_lost: 2 }, - farming: Skill { experience: 70, exp_lost: 7 }, - fishing: Skill { experience: 80, exp_lost: 6 }, - foraging: Skill { experience: 40, exp_lost: 12 }, - hunting: Skill { experience: 55, exp_lost: 9 }, - mining: Skill { experience: 65, exp_lost: 5 }, - social: Skill { experience: 30, exp_lost: 15 }, - woodcutting: Skill { experience: 85, exp_lost: 4 }, + animal_raising: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + brawling: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + construction: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + cooking: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + crafting: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + doctoring: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + farming: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + fishing: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + foraging: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + hunting: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + mining: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + social: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, + woodcutting: Skill { experience: values.pop().unwrap_or(100), exp_lost: loss_values.pop().unwrap_or(0) }, } } pub fn random_attributeset_humanoid() -> Attributeset { Attributeset { health: 100, - strength: 3, - dexterity: 3, - constitution: 3, - intelligence: 3, - wisdom: 3, - charisma: 4, + strength: 3, // Represents ability to do physical work. + dexterity: 3, // Represents ability to do fine work, and affects speed. + constitution: 3,// Represents ability to resist disease, poison, and damage. + intelligence: 3,// Represents ability to learn and remember. + wisdom: 3, // Represents ability to make good decisions. + charisma: 4, // Represents ability to influence others. } } } \ No newline at end of file