diff --git a/README.md b/README.md index 3f789c8..31d65ad 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The goal is to closely mimic the look and behavior of the original game, but not ## License -The original "Kroz" copyright 1987 - 2022 Apogee Entertainment Inc. All trademarks and copyrights reserved. +"Kroz" is a registered trademark of Apogee Software, Ltd. +The original "Kroz" copyright 1987 - 2009 Apogee Software, Ltd. All trademarks and copyrights reserved. -This project has no affiliation with Apogee Entertainment Inc. and the code within is licensed under the [GNU General Public License Version 3](https://www.gnu.org/licenses/gpl-3.0.en.html). +This project has no affiliation with Apogee Software, Ltd and its code is licensed under the [GNU General Public License Version 3](https://www.gnu.org/licenses/gpl-3.0.en.html). diff --git a/src/main.rs b/src/main.rs index 136d7d9..2e29d1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,6 @@ pub mod resources; mod sidebar; mod state; pub mod systems; -pub mod tile_data; pub mod vga_color; use bracket_lib::prelude::*; @@ -14,11 +13,11 @@ use components::{ monster::{color_for_kind, glyphs_for_kind, ticks_for_kind, MonsterKind}, Monster, Player, Position, Renderable, }; +use resources::map::TileType; use resources::{Clock, LevelNumber, Map, ShowDebugInfo, SoundEffects, SoundOutput, Stats}; use specs::prelude::*; use state::State; use std::time::Instant; -use tile_data::TileType; use vga_color as vga; @@ -62,12 +61,7 @@ fn main() -> BError { for (i, tile) in &mut map.get_tiles().iter().enumerate() { if rng.roll_dice(1, 16) < 2 && *tile == TileType::Floor { let position = map.index_to_point2d(i); - let kind = match rng.range(0, 3) { - 0 => MonsterKind::Slow, - 1 => MonsterKind::Medium, - 2 => MonsterKind::Fast, - _ => MonsterKind::Slow, - }; + let kind = MonsterKind::Slow; ecs.create_entity() .with(Position { x: position.x, diff --git a/src/resources/map.rs b/src/resources/map.rs index 3e72d57..5ac0194 100644 --- a/src/resources/map.rs +++ b/src/resources/map.rs @@ -1,11 +1,17 @@ use crate::{ constants::{MAP_HEIGHT, MAP_SIZE, MAP_WIDTH, MAP_X, MAP_Y}, - tile_data::{self, TileType}, vga_color as vga, }; use bracket_lib::{prelude::*, random::RandomNumberGenerator}; use specs::Entity; +#[derive(PartialEq, Copy, Clone)] +pub enum TileType { + Wall, + BreakableWall, + Floor, +} + pub struct Map { tiles: Vec, tile_content: Vec>, @@ -35,7 +41,7 @@ impl Map { if rng.roll_dice(1, 16) < 2 { *tile = TileType::Wall; } else if rng.roll_dice(1, 16) < 2 { - *tile = TileType::Block; + *tile = TileType::BreakableWall; } } Self { @@ -82,14 +88,35 @@ impl Map { let point = self.index_to_point2d(i); let (x, y) = (point.x as usize, point.y as usize); - let data = tile_data::tile_data(*tile); - ctx.set( - x + MAP_X, - y + MAP_Y, - data.color_fg, - data.color_bg, - data.glyph, - ); + match tile { + 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('█'), + ); + } + } } } @@ -103,6 +130,9 @@ impl Map { } pub fn is_solid(&self, point: Point) -> bool { - matches!(self.get_tile_at(point), TileType::Wall | TileType::Block) + matches!( + self.get_tile_at(point), + TileType::Wall | TileType::BreakableWall + ) } } diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 330b80e..f497725 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -48,18 +48,3 @@ pub struct Stats { pub teleports: u32, pub keys: u32, } - -type PlayerSurvived = bool; - -impl Stats { - pub fn take_gems(&mut self, num_gems: u32) -> PlayerSurvived { - let new_num_gems = self.gems as i64 - num_gems as i64; - if new_num_gems <= 0 { - self.gems = 0; - false - } else { - self.gems = new_num_gems as u32; - true - } - } -} diff --git a/src/state.rs b/src/state.rs index e69f991..afa3d62 100644 --- a/src/state.rs +++ b/src/state.rs @@ -111,7 +111,9 @@ impl State { } else { if let Some(e) = map.get_tile_content(map.point2d_to_index(destination)) { if let Some(monster) = monsters.get(e) { - stats.take_gems(damage_for_kind(monster.kind)); + if stats.gems > 0 { + stats.gems -= damage_for_kind(monster.kind); + } let _ = entities.delete(e); } } diff --git a/src/systems/monster_ai_system.rs b/src/systems/monster_ai_system.rs index 243aaeb..9b0eeb2 100644 --- a/src/systems/monster_ai_system.rs +++ b/src/systems/monster_ai_system.rs @@ -3,8 +3,8 @@ use crate::{ monster::{self, damage_for_kind, ticks_for_kind}, Monster, Player, Position, Renderable, }, + resources::map::TileType, resources::{Clock, Map, Stats}, - tile_data::TileType, }; use bracket_lib::{prelude::*, random::RandomNumberGenerator}; use specs::prelude::*; @@ -77,17 +77,19 @@ impl<'a> System<'a> for MonsterAiSystem { if let Some(e) = map.get_tile_content(map.point2d_to_index(destination)) { if let Some(_player) = players.get(e) { // TODO: Sound - stats.take_gems(damage_for_kind(monster.kind)); + if stats.gems > 0 { + stats.gems -= damage_for_kind(monster.kind); + } let _ = entities.delete(*entity); } } else { match map.get_tile_at(destination) { TileType::Wall => {} - TileType::Block => { + TileType::BreakableWall => { // TODO: Sound let _ = entities.delete(*entity); } - _ => { + TileType::Floor => { position.x = destination.x; position.y = destination.y; } diff --git a/src/tile_data.rs b/src/tile_data.rs deleted file mode 100644 index 6fe105d..0000000 --- a/src/tile_data.rs +++ /dev/null @@ -1,405 +0,0 @@ -use bracket_lib::prelude::*; - -use crate::vga_color as vga; - -#[derive(PartialEq, Copy, Clone)] -pub struct TileData { - pub glyph: u16, - pub color_fg: (u8, u8, u8), - pub color_bg: (u8, u8, u8), - pub serialized_char: char, - pub blink: bool, -} - -#[derive(PartialEq, Copy, Clone)] -pub enum TileType { - Floor, // 0 - Block, // 4 - Whip, // 5 - Stairs, // 6 - Chest, // 7 - SlowTime, // 8 - Gem, // 9 - Invisible, // 10 - Teleport, // 11 - Key, // 12 - Door, // 13 - Wall, // 14 - SpeedTime, // 15 - Trap, // 16 - River, // 17 - Power, // 18 - Forest, // 19 - Tree, // 20, 252 - Bomb, // 21 - Lava, // 22 - Pit, // 23 - Tome, // 24 - Tunnel, // 25 - Freeze, // 26 - Nugget, // 27 - Quake, // 28 - InvisibleBlock, // 29 - InvisibleWall, // 30 - InvisibleDoor, // 31 - Stop, // 32 - Zap, // 34 - Create, // 35 - Generator, // 36 - Trap2, // 33 - Trap3, // 37 - Trap4, // 39 - Trap5, // 67 - Trap6, // 224 - Trap7, // 225 - Trap8, // 226 - Trap9, // 227 - Trap10, // 228 - Trap11, // 229 - Trap12, // 230 - Trap13, // 231 - Player, // 40 - Punctuation, // 222 - Letter(char), -} - -pub fn tile_data(tile: TileType) -> TileData { - match tile { - TileType::Floor => TileData { - glyph: 0, - serialized_char: ' ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Block => TileData { - glyph: to_cp437('▓'), - serialized_char: 'X', - color_fg: vga::YELLOW, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Whip => TileData { - glyph: to_cp437('⌠'), - serialized_char: 'W', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Stairs => TileData { - glyph: to_cp437('≡'), - serialized_char: 'L', - color_fg: vga::BLACK, - color_bg: vga::WHITE, - blink: true, - }, - TileType::Chest => TileData { - glyph: to_cp437('C'), - serialized_char: 'C', - color_fg: vga::YELLOW_BRIGHT, - color_bg: vga::RED, - blink: false, - }, - TileType::SlowTime => TileData { - glyph: to_cp437('Φ'), - serialized_char: 'S', - color_fg: vga::CYAN_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Gem => TileData { - glyph: to_cp437('♦'), - serialized_char: '+', - color_fg: vga::WHITE, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Invisible => TileData { - glyph: to_cp437('¡'), - serialized_char: 'I', - color_fg: vga::GREEN, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Teleport => TileData { - glyph: to_cp437('↑'), - serialized_char: 'T', - color_fg: vga::MAGENTA_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Key => TileData { - glyph: to_cp437('î'), - serialized_char: 'K', - color_fg: vga::RED_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Door => TileData { - glyph: to_cp437('∞'), - serialized_char: 'D', - color_fg: vga::CYAN, - color_bg: vga::MAGENTA, - blink: false, - }, - TileType::Wall => TileData { - glyph: to_cp437('█'), - serialized_char: '#', - color_fg: vga::YELLOW, - color_bg: vga::BLACK, - blink: false, - }, - TileType::SpeedTime => TileData { - glyph: to_cp437('Θ'), - serialized_char: 'F', - color_fg: vga::CYAN_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap => TileData { - glyph: to_cp437('∙'), - serialized_char: '.', - color_fg: vga::WHITE, - color_bg: vga::BLACK, - blink: false, - }, - TileType::River => TileData { - glyph: to_cp437('≈'), - serialized_char: 'R', - color_fg: vga::BLUE_BRIGHT, - color_bg: vga::BLUE, - blink: false, - }, - TileType::Power => TileData { - glyph: to_cp437('○'), - serialized_char: 'Q', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Forest => TileData { - glyph: to_cp437('█'), - serialized_char: '/', - color_fg: vga::GREEN, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Tree => TileData { - glyph: to_cp437('♣'), - serialized_char: '\\', - color_fg: vga::YELLOW, - color_bg: vga::GREEN, - blink: false, - }, - TileType::Bomb => TileData { - glyph: to_cp437('¥'), - serialized_char: 'B', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Lava => TileData { - glyph: to_cp437('▓'), - serialized_char: 'V', - color_fg: vga::RED_BRIGHT, - color_bg: vga::RED, - blink: false, - }, - TileType::Pit => TileData { - glyph: to_cp437('░'), - serialized_char: '=', - color_fg: vga::WHITE, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Tome => TileData { - glyph: to_cp437('♀'), - serialized_char: 'A', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: true, - }, - TileType::Tunnel => TileData { - glyph: to_cp437('∩'), - serialized_char: 'U', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Freeze => TileData { - glyph: to_cp437('ƒ'), - serialized_char: 'Z', - color_fg: vga::CYAN_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Nugget => TileData { - glyph: to_cp437('☼'), - serialized_char: '*', - color_fg: vga::YELLOW_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Quake => TileData { - glyph: 0, - serialized_char: 'E', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::InvisibleBlock => TileData { - glyph: 0, - serialized_char: ';', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::InvisibleWall => TileData { - glyph: 0, - serialized_char: ':', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::InvisibleDoor => TileData { - glyph: 0, - serialized_char: '`', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Stop => TileData { - glyph: 0, - serialized_char: '-', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Zap => TileData { - glyph: to_cp437('▲'), - serialized_char: '%', - color_fg: vga::RED_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Create => TileData { - glyph: to_cp437('▼'), - serialized_char: ']', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Generator => TileData { - glyph: to_cp437('♠'), - serialized_char: 'G', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap2 => TileData { - glyph: 0, - serialized_char: '@', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap3 => TileData { - glyph: 0, - serialized_char: ')', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap4 => TileData { - glyph: 0, - serialized_char: '(', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap5 => TileData { - glyph: 0, - serialized_char: '$', // Unsure about this - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap6 => TileData { - glyph: 0, - serialized_char: 'α', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap7 => TileData { - glyph: 0, - serialized_char: 'ß', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap8 => TileData { - glyph: 0, - serialized_char: 'Γ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap9 => TileData { - glyph: 0, - serialized_char: 'π', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap10 => TileData { - glyph: 0, - serialized_char: 'Σ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap11 => TileData { - glyph: 0, - serialized_char: 'σ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap12 => TileData { - glyph: 0, - serialized_char: 'µ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Trap13 => TileData { - glyph: 0, - serialized_char: 'τ', - color_fg: vga::BLACK, - color_bg: vga::BLACK, - blink: false, - }, - TileType::Player => TileData { - glyph: to_cp437('≡'), - serialized_char: 'P', - color_fg: vga::BLACK, - color_bg: vga::WHITE, - blink: true, - }, - TileType::Punctuation => TileData { - glyph: to_cp437('!'), - serialized_char: '!', - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::YELLOW, - blink: false, - }, - TileType::Letter(c) => TileData { - glyph: to_cp437(c), - serialized_char: c, - color_fg: vga::WHITE_BRIGHT, - color_bg: vga::YELLOW, - blink: false, - }, - } -}