kroz-rs/src/resources/map.rs

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
)
}
}