diff options
| -rw-r--r-- | data/recipes.yaml | 47 | ||||
| -rw-r--r-- | server/src/game.rs | 24 | ||||
| -rw-r--r-- | server/src/interaction.rs | 42 | ||||
| -rw-r--r-- | test-client/main.ts | 7 | ||||
| -rw-r--r-- | test-client/tiles.ts | 44 | ||||
| -rw-r--r-- | test-client/util.ts | 2 | 
6 files changed, 120 insertions, 46 deletions
diff --git a/data/recipes.yaml b/data/recipes.yaml index 46ac8b15..e76b2f5e 100644 --- a/data/recipes.yaml +++ b/data/recipes.yaml @@ -1,17 +1,21 @@ -- tile: floor -  action: !never # tomato pipeline +- { tile: floor, action: !never  } +- { tile: counter, inputs: [steak-meal, void] } +- { tile: counter, inputs: [sliced-tomato-meal, void] } +- { tile: counter, inputs: [bread-meal, void] } +- { tile: counter, inputs: [tomatosteak-meal, void] } +- { tile: counter, inputs: [tomatoburger-meal, void] } -- tile: meat-spawn -  action: !instant -  outputs: [raw-steak] - -- tile: trash -  action: !instant -  inputs: [raw-steak] - +- { tile: trash, action: !instant , inputs: [raw-steak] } +- { tile: trash, action: !instant , inputs: [steak] } +- { tile: trash, action: !instant , inputs: [flour] } +- { tile: trash, action: !instant , inputs: [dough] } +- { tile: trash, action: !instant , inputs: [steak-meal] }  - { tile: table, inputs: [raw-steak, void] } +- tile: tomato-spawn # Tomato pipeline +  outputs: [tomato] +  action: !instant  - tile: table    inputs: [tomato]    outputs: [sliced-tomato] @@ -19,9 +23,11 @@  - tile: table    inputs: [sliced-tomato, plate]    outputs: [sliced-tomato-meal] -  action: !instant # bread pipeline - +  action: !instant +- tile: flour-spawn # Bread pipeline +  outputs: [flour] +  action: !instant  - tile: table    inputs: [flour]    outputs: [dough] @@ -33,9 +39,11 @@  - tile: table    inputs: [bread, plate]    outputs: [bread-meal] -  action: !instant # steak pipeline - +  action: !instant +- tile: raw-steak-spawn # Steak pipeline +  action: !instant +  outputs: [raw-steak]  - tile: pan    inputs: [raw-steak]    outputs: [steak] @@ -43,10 +51,9 @@  - tile: table    inputs: [steak, plate]    outputs: [steak-meal] -  action: !instant # combination meals - +  action: !instant -- tile: table +- tile: table # Combination meals    inputs: [steak-meal, bread]    outputs: [burger-meal]    action: !instant @@ -71,9 +78,11 @@  - tile: sink    inputs: [water]    outputs: [glass] -  action: !instant # cleaning - +  action: !instant +- tile: dirty-plate-spawn # Cleaning +  outputs: [dirty-plate] +  action: !instant  - tile: sink    inputs: [dirty-glass]    outputs: [glass] diff --git a/server/src/game.rs b/server/src/game.rs index 14d096e1..4f724446 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -3,7 +3,7 @@ use crate::{      protocol::{ItemID, ItemIndex, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex},      recipes::Gamedata,  }; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, bail, Result};  use glam::IVec2;  use log::info;  use std::{ @@ -26,6 +26,7 @@ pub struct Tile {  struct Player {      name: String, +    interacting: bool,      hand: Option<ItemID>,  } @@ -57,7 +58,7 @@ impl Game {          for x in -5..5 {              g.tiles.insert(                  IVec2 { x, y: -5 }, -                gamedata.get_tile("table").unwrap().into(), +                gamedata.get_tile("counter").unwrap().into(),              );              g.tiles.insert(                  IVec2 { x, y: 4 }, @@ -77,10 +78,14 @@ impl Game {          g.tiles.extend(              [ +                ([1, 4], "pan"),                  ([2, 4], "pan"), -                ([3, 4], "pan"), -                ([4, 3], "meat-spawn"), -                ([4, 1], "trash"), +                ([-5, 2], "sink"), +                ([-5, 3], "dirty-plate-spawn"), +                ([4, 0], "flour-spawn"), +                ([4, 1], "tomato-spawn"), +                ([4, 2], "raw-steak-spawn"), +                ([4, -4], "trash"),              ]              .map(|(k, v)| (IVec2::from_array(k), gamedata.get_tile(v).unwrap().into())),          ); @@ -128,6 +133,7 @@ impl Game {                      player,                      Player {                          hand: None, +                        interacting: false,                          name: name.clone(),                      },                  ); @@ -153,6 +159,8 @@ impl Game {                      .push_back(PacketC::Position { player, pos, rot });              }              PacketS::Interact { pos, edge } => { +                info!("interact {pos:?} edge={edge}"); +                  let pid = player;                  let player = self                      .players @@ -163,6 +171,10 @@ impl Game {                      .get_mut(&pos)                      .ok_or(anyhow!("tile does not exist"))?; +                if edge == player.interacting { +                    bail!("already (not) interacting") +                } +                  let items = tile.items.iter().map(|e| self.items[e]).collect::<Vec<_>>();                  let tilekind = tile.kind;                  let hand = player.hand.map(|e| self.items[&e]); @@ -212,6 +224,8 @@ impl Game {                          }                      },                  ); + +                player.interacting = edge;              }          }          Ok(()) diff --git a/server/src/interaction.rs b/server/src/interaction.rs index f2d44dee..11409b10 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -31,14 +31,26 @@ pub fn interact(          }      }      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; @@ -54,7 +66,7 @@ pub fn interact(          }      } -    if hand.is_none() { +    if hand.is_none() && active.is_none() {          'rloop: for (ri, r) in data.recipes.iter().enumerate() {              if tile != r.tile {                  continue; @@ -74,19 +86,27 @@ pub fn interact(              match r.action {                  Action::Passive(_) => { -                    info!("use recipe {r:?}"); +                    info!("use passive recipe {ri}");                      *active = Some(ActiveRecipe {                          recipe: ri,                          progress: 0., -                        working: 0, +                        working: 1, +                    }); +                    break 'rloop; +                } +                Action::Active(_) => { +                    info!("use active recipe {ri}"); +                    *active = Some(ActiveRecipe { +                        recipe: ri, +                        progress: 0., +                        working: 1,                      });                      break 'rloop;                  } -                Action::Active(_) => {}                  Action::Instant => { -                    info!("use recipe {r:?}"); -                    for i in 0..items.len() { -                        out(Consume(i)) +                    info!("use instant recipe {ri}"); +                    for _ in 0..items.len() { +                        out(Consume(0))                      }                      for i in &r.outputs {                          out(Produce(*i)); @@ -108,15 +128,15 @@ pub fn tick_tile(      data: &Gamedata,      _tile: TileIndex,      active: &mut Option<ActiveRecipe>, -    mut items: Vec<ItemIndex>, +    items: Vec<ItemIndex>,      mut out: impl FnMut(Out),  ) {      if let Some(a) = active {          let r = &data.recipes[a.recipe]; -        a.progress += dt / r.action.duration(); +        a.progress += a.working as f32 * dt / r.action.duration();          if a.progress >= 1. { -            for i in 0..items.len() { -                out(Consume(i)) +            for _ in 0..items.len() { +                out(Consume(0))              }              for i in &r.outputs {                  out(Produce(*i)); diff --git a/test-client/main.ts b/test-client/main.ts index ef84689f..1b034f28 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -49,7 +49,7 @@ let scale = 0  function send(p: PacketS) { ws.send(JSON.stringify(p)) }  function packet(p: PacketC) { -    if (!("position" in p)) console.log(p); +    if (!("position" in p) && !("set_active" in p)) console.log(p);      if ("joined" in p) {          my_id = p.joined.id          data = p.joined.data @@ -90,9 +90,12 @@ const keys_down = new Set();  const HANDLED_KEYS = ["KeyW", "KeyA", "KeyS", "KeyD", "Space"]  function keyboard(ev: KeyboardEvent, down: boolean) {      if (HANDLED_KEYS.includes(ev.code)) ev.preventDefault() -    if (ev.code == "Space") interact(down) +    let change; +    if (down) change = !keys_down.has(ev.code) +    else change = keys_down.has(ev.code)      if (down) keys_down.add(ev.code)      else keys_down.delete(ev.code) +    if (change && ev.code == "Space") interact(down)  }  function get_interact_target(): V2 | undefined { diff --git a/test-client/tiles.ts b/test-client/tiles.ts index c628ea5d..883ab7cb 100644 --- a/test-client/tiles.ts +++ b/test-client/tiles.ts @@ -7,7 +7,7 @@ function base(fill: string, stroke?: string, stroke_width?: number): Component {          c.lineWidth = stroke_width ?? 0.05          c.lineJoin = "miter"          c.lineCap = "square" -        c.fillRect(-0.5, -0.5, 1,1) +        c.fillRect(-0.5, -0.5, 1, 1)          if (stroke) c.strokeRect(-0.5 + c.lineWidth / 2, -0.5 + c.lineWidth / 2, 1 - c.lineWidth, 1 - c.lineWidth)      }  } @@ -22,20 +22,48 @@ function circle(radius: number, fill: string, stroke?: string, stroke_width?: nu          c.fill()      }  } +function cross(size: number, stroke: string, stroke_width = 0.05): Component { +    return c => { +        c.strokeStyle = stroke +        c.lineWidth = stroke_width +        c.lineCap = "round" +        c.beginPath() +        c.moveTo(-size, -size) +        c.lineTo(size, size) +        c.moveTo(size, -size) +        c.lineTo(-size, size) +        c.stroke() +    } +} + +const plate = [circle(0.4, "#b6b6b6", "#f7f7f7", 0.02)]; + +export const FALLBACK_ITEM: Component[] = [circle(0.3, "#f0f")]; +export const ITEMS: { [key: string]: Component[] } = { +    "raw-steak": [circle(0.3, "#cc3705")], +    "steak": [circle(0.3, "#702200")], +    "flour": [circle(0.3, "#d8c9c2")], +    "dough": [circle(0.3, "#b38d7d")], +    "tomato": [circle(0.3, "#d63838")], +    "dirty-plate": [circle(0.4, "#947a6f", "#d3a187", 0.02)], +    "plate": plate, +    "steak-meal": [...plate, circle(0.3, "#702200")], +}  const table = [base("rgb(133, 76, 38)")];  const floor = [base("#333", "#222", 0.05)]; +const spawn = (i: string) => [base("#60701e", "#b9da37", 0.05), ...ITEMS[i]];  export const FALLBACK_TILE: Component[] = [base("#f0f")];  export const TILES: { [key: string]: Component[] } = {      "floor": floor,      "table": table, +    "counter": [base("rgb(182, 172, 164)")], +    "trash": [...floor, circle(0.4, "rgb(20, 20, 20)"), cross(0.3, "rgb(90, 36, 36)")], +    "sink": [base("rgb(131, 129, 161)", "rgb(177, 174, 226)", 0.2)],      "pan": [...table, circle(0.4, "#444", "#999")], -    "flour_bag": [...floor, circle(0.5, "#fff", "#ddd")], -} - -export const FALLBACK_ITEM: Component[] = [circle(0.3, "#f0f")]; -export const ITEMS: { [key: string]: Component[] } = { -    "raw-steak": [circle(0.3, "rgb(204, 55, 5)")], -    "steak": [circle(0.3, "rgb(112, 34, 0)")], +    "flour-spawn": spawn("flour"), +    "dirty-plate-spawn": spawn("dirty-plate"), +    "raw-steak-spawn": spawn("raw-steak"), +    "tomato-spawn": spawn("tomato"),  } diff --git a/test-client/util.ts b/test-client/util.ts index 6febac37..baebc61e 100644 --- a/test-client/util.ts +++ b/test-client/util.ts @@ -20,4 +20,4 @@ export function ceil_v2(p: V2): V2 { return { x: Math.ceil(p.x), y: Math.ceil(p.  export function add_v2(p: V2, o: V2 | number) {      if (typeof o == "number") return { x: p.x + o, y: p.y + o }      else return { x: p.x + o.x, y: p.y + o.y } -}
\ No newline at end of file +}  |