diff options
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r-- | server/src/interaction.rs | 66 |
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 => (), + } + } + } +} |