133 lines
3.6 KiB
Rust
133 lines
3.6 KiB
Rust
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<TileType>,
|
|
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<TileType> {
|
|
&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
|
|
)
|
|
}
|
|
}
|