map themes

This commit is contained in:
Tyrel Souza 2021-08-31 13:52:56 -04:00
parent fae5608d91
commit aee89fade7
8 changed files with 64 additions and 14 deletions

View File

@ -49,6 +49,7 @@ impl State {
resources.insert(Camera::new(map_builder.player_start)); resources.insert(Camera::new(map_builder.player_start));
resources.insert(TurnState::AwaitingInput); resources.insert(TurnState::AwaitingInput);
resources.insert(map_builder.theme);
State { State {
ecs, ecs,
resources, resources,
@ -98,6 +99,7 @@ impl State {
self.resources.insert(map_builder.map); self.resources.insert(map_builder.map);
self.resources.insert(Camera::new(map_builder.player_start)); self.resources.insert(Camera::new(map_builder.player_start));
self.resources.insert(TurnState::AwaitingInput); self.resources.insert(TurnState::AwaitingInput);
self.resources.insert(map_builder.theme);
} }
fn victory(&mut self, ctx: &mut BTerm) { fn victory(&mut self, ctx: &mut BTerm) {

View File

@ -1,9 +1,9 @@
use super::MapArchitect; use super::MapArchitect;
use crate::prelude::*; use crate::prelude::*;
pub struct AutomataArchitect {} pub struct CellularAutomataArchitect {}
impl MapArchitect for AutomataArchitect { impl MapArchitect for CellularAutomataArchitect {
fn new(&mut self, rng: &mut RandomNumberGenerator) -> MapBuilder { fn new(&mut self, rng: &mut RandomNumberGenerator) -> MapBuilder {
let mut mb = MapBuilder { let mut mb = MapBuilder {
map: Map::new(), map: Map::new(),
@ -11,6 +11,7 @@ impl MapArchitect for AutomataArchitect {
monster_spawns: Vec::new(), monster_spawns: Vec::new(),
player_start: Point::zero(), player_start: Point::zero(),
amulet_start: Point::zero(), amulet_start: Point::zero(),
theme: super::themes::DungeonTheme::new(),
}; };
self.random_noise_map(rng, &mut mb.map); self.random_noise_map(rng, &mut mb.map);
for _ in 0..10 { for _ in 0..10 {
@ -25,7 +26,7 @@ impl MapArchitect for AutomataArchitect {
} }
} }
impl AutomataArchitect { impl CellularAutomataArchitect {
fn random_noise_map(&mut self, rng: &mut RandomNumberGenerator, map: &mut Map) { fn random_noise_map(&mut self, rng: &mut RandomNumberGenerator, map: &mut Map) {
map.tiles.iter_mut().for_each(|t| { map.tiles.iter_mut().for_each(|t| {
let roll = rng.range(0, 100); let roll = rng.range(0, 100);

View File

@ -14,6 +14,7 @@ impl MapArchitect for DrunkardsWalkArchitect {
monster_spawns: Vec::new(), monster_spawns: Vec::new(),
player_start: Point::zero(), player_start: Point::zero(),
amulet_start: Point::zero(), amulet_start: Point::zero(),
theme: super::themes::DungeonTheme::new(),
}; };
mb.fill(TileType::Wall); mb.fill(TileType::Wall);
let center = Point::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); let center = Point::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);

View File

@ -11,6 +11,7 @@ impl MapArchitect for EmptyArchitect {
monster_spawns: Vec::new(), monster_spawns: Vec::new(),
player_start: Point::zero(), player_start: Point::zero(),
amulet_start: Point::zero(), amulet_start: Point::zero(),
theme: super::themes::DungeonTheme::new(),
}; };
mb.fill(TileType::Floor); mb.fill(TileType::Floor);
mb.player_start = Point::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2); mb.player_start = Point::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);

View File

@ -3,11 +3,13 @@ mod drunkard;
mod empty; mod empty;
mod prefab; mod prefab;
mod rooms; mod rooms;
mod themes;
use automata::AutomataArchitect; use automata::CellularAutomataArchitect;
use drunkard::DrunkardsWalkArchitect; use drunkard::DrunkardsWalkArchitect;
use empty::EmptyArchitect; use empty::EmptyArchitect;
use rooms::RoomsArchitect; use rooms::RoomsArchitect;
use themes::*;
use crate::map_builder::prefab::apply_prefab; use crate::map_builder::prefab::apply_prefab;
use crate::prelude::*; use crate::prelude::*;
@ -23,6 +25,11 @@ pub struct MapBuilder {
pub monster_spawns: Vec<Point>, pub monster_spawns: Vec<Point>,
pub player_start: Point, pub player_start: Point,
pub amulet_start: Point, pub amulet_start: Point,
pub theme: Box<dyn MapTheme>,
}
pub trait MapTheme: Sync + Send {
fn tile_to_render(&self, tile_type: TileType) -> FontCharType;
} }
impl MapBuilder { impl MapBuilder {
@ -30,12 +37,17 @@ impl MapBuilder {
let mut architect: Box<dyn MapArchitect> = match rng.range(0, 3) { let mut architect: Box<dyn MapArchitect> = match rng.range(0, 3) {
0 => Box::new(DrunkardsWalkArchitect {}), 0 => Box::new(DrunkardsWalkArchitect {}),
1 => Box::new(RoomsArchitect {}), 1 => Box::new(RoomsArchitect {}),
_ => Box::new(AutomataArchitect {}), _ => Box::new(CellularAutomataArchitect {}),
}; };
let mut mb = architect.new(rng); let mut mb = architect.new(rng);
apply_prefab(&mut mb, rng); apply_prefab(&mut mb, rng);
mb.theme = match rng.range(0, 2) {
0 => DungeonTheme::new(),
_ => ForestTheme::new(),
};
mb mb
} }

View File

@ -11,6 +11,7 @@ impl MapArchitect for RoomsArchitect {
monster_spawns: Vec::new(), monster_spawns: Vec::new(),
player_start: Point::zero(), player_start: Point::zero(),
amulet_start: Point::zero(), amulet_start: Point::zero(),
theme: super::themes::DungeonTheme::new(),
}; };
mb.fill(TileType::Wall); mb.fill(TileType::Wall);
mb.build_random_rooms(rng); mb.build_random_rooms(rng);

33
src/map_builder/themes.rs Normal file
View File

@ -0,0 +1,33 @@
use crate::prelude::*;
pub struct DungeonTheme {}
pub struct ForestTheme {}
impl DungeonTheme {
pub fn new() -> Box<dyn MapTheme> {
Box::new(Self {})
}
}
impl MapTheme for DungeonTheme {
fn tile_to_render(&self, tile_type: TileType) -> FontCharType {
match tile_type {
TileType::Floor => to_cp437('.'),
TileType::Wall => to_cp437('#'),
}
}
}
impl ForestTheme {
pub fn new() -> Box<dyn MapTheme> {
Box::new(Self {})
}
}
impl MapTheme for ForestTheme {
fn tile_to_render(&self, tile_type: TileType) -> FontCharType {
match tile_type {
TileType::Floor => to_cp437(';'),
TileType::Wall => to_cp437('"'),
}
}
}

View File

@ -3,7 +3,12 @@ use crate::prelude::*;
#[system] #[system]
#[read_component(Player)] #[read_component(Player)]
#[read_component(FieldOfView)] #[read_component(FieldOfView)]
pub fn map_render(ecs: &SubWorld, #[resource] map: &Map, #[resource] camera: &Camera) { pub fn map_render(
ecs: &SubWorld,
#[resource] map: &Map,
#[resource] camera: &Camera,
#[resource] theme: &Box<dyn MapTheme>,
) {
let mut fov = <&FieldOfView>::query().filter(component::<Player>()); let mut fov = <&FieldOfView>::query().filter(component::<Player>());
let player_fov = fov.iter(ecs).nth(0).unwrap(); let player_fov = fov.iter(ecs).nth(0).unwrap();
let mut draw_batch = DrawBatch::new(); let mut draw_batch = DrawBatch::new();
@ -21,14 +26,8 @@ pub fn map_render(ecs: &SubWorld, #[resource] map: &Map, #[resource] camera: &Ca
} else { } else {
DARK_GRAY DARK_GRAY
}; };
match map.tiles[idx] { let glyph = theme.tile_to_render(map.tiles[idx]);
TileType::Floor => { draw_batch.set(pt - offset, ColorPair::new(tint, BLACK), glyph);
draw_batch.set(pt - offset, ColorPair::new(tint, BLACK), to_cp437('.'));
}
TileType::Wall => {
draw_batch.set(pt - offset, ColorPair::new(tint, BLACK), to_cp437('#'));
}
}
} }
} }
} }