From 416af96be39a49eaf7f7b3f237483528f712a098 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Mon, 15 Nov 2021 13:27:40 -0500 Subject: [PATCH] Complete the first section --- src/damage_system.rs | 8 +++--- src/gui.rs | 39 +++++++++++++++++++++++++++ src/inventory_system.rs | 5 ++-- src/main.rs | 59 ++++++++++++++++++++++++++++++++++++++++- src/spawner.rs | 2 +- 5 files changed, 106 insertions(+), 7 deletions(-) diff --git a/src/damage_system.rs b/src/damage_system.rs index 59f7116..eabec95 100644 --- a/src/damage_system.rs +++ b/src/damage_system.rs @@ -1,5 +1,4 @@ -use crate::{game_log::GameLog, CombatStats, Name, Player, SufferDamage}; -use rltk::console; +use crate::{game_log::GameLog, CombatStats, Name, Player, RunState, SufferDamage}; use specs::prelude::*; pub struct DamageSystem {} @@ -44,7 +43,10 @@ pub fn delete_the_dead(ecs: &mut World) { dead.push(entity) } - Some(_) => console::log("You are dead"), + Some(_) => { + let mut runstate = ecs.write_resource::(); + *runstate = RunState::GameOver; + } } } } diff --git a/src/gui.rs b/src/gui.rs index 746440f..4f06e10 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -619,3 +619,42 @@ pub fn remove_item_menu(gs: &mut State, ctx: &mut Rltk) -> (ItemMenuResult, Opti }, } } + +#[derive(PartialEq, Copy, Clone)] +pub enum GameOverResult { + NoSelection, + QuitToMenu, +} + +pub fn game_over(ctx: &mut Rltk) -> GameOverResult { + ctx.print_color_centered( + 15, + RGB::named(rltk::YELLOW), + RGB::named(rltk::BLACK), + "Your journey has ended!", + ); + ctx.print_color_centered( + 17, + RGB::named(rltk::WHITE), + RGB::named(rltk::BLACK), + "One day, we'll tell you all about how you did.", + ); + ctx.print_color_centered( + 18, + RGB::named(rltk::WHITE), + RGB::named(rltk::BLACK), + "That day, sadly, is not in this chapter...", + ); + + ctx.print_color_centered( + 20, + RGB::named(rltk::MAGENTA), + RGB::named(rltk::BLACK), + "Press any key to return to the menu.", + ); + + match ctx.key { + None => GameOverResult::NoSelection, + Some(_) => GameOverResult::QuitToMenu, + } +} diff --git a/src/inventory_system.rs b/src/inventory_system.rs index e19410d..dcbfc17 100644 --- a/src/inventory_system.rs +++ b/src/inventory_system.rs @@ -327,7 +327,7 @@ impl<'a> System<'a> for ItemRemoveSystem { Entities<'a>, WriteStorage<'a, WantsToRemoveItem>, WriteStorage<'a, Equipped>, - WriteStorage<'a, InBackpack> + WriteStorage<'a, InBackpack>, ); fn run(&mut self, data: Self::SystemData) { @@ -335,7 +335,8 @@ impl<'a> System<'a> for ItemRemoveSystem { for (entity, to_remove) in (&entities, &wants_remove).join() { equipped.remove(to_remove.item); - backpack.insert(to_remove.item, InBackpack { owner: entity}) + backpack + .insert(to_remove.item, InBackpack { owner: entity }) .expect("Unable to remove item and put in backpack"); } diff --git a/src/main.rs b/src/main.rs index 7584b6c..a37249d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ pub mod saveload_system; mod spawner; mod visibility_system; +use crate::inventory_system::ItemRemoveSystem; use components::*; use damage_system::DamageSystem; pub use game_log::GameLog; @@ -30,7 +31,6 @@ use monster_ai_system::MonsterAI; use player::*; pub use rect::Rect; use visibility_system::VisibilitySystem; -use crate::inventory_system::ItemRemoveSystem; /// Cut down on the amount of syntax to register components macro_rules! register { @@ -63,6 +63,7 @@ pub enum RunState { SaveGame, NextLevel, ShowRemoveItem, + GameOver, } pub struct State { @@ -282,6 +283,15 @@ impl GameState for State { } } } + RunState::GameOver => match gui::game_over(ctx) { + gui::GameOverResult::NoSelection => {} + gui::GameOverResult::QuitToMenu => { + self.game_over_cleanup(); + newrunstate = RunState::MainMenu { + menu_selection: gui::MainMenuSelection::NewGame, + }; + } + }, } { @@ -389,6 +399,53 @@ impl State { player_health.hp = i32::max(player_health.hp, player_health.max_hp / 2); } } + + fn game_over_cleanup(&mut self) { + // Delete everything + let mut to_delete = Vec::new(); + for e in self.ecs.entities().join() { + to_delete.push(e); + } + for del in to_delete.iter() { + self.ecs + .delete_entity(*del) + .expect("Failed to delete entity"); + } + + // Build a new map and place the player + let worldmap; + { + let mut worldmap_resource = self.ecs.write_resource::(); + *worldmap_resource = Map::new_map_rooms_and_corridors(1); + worldmap = worldmap_resource.clone(); + } + + // Spawn bad guys + for room in worldmap.rooms.iter().skip(1) { + spawner::spawn_room(&mut self.ecs, room, 1); + } + + // Place the player and update resources + let (player_x, player_y) = worldmap.rooms[0].center(); + let player_entity = spawner::player(&mut self.ecs, player_x, player_y); + let mut player_position = self.ecs.write_resource::(); + *player_position = Point::new(player_x, player_y); + let mut position_components = self.ecs.write_storage::(); + let mut player_entity_writer = self.ecs.write_resource::(); + *player_entity_writer = player_entity; + let player_pos_comp = position_components.get_mut(player_entity); + if let Some(player_pos_comp) = player_pos_comp { + player_pos_comp.x = player_x; + player_pos_comp.y = player_y; + } + + // Mark the player's visibility as dirty + let mut viewshed_components = self.ecs.write_storage::(); + let vs = viewshed_components.get_mut(player_entity); + if let Some(vs) = vs { + vs.dirty = true; + } + } } fn main() -> rltk::BError { diff --git a/src/spawner.rs b/src/spawner.rs index 5c4afce..b5ff8ec 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -278,4 +278,4 @@ fn tower_shield(ecs: &mut World, x: i32, y: i32) { .with(DefenseBonus { defense: 3 }) .marked::>() .build(); -} \ No newline at end of file +}