diff options
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r-- | server/src/interaction.rs | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 5f8b0097..7ef4a9b4 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -1,8 +1,11 @@ use crate::{ + game::ActiveRecipe, protocol::{ItemIndex, TileIndex}, recipes::{Action, Gamedata}, }; +use log::{debug, info}; use std::collections::BTreeSet; +use Out::*; pub enum Out { Take(usize), @@ -10,14 +13,14 @@ pub enum Out { Produce(ItemIndex), Consume(usize), } -use Out::*; pub fn interact( data: &Gamedata, edge: bool, tile: TileIndex, - items: &[ItemIndex], - hand: &Option<ItemIndex>, + active: &mut Option<ActiveRecipe>, + mut items: Vec<ItemIndex>, + mut hand: Option<ItemIndex>, mut out: impl FnMut(Out), ) { let mut allowed = BTreeSet::new(); @@ -27,28 +30,52 @@ pub fn interact( } } if !edge { + if let Some(ac) = active { + if matches!(data.recipes[ac.recipe].action, Action::Active(_)) { + ac.working -= 1; + } + } return; } - let mut put_item = None; - if let Some(hand) = hand { - if allowed.contains(hand) { + if let Some(hi) = hand { + if allowed.contains(&hi) { out(Put); - put_item = Some(*hand); + items.push(hi); + hand = None; } } - 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 { + if hand.is_none() { + 'rloop: for (ri, r) in data.recipes.iter().enumerate() { + if tile != r.tile { + continue; + } + let mut inputs = r.inputs.clone(); + for i in &items { + debug!("take {i:?} {inputs:?}"); + let Some(pos) = inputs.iter().position(|e| e == i) else { + continue 'rloop; + }; + inputs.remove(pos); + } + debug!("end {inputs:?}"); + if !inputs.is_empty() { + continue; + } + match r.action { - Action::Passive(_) => todo!(), - Action::Active(_) => todo!(), + Action::Passive(_) => { + *active = Some(ActiveRecipe { + recipe: ri, + progress: 0., + working: 0, + }); + break 'rloop; + } + Action::Active(_) => {} Action::Instant => { + info!("use recipe {r:?}"); for i in 0..items.len() { out(Consume(i)) } @@ -58,9 +85,14 @@ pub fn interact( if !r.outputs.is_empty() { out(Take(r.outputs.len() - 1)); } + break 'rloop; } Action::Never => (), } } } + + if !items.is_empty() && hand.is_none() { + out(Take(items.len() - 1)); + } } |