diff options
-rw-r--r-- | server/src/game.rs | 52 | ||||
-rw-r--r-- | server/src/interaction.rs | 41 | ||||
-rw-r--r-- | test-client/main.ts | 26 | ||||
-rw-r--r-- | test-client/tiles.ts | 12 |
4 files changed, 102 insertions, 29 deletions
diff --git a/server/src/game.rs b/server/src/game.rs index f207e8f6..14d096e1 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -1,5 +1,5 @@ use crate::{ - interaction::{interact, Out}, + interaction::{interact, tick_tile, Out}, protocol::{ItemID, ItemIndex, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex}, recipes::Gamedata, }; @@ -22,7 +22,6 @@ pub struct Tile { kind: TileIndex, items: Vec<ItemID>, active: Option<ActiveRecipe>, - last_active: bool, } struct Player { @@ -205,6 +204,12 @@ impl Game { info!("left {:?}", tile.items); self.packet_out.push_back(PacketC::ConsumeItem { id, pos }); } + Out::SetActive(progress) => { + self.packet_out.push_back(PacketC::SetActive { + tile: pos, + progress, + }); + } }, ); } @@ -214,14 +219,40 @@ impl Game { pub fn tick(&mut self, dt: f32) { for (&pos, tile) in &mut self.tiles { - if let Some(active) = &mut tile.active { - active.progress += dt / self.data.recipes[active.recipe].action.duration(); - self.packet_out.push_back(PacketC::SetActive { - tile: pos, - progress: Some(active.progress), - }); - } - tile.last_active = tile.active.is_some() + let items = tile.items.iter().map(|e| self.items[e]).collect::<Vec<_>>(); + tick_tile( + dt, + &self.data, + tile.kind, + &mut tile.active, + items, + |out| match out { + Out::Take(_) | Out::Put => { + unreachable!() + } + Out::Produce(kind) => { + info!("produce"); + let id = self.item_id_counter; + self.item_id_counter += 1; + self.items.insert(id, kind); + tile.items.push(id); + self.packet_out + .push_back(PacketC::ProduceItem { id, pos, kind }); + } + Out::Consume(index) => { + info!("consume"); + let id = tile.items.remove(index); + info!("left {:?}", tile.items); + self.packet_out.push_back(PacketC::ConsumeItem { id, pos }); + } + Out::SetActive(progress) => { + self.packet_out.push_back(PacketC::SetActive { + tile: pos, + progress, + }); + } + }, + ); } } } @@ -231,7 +262,6 @@ impl From<TileIndex> for Tile { Self { kind, items: vec![], - last_active: false, active: None, } } diff --git a/server/src/interaction.rs b/server/src/interaction.rs index fadfe8d9..f2d44dee 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -12,6 +12,7 @@ pub enum Out { Put, Produce(ItemIndex), Consume(usize), + SetActive(Option<f32>), } pub fn interact( @@ -38,16 +39,18 @@ pub fn interact( return; } - if !items.is_empty() && hand.is_none() { + if active.is_none() && !items.is_empty() && hand.is_none() { out(Take(items.len() - 1)); return; } - if let Some(hi) = hand { - if allowed.contains(&hi) { - out(Put); - items.push(hi); - hand = None; + if active.is_none() { + if let Some(hi) = hand { + if allowed.contains(&hi) { + out(Put); + items.push(hi); + hand = None; + } } } @@ -99,3 +102,29 @@ pub fn interact( } } } + +pub fn tick_tile( + dt: f32, + data: &Gamedata, + _tile: TileIndex, + active: &mut Option<ActiveRecipe>, + mut 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(); + if a.progress >= 1. { + for i in 0..items.len() { + out(Consume(i)) + } + for i in &r.outputs { + out(Produce(*i)); + } + out(SetActive(None)); + active.take(); + } else { + out(SetActive(Some(a.progress))); + } + } +} diff --git a/test-client/main.ts b/test-client/main.ts index 3926dffc..ef84689f 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -1,7 +1,8 @@ /// <reference lib="dom" /> import { Gamedata, ItemID, ItemIndex, PacketC, PacketS, PlayerID, TileIndex } from "./protocol.ts"; -import { FALLBACK_TILE, TILES } from "./tiles.ts"; +import { FALLBACK_ITEM } from "./tiles.ts"; +import { FALLBACK_TILE, ITEMS, TILES } from "./tiles.ts"; import { V2, add_v2, ceil_v2, floor_v2, length, lerp_exp_v2_mut, normalize } from "./util.ts"; let ctx: CanvasRenderingContext2D; @@ -192,15 +193,11 @@ function draw_ingame() { for (const [_, tile] of tiles) { ctx.save() - ctx.translate(tile.x, tile.y) + ctx.translate(tile.x + 0.5, tile.y + 0.5) const comps = TILES[data.tile_names[tile.kind]] ?? FALLBACK_TILE for (const c of comps) { c(ctx) } - if (tile.active_progress !== null && tile.active_progress !== undefined) { - ctx.fillStyle = "rgba(115, 230, 58, 0.66)" - ctx.fillRect(0, 0, 1, tile.active_progress) - } ctx.restore() } @@ -216,10 +213,21 @@ function draw_ingame() { for (const [_, item] of items) { ctx.save() - ctx.translate(item.x, item.y) - ctx.fillStyle = "rgb(252, 19, 19)" - ctx.fillRect(-0.1, -0.1, 0.2, 0.2) + const comps = ITEMS[data.item_names[item.kind]] ?? FALLBACK_ITEM + for (const c of comps) { + c(ctx) + } + ctx.restore() + } + + for (const [_, tile] of tiles) { + ctx.save() + ctx.translate(tile.x, tile.y) + if (tile.active_progress !== null && tile.active_progress !== undefined) { + ctx.fillStyle = "rgba(115, 230, 58, 0.66)" + ctx.fillRect(0, 0, 1, tile.active_progress) + } ctx.restore() } diff --git a/test-client/tiles.ts b/test-client/tiles.ts index 6eb1dc29..c628ea5d 100644 --- a/test-client/tiles.ts +++ b/test-client/tiles.ts @@ -7,8 +7,8 @@ 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, 0, 1, 1) - if (stroke) c.strokeRect(c.lineWidth / 2, c.lineWidth / 2, 1 - c.lineWidth, 1 - c.lineWidth) + 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) } } function circle(radius: number, fill: string, stroke?: string, stroke_width?: number): Component { @@ -17,7 +17,7 @@ function circle(radius: number, fill: string, stroke?: string, stroke_width?: nu c.strokeStyle = stroke ?? "black"; c.lineWidth = stroke_width ?? 0.05 c.beginPath() - c.arc(0.5, 0.5, radius, 0, Math.PI * 2) + c.arc(0.0, 0.0, radius, 0, Math.PI * 2) if (stroke) c.stroke() c.fill() } @@ -33,3 +33,9 @@ export const TILES: { [key: string]: Component[] } = { "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)")], +} |