diff --git a/src/creature.rs b/src/creature.rs index a9b97a6..c62c8c0 100644 --- a/src/creature.rs +++ b/src/creature.rs @@ -1,7 +1,7 @@ -use std::{rc::Rc, fmt::Display}; +use std::{fmt::Display}; use rand::prelude::*; -use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location, EntityId}}; +use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location}}; #[derive(Clone, Copy)] pub enum Profession { @@ -41,7 +41,7 @@ impl Creature { if *days <= 0 { // pick random destination let mut rng = rand::thread_rng(); - let dest = world.structures.keys().choose(&mut rng); + let dest = world.sites.keys().choose(&mut rng); self.agenda = Agenda::Traveling(*dest.unwrap()); } else { self.agenda = Agenda::Idle(days - 1); @@ -77,10 +77,10 @@ impl Creature { match &self.agenda { Agenda::Idle(days) => format!("I'll stay here for {} days", days), Agenda::Traveling(destination) => { - let dest_struct = state.world.get_structure_at(*destination); - match dest_struct { - Some(dest) => { - return format!("I'm traveling to {}", dest); + let dest_site = state.world.get_site_at(*destination); + match dest_site { + Some(site) => { + return format!("I'm traveling to {}", site); }, None => return format!("I'm traveling to an unknown location"), } @@ -97,8 +97,7 @@ impl Display for Creature { #[cfg(test)] mod tests { - - use crate::world::{World, Structure, Town}; + use crate::{world::{World}, site::{Site, Town, Structure}}; use super::*; @@ -121,7 +120,10 @@ mod tests { let mut person = Creature::new(Time { time: 0 }, Location{x: 0, y: 0}); person.agenda = Agenda::Idle(0); let mut world = World::new(32); - world.add_structure(Location{x: 10, y: 10}, Structure::Town(Rc::new(Town::new()))); + world.add_site(Site{ + entity: Entity { id: 0, loc: Location{x: 10, y: 10} }, + structure: Structure::Town(Town::new()), + }); person.step(&world); match &person.agenda { Agenda::Traveling(_) => {}, diff --git a/src/events/found_town.rs b/src/events/found_town.rs index 8bf4416..7a7e4a5 100644 --- a/src/events/found_town.rs +++ b/src/events/found_town.rs @@ -1,15 +1,22 @@ -use std::rc::Rc; - -use crate::{state::Action, world::{Town, Structure}, state::GameState, entity::Location}; +use crate::{state::Action, site::{Town, Structure, Site}, state::GameState, entity::{Location, Entity}}; pub struct FoundTown{ pub loc: Location, - pub town: Rc, + pub town: Town, } impl Action for FoundTown { fn apply(&self, state: &mut GameState) { - state.world.add_structure(self.loc, Structure::Town(self.town.clone())); + state.world.add_site( + Site{ + entity: Entity{ + loc: self.loc, + id: 0, + }, + structure: Structure::Town(self.town.clone()), + } + ); + //self.loc, ucture::Town(self.town.clone())); } fn description(&self) -> String { diff --git a/src/events/person_genesis.rs b/src/events/person_genesis.rs index 90a5d8c..3fa5817 100644 --- a/src/events/person_genesis.rs +++ b/src/events/person_genesis.rs @@ -1,9 +1,7 @@ -use std::rc::Rc; - -use crate::{state::{GameState, Action}, world::Town, creature::Creature}; +use crate::{state::{GameState, Action}, creature::Creature, site::Town}; pub struct PersonGenesis { - pub town: Rc, + pub town: Town, pub person: Creature, } diff --git a/src/events/tavern_built.rs b/src/events/tavern_built.rs index 9084c90..c4e6329 100644 --- a/src/events/tavern_built.rs +++ b/src/events/tavern_built.rs @@ -1,16 +1,19 @@ use std::rc::Rc; -use crate::{state::{GameState, Action}, world::{Structure, Tavern}, entity::Location}; +use crate::{state::{GameState, Action}, site::{Structure, Tavern, Site}, entity::{Location, Entity}}; pub struct TavernBuilt { pub loc: Location, - pub tavern: Rc, + pub tavern: Tavern, } impl Action for TavernBuilt { fn apply(&self, state: &mut GameState) { - state.world.add_structure(self.loc, Structure::Tavern(self.tavern.clone())); - state.set_tavern(self.tavern.clone()); + let tavern_id = state.world.add_site(Site{ + entity: Entity{ loc: self.loc, id: 0}, + structure: Structure::Tavern(self.tavern.clone()), + }); + state.set_tavern(tavern_id); } fn description(&self) -> String { diff --git a/src/game.rs b/src/game.rs index 2377edc..7cf8edd 100644 --- a/src/game.rs +++ b/src/game.rs @@ -48,9 +48,7 @@ impl Game { #[cfg(test)] mod tests { - use std::rc::Rc; - - use crate::{world::{World, Terrain, Town}, creature::{Creature, Agenda}, time::Time, entity::Location}; + use crate::{world::{World, Terrain}, creature::{Creature, Agenda}, time::Time, entity::Location}; use super::*; diff --git a/src/main.rs b/src/main.rs index 140da03..06822ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod events; mod time; mod generators; mod creature; +mod site; mod app; mod entity; mod game; diff --git a/src/site.rs b/src/site.rs new file mode 100644 index 0000000..ef821a7 --- /dev/null +++ b/src/site.rs @@ -0,0 +1,56 @@ +use std::fmt; + +use crate::{entity::Entity, generators::TownNameGenerator}; + +#[derive(Clone)] +pub struct Town { + pub name: String, +} + +#[derive(Clone)] +pub struct Tavern { + pub name: String, +} + +#[derive(Clone)] +pub enum Structure { + Town(Town), + Tavern(Tavern), +} + +pub struct Site { + pub entity: Entity, + pub structure: Structure, +} + + +impl Town { + pub fn new() -> Town { + Town { + name: TownNameGenerator::name(), + } + } +} + +impl Tavern { + pub fn new() -> Tavern { + Tavern { + name: TownNameGenerator::name(), + } + } +} + +impl fmt::Display for Structure { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Structure::Town(t) => write!(f, "Town: {}", t.name), + Structure::Tavern(t) => write!(f, "Tavern: {}", t.name), + } + } +} + +impl fmt::Display for Site { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.structure) + } +} \ No newline at end of file diff --git a/src/state.rs b/src/state.rs index 1f2e8b8..27c84ef 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,15 +5,16 @@ use std::rc::Rc; use rand::prelude::*; use crate::entity::{Location, EntityId}; use crate::creature::Creature; +use crate::site::{Town, Tavern}; use crate::time::Time; -use crate::world::{World, Terrain, Town, Tavern}; +use crate::world::{World, Terrain}; use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt}; pub struct GameState { pub time: Time, pub world: World, pub creatures: HashMap, pub events: Vec>, - pub tavern: Option>, + pub tavern: Option, } pub struct Event { @@ -57,7 +58,7 @@ impl GameState { } } - pub fn set_tavern(&mut self, tavern: Rc) { + pub fn set_tavern(&mut self, tavern: EntityId) { self.tavern = Some(tavern); } @@ -74,7 +75,7 @@ impl GameState { pub fn guests(&self) -> Vec { match &self.tavern { Some(tavern) => { - let loc = self.world.get_tavern_location(tavern); + let loc = self.world.get_site_location(*tavern); self.creatures.values().filter(|c| { c.entity.loc == loc }).map(|p| p.entity.id).collect::>() @@ -102,7 +103,7 @@ impl GameState { self.world.map[x][y].terrain == Terrain::Flats || self.world.map[x][y].terrain == Terrain::Hills { - let town = Rc::new(Town::new()); + let town = Town::new(); self.add_event(Event { time: self.time, effect: Box::new(FoundTown { @@ -120,7 +121,7 @@ impl GameState { town: town.clone(), person: Creature::new( self.time.substract_years(rng.gen_range(18..30)), - self.world.get_town_location(&town) + Location { x: x as i32, y: y as i32 } ), }) }); @@ -149,7 +150,7 @@ impl GameState { time: self.time, effect: Box::new(TavernBuilt { loc: Location{ x: x as i32, y: y as i32 }, - tavern: Rc::new(Tavern::new()), + tavern: Tavern::new(), }) }); break; diff --git a/src/world.rs b/src/world.rs index 8434ac3..b0ad34f 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,6 +1,6 @@ use std::{rc::Rc, collections::HashMap, fmt}; -use crate::{generators::TownNameGenerator, entity::Location}; +use crate::{generators::TownNameGenerator, entity::{Location, Entity, EntityId}, site::Site}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Terrain { @@ -14,20 +14,6 @@ pub enum Terrain { HighMountains, } -pub struct Town { - pub name: String, -} - -pub struct Tavern { - pub name: String, -} - -#[derive(Clone)] -pub enum Structure { - Town(Rc), - Tavern(Rc), -} - pub struct WorldCell { pub terrain: Terrain, } @@ -35,7 +21,7 @@ pub struct WorldCell { pub struct World { pub map: Vec>, pub size: usize, - pub structures: HashMap + pub sites: HashMap } impl WorldCell { @@ -59,49 +45,29 @@ impl World { World { map: map, size: size, - structures: HashMap::new(), + sites: HashMap::new(), } } - pub fn add_structure(&mut self, location: Location, structure: Structure) { - self.structures.insert(location, structure); + pub fn add_site(&mut self, mut site: Site) -> EntityId{ + let id = self.sites.len() as EntityId; + site.entity.id = id; + self.sites.insert(site.entity.loc, site); + return id; } - pub fn get_town_location(&self, town: &Rc) -> Location { - for (location, structure) in self.structures.iter() { - match structure { - Structure::Town(t) => { - if Rc::ptr_eq(t, town) { - return *location; - } - } - _ => {} + pub fn get_site_location(&self, site_id: EntityId) -> Location { + for (loc, site) in self.sites.iter() { + if site.entity.id == site_id { + return *loc; } } panic!("Town not found"); } - pub fn get_tavern_location(&self, tavern: &Rc) -> Location { - for (location, structure) in self.structures.iter() { - match structure { - Structure::Tavern(t) => { - if Rc::ptr_eq(t, tavern) { - return *location; - } - } - _ => {} - } - } - panic!("Tavern not found"); - } - - - pub fn get_structure_at(&self, pos: Location) -> Option { - match self.structures.get(&pos) { - Some(s) => Some(s.clone()), - None => None, - } + pub fn get_site_at(&self, pos: Location) -> Option<&Site> { + return self.sites.get(&pos); } } @@ -138,28 +104,3 @@ impl Terrain { } } } - -impl Town { - pub fn new() -> Town { - Town { - name: TownNameGenerator::name(), - } - } -} - -impl Tavern { - pub fn new() -> Tavern { - Tavern { - name: TownNameGenerator::name(), - } - } -} - -impl fmt::Display for Structure { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Structure::Town(t) => write!(f, "Town: {}", t.name), - Structure::Tavern(t) => write!(f, "Tavern: {}", t.name), - } - } -}