use ::rltk::{to_cp437, FontCharType, RGB}; use super::{Map, TileType}; pub fn tile_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) { let (glyph, mut fg, mut bg) = match map.depth { 3 => get_limestone_cavern_glyph(idx, map), 2 => get_forest_glyph(idx, map), _ => get_tile_glyph_default(idx, map), }; if map.bloodstains.contains(&idx) { bg = RGB::from_f32(0.7, 0., 0.); } if !map.visible_tiles[idx] { fg = fg.to_greyscale(); bg = RGB::from_f32(0., 0., 0.); } 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 = RGB::from_f32(0., 0., 0.); let (glyph, fg) = match map.tiles[idx] { TileType::Wall => (to_cp437('▒'), RGB::from_f32(0.7, 0.7, 0.7)), TileType::Bridge => (to_cp437('.'), RGB::named(rltk::CHOCOLATE)), TileType::Road => (to_cp437('≡'), RGB::named(rltk::YELLOW)), TileType::Grass => (to_cp437('"'), RGB::named(rltk::GREEN)), TileType::ShallowWater => (to_cp437('░'), RGB::named(rltk::CYAN)), TileType::DeepWater => (to_cp437('▓'), RGB::named(rltk::BLUE)), TileType::Gravel => (to_cp437(';'), RGB::from_f32(0.5, 0.5, 0.5)), TileType::DownStairs => (to_cp437('>'), RGB::from_f32(0., 1.0, 1.0)), TileType::UpStairs => (to_cp437('<'), RGB::from_f32(0., 1.0, 1.0)), TileType::Stalactite => (to_cp437('╨'), RGB::from_f32(0.5, 0.5, 0.5)), TileType::Stalagmite => (to_cp437('╥'), RGB::from_f32(0.5, 0.5, 0.5)), _ => (to_cp437('░'), RGB::from_f32(0.4, 0.4, 0.4)), }; (glyph, fg, bg) } fn get_forest_glyph(idx: usize, map: &Map) -> (FontCharType, RGB, RGB) { let bg = RGB::from_f32(0., 0., 0.); let (glyph, fg) = match map.tiles[idx] { TileType::Wall => (to_cp437('♣'), RGB::from_f32(0.0, 0.6, 0.0)), TileType::Bridge => (to_cp437('.'), RGB::named(rltk::CHOCOLATE)), TileType::Road => (to_cp437('≡'), RGB::named(rltk::YELLOW)), TileType::Grass => (to_cp437('"'), RGB::named(rltk::GREEN)), TileType::ShallowWater => (to_cp437('~'), RGB::named(rltk::CYAN)), TileType::DeepWater => (to_cp437('~'), RGB::named(rltk::BLUE)), TileType::Gravel => (to_cp437(';'), RGB::from_f32(0.5, 0.5, 0.5)), TileType::DownStairs => (to_cp437('>'), RGB::from_f32(0., 1.0, 1.0)), TileType::UpStairs => (to_cp437('<'), RGB::from_f32(0., 1.0, 1.0)), _ => (to_cp437('"'), RGB::from_f32(0.0, 0.6, 0.0)), }; (glyph, fg, bg) } fn get_tile_glyph_default(idx: usize, map: &Map) -> (rltk::FontCharType, RGB, RGB) { let mut bg = RGB::from_f32(0., 0., 0.); let (glyph, mut fg) = match map.tiles[idx] { TileType::Floor => (to_cp437('.'), RGB::from_f32(0., 0.5, 0.5)), TileType::WoodFloor => (to_cp437('░'), RGB::named(rltk::CHOCOLATE)), TileType::Wall => { let x = idx as i32 % map.width; let y = idx as i32 / map.width; (wall_glyph(&*map, x, y), RGB::from_f32(0., 1.0, 0.)) } TileType::DownStairs => (to_cp437('>'), RGB::from_f32(0., 1.0, 1.0)), TileType::Bridge => (to_cp437('.'), RGB::named(rltk::CHOCOLATE)), TileType::Road => (to_cp437('≡'), RGB::named(rltk::GRAY)), TileType::Grass => (to_cp437('"'), RGB::named(rltk::GREEN)), TileType::ShallowWater => (to_cp437('~'), RGB::named(rltk::CYAN)), TileType::DeepWater => (to_cp437('~'), RGB::named(rltk::NAVY_BLUE)), TileType::Gravel => (to_cp437(';'), RGB::named(rltk::GRAY)), TileType::UpStairs => (to_cp437('<'), RGB::from_f32(0., 1.0, 1.0)), TileType::Stalactite => (to_cp437('╨'), RGB::from_f32(0.5, 0.5, 0.5)), TileType::Stalagmite => (to_cp437('╥'), RGB::from_f32(0.5, 0.5, 0.5)), }; if map.bloodstains.contains(&idx) { bg = RGB::from_f32(0.75, 0., 0.); } if !map.visible_tiles[idx] { fg = fg.to_greyscale(); // Don't show bloodstains out of visual range bg = RGB::from_f32(0., 0., 0.); } (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] }