diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index b171a85b89..8e221167d4 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1466,7 +1466,6 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState { }, timer: Duration::default(), stage_section: StageSection::Buildup, - particle_ori: None::>, offset: Vec3::zero(), }), } diff --git a/common/src/states/basic_beam.rs b/common/src/states/basic_beam.rs index fa430ddfb3..888dd4a16d 100644 --- a/common/src/states/basic_beam.rs +++ b/common/src/states/basic_beam.rs @@ -60,8 +60,6 @@ pub struct Data { pub timer: Duration, /// What section the character stage is in pub stage_section: StageSection, - /// Used for particle stuffs - pub particle_ori: Option>, /// Used to offset beam and particles pub offset: Vec3, } @@ -105,7 +103,6 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), - particle_ori: Some(*data.inputs.look_dir), ..*self }); } else { @@ -125,7 +122,6 @@ impl CharacterBehavior for Data { update.character = CharacterState::BasicBeam(Data { timer: Duration::default(), stage_section: StageSection::Cast, - particle_ori: Some(*data.inputs.look_dir), offset: body_offsets, ..*self }); @@ -203,7 +199,6 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), - particle_ori: Some(*data.inputs.look_dir), offset: body_offsets, ..*self }); @@ -217,7 +212,6 @@ impl CharacterBehavior for Data { update.character = CharacterState::BasicBeam(Data { timer: Duration::default(), stage_section: StageSection::Recover, - particle_ori: Some(*data.inputs.look_dir), ..*self }); } @@ -229,7 +223,6 @@ impl CharacterBehavior for Data { .timer .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or_default(), - particle_ori: Some(*data.inputs.look_dir), ..*self }); } else { diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 9ae5e1d97d..0f79b4a1f8 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -8,13 +8,12 @@ use crate::{ }; use common::{ assets::{AssetExt, DotVoxAsset}, - comp::{item::Reagent, object, Body, CharacterState, Ori, Pos, Shockwave}, + comp::{item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, Shockwave}, figure::Segment, outcome::Outcome, resources::DeltaTime, span, spiral::Spiral2d, - states::utils::StageSection, terrain::TerrainChunk, vol::{RectRasterableVol, SizedVol}, }; @@ -366,65 +365,63 @@ impl ParticleMgr { let state = scene_data.state; let ecs = state.ecs(); let time = state.get_time(); + let dt = scene_data.state.ecs().fetch::().0; - for (pos, ori, character_state) in ( + for (pos, ori, beam) in ( &ecs.read_storage::(), &ecs.read_storage::(), - &ecs.read_storage::(), + &ecs.read_storage::(), ) .join() + .filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time)) { - if let CharacterState::BasicBeam(b) = character_state { - let particle_ori = b.particle_ori.unwrap_or_else(|| ori.look_vec()); - if b.stage_section == StageSection::Cast { - if b.static_data.base_hps > 0.0 { - // Emit a light when using healing - lights.push(Light::new(pos.0 + b.offset, Rgb::new(0.1, 1.0, 0.15), 1.0)); - for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) { - self.particles.push(Particle::new_beam( - b.static_data.beam_duration, - time + i as f64 / 1000.0, - ParticleMode::HealingBeam, - pos.0 + particle_ori * 0.5 + b.offset, - pos.0 + particle_ori * b.static_data.range + b.offset, - )); - } - } else { - let mut rng = thread_rng(); - let (from, to) = (Vec3::::unit_z(), particle_ori); - let m = Mat3::::rotation_from_to_3d(from, to); - // Emit a light when using flames - lights.push(Light::new( - pos.0 + b.offset, - Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)), - 2.0, - )); - self.particles.resize_with( - self.particles.len() - + 2 * usize::from( - self.scheduler.heartbeats(Duration::from_millis(1)), - ), - || { - let phi: f32 = - rng.gen_range(0.0..b.static_data.max_angle.to_radians()); - let theta: f32 = rng.gen_range(0.0..2.0 * PI); - let offset_z = Vec3::new( - phi.sin() * theta.cos(), - phi.sin() * theta.sin(), - phi.cos(), - ); - let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0); - Particle::new_beam( - b.static_data.beam_duration, - time, - ParticleMode::FlameThrower, - pos.0 + random_ori * 0.5 + b.offset, - pos.0 + random_ori * b.static_data.range + b.offset, - ) - }, - ); - } + let range = beam.properties.speed * beam.properties.duration.as_secs_f32(); + if beam.properties.lifesteal_eff > 0.0 { + // Emit a light when using healing + lights.push(Light::new(pos.0, Rgb::new(0.1, 1.0, 0.15), 1.0)); + for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) { + self.particles.push(Particle::new_beam( + beam.properties.duration, + time + i as f64 / 1000.0, + ParticleMode::HealingBeam, + pos.0 + *ori.0 * 0.5, + pos.0 + *ori.0 * range, + )); } + } else { + let mut rng = thread_rng(); + let (from, to) = (Vec3::::unit_z(), *ori.0); + let m = Mat3::::rotation_from_to_3d(from, to); + // Emit a light when using flames + lights.push(Light::new( + pos.0, + Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8, 1.2)), + 2.0, + )); + self.particles.resize_with( + self.particles.len() + + 2 * usize::from( + self.scheduler.heartbeats(Duration::from_millis(1)), + ), + || { + let phi: f32 = + rng.gen_range(0.0, beam.properties.angle.to_radians()); + let theta: f32 = rng.gen_range(0.0, 2.0 * PI); + let offset_z = Vec3::new( + phi.sin() * theta.cos(), + phi.sin() * theta.sin(), + phi.cos(), + ); + let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0); + Particle::new_beam( + beam.properties.duration, + time, + ParticleMode::FlameThrower, + pos.0 + random_ori, + pos.0 + random_ori * range, + ) + }, + ); } } }