From 5c438cc3c02f9992d880a91d9da4bb6cd4618879 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Fri, 21 Jan 2022 11:57:36 -0500 Subject: [PATCH] Implement scrolls to uncurse cursed items --- src/components/tags.rs | 3 +++ src/effects/triggers.rs | 16 ++++++++++++++-- src/gui.rs | 4 ++-- src/gui/menu.rs | 8 +------- src/inventory_system/use_equip.rs | 1 - src/main.rs | 1 + src/raws/rawmaster.rs | 19 ++++++++++--------- src/saveload_system.rs | 2 ++ src/spawner.rs | 12 +++++------- src/state.rs | 15 +++++++++++++++ 10 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/components/tags.rs b/src/components/tags.rs index dea48d9..7714d0a 100644 --- a/src/components/tags.rs +++ b/src/components/tags.rs @@ -45,3 +45,6 @@ pub struct TownPortal {} #[derive(Component, Debug, Serialize, Deserialize, Clone)] pub struct CursedItem {} + +#[derive(Component, Debug, Serialize, Deserialize, Clone)] +pub struct ProvidesRemoveCurse {} diff --git a/src/effects/triggers.rs b/src/effects/triggers.rs index f7d6a4c..3f398d4 100644 --- a/src/effects/triggers.rs +++ b/src/effects/triggers.rs @@ -3,8 +3,8 @@ use ::specs::prelude::*; use super::{add_effect, EffectType, Targets}; use crate::components::{ Confusion, Consumable, Hidden, InflictsDamage, MagicMapper, Name, ProvidesFood, - ProvidesHealing, SingleActivation, SpawnParticleBurst, SpawnParticleLine, TeleportTo, - TownPortal, + ProvidesHealing, ProvidesRemoveCurse, SingleActivation, SpawnParticleBurst, SpawnParticleLine, + TeleportTo, TownPortal, }; use crate::effects::{entity_position, targeting}; use crate::{colors, GameLog, Map, RunState}; @@ -106,6 +106,18 @@ fn event_trigger( did_something = true; } + // Remove Curse + if ecs + .read_storage::() + .get(entity) + .is_some() + { + let mut runstate = ecs.fetch_mut::(); + *runstate = RunState::ShowRemoveCurse; + + did_something = true; + } + // Town Portal if ecs.read_storage::().get(entity).is_some() { let map = ecs.fetch::(); diff --git a/src/gui.rs b/src/gui.rs index 62dbcd9..d93a2d4 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -11,10 +11,10 @@ pub use menu::*; use tooltip::draw_tooltips; use crate::components::{ - Attribute, Attributes, Consumable, CursedItem, Equipped, HungerClock, HungerState, InBackpack, MagicItem, MagicItemClass, Name, ObfuscatedName, Pools, Viewshed, + Attribute, Attributes, Consumable, CursedItem, Equipped, HungerClock, HungerState, InBackpack, + MagicItem, MagicItemClass, Name, ObfuscatedName, Pools, Viewshed, }; use crate::game_log::GameLog; - use crate::{camera, colors, Map, MasterDungeonMap, State}; pub fn get_item_color(ecs: &World, item: Entity) -> RGB { diff --git a/src/gui/menu.rs b/src/gui/menu.rs index 5ca368a..29a4892 100644 --- a/src/gui/menu.rs +++ b/src/gui/menu.rs @@ -1,15 +1,9 @@ - - use ::rltk::{Rltk, VirtualKeyCode, RGB}; use ::specs::prelude::*; use super::enums::*; use super::{get_item_color, get_item_display_name}; -use crate::components::{ - CursedItem, Equipped, InBackpack, - Item, Name, Vendor, -}; - +use crate::components::{CursedItem, Equipped, InBackpack, Item, Name, Vendor}; use crate::rex_assets::RexAssets; use crate::{colors, MasterDungeonMap, RunState, State, VendorMode}; diff --git a/src/inventory_system/use_equip.rs b/src/inventory_system/use_equip.rs index 7fe1085..ad0c18f 100644 --- a/src/inventory_system/use_equip.rs +++ b/src/inventory_system/use_equip.rs @@ -4,7 +4,6 @@ use crate::components::{ CursedItem, EquipmentChanged, Equippable, Equipped, IdentifiedItem, InBackpack, Name, WantsToUseItem, }; - use crate::GameLog; pub struct ItemEquipOnUse {} diff --git a/src/main.rs b/src/main.rs index accb798..c42cbcb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,6 +97,7 @@ fn init_state() -> State { Position, ProvidesFood, ProvidesHealing, + ProvidesRemoveCurse, Quips, Ranged, Renderable, diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index 1e91a48..ba34ec9 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; use ::regex::Regex; -use ::rltk::{RandomNumberGenerator, RGB}; +use ::rltk::{console, RandomNumberGenerator, RGB}; use ::specs::prelude::*; use ::specs::saveload::{MarkedBuilder, SimpleMarker}; @@ -74,7 +74,7 @@ impl RawMaster { let mut used_names: HashSet = HashSet::new(); for (i, item) in self.raws.items.iter().enumerate() { if used_names.contains(&item.name) { - rltk::console::log(format!( + console::log(format!( "WARNING - duplicate item name in raws [{}]", item.name )); @@ -84,7 +84,7 @@ impl RawMaster { } for (i, mob) in self.raws.mobs.iter().enumerate() { if used_names.contains(&mob.name) { - rltk::console::log(format!( + console::log(format!( "WARNING - duplicate mob name in raws [{}]", mob.name )); @@ -94,7 +94,7 @@ impl RawMaster { } for (i, prop) in self.raws.props.iter().enumerate() { if used_names.contains(&prop.name) { - rltk::console::log(format!( + console::log(format!( "WARNING - duplicate prop name in raws [{}]", prop.name )); @@ -105,7 +105,7 @@ impl RawMaster { for spawn in self.raws.spawn_table.iter() { if !used_names.contains(&spawn.name) { - rltk::console::log(format!( + console::log(format!( "WARNING - Spawn tables references unspecified entity {}", spawn.name )); @@ -261,7 +261,7 @@ pub fn string_to_slot(slot: &str) -> EquipmentSlot { "Hands" => EquipmentSlot::Hands, "Melee" => EquipmentSlot::Melee, _ => { - rltk::console::log(format!("Warning: unknown equipment slot type [{}]", slot)); + console::log(format!("Warning: unknown equipment slot type [{}]", slot)); EquipmentSlot::Melee } @@ -322,9 +322,10 @@ macro_rules! apply_effects { "single_activation" => $eb = $eb.with(SingleActivation {}), "particle_line" => $eb = $eb.with(parse_particle_line(&effect.1)), "particle" => $eb = $eb.with(parse_particle(&effect.1)), + "remove_curse" => $eb = $eb.with(ProvidesRemoveCurse {}), _ => { - ::rltk::console::log(format!( - "Warning: consumable effect {} not implemented.", + console::log(format!( + "Warning: consumable effect '{}' not implemented.", effect_name )); } @@ -554,7 +555,7 @@ pub fn spawn_named_mob( skills.skills.insert(Skill::Magic, *sk.1); } _ => { - ::rltk::console::log(format!("Unknown skill referenced [{}]", sk.0)); + console::log(format!("Unknown skill referenced [{}]", sk.0)); } } } diff --git a/src/saveload_system.rs b/src/saveload_system.rs index 5c0525a..dde28e1 100644 --- a/src/saveload_system.rs +++ b/src/saveload_system.rs @@ -102,6 +102,7 @@ pub fn save_game(ecs: &mut World) { Position, ProvidesFood, ProvidesHealing, + ProvidesRemoveCurse, Quips, Ranged, Renderable, @@ -220,6 +221,7 @@ pub fn load_game(ecs: &mut World) { Position, ProvidesFood, ProvidesHealing, + ProvidesRemoveCurse, Quips, Ranged, Renderable, diff --git a/src/spawner.rs b/src/spawner.rs index 59cd913..6636db9 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -174,8 +174,9 @@ pub fn spawn_region( pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) { let map = ecs.fetch::(); let width = map.width as usize; - let x = (*spawn.0 % width) as i32; - let y = (*spawn.0 / width) as i32; + let (idx, name) = *spawn; + let x = (*idx % width) as i32; + let y = (*idx / width) as i32; // Drop this map reference to make the borrow checker happy std::mem::drop(map); @@ -183,17 +184,14 @@ pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) { let item_result = spawn_named_entity( &RAWS.lock().unwrap(), ecs, - spawn.1, + name, SpawnType::AtPosition { x, y }, ); if item_result.is_some() { return; } - rltk::console::log(format!( - "WARNING: We don't know how to spawn [{}]!", - spawn.1 - )); + ::rltk::console::log(format!("WARNING: We don't know how to spawn [{}]!", name)); } pub fn spawn_town_portal(ecs: &mut World) { diff --git a/src/state.rs b/src/state.rs index 19ad58d..1c98f6f 100644 --- a/src/state.rs +++ b/src/state.rs @@ -49,6 +49,7 @@ pub enum RunState { ShowCheatMenu, ShowVendor { vendor: Entity, mode: VendorMode }, TeleportingToOtherLevel { x: i32, y: i32, depth: i32 }, + ShowRemoveCurse, } pub struct State { @@ -260,6 +261,7 @@ impl GameState for State { RunState::TeleportingToOtherLevel { x, y, depth } => { RunState::TeleportingToOtherLevel { x, y, depth } } + RunState::ShowRemoveCurse => RunState::ShowRemoveCurse, _ => RunState::Ticking, }; } @@ -535,6 +537,19 @@ impl GameState for State { newrunstate = RunState::MapGeneration; } + RunState::ShowRemoveCurse => { + let result = gui::remove_curse_menu(self, ctx); + match result.0 { + gui::ItemMenuResult::Cancel => newrunstate = RunState::AwaitingInput, + gui::ItemMenuResult::NoResponse => {} + gui::ItemMenuResult::Selected => { + let item_entity = result.1.unwrap(); + self.ecs.write_storage::().remove(item_entity); + + newrunstate = RunState::Ticking; + } + } + } } {