tavern_keeper/src/world.rs

167 lines
3.8 KiB
Rust

use std::{rc::Rc, collections::HashMap, fmt};
use rand::prelude::*;
use crate::generators::TownNameGenerator;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Terrain {
Void,
DeepOcean,
Ocean,
Beach,
Flats,
Hills,
Mountains,
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,
}
pub struct World {
pub map: Vec<Vec<WorldCell>>,
pub size: usize,
pub structures: HashMap<[usize; 2], Structure>
}
impl WorldCell {
pub fn new(terrain: Terrain) -> WorldCell {
WorldCell {
terrain: terrain,
}
}
}
impl World {
pub fn new(size: usize) -> World {
let mut map = Vec::new();
for _ in 0..size {
let mut row = Vec::new();
for _ in 0..size {
row.push(WorldCell::new(Terrain::Void));
}
map.push(row);
}
World {
map: map,
size: size,
structures: HashMap::new(),
}
}
pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) {
self.structures.insert([x, y], structure);
}
pub fn get_town_location(&self, town: &Rc<Town>) -> [usize; 2] {
for (location, structure) in self.structures.iter() {
match structure {
Structure::Town(t) => {
if Rc::ptr_eq(t, town) {
return *location;
}
}
_ => {}
}
}
panic!("Town not found");
}
pub fn get_tavern_location(&self, tavern: &Rc<Tavern>) -> [usize; 2] {
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: [usize; 2]) -> Option<Structure> {
match self.structures.get(&pos) {
Some(s) => Some(s.clone()),
None => None,
}
}
}
impl Terrain {
pub fn from_height(height: f64) -> Terrain {
if height < -2000.0 {
Terrain::DeepOcean
} else if height < 0.0 {
Terrain::Ocean
} else if height < 50.0 {
Terrain::Beach
} else if height < 1000.0 {
Terrain::Flats
} else if height < 2000.0 {
Terrain::Hills
} else if height < 3500.0 {
Terrain::Mountains
} else {
Terrain::HighMountains
}
}
pub fn to_color(self) -> [u8; 3] {
match self {
Terrain::Void => [0, 0, 0],
Terrain::DeepOcean => [20, 60, 255],
Terrain::Ocean => [20, 120, 255],
Terrain::Beach => [255, 255, 100],
Terrain::Flats => [0, 204, 0],
Terrain::Hills => [102, 153, 0],
Terrain::Mountains => [153, 153, 102],
Terrain::HighMountains => [230, 230, 230],
}
}
}
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),
}
}
}