summaryrefslogtreecommitdiff
path: root/server/src/interaction.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-18 19:36:36 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-23 19:21:22 +0200
commit48934ff63ee14d4759eda36512af87361dd915dd (patch)
treef7a80115eacfee7b6871040a87f5fb0087098ea8 /server/src/interaction.rs
parent6ec47d729509db83eaeb6a9d855ce2483d70f227 (diff)
downloadhurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar
hurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar.bz2
hurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar.zst
remodel game.
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r--server/src/interaction.rs302
1 files changed, 174 insertions, 128 deletions
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index 11409b10..aa216410 100644
--- a/server/src/interaction.rs
+++ b/server/src/interaction.rs
@@ -1,150 +1,196 @@
use crate::{
- game::ActiveRecipe,
+ data::{Action, Gamedata},
+ game::{Involvement, Item, Player, Tile},
protocol::{ItemIndex, TileIndex},
- recipes::{Action, Gamedata},
};
use log::{debug, info};
+use serde::{Deserialize, Serialize};
use std::collections::BTreeSet;
-use Out::*;
-pub enum Out {
- Take(usize),
- Put,
- Produce(ItemIndex),
- Consume(usize),
- SetActive(Option<f32>),
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub enum Recipe {
+ Passive {
+ duration: f32,
+ tile: Option<TileIndex>,
+ input: ItemIndex,
+ output: Option<ItemIndex>,
+ },
+ Active {
+ duration: f32,
+ tile: Option<TileIndex>,
+ input: ItemIndex,
+ outputs: [Option<ItemIndex>; 2],
+ },
+ Instant {
+ tile: Option<TileIndex>,
+ inputs: [Option<ItemIndex>; 2],
+ outputs: [Option<ItemIndex>; 2],
+ },
}
-pub fn interact(
- data: &Gamedata,
- edge: bool,
- tile: TileIndex,
- active: &mut Option<ActiveRecipe>,
- mut items: Vec<ItemIndex>,
- mut 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 {
- debug!("falling edge");
- if let Some(ac) = active {
- if matches!(data.recipes[ac.recipe].action, Action::Active(_)) {
- debug!("workers--");
- ac.working -= 1;
- }
- }
- return;
- }
-
- if hand.is_none() {
- debug!("rising edge");
- if let Some(active) = active {
- if matches!(data.recipes[active.recipe].action, Action::Active(_)) {
- debug!("workers++");
- active.working += 1;
- }
+impl Recipe {
+ pub fn tile(&self) -> Option<TileIndex> {
+ match self {
+ Recipe::Passive { tile, .. } => *tile,
+ Recipe::Active { tile, .. } => *tile,
+ Recipe::Instant { tile, .. } => *tile,
}
}
+}
- if active.is_none() && !items.is_empty() && hand.is_none() {
- out(Take(items.len() - 1));
+pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Player) {
+ if !edge {
return;
}
- if active.is_none() {
- if let Some(hi) = hand {
- if allowed.contains(&hi) {
- out(Put);
- items.push(hi);
- hand = None;
- }
- }
- }
-
- if hand.is_none() && active.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() {
+ for recipe in &data.recipes {
+ if let Some(tile_constraint) = recipe.tile() {
+ if tile.kind != tile_constraint {
continue;
}
-
- match r.action {
- Action::Passive(_) => {
- info!("use passive recipe {ri}");
- *active = Some(ActiveRecipe {
- recipe: ri,
- progress: 0.,
- working: 1,
- });
- break 'rloop;
- }
- Action::Active(_) => {
- info!("use active recipe {ri}");
- *active = Some(ActiveRecipe {
- recipe: ri,
- progress: 0.,
- working: 1,
- });
- break 'rloop;
- }
- Action::Instant => {
- info!("use instant recipe {ri}");
- for _ in 0..items.len() {
- out(Consume(0))
- }
- for i in &r.outputs {
- out(Produce(*i));
- }
- if !r.outputs.is_empty() {
- out(Take(r.outputs.len() - 1));
- }
- items.clear();
- break 'rloop;
+ }
+ match recipe {
+ Recipe::Passive {
+ duration,
+ input,
+ output,
+ ..
+ } => todo!(),
+ Recipe::Active {
+ duration,
+ input: inputs,
+ outputs,
+ ..
+ } => todo!(),
+ Recipe::Instant {
+ inputs, outputs, ..
+ } => {
+ let on_tile = tile.item.as_ref().map(|i| i.kind);
+ let in_hand = player.item.as_ref().map(|i| i.kind);
+ let ok = (inputs[0] == on_tile && inputs[1] == in_hand)
+ || (inputs[1] == on_tile && inputs[0] == in_hand);
+ if ok {
+ player.item = outputs[0].map(|kind| Item { kind, active: None });
+ tile.item = outputs[1].map(|kind| Item { kind, active: None });
}
- Action::Never => (),
}
}
}
}
+// if !edge {
+// debug!("falling edge");
+// if let Some(ac) = active {
+// if matches!(data.recipes[ac.recipe].action, Action::Active(_)) {
+// debug!("workers--");
+// ac.working -= 1;
+// }
+// }
+// return;
+// }
-pub fn tick_tile(
- dt: f32,
- data: &Gamedata,
- _tile: TileIndex,
- active: &mut Option<ActiveRecipe>,
- items: Vec<ItemIndex>,
- mut out: impl FnMut(Out),
-) {
- if let Some(a) = active {
- let r = &data.recipes[a.recipe];
- a.progress += a.working as f32 * dt / r.action.duration();
- if a.progress >= 1. {
- for _ in 0..items.len() {
- out(Consume(0))
- }
- for i in &r.outputs {
- out(Produce(*i));
- }
- out(SetActive(None));
- active.take();
- } else {
- out(SetActive(Some(a.progress)));
- }
- }
-}
+// if hand.is_none() {
+// debug!("rising edge");
+// if let Some(active) = active {
+// if matches!(data.recipes[active.recipe].action, Action::Active(_)) {
+// debug!("workers++");
+// active.working += 1;
+// }
+// }
+// }
+
+// if active.is_none() && !items.is_empty() && hand.is_none() {
+// out(Take(items.len() - 1));
+// return;
+// }
+
+// if active.is_none() {
+// if let Some(hi) = hand {
+// if allowed.contains(&hi) {
+// out(Put);
+// items.push(hi);
+// hand = None;
+// }
+// }
+// }
+
+// if hand.is_none() && active.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(_) => {
+// info!("use passive recipe {ri}");
+// *active = Some(Involvement {
+// recipe: ri,
+// progress: 0.,
+// working: 1,
+// });
+// break 'rloop;
+// }
+// Action::Active(_) => {
+// info!("use active recipe {ri}");
+// *active = Some(Involvement {
+// recipe: ri,
+// progress: 0.,
+// working: 1,
+// });
+// break 'rloop;
+// }
+// Action::Instant => {
+// info!("use instant recipe {ri}");
+// for _ in 0..items.len() {
+// out(Consume(0))
+// }
+// for i in &r.outputs {
+// out(Produce(*i));
+// }
+// if !r.outputs.is_empty() {
+// out(Take(r.outputs.len() - 1));
+// }
+// items.clear();
+// break 'rloop;
+// }
+// Action::Never => (),
+// }
+// }
+// }
+
+// pub fn tick_tile(
+// dt: f32,
+// data: &Gamedata,
+// _tile: TileIndex,
+// active: &mut Option<Involvement>,
+// items: Vec<ItemIndex>,
+// mut out: impl FnMut(Out),
+// ) {
+// if let Some(a) = active {
+// let r = &data.recipes[a.recipe];
+// a.progress += a.working as f32 * dt / r.action.duration();
+// if a.progress >= 1. {
+// for _ in 0..items.len() {
+// out(Consume(0))
+// }
+// for i in &r.outputs {
+// out(Produce(*i));
+// }
+// out(SetActive(None));
+// active.take();
+// } else {
+// out(SetActive(Some(a.progress)));
+// }
+// }
+// }