diff --git a/src/components.rs b/src/components.rs index 3db07f4..c36ff1b 100644 --- a/src/components.rs +++ b/src/components.rs @@ -423,3 +423,8 @@ pub struct WantsToCastSpell { pub spell: Entity, pub target: Option, } + +#[derive(Component, Debug, Serialize, Deserialize, Clone)] +pub struct ProvidesMana { + pub mana_amount: i32, +} diff --git a/src/effects.rs b/src/effects.rs index 433a1c9..5a86373 100644 --- a/src/effects.rs +++ b/src/effects.rs @@ -42,6 +42,9 @@ pub enum EffectType { Healing { amount: i32, }, + Mana { + amount: i32, + }, Confusion { turns: i32, }, @@ -128,6 +131,7 @@ fn tile_effect_hits_entities(effect: &EffectType) -> bool { | EffectType::Confusion { .. } | EffectType::TeleportTo { .. } | EffectType::AttributeEffect { .. } + | EffectType::Mana { .. } ) } @@ -161,6 +165,7 @@ fn affect_entity(ecs: &mut World, effect: &EffectSpawner, target: Entity) { } EffectType::WellFed => hunger::well_fed(ecs, effect, target), EffectType::Healing { .. } => damage::heal_damage(ecs, effect, target), + EffectType::Mana { .. } => damage::restore_mana(ecs, effect, target), EffectType::Confusion { .. } => damage::add_confusion(ecs, effect, target), EffectType::TeleportTo { .. } => movement::apply_teleport(ecs, effect, target), EffectType::AttributeEffect { .. } => damage::attribute_effect(ecs, effect, target), diff --git a/src/effects/damage.rs b/src/effects/damage.rs index 23391d0..381d9a1 100644 --- a/src/effects/damage.rs +++ b/src/effects/damage.rs @@ -129,6 +129,25 @@ pub fn heal_damage(ecs: &mut World, heal: &EffectSpawner, target: Entity) { } } +pub fn restore_mana(ecs: &mut World, mana: &EffectSpawner, target: Entity) { + let mut pools = ecs.write_storage::(); + if let Some(pool) = pools.get_mut(target) { + if let EffectType::Mana { amount } = mana.effect_type { + pool.hit_points.current = i32::min(pool.mana.max, pool.mana.current + amount); + add_effect( + None, + EffectType::Particle { + glyph: ::rltk::to_cp437('‼'), + fg: colors::BLUE, + bg: colors::BLACK, + lifespan: 200.0, + }, + Targets::Single { target }, + ); + } + } +} + pub fn add_confusion(ecs: &mut World, effect: &EffectSpawner, target: Entity) { if let EffectType::Confusion { turns } = &effect.effect_type { ecs.create_entity() diff --git a/src/effects/triggers.rs b/src/effects/triggers.rs index bbe4c8a..e569af7 100644 --- a/src/effects/triggers.rs +++ b/src/effects/triggers.rs @@ -3,8 +3,9 @@ use ::specs::prelude::*; use super::{add_effect, EffectType, Targets}; use crate::components::{ AttributeBonus, Confusion, Consumable, Duration, Hidden, InflictsDamage, MagicMapper, Name, - Pools, ProvidesFood, ProvidesHealing, ProvidesRemoveCurse, SingleActivation, - SpawnParticleBurst, SpawnParticleLine, SpellTemplate, TeleportTo, TownPortal, + Pools, ProvidesFood, ProvidesHealing, ProvidesIdentification, ProvidesMana, + ProvidesRemoveCurse, SingleActivation, SpawnParticleBurst, SpawnParticleLine, SpellTemplate, + TeleportTo, TownPortal, }; use crate::effects::{entity_position, targeting}; use crate::{colors, GameLog, Map, RunState}; @@ -153,6 +154,18 @@ fn event_trigger( did_something = true; } + // Identify Item + if ecs + .read_storage::() + .get(entity) + .is_some() + { + let mut runstate = ecs.fetch_mut::(); + *runstate = RunState::ShowIdentify; + + did_something = true; + } + // Town Portal if ecs.read_storage::().get(entity).is_some() { let map = ecs.fetch::(); @@ -180,6 +193,19 @@ fn event_trigger( did_something = true; } + // Mana + if let Some(mana) = ecs.read_storage::().get(entity) { + add_effect( + creator, + EffectType::Mana { + amount: mana.mana_amount, + }, + targets.clone(), + ); + + did_something = true; + } + // Damage if let Some(damage) = ecs.read_storage::().get(entity) { add_effect( diff --git a/src/main.rs b/src/main.rs index 515ab16..238f885 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,6 +127,7 @@ fn init_state() -> State { ProvidesFood, ProvidesHealing, ProvidesIdentification, + ProvidesMana, ProvidesRemoveCurse, Quips, Ranged, diff --git a/src/player.rs b/src/player.rs index 8b7d2f1..ec9b915 100644 --- a/src/player.rs +++ b/src/player.rs @@ -249,6 +249,11 @@ fn skip_turn(ecs: &mut World) -> RunState { let mut health_components = ecs.write_storage::(); let pools = health_components.get_mut(*player_entity).unwrap(); pools.hit_points.current = i32::min(pools.hit_points.current + 1, pools.hit_points.max); + + let mut rng = ecs.fetch_mut::<::rltk::RandomNumberGenerator>(); + if rng.roll_dice(1, 6) == 1 { + pools.mana.current = i32::min(pools.mana.current + 1, pools.mana.max); + } } RunState::Ticking diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index 9ad8217..0575a91 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -288,6 +288,11 @@ macro_rules! apply_effects { heal_amount: effect.1.parse::().unwrap(), }); } + "provides_mana" => { + $eb = $eb.with(ProvidesMana { + mana_amount: effect.1.parse::().unwrap(), + }) + } "ranged" => { $eb = $eb.with(Ranged { range: effect.1.parse::().unwrap(), @@ -316,9 +321,10 @@ macro_rules! apply_effects { "particle_line" => $eb = $eb.with(parse_particle_line(&effect.1)), "particle" => $eb = $eb.with(parse_particle(&effect.1)), "remove_curse" => $eb = $eb.with(ProvidesRemoveCurse {}), + "identify" => $eb = $eb.with(ProvidesIdentification {}), _ => { console::log(format!( - "Warning: consumable effect '{}' not implemented.", + "WARNING: consumable effect '{}' not implemented.", effect_name )); } diff --git a/src/saveload_system.rs b/src/saveload_system.rs index ac4f397..42097d7 100644 --- a/src/saveload_system.rs +++ b/src/saveload_system.rs @@ -106,6 +106,7 @@ pub fn save_game(ecs: &mut World) { ProvidesFood, ProvidesHealing, ProvidesIdentification, + ProvidesMana, ProvidesRemoveCurse, Quips, Ranged, @@ -232,6 +233,7 @@ pub fn load_game(ecs: &mut World) { ProvidesFood, ProvidesHealing, ProvidesIdentification, + ProvidesMana, ProvidesRemoveCurse, Quips, Ranged, diff --git a/src/spawner.rs b/src/spawner.rs index 1101508..f565d2d 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -201,20 +201,20 @@ pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) { } let (idx, name) = *spawn; + if name == "None" || name.is_empty() { + return; + } + let x = (*idx % width) as i32; let y = (*idx / width) as i32; - let item_result = spawn_named_entity( &RAWS.lock().unwrap(), ecs, name, SpawnType::AtPosition { x, y }, ); - if item_result.is_some() { - return; - } - if !name.is_empty() { + if item_result.is_none() { ::rltk::console::log(format!("WARNING: We don't know how to spawn [{}]!", name)); } }