From 7f6638762edba01c6a896df70de6aa9b5e5dbd42 Mon Sep 17 00:00:00 2001 From: Nathan Douglas Date: Sun, 24 Oct 2021 11:30:52 -0400 Subject: [PATCH] Splits experience system from death, adds level cheat. Closes #1. --- src/effects/damage.rs | 100 ++++-------------------------------- src/effects/experience.rs | 105 ++++++++++++++++++++++++++++++++++++++ src/effects/mod.rs | 7 +++ src/gamelog/logstore.rs | 34 +++++++----- src/gui/cheat_menu.rs | 10 ++++ src/main.rs | 11 ++++ 6 files changed, 162 insertions(+), 105 deletions(-) create mode 100644 src/effects/experience.rs diff --git a/src/effects/damage.rs b/src/effects/damage.rs index 5f86ca8..43e31c6 100644 --- a/src/effects/damage.rs +++ b/src/effects/damage.rs @@ -1,9 +1,8 @@ use super::*; use crate::components::{ Attributes, Confusion, DamageOverTime, Duration, EquipmentChanged, Name, Player, Pools, - SerializeMe, Skills, Slow, StatusEffect, + SerializeMe, Slow, StatusEffect, }; -use crate::gamesystem::{mana_at_level, player_hp_at_level}; use crate::map::Map; use specs::prelude::*; use specs::saveload::{MarkedBuilder, SimpleMarker}; @@ -58,7 +57,6 @@ pub fn bloodstain(ecs: &mut World, tile_idx: i32) { } pub fn death(ecs: &mut World, effect: &EffectSpawner, target: Entity) { - let mut xp_gain = 0; let mut gold_gain = 0.0f32; let mut pools = ecs.write_storage::(); @@ -71,99 +69,19 @@ pub fn death(ecs: &mut World, effect: &EffectSpawner, target: Entity) { if let Some(source) = effect.creator { if ecs.read_storage::().get(source).is_some() { if let Some(stats) = pools.get(target) { - xp_gain += stats.level * 100; + add_effect( + None, + EffectType::AddExperience { + amount: stats.level * 100, + }, + Targets::Single { target: source }, + ); gold_gain += stats.gold; } - if xp_gain != 0 || gold_gain != 0.0 { + if gold_gain != 0.0 { let mut player_stats = pools.get_mut(source).unwrap(); - let mut player_attributes = attributes.get_mut(source).unwrap(); - player_stats.xp += xp_gain; player_stats.gold += gold_gain; - if player_stats.xp >= player_stats.level * 1000 { - // We've gone up a level! - player_stats.level += 1; - crate::gamelog::Logger::new() - .color(rltk::MAGENTA) - .append("Congratulations, you are now level") - .append(format!("{}", player_stats.level)) - .log(); - - // Improve a random attribute - let attr_to_boost = crate::rng::roll_dice(1, 4); - match attr_to_boost { - 1 => { - player_attributes.might.base += 1; - crate::gamelog::Logger::new() - .color(rltk::GREEN) - .append("You feel stronger!") - .log(); - } - 2 => { - player_attributes.fitness.base += 1; - crate::gamelog::Logger::new() - .color(rltk::GREEN) - .append("You feel healthier!") - .log(); - } - 3 => { - player_attributes.quickness.base += 1; - crate::gamelog::Logger::new() - .color(rltk::GREEN) - .append("You feel quicker!") - .log(); - } - _ => { - player_attributes.intelligence.base += 1; - crate::gamelog::Logger::new() - .color(rltk::GREEN) - .append("You feel smarter!") - .log(); - } - } - - // Improve all skills - let mut skills = ecs.write_storage::(); - let player_skills = skills.get_mut(*ecs.fetch::()).unwrap(); - for sk in player_skills.skills.iter_mut() { - *sk.1 += 1; - } - - ecs.write_storage::() - .insert(*ecs.fetch::(), EquipmentChanged {}) - .expect("Insert Failed"); - - player_stats.hit_points.max = player_hp_at_level( - player_attributes.fitness.base + player_attributes.fitness.modifiers, - player_stats.level, - ); - player_stats.hit_points.current = player_stats.hit_points.max; - player_stats.mana.max = mana_at_level( - player_attributes.intelligence.base - + player_attributes.intelligence.modifiers, - player_stats.level, - ); - player_stats.mana.current = player_stats.mana.max; - - let player_pos = ecs.fetch::(); - let map = ecs.fetch::(); - for i in 0..10 { - if player_pos.y - i > 1 { - add_effect( - None, - EffectType::Particle { - glyph: rltk::to_cp437('░'), - fg: rltk::RGB::named(rltk::GOLD), - bg: rltk::RGB::named(rltk::BLACK), - lifespan: 400.0, - }, - Targets::Tile { - tile_idx: map.xy_idx(player_pos.x, player_pos.y - i) as i32, - }, - ); - } - } - } } } } diff --git a/src/effects/experience.rs b/src/effects/experience.rs new file mode 100644 index 0000000..3b99e38 --- /dev/null +++ b/src/effects/experience.rs @@ -0,0 +1,105 @@ +use super::*; +use specs::prelude::*; +use crate::gamesystem::{ mana_at_level, player_hp_at_level }; +use crate::components::{ Attributes, Pools, Skills, EquipmentChanged }; + +pub fn add_experience(ecs: &mut World, experience_effect: &EffectSpawner, target: Entity) { + let mut pools = ecs.write_storage::(); + let mut attributes = ecs.write_storage::(); + let mut player_stats = pools.get_mut(target).unwrap(); + if let EffectType::AddExperience { amount } = experience_effect.effect_type { + player_stats.xp += amount; + if player_stats.xp >= player_stats.level * 1000 { + add_effect( + None, + EffectType::AddExperienceLevel {}, + Targets::Single { target: target }, + ); + } + } +} + +pub fn add_experience_level(ecs: &mut World, level_effect: &EffectSpawner, target: Entity) { + let mut pools = ecs.write_storage::(); + let mut attributes = ecs.write_storage::(); + let mut player_stats = pools.get_mut(target).unwrap(); + let mut player_attributes = attributes.get_mut(target).unwrap(); + player_stats.level += 1; + crate::gamelog::Logger::new() + .color(rltk::MAGENTA) + .append("Congratulations, you are now level") + .append(format!("{}", player_stats.level)) + .log(); + + let attr_to_boost = crate::rng::roll_dice(1, 4); + match attr_to_boost { + 1 => { + player_attributes.might.base += 1; + crate::gamelog::Logger::new() + .color(rltk::GREEN) + .append("You feel stronger!") + .log(); + } + 2 => { + player_attributes.fitness.base += 1; + crate::gamelog::Logger::new() + .color(rltk::GREEN) + .append("You feel healthier!") + .log(); + } + 3 => { + player_attributes.quickness.base += 1; + crate::gamelog::Logger::new() + .color(rltk::GREEN) + .append("You feel quicker!") + .log(); + } + _ => { + player_attributes.intelligence.base += 1; + crate::gamelog::Logger::new() + .color(rltk::GREEN) + .append("You feel smarter!") + .log(); + } + } + + let mut skills = ecs.write_storage::(); + let player_skills = skills.get_mut(*ecs.fetch::()).unwrap(); + for sk in player_skills.skills.iter_mut() { + *sk.1 += 1; + } + + ecs.write_storage::() + .insert(*ecs.fetch::(), EquipmentChanged {}) + .expect("Insert Failed"); + + player_stats.hit_points.max = player_hp_at_level( + player_attributes.fitness.base + player_attributes.fitness.modifiers, + player_stats.level, + ); + player_stats.hit_points.current = player_stats.hit_points.max; + player_stats.mana.max = mana_at_level( + player_attributes.intelligence.base + player_attributes.intelligence.modifiers, + player_stats.level, + ); + player_stats.mana.current = player_stats.mana.max; + + let player_pos = ecs.fetch::(); + let map = ecs.fetch::(); + for i in 0..10 { + if player_pos.y - i > 1 { + add_effect( + None, + EffectType::Particle { + glyph: rltk::to_cp437('░'), + fg: rltk::RGB::named(rltk::GOLD), + bg: rltk::RGB::named(rltk::BLACK), + lifespan: 400.0, + }, + Targets::Tile { + tile_idx: map.xy_idx(player_pos.x, player_pos.y - i) as i32, + }, + ); + } + } +} diff --git a/src/effects/mod.rs b/src/effects/mod.rs index 7e0eee1..2ec4883 100644 --- a/src/effects/mod.rs +++ b/src/effects/mod.rs @@ -3,6 +3,7 @@ use specs::prelude::*; use std::collections::{HashSet, VecDeque}; use std::sync::Mutex; mod damage; +mod experience; mod targeting; pub use targeting::*; mod hunger; @@ -18,6 +19,10 @@ lazy_static! { #[derive(Debug)] pub enum EffectType { + AddExperience { + amount: i32, + }, + AddExperienceLevel, Damage { amount: i32, }, @@ -169,6 +174,8 @@ fn affect_entity(ecs: &mut World, effect: &mut EffectSpawner, target: Entity) { } effect.dedupe.insert(target); match &effect.effect_type { + EffectType::AddExperience { .. } => experience::add_experience(ecs, effect, target), + EffectType::AddExperienceLevel => experience::add_experience_level(ecs, effect, target), EffectType::Damage { .. } => damage::inflict_damage(ecs, effect, target), EffectType::EntityDeath => damage::death(ecs, effect, target), EffectType::Bloodstain { .. } => { diff --git a/src/gamelog/logstore.rs b/src/gamelog/logstore.rs index 827f323..3482d4f 100644 --- a/src/gamelog/logstore.rs +++ b/src/gamelog/logstore.rs @@ -17,21 +17,27 @@ pub fn clear_log() { pub fn print_log(console: &mut Box, pos: Point) { let mut y = pos.y; let mut x = pos.x; - LOG.lock().unwrap().iter().rev().take(6).rev().for_each(|log| { - log.iter().for_each(|frag| { - console.print_color( - x, - y, - frag.color.to_rgba(1.0), - RGBA::named(rltk::BLACK), - &frag.text, - ); - x += frag.text.len() as i32; - x += 1; + LOG.lock() + .unwrap() + .iter() + .rev() + .take(6) + .rev() + .for_each(|log| { + log.iter().for_each(|frag| { + console.print_color( + x, + y, + frag.color.to_rgba(1.0), + RGBA::named(rltk::BLACK), + &frag.text, + ); + x += frag.text.len() as i32; + x += 1; + }); + y += 1; + x = pos.x; }); - y += 1; - x = pos.x; - }); } pub fn clone_log() -> Vec> { diff --git a/src/gui/cheat_menu.rs b/src/gui/cheat_menu.rs index 4c743cb..ba697c9 100644 --- a/src/gui/cheat_menu.rs +++ b/src/gui/cheat_menu.rs @@ -10,6 +10,7 @@ pub enum CheatMenuResult { Heal, Reveal, GodMode, + LevelUp, } pub fn show_cheat_mode(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult { @@ -54,6 +55,14 @@ pub fn show_cheat_mode(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult { rltk::to_cp437('G'), "God Mode (No Death)", ); + y += 1; + menu_option( + &mut draw_batch, + 17, + y, + rltk::to_cp437('L'), + "Level up", + ); draw_batch.submit(6000); @@ -64,6 +73,7 @@ pub fn show_cheat_mode(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult { VirtualKeyCode::H => CheatMenuResult::Heal, VirtualKeyCode::R => CheatMenuResult::Reveal, VirtualKeyCode::G => CheatMenuResult::GodMode, + VirtualKeyCode::L => CheatMenuResult::LevelUp, VirtualKeyCode::Escape => CheatMenuResult::Cancel, _ => CheatMenuResult::NoResponse, }, diff --git a/src/main.rs b/src/main.rs index 35618d6..35f9b90 100644 --- a/src/main.rs +++ b/src/main.rs @@ -237,6 +237,17 @@ impl GameState for State { player_pools.god_mode = true; newrunstate = RunState::AwaitingInput; } + gui::CheatMenuResult::LevelUp => { + let player = self.ecs.fetch::(); + let mut pools = self.ecs.write_storage::(); + let mut player_pools = pools.get_mut(*player).unwrap(); + crate::effects::add_effect( + None, + crate::effects::EffectType::AddExperienceLevel {}, + crate::effects::Targets::Single { target: *player }, + ); + newrunstate = RunState::Ticking; + } } } RunState::ShowDropItem => {