summaryrefslogtreecommitdiff
path: root/server/src/interaction.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-18 21:04:11 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-23 19:21:22 +0200
commitf4bc78d9dffda792cde848e0ae8040a98959591b (patch)
tree271ff06cbda6955eb5e093f83a952b9cb7b3e2a6 /server/src/interaction.rs
parent48934ff63ee14d4759eda36512af87361dd915dd (diff)
downloadhurrycurry-f4bc78d9dffda792cde848e0ae8040a98959591b.tar
hurrycurry-f4bc78d9dffda792cde848e0ae8040a98959591b.tar.bz2
hurrycurry-f4bc78d9dffda792cde848e0ae8040a98959591b.tar.zst
passive works
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r--server/src/interaction.rs227
1 files changed, 91 insertions, 136 deletions
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index aa216410..75cd0c84 100644
--- a/server/src/interaction.rs
+++ b/server/src/interaction.rs
@@ -1,11 +1,9 @@
use crate::{
- data::{Action, Gamedata},
+ data::Gamedata,
game::{Involvement, Item, Player, Tile},
protocol::{ItemIndex, TileIndex},
};
-use log::{debug, info};
use serde::{Deserialize, Serialize};
-use std::collections::BTreeSet;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Recipe {
@@ -36,32 +34,47 @@ impl Recipe {
Recipe::Instant { tile, .. } => *tile,
}
}
+ pub fn duration(&self) -> Option<f32> {
+ match self {
+ Recipe::Passive { duration, .. } => Some(*duration),
+ Recipe::Active { duration, .. } => Some(*duration),
+ _ => None,
+ }
+ }
+ pub fn supports_tile(&self, tile: TileIndex) -> bool {
+ if let Some(tile_constraint) = self.tile() {
+ if tile != tile_constraint {
+ false
+ } else {
+ true
+ }
+ } else {
+ true
+ }
+ }
+}
+
+pub enum InteractEffect {
+ Put,
+ Take,
+ Produce,
}
-pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Player) {
+pub fn interact(
+ data: &Gamedata,
+ edge: bool,
+ tile: &mut Tile,
+ player: &mut Player,
+) -> Option<InteractEffect> {
if !edge {
- return;
+ return None;
}
for recipe in &data.recipes {
- if let Some(tile_constraint) = recipe.tile() {
- if tile.kind != tile_constraint {
- continue;
- }
+ if !recipe.supports_tile(tile.kind) {
+ continue;
}
match recipe {
- Recipe::Passive {
- duration,
- input,
- output,
- ..
- } => todo!(),
- Recipe::Active {
- duration,
- input: inputs,
- outputs,
- ..
- } => todo!(),
Recipe::Instant {
inputs, outputs, ..
} => {
@@ -72,125 +85,67 @@ pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Playe
if ok {
player.item = outputs[0].map(|kind| Item { kind, active: None });
tile.item = outputs[1].map(|kind| Item { kind, active: None });
+ return Some(InteractEffect::Produce);
}
}
+ _ => (),
}
}
-}
-// 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;
-// }
-// }
-// }
-// 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;
-// }
+ if tile.item.is_none() {
+ if let Some(item) = player.item.take() {
+ tile.item = Some(item);
+ return Some(InteractEffect::Put);
+ }
+ }
+ if player.item.is_none() {
+ if let Some(item) = tile.item.take() {
+ player.item = Some(item);
+ return Some(InteractEffect::Take);
+ }
+ }
-// 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 => (),
-// }
-// }
-// }
+ None
+}
-// 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)));
-// }
-// }
-// }
+pub enum TickEffect {
+ Progress,
+ Produce,
+}
+pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect> {
+ if let Some(item) = &mut tile.item {
+ if let Some(a) = &mut item.active {
+ let r = &data.recipes[a.recipe];
+ if r.supports_tile(tile.kind) {
+ a.progress += a.working as f32 * dt / r.duration().unwrap();
+ if a.progress >= 1. {
+ let Recipe::Passive { output, .. } = &data.recipes[a.recipe] else {
+ unreachable!()
+ };
+ tile.item = output.map(|kind| Item { kind, active: None });
+ return Some(TickEffect::Produce);
+ }
+ return Some(TickEffect::Progress);
+ }
+ } else {
+ for (ri, recipe) in data.recipes.iter().enumerate() {
+ if let Some(tile_constraint) = recipe.tile() {
+ if tile.kind != tile_constraint {
+ continue;
+ }
+ }
+ if let Recipe::Passive { input, .. } = recipe {
+ if *input == item.kind {
+ item.active = Some(Involvement {
+ recipe: ri,
+ progress: 0.,
+ working: 1,
+ })
+ }
+ }
+ }
+ return Some(TickEffect::Progress);
+ }
+ }
+ None
+}