(Wiring) OnDeath

This commit is contained in:
Daniel Mizerski 2021-05-05 15:54:24 +02:00
parent bd966eaf4b
commit b34704ea3f
8 changed files with 97 additions and 15 deletions

View File

@ -1,3 +1,4 @@
use crate::comp::Pos;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::Entity; use specs::Entity;
@ -13,6 +14,9 @@ pub struct Time(pub f64);
#[derive(Default)] #[derive(Default)]
pub struct DeltaTime(pub f32); pub struct DeltaTime(pub f32);
#[derive(Default)]
pub struct EntitiesDiedLastTick(pub Vec<(Entity, Pos)>);
/// A resource that indicates what mode the local game is being played in. /// A resource that indicates what mode the local game is being played in.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum GameMode { pub enum GameMode {

View File

@ -9,7 +9,10 @@ use common::{
event::{EventBus, LocalEvent, ServerEvent}, event::{EventBus, LocalEvent, ServerEvent},
outcome::Outcome, outcome::Outcome,
region::RegionMap, region::RegionMap,
resources::{DeltaTime, GameMode, PlayerEntity, PlayerPhysicsSettings, Time, TimeOfDay}, resources::{
DeltaTime, EntitiesDiedLastTick, GameMode, PlayerEntity, PlayerPhysicsSettings, Time,
TimeOfDay,
},
slowjob::SlowJobPool, slowjob::SlowJobPool,
terrain::{Block, TerrainChunk, TerrainGrid}, terrain::{Block, TerrainChunk, TerrainGrid},
time::DayPeriod, time::DayPeriod,
@ -208,6 +211,7 @@ impl State {
ecs.insert(game_mode); ecs.insert(game_mode);
ecs.insert(Vec::<common::outcome::Outcome>::new()); ecs.insert(Vec::<common::outcome::Outcome>::new());
ecs.insert(common::CachedSpatialGrid::default()); ecs.insert(common::CachedSpatialGrid::default());
ecs.insert(EntitiesDiedLastTick::default());
let num_cpu = num_cpus::get() as u64; let num_cpu = num_cpus::get() as u64;
let slow_limit = (num_cpu / 2 + num_cpu / 4).max(1); let slow_limit = (num_cpu / 2 + num_cpu / 4).max(1);

View File

@ -7,7 +7,7 @@ use common::{
}, },
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
outcome::Outcome, outcome::Outcome,
resources::{DeltaTime, Time}, resources::{DeltaTime, EntitiesDiedLastTick, Time},
uid::Uid, uid::Uid,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
@ -45,6 +45,7 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Poise>, WriteStorage<'a, Poise>,
WriteStorage<'a, Energy>, WriteStorage<'a, Energy>,
WriteStorage<'a, Combo>, WriteStorage<'a, Combo>,
Write<'a, EntitiesDiedLastTick>,
Write<'a, Vec<Outcome>>, Write<'a, Vec<Outcome>>,
); );
@ -62,9 +63,11 @@ impl<'a> System<'a> for Sys {
mut poises, mut poises,
mut energies, mut energies,
mut combos, mut combos,
mut entities_died_last_tick,
mut outcomes, mut outcomes,
): Self::SystemData, ): Self::SystemData,
) { ) {
entities_died_last_tick.0.clear();
let mut server_event_emitter = read_data.server_bus.emitter(); let mut server_event_emitter = read_data.server_bus.emitter();
let dt = read_data.dt.0; let dt = read_data.dt.0;
@ -98,6 +101,8 @@ impl<'a> System<'a> for Sys {
if set_dead { if set_dead {
let mut health = health.get_mut_unchecked(); let mut health = health.get_mut_unchecked();
let cloned_entity = (entity, *pos);
entities_died_last_tick.0.push(cloned_entity);
server_event_emitter.emit(ServerEvent::Destroy { server_event_emitter.emit(ServerEvent::Destroy {
entity, entity,
cause: health.last_change.1.cause, cause: health.last_change.1.cause,

View File

@ -1718,8 +1718,9 @@ fn handle_spawn_wiring(
pos.0.x += 3.0; pos.0.x += 3.0;
let mut outputs1 = HashMap::new(); let mut outputs1 = HashMap::new();
outputs1.insert(String::from("color"), wiring::OutputFormula::OnCollide { outputs1.insert(String::from("color"), wiring::OutputFormula::OnDeath {
value: 1.0, value: 1.0,
radius: 30.0,
}); });
let builder1 = server let builder1 = server

View File

@ -1,7 +1,8 @@
use crate::wiring::{Circuit, WiringElement}; use crate::wiring::{Circuit, WiringElement};
use common::{ use common::{
comp::{LightEmitter, PhysicsState}, comp::{LightEmitter, PhysicsState, Pos},
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
resources::EntitiesDiedLastTick,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use hashbrown::HashMap; use hashbrown::HashMap;
@ -23,8 +24,10 @@ pub struct WiringData<'a> {
pub light_emitters: WriteStorage<'a, LightEmitter>, // maybe pub light_emitters: WriteStorage<'a, LightEmitter>, // maybe
pub physics_states: ReadStorage<'a, PhysicsState>, // maybe pub physics_states: ReadStorage<'a, PhysicsState>, // maybe
pub pos: ReadStorage<'a, Pos>,
pub event_bus: Read<'a, EventBus<ServerEvent>>, pub event_bus: Read<'a, EventBus<ServerEvent>>,
pub entities_died_last_tick: Read<'a, EntitiesDiedLastTick>,
} }
/// This system is responsible for handling wiring (signals and wiring systems) /// This system is responsible for handling wiring (signals and wiring systems)

View File

@ -1,8 +1,12 @@
use super::WiringData; use super::WiringData;
use crate::wiring::OutputFormula; use crate::wiring::OutputFormula;
use common::comp::PhysicsState; use common::{
comp::{PhysicsState, Pos},
resources::EntitiesDiedLastTick,
};
use hashbrown::HashMap; use hashbrown::HashMap;
use specs::{join::Join, Entity}; use rand_distr::num_traits::ToPrimitive;
use specs::{join::Join, Entity, Read};
use tracing::warn; use tracing::warn;
pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<String, f32>> { pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<String, f32>> {
@ -10,11 +14,18 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<Stri
entities, entities,
wiring_elements, wiring_elements,
physics_states, physics_states,
entities_died_last_tick,
pos,
.. ..
} = system_data; } = system_data;
(&*entities, wiring_elements, physics_states.maybe()) (
&*entities,
wiring_elements,
physics_states.maybe(),
pos.maybe(),
)
.join() .join()
.map(|(entity, wiring_element, physics_state)| { .map(|(entity, wiring_element, physics_state, pos)| {
( (
entity, entity,
wiring_element wiring_element
@ -27,6 +38,8 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<Stri
output_formula, output_formula,
&wiring_element.inputs, &wiring_element.inputs,
physics_state, physics_state,
entities_died_last_tick,
pos,
) )
}, // (String, f32) }, // (String, f32)
) )
@ -36,6 +49,7 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<Stri
.collect() .collect()
} }
#[allow(clippy::too_many_arguments)]
pub fn compute_output_with_key( pub fn compute_output_with_key(
// yes, this function is defined only to make one place // yes, this function is defined only to make one place
// look a bit nicer // look a bit nicer
@ -44,17 +58,28 @@ pub fn compute_output_with_key(
output_formula: &OutputFormula, output_formula: &OutputFormula,
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
physics_state: Option<&PhysicsState>, physics_state: Option<&PhysicsState>,
entities_died_last_tick: &Read<EntitiesDiedLastTick>,
pos: Option<&Pos>,
) -> (String, f32) { ) -> (String, f32) {
( (
key.to_string(), key.to_string(),
compute_output(output_formula, inputs, physics_state), compute_output(
output_formula,
inputs,
physics_state,
entities_died_last_tick,
pos,
),
) )
} }
#[allow(clippy::too_many_arguments)]
pub fn compute_output( pub fn compute_output(
output_formula: &OutputFormula, output_formula: &OutputFormula,
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
physics_state: Option<&PhysicsState>, physics_state: Option<&PhysicsState>,
entities_died_last_tick: &Read<EntitiesDiedLastTick>,
pos: Option<&Pos>,
) -> f32 { ) -> f32 {
match output_formula { match output_formula {
OutputFormula::Constant { value } => *value, OutputFormula::Constant { value } => *value,
@ -72,6 +97,9 @@ pub fn compute_output(
warn!("Not implemented OutputFormula::OnInteract"); warn!("Not implemented OutputFormula::OnInteract");
0.0 0.0
}, },
OutputFormula::OnDeath { value, radius } => {
output_formula_on_death(value, radius, entities_died_last_tick, pos)
},
} }
} }
@ -83,3 +111,22 @@ fn output_formula_on_collide(value: &f32, physics_state: Option<&PhysicsState>)
} }
0.0 0.0
} }
fn output_formula_on_death(
value: &f32,
radius: &f32,
entities_died_last_tick: &Read<EntitiesDiedLastTick>,
pos: Option<&Pos>,
) -> f32 {
if let Some(pos_of_entity) = pos {
return *value
* entities_died_last_tick
.0
.iter()
.filter(|(_, dead_pos)| pos_of_entity.0.distance(dead_pos.0) <= *radius)
.count()
.to_f32()
.unwrap_or(0.0);
}
0.0
}

View File

@ -3,12 +3,13 @@ use std::ops::DerefMut;
use super::{compute_outputs::compute_output, WiringData}; use super::{compute_outputs::compute_output, WiringData};
use crate::wiring::{OutputFormula, WiringActionEffect}; use crate::wiring::{OutputFormula, WiringActionEffect};
use common::{ use common::{
comp::{object, Body, LightEmitter, PhysicsState, ProjectileConstructor}, comp::{object, Body, LightEmitter, PhysicsState, Pos, ProjectileConstructor},
event::{Emitter, ServerEvent}, event::{Emitter, ServerEvent},
resources::EntitiesDiedLastTick,
util::Dir, util::Dir,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
use specs::{join::Join, Entity}; use specs::{join::Join, Entity, Read};
use tracing::warn; use tracing::warn;
use vek::Rgb; use vek::Rgb;
@ -19,6 +20,8 @@ pub fn dispatch_actions(system_data: &mut WiringData) {
wiring_elements, wiring_elements,
physics_states, physics_states,
light_emitters, light_emitters,
entities_died_last_tick,
pos,
.. ..
} = system_data; } = system_data;
let mut server_emitter = event_bus.emitter(); let mut server_emitter = event_bus.emitter();
@ -28,10 +31,11 @@ pub fn dispatch_actions(system_data: &mut WiringData) {
wiring_elements, wiring_elements,
physics_states.maybe(), physics_states.maybe(),
light_emitters.maybe(), light_emitters.maybe(),
pos.maybe(),
) )
.join() .join()
.for_each( .for_each(
|(entity, wiring_element, physics_state, mut light_emitter)| { |(entity, wiring_element, physics_state, mut light_emitter, pos)| {
wiring_element wiring_element
.actions .actions
.iter() .iter()
@ -40,6 +44,8 @@ pub fn dispatch_actions(system_data: &mut WiringData) {
&wiring_action.formula, &wiring_action.formula,
&wiring_element.inputs, &wiring_element.inputs,
physics_state, physics_state,
entities_died_last_tick,
pos,
) >= wiring_action.threshold ) >= wiring_action.threshold
}) })
.for_each(|wiring_action| { .for_each(|wiring_action| {
@ -50,12 +56,15 @@ pub fn dispatch_actions(system_data: &mut WiringData) {
&mut server_emitter, &mut server_emitter,
&mut light_emitter, &mut light_emitter,
physics_state, physics_state,
entities_died_last_tick,
pos,
); );
}) })
}, },
) )
} }
#[allow(clippy::too_many_arguments)]
fn dispatch_action( fn dispatch_action(
entity: Entity, entity: Entity,
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
@ -65,6 +74,8 @@ fn dispatch_action(
light_emitter: &mut Option<impl DerefMut<Target = LightEmitter>>, light_emitter: &mut Option<impl DerefMut<Target = LightEmitter>>,
physics_state: Option<&PhysicsState>, physics_state: Option<&PhysicsState>,
entities_died_last_tick: &Read<EntitiesDiedLastTick>,
pos: Option<&Pos>,
) { ) {
action_effects action_effects
.iter() .iter()
@ -82,6 +93,8 @@ fn dispatch_action(
b, b,
&mut light_emitter.as_deref_mut(), &mut light_emitter.as_deref_mut(),
physics_state, physics_state,
entities_died_last_tick,
pos,
), ),
}); });
} }
@ -104,6 +117,7 @@ fn dispatch_action_spawn_projectile(
}); });
} }
#[allow(clippy::too_many_arguments)]
fn dispatch_action_set_light( fn dispatch_action_set_light(
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
r: &OutputFormula, r: &OutputFormula,
@ -113,13 +127,15 @@ fn dispatch_action_set_light(
light_emitter: &mut Option<&mut LightEmitter>, light_emitter: &mut Option<&mut LightEmitter>,
physics_state: Option<&PhysicsState>, physics_state: Option<&PhysicsState>,
entities_died_last_tick: &Read<EntitiesDiedLastTick>,
pos: Option<&Pos>,
) { ) {
if let Some(light_emitter) = light_emitter { if let Some(light_emitter) = light_emitter {
// TODO: make compute_output accept multiple formulas // TODO: make compute_output accept multiple formulas
let computed_r = compute_output(r, inputs, physics_state); let computed_r = compute_output(r, inputs, physics_state, entities_died_last_tick, pos);
let computed_g = compute_output(g, inputs, physics_state); let computed_g = compute_output(g, inputs, physics_state, entities_died_last_tick, pos);
let computed_b = compute_output(b, inputs, physics_state); let computed_b = compute_output(b, inputs, physics_state, entities_died_last_tick, pos);
light_emitter.col = Rgb::new(computed_r, computed_g, computed_b); light_emitter.col = Rgb::new(computed_r, computed_g, computed_b);
} }

View File

@ -29,12 +29,14 @@ pub enum OutputFormula {
SineWave { amplitude: f32, frequency: f32 }, SineWave { amplitude: f32, frequency: f32 },
OnCollide { value: f32 }, OnCollide { value: f32 },
OnInteract { value: f32 }, OnInteract { value: f32 },
OnDeath { value: f32, radius: f32 },
} }
pub enum LogicKind { pub enum LogicKind {
Min, // acts like And Min, // acts like And
Max, // acts like Or Max, // acts like Or
Sub, // `|x| { 5.0 - x }` acts like Not, depending on reference voltages Sub, // `|x| { 5.0 - x }` acts like Not, depending on reference voltages
Sum,
} }
pub struct WiringAction { pub struct WiringAction {