populating the world with people

This commit is contained in:
Niko Abeler 2022-12-31 09:38:01 +01:00
parent 99f61fbd70
commit b25e620cc3
9 changed files with 148 additions and 7 deletions

View File

@ -1,5 +1,7 @@
mod found_town; mod found_town;
mod world_genesis; mod world_genesis;
mod person_genesis;
pub use found_town::FoundTown; pub use found_town::FoundTown;
pub use world_genesis::WorldGenesis; pub use world_genesis::WorldGenesis;
pub use person_genesis::PersonGenesis;

View File

@ -0,0 +1,18 @@
use std::rc::Rc;
use crate::{state::{GameState, Effect}, world::Town, person::Person};
pub struct PersonGenesis {
pub town: Rc<Town>,
pub person: Rc<Person>,
}
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)
}
}

View File

@ -1,4 +1,5 @@
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use rand::prelude::*;
pub struct TownNameGenerator { pub struct TownNameGenerator {
} }
@ -15,4 +16,32 @@ impl TownNameGenerator {
// capitalize first letter // capitalize first letter
name[0..1].to_uppercase() + &name[1..] 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::<Vec<&str>>();
let second = include_str!("names/towns/second.txt").split("\n").collect::<Vec<&str>>();
let syllables = include_str!("names/people/syllables.txt").split("\n").collect::<Vec<&str>>();
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)
}
} }

View File

@ -3,6 +3,7 @@ mod state;
mod events; mod events;
mod time; mod time;
mod generators; mod generators;
mod person;
use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias}; use noise::{Perlin, ScalePoint, Add, NoiseFn, ScaleBias};
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
@ -92,6 +93,7 @@ fn main() {
let mut state = state::GameState::new(build_world()); let mut state = state::GameState::new(build_world());
state.step_n(36000);
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
for _ in 0..N_TOWNS { for _ in 0..N_TOWNS {

View File

@ -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

View File

@ -1,3 +1,7 @@
use std::rc::Rc;
use crate::{time::Time, world::Town, generators::PersonNameGenerator};
pub enum Profession { pub enum Profession {
Peasant, Peasant,
Adventurer, Adventurer,
@ -6,7 +10,20 @@ pub enum Profession {
pub struct Person { pub struct Person {
pub name: String, pub name: String,
pub age: u32, pub birth_date: Time,
pub birth_location: Rc<Town>,
pub profession: Profession, pub profession: Profession,
pub location: [usize; 2], pub location: [usize; 2],
}
impl Person {
pub fn new(birth_date: Time, birth_location: Rc<Town>, location: [usize; 2]) -> Person {
Person {
name: PersonNameGenerator::name(),
birth_date: birth_date,
birth_location: birth_location,
profession: Profession::Peasant,
location: [0, 0],
}
}
} }

View File

@ -2,9 +2,10 @@
use std::rc::Rc; use std::rc::Rc;
use rand::prelude::*; use rand::prelude::*;
use crate::person::Person;
use crate::time::Time; use crate::time::Time;
use crate::world::{World, Terrain, Town}; use crate::world::{World, Terrain, Town};
use crate::events::{FoundTown, WorldGenesis}; use crate::events::{FoundTown, WorldGenesis, PersonGenesis};
pub struct GameState { pub struct GameState {
pub time: Time, pub time: Time,
pub world: World, pub world: World,
@ -73,16 +74,37 @@ impl GameState {
self.world.map[x][y].terrain == Terrain::Flats || self.world.map[x][y].terrain == Terrain::Flats ||
self.world.map[x][y].terrain == Terrain::Hills self.world.map[x][y].terrain == Terrain::Hills
{ {
let town = Rc::new(Town::new());
self.add_event(Event { self.add_event(Event {
time: self.time, time: self.time,
effect: Box::new(FoundTown { effect: Box::new(FoundTown {
x: x, x: x,
y: y, 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; break;
} }
} }
} }
pub fn add_person(&mut self, person: Rc<Person>) {
}
} }

View File

@ -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 }
}
}

View File

@ -17,7 +17,6 @@ pub enum Terrain {
pub struct Town { pub struct Town {
pub name: String, pub name: String,
pub population: u32,
} }
pub enum Structure { pub enum Structure {
@ -62,6 +61,20 @@ impl World {
pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) { pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) {
self.map[x][y].structure = Some(structure); self.map[x][y].structure = Some(structure);
} }
pub fn get_town_location(&self, town: &Rc<Town>) -> [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 { impl Terrain {
@ -99,10 +112,8 @@ impl Terrain {
impl Town { impl Town {
pub fn new() -> Town { pub fn new() -> Town {
let mut rng = rand::thread_rng();
Town { Town {
name: TownNameGenerator::name(), name: TownNameGenerator::name(),
population: rng.gen_range(100..500),
} }
} }
} }