Compare commits

..

No commits in common. "62565bd2d16874adabc42b9f6fa26ec5a289362a" and "bdcebeafa85c173ec70650b6a46cc85fba962e48" have entirely different histories.

10 changed files with 110 additions and 117 deletions

View File

@ -122,7 +122,7 @@ impl<'a> App<'a> {
} }
pub fn draw_initial<B: Backend>(&mut self, _f: &mut Frame<B>) {} pub fn draw_initial<B: Backend>(&mut self, f: &mut Frame<B>) {}
pub fn draw_guest_selection<B: Backend>(&mut self, f: &mut Frame<B>) { pub fn draw_guest_selection<B: Backend>(&mut self, f: &mut Frame<B>) {
let chunks = Layout::default() let chunks = Layout::default()

View File

@ -1,7 +1,7 @@
use std::{fmt::Display}; use std::{rc::Rc, fmt::Display};
use rand::prelude::*; use rand::prelude::*;
use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location}}; use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location, EntityId}};
#[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.sites.keys().choose(&mut rng); let dest = world.structures.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);
@ -69,7 +69,6 @@ impl Creature {
} }
} }
#[allow(dead_code)]
pub fn set_agenda(&mut self, agenda: Agenda) { pub fn set_agenda(&mut self, agenda: Agenda) {
self.agenda = agenda; self.agenda = agenda;
} }
@ -78,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_site = state.world.get_site_at(*destination); let dest_struct = state.world.get_structure_at(*destination);
match dest_site { match dest_struct {
Some(site) => { Some(dest) => {
return format!("I'm traveling to {}", site); return format!("I'm traveling to {}", dest);
}, },
None => return format!("I'm traveling to an unknown location"), None => return format!("I'm traveling to an unknown location"),
} }
@ -98,7 +97,8 @@ 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,10 +121,7 @@ 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_site(Site{ world.add_structure(Location{x: 10, y: 10}, Structure::Town(Rc::new(Town::new())));
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,22 +1,15 @@
use crate::{state::Action, site::{Town, Structure, Site}, state::GameState, entity::{Location, Entity}}; use std::rc::Rc;
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: Town, pub town: Rc<Town>,
} }
impl Action for FoundTown { impl Action for FoundTown {
fn apply(&self, state: &mut GameState) { fn apply(&self, state: &mut GameState) {
state.world.add_site( state.world.add_structure(self.loc, Structure::Town(self.town.clone()));
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,7 +1,9 @@
use crate::{state::{GameState, Action}, creature::Creature, site::Town}; use std::rc::Rc;
use crate::{state::{GameState, Action}, world::Town, creature::Creature};
pub struct PersonGenesis { pub struct PersonGenesis {
pub town: Town, pub town: Rc<Town>,
pub person: Creature, pub person: Creature,
} }

View File

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

View File

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

View File

@ -4,7 +4,6 @@ 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;

View File

@ -1,56 +0,0 @@
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

@ -1,19 +1,19 @@
use std::collections::HashMap; use std::collections::HashMap;
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}; use crate::world::{World, Terrain, Town, Tavern};
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<EntityId>, pub tavern: Option<Rc<Tavern>>,
} }
pub struct Event { pub struct Event {
@ -34,7 +34,6 @@ pub trait Action {
} }
impl Event { impl Event {
#[allow(dead_code)]
pub fn description(&self) -> String { pub fn description(&self) -> String {
format!("{}: {}", self.time, self.effect.description()) format!("{}: {}", self.time, self.effect.description())
} }
@ -58,7 +57,7 @@ impl GameState {
} }
} }
pub fn set_tavern(&mut self, tavern: EntityId) { pub fn set_tavern(&mut self, tavern: Rc<Tavern>) {
self.tavern = Some(tavern); self.tavern = Some(tavern);
} }
@ -75,7 +74,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_site_location(*tavern); let loc = self.world.get_tavern_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<_>>()
@ -103,7 +102,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 = Town::new(); 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 {
@ -121,7 +120,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)),
Location { x: x as i32, y: y as i32 } self.world.get_town_location(&town)
), ),
}) })
}); });
@ -150,7 +149,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: Tavern::new(), tavern: Rc::new(Tavern::new()),
}) })
}); });
break; break;

View File

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