Beginning the conversion to an Effects system
This commit is contained in:
parent
a6690029e6
commit
efe15705ad
13 changed files with 382 additions and 67 deletions
|
|
@ -16,59 +16,56 @@ impl<'a> System<'a> for AdjacentAI {
|
|||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (mut turns, factions, positions, map, mut wants_to_melee, entities, player) = data;
|
||||
let (mut turns, factions, positions, map, mut want_melee, entities, player) = data;
|
||||
|
||||
let mut turn_done: Vec<Entity> = Vec::new();
|
||||
for (entity, _turn, faction, pos) in (&entities, &turns, &factions, &positions).join() {
|
||||
if entity == *player {
|
||||
continue;
|
||||
}
|
||||
for (entity, _turn, my_faction, pos) in (&entities, &turns, &factions, &positions).join() {
|
||||
if entity != *player {
|
||||
let mut reactions: Vec<(Entity, Reaction)> = Vec::new();
|
||||
let idx = map.xy_idx(pos.x, pos.y);
|
||||
let (w, h) = (map.width, map.height);
|
||||
// Evaluate adjacent squares, add possible reactions
|
||||
let mut eval_idx: usize = idx;
|
||||
let w = map.width;
|
||||
let h = map.height;
|
||||
// Add possible reactions to adjacents for each direction
|
||||
if pos.x > 0 {
|
||||
eval_idx = idx - 1;
|
||||
evaluate(idx - 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.x < w - 1 {
|
||||
eval_idx = idx + 1;
|
||||
evaluate(idx + 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y > 0 {
|
||||
eval_idx = idx - w as usize;
|
||||
evaluate(idx - w as usize, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y < h - 1 {
|
||||
eval_idx = idx + w as usize;
|
||||
evaluate(idx + w as usize, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y > 0 && pos.x > 0 {
|
||||
eval_idx = (idx - w as usize) - 1;
|
||||
evaluate((idx - w as usize) - 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y > 0 && pos.x < w - 1 {
|
||||
eval_idx = (idx - w as usize) + 1;
|
||||
evaluate((idx - w as usize) + 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y < h - 1 && pos.x > 0 {
|
||||
eval_idx = (idx + w as usize) - 1;
|
||||
evaluate((idx + w as usize) - 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
if pos.y < h - 1 && pos.x < w - 1 {
|
||||
eval_idx = (idx + w as usize) + 1;
|
||||
}
|
||||
if eval_idx != idx {
|
||||
evaluate(eval_idx, &factions, &faction.name, &mut reactions);
|
||||
evaluate((idx + w as usize) + 1, &factions, &my_faction.name, &mut reactions);
|
||||
}
|
||||
|
||||
let mut done = false;
|
||||
for reaction in reactions.iter() {
|
||||
if let Reaction::Attack = reaction.1 {
|
||||
wants_to_melee
|
||||
.insert(entity, WantsToMelee { target: reaction.0 })
|
||||
.expect("Error inserting WantsToMelee");
|
||||
want_melee.insert(entity, WantsToMelee { target: reaction.0 }).expect("Error inserting melee");
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if done {
|
||||
turn_done.push(entity);
|
||||
}
|
||||
}
|
||||
// Remove turn from entities that are done
|
||||
}
|
||||
|
||||
// Remove turn marker for those that are done
|
||||
for done in turn_done.iter() {
|
||||
turns.remove(*done);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use super::{
|
|||
gamelog, Attributes, Equipped, GrantsXP, InBackpack, Item, LootTable, Map, Name, ParticleBuilder, Player, Pools,
|
||||
Position, RunState, SufferDamage,
|
||||
};
|
||||
use crate::gamesystem::{mana_per_level, player_hp_per_level};
|
||||
use crate::gamesystem::{hp_per_level, mana_per_level};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ impl<'a> System<'a> for DamageSystem {
|
|||
}
|
||||
}
|
||||
// Roll for HP gain this level
|
||||
let hp_gained = player_hp_per_level(
|
||||
let hp_gained = hp_per_level(
|
||||
&mut rng,
|
||||
player_attributes.constitution.base + player_attributes.constitution.modifiers,
|
||||
);
|
||||
|
|
|
|||
180
src/effects/damage.rs
Normal file
180
src/effects/damage.rs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
use super::{add_effect, targeting, EffectSpawner, EffectType, Entity, Targets, World};
|
||||
use crate::{
|
||||
gamelog,
|
||||
gamesystem::{hp_per_level, mana_per_level},
|
||||
Attributes, GrantsXP, Map, Player, Pools, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
||||
let mut pools = ecs.write_storage::<Pools>();
|
||||
if let Some(target_pool) = pools.get_mut(target) {
|
||||
if !target_pool.god {
|
||||
if let EffectType::Damage { amount } = damage.effect_type {
|
||||
target_pool.hit_points.current -= amount;
|
||||
add_effect(None, EffectType::Bloodstain, Targets::Entity { target });
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('‼'),
|
||||
fg: RGB::named(ORANGE),
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: DEFAULT_PARTICLE_LIFETIME,
|
||||
delay: 0.0,
|
||||
},
|
||||
Targets::Entity { target },
|
||||
);
|
||||
if target_pool.hit_points.current < 1 {
|
||||
add_effect(damage.source, EffectType::EntityDeath, Targets::Entity { target });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bloodstain(ecs: &mut World, target: usize) {
|
||||
let mut map = ecs.fetch_mut::<Map>();
|
||||
// If the current tile isn't bloody, bloody it.
|
||||
if !map.bloodstains.contains(&target) {
|
||||
map.bloodstains.insert(target);
|
||||
return;
|
||||
}
|
||||
let mut spread: i32 = target as i32;
|
||||
let mut attempts: i32 = 0;
|
||||
// Otherwise, roll to move one tile in any direction.
|
||||
// If this tile isn't bloody, bloody it. If not, loop.
|
||||
loop {
|
||||
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
|
||||
attempts += 1;
|
||||
spread = match rng.roll_dice(1, 8) {
|
||||
1 => spread + 1,
|
||||
2 => spread - 1,
|
||||
3 => spread + 1 + map.width,
|
||||
4 => spread - 1 + map.width,
|
||||
5 => spread + 1 - map.width,
|
||||
6 => spread - 1 - map.width,
|
||||
7 => spread + map.width,
|
||||
_ => spread - map.width,
|
||||
};
|
||||
// - If we're in bounds and the tile is unbloodied, bloody it and return.
|
||||
// - If we ever leave bounds, return.
|
||||
// - Roll a dice on each failed attempt, with an increasing change to return (soft-capping max spread)
|
||||
if spread > 0 && spread < (map.height * map.width) {
|
||||
if !map.bloodstains.contains(&(spread as usize)) {
|
||||
map.bloodstains.insert(spread as usize);
|
||||
return;
|
||||
}
|
||||
if rng.roll_dice(1, 10 - attempts) == 1 {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||
let mut xp_gain = 0;
|
||||
let mut pools = ecs.write_storage::<Pools>();
|
||||
let attributes = ecs.read_storage::<Attributes>();
|
||||
console::log("HERE");
|
||||
|
||||
// If the target has a position, remove it from the SpatialMap.
|
||||
if let Some(pos) = targeting::entity_position(ecs, target) {
|
||||
console::log("HEREE");
|
||||
crate::spatial::remove_entity(target, pos as usize);
|
||||
console::log("HEREEE");
|
||||
}
|
||||
// If the target was killed by a source, cont.
|
||||
if let Some(source) = effect.source {
|
||||
// Calc XP value of target.
|
||||
if let Some(xp_value) = ecs.read_storage::<GrantsXP>().get(target) {
|
||||
xp_gain += xp_value.amount;
|
||||
}
|
||||
// If there was XP, run through XP-gain and level-up.
|
||||
if xp_gain != 0 {
|
||||
let mut source_pools = pools.get_mut(source).unwrap();
|
||||
let source_attributes = attributes.get(source).unwrap();
|
||||
source_pools.xp += xp_gain;
|
||||
let mut next_level_requirement = -1;
|
||||
if source_pools.level < 10 {
|
||||
next_level_requirement = 20 * 2_i32.pow(source_pools.level as u32 - 1);
|
||||
} else if source_pools.level < 20 {
|
||||
next_level_requirement = 10000 * 2_i32.pow(source_pools.level as u32 - 10);
|
||||
} else if source_pools.level < 30 {
|
||||
next_level_requirement = 10000000 * (source_pools.level - 19);
|
||||
}
|
||||
if next_level_requirement != -1 && source_pools.xp >= next_level_requirement {
|
||||
source_pools.level += 1;
|
||||
// If it was the PLAYER that levelled up:
|
||||
if ecs.read_storage::<Player>().get(source).is_some() {
|
||||
gamelog::record_event("player_level", 1);
|
||||
gamelog::Logger::new()
|
||||
.append("Welcome to experience level")
|
||||
.append(source_pools.level)
|
||||
.append(".")
|
||||
.log();
|
||||
let player_pos = ecs.fetch::<Point>();
|
||||
let map = ecs.fetch_mut::<Map>();
|
||||
for i in 0..5 {
|
||||
if player_pos.y - i > 1 {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('░'),
|
||||
fg: RGB::named(GOLD),
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: LONG_PARTICLE_LIFETIME,
|
||||
delay: i as f32 * 100.0,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(player_pos.x, player_pos.y - i) },
|
||||
);
|
||||
if i > 2 {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('░'),
|
||||
fg: RGB::named(GOLD),
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: LONG_PARTICLE_LIFETIME,
|
||||
delay: i as f32 * 100.0,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(player_pos.x + (i - 2), player_pos.y - i) },
|
||||
);
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('░'),
|
||||
fg: RGB::named(GOLD),
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: LONG_PARTICLE_LIFETIME,
|
||||
delay: i as f32 * 100.0,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(player_pos.x - (i - 2), player_pos.y - i) },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console::log("DEBUGINFO: Something other than the player levelled up.");
|
||||
// TODO: Growing up, NPC-specific level-up cases.
|
||||
}
|
||||
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
|
||||
let hp_gained = hp_per_level(
|
||||
&mut rng,
|
||||
source_attributes.constitution.base + source_attributes.constitution.modifiers,
|
||||
);
|
||||
let mana_gained = mana_per_level(
|
||||
&mut rng,
|
||||
source_attributes.intelligence.base + source_attributes.intelligence.modifiers,
|
||||
);
|
||||
source_pools.hit_points.max += hp_gained;
|
||||
source_pools.hit_points.current += hp_gained;
|
||||
// Roll for MANA gain this level
|
||||
source_pools.mana.max += mana_gained;
|
||||
source_pools.mana.current += mana_gained;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/effects/mod.rs
Normal file
105
src/effects/mod.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use crate::spatial;
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::Mutex;
|
||||
|
||||
mod damage;
|
||||
mod particles;
|
||||
mod targeting;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref EFFECT_QUEUE: Mutex<VecDeque<EffectSpawner>> = Mutex::new(VecDeque::new());
|
||||
}
|
||||
|
||||
pub enum EffectType {
|
||||
Damage { amount: i32 },
|
||||
Bloodstain,
|
||||
Particle { glyph: FontCharType, fg: RGB, bg: RGB, lifespan: f32, delay: f32 },
|
||||
EntityDeath,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Targets {
|
||||
Entity { target: Entity },
|
||||
EntityList { targets: Vec<Entity> },
|
||||
Tile { target: usize },
|
||||
TileList { targets: Vec<usize> },
|
||||
}
|
||||
|
||||
pub struct EffectSpawner {
|
||||
pub source: Option<Entity>,
|
||||
pub effect_type: EffectType,
|
||||
pub target: Targets,
|
||||
}
|
||||
|
||||
/// Adds an effect to the effects queue
|
||||
pub fn add_effect(source: Option<Entity>, effect_type: EffectType, target: Targets) {
|
||||
let mut lock = EFFECT_QUEUE.lock().unwrap();
|
||||
lock.push_back(EffectSpawner { source, effect_type, target });
|
||||
}
|
||||
|
||||
/// Iterates through the effects queue, applying each effect to their target.
|
||||
pub fn run_effects_queue(ecs: &mut World) {
|
||||
loop {
|
||||
let effect: Option<EffectSpawner> = EFFECT_QUEUE.lock().unwrap().pop_front();
|
||||
if let Some(effect) = effect {
|
||||
target_applicator(ecs, &effect);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies an effect to the correct target(s).
|
||||
fn target_applicator(ecs: &mut World, effect: &EffectSpawner) {
|
||||
match &effect.target {
|
||||
Targets::Tile { target } => affect_tile(ecs, effect, *target),
|
||||
Targets::TileList { targets } => targets.iter().for_each(|target| affect_tile(ecs, effect, *target)),
|
||||
Targets::Entity { target } => affect_entity(ecs, effect, *target),
|
||||
Targets::EntityList { targets } => targets.iter().for_each(|target| affect_entity(ecs, effect, *target)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if a given effect affects entities or not.
|
||||
fn tile_effect_hits_entities(effect: &EffectType) -> bool {
|
||||
match effect {
|
||||
EffectType::Damage { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs an effect on a given tile index
|
||||
fn affect_tile(ecs: &mut World, effect: &EffectSpawner, target: usize) {
|
||||
if tile_effect_hits_entities(&effect.effect_type) {
|
||||
spatial::for_each_tile_content(target, |entity| {
|
||||
affect_entity(ecs, effect, entity);
|
||||
});
|
||||
}
|
||||
|
||||
match &effect.effect_type {
|
||||
EffectType::Bloodstain => damage::bloodstain(ecs, target),
|
||||
EffectType::Particle { .. } => particles::particle_to_tile(ecs, target as i32, &effect),
|
||||
_ => {}
|
||||
}
|
||||
// Run the effect
|
||||
}
|
||||
|
||||
/// Runs an effect on a given entity
|
||||
fn affect_entity(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||
match &effect.effect_type {
|
||||
EffectType::Damage { .. } => damage::inflict_damage(ecs, effect, target),
|
||||
EffectType::Bloodstain { .. } => {
|
||||
if let Some(pos) = targeting::entity_position(ecs, target) {
|
||||
damage::bloodstain(ecs, pos)
|
||||
}
|
||||
}
|
||||
EffectType::Particle { .. } => {
|
||||
if let Some(pos) = targeting::entity_position(ecs, target) {
|
||||
particles::particle_to_tile(ecs, pos as i32, &effect)
|
||||
}
|
||||
}
|
||||
EffectType::EntityDeath => damage::entity_death(ecs, effect, target),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
15
src/effects/particles.rs
Normal file
15
src/effects/particles.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use super::{EffectSpawner, EffectType};
|
||||
use crate::{Map, ParticleBuilder};
|
||||
use specs::prelude::*;
|
||||
|
||||
pub fn particle_to_tile(ecs: &mut World, target: i32, effect: &EffectSpawner) {
|
||||
if let EffectType::Particle { glyph, fg, bg, lifespan, delay } = effect.effect_type {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let mut particle_builder = ecs.fetch_mut::<ParticleBuilder>();
|
||||
if delay <= 0.0 {
|
||||
particle_builder.request(target % map.width, target / map.width, fg, bg, glyph, lifespan);
|
||||
} else {
|
||||
particle_builder.delay(target % map.width, target / map.width, fg, bg, glyph, lifespan, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/effects/targeting.rs
Normal file
10
src/effects/targeting.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use crate::{Map, Position};
|
||||
use specs::prelude::*;
|
||||
|
||||
pub fn entity_position(ecs: &World, target: Entity) -> Option<usize> {
|
||||
if let Some(position) = ecs.read_storage::<Position>().get(target) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
return Some(map.xy_idx(position.x, position.y));
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ pub fn attr_bonus(value: i32) -> i32 {
|
|||
return (value - 10) / 2;
|
||||
}
|
||||
|
||||
pub fn player_hp_per_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32) -> i32 {
|
||||
pub fn hp_per_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32) -> i32 {
|
||||
return rng.roll_dice(1, 8) + attr_bonus(constitution);
|
||||
}
|
||||
|
||||
|
|
@ -12,12 +12,12 @@ pub fn player_hp_per_level(rng: &mut rltk::RandomNumberGenerator, constitution:
|
|||
pub fn player_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 {
|
||||
let mut total = 10 + attr_bonus(constitution);
|
||||
for _i in 0..level {
|
||||
total += player_hp_per_level(rng, constitution);
|
||||
total += hp_per_level(rng, constitution);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
pub fn npc_hp(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 {
|
||||
pub fn npc_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 {
|
||||
if level == 0 {
|
||||
return rng.roll_dice(1, 4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ mod saveload_system;
|
|||
mod spawner;
|
||||
mod visibility_system;
|
||||
use visibility_system::VisibilitySystem;
|
||||
mod map_indexing_system;
|
||||
use map_indexing_system::MapIndexingSystem;
|
||||
mod damage_system;
|
||||
use damage_system::*;
|
||||
mod hunger_system;
|
||||
|
|
@ -32,6 +30,7 @@ mod inventory;
|
|||
mod particle_system;
|
||||
use particle_system::{ParticleBuilder, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME};
|
||||
mod ai;
|
||||
mod effects;
|
||||
mod gamesystem;
|
||||
mod random_table;
|
||||
mod rex_assets;
|
||||
|
|
@ -89,7 +88,7 @@ impl State {
|
|||
}
|
||||
|
||||
fn run_systems(&mut self) {
|
||||
let mut mapindex = MapIndexingSystem {};
|
||||
let mut mapindex = spatial::MapIndexingSystem {};
|
||||
let mut vis = VisibilitySystem {};
|
||||
let mut regen_system = ai::RegenSystem {};
|
||||
let mut energy = ai::EnergySystem {};
|
||||
|
|
@ -123,6 +122,7 @@ impl State {
|
|||
item_id_system.run_now(&self.ecs);
|
||||
melee_system.run_now(&self.ecs);
|
||||
damage_system.run_now(&self.ecs);
|
||||
effects::run_effects_queue(&mut self.ecs);
|
||||
hunger_clock.run_now(&self.ecs);
|
||||
particle_system.run_now(&self.ecs);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::{
|
||||
effects::{add_effect, EffectType, Targets},
|
||||
gamelog, gamesystem, ArmourClassBonus, Attributes, EquipmentSlot, Equipped, HungerClock, HungerState, MeleeWeapon,
|
||||
MultiAttack, Name, NaturalAttacks, ParticleBuilder, Pools, Position, Skill, Skills, SufferDamage, WantsToMelee,
|
||||
WeaponAttribute,
|
||||
MultiAttack, Name, NaturalAttacks, ParticleBuilder, Pools, Position, Skill, Skills, WantsToMelee, WeaponAttribute,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
|
||||
|
|
@ -16,7 +16,6 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
|||
ReadStorage<'a, Attributes>,
|
||||
ReadStorage<'a, Skills>,
|
||||
ReadStorage<'a, Pools>,
|
||||
WriteStorage<'a, SufferDamage>,
|
||||
WriteExpect<'a, ParticleBuilder>,
|
||||
ReadStorage<'a, Position>,
|
||||
ReadStorage<'a, Equipped>,
|
||||
|
|
@ -37,7 +36,6 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
|||
attributes,
|
||||
skills,
|
||||
pools,
|
||||
mut inflict_damage,
|
||||
mut particle_builder,
|
||||
positions,
|
||||
equipped,
|
||||
|
|
@ -223,7 +221,11 @@ impl<'a> System<'a> for MeleeCombatSystem {
|
|||
if let Some(pos) = pos {
|
||||
particle_builder.damage_taken(pos.x, pos.y)
|
||||
}
|
||||
SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage, entity == *player_entity);
|
||||
add_effect(
|
||||
Some(entity),
|
||||
EffectType::Damage { amount: damage },
|
||||
Targets::Entity { target: wants_melee.target },
|
||||
);
|
||||
if entity == *player_entity {
|
||||
something_to_log = true;
|
||||
logger = logger // You hit the <name>.
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ pub fn spawn_named_mob(
|
|||
|
||||
// Should really use existing RNG here
|
||||
let mut rng = rltk::RandomNumberGenerator::new();
|
||||
let mob_hp = npc_hp(&mut rng, mob_con, mob_level);
|
||||
let mob_hp = npc_hp_at_level(&mut rng, mob_con, mob_level);
|
||||
let mob_mana = mana_at_level(&mut rng, mob_int, mob_level);
|
||||
let mob_bac = if mob_template.bac.is_some() { mob_template.bac.unwrap() } else { 10 };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use super::{spatial, BlocksTile, Map, Pools, Position};
|
||||
use crate::{spatial, BlocksTile, Map, Pools, Position};
|
||||
use specs::prelude::*;
|
||||
|
||||
pub struct MapIndexingSystem {}
|
||||
|
|
@ -2,6 +2,9 @@ use crate::{tile_walkable, Map, RunState};
|
|||
use specs::prelude::*;
|
||||
use std::sync::Mutex;
|
||||
|
||||
mod map_indexing_system;
|
||||
pub use map_indexing_system::MapIndexingSystem;
|
||||
|
||||
struct SpatialMap {
|
||||
blocked: Vec<(bool, bool)>,
|
||||
tile_content: Vec<Vec<(Entity, bool)>>,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use super::{
|
||||
effects::{add_effect, EffectType, Targets},
|
||||
gamelog, Confusion, EntityMoved, EntryTrigger, Hidden, InflictsDamage, Map, Name, ParticleBuilder, Position,
|
||||
SingleActivation, SufferDamage,
|
||||
SingleActivation,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
|
||||
|
|
@ -15,7 +16,6 @@ impl<'a> System<'a> for TriggerSystem {
|
|||
ReadStorage<'a, EntryTrigger>,
|
||||
ReadStorage<'a, InflictsDamage>,
|
||||
WriteStorage<'a, Confusion>,
|
||||
WriteStorage<'a, SufferDamage>,
|
||||
WriteStorage<'a, Hidden>,
|
||||
ReadStorage<'a, SingleActivation>,
|
||||
ReadStorage<'a, Name>,
|
||||
|
|
@ -32,7 +32,6 @@ impl<'a> System<'a> for TriggerSystem {
|
|||
entry_trigger,
|
||||
inflicts_damage,
|
||||
mut confusion,
|
||||
mut inflict_damage,
|
||||
mut hidden,
|
||||
single_activation,
|
||||
names,
|
||||
|
|
@ -63,7 +62,11 @@ impl<'a> System<'a> for TriggerSystem {
|
|||
if let Some(damage) = damage {
|
||||
let damage_roll = rng.roll_dice(damage.n_dice, damage.sides) + damage.modifier;
|
||||
particle_builder.damage_taken(pos.x, pos.y);
|
||||
SufferDamage::new_damage(&mut inflict_damage, entity, damage_roll, false);
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Damage { amount: damage_roll },
|
||||
Targets::Entity { target: entity },
|
||||
);
|
||||
}
|
||||
|
||||
let confuses = confusion.get(entity_id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue