more refactoring

This commit is contained in:
Niko Abeler 2023-01-04 17:52:58 +01:00
parent bdcebeafa8
commit a1579442e1
9 changed files with 113 additions and 106 deletions

View File

@ -1,7 +1,7 @@
use std::{rc::Rc, fmt::Display}; use std::{fmt::Display};
use rand::prelude::*; 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)] #[derive(Clone, Copy)]
pub enum Profession { pub enum Profession {
@ -41,7 +41,7 @@ impl Creature {
if *days <= 0 { if *days <= 0 {
// pick random destination // pick random destination
let mut rng = rand::thread_rng(); 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()); self.agenda = Agenda::Traveling(*dest.unwrap());
} else { } else {
self.agenda = Agenda::Idle(days - 1); self.agenda = Agenda::Idle(days - 1);
@ -77,10 +77,10 @@ impl Creature {
match &self.agenda { match &self.agenda {
Agenda::Idle(days) => format!("I'll stay here for {} days", days), Agenda::Idle(days) => format!("I'll stay here for {} days", days),
Agenda::Traveling(destination) => { Agenda::Traveling(destination) => {
let dest_struct = state.world.get_structure_at(*destination); let dest_site = state.world.get_site_at(*destination);
match dest_struct { match dest_site {
Some(dest) => { Some(site) => {
return format!("I'm traveling to {}", dest); return format!("I'm traveling to {}", site);
}, },
None => return format!("I'm traveling to an unknown location"), None => return format!("I'm traveling to an unknown location"),
} }
@ -97,8 +97,7 @@ impl Display for Creature {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{world::{World}, site::{Site, Town, Structure}};
use crate::world::{World, Structure, Town};
use super::*; use super::*;
@ -121,7 +120,10 @@ mod tests {
let mut person = Creature::new(Time { time: 0 }, Location{x: 0, y: 0}); let mut person = Creature::new(Time { time: 0 }, Location{x: 0, y: 0});
person.agenda = Agenda::Idle(0); person.agenda = Agenda::Idle(0);
let mut world = World::new(32); 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); person.step(&world);
match &person.agenda { match &person.agenda {
Agenda::Traveling(_) => {}, Agenda::Traveling(_) => {},

View File

@ -1,15 +1,22 @@
use std::rc::Rc; use crate::{state::Action, site::{Town, Structure, Site}, state::GameState, entity::{Location, Entity}};
use crate::{state::Action, world::{Town, Structure}, state::GameState, entity::Location};
pub struct FoundTown{ pub struct FoundTown{
pub loc: Location, pub loc: Location,
pub town: Rc<Town>, pub town: Town,
} }
impl Action for FoundTown { impl Action for FoundTown {
fn apply(&self, state: &mut GameState) { 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 { fn description(&self) -> String {

View File

@ -1,9 +1,7 @@
use std::rc::Rc; use crate::{state::{GameState, Action}, creature::Creature, site::Town};
use crate::{state::{GameState, Action}, world::Town, creature::Creature};
pub struct PersonGenesis { pub struct PersonGenesis {
pub town: Rc<Town>, pub town: Town,
pub person: Creature, pub person: Creature,
} }

View File

@ -1,16 +1,19 @@
use std::rc::Rc; 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 struct TavernBuilt {
pub loc: Location, pub loc: Location,
pub tavern: Rc<Tavern>, pub tavern: Tavern,
} }
impl Action for TavernBuilt { impl Action for TavernBuilt {
fn apply(&self, state: &mut GameState) { fn apply(&self, state: &mut GameState) {
state.world.add_structure(self.loc, Structure::Tavern(self.tavern.clone())); let tavern_id = state.world.add_site(Site{
state.set_tavern(self.tavern.clone()); entity: Entity{ loc: self.loc, id: 0},
structure: Structure::Tavern(self.tavern.clone()),
});
state.set_tavern(tavern_id);
} }
fn description(&self) -> String { fn description(&self) -> String {

View File

@ -48,9 +48,7 @@ impl Game {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::rc::Rc; use crate::{world::{World, Terrain}, creature::{Creature, Agenda}, time::Time, entity::Location};
use crate::{world::{World, Terrain, Town}, creature::{Creature, Agenda}, time::Time, entity::Location};
use super::*; use super::*;

View File

@ -4,6 +4,7 @@ mod events;
mod time; mod time;
mod generators; mod generators;
mod creature; mod creature;
mod site;
mod app; mod app;
mod entity; mod entity;
mod game; mod game;

56
src/site.rs Normal file
View File

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

View File

@ -5,15 +5,16 @@ use std::rc::Rc;
use rand::prelude::*; use rand::prelude::*;
use crate::entity::{Location, EntityId}; use crate::entity::{Location, EntityId};
use crate::creature::Creature; use crate::creature::Creature;
use crate::site::{Town, Tavern};
use crate::time::Time; use crate::time::Time;
use crate::world::{World, Terrain, Town, Tavern}; use crate::world::{World, Terrain};
use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt}; use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt};
pub struct GameState { pub struct GameState {
pub time: Time, pub time: Time,
pub world: World, pub world: World,
pub creatures: HashMap<u32, Creature>, pub creatures: HashMap<u32, Creature>,
pub events: Vec<Box<Event>>, pub events: Vec<Box<Event>>,
pub tavern: Option<Rc<Tavern>>, pub tavern: Option<EntityId>,
} }
pub struct Event { pub struct Event {
@ -57,7 +58,7 @@ impl GameState {
} }
} }
pub fn set_tavern(&mut self, tavern: Rc<Tavern>) { pub fn set_tavern(&mut self, tavern: EntityId) {
self.tavern = Some(tavern); self.tavern = Some(tavern);
} }
@ -74,7 +75,7 @@ impl GameState {
pub fn guests(&self) -> Vec<EntityId> { pub fn guests(&self) -> Vec<EntityId> {
match &self.tavern { match &self.tavern {
Some(tavern) => { Some(tavern) => {
let loc = self.world.get_tavern_location(tavern); let loc = self.world.get_site_location(*tavern);
self.creatures.values().filter(|c| { self.creatures.values().filter(|c| {
c.entity.loc == loc c.entity.loc == loc
}).map(|p| p.entity.id).collect::<Vec<_>>() }).map(|p| p.entity.id).collect::<Vec<_>>()
@ -102,7 +103,7 @@ 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()); let town = Town::new();
self.add_event(Event { self.add_event(Event {
time: self.time, time: self.time,
effect: Box::new(FoundTown { effect: Box::new(FoundTown {
@ -120,7 +121,7 @@ impl GameState {
town: town.clone(), town: town.clone(),
person: Creature::new( person: Creature::new(
self.time.substract_years(rng.gen_range(18..30)), 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, time: self.time,
effect: Box::new(TavernBuilt { effect: Box::new(TavernBuilt {
loc: Location{ x: x as i32, y: y as i32 }, loc: Location{ x: x as i32, y: y as i32 },
tavern: Rc::new(Tavern::new()), tavern: Tavern::new(),
}) })
}); });
break; break;

View File

@ -1,6 +1,6 @@
use std::{rc::Rc, collections::HashMap, fmt}; 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)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Terrain { pub enum Terrain {
@ -14,20 +14,6 @@ pub enum Terrain {
HighMountains, HighMountains,
} }
pub struct Town {
pub name: String,
}
pub struct Tavern {
pub name: String,
}
#[derive(Clone)]
pub enum Structure {
Town(Rc<Town>),
Tavern(Rc<Tavern>),
}
pub struct WorldCell { pub struct WorldCell {
pub terrain: Terrain, pub terrain: Terrain,
} }
@ -35,7 +21,7 @@ pub struct WorldCell {
pub struct World { pub struct World {
pub map: Vec<Vec<WorldCell>>, pub map: Vec<Vec<WorldCell>>,
pub size: usize, pub size: usize,
pub structures: HashMap<Location, Structure> pub sites: HashMap<Location, Site>
} }
impl WorldCell { impl WorldCell {
@ -59,49 +45,29 @@ impl World {
World { World {
map: map, map: map,
size: size, size: size,
structures: HashMap::new(), sites: HashMap::new(),
} }
} }
pub fn add_structure(&mut self, location: Location, structure: Structure) { pub fn add_site(&mut self, mut site: Site) -> EntityId{
self.structures.insert(location, structure); 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<Town>) -> Location { pub fn get_site_location(&self, site_id: EntityId) -> Location {
for (location, structure) in self.structures.iter() { for (loc, site) in self.sites.iter() {
match structure { if site.entity.id == site_id {
Structure::Town(t) => { return *loc;
if Rc::ptr_eq(t, town) {
return *location;
}
}
_ => {}
} }
} }
panic!("Town not found"); panic!("Town not found");
} }
pub fn get_tavern_location(&self, tavern: &Rc<Tavern>) -> Location { pub fn get_site_at(&self, pos: Location) -> Option<&Site> {
for (location, structure) in self.structures.iter() { return self.sites.get(&pos);
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<Structure> {
match self.structures.get(&pos) {
Some(s) => Some(s.clone()),
None => None,
}
} }
} }
@ -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),
}
}
}