Particles for summoned minions

This commit is contained in:
Sam 2021-03-27 11:47:56 -04:00
parent b0b114a7f8
commit 91ddcaa155
6 changed files with 69 additions and 13 deletions

View File

@ -1,17 +1,18 @@
use crate::{ use crate::{
character::CharacterId, character::CharacterId,
comp, comp::{
self,
invite::{InviteKind, InviteResponse},
item::Item,
Ori, Pos,
},
outcome::Outcome,
rtsim::RtSimEntity, rtsim::RtSimEntity,
trade::{TradeAction, TradeId}, trade::{TradeAction, TradeId},
uid::Uid, uid::Uid,
util::Dir, util::Dir,
Explosion, Explosion,
}; };
use comp::{
invite::{InviteKind, InviteResponse},
item::Item,
Ori, Pos,
};
use specs::Entity as EcsEntity; use specs::Entity as EcsEntity;
use std::{collections::VecDeque, ops::DerefMut, sync::Mutex}; use std::{collections::VecDeque, ops::DerefMut, sync::Mutex};
use vek::*; use vek::*;
@ -30,6 +31,8 @@ pub enum LocalEvent {
Boost { entity: EcsEntity, vel: Vec3<f32> }, Boost { entity: EcsEntity, vel: Vec3<f32> },
/// Updates the position of the entity /// Updates the position of the entity
PositionUpdate { entity: EcsEntity, pos: Pos }, PositionUpdate { entity: EcsEntity, pos: Pos },
/// Creates an outcome
CreateOutcome(Outcome),
} }
#[allow(clippy::large_enum_variant)] // TODO: Pending review in #587 #[allow(clippy::large_enum_variant)] // TODO: Pending review in #587

View File

@ -45,6 +45,10 @@ pub enum Outcome {
pos: Vec3<i32>, pos: Vec3<i32>,
color: Option<Rgb<u8>>, color: Option<Rgb<u8>>,
}, },
SummonedCreature {
pos: Vec3<f32>,
body: comp::Body,
},
} }
impl Outcome { impl Outcome {
@ -53,7 +57,8 @@ impl Outcome {
Outcome::Explosion { pos, .. } Outcome::Explosion { pos, .. }
| Outcome::ProjectileShot { pos, .. } | Outcome::ProjectileShot { pos, .. }
| Outcome::Beam { pos, .. } | Outcome::Beam { pos, .. }
| Outcome::SkillPointGain { pos, .. } => Some(*pos), | Outcome::SkillPointGain { pos, .. }
| Outcome::SummonedCreature { pos, .. } => Some(*pos),
Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)), Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)),
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None, Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None,
} }

View File

@ -4,7 +4,8 @@ use crate::{
inventory::loadout_builder::{LoadoutBuilder, LoadoutConfig}, inventory::loadout_builder::{LoadoutBuilder, LoadoutConfig},
CharacterState, StateUpdate, CharacterState, StateUpdate,
}, },
event::ServerEvent, event::{LocalEvent, ServerEvent},
outcome::Outcome,
skillset_builder::{SkillSetBuilder, SkillSetConfig}, skillset_builder::{SkillSetBuilder, SkillSetConfig},
states::{ states::{
behavior::{CharacterBehavior, JoinData}, behavior::{CharacterBehavior, JoinData},
@ -92,6 +93,7 @@ impl CharacterBehavior for Data {
) )
.build(); .build();
// Send server event to create npc
update.server_events.push_front(ServerEvent::CreateNpc { update.server_events.push_front(ServerEvent::CreateNpc {
pos: *data.pos, pos: *data.pos,
stats, stats,
@ -114,6 +116,14 @@ impl CharacterBehavior for Data {
rtsim_entity: None, rtsim_entity: None,
}); });
// Send local event used for frontend shenanigans
update.local_events.push_front(LocalEvent::CreateOutcome(
Outcome::SummonedCreature {
pos: data.pos.0,
body,
},
));
update.character = CharacterState::BasicSummon(Data { update.character = CharacterState::BasicSummon(Data {
timer: self timer: self
.timer .timer

View File

@ -8,6 +8,7 @@ use common::{
comp, comp,
depot::{Depot, Id}, depot::{Depot, Id},
event::{EventBus, LocalEvent, ServerEvent}, event::{EventBus, LocalEvent, ServerEvent},
outcome::Outcome,
region::RegionMap, region::RegionMap,
resources::{DeltaTime, GameMode, PlayerEntity, Time, TimeOfDay}, resources::{DeltaTime, GameMode, PlayerEntity, Time, TimeOfDay},
slowjob::SlowJobPool, slowjob::SlowJobPool,
@ -515,6 +516,9 @@ impl State {
*position = pos; *position = pos;
} }
}, },
LocalEvent::CreateOutcome(outcome) => {
self.ecs.write_resource::<Vec<Outcome>>().push(outcome);
},
} }
} }
drop(guard); drop(guard);

