veloren/server/src/sys/wiring/dispatch_actions.rs

127 lines
3.8 KiB
Rust
Raw Normal View History

2021-05-05 14:13:38 +00:00
use std::ops::DerefMut;
2021-04-15 16:28:16 +00:00
use super::{compute_outputs::compute_output, WiringData};
use crate::wiring::{OutputFormula, WiringActionEffect};
use common::{
comp::{object, Body, LightEmitter, PhysicsState, ProjectileConstructor},
event::{Emitter, ServerEvent},
util::Dir,
};
use hashbrown::HashMap;
2021-05-05 14:13:38 +00:00
use specs::{join::Join, Entity};
2021-04-15 16:28:16 +00:00
use tracing::warn;
use vek::Rgb;
pub fn dispatch_actions(system_data: &mut WiringData) {
let WiringData {
entities,
event_bus,
wiring_elements,
physics_states,
2021-05-05 14:13:38 +00:00
light_emitters,
2021-04-15 16:28:16 +00:00
..
} = system_data;
let mut server_emitter = event_bus.emitter();
2021-05-05 14:13:38 +00:00
(
&*entities,
wiring_elements,
physics_states.maybe(),
light_emitters.maybe(),
)
2021-04-15 16:28:16 +00:00
.join()
2021-05-05 14:13:38 +00:00
.for_each(
|(entity, wiring_element, physics_state, mut light_emitter)| {
wiring_element
.actions
.iter()
.filter(|wiring_action| {
compute_output(
&wiring_action.formula,
&wiring_element.inputs,
physics_state,
) >= wiring_action.threshold
})
.for_each(|wiring_action| {
dispatch_action(
entity,
&wiring_element.inputs,
&wiring_action.effects,
&mut server_emitter,
&mut light_emitter,
physics_state,
);
})
},
)
2021-04-15 16:28:16 +00:00
}
fn dispatch_action(
entity: Entity,
2021-05-05 14:13:38 +00:00
inputs: &HashMap<String, f32>,
2021-04-15 16:28:16 +00:00
action_effects: &[WiringActionEffect],
server_emitter: &mut Emitter<ServerEvent>,
2021-05-05 14:13:38 +00:00
light_emitter: &mut Option<impl DerefMut<Target = LightEmitter>>,
physics_state: Option<&PhysicsState>,
2021-04-15 16:28:16 +00:00
) {
action_effects
.iter()
.for_each(|action_effect| match action_effect {
WiringActionEffect::SetBlockCollidability { .. } => {
warn!("Not implemented WiringActionEffect::SetBlockCollidability")
},
WiringActionEffect::SpawnProjectile { constr } => {
dispatch_action_spawn_projectile(entity, constr, server_emitter)
},
2021-05-05 14:13:38 +00:00
WiringActionEffect::SetLight { r, g, b } => dispatch_action_set_light(
inputs,
r,
g,
b,
&mut light_emitter.as_deref_mut(),
physics_state,
),
2021-04-15 16:28:16 +00:00
});
}
fn dispatch_action_spawn_projectile(
entity: Entity,
constr: &ProjectileConstructor,
server_emitter: &mut Emitter<ServerEvent>,
) {
// Use match here if there will be more options
// NOTE: constr in RFC is about Arrow projectile
server_emitter.emit(ServerEvent::Shoot {
entity,
dir: Dir::forward(),
body: Body::Object(object::Body::Arrow),
projectile: constr.create_projectile(None, 1.0, 1.0),
light: None,
speed: 5.0,
object: None,
});
}
fn dispatch_action_set_light(
2021-05-05 14:13:38 +00:00
inputs: &HashMap<String, f32>,
2021-04-15 16:28:16 +00:00
r: &OutputFormula,
g: &OutputFormula,
b: &OutputFormula,
2021-05-05 14:13:38 +00:00
light_emitter: &mut Option<&mut LightEmitter>,
physics_state: Option<&PhysicsState>,
2021-04-15 16:28:16 +00:00
) {
2021-05-05 14:13:38 +00:00
if let Some(light_emitter) = light_emitter {
// TODO: make compute_output accept multiple formulas
2021-04-15 16:28:16 +00:00
2021-05-05 14:13:38 +00:00
let computed_r = compute_output(r, inputs, physics_state);
let computed_g = compute_output(g, inputs, physics_state);
let computed_b = compute_output(b, inputs, physics_state);
2021-04-15 16:28:16 +00:00
2021-05-05 14:13:38 +00:00
light_emitter.col = Rgb::new(computed_r, computed_g, computed_b);
}
2021-04-15 16:28:16 +00:00
}