Implement Slow and DamageOverTime effects
This commit is contained in:
parent
1fb4bf293f
commit
2f0b9b4535
@ -3,7 +3,8 @@ use std::collections::HashMap;
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
AttributeBonus, Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools, StatusEffect,
|
AttributeBonus, Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools, Slow,
|
||||||
|
StatusEffect,
|
||||||
};
|
};
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::gamesystem::attr_bonus;
|
use crate::gamesystem::attr_bonus;
|
||||||
@ -24,6 +25,7 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
WriteExpect<'a, GameLog>,
|
WriteExpect<'a, GameLog>,
|
||||||
ReadStorage<'a, AttributeBonus>,
|
ReadStorage<'a, AttributeBonus>,
|
||||||
ReadStorage<'a, StatusEffect>,
|
ReadStorage<'a, StatusEffect>,
|
||||||
|
ReadStorage<'a, Slow>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
@ -39,6 +41,7 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
mut gamelog,
|
mut gamelog,
|
||||||
attrbonus,
|
attrbonus,
|
||||||
statuses,
|
statuses,
|
||||||
|
slowed,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
if equip_dirty.is_empty() {
|
if equip_dirty.is_empty() {
|
||||||
@ -99,6 +102,14 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total up hast/slow
|
||||||
|
for (status, slow) in (&statuses, &slowed).join() {
|
||||||
|
if to_update.contains_key(&status.target) {
|
||||||
|
let totals = to_update.get_mut(&status.target).unwrap();
|
||||||
|
totals.initiative += slow.initiative_penalty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the data to Pools
|
// Apply the data to Pools
|
||||||
for (entity, item) in to_update.iter() {
|
for (entity, item) in to_update.iter() {
|
||||||
if let Some(pool) = pools.get_mut(*entity) {
|
if let Some(pool) = pools.get_mut(*entity) {
|
||||||
|
@ -2,7 +2,8 @@ use ::rltk::{DistanceAlg, Point, RandomNumberGenerator};
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Attributes, Duration, EquipmentChanged, Initiative, MyTurn, Pools, Position, StatusEffect,
|
Attributes, DamageOverTime, Duration, EquipmentChanged, Initiative, MyTurn, Pools, Position,
|
||||||
|
StatusEffect,
|
||||||
};
|
};
|
||||||
use crate::RunState;
|
use crate::RunState;
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ impl<'a> System<'a> for InitiativeSystem {
|
|||||||
WriteStorage<'a, Duration>,
|
WriteStorage<'a, Duration>,
|
||||||
WriteStorage<'a, EquipmentChanged>,
|
WriteStorage<'a, EquipmentChanged>,
|
||||||
ReadStorage<'a, StatusEffect>,
|
ReadStorage<'a, StatusEffect>,
|
||||||
|
ReadStorage<'a, DamageOverTime>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
@ -41,6 +43,7 @@ impl<'a> System<'a> for InitiativeSystem {
|
|||||||
mut durations,
|
mut durations,
|
||||||
mut dirty,
|
mut dirty,
|
||||||
statuses,
|
statuses,
|
||||||
|
dots,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
if *runstate != RunState::Ticking {
|
if *runstate != RunState::Ticking {
|
||||||
@ -91,16 +94,30 @@ impl<'a> System<'a> for InitiativeSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle durations
|
||||||
if *runstate == RunState::AwaitingInput {
|
if *runstate == RunState::AwaitingInput {
|
||||||
|
use crate::effects::*;
|
||||||
|
|
||||||
for (effect_entity, duration, status) in (&entities, &mut durations, &statuses).join() {
|
for (effect_entity, duration, status) in (&entities, &mut durations, &statuses).join() {
|
||||||
duration.turns -= 1;
|
if entities.is_alive(status.target) {
|
||||||
if duration.turns < 1 {
|
duration.turns -= 1;
|
||||||
dirty
|
if let Some(dot) = dots.get(effect_entity) {
|
||||||
.insert(status.target, EquipmentChanged {})
|
add_effect(
|
||||||
.expect("Unable to insert EquipmentChanged tag");
|
None,
|
||||||
entities
|
EffectType::Damage { amount: dot.damage },
|
||||||
.delete(effect_entity)
|
Targets::Single {
|
||||||
.expect("Unable to delete status effect tag entity");
|
target: status.target,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if duration.turns < 1 {
|
||||||
|
dirty
|
||||||
|
.insert(status.target, EquipmentChanged {})
|
||||||
|
.expect("Unable to insert EquipmentChanged tag");
|
||||||
|
entities
|
||||||
|
.delete(effect_entity)
|
||||||
|
.expect("Unable to delete status effect tag entity");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,12 @@ pub enum EffectType {
|
|||||||
name: String,
|
name: String,
|
||||||
duration: i32,
|
duration: i32,
|
||||||
},
|
},
|
||||||
|
Slow {
|
||||||
|
initiative_penalty: f32,
|
||||||
|
},
|
||||||
|
DamageOverTime {
|
||||||
|
damage: i32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Who, or what the effect should affect.
|
/// Who, or what the effect should affect.
|
||||||
@ -132,6 +138,8 @@ fn tile_effect_hits_entities(effect: &EffectType) -> bool {
|
|||||||
| EffectType::TeleportTo { .. }
|
| EffectType::TeleportTo { .. }
|
||||||
| EffectType::AttributeEffect { .. }
|
| EffectType::AttributeEffect { .. }
|
||||||
| EffectType::Mana { .. }
|
| EffectType::Mana { .. }
|
||||||
|
| EffectType::Slow { .. }
|
||||||
|
| EffectType::DamageOverTime { .. }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +177,8 @@ fn affect_entity(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||||||
EffectType::Confusion { .. } => damage::add_confusion(ecs, effect, target),
|
EffectType::Confusion { .. } => damage::add_confusion(ecs, effect, target),
|
||||||
EffectType::TeleportTo { .. } => movement::apply_teleport(ecs, effect, target),
|
EffectType::TeleportTo { .. } => movement::apply_teleport(ecs, effect, target),
|
||||||
EffectType::AttributeEffect { .. } => damage::attribute_effect(ecs, effect, target),
|
EffectType::AttributeEffect { .. } => damage::attribute_effect(ecs, effect, target),
|
||||||
|
EffectType::Slow { .. } => damage::slow(ecs, effect, target),
|
||||||
|
EffectType::DamageOverTime { .. } => damage::damage_over_time(ecs, effect, target),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ use ::specs::prelude::*;
|
|||||||
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||||
|
|
||||||
use super::{add_effect, entity_position, EffectSpawner, EffectType, Targets};
|
use super::{add_effect, entity_position, EffectSpawner, EffectType, Targets};
|
||||||
use crate::components::{Attributes, Confusion, Duration, Name, Player, Pools, SerializeMe};
|
use crate::components::{
|
||||||
|
Attributes, Confusion, DamageOverTime, Duration, Name, Player, Pools, SerializeMe, Slow,
|
||||||
|
};
|
||||||
use crate::gamesystem::{mana_at_level, player_hp_at_level};
|
use crate::gamesystem::{mana_at_level, player_hp_at_level};
|
||||||
use crate::{colors, EquipmentChanged, GameLog, Map, StatusEffect};
|
use crate::{colors, EquipmentChanged, GameLog, Map, StatusEffect};
|
||||||
|
|
||||||
@ -180,3 +182,33 @@ pub fn attribute_effect(ecs: &mut World, effect: &EffectSpawner, target: Entity)
|
|||||||
.expect("Failed to insert EquipmentChanged tag");
|
.expect("Failed to insert EquipmentChanged tag");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn slow(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||||
|
if let EffectType::Slow { initiative_penalty } = &effect.effect_type {
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(StatusEffect { target })
|
||||||
|
.with(Slow {
|
||||||
|
initiative_penalty: *initiative_penalty,
|
||||||
|
})
|
||||||
|
.with(Duration { turns: 5 })
|
||||||
|
.with(if *initiative_penalty > 0.0 {
|
||||||
|
Name::from("Slowed")
|
||||||
|
} else {
|
||||||
|
Name::from("Hasted")
|
||||||
|
})
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn damage_over_time(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||||
|
if let EffectType::DamageOverTime { damage } = &effect.effect_type {
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(StatusEffect { target })
|
||||||
|
.with(DamageOverTime { damage: *damage })
|
||||||
|
.with(Duration { turns: 5 })
|
||||||
|
.with(Name::from("Damage Over Time"))
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,10 +2,10 @@ use ::specs::prelude::*;
|
|||||||
|
|
||||||
use super::{add_effect, EffectType, Targets};
|
use super::{add_effect, EffectType, Targets};
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
AttributeBonus, Confusion, Consumable, Duration, Hidden, InflictsDamage, MagicMapper, Name,
|
AttributeBonus, Confusion, Consumable, DamageOverTime, Duration, Hidden, InflictsDamage,
|
||||||
Pools, ProvidesFood, ProvidesHealing, ProvidesIdentification, ProvidesMana,
|
MagicMapper, Name, Pools, ProvidesFood, ProvidesHealing, ProvidesIdentification, ProvidesMana,
|
||||||
ProvidesRemoveCurse, SingleActivation, SpawnParticleBurst, SpawnParticleLine, SpellTemplate,
|
ProvidesRemoveCurse, SingleActivation, Slow, SpawnParticleBurst, SpawnParticleLine,
|
||||||
TeachesSpell, TeleportTo, TownPortal,
|
SpellTemplate, TeachesSpell, TeleportTo, TownPortal,
|
||||||
};
|
};
|
||||||
use crate::effects::{entity_position, targeting};
|
use crate::effects::{entity_position, targeting};
|
||||||
use crate::raws::find_spell_entity;
|
use crate::raws::find_spell_entity;
|
||||||
@ -290,6 +290,32 @@ fn event_trigger(
|
|||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slow
|
||||||
|
if let Some(slow) = ecs.read_storage::<Slow>().get(entity) {
|
||||||
|
add_effect(
|
||||||
|
creator,
|
||||||
|
EffectType::Slow {
|
||||||
|
initiative_penalty: slow.initiative_penalty,
|
||||||
|
},
|
||||||
|
targets.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Damage Over Time
|
||||||
|
if let Some(damage) = ecs.read_storage::<DamageOverTime>().get(entity) {
|
||||||
|
add_effect(
|
||||||
|
creator,
|
||||||
|
EffectType::DamageOverTime {
|
||||||
|
damage: damage.damage,
|
||||||
|
},
|
||||||
|
targets.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
|
||||||
did_something
|
did_something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user