View File

@ -364,11 +364,13 @@ impl SfxMgr {
audio.play_sfx(file_ref, *pos, None); audio.play_sfx(file_ref, *pos, None);
}, },
}, },
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => {},
Outcome::BreakBlock { pos, .. } => { Outcome::BreakBlock { pos, .. } => {
let file_ref = "voxygen.audio.sfx.footsteps.stone_step_1"; let file_ref = "voxygen.audio.sfx.footsteps.stone_step_1";
audio.play_sfx(file_ref, pos.map(|e| e as f32 + 0.5), Some(3.0)); audio.play_sfx(file_ref, pos.map(|e| e as f32 + 0.5), Some(3.0));
}, },
Outcome::ExpChange { .. }
| Outcome::ComboChange { .. }
| Outcome::SummonedCreature { .. } => {},
} }
} }

View File

@ -9,8 +9,8 @@ use crate::{
use common::{ use common::{
assets::{AssetExt, DotVoxAsset}, assets::{AssetExt, DotVoxAsset},
comp::{ comp::{
self, aura, beam, buff, item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, self, aura, beam, body, buff, item::Reagent, object, BeamSegment, Body, CharacterState,
Shockwave, Vel, Ori, Pos, Shockwave, Vel,
}, },
figure::Segment, figure::Segment,
outcome::Outcome, outcome::Outcome,
@ -156,7 +156,6 @@ impl ParticleMgr {
); );
} }
}, },
Outcome::ProjectileShot { .. } => {},
Outcome::BreakBlock { pos, .. } => { Outcome::BreakBlock { pos, .. } => {
// TODO: Use color field when particle colors are a thing // TODO: Use color field when particle colors are a thing
self.particles.resize_with(self.particles.len() + 30, || { self.particles.resize_with(self.particles.len() + 30, || {
@ -168,7 +167,40 @@ impl ParticleMgr {
) )
}); });
}, },
Outcome::SummonedCreature { pos, body } => match body {
Body::BipedSmall(b) if matches!(b.species, body::biped_small::Species::Husk) => {
self.particles.resize_with(
self.particles.len()
+ 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))),
|| {
let start_pos = pos + Vec3::unit_z() * body.height() / 2.0;
let end_pos = pos
+ Vec3::new(
2.0 * rng.gen::<f32>() - 1.0,
2.0 * rng.gen::<f32>() - 1.0,
0.0,
)
.normalized()
* (body.radius() + 4.0)
+ Vec3::unit_z() * (body.height() + 2.0) * rng.gen::<f32>();
Particle::new_directed(
Duration::from_secs_f32(0.5),
time,
ParticleMode::CultistFlame,
start_pos,
end_pos,
)
},
);
},
_ => {}, _ => {},
},
Outcome::ProjectileShot { .. }
| Outcome::Beam { .. }
| Outcome::ExpChange { .. }
| Outcome::SkillPointGain { .. }
| Outcome::ComboChange { .. } => {},
} }
} }