veloren_common_systems/
phys_events.rs1use common::{
2 comp::{Fluid, Mass, PhysicsState, Pos, PreviousPhysCache, Vel},
3 event::EventBus,
4 outcome::Outcome,
5};
6use common_ecs::System;
7use specs::{Join, Read, ReadStorage};
8
9#[derive(Default)]
10pub struct Sys;
11
12impl<'a> System<'a> for Sys {
13 type SystemData = (
14 Read<'a, EventBus<Outcome>>,
15 ReadStorage<'a, PhysicsState>,
16 ReadStorage<'a, PreviousPhysCache>,
17 ReadStorage<'a, Vel>,
18 ReadStorage<'a, Pos>,
19 ReadStorage<'a, Mass>,
20 );
21
22 const NAME: &'static str = "phys_events";
23 const ORIGIN: common_ecs::Origin = common_ecs::Origin::Common;
24 const PHASE: common_ecs::Phase = common_ecs::Phase::Create;
25
26 fn run(
27 _job: &mut common_ecs::Job<Self>,
28 (outcomes, physics_states, previous_phys_cache, velocities, positions, masses): Self::SystemData,
29 ) {
30 let mut outcomes = outcomes.emitter();
31 for (physics_state, prev, vel, pos, mass) in (
32 &physics_states,
33 &previous_phys_cache,
34 &velocities,
35 &positions,
36 &masses,
37 )
38 .join()
39 {
40 if let (Some(Fluid::Liquid { kind, .. }), Some(Fluid::Air { .. })) =
42 (physics_state.in_fluid, prev.in_fluid)
43 {
44 outcomes.emit(Outcome::Splash {
45 pos: pos.0,
46 vel: if vel.0.magnitude_squared() > prev.velocity.magnitude_squared() {
47 vel.0
48 } else {
49 prev.velocity
50 },
51 mass: mass.0,
52 kind,
53 });
54 }
55 }
56 }
57}