fancy particle effects
This commit is contained in:
parent
5f23822f62
commit
366c5d6543
8 changed files with 189 additions and 79 deletions
|
|
@ -1,5 +1,6 @@
|
|||
use super::{EffectSpawner, EffectType};
|
||||
use crate::{Map, ParticleBuilder};
|
||||
use super::{add_effect, targeting, EffectSpawner, EffectType, Targets};
|
||||
use crate::{Map, ParticleBuilder, SpawnParticleBurst, SpawnParticleLine, SpawnParticleSimple};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
pub fn particle_to_tile(ecs: &mut World, target: i32, effect: &EffectSpawner) {
|
||||
|
|
@ -13,3 +14,148 @@ pub fn particle_to_tile(ecs: &mut World, target: i32, effect: &EffectSpawner) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_simple_particles(ecs: &World, entity: Entity, target: &Targets) {
|
||||
if let Some(part) = ecs.read_storage::<SpawnParticleSimple>().get(entity) {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: part.glyph,
|
||||
fg: part.colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.lifetime_ms,
|
||||
delay: 0.0,
|
||||
},
|
||||
target.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_burst_particles(ecs: &World, entity: Entity, target: &Targets) {
|
||||
if let Some(part) = ecs.read_storage::<SpawnParticleBurst>().get(entity) {
|
||||
if let Some(start_pos) = targeting::find_item_position(ecs, entity) {
|
||||
let end_pos: i32 = get_centre(ecs, target);
|
||||
spawn_line_particles(
|
||||
ecs,
|
||||
start_pos,
|
||||
end_pos,
|
||||
&SpawnParticleLine {
|
||||
glyph: part.glyph,
|
||||
colour: part.colour,
|
||||
trail_colour: part.colour,
|
||||
lifetime_ms: part.trail_lifetime_ms, // 75.0 is good here.
|
||||
trail_lifetime_ms: part.trail_lifetime_ms + 25.0,
|
||||
},
|
||||
);
|
||||
let map = ecs.fetch::<Map>();
|
||||
let line = line2d(
|
||||
LineAlg::Bresenham,
|
||||
Point::new(start_pos % map.width, start_pos / map.width),
|
||||
Point::new(end_pos % map.width, end_pos / map.width),
|
||||
);
|
||||
let burst_delay = line.len() as f32 * 75.0;
|
||||
for i in 0..10 {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: part.glyph,
|
||||
fg: part.colour.lerp(part.lerp, i as f32 * 0.1),
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.lifetime_ms / 10.0, // ~50-80 is good here.
|
||||
delay: burst_delay + (i as f32 * part.lifetime_ms / 10.0),
|
||||
},
|
||||
target.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_centre(ecs: &World, target: &Targets) -> i32 {
|
||||
match target {
|
||||
Targets::Tile { target } => return *target as i32,
|
||||
Targets::TileList { targets } => {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let (mut count, mut sum_x, mut sum_y) = (0, 0, 0);
|
||||
for target in targets {
|
||||
sum_x += *target as i32 % map.width;
|
||||
sum_y += *target as i32 / map.width;
|
||||
count += 1;
|
||||
}
|
||||
let (mean_x, mean_y) = (sum_x / count, sum_y / count);
|
||||
let centre = map.xy_idx(mean_x, mean_y);
|
||||
return centre as i32;
|
||||
}
|
||||
Targets::Entity { target } => return targeting::entity_position(ecs, *target).unwrap() as i32,
|
||||
Targets::EntityList { targets } => {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let (mut count, mut sum_x, mut sum_y) = (0, 0, 0);
|
||||
for target in targets {
|
||||
if let Some(pos) = targeting::entity_position(ecs, *target) {
|
||||
sum_x += pos as i32 % map.width;
|
||||
sum_y += pos as i32 / map.width;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
let (mean_x, mean_y) = (sum_x / count, sum_y / count);
|
||||
let centre = map.xy_idx(mean_x, mean_y);
|
||||
return centre as i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_line_particles(ecs: &World, entity: Entity, target: &Targets) {
|
||||
if let Some(part) = ecs.read_storage::<SpawnParticleLine>().get(entity) {
|
||||
if let Some(start_pos) = targeting::find_item_position(ecs, entity) {
|
||||
match target {
|
||||
Targets::Tile { target } => spawn_line_particles(ecs, start_pos, *target as i32, part),
|
||||
Targets::TileList { targets } => {
|
||||
targets.iter().for_each(|target| spawn_line_particles(ecs, start_pos, *target as i32, part))
|
||||
}
|
||||
Targets::Entity { target } => {
|
||||
if let Some(end_pos) = targeting::entity_position(ecs, *target) {
|
||||
spawn_line_particles(ecs, start_pos, end_pos as i32, part);
|
||||
}
|
||||
}
|
||||
Targets::EntityList { targets } => targets.iter().for_each(|target| {
|
||||
if let Some(end_pos) = targeting::entity_position(ecs, *target) {
|
||||
spawn_line_particles(ecs, start_pos, end_pos as i32, part);
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleLine) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let start_pt = Point::new(start % map.width, start / map.width);
|
||||
let end_pt = Point::new(end % map.width, end / map.width);
|
||||
let line = line2d(LineAlg::Bresenham, start_pt, end_pt);
|
||||
for (i, pt) in line.iter().enumerate() {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: part.glyph,
|
||||
fg: part.colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.lifetime_ms,
|
||||
delay: i as f32 * part.lifetime_ms,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(pt.x, pt.y) },
|
||||
);
|
||||
if i > 0 {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('-'),
|
||||
fg: part.trail_colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.trail_lifetime_ms,
|
||||
delay: i as f32 * part.lifetime_ms,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(line[i - 1].x, line[i - 1].y) },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use super::{add_effect, get_noncursed, spatial, targeting, EffectType, Entity, Targets, World};
|
||||
use super::{add_effect, get_noncursed, particles, spatial, targeting, EffectType, Entity, Targets, World};
|
||||
use crate::{
|
||||
gamelog, gui::item_colour_ecs, gui::obfuscate_name_ecs, gui::renderable_colour, Beatitude, Charges, Confusion,
|
||||
Consumable, Destructible, Hidden, InflictsDamage, Item, MagicMapper, Map, Player, Prop, ProvidesHealing,
|
||||
ProvidesNutrition, RandomNumberGenerator, Renderable, RunState, SingleActivation, SpawnParticleBurst,
|
||||
SpawnParticleLine, BUC,
|
||||
Consumable, Destructible, Hidden, InflictsDamage, Item, MagicMapper, Player, Prop, ProvidesHealing,
|
||||
ProvidesNutrition, RandomNumberGenerator, Renderable, RunState, SingleActivation, BUC,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
|
@ -62,41 +61,8 @@ fn event_trigger(source: Option<Entity>, entity: Entity, target: &Targets, ecs:
|
|||
let logger = gamelog::Logger::new();
|
||||
|
||||
let mut did_something = false;
|
||||
// Simple particle spawn
|
||||
if let Some(part) = ecs.read_storage::<SpawnParticleBurst>().get(entity) {
|
||||
add_effect(
|
||||
event.source,
|
||||
EffectType::Particle {
|
||||
glyph: part.glyph,
|
||||
fg: part.colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.lifetime_ms,
|
||||
delay: 0.0,
|
||||
},
|
||||
event.target.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 target {
|
||||
Targets::Tile { target } => spawn_line_particles(ecs, start_pos, *target as i32, part),
|
||||
Targets::TileList { targets } => {
|
||||
targets.iter().for_each(|target| spawn_line_particles(ecs, start_pos, *target as i32, part))
|
||||
}
|
||||
Targets::Entity { target } => {
|
||||
if let Some(end_pos) = targeting::entity_position(ecs, *target) {
|
||||
spawn_line_particles(ecs, start_pos, end_pos as i32, part);
|
||||
}
|
||||
}
|
||||
Targets::EntityList { targets } => targets.iter().for_each(|target| {
|
||||
if let Some(end_pos) = targeting::entity_position(ecs, *target) {
|
||||
spawn_line_particles(ecs, start_pos, end_pos as i32, part);
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
particles::handle_burst_particles(ecs, entity, &target);
|
||||
particles::handle_line_particles(ecs, entity, &target);
|
||||
let (logger, restored_nutrition) = handle_restore_nutrition(ecs, &mut event, logger);
|
||||
let (logger, magic_mapped) = handle_magic_mapper(ecs, &mut event, logger);
|
||||
let (logger, healed) = handle_healing(ecs, &mut event, logger);
|
||||
|
|
@ -262,36 +228,3 @@ fn get_entity_targets(target: &Targets) -> Vec<Entity> {
|
|||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleLine) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let start_pt = Point::new(start % map.width, start / map.width);
|
||||
let end_pt = Point::new(end % map.width, end / map.width);
|
||||
let line = line2d(LineAlg::Bresenham, start_pt, end_pt);
|
||||
for (i, pt) in line.iter().enumerate() {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: part.glyph,
|
||||
fg: part.colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.lifetime_ms,
|
||||
delay: i as f32 * part.lifetime_ms,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(pt.x, pt.y) },
|
||||
);
|
||||
if i > 0 {
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::Particle {
|
||||
glyph: to_cp437('-'),
|
||||
fg: part.trail_colour,
|
||||
bg: RGB::named(BLACK),
|
||||
lifespan: part.trail_lifetime_ms,
|
||||
delay: i as f32 * part.lifetime_ms,
|
||||
},
|
||||
Targets::Tile { target: map.xy_idx(line[i - 1].x, line[i - 1].y) },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue