Beam particles now determined from beam segment rather than character state.

This commit is contained in:
Sam 2021-01-24 12:45:52 -05:00 committed by Snowram
parent e7bbf3981d
commit 11050a05ce
3 changed files with 51 additions and 62 deletions

View File

@ -1466,7 +1466,6 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
}, },
timer: Duration::default(), timer: Duration::default(),
stage_section: StageSection::Buildup, stage_section: StageSection::Buildup,
particle_ori: None::<Vec3<f32>>,
offset: Vec3::zero(), offset: Vec3::zero(),
}), }),
} }

View File

@ -60,8 +60,6 @@ pub struct Data {
pub timer: Duration, pub timer: Duration,
/// What section the character stage is in /// What section the character stage is in
pub stage_section: StageSection, pub stage_section: StageSection,
/// Used for particle stuffs
pub particle_ori: Option<Vec3<f32>>,
/// Used to offset beam and particles /// Used to offset beam and particles
pub offset: Vec3<f32>, pub offset: Vec3<f32>,
} }
@ -105,7 +103,6 @@ impl CharacterBehavior for Data {
.timer .timer
.checked_add(Duration::from_secs_f32(data.dt.0)) .checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(), .unwrap_or_default(),
particle_ori: Some(*data.inputs.look_dir),
..*self ..*self
}); });
} else { } else {
@ -125,7 +122,6 @@ impl CharacterBehavior for Data {
update.character = CharacterState::BasicBeam(Data { update.character = CharacterState::BasicBeam(Data {
timer: Duration::default(), timer: Duration::default(),
stage_section: StageSection::Cast, stage_section: StageSection::Cast,
particle_ori: Some(*data.inputs.look_dir),
offset: body_offsets, offset: body_offsets,
..*self ..*self
}); });
@ -203,7 +199,6 @@ impl CharacterBehavior for Data {
.timer .timer
.checked_add(Duration::from_secs_f32(data.dt.0)) .checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(), .unwrap_or_default(),
particle_ori: Some(*data.inputs.look_dir),
offset: body_offsets, offset: body_offsets,
..*self ..*self
}); });
@ -217,7 +212,6 @@ impl CharacterBehavior for Data {
update.character = CharacterState::BasicBeam(Data { update.character = CharacterState::BasicBeam(Data {
timer: Duration::default(), timer: Duration::default(),
stage_section: StageSection::Recover, stage_section: StageSection::Recover,
particle_ori: Some(*data.inputs.look_dir),
..*self ..*self
}); });
} }
@ -229,7 +223,6 @@ impl CharacterBehavior for Data {
.timer .timer
.checked_add(Duration::from_secs_f32(data.dt.0)) .checked_add(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(), .unwrap_or_default(),
particle_ori: Some(*data.inputs.look_dir),
..*self ..*self
}); });
} else { } else {

View File

@ -8,13 +8,12 @@ use crate::{
}; };
use common::{ use common::{
assets::{AssetExt, DotVoxAsset}, assets::{AssetExt, DotVoxAsset},
comp::{item::Reagent, object, Body, CharacterState, Ori, Pos, Shockwave}, comp::{item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, Shockwave},
figure::Segment, figure::Segment,
outcome::Outcome, outcome::Outcome,
resources::DeltaTime, resources::DeltaTime,
span, span,
spiral::Spiral2d, spiral::Spiral2d,
states::utils::StageSection,
terrain::TerrainChunk, terrain::TerrainChunk,
vol::{RectRasterableVol, SizedVol}, vol::{RectRasterableVol, SizedVol},
}; };
@ -366,65 +365,63 @@ impl ParticleMgr {
let state = scene_data.state; let state = scene_data.state;
let ecs = state.ecs(); let ecs = state.ecs();
let time = state.get_time(); let time = state.get_time();
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
for (pos, ori, character_state) in ( for (pos, ori, beam) in (
&ecs.read_storage::<Pos>(), &ecs.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(), &ecs.read_storage::<Ori>(),
&ecs.read_storage::<CharacterState>(), &ecs.read_storage::<BeamSegment>(),
) )
.join() .join()
.filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
{ {
if let CharacterState::BasicBeam(b) = character_state { let range = beam.properties.speed * beam.properties.duration.as_secs_f32();
let particle_ori = b.particle_ori.unwrap_or_else(|| ori.look_vec()); if beam.properties.lifesteal_eff > 0.0 {
if b.stage_section == StageSection::Cast { // Emit a light when using healing
if b.static_data.base_hps > 0.0 { lights.push(Light::new(pos.0, Rgb::new(0.1, 1.0, 0.15), 1.0));
// Emit a light when using healing for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) {
lights.push(Light::new(pos.0 + b.offset, Rgb::new(0.1, 1.0, 0.15), 1.0)); self.particles.push(Particle::new_beam(
for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) { beam.properties.duration,
self.particles.push(Particle::new_beam( time + i as f64 / 1000.0,
b.static_data.beam_duration, ParticleMode::HealingBeam,
time + i as f64 / 1000.0, pos.0 + *ori.0 * 0.5,
ParticleMode::HealingBeam, pos.0 + *ori.0 * range,
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::<f32>::unit_z(), particle_ori);
let m = Mat3::<f32>::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,
)
},
);
}
} }
} else {
let mut rng = thread_rng();
let (from, to) = (Vec3::<f32>::unit_z(), *ori.0);
let m = Mat3::<f32>::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,
)
},
);
} }
} }
} }