diff --git a/assets/pig.png b/assets/pig.png index 06d18c4..e4c7fe4 100644 Binary files a/assets/pig.png and b/assets/pig.png differ diff --git a/src/entities/livestock/mod.rs b/src/entities/livestock/mod.rs new file mode 100644 index 0000000..6fdf2e7 --- /dev/null +++ b/src/entities/livestock/mod.rs @@ -0,0 +1,2 @@ +pub mod pig; +pub mod rabbit; diff --git a/src/entities/livestock/pig.rs b/src/entities/livestock/pig.rs new file mode 100644 index 0000000..8d7110a --- /dev/null +++ b/src/entities/livestock/pig.rs @@ -0,0 +1,59 @@ +use crate::constants::TILE_SIZE; +use crate::constants::*; +use crate::entities::shared_components::Ambulatory; +use crate::tilemap::VisibleGameEntity; +use bevy::prelude::*; +use bevy_rand::prelude::*; +use rand::Rng; + +#[derive(Bundle)] +pub struct Pig { + ambulatory: Ambulatory, + sprite: Sprite, + transform: Transform, + visibility: Visibility, +} + +impl Pig { + pub fn new(asset_server: &Res, position: Vec3) -> Self { + Pig { + ambulatory: Ambulatory { + walk_speed: 25., + run_speed: 6., + target: None, + current_path: None, + path_index: 0, + step_recovery: 0, + }, + sprite: Sprite { + image: asset_server.load("pig.png"), + ..Default::default() + }, + transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), + visibility: Visibility::Hidden, + } + } +} + +pub fn spawn_pigs( + mut commands: Commands, + asset_server: Res, + mut rng_q: Query<&mut Entropy, With>, +) { + if let Ok(mut rng) = rng_q.single_mut() { + // Spawn a handful of pigs + for _ in 0..5 { + let cit = commands + .spawn(Pig::new( + &asset_server, + Vec3::new( + rng.random_range(-32.0f32..32.0f32).round(), + rng.random_range(-32.0f32..32.0f32).round(), + 35.0, + ) * TILE_SIZE, + )) + .id(); + commands.entity(cit).insert(VisibleGameEntity); + } + } +} diff --git a/src/entities/livestock/rabbit.rs b/src/entities/livestock/rabbit.rs new file mode 100644 index 0000000..a8d6973 --- /dev/null +++ b/src/entities/livestock/rabbit.rs @@ -0,0 +1,59 @@ +use crate::constants::TILE_SIZE; +use crate::constants::*; +use crate::entities::shared_components::Ambulatory; +use crate::tilemap::VisibleGameEntity; +use bevy::prelude::*; +use bevy_rand::prelude::*; +use rand::Rng; + +#[derive(Bundle)] +pub struct Rabbit { + ambulatory: Ambulatory, + sprite: Sprite, + transform: Transform, + visibility: Visibility, +} + +impl Rabbit { + pub fn new(asset_server: &Res, position: Vec3) -> Self { + Rabbit { + ambulatory: Ambulatory { + walk_speed: 1., + run_speed: 6., + target: None, + current_path: None, + path_index: 0, + step_recovery: 0, + }, + sprite: Sprite { + image: asset_server.load("rabbit.png"), + ..Default::default() + }, + transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), + visibility: Visibility::Hidden, + } + } +} + +pub fn spawn_rabbits( + mut commands: Commands, + asset_server: Res, + mut rng_q: Query<&mut Entropy, With>, +) { + if let Ok(mut rng) = rng_q.single_mut() { + // Spawn a handful of rabbits + for _ in 0..15 { + let cit = commands + .spawn(Rabbit::new( + &asset_server, + Vec3::new( + rng.random_range(-32.0f32..32.0f32).round(), + rng.random_range(-32.0f32..32.0f32).round(), + 35.0, + ) * TILE_SIZE, + )) + .id(); + commands.entity(cit).insert(VisibleGameEntity); + } + } +} diff --git a/src/entities/mod.rs b/src/entities/mod.rs new file mode 100644 index 0000000..851d3be --- /dev/null +++ b/src/entities/mod.rs @@ -0,0 +1,6 @@ +pub mod livestock; +pub mod sentient; +pub mod shared_components; +pub mod shared_systems; + +pub use shared_systems::*; diff --git a/src/entities/sentient/dorf.rs b/src/entities/sentient/dorf.rs new file mode 100644 index 0000000..ac6e6df --- /dev/null +++ b/src/entities/sentient/dorf.rs @@ -0,0 +1,59 @@ +use crate::constants::TILE_SIZE; +use crate::constants::*; +use crate::entities::shared_components::Ambulatory; +use crate::tilemap::VisibleGameEntity; +use bevy::prelude::*; +use bevy_rand::prelude::*; +use rand::Rng; + +#[derive(Bundle)] +pub struct Dorf { + ambulatory: Ambulatory, + sprite: Sprite, + transform: Transform, + visibility: Visibility, +} + +impl Dorf { + pub fn new(asset_server: &Res, position: Vec3) -> Self { + Dorf { + ambulatory: Ambulatory { + walk_speed: 5., + run_speed: 6., + target: None, + current_path: None, + path_index: 0, + step_recovery: 0, + }, + sprite: Sprite { + image: asset_server.load("dorf.png"), + ..Default::default() + }, + transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), + visibility: Visibility::Hidden, + } + } +} + +pub fn spawn_dorfs( + mut commands: Commands, + asset_server: Res, + mut rng_q: Query<&mut Entropy, With>, +) { + if let Ok(mut rng) = rng_q.single_mut() { + // Spawn a handful of dorfs + for _ in 0..40 { + let cit = commands + .spawn(Dorf::new( + &asset_server, + Vec3::new( + rng.random_range(-8.0f32..8.0f32).round(), + rng.random_range(-8.0f32..8.0f32).round(), + 35.0, + ) * TILE_SIZE, + )) + .id(); + commands.entity(cit).insert(VisibleGameEntity); + } + } +} diff --git a/src/entities/sentient/mod.rs b/src/entities/sentient/mod.rs new file mode 100644 index 0000000..dc43085 --- /dev/null +++ b/src/entities/sentient/mod.rs @@ -0,0 +1 @@ +pub mod dorf; diff --git a/src/entities/shared_components/ambulatory.rs b/src/entities/shared_components/ambulatory.rs new file mode 100644 index 0000000..8c7ae65 --- /dev/null +++ b/src/entities/shared_components/ambulatory.rs @@ -0,0 +1,11 @@ +use bevy::prelude::*; + +#[derive(Component)] +pub struct Ambulatory { + pub walk_speed: f32, + pub run_speed: f32, + pub current_path: Option>, + pub path_index: usize, + pub target: Option, + pub step_recovery: u32, +} diff --git a/src/entities/shared_components/mod.rs b/src/entities/shared_components/mod.rs new file mode 100644 index 0000000..8689206 --- /dev/null +++ b/src/entities/shared_components/mod.rs @@ -0,0 +1,2 @@ +pub mod ambulatory; +pub use ambulatory::*; // replace with explicit imports/exports eventually diff --git a/src/entities/shared_systems/mod.rs b/src/entities/shared_systems/mod.rs new file mode 100644 index 0000000..1bc27c5 --- /dev/null +++ b/src/entities/shared_systems/mod.rs @@ -0,0 +1 @@ +pub mod pathfinding; diff --git a/src/citizen.rs b/src/entities/shared_systems/pathfinding.rs similarity index 86% rename from src/citizen.rs rename to src/entities/shared_systems/pathfinding.rs index cce3fa7..a7884dc 100644 --- a/src/citizen.rs +++ b/src/entities/shared_systems/pathfinding.rs @@ -2,7 +2,8 @@ use crate::constants::TILE_SIZE; use crate::tile::TileMap; use crate::{ constants::*, - tilemap::{ChunkMap, VisibleGameEntity, CHUNK_SIZE}, + entities::shared_components::Ambulatory, + tilemap::{ChunkMap, CHUNK_SIZE}, }; use bevy::{math::ivec3, prelude::*}; use bevy_rand::prelude::*; @@ -12,45 +13,6 @@ use std::{ process::exit, }; -#[derive(Bundle)] -pub struct Citizen { - ambulatory: Ambulatory, - sprite: Sprite, - transform: Transform, - visibility: Visibility, -} - -impl Citizen { - pub fn new(asset_server: &Res, position: Vec3) -> Self { - Citizen { - ambulatory: Ambulatory { - walk_speed: 0., - run_speed: 6., - target: None, - current_path: None, - path_index: 0, - step_recovery: 0, - }, - sprite: Sprite { - image: asset_server.load("dorf.png"), - ..Default::default() - }, - transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), - visibility: Visibility::Hidden, - } - } -} - -#[derive(Component)] -pub struct Ambulatory { - pub walk_speed: f32, - pub run_speed: f32, - pub current_path: Option>, - pub path_index: usize, - pub target: Option, - pub step_recovery: u32, -} - #[derive(Clone, Eq, PartialEq, Debug)] struct PathNode { position: IVec3, @@ -74,15 +36,12 @@ pub struct PathfindingPlugin; impl Plugin for PathfindingPlugin { fn build(&self, app: &mut App) { - app.add_systems( - FixedUpdate, - (update_citizen_wandering_targets, citizen_movement).chain(), - ); + app.add_systems(FixedUpdate, (update_wandering_targets, movement).chain()); } } -pub fn update_citizen_wandering_targets( - mut query: Query<(&mut Ambulatory, &Transform)>, +pub fn update_wandering_targets( + mut query: Query<(&mut Ambulatory, &Transform)>, // add a 'with' here when behaviours are implemented tilemap: Res, chunk_map: Res, mut rng_q: Query<&mut Entropy, With>, @@ -134,19 +93,12 @@ pub fn update_citizen_wandering_targets( } } -pub fn citizen_movement( - mut query: Query<( - &mut Ambulatory, - &mut Transform, - &mut Visibility, - &mut Sprite, - )>, - tilemap: Res, -) { +pub fn movement(mut query: Query<(&mut Ambulatory, &mut Transform)>, tilemap: Res) { query .par_iter_mut() - .for_each(|(mut ambulatory, mut transform, _, _)| { + .for_each(|(mut ambulatory, mut transform)| { let current_pos = transform.translation; + // Apply gravity if in air if !is_standable_tile(&tilemap, current_pos.as_ivec3()) { transform.translation.z -= TILE_SIZE; return; @@ -432,25 +384,3 @@ fn reconstruct_path(came_from: HashMap, mut current: IVec3) -> Vec path.reverse(); path } -pub fn spawn_citizens( - mut commands: Commands, - asset_server: Res, - mut rng_q: Query<&mut Entropy, With>, -) { - if let Ok(mut rng) = rng_q.single_mut() { - // Spawn a handful of citizens - for _ in 0..10 { - let cit = commands - .spawn(Citizen::new( - &asset_server, - Vec3::new( - rng.random_range(-8.0f32..8.0f32).round(), - rng.random_range(-8.0f32..8.0f32).round(), - 35.0, - ) * TILE_SIZE, - )) - .id(); - commands.entity(cit).insert(VisibleGameEntity); - } - } -} diff --git a/src/main.rs b/src/main.rs index 51f9e75..553908e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,9 @@ use bevy::prelude::*; use bevy_rand::prelude::*; mod camera; -mod citizen; mod constants; mod cursor; +mod entities; mod game; mod item; mod tile; @@ -36,13 +36,15 @@ fn main() { )) .insert_resource(ClearColor(Color::srgb(0., 0., 0.))) .add_plugins(tilemap::TilemapPlugin) - .add_plugins(citizen::PathfindingPlugin) + .add_plugins(entities::pathfinding::PathfindingPlugin) .add_systems( Startup, ( camera::spawn_panning_camera, cursor::setup_cursor, - citizen::spawn_citizens, + entities::sentient::dorf::spawn_dorfs, + entities::livestock::pig::spawn_pigs, + entities::livestock::rabbit::spawn_rabbits, ), ) .add_systems( diff --git a/src/tilemap.rs b/src/tilemap.rs index 5ddcb5d..70a611d 100644 --- a/src/tilemap.rs +++ b/src/tilemap.rs @@ -398,7 +398,7 @@ fn generate_chunk_weathering_and_precipitation(// mut commands: Commands, // TODO: Generate weathering and precipitation // Temperature and humidity // Erosion - // Hadley lines etc + // Hadley lines/cells etc // Biomes }