tavern_keeper/src/state.rs

88 lines
2.0 KiB
Rust

use std::rc::Rc;
use rand::prelude::*;
use crate::time::Time;
use crate::world::{World, Terrain, Town};
use crate::events::{FoundTown, WorldGenesis};
pub struct GameState {
pub time: Time,
pub world: World,
pub events: Vec<Box<Event>>
}
pub struct Event {
pub time: Time,
pub effect: Box<dyn Effect>,
}
pub trait Effect {
fn apply(&self, state: &mut GameState);
fn description(&self) -> String;
}
impl Event {
pub fn description(&self) -> String {
format!("{}: {}", self.time, self.effect.description())
}
}
impl GameState {
pub fn new(world: World) -> GameState {
let mut events = Vec::new();
events.push(Box::new(Event {
time: Time { time: 0 },
effect: Box::new(WorldGenesis),
}));
GameState {
time: Time { time: 0 },
world: world,
events: events,
}
}
pub fn add_event(&mut self, event: Event) {
event.effect.apply(self);
self.events.push(Box::new(event));
}
pub fn step(&mut self) {
self.time.time += 1;
}
pub fn step_n(&mut self, n: u32) {
for _ in 0..n {
self.step();
}
}
pub fn step_year(&mut self) {
for _ in 0..360 {
self.step();
}
}
pub fn found_town(&mut self) {
let mut rng = rand::thread_rng();
loop {
let x = rng.gen_range(0..self.world.size);
let y = rng.gen_range(0..self.world.size);
if
self.world.map[x][y].terrain == Terrain::Flats ||
self.world.map[x][y].terrain == Terrain::Hills
{
self.add_event(Event {
time: self.time,
effect: Box::new(FoundTown {
x: x,
y: y,
town: Rc::new(Town::new()),
})
});
break;
}
}
}
}