roguelike-game/src/map/themes.rs

150 lines
5.1 KiB
Rust

use ::rltk::{to_cp437, FontCharType, RGB};
use super::{Map, TileType};
use crate::colors;
pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let (glyph, mut fg, mut bg) = match map.depth {
3 | 4 => get_limestone_cavern_glyph(idx, map),
2 => get_forest_glyph(idx, map),
_ => get_tile_glyph_default(idx, map),
};
if map.bloodstains.contains(&idx) {
bg = colors::BLOOD;
}
if !map.visible_tiles[idx] {
fg = fg.to_greyscale();
bg = colors::BLACK;
} else if !map.outdoors {
fg = fg * map.light[idx];
bg = bg * map.light[idx];
}
(glyph, fg, bg)
}
fn get_limestone_cavern_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let bg = colors::BLACK;
let (glyph, fg) = match map.tiles[idx] {
TileType::Wall => (to_cp437('▒'), colors::GRAY),
TileType::Bridge => (to_cp437('.'), colors::CHOCOLATE),
TileType::Road => (to_cp437('≡'), colors::YELLOW),
TileType::Grass => (to_cp437('"'), colors::GREEN),
TileType::ShallowWater => (to_cp437('░'), colors::CYAN),
TileType::DeepWater => (to_cp437('▓'), colors::DEEP_WATER),
TileType::Gravel => (to_cp437(';'), colors::MID_GRAY),
TileType::DownStairs => (to_cp437('>'), colors::CYAN),
TileType::UpStairs => (to_cp437('<'), colors::CYAN),
TileType::Stalactite => (to_cp437('╨'), colors::MID_GRAY),
TileType::Stalagmite => (to_cp437('╥'), colors::MID_GRAY),
_ => (to_cp437('░'), colors::DARK_GRAY),
};
(glyph, fg, bg)
}
fn get_forest_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) {
let bg = colors::BLACK;
let (glyph, fg) = match map.tiles[idx] {
TileType::Wall => (to_cp437('♣'), colors::FOREST_GREEN),
TileType::Bridge => (to_cp437('.'), colors::CHOCOLATE),
TileType::Road => (to_cp437('≡'), colors::YELLOW),
TileType::Grass => (to_cp437('"'), colors::GREEN),
TileType::ShallowWater => (to_cp437('~'), colors::CYAN),
TileType::DeepWater => (to_cp437('~'), colors::DEEP_WATER),
TileType::Gravel => (to_cp437(';'), colors::MID_GRAY),
TileType::DownStairs => (to_cp437('>'), colors::CYAN),
TileType::UpStairs => (to_cp437('<'), colors::CYAN),
_ => (to_cp437('"'), colors::FOREST_GREEN),
};
(glyph, fg, bg)
}
fn get_tile_glyph_default(idx: usize, map: &Map) -> (rltk::FontCharType, RGB, RGB) {
let mut bg = colors::BLACK;
let (glyph, mut fg) = match map.tiles[idx] {
TileType::Floor => (to_cp437('.'), colors::DEFAULT_FLOOR),
TileType::WoodFloor => (to_cp437('░'), colors::CHOCOLATE),
TileType::Wall => {
let x = idx as i32 % map.width;
let y = idx as i32 / map.width;
(wall_glyph(&*map, x, y), colors::GREEN)
}
TileType::DownStairs => (to_cp437('>'), colors::CYAN),
TileType::Bridge => (to_cp437('.'), colors::CHOCOLATE),
TileType::Road => (to_cp437('≡'), colors::GRAY),
TileType::Grass => (to_cp437('"'), colors::GREEN),
TileType::ShallowWater => (to_cp437('~'), colors::CYAN),
TileType::DeepWater => (to_cp437('~'), colors::DEEP_WATER),
TileType::Gravel => (to_cp437(';'), colors::GRAY),
TileType::UpStairs => (to_cp437('<'), colors::CYAN),
TileType::Stalactite => (to_cp437('╨'), colors::MID_GRAY),
TileType::Stalagmite => (to_cp437('╥'), colors::MID_GRAY),
};
if map.bloodstains.contains(&idx) {
bg = colors::BLOOD;
}
if !map.visible_tiles[idx] {
fg = fg.to_greyscale();
// Don't show bloodstains out of visual range
bg = colors::BLACK;
}
(glyph, fg, bg)
}
fn wall_glyph(map: &Map, x: i32, y: i32) -> FontCharType {
if x < 1 || x > map.width - 2 || y < 1 || y > map.height - 2 {
return 35;
}
let mut mask = 0u8;
if is_revealed_and_wall(map, x, y - 1) {
mask += 1;
}
if is_revealed_and_wall(map, x, y + 1) {
mask += 2;
}
if is_revealed_and_wall(map, x - 1, y) {
mask += 4;
}
if is_revealed_and_wall(map, x + 1, y) {
mask += 8;
}
match mask {
0 => 9, // Pillar because we can't see neighbors
1 => 186, // Wall only to the north
2 => 186, // Wall only to the south
3 => 186, // Wall to the north and south
4 => 205, // Wall only to the west
5 => 188, // Wall to the north and west
6 => 187, // Wall to the south and west
7 => 185, // Wall to the north, south, and west
8 => 205, // Wall only to the east
9 => 200, // Wall to the north and east
10 => 201, // Wall to the sound and east
11 => 204, // Wall to the north, south, and east
12 => 205, // Wall to the east and west
13 => 202, // Wall to the east, west, and south
14 => 203, // Wall to the east, west, and north
15 => 206, // ╬ Wall on all sides
_ => 35, // We missed one?
}
}
fn is_revealed_and_wall(map: &Map, x: i32, y: i32) -> bool {
let idx = map.xy_idx(x, y);
map.tiles[idx] == TileType::Wall && map.revealed_tiles[idx]
}