summaryrefslogtreecommitdiff
path: root/server/src/interaction.rs
blob: 5f8b0097bcf7249c70d98f24cd1dac71ff99b623 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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 => (),
            }
        }
    }
}