Complete Section 5.21
This commit is contained in:
parent
1cbb70f294
commit
03a90aba44
@ -47,7 +47,7 @@ pub fn death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||||||
|
|
||||||
let mut pools = ecs.write_storage::<Pools>();
|
let mut pools = ecs.write_storage::<Pools>();
|
||||||
let attributes = ecs.read_storage::<Attributes>();
|
let attributes = ecs.read_storage::<Attributes>();
|
||||||
let map = ecs.fetch_mut::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
|
|
||||||
if let Some(pos) = entity_position(ecs, target) {
|
if let Some(pos) = entity_position(ecs, target) {
|
||||||
crate::spatial::remove_entity(target, pos as usize);
|
crate::spatial::remove_entity(target, pos as usize);
|
||||||
|
@ -22,3 +22,30 @@ pub fn aoe_tiles(map: &Map, target: ::rltk::Point, radius: i32) -> Vec<i32> {
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_item_position(ecs: &World, target: Entity) -> Option<i32> {
|
||||||
|
let positions = ecs.read_storage::<Position>();
|
||||||
|
let map = ecs.fetch::<Map>();
|
||||||
|
|
||||||
|
// Easy - it has a position
|
||||||
|
if let Some(pos) = positions.get(target) {
|
||||||
|
return Some(map.xy_idx(pos.x, pos.y) as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe it is carried?
|
||||||
|
if let Some(carried) = ecs.read_storage::<InBackpack>().get(target) {
|
||||||
|
if let Some(pos) = positions.get(carried.owner) {
|
||||||
|
return Some(map.xy_idx(pos.x, pos.y) as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe it is equipped?
|
||||||
|
if let Some(equipped) = ecs.read_storage::<Equipped>().get(target) {
|
||||||
|
if let Some(pos) = positions.get(equipped.owner) {
|
||||||
|
return Some(map.xy_idx(pos.x, pos.y) as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No idea - give up
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -3,9 +3,11 @@ use ::specs::prelude::*;
|
|||||||
use super::{add_effect, EffectType, Targets};
|
use super::{add_effect, EffectType, Targets};
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Confusion, Consumable, Hidden, InflictsDamage, MagicMapper, Name, ProvidesFood,
|
Confusion, Consumable, Hidden, InflictsDamage, MagicMapper, Name, ProvidesFood,
|
||||||
ProvidesHealing, SingleActivation, TeleportTo, TownPortal,
|
ProvidesHealing, SingleActivation, SpawnParticleBurst, SpawnParticleLine, TeleportTo,
|
||||||
|
TownPortal,
|
||||||
};
|
};
|
||||||
use crate::{GameLog, Map, RunState};
|
use crate::effects::{entity_position, targeting};
|
||||||
|
use crate::{colors, GameLog, Map, RunState};
|
||||||
|
|
||||||
pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ecs: &mut World) {
|
pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ecs: &mut World) {
|
||||||
// Use the item via the generic system
|
// Use the item via the generic system
|
||||||
@ -48,6 +50,44 @@ fn event_trigger(
|
|||||||
let mut did_something = false;
|
let mut did_something = false;
|
||||||
let mut gamelog = ecs.fetch_mut::<GameLog>();
|
let mut gamelog = ecs.fetch_mut::<GameLog>();
|
||||||
|
|
||||||
|
// Simple particle spawn
|
||||||
|
if let Some(part) = ecs.read_storage::<SpawnParticleBurst>().get(entity) {
|
||||||
|
add_effect(
|
||||||
|
creator,
|
||||||
|
EffectType::Particle {
|
||||||
|
glyph: part.glyph,
|
||||||
|
fg: part.color,
|
||||||
|
bg: colors::BLACK,
|
||||||
|
lifespan: part.lifetime_ms,
|
||||||
|
},
|
||||||
|
targets.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line particle spawn
|
||||||
|
if let Some(part) = ecs.read_storage::<SpawnParticleLine>().get(entity) {
|
||||||
|
if let Some(start_pos) = targeting::find_item_position(ecs, entity) {
|
||||||
|
match targets {
|
||||||
|
Targets::Tile { tile_idx } => spawn_line_particles(ecs, start_pos, *tile_idx, part),
|
||||||
|
Targets::Tiles { tiles } => tiles
|
||||||
|
.iter()
|
||||||
|
.for_each(|tile_idx| spawn_line_particles(ecs, start_pos, *tile_idx, part)),
|
||||||
|
Targets::Single { target } => {
|
||||||
|
if let Some(end_pos) = entity_position(ecs, *target) {
|
||||||
|
spawn_line_particles(ecs, start_pos, end_pos, part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Targets::TargetList { targets } => {
|
||||||
|
targets.iter().for_each(|target| {
|
||||||
|
if let Some(end_pos) = entity_position(ecs, *target) {
|
||||||
|
spawn_line_particles(ecs, start_pos, end_pos, part);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Providing food
|
// Providing food
|
||||||
if ecs.read_storage::<ProvidesFood>().get(entity).is_some() {
|
if ecs.read_storage::<ProvidesFood>().get(entity).is_some() {
|
||||||
add_effect(creator, EffectType::WellFed, targets.clone());
|
add_effect(creator, EffectType::WellFed, targets.clone());
|
||||||
@ -137,3 +177,26 @@ fn event_trigger(
|
|||||||
|
|
||||||
did_something
|
did_something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleLine) {
|
||||||
|
use ::rltk::{LineAlg, Point};
|
||||||
|
|
||||||
|
let map = ecs.fetch::<Map>();
|
||||||
|
let start_pt = Point::new(start % map.width, end / map.width);
|
||||||
|
let end_pt = Point::new(end % map.width, end / map.width);
|
||||||
|
let line = ::rltk::line2d(LineAlg::Bresenham, start_pt, end_pt);
|
||||||
|
for pt in line.iter() {
|
||||||
|
add_effect(
|
||||||
|
None,
|
||||||
|
EffectType::Particle {
|
||||||
|
glyph: part.glyph,
|
||||||
|
fg: part.color,
|
||||||
|
bg: colors::BLACK,
|
||||||
|
lifespan: part.lifetime_ms,
|
||||||
|
},
|
||||||
|
Targets::Tile {
|
||||||
|
tile_idx: map.xy_idx(pt.x, pt.y) as i32,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -268,6 +268,24 @@ pub fn string_to_slot(slot: &str) -> EquipmentSlot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_particle_line(n: &str) -> SpawnParticleLine {
|
||||||
|
let tokens: Vec<_> = n.split(';').collect();
|
||||||
|
SpawnParticleLine {
|
||||||
|
glyph: rltk::to_cp437(tokens[0].chars().next().unwrap()),
|
||||||
|
color: RGB::from_hex(tokens[1]).expect("Invalid hex rgb color"),
|
||||||
|
lifetime_ms: tokens[2].parse::<f32>().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_particle(n: &str) -> SpawnParticleBurst {
|
||||||
|
let tokens: Vec<_> = n.split(';').collect();
|
||||||
|
SpawnParticleBurst {
|
||||||
|
glyph: rltk::to_cp437(tokens[0].chars().next().unwrap()),
|
||||||
|
color: RGB::from_hex(tokens[1]).expect("Invalid hex rgb color"),
|
||||||
|
lifetime_ms: tokens[2].parse::<f32>().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! apply_effects {
|
macro_rules! apply_effects {
|
||||||
($effects:expr, $eb:expr) => {
|
($effects:expr, $eb:expr) => {
|
||||||
for effect in $effects.iter() {
|
for effect in $effects.iter() {
|
||||||
@ -302,6 +320,8 @@ macro_rules! apply_effects {
|
|||||||
"town_portal" => $eb = $eb.with(TownPortal {}),
|
"town_portal" => $eb = $eb.with(TownPortal {}),
|
||||||
"food" => $eb = $eb.with(ProvidesFood {}),
|
"food" => $eb = $eb.with(ProvidesFood {}),
|
||||||
"single_activation" => $eb = $eb.with(SingleActivation {}),
|
"single_activation" => $eb = $eb.with(SingleActivation {}),
|
||||||
|
"particle_line" => $eb = $eb.with(parse_particle_line(&effect.1)),
|
||||||
|
"particle" => $eb = $eb.with(parse_particle(&effect.1)),
|
||||||
_ => {
|
_ => {
|
||||||
::rltk::console::log(format!(
|
::rltk::console::log(format!(
|
||||||
"Warning: consumable effect {} not implemented.",
|
"Warning: consumable effect {} not implemented.",
|
||||||
|
Loading…
Reference in New Issue
Block a user