summaryrefslogtreecommitdiff
path: root/server/src/interaction.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r--server/src/interaction.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
new file mode 100644
index 00000000..5f8b0097
--- /dev/null
+++ b/server/src/interaction.rs
@@ -0,0 +1,66 @@
+use crate::{
+ protocol::{ItemIndex, TileIndex},
+ recipes::{Action, Gamedata},
+};
+use std::collections::BTreeSet;
+
+pub enum Out {
+ Take(usize),
+ Put,
+ Produce(ItemIndex),
+ Consume(usize),
+}
+use Out::*;
+
+pub fn interact(
+ data: &Gamedata,
+ edge: bool,
+ tile: TileIndex,
+ items: &[ItemIndex],
+ hand: &Option<ItemIndex>,
+ mut out: impl FnMut(Out),
+) {
+ let mut allowed = BTreeSet::new();
+ for r in &data.recipes {
+ if r.tile == tile {
+ allowed.extend(r.inputs.clone())
+ }
+ }
+ if !edge {
+ return;
+ }
+
+ let mut put_item = None;
+ if let Some(hand) = hand {
+ if allowed.contains(hand) {
+ out(Put);
+ put_item = Some(*hand);
+ }
+ }
+
+ for r in &data.recipes {
+ let ok = r
+ .inputs
+ .iter()
+ .all(|e| items.contains(e) || put_item == Some(*e))
+ && r.inputs.len() == items.len();
+ if ok {
+ match r.action {
+ Action::Passive(_) => todo!(),
+ Action::Active(_) => todo!(),
+ Action::Instant => {
+ for i in 0..items.len() {
+ out(Consume(i))
+ }
+ for i in &r.outputs {
+ out(Produce(*i));
+ }
+ if !r.outputs.is_empty() {
+ out(Take(r.outputs.len() - 1));
+ }
+ }
+ Action::Never => (),
+ }
+ }
+ }
+}