summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/map.yaml5
-rw-r--r--data/recipes.yaml1
-rw-r--r--server/examples/client.rs1
-rw-r--r--server/src/game.rs14
-rw-r--r--server/src/interaction.rs4
-rw-r--r--server/src/main.rs7
-rw-r--r--server/src/protocol.rs6
-rw-r--r--test-client/main.ts48
-rw-r--r--test-client/protocol.ts4
9 files changed, 64 insertions, 26 deletions
diff --git a/data/map.yaml b/data/map.yaml
index be2e6aeb..e85b6ba2 100644
--- a/data/map.yaml
+++ b/data/map.yaml
@@ -3,11 +3,11 @@ map:
- "|ctc.ctc.ctc.ctc.ctc.|"
- "|.....c..............|"
- "|c...c...+--www---dd-+"
- - "|tc.ctc..|##...##W..#|"
+ - "|tc.ctc..|##...##W..D|"
- "|c...c...w........~.S|"
- "|c.......w..######..T|"
- "|tc......w..........F|"
- - "|c.....ct|##ss#oopp#D|"
+ - "|c.....ct|##ss#oopp#X|"
- "+---dd---+-----------+"
tiles:
@@ -29,3 +29,4 @@ tiles:
"T": tomato-crate
"F": flour-crate
"D": dirty-plate-crate
+ "X": trash
diff --git a/data/recipes.yaml b/data/recipes.yaml
index 713509df..d462acbe 100644
--- a/data/recipes.yaml
+++ b/data/recipes.yaml
@@ -9,6 +9,7 @@
- { tile: trash, action: !instant , inputs: [raw-steak] }
- { tile: trash, action: !instant , inputs: [steak] }
+- { tile: trash, action: !instant , inputs: [tomato] }
- { tile: trash, action: !instant , inputs: [flour] }
- { tile: trash, action: !instant , inputs: [dough] }
- { tile: trash, action: !instant , inputs: [steak-meal] }
diff --git a/server/examples/client.rs b/server/examples/client.rs
index 02c9c9e3..e22656d4 100644
--- a/server/examples/client.rs
+++ b/server/examples/client.rs
@@ -24,6 +24,7 @@ fn main() {
let mut toks = line.split(" ");
let packet = match toks.next().unwrap() {
"j" => PacketS::Join {
+ character: 0,
name: "test".to_string(),
},
"p" => PacketS::Position {
diff --git a/server/src/game.rs b/server/src/game.rs
index 35502d3c..c9881e7c 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -32,6 +32,7 @@ pub struct Tile {
pub struct Player {
pub name: String,
+ pub character: usize,
pub position: Vec2,
pub interacting: Option<IVec2>,
pub item: Option<Item>,
@@ -71,8 +72,10 @@ impl Game {
for (&id, player) in &self.players {
out.push(PacketC::AddPlayer {
id,
+ position: player.position,
+ character: player.character,
name: player.name.clone(),
- hand: player.item.as_ref().map(|i| i.kind),
+ item: player.item.as_ref().map(|i| i.kind),
})
}
for (&tile, tdata) in &self.tiles {
@@ -92,11 +95,12 @@ impl Game {
pub fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> {
match packet {
- PacketS::Join { name } => {
+ PacketS::Join { name, character } => {
self.players.insert(
player,
Player {
item: None,
+ character,
position: self.data.spawn,
interacting: None,
name: name.clone(),
@@ -105,7 +109,9 @@ impl Game {
self.packet_out.push_back(PacketC::AddPlayer {
id: player,
name,
- hand: None,
+ position: self.data.spawn,
+ character,
+ item: None,
});
}
PacketS::Leave => {
@@ -157,7 +163,7 @@ impl Game {
}
let tile_had_item = tile.item.is_some();
- let player_had_item = tile.item.is_some();
+ let player_had_item = player.item.is_some();
if let Some(effect) = interact(&self.data, edge, tile, player) {
match effect {
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index d43c71da..d822340f 100644
--- a/server/src/interaction.rs
+++ b/server/src/interaction.rs
@@ -3,6 +3,7 @@ use crate::{
game::{Involvement, Item, Player, Tile},
protocol::{ItemIndex, TileIndex},
};
+use log::info;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -101,6 +102,7 @@ pub fn interact(
if let Some(item) = &mut tile.item {
if item.kind == *input {
if item.active.is_none() {
+ info!("start active recipe {ri}");
item.active = Some(Involvement {
recipe: ri,
working: 1,
@@ -117,6 +119,7 @@ pub fn interact(
if let Some(active) = &mut item.active {
active.working += 1;
} else {
+ info!("start active recipe {ri}");
item.active = Some(Involvement {
recipe: ri,
working: 1,
@@ -137,6 +140,7 @@ pub fn interact(
let ok = (inputs[0] == on_tile && inputs[1] == in_hand)
|| (inputs[1] == on_tile && inputs[0] == in_hand);
if ok {
+ info!("instant recipe {ri}");
player.item = outputs[0].map(|kind| Item { kind, active: None });
tile.item = outputs[1].map(|kind| Item { kind, active: None });
return Some(InteractEffect::Produce);
diff --git a/server/src/main.rs b/server/src/main.rs
index c4df346e..45ee39dd 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -11,9 +11,9 @@ use tokio::{
};
use tokio_tungstenite::tungstenite::Message;
use undercooked::{
+ data::build_gamedata,
game::Game,
protocol::{PacketC, PacketS},
- data::build_gamedata,
};
#[tokio::main]
@@ -94,7 +94,10 @@ async fn main() -> Result<()> {
}
r = ws_listener.accept() => {
let (sock, addr) = r?;
- let sock = tokio_tungstenite::accept_async(sock).await?;
+ let Ok(sock) = tokio_tungstenite::accept_async(sock).await else {
+ warn!("invalid ws handshake");
+ continue
+ };
let (mut write, mut read) = sock.split();
let game = game.clone();
let mut rx = rx.resubscribe();
diff --git a/server/src/protocol.rs b/server/src/protocol.rs
index 4f04793f..6fe8ccd8 100644
--- a/server/src/protocol.rs
+++ b/server/src/protocol.rs
@@ -10,7 +10,7 @@ pub type RecipeIndex = usize;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum PacketS {
- Join { name: String },
+ Join { name: String, character: usize },
Leave,
Position { pos: Vec2, rot: f32 },
Interact { pos: IVec2, edge: bool },
@@ -26,8 +26,10 @@ pub enum PacketC {
},
AddPlayer {
id: PlayerID,
+ position: Vec2,
+ character: usize,
name: String,
- hand: Option<ItemIndex>,
+ item: Option<ItemIndex>,
},
RemovePlayer {
id: PlayerID,
diff --git a/test-client/main.ts b/test-client/main.ts
index bfd352b3..20ec2a18 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -19,7 +19,7 @@ document.addEventListener("DOMContentLoaded", () => {
ws.onclose = () => console.log("close")
ws.onopen = () => {
console.log("open")
- send({ type: "join", name: "test" })
+ send({ type: "join", name: "test", character: Math.floor(Math.random() * 255) })
}
canvas = document.createElement("canvas");
@@ -48,6 +48,7 @@ interface PlayerData {
rot: number,
item?: ItemData,
facing: V2,
+ character: number,
vel: { x: number, y: number }
}
interface TileData {
@@ -64,6 +65,7 @@ let data: Gamedata = { item_names: [], tile_names: [], spawn: [0, 0] }
let my_id: PlayerID = -1
const camera: V2 = { x: 0, y: 0 }
const interact_target_anim: V2 = { x: 0, y: 0 }
+let interacting: V2 | undefined;
let scale = 0
function send(p: PacketS) { ws.send(JSON.stringify(p)) }
@@ -78,7 +80,16 @@ function packet(p: PacketC) {
case "add_player": {
let item = undefined
if (p.item) item = { kind: p.item, x: 0, y: 0 };
- players.set(p.id, { x: data.spawn[0], y: data.spawn[1], name: p.name, rot: 0, item, facing: { x: 0, y: 1 }, vel: { x: 0, y: 0 } })
+ players.set(p.id, {
+ x: p.position[0],
+ y: p.position[1],
+ character: p.character,
+ name: p.name,
+ rot: 0,
+ item,
+ facing: { x: 0, y: 1 },
+ vel: { x: 0, y: 0 },
+ })
break;
}
case "remove_player":
@@ -131,12 +142,8 @@ 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()
- 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 {
@@ -148,16 +155,23 @@ function get_interact_target(): V2 | undefined {
}
}
-function interact(edge: boolean) {
- const { x, y } = get_interact_target()!;
- send({ type: "interact", pos: [x, y], edge })
-}
-
function tick_update() {
const p = players.get(my_id)
if (!p) return
send({ type: "position", pos: [p.x, p.y], rot: p.rot })
+
+ const { x, y } = get_interact_target()!;
+ if (interacting && !keys_down.has("Space")) {
+ send({ type: "interact", pos: [interacting.x, interacting.y], edge: false })
+ interacting = undefined;
+ }
+ if (keys_down.has("Space") && x != interacting?.x && y != interacting?.y) {
+ if (interacting)
+ send({ type: "interact", pos: [interacting.x, interacting.y], edge: false })
+ send({ type: "interact", pos: [x, y], edge: true })
+ interacting = { x, y }
+ }
}
function frame_update(dt: number) {
@@ -178,7 +192,6 @@ function frame_update(dt: number) {
collide_player(p)
lerp_exp_v2_mut(p.vel, { x: 0, y: 0 }, dt * 5.)
-
const update_item = (item: ItemData, parent: V2) => {
lerp_exp_v2_mut(item, parent, dt * 10.)
}
@@ -262,16 +275,23 @@ function draw_ingame() {
ctx.translate(player.x, player.y)
ctx.rotate(-player.rot)
- ctx.fillStyle = "rgb(226, 176, 26)"
+ ctx.fillStyle = `hsl(${player.character}rad, 50%, 50%)`
ctx.beginPath()
ctx.arc(0, 0, PLAYER_SIZE, 0, Math.PI * 2)
ctx.fill()
- ctx.fillStyle = "rgb(103, 79, 7)"
+ ctx.fillStyle = `hsl(${player.character}rad, 80%, 10%)`
ctx.beginPath()
ctx.arc(0, -0.2, PLAYER_SIZE, 0, Math.PI * 2)
ctx.fill()
+ ctx.fillStyle = `hsl(${player.character}rad, 80%, 70%)`
+ ctx.beginPath()
+ ctx.moveTo(-0.04, 0.35)
+ ctx.lineTo(0.04, 0.35)
+ ctx.lineTo(0, 0.5)
+ ctx.fill()
+
ctx.restore()
if (player.item) draw_item(player.item)
diff --git a/test-client/protocol.ts b/test-client/protocol.ts
index 98fcbf39..31f61d19 100644
--- a/test-client/protocol.ts
+++ b/test-client/protocol.ts
@@ -10,14 +10,14 @@ export interface Gamedata {
}
export type PacketS =
- { type: "join", name: string } // You join, sent as first packet.
+ { type: "join", name: string, character: number } // You join, sent as first packet.
| { type: "position", pos: Vec2, rot: number } // Update your position and rotation in radians (0 is -y)
| { type: "interact", pos: Vec2, edge: boolean } // Interact with some tile. edge is true when pressing and false when releasing interact button
| { type: "collide", player: PlayerID, force: Vec2 } // Apply force to another player as a result of a collision
export type PacketC =
{ type: "init", id: PlayerID, data: Gamedata } // You joined
- | { type: "add_player", id: PlayerID, name: string, item?: ItemIndex } // Somebody else joined (or was already in the game)
+ | { type: "add_player", id: PlayerID, name: string, item?: ItemIndex, position: Vec2, character: number } // Somebody else joined (or was already in the game)
| { type: "remove_player", id: PlayerID } // Somebody left
| { type: "position", player: PlayerID, pos: Vec2, rot: number } // Update the position of a players (your own position is included here)
| { type: "take_item", tile: Vec2, player: PlayerID } // An item was taken from a tile