diff options
author | metamuffin <metamuffin@disroot.org> | 2024-06-19 00:08:13 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-06-23 19:21:22 +0200 |
commit | 203a4309a762488a4de72123e2f08f229e607e1a (patch) | |
tree | 752e7ffade32c6d66ee02725280c3041e25d6194 | |
parent | fe0dd480d6e93098cddc71d596a8d7e61fec68ed (diff) | |
download | hurrycurry-203a4309a762488a4de72123e2f08f229e607e1a.tar hurrycurry-203a4309a762488a4de72123e2f08f229e607e1a.tar.bz2 hurrycurry-203a4309a762488a4de72123e2f08f229e607e1a.tar.zst |
character selection
-rw-r--r-- | data/map.yaml | 5 | ||||
-rw-r--r-- | data/recipes.yaml | 1 | ||||
-rw-r--r-- | server/examples/client.rs | 1 | ||||
-rw-r--r-- | server/src/game.rs | 14 | ||||
-rw-r--r-- | server/src/interaction.rs | 4 | ||||
-rw-r--r-- | server/src/main.rs | 7 | ||||
-rw-r--r-- | server/src/protocol.rs | 6 | ||||
-rw-r--r-- | test-client/main.ts | 48 | ||||
-rw-r--r-- | test-client/protocol.ts | 4 |
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 |