From b25e620cc385a5342b8e66e7d7fcc47110a01618 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Sat, 31 Dec 2022 09:38:01 +0100 Subject: [PATCH] populating the world with people --- src/events/mod.rs | 4 +++- src/events/person_genesis.rs | 18 ++++++++++++++++++ src/generators.rs | 29 +++++++++++++++++++++++++++++ src/main.rs | 2 ++ src/names/people/syllables.txt | 34 ++++++++++++++++++++++++++++++++++ src/person.rs | 19 ++++++++++++++++++- src/state.rs | 26 ++++++++++++++++++++++++-- src/time.rs | 6 ++++++ src/world.rs | 17 ++++++++++++++--- 9 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/events/person_genesis.rs create mode 100644 src/names/people/syllables.txt diff --git a/src/events/mod.rs b/src/events/mod.rs index 7586ce2..290e236 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -1,5 +1,7 @@ mod found_town; mod world_genesis; +mod person_genesis; pub use found_town::FoundTown; -pub use world_genesis::WorldGenesis; \ No newline at end of file +pub use world_genesis::WorldGenesis; +pub use person_genesis::PersonGenesis; \ No newline at end of file diff --git a/src/events/person_genesis.rs b/src/events/person_genesis.rs new file mode 100644 index 0000000..2146c9a --- /dev/null +++ b/src/events/person_genesis.rs @@ -0,0 +1,18 @@ +use std::rc::Rc; + +use crate::{state::{GameState, Effect}, world::Town, person::Person}; + +pub struct PersonGenesis { + pub town: Rc, + pub person: Rc, +} + +impl Effect for PersonGenesis { + fn apply(&self, state: &mut GameState) { + state.add_person(self.person.clone()); + } + + fn description(&self) -> String { + format!("{} was sent by the Gods to {}", self.person.name, self.town.name) + } +} \ No newline at end of file diff --git a/src/generators.rs b/src/generators.rs index 9d38145..fde7ad1 100644 --- a/src/generators.rs +++ b/src/generators.rs @@ -1,4 +1,5 @@ use rand::seq::SliceRandom; +use rand::prelude::*; pub struct TownNameGenerator { } @@ -15,4 +16,32 @@ impl TownNameGenerator { // capitalize first letter name[0..1].to_uppercase() + &name[1..] } +} + +pub struct PersonNameGenerator { +} + +impl PersonNameGenerator { + pub fn name() -> String { + let first = include_str!("names/towns/first.txt").split("\n").collect::>(); + let second = include_str!("names/towns/second.txt").split("\n").collect::>(); + let syllables = include_str!("names/people/syllables.txt").split("\n").collect::>(); + + let mut rng = rand::thread_rng(); + let first = first.choose(&mut rng).unwrap(); + let second = second.choose(&mut rng).unwrap(); + + let mut name = "".to_owned(); + for _ in 0..rng.gen_range(2..5) { + name = format!("{}{}", name, syllables.choose(&mut rng).unwrap()); + } + name = name[0..1].to_uppercase() + &name[1..]; + + let mut surname = format!("{}{}", first, second); + // capitalize first letter + surname = surname[0..1].to_uppercase() + &surname[1..]; + + format!("{} {}", name, surname) + + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e1eb97a..f0ea740 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod state; mod events; mod time; mod generators; +mod person; use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; @@ -92,6 +93,7 @@ fn main() { let mut state = state::GameState::new(build_world()); + state.step_n(36000); let mut rng = rand::thread_rng(); for _ in 0..N_TOWNS { diff --git a/src/names/people/syllables.txt b/src/names/people/syllables.txt new file mode 100644 index 0000000..a31b72e --- /dev/null +++ b/src/names/people/syllables.txt @@ -0,0 +1,34 @@ +al +ak +ap +aw +aan +ur +ist +er +ku +ko +ki +tu +to +te +the +th +ew +uw +va +ve +ers +ser +res +bu +mu +nu +un +um +qen +qo +qum +cum +cah +caj \ No newline at end of file diff --git a/src/person.rs b/src/person.rs index 27fa7c1..1c38e7f 100644 --- a/src/person.rs +++ b/src/person.rs @@ -1,3 +1,7 @@ +use std::rc::Rc; + +use crate::{time::Time, world::Town, generators::PersonNameGenerator}; + pub enum Profession { Peasant, Adventurer, @@ -6,7 +10,20 @@ pub enum Profession { pub struct Person { pub name: String, - pub age: u32, + pub birth_date: Time, + pub birth_location: Rc, pub profession: Profession, pub location: [usize; 2], +} + +impl Person { + pub fn new(birth_date: Time, birth_location: Rc, location: [usize; 2]) -> Person { + Person { + name: PersonNameGenerator::name(), + birth_date: birth_date, + birth_location: birth_location, + profession: Profession::Peasant, + location: [0, 0], + } + } } \ No newline at end of file diff --git a/src/state.rs b/src/state.rs index 8752f39..be8b08d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -2,9 +2,10 @@ use std::rc::Rc; use rand::prelude::*; +use crate::person::Person; use crate::time::Time; use crate::world::{World, Terrain, Town}; -use crate::events::{FoundTown, WorldGenesis}; +use crate::events::{FoundTown, WorldGenesis, PersonGenesis}; pub struct GameState { pub time: Time, pub world: World, @@ -73,16 +74,37 @@ impl GameState { self.world.map[x][y].terrain == Terrain::Flats || self.world.map[x][y].terrain == Terrain::Hills { + let town = Rc::new(Town::new()); self.add_event(Event { time: self.time, effect: Box::new(FoundTown { x: x, y: y, - town: Rc::new(Town::new()), + town: town.clone(), }) }); + + let pop_size = rng.gen_range(20..200); + + for _ in 0..pop_size { + self.add_event(Event { + time: self.time, + effect: Box::new(PersonGenesis { + town: town.clone(), + person: Rc::new(Person::new( + self.time.substract_years(rng.gen_range(18..30)), + town.clone(), + self.world.get_town_location(&town) + )), + }) + }); + } break; } } } + + pub fn add_person(&mut self, person: Rc) { + + } } \ No newline at end of file diff --git a/src/time.rs b/src/time.rs index a46d1c8..5a2e499 100644 --- a/src/time.rs +++ b/src/time.rs @@ -15,3 +15,9 @@ impl fmt::Display for Time { } } +impl Time { + pub fn substract_years(&self, years: u32) -> Time { + Time { time: self.time - years * 360 } + } +} + diff --git a/src/world.rs b/src/world.rs index 49048ea..c1aa5cf 100644 --- a/src/world.rs +++ b/src/world.rs @@ -17,7 +17,6 @@ pub enum Terrain { pub struct Town { pub name: String, - pub population: u32, } pub enum Structure { @@ -62,6 +61,20 @@ impl World { pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) { self.map[x][y].structure = Some(structure); } + + + pub fn get_town_location(&self, town: &Rc) -> [usize; 2] { + for x in 0..self.size { + for y in 0..self.size { + if let Some(Structure::Town(t)) = &self.map[x][y].structure { + if Rc::ptr_eq(&t, town) { + return [x, y]; + } + } + } + } + panic!("Town not found"); + } } impl Terrain { @@ -99,10 +112,8 @@ impl Terrain { impl Town { pub fn new() -> Town { - let mut rng = rand::thread_rng(); Town { name: TownNameGenerator::name(), - population: rng.gen_range(100..500), } } }