diff options
author | metamuffin <metamuffin@disroot.org> | 2024-06-18 19:36:36 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-06-23 19:21:22 +0200 |
commit | 48934ff63ee14d4759eda36512af87361dd915dd (patch) | |
tree | f7a80115eacfee7b6871040a87f5fb0087098ea8 /server/src/interaction.rs | |
parent | 6ec47d729509db83eaeb6a9d855ce2483d70f227 (diff) | |
download | hurrycurry-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.rs | 302 |
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))); +// } +// } +// } |