From 3197bcd12a83f22a494512d890062c18ad526897 Mon Sep 17 00:00:00 2001 From: Daniel Mizerski Date: Thu, 6 May 2021 18:50:15 +0200 Subject: [PATCH] (Wiring) Logic - make wiring turing complete --- CHANGELOG.md | 1 + server/src/cmd.rs | 73 ++++++++++++++++++++---- server/src/sys/wiring/compute_outputs.rs | 38 ++++++++++-- server/src/wiring.rs | 1 + 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d53f415afb..dfa0221af1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Potion Kit is renamed to "consumables" and gives potions and mushroom curry - Cultist Kit gives cape, rings and necklace in addition to armour and weapons. - Reworked minotaur to have unique attacks. +- Wiring is now turing complete ### Removed diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 219e5e477e..4f8f721c78 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -4,6 +4,7 @@ use crate::{ settings::{BanRecord, EditableSetting}, + wiring::{Logic, OutputFormula}, Server, SpawnPoint, StateExt, }; use assets::AssetExt; @@ -1721,9 +1722,39 @@ fn handle_spawn_wiring( pos.0.x += 3.0; let mut outputs1 = HashMap::new(); - outputs1.insert(String::from("color"), wiring::OutputFormula::OnDeath { - value: 1.0, - radius: 30.0, + outputs1.insert( + "deaths_last_tick".to_string(), + wiring::OutputFormula::OnDeath { + value: 1.0, + radius: 30.0, + }, + ); + outputs1.insert( + "deaths_accumulated".to_string(), + OutputFormula::Logic(Box::new(Logic { + kind: wiring::LogicKind::Sum, + left: OutputFormula::Logic(Box::new(Logic { + kind: wiring::LogicKind::Sub, + left: OutputFormula::Input { + name: "deaths_accumulated".to_string(), + }, + right: OutputFormula::Logic(Box::new(Logic { + kind: wiring::LogicKind::Min, + left: OutputFormula::Input { + name: "pressed".to_string(), + }, + right: OutputFormula::Input { + name: "deaths_accumulated".to_string(), + }, + })), + })), + right: OutputFormula::Input { + name: "deaths_last_tick".to_string(), + }, + })), + ); + outputs1.insert("pressed".to_string(), OutputFormula::OnCollide { + value: f32::MAX, }); let builder1 = server @@ -1757,9 +1788,9 @@ fn handle_spawn_wiring( actions: vec![ WiringAction { formula: wiring::OutputFormula::Input { - name: String::from("color"), + name: String::from("deaths_accumulated"), }, - threshold: 1.0, + threshold: 5.0, effects: vec![WiringActionEffect::SpawnProjectile { constr: comp::ProjectileConstructor::Arrow { damage: 1.0, @@ -1798,12 +1829,32 @@ fn handle_spawn_wiring( outputs: HashMap::new(), }) .with(Circuit { - wires: vec![Wire { - input_entity: ent1, - input_field: String::from("color"), - output_entity: ent2, - output_field: String::from("color"), - }], + wires: vec![ + Wire { + input_entity: ent1, + input_field: String::from("deaths_last_tick"), + output_entity: ent1, + output_field: String::from("deaths_last_tick"), + }, + Wire { + input_entity: ent1, + input_field: String::from("deaths_accumulated"), + output_entity: ent1, + output_field: String::from("deaths_accumulated"), + }, + Wire { + input_entity: ent1, + input_field: String::from("pressed"), + output_entity: ent1, + output_field: String::from("pressed"), + }, + Wire { + input_entity: ent1, + input_field: String::from("deaths_accumulated"), + output_entity: ent2, + output_field: String::from("deaths_accumulated"), + }, + ], }); builder3.build(); diff --git a/server/src/sys/wiring/compute_outputs.rs b/server/src/sys/wiring/compute_outputs.rs index 3877776a03..651e631234 100644 --- a/server/src/sys/wiring/compute_outputs.rs +++ b/server/src/sys/wiring/compute_outputs.rs @@ -1,5 +1,5 @@ use super::WiringData; -use crate::wiring::OutputFormula; +use crate::wiring::{Logic, LogicKind, OutputFormula}; use common::{ comp::{PhysicsState, Pos}, resources::EntitiesDiedLastTick, @@ -84,9 +84,8 @@ pub fn compute_output( match output_formula { OutputFormula::Constant { value } => *value, OutputFormula::Input { name } => *inputs.get(name).unwrap_or(&0.0), - OutputFormula::Logic(_logic) => { - warn!("Not implemented OutputFormula::Logic"); - 0.0 + OutputFormula::Logic(logic) => { + output_formula_logic(logic, inputs, physics_state, entities_died_last_tick, pos) }, OutputFormula::SineWave { .. } => { warn!("Not implemented OutputFormula::SineWave"); @@ -130,3 +129,34 @@ fn output_formula_on_death( } 0.0 } + +#[allow(clippy::too_many_arguments)] +fn output_formula_logic( + logic: &Logic, + inputs: &HashMap, + physics_state: Option<&PhysicsState>, + entities_died_last_tick: &Read, + pos: Option<&Pos>, +) -> f32 { + let left = compute_output( + &logic.left, + inputs, + physics_state, + entities_died_last_tick, + pos, + ); + let right = compute_output( + &logic.right, + inputs, + physics_state, + entities_died_last_tick, + pos, + ); + match logic.kind { + LogicKind::Max => f32::max(left, right), + LogicKind::Min => f32::min(left, right), + LogicKind::Sub => left - right, + LogicKind::Sum => left + right, + LogicKind::Mul => left * right, + } +} diff --git a/server/src/wiring.rs b/server/src/wiring.rs index 755d9848ea..620dd38ff1 100644 --- a/server/src/wiring.rs +++ b/server/src/wiring.rs @@ -37,6 +37,7 @@ pub enum LogicKind { Max, // acts like Or Sub, // `|x| { 5.0 - x }` acts like Not, depending on reference voltages Sum, + Mul, } pub struct WiringAction {