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 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(_) => {},

View File

@ -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<Town>,
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 {

View File

@ -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<Town>,
pub town: Town,
pub person: Creature,
}

View File

@ -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<Tavern>,
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 {

View File

@ -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::*;

View File

@ -4,6 +4,7 @@ mod events;
mod time;
mod generators;
mod creature;
mod site;
mod app;
mod entity;
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 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<u32, Creature>,
pub events: Vec<Box<Event>>,
pub tavern: Option<Rc<Tavern>>,
pub tavern: Option<EntityId>,
}
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);
}
@ -74,7 +75,7 @@ impl GameState {
pub fn guests(&self) -> Vec<EntityId> {
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::<Vec<_>>()
@ -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;

View File

@ -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<Town>),
Tavern(Rc<Tavern>),
}
pub struct WorldCell {
pub terrain: Terrain,
}
@ -35,7 +21,7 @@ pub struct WorldCell {
pub struct World {
pub map: Vec<Vec<WorldCell>>,
pub size: usize,
pub structures: HashMap<Location, Structure>
pub sites: HashMap<Location, Site>
}
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<Town>) -> 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<Tavern>) -> 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<Structure> {
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),
}
}
}