Cleanup code now handled by effects module
This commit is contained in:
parent
64cc39eba1
commit
64aeb189c9
@ -88,29 +88,6 @@ pub struct Item {
|
||||
pub base_value: f32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct SufferDamage {
|
||||
pub amount: Vec<(i32, bool)>,
|
||||
}
|
||||
|
||||
impl SufferDamage {
|
||||
pub fn new_damage(
|
||||
store: &mut WriteStorage<SufferDamage>,
|
||||
victim: Entity,
|
||||
amount: i32,
|
||||
from_player: bool,
|
||||
) {
|
||||
if let Some(suffering) = store.get_mut(victim) {
|
||||
suffering.amount.push((amount, from_player));
|
||||
} else {
|
||||
let dmg = SufferDamage {
|
||||
amount: vec![(amount, from_player)],
|
||||
};
|
||||
store.insert(victim, dmg).expect("Unable to insert damage");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct Ranged {
|
||||
pub range: i32,
|
||||
|
@ -1,109 +1,10 @@
|
||||
use ::rltk::{Point, RandomNumberGenerator};
|
||||
use ::rltk::RandomNumberGenerator;
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use crate::components::{
|
||||
Attributes, Equipped, InBackpack, LootTable, Name, Player, Pools, Position, SufferDamage,
|
||||
};
|
||||
use crate::components::{Equipped, InBackpack, LootTable, Name, Player, Pools, Position};
|
||||
use crate::game_log::GameLog;
|
||||
use crate::gamesystem::{mana_at_level, player_hp_at_level};
|
||||
use crate::particle_system::ParticleBuilder;
|
||||
use crate::raws::{self, SpawnType, RAWS};
|
||||
use crate::{colors, Map, RunState};
|
||||
|
||||
pub struct DamageSystem {}
|
||||
|
||||
impl<'a> System<'a> for DamageSystem {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type SystemData = (
|
||||
WriteStorage<'a, Pools>,
|
||||
WriteStorage<'a, SufferDamage>,
|
||||
ReadStorage<'a, Position>,
|
||||
WriteExpect<'a, Map>,
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, Entity>,
|
||||
ReadStorage<'a, Attributes>,
|
||||
WriteExpect<'a, GameLog>,
|
||||
WriteExpect<'a, ParticleBuilder>,
|
||||
ReadExpect<'a, Point>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (
|
||||
mut stats,
|
||||
mut damage,
|
||||
positions,
|
||||
mut map,
|
||||
entities,
|
||||
player,
|
||||
attributes,
|
||||
mut log,
|
||||
mut particles,
|
||||
player_pos,
|
||||
) = data;
|
||||
let mut xp_gain = 0;
|
||||
let mut gold_gain = 0.0_f32;
|
||||
|
||||
for (entity, mut stats, damage) in (&entities, &mut stats, &damage).join() {
|
||||
gold_gain += stats.gold;
|
||||
for dmg in damage.amount.iter() {
|
||||
if !stats.god_mode {
|
||||
stats.hit_points.current -= dmg.0;
|
||||
}
|
||||
|
||||
if let Some(pos) = positions.get(entity) {
|
||||
let idx = map.xy_idx(pos.x, pos.y);
|
||||
map.bloodstains.insert(idx);
|
||||
}
|
||||
|
||||
if stats.hit_points.current < 1 && dmg.1 {
|
||||
xp_gain += stats.level * 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if xp_gain != 0 || gold_gain != 0.0 {
|
||||
let mut player_stats = stats.get_mut(*player).unwrap();
|
||||
let player_attributes = attributes.get(*player).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;
|
||||
log.append(format!(
|
||||
"Congratulations, you are now level {}",
|
||||
player_stats.level
|
||||
));
|
||||
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;
|
||||
|
||||
for i in 0..10 {
|
||||
if player_pos.y - i > 1 {
|
||||
particles.request(
|
||||
player_pos.x,
|
||||
player_pos.y - i,
|
||||
colors::GOLD,
|
||||
colors::BLACK,
|
||||
rltk::to_cp437('░'),
|
||||
400.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
damage.clear();
|
||||
}
|
||||
}
|
||||
use crate::RunState;
|
||||
|
||||
pub fn delete_the_dead(ecs: &mut World) {
|
||||
let mut dead: Vec<Entity> = Vec::new();
|
||||
|
@ -9,10 +9,10 @@ use crate::{GameLog, Map, RunState};
|
||||
|
||||
pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ecs: &mut World) {
|
||||
// Use the item via the generic system
|
||||
event_trigger(creator, item, targets, ecs);
|
||||
let did_something = event_trigger(creator, item, targets, ecs);
|
||||
|
||||
// If it was a consumable, then it gets deleted
|
||||
if ecs.read_storage::<Consumable>().get(item).is_some() {
|
||||
if did_something && ecs.read_storage::<Consumable>().get(item).is_some() {
|
||||
ecs.entities()
|
||||
.delete(item)
|
||||
.expect("Failed to delete consumable item");
|
||||
@ -24,10 +24,11 @@ pub fn trigger(creator: Option<Entity>, trigger: Entity, targets: &Targets, ecs:
|
||||
ecs.write_storage::<Hidden>().remove(trigger);
|
||||
|
||||
// Use the item via the generic system
|
||||
event_trigger(creator, trigger, targets, ecs);
|
||||
let did_something = event_trigger(creator, trigger, targets, ecs);
|
||||
|
||||
// If it was a single activation, then it gets deleted
|
||||
if ecs
|
||||
if did_something
|
||||
&& ecs
|
||||
.read_storage::<SingleActivation>()
|
||||
.get(trigger)
|
||||
.is_some()
|
||||
@ -38,7 +39,13 @@ pub fn trigger(creator: Option<Entity>, trigger: Entity, targets: &Targets, ecs:
|
||||
}
|
||||
}
|
||||
|
||||
fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs: &mut World) {
|
||||
fn event_trigger(
|
||||
creator: Option<Entity>,
|
||||
entity: Entity,
|
||||
targets: &Targets,
|
||||
ecs: &mut World,
|
||||
) -> bool {
|
||||
let mut did_something = false;
|
||||
let mut gamelog = ecs.fetch_mut::<GameLog>();
|
||||
|
||||
// Providing food
|
||||
@ -46,6 +53,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
add_effect(creator, EffectType::WellFed, targets.clone());
|
||||
let names = ecs.read_storage::<Name>();
|
||||
gamelog.append(format!("You eat the {}.", names.get(entity).unwrap().name));
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
// Magic mapper
|
||||
@ -53,6 +62,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
let mut runstate = ecs.fetch_mut::<RunState>();
|
||||
gamelog.append("The map is revealed to you!");
|
||||
*runstate = RunState::MagicMapReveal { row: 0 };
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
// Town Portal
|
||||
@ -64,6 +75,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
gamelog.append("You are teleported back to town!");
|
||||
let mut runstate = ecs.fetch_mut::<RunState>();
|
||||
*runstate = RunState::TownPortal;
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +89,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
},
|
||||
targets.clone(),
|
||||
);
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
// Damage
|
||||
@ -87,6 +102,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
},
|
||||
targets.clone(),
|
||||
);
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
// Confusion
|
||||
@ -98,6 +115,8 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
},
|
||||
targets.clone(),
|
||||
);
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
// Teleport
|
||||
@ -112,5 +131,9 @@ fn event_trigger(creator: Option<Entity>, entity: Entity, targets: &Targets, ecs
|
||||
},
|
||||
targets.clone(),
|
||||
);
|
||||
|
||||
did_something = true;
|
||||
}
|
||||
|
||||
did_something
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use crate::components::{HungerClock, HungerState, MyTurn, SufferDamage};
|
||||
use crate::components::{HungerClock, HungerState, MyTurn};
|
||||
use crate::effects::{add_effect, EffectType, Targets};
|
||||
use crate::game_log::GameLog;
|
||||
|
||||
pub struct HungerSystem {}
|
||||
@ -11,13 +12,12 @@ impl<'a> System<'a> for HungerSystem {
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, HungerClock>,
|
||||
ReadExpect<'a, Entity>, // The player
|
||||
WriteStorage<'a, SufferDamage>,
|
||||
WriteExpect<'a, GameLog>,
|
||||
ReadStorage<'a, MyTurn>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (entities, mut hunger_clock, player_entity, mut inflict_damage, mut log, turns) = data;
|
||||
let (entities, mut hunger_clock, player_entity, mut log, turns) = data;
|
||||
|
||||
for (entity, mut clock, _myturn) in (&entities, &mut hunger_clock, &turns).join() {
|
||||
clock.duration -= 1;
|
||||
@ -54,7 +54,11 @@ impl<'a> System<'a> for HungerSystem {
|
||||
log.append("Your hunger pangs are getting painful!");
|
||||
}
|
||||
|
||||
SufferDamage::new_damage(&mut inflict_damage, entity, 1, false);
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Damage { amount: 1 },
|
||||
Targets::Single { target: entity },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +268,51 @@ pub fn string_to_slot(slot: &str) -> EquipmentSlot {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! apply_effects {
|
||||
($effects:expr, $eb:expr) => {
|
||||
for effect in $effects.iter() {
|
||||
let effect_name = effect.0.as_str();
|
||||
match effect_name {
|
||||
"provides_healing" => {
|
||||
$eb = $eb.with(ProvidesHealing {
|
||||
heal_amount: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"ranged" => {
|
||||
$eb = $eb.with(Ranged {
|
||||
range: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"damage" => {
|
||||
$eb = $eb.with(InflictsDamage {
|
||||
damage: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"area_of_effect" => {
|
||||
$eb = $eb.with(AreaOfEffect {
|
||||
radius: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"confusion" => {
|
||||
$eb = $eb.with(Confusion {
|
||||
turns: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"magic_mapping" => $eb = $eb.with(MagicMapper {}),
|
||||
"town_portal" => $eb = $eb.with(TownPortal {}),
|
||||
"food" => $eb = $eb.with(ProvidesFood {}),
|
||||
"single_activation" => $eb = $eb.with(SingleActivation {}),
|
||||
_ => {
|
||||
::rltk::console::log(format!(
|
||||
"Warning: consumable effect {} not implemented.",
|
||||
effect_name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn spawn_named_item(
|
||||
raws: &RawMaster,
|
||||
ecs: &mut World,
|
||||
@ -303,45 +348,7 @@ pub fn spawn_named_item(
|
||||
|
||||
if let Some(consumable) = &item_template.consumable {
|
||||
eb = eb.with(Consumable {});
|
||||
for effect in consumable.effects.iter() {
|
||||
let effect_name = effect.0.as_str();
|
||||
match effect_name {
|
||||
"provides_healing" => {
|
||||
eb = eb.with(ProvidesHealing {
|
||||
heal_amount: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"ranged" => {
|
||||
eb = eb.with(Ranged {
|
||||
range: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"damage" => {
|
||||
eb = eb.with(InflictsDamage {
|
||||
damage: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"area_of_effect" => {
|
||||
eb = eb.with(AreaOfEffect {
|
||||
radius: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"confusion" => {
|
||||
eb = eb.with(Confusion {
|
||||
turns: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"magic_mapping" => eb = eb.with(MagicMapper {}),
|
||||
"town_portal" => eb = eb.with(TownPortal {}),
|
||||
"food" => eb = eb.with(ProvidesFood {}),
|
||||
_ => {
|
||||
rltk::console::log(format!(
|
||||
"Warning: consumable effect {} not implemented.",
|
||||
effect_name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
apply_effects!(consumable.effects, eb);
|
||||
}
|
||||
|
||||
if let Some(weapon) = &item_template.weapon {
|
||||
@ -636,17 +643,7 @@ pub fn spawn_named_prop(
|
||||
}
|
||||
if let Some(entry_trigger) = &prop_template.entry_trigger {
|
||||
eb = eb.with(EntryTrigger {});
|
||||
for effect in entry_trigger.effects.iter() {
|
||||
match effect.0.as_str() {
|
||||
"damage" => {
|
||||
eb = eb.with(InflictsDamage {
|
||||
damage: effect.1.parse::<i32>().unwrap(),
|
||||
});
|
||||
}
|
||||
"single_activation" => eb = eb.with(SingleActivation {}),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
apply_effects!(entry_trigger.effects, eb);
|
||||
}
|
||||
if let Some(light) = &prop_template.light {
|
||||
eb = eb
|
||||
|
@ -2,7 +2,6 @@ use ::rltk::{GameState, Point, Rltk};
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use crate::components::*;
|
||||
use crate::damage_system::{self, DamageSystem};
|
||||
use crate::game_log::GameLog;
|
||||
use crate::gui::{self, show_cheat_mode, CheatMenuResult, MainMenuSelection};
|
||||
use crate::hunger_system::HungerSystem;
|
||||
@ -20,7 +19,7 @@ use crate::player::*;
|
||||
use crate::raws::*;
|
||||
use crate::trigger_system::TriggerSystem;
|
||||
use crate::visibility_system::VisibilitySystem;
|
||||
use crate::{ai, camera, effects, saveload_system, spawner};
|
||||
use crate::{ai, camera, damage_system, effects, saveload_system, spawner};
|
||||
|
||||
pub const SHOW_MAPGEN_VISUALIZER: bool = false;
|
||||
|
||||
@ -119,9 +118,6 @@ impl State {
|
||||
let mut melee = MeleeCombatSystem {};
|
||||
melee.run_now(&self.ecs);
|
||||
|
||||
let mut damage = DamageSystem {};
|
||||
damage.run_now(&self.ecs);
|
||||
|
||||
let mut pickup = ItemCollectionSystem {};
|
||||
pickup.run_now(&self.ecs);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user