diff --git a/src/main.rs b/src/main.rs index 0acfb9f..35f3a38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ mod inventory_system; use inventory_system::*; mod saveload_system; +pub mod random_table; #[derive(PartialEq, Copy, Clone)] pub enum RunState { diff --git a/src/player.rs b/src/player.rs index f43b0c8..08b2aff 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,6 +1,8 @@ +use crate::Monster; + use super::{Map, Player, Position, RunState, State, Viewshed, CombatStats, WantsToMelee, Item, GameLog, WantsToPickupItem, spawner, TileType}; use rltk::{Point, Rltk, VirtualKeyCode}; -use specs::prelude::*; +use specs::{prelude::*, world}; use std::cmp::{max, min}; pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) { @@ -72,6 +74,34 @@ fn get_item(ecs: &mut World) { } } +fn skip_turn(ecs: &mut World) -> RunState { + let player_entity = ecs.fetch::(); + let viewshed_components = ecs.read_storage::(); + let monsters = ecs.read_storage::(); + + let worldmap_resource = ecs.fetch::(); + + let mut can_heal = true; + let viewshed = viewshed_components.get(*player_entity).unwrap(); + for tile in viewshed.visible_tiles.iter() { + let idx = worldmap_resource.xy_idx(tile.x, tile.y); + for entity_id in worldmap_resource.tile_content[idx].iter() { + let mob = monsters.get(*entity_id); + match mob { + None => {} + Some(_) => { can_heal = false; } + } + } + } + + if can_heal { + let mut health_components = ecs.write_storage::(); + let player_hp = health_components.get_mut(*player_entity).unwrap(); + player_hp.hp = i32::max(player_hp.hp + 1, player_hp.max_hp); + } + + RunState::PlayerTurn +} pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { match ctx.key { @@ -112,6 +142,9 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState { return RunState::NextLevel; } } + // Skip turn + VirtualKeyCode::Numpad5 => return skip_turn(&mut gs.ecs), + VirtualKeyCode::Space => return skip_turn(&mut gs.ecs), _ => return RunState::AwaitingInput, }, } diff --git a/src/random_table.rs b/src/random_table.rs new file mode 100644 index 0000000..919ea2d --- /dev/null +++ b/src/random_table.rs @@ -0,0 +1,47 @@ +use rltk::RandomNumberGenerator; + +pub struct RandomEntry { + name : String, + weight : i32, +} + +impl RandomEntry { + pub fn new(name: S, weight: i32) -> RandomEntry { + RandomEntry{ name: name.to_string(), weight } + } +} + +#[derive(Default)] +pub struct RandomTable { + entities : Vec, + total_weight : i32 +} + +impl RandomTable { + pub fn new() -> RandomTable { + RandomTable{ entities: Vec::new(), total_weight: 0 } + } + + pub fn add(mut self, name : S, weight: i32) -> RandomTable { + self.total_weight += weight; + self.entities.push(RandomEntry::new(name.to_string(), weight)); + self + } + + pub fn roll(&self, rng : &mut RandomNumberGenerator) -> String { + if self.total_weight == 0 { return "None".to_string(); } + let mut roll = rng.roll_dice(1, self.total_weight)-1; + let mut index : usize = 0; + + while roll > 0 { + if roll < self.entities[index].weight { + return self.entities[index].name.clone(); + } + + roll -= self.entities[index].weight; + index += 1; + } + + "None".to_string() + } +} diff --git a/src/spawner.rs b/src/spawner.rs index c3b619a..e81f523 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -2,7 +2,7 @@ use crate::{AreaOfEffect, SerializeMe}; use super::{ BlocksTile, CombatStats, Confusion, Consumable, InflictsDamage, Item, Monster, Name, Player, - Position, ProvidesHealing, Ranged, Rect, Renderable, Viewshed, MAPWIDTH, + Position, ProvidesHealing, Ranged, Rect, Renderable, Viewshed, MAPWIDTH, random_table::RandomTable }; use rltk::{RandomNumberGenerator, RGB}; use specs::{ @@ -235,3 +235,13 @@ pub fn confusion_scroll(ecs: &mut World, x: i32, y: i32) { .marked::>() .build(); } + +fn room_table() -> RandomTable { + RandomTable::new() + .add("Goblin", 10) + .add("Orc", 1) + .add("Health Potion", 7) + .add("Fireball Scroll", 2) + .add("Confusion Scroll", 2) + .add("Magic Missile Scroll", 4) +} \ No newline at end of file