summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/game.rs16
-rw-r--r--server/src/protocol.rs4
-rw-r--r--test-client/main.ts67
-rw-r--r--test-client/tiles.ts4
-rw-r--r--test-client/util.ts15
5 files changed, 91 insertions, 15 deletions
diff --git a/server/src/game.rs b/server/src/game.rs
index fbbab0a4..18bd6519 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -1,6 +1,7 @@
use crate::protocol::{Item, PacketC, PacketS, Tile, ID};
use anyhow::{anyhow, Result};
use glam::IVec2;
+use log::info;
use std::collections::{HashMap, VecDeque};
struct TileData {
@@ -44,7 +45,7 @@ impl Game {
[
([-5, 1], Tile::Pan),
([-5, 2], Tile::Pan),
- ([4, 3], Tile::Pan),
+ ([4, 3], Tile::FlourBag),
]
.map(|(k, v)| {
(
@@ -132,11 +133,24 @@ impl Game {
.get_mut(&player)
.ok_or(anyhow!("player does not exist"))?;
+ if let Tile::FlourBag = tile.kind {
+ info!("new flour");
+ self.items.insert(self.item_id_counter, Item::Flour);
+ tile.items.push(self.item_id_counter);
+ self.packet_out.push_back(PacketC::ProduceItem {
+ id: self.item_id_counter,
+ pos,
+ kind: Item::Flour,
+ });
+ self.item_id_counter += 1;
+ }
if let Some(item) = player_data.hand.take() {
+ info!("put {item}");
tile.items.push(item);
self.packet_out.push_back(PacketC::PutItem { item, pos })
} else {
if let Some(item) = tile.items.pop() {
+ info!("take {item}");
player_data.hand = Some(item);
self.packet_out
.push_back(PacketC::TakeItem { item, player })
diff --git a/server/src/protocol.rs b/server/src/protocol.rs
index a8fd9979..0218658d 100644
--- a/server/src/protocol.rs
+++ b/server/src/protocol.rs
@@ -6,6 +6,8 @@ pub type ID = u32;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Item {
+ Flour,
+ Water,
Dough,
Pancake,
}
@@ -13,6 +15,8 @@ pub enum Item {
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Tile {
+ Sink,
+ FlourBag,
Floor,
Table,
Pan,
diff --git a/test-client/main.ts b/test-client/main.ts
index 3c1285a4..009b1705 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -1,8 +1,8 @@
/// <reference lib="dom" />
-import { ID, Item, PacketC, PacketS, Tile } from "./protocol.ts";
+import { ID, Item, PacketC, PacketS, Tile, Vec2 } from "./protocol.ts";
import { FALLBACK_TILE, TILES } from "./tiles.ts";
-import { V2, ceil_v2, floor_v2, lerp_v2_mut, normalize } from "./util.ts";
+import { V2, add_v2, ceil_v2, floor_v2, lerp_exp_v2_mut, normalize } from "./util.ts";
let ctx: CanvasRenderingContext2D;
let canvas: HTMLCanvasElement;
@@ -34,9 +34,9 @@ document.addEventListener("DOMContentLoaded", () => {
interface PlayerData { x: number; y: number, name: string, rot: number, hand?: ID }
const players = new Map<number, PlayerData>()
-interface ItemData { x: number; y: number, kind: Item }
+interface ItemData { kind: Item, tile?: V2, player?: ID, tracking_player: boolean, x: number, y: number }
const items = new Map<number, ItemData>()
-interface TileData { x: number; y: number, kind: Tile }
+interface TileData { x: number; y: number, kind: Tile, items: ID[], active: boolean }
const tiles = new Map<string, TileData>()
let my_id: number = -1
@@ -49,7 +49,7 @@ function packet(p: PacketC) {
if ("joined" in p) {
my_id = p.joined.id
} else if ("add_player" in p) {
- if (p.add_player.hand) items.set(p.add_player.hand[0], { kind: p.add_player.hand[1], x: 0, y: 0 })
+ if (p.add_player.hand) items.set(p.add_player.hand[0], { kind: p.add_player.hand[1], player: p.add_player.id, tracking_player: true, x: 0, y: 0 })
players.set(p.add_player.id, { x: 0, y: 0, name: p.add_player.name, rot: 0, hand: p.add_player.hand?.[0] })
} else if ("remove_player" in p) {
players.delete(p.remove_player.id)
@@ -60,17 +60,22 @@ function packet(p: PacketC) {
pl.y = p.position.pos[1]
pl.rot = p.position.rot
} else if ("take_item" in p) {
- // TODO
+ const item = items.get(p.take_item.item)!
+ item.tracking_player = true
+ item.player = p.take_item.player
} else if ("put_item" in p) {
- // TODO
+ const item = items.get(p.put_item.item)!
+ item.tracking_player = false
+ item.tile = { x: p.put_item.pos[0], y: p.put_item.pos[1] }
} else if ("produce_item" in p) {
- // TODO
+ items.set(p.produce_item.id, { kind: p.produce_item.kind, x: p.produce_item.pos[0] + 0.5, y: p.produce_item.pos[1] + 0.5, tracking_player: false, tile: { x: p.produce_item.pos[0], y: p.produce_item.pos[1] } })
+ tiles.get(p.produce_item.pos.toString())!.items.push(p.produce_item.id)
} else if ("consume_item" in p) {
// TODO
} else if ("set_active" in p) {
// TODO
} else if ("update_map" in p) {
- tiles.set(p.update_map.pos.toString(), { x: p.update_map.pos[0], y: p.update_map.pos[1], kind: p.update_map.tile })
+ tiles.set(p.update_map.pos.toString(), { x: p.update_map.pos[0], y: p.update_map.pos[1], kind: p.update_map.tile, active: false, items: [] })
} else console.warn("unknown packet", p);
}
@@ -78,13 +83,22 @@ 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()
+ if (ev.code == "Space" && down) interact()
if (down) keys_down.add(ev.code)
else keys_down.delete(ev.code)
}
-function interact() {
+function get_interact_target(): Vec2 | undefined {
+ const me = players.get(my_id)
+ if (!me) return
+ return [
+ Math.floor(me.x + Math.sin(me.rot)),
+ Math.floor(me.y + Math.cos(me.rot))
+ ]
+}
+function interact() {
+ send({ interact: { pos: get_interact_target()! } })
}
function tick_update() {
@@ -105,7 +119,11 @@ function frame_update(dt: number) {
p.x += input.x * dt * 5
p.y += input.y * dt * 5
- lerp_v2_mut(camera, p, dt * 10.)
+ for (const [_, i] of items) {
+ lerp_exp_v2_mut(i, i.tracking_player ? players.get(i.player!)! : add_v2(i.tile!, 0.5), dt * 10.)
+ }
+
+ lerp_exp_v2_mut(camera, p, dt * 10.)
}
function resize() {
@@ -181,6 +199,31 @@ function draw_ingame() {
ctx.restore()
}
+ 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)
+ ctx.restore()
+ }
+
+ draw_interact_target()
+
+ ctx.restore()
+}
+
+function draw_interact_target() {
+ const [x, y] = get_interact_target() ?? [0, 0]
+ ctx.save()
+ ctx.translate(x, y)
+
+ ctx.lineCap = "round"
+ ctx.lineJoin = "round"
+ ctx.lineWidth = 0.06 + 0.03 * Math.sin(Date.now() / 100)
+ ctx.strokeStyle = "rgb(84, 122, 236)"
+ ctx.strokeRect(0, 0, 1, 1)
+
ctx.restore()
}
diff --git a/test-client/tiles.ts b/test-client/tiles.ts
index 3b15385c..6eb1dc29 100644
--- a/test-client/tiles.ts
+++ b/test-client/tiles.ts
@@ -24,10 +24,12 @@ function circle(radius: number, fill: string, stroke?: string, stroke_width?: nu
}
const table = [base("rgb(133, 76, 38)")];
+const floor = [base("#333", "#222", 0.05)];
export const FALLBACK_TILE: Component[] = [base("#f0f")];
export const TILES: { [key: string]: Component[] } = {
- "floor": [base("#333", "#222", 0.05)],
+ "floor": floor,
"table": table,
"pan": [...table, circle(0.4, "#444", "#999")],
+ "flour_bag": [...floor, circle(0.5, "#fff", "#ddd")],
}
diff --git a/test-client/util.ts b/test-client/util.ts
index 99f0c013..6febac37 100644
--- a/test-client/util.ts
+++ b/test-client/util.ts
@@ -2,9 +2,22 @@ export interface V2 { x: number, y: number }
export function length(p: V2): number { return Math.sqrt(p.x * p.x + p.y * p.y) }
export function normalize_mut(p: V2) { const l = length(p); if (l == 0) return; p.x /= l; p.y /= l }
export function normalize(p: V2): V2 { let l = length(p); if (l == 0) l = 1; return { x: p.x / l, y: p.y / l } }
-export function lerp_v2_mut(current: V2, target: V2, dt: number) {
+export function lerp_exp(current: number, target: number, dt: number): number {
+ return target + (current - target) * Math.exp(-dt)
+}
+export function lerp_v2(a: V2, b: V2, t: number): V2 {
+ return {
+ x: a.x * (1 - t) + b.x * t,
+ y: a.y * (1 - t) + b.y * t,
+ }
+}
+export function lerp_exp_v2_mut(current: V2, target: V2, dt: number) {
current.x = target.x + (current.x - target.x) * Math.exp(-dt)
current.y = target.y + (current.y - target.y) * Math.exp(-dt)
}
export function floor_v2(p: V2): V2 { return { x: Math.floor(p.x), y: Math.floor(p.y) } }
export function ceil_v2(p: V2): V2 { return { x: Math.ceil(p.x), y: Math.ceil(p.y) } }
+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