use crate::{ constants::{MAP_HEIGHT, MAP_SIZE, MAP_WIDTH, MAP_X, MAP_Y}, vga_color as vga, }; use bracket_lib::{prelude::*, random::RandomNumberGenerator}; use specs::Entity; #[derive(PartialEq, Copy, Clone)] pub enum TileType { Player, Monster(Entity), Wall, BreakableWall, Floor, } pub struct Map { tiles: Vec, border_fg: RGB, border_bg: RGB, } impl BaseMap for Map {} impl Algorithm2D for Map { fn dimensions(&self) -> Point { Point::new(MAP_WIDTH, MAP_HEIGHT) } } impl Default for Map { fn default() -> Self { Self::new() } } impl Map { pub fn new() -> Self { let mut tiles = vec![TileType::Floor; MAP_SIZE]; let mut rng = RandomNumberGenerator::new(); for tile in &mut tiles { if rng.roll_dice(1, 16) < 2 { *tile = TileType::Wall; } else if rng.roll_dice(1, 16) < 2 { *tile = TileType::BreakableWall; } } Self { tiles, border_fg: RGB::named(vga::get_by_index(rng.range(8, 15))), border_bg: RGB::named(vga::get_by_index(rng.range(1, 7) as usize)), } } pub fn get_tiles(&self) -> &Vec { &self.tiles } pub fn draw(&self, ctx: &mut BTerm) { // Border ctx.fill_region( Rect { x1: MAP_X as i32 - 1, x2: MAP_WIDTH as i32 + MAP_X as i32 + 1, y1: MAP_Y as i32 - 1, y2: MAP_HEIGHT as i32 + MAP_Y as i32 + 1, }, to_cp437('▓'), self.border_fg, self.border_bg, ); for (i, tile) in self.tiles.iter().enumerate() { let point = self.index_to_point2d(i); let (x, y) = (point.x as usize, point.y as usize); match tile { TileType::Player | TileType::Monster(_) => { ctx.set( x + MAP_X, y + MAP_Y, RGB::named(vga::BLACK), RGB::named(vga::BLACK), to_cp437(' '), ); } TileType::Floor => { ctx.set( x + MAP_X, y + MAP_Y, RGB::named(vga::BLACK), RGB::named(vga::BLACK), to_cp437(' '), ); } TileType::BreakableWall => { ctx.set( x + MAP_X, y + MAP_Y, RGB::named(vga::YELLOW), RGB::named(vga::BLACK), to_cp437('▓'), ); } TileType::Wall => { ctx.set( x + MAP_X, y + MAP_Y, RGB::named(vga::YELLOW), RGB::named(vga::BLACK), to_cp437('█'), ); } } } } pub fn get_tile_at(&self, point: Point) -> TileType { self.tiles[self.point2d_to_index(point)] } pub fn set_tile_at(&mut self, point: Point, tile: TileType) { let index = self.point2d_to_index(point); self.tiles[index] = tile; } pub fn is_solid(&self, point: Point) -> bool { matches!( self.get_tile_at(point), TileType::Wall | TileType::BreakableWall ) } }