summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-06-17 17:39:39 +0200
committermetamuffin <metamuffin@disroot.org>2024-06-23 19:20:50 +0200
commit6f0424b9b4cddc0495eb673d314c570e27e61e83 (patch)
tree3ca2f5c8f1d16020dfa432d8a93fb1f53be93c4b
parent428fa6fb8dac18c541c0c231f1b640ba172e52b9 (diff)
downloadhurrycurry-6f0424b9b4cddc0495eb673d314c570e27e61e83.tar
hurrycurry-6f0424b9b4cddc0495eb673d314c570e27e61e83.tar.bz2
hurrycurry-6f0424b9b4cddc0495eb673d314c570e27e61e83.tar.zst
everything indexed
-rw-r--r--Cargo.lock42
-rw-r--r--data/recipes.yaml98
-rw-r--r--data/recipes_raw.yaml37
-rw-r--r--server/Cargo.toml1
-rw-r--r--server/src/game.rs133
-rw-r--r--server/src/interaction.rs66
-rw-r--r--server/src/lib.rs2
-rw-r--r--server/src/main.rs8
-rw-r--r--server/src/protocol.rs38
-rw-r--r--server/src/recipes.rs73
-rw-r--r--test-client/main.ts19
-rw-r--r--test-client/protocol.ts31
12 files changed, 349 insertions, 199 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d354b2ca..b100b668 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -206,6 +206,12 @@ dependencies = [
]
[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -292,6 +298,12 @@ dependencies = [
]
[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
+[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -321,6 +333,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
+name = "indexmap"
+version = "2.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -576,6 +598,19 @@ dependencies = [
]
[[package]]
+name = "serde_yaml"
+version = "0.9.34+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -728,6 +763,7 @@ dependencies = [
"log",
"serde",
"serde_json",
+ "serde_yaml",
"tokio",
"tokio-tungstenite",
]
@@ -739,6 +775,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
+name = "unsafe-libyaml"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
+
+[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/data/recipes.yaml b/data/recipes.yaml
index c35bee30..de8de444 100644
--- a/data/recipes.yaml
+++ b/data/recipes.yaml
@@ -1,86 +1,78 @@
-# tomato pipeline
-- tile: counter
+- tile: floor
+ action: !never # tomato pipeline
+
+- tile: meat-spawn
+ action: !instant
+ outputs: [raw-meat]
+
+
+- tile: table
inputs: [tomato]
outputs: [sliced-tomato]
- action: hold
- duration: 3
-- tile: counter
- inputs: [sliced-tomato,plate]
+ action: !active 3
+- tile: table
+ inputs: [sliced-tomato, plate]
outputs: [sliced-tomato-meal]
- action: instant
- duration: 0
+ action: !instant # bread pipeline
-# bread pipeline
-- tile: counter
+
+- tile: table
inputs: [flour]
outputs: [dough]
- action: hold
- duration: 5
+ action: !active 5
- tile: oven
inputs: [dough]
outputs: [bread]
- action: wait
- duration: 20
-- tile: counter
- inputs: [bread,plate]
+ action: !passive 20
+- tile: table
+ inputs: [bread, plate]
outputs: [bread-meal]
- action: instant
- duration: 0
+ action: !instant # steak pipeline
-# steak pipeline
-- tile: oven
+
+- tile: pan
inputs: [raw-steak]
outputs: [steak]
- action: wait
- duration: 15
-- tile: counter
- inputs: [steak,plate]
+ action: !passive 15
+- tile: table
+ inputs: [steak, plate]
outputs: [steak-meal]
- action: instant
- duration: 0
+ action: !instant # combination meals
+
-# combination meals
-- tile: counter
- inputs: [steak-meal,bread]
+- tile: table
+ inputs: [steak-meal, bread]
outputs: [burger-meal]
- action: instant
- duration: 0
-- tile: counter
- inputs: [steak-meal,tomato]
+ action: !instant
+- tile: table
+ inputs: [steak-meal, tomato]
outputs: [tomatosteak-meal]
- action: instant
- duration: 0
-- tile: counter
- inputs: [burger-meal,tomato]
+ action: !instant
+- tile: table
+ inputs: [burger-meal, tomato]
outputs: [tomatoburger-meal]
- action: instant
- duration: 0
-- tile: counter
- inputs: [tomatosteak-meal,bread]
+ action: !instant
+- tile: table
+ inputs: [tomatosteak-meal, bread]
outputs: [tomatoburger-meal]
- action: instant
- duration: 0
+ action: !instant # cups
+
-# cups
- tile: watercooler
inputs: [glass]
outputs: [water]
- action: wait
- duration: 2
+ action: !passive 2
- tile: sink
inputs: [water]
outputs: [glass]
- action: instant
- duration: 0
+ action: !instant # cleaning
+
-# cleaning
- tile: sink
inputs: [dirty-glass]
outputs: [glass]
- action: hold
- duration: 5
+ action: !active 5
- tile: sink
inputs: [dirty-plate]
outputs: [plate]
- action: hold
- duration: 5
+ action: !active 5
diff --git a/data/recipes_raw.yaml b/data/recipes_raw.yaml
deleted file mode 100644
index 75939c11..00000000
--- a/data/recipes_raw.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-- tile: cutting-plate
- inputs: [tomato]
- outputs: [sliced-tomato]
- duration: 3
- active: true
-
-- tile: sink
- inputs: [empty-bottle]
- outputs: [water-bottle]
- instant: true
-
-- tile: dishwasher
- inputs: [dirty-dish]
- output: [empty-dish]
- duration: 10
-
-- tile: table
- inputs: [steak, herbs]
- outputs: [steak-with-herbs]
- ordered: true
- instant: true
-
-- tile: table
- inputs: [apple-juice-bottle, carbonated-water-bottle]
- outputs: [apply-soda-bottle, empty-bottle]
- instant: true
-
-- tile: table
- inputs: [empty-cup, <a>-bottle]
- outputs: [<a>-cup, empty-bottle]
- instant: true
-
-- tile: flour-bag
- outputs: [flour]
- instant: true
-
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 27e6f4b7..447a3ff1 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -13,3 +13,4 @@ tokio = { version = "1.38.0", features = ["full"] }
serde_json = "1.0.117"
tokio-tungstenite = "0.23.1"
futures-util = "0.3.30"
+serde_yaml = "0.9.34+deprecated"
diff --git a/server/src/game.rs b/server/src/game.rs
index a9ee8f3d..a7a07881 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -1,60 +1,81 @@
-use crate::protocol::{Item, PacketC, PacketS, Tile, ID};
+use crate::{
+ protocol::{ItemID, ItemIndex, PacketC, PacketS, PlayerID, TileIndex},
+ recipes::Gamedata,
+};
use anyhow::{anyhow, Result};
use glam::IVec2;
-use log::info;
-use std::collections::{HashMap, VecDeque};
+use std::{
+ collections::{HashMap, VecDeque},
+ ops::Deref,
+ sync::Arc,
+};
-struct TileData {
- kind: Tile,
- items: Vec<ID>,
+pub struct Tile {
+ kind: TileIndex,
+ items: Vec<ItemID>,
active: bool,
progress: f32,
}
struct Player {
name: String,
- hand: Option<ID>,
+ hand: Option<ItemID>,
}
-#[derive(Default)]
pub struct Game {
- item_id_counter: ID,
- tiles: HashMap<IVec2, TileData>,
- items: HashMap<ID, Item>,
- players: HashMap<ID, Player>,
+ data: Arc<Gamedata>,
+ item_id_counter: ItemID,
+ tiles: HashMap<IVec2, Tile>,
+ items: HashMap<ItemID, ItemIndex>,
+ players: HashMap<PlayerID, Player>,
packet_out: VecDeque<PacketC>,
}
impl Game {
- pub fn new() -> Self {
- let mut g = Self::default();
+ pub fn new(gamedata: Arc<Gamedata>) -> Self {
+ let mut g = Self {
+ data: gamedata.clone(),
+ item_id_counter: 0,
+ items: Default::default(),
+ packet_out: Default::default(),
+ players: Default::default(),
+ tiles: Default::default(),
+ };
for x in -5..5 {
for y in -5..5 {
g.tiles
- .insert(IVec2 { x, y }, Tile("floor".to_string()).into());
+ .insert(IVec2 { x, y }, gamedata.get_tile("floor").unwrap().into());
}
}
for x in -5..5 {
- g.tiles
- .insert(IVec2 { x, y: -5 }, Tile("table".to_string()).into());
- g.tiles
- .insert(IVec2 { x, y: 4 }, Tile("table".to_string()).into());
+ g.tiles.insert(
+ IVec2 { x, y: -5 },
+ gamedata.get_tile("table").unwrap().into(),
+ );
+ g.tiles.insert(
+ IVec2 { x, y: 4 },
+ gamedata.get_tile("table").unwrap().into(),
+ );
}
for y in -5..5 {
- g.tiles
- .insert(IVec2 { x: -5, y }, Tile("table".to_string()).into());
- g.tiles
- .insert(IVec2 { x: 4, y }, Tile("table".to_string()).into());
+ g.tiles.insert(
+ IVec2 { x: -5, y },
+ gamedata.get_tile("table").unwrap().into(),
+ );
+ g.tiles.insert(
+ IVec2 { x: 4, y },
+ gamedata.get_tile("table").unwrap().into(),
+ );
}
g.tiles.extend(
- [([-5, 1], "pan"), ([-5, 2], "pan"), ([4, 3], "flour_bag")].map(|(k, v)| {
+ [([-5, 1], "pan"), ([-5, 2], "pan"), ([4, 3], "meat-spawn")].map(|(k, v)| {
(
IVec2::from_array(k),
- TileData {
+ Tile {
active: false,
items: vec![],
- kind: Tile(v.to_string()).into(),
+ kind: gamedata.get_tile(v).unwrap().into(),
progress: 0.,
},
)
@@ -68,7 +89,7 @@ impl Game {
self.packet_out.pop_front()
}
- pub fn prime_client(&self, id: ID) -> Vec<PacketC> {
+ pub fn prime_client(&self, id: PlayerID) -> Vec<PacketC> {
let mut out = Vec::new();
for (&id, player) in &self.players {
out.push(PacketC::AddPlayer {
@@ -90,11 +111,14 @@ impl Game {
})
}
}
- out.push(PacketC::Joined { id });
+ out.push(PacketC::Joined {
+ id,
+ data: self.data.deref().to_owned(),
+ });
out
}
- pub fn packet_in(&mut self, player: ID, packet: PacketS) -> Result<()> {
+ pub fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> {
match packet {
PacketS::Join { name } => {
self.players.insert(
@@ -126,50 +150,27 @@ impl Game {
.push_back(PacketC::Position { player, pos, rot });
}
PacketS::Interact { pos, edge } => {
- if !edge {
- return Ok(());
- }
- let tile = self
- .tiles
- .get_mut(&pos)
- .ok_or(anyhow!("interacting with empty tile"))?;
- let player_data = self
- .players
- .get_mut(&player)
- .ok_or(anyhow!("player does not exist"))?;
- if tile.kind.0 == "flour_bag" {
- info!("new flour");
- let item = Item("flour".to_string());
- self.items.insert(self.item_id_counter, item.clone());
- tile.items.push(self.item_id_counter);
- self.packet_out.push_back(PacketC::ProduceItem {
- id: self.item_id_counter,
- pos,
- kind: item,
- });
- 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 })
- }
- }
+ // 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 })
+ // }
+ // }
}
}
Ok(())
}
}
-impl From<Tile> for TileData {
- fn from(kind: Tile) -> Self {
+impl From<TileIndex> for Tile {
+ fn from(kind: TileIndex) -> Self {
Self {
kind,
progress: 0.,
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
new file mode 100644
index 00000000..5f8b0097
--- /dev/null
+++ b/server/src/interaction.rs
@@ -0,0 +1,66 @@
+use crate::{
+ protocol::{ItemIndex, TileIndex},
+ recipes::{Action, Gamedata},
+};
+use std::collections::BTreeSet;
+
+pub enum Out {
+ Take(usize),
+ Put,
+ Produce(ItemIndex),
+ Consume(usize),
+}
+use Out::*;
+
+pub fn interact(
+ data: &Gamedata,
+ edge: bool,
+ tile: TileIndex,
+ items: &[ItemIndex],
+ hand: &Option<ItemIndex>,
+ mut out: impl FnMut(Out),
+) {
+ let mut allowed = BTreeSet::new();
+ for r in &data.recipes {
+ if r.tile == tile {
+ allowed.extend(r.inputs.clone())
+ }
+ }
+ if !edge {
+ return;
+ }
+
+ let mut put_item = None;
+ if let Some(hand) = hand {
+ if allowed.contains(hand) {
+ out(Put);
+ put_item = Some(*hand);
+ }
+ }
+
+ for r in &data.recipes {
+ let ok = r
+ .inputs
+ .iter()
+ .all(|e| items.contains(e) || put_item == Some(*e))
+ && r.inputs.len() == items.len();
+ if ok {
+ match r.action {
+ Action::Passive(_) => todo!(),
+ Action::Active(_) => todo!(),
+ Action::Instant => {
+ for i in 0..items.len() {
+ out(Consume(i))
+ }
+ for i in &r.outputs {
+ out(Produce(*i));
+ }
+ if !r.outputs.is_empty() {
+ out(Take(r.outputs.len() - 1));
+ }
+ }
+ Action::Never => (),
+ }
+ }
+ }
+}
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 4659e440..5bb09e41 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -1,2 +1,4 @@
pub mod game;
pub mod protocol;
+pub mod recipes;
+pub mod interaction;
diff --git a/server/src/main.rs b/server/src/main.rs
index 7426e27e..441487e8 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -1,7 +1,7 @@
use anyhow::Result;
use futures_util::{SinkExt, StreamExt};
use log::{debug, info, warn};
-use std::{sync::Arc, time::Duration};
+use std::{fs::File, sync::Arc, time::Duration};
use tokio::{
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
net::TcpListener,
@@ -13,6 +13,7 @@ use tokio_tungstenite::tungstenite::Message;
use undercooked::{
game::Game,
protocol::{PacketC, PacketS},
+ recipes::build_gamedata,
};
#[tokio::main]
@@ -26,7 +27,10 @@ async fn main() -> Result<()> {
);
info!("listening for websockets on {}", ws_listener.local_addr()?);
- let game = Arc::new(RwLock::new(Game::new()));
+ let data =
+ build_gamedata(serde_yaml::from_reader(File::open("data/recipes.yaml").unwrap()).unwrap());
+
+ let game = Arc::new(RwLock::new(Game::new(data.into())));
let (tx, rx) = broadcast::channel::<PacketC>(1024);
{
diff --git a/server/src/protocol.rs b/server/src/protocol.rs
index a318a9b2..ae87ffb4 100644
--- a/server/src/protocol.rs
+++ b/server/src/protocol.rs
@@ -1,15 +1,12 @@
use glam::{IVec2, Vec2};
use serde::{Deserialize, Serialize};
-pub type ID = u32;
+use crate::recipes::Gamedata;
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(transparent)]
-pub struct Item(pub String);
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(transparent)]
-pub struct Tile(pub String);
+pub type PlayerID = usize;
+pub type ItemID = usize;
+pub type ItemIndex = usize;
+pub type TileIndex = usize;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
@@ -24,36 +21,37 @@ pub enum PacketS {
#[serde(rename_all = "snake_case")]
pub enum PacketC {
Joined {
- id: ID,
+ data: Gamedata,
+ id: PlayerID,
},
AddPlayer {
- id: ID,
+ id: PlayerID,
name: String,
- hand: Option<(ID, Item)>,
+ hand: Option<(ItemID, ItemIndex)>,
},
RemovePlayer {
- id: ID,
+ id: PlayerID,
},
Position {
- player: ID,
+ player: PlayerID,
pos: Vec2,
rot: f32,
},
TakeItem {
- item: ID,
- player: ID,
+ item: ItemID,
+ player: PlayerID,
},
PutItem {
- item: ID,
+ item: ItemID,
pos: IVec2,
},
ProduceItem {
- id: ID,
+ id: ItemID,
pos: IVec2,
- kind: Item,
+ kind: ItemIndex,
},
ConsumeItem {
- id: ID,
+ id: ItemID,
pos: IVec2,
},
SetActive {
@@ -62,6 +60,6 @@ pub enum PacketC {
},
UpdateMap {
pos: IVec2,
- tile: Tile,
+ tile: TileIndex,
},
}
diff --git a/server/src/recipes.rs b/server/src/recipes.rs
new file mode 100644
index 00000000..25a4be98
--- /dev/null
+++ b/server/src/recipes.rs
@@ -0,0 +1,73 @@
+use crate::protocol::{ItemIndex, TileIndex};
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
+#[serde(rename_all = "snake_case")]
+pub enum Action {
+ Passive(f32),
+ Active(f32),
+ Instant,
+ Never,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize)]
+pub struct Recipe<T = TileIndex, I = ItemIndex> {
+ pub tile: T,
+ #[serde(default)]
+ pub inputs: Vec<I>,
+ #[serde(default)]
+ pub outputs: Vec<I>,
+ pub action: Action,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Gamedata {
+ pub recipes: Vec<Recipe>,
+ pub item_names: Vec<String>,
+ pub tile_names: Vec<String>,
+}
+pub fn build_gamedata(recipes_in: Vec<Recipe<String, String>>) -> Gamedata {
+ let mut item_names = Vec::new();
+ let mut tile_names = Vec::new();
+ let mut recipes = Vec::new();
+
+ for r in recipes_in {
+ recipes.push(Recipe {
+ action: r.action,
+ tile: register(&mut tile_names, r.tile.clone()),
+ inputs: r
+ .inputs
+ .clone()
+ .into_iter()
+ .map(|e| register(&mut item_names, e))
+ .collect(),
+ outputs: r
+ .outputs
+ .clone()
+ .into_iter()
+ .map(|e| register(&mut item_names, e))
+ .collect(),
+ })
+ }
+
+ Gamedata {
+ recipes,
+ item_names,
+ tile_names,
+ }
+}
+fn register(db: &mut Vec<String>, name: String) -> usize {
+ if let Some(index) = db.iter().position(|e| e == &name) {
+ index
+ } else {
+ let index = db.len();
+ db.push(name);
+ index
+ }
+}
+
+impl Gamedata {
+ pub fn get_tile(&self, name: &str) -> Option<TileIndex> {
+ self.tile_names.iter().position(|t| t == name)
+ }
+}
diff --git a/test-client/main.ts b/test-client/main.ts
index 3e04dc05..5f4475f2 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -1,6 +1,6 @@
/// <reference lib="dom" />
-import { ID, Item, PacketC, PacketS, Tile } from "./protocol.ts";
+import { Gamedata, ItemID, ItemIndex, PacketC, PacketS, PlayerID, TileIndex } from "./protocol.ts";
import { FALLBACK_TILE, TILES } from "./tiles.ts";
import { V2, add_v2, ceil_v2, floor_v2, length, lerp_exp_v2_mut, normalize } from "./util.ts";
@@ -32,14 +32,16 @@ document.addEventListener("DOMContentLoaded", () => {
setInterval(tick_update, 1000 / 25);
})
-interface PlayerData { x: number; y: number, name: string, rot: number, hand?: ID, facing: V2 }
-const players = new Map<number, PlayerData>()
-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, items: ID[], active: boolean }
+interface PlayerData { x: number; y: number, name: string, rot: number, hand?: ItemID, facing: V2 }
+const players = new Map<PlayerID, PlayerData>()
+interface ItemData { kind: ItemIndex, tile?: V2, player?: PlayerID, tracking_player: boolean, x: number, y: number }
+const items = new Map<ItemID, ItemData>()
+interface TileData { x: number; y: number, kind: TileIndex, items: ItemID[], active: boolean }
const tiles = new Map<string, TileData>()
-let my_id: number = -1
+let data: Gamedata = { item_names: [], tile_names: [] }
+
+let my_id: PlayerID = -1
const camera: V2 = { x: 0, y: 0 }
const interact_target_anim: V2 = { x: 0, y: 0 }
let scale = 0
@@ -49,6 +51,7 @@ function packet(p: PacketC) {
if (!("position" in p)) console.log(p);
if ("joined" in p) {
my_id = p.joined.id
+ data = p.joined.data
} else if ("add_player" in p) {
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], facing: { x: 0, y: 1 } })
@@ -188,7 +191,7 @@ function draw_ingame() {
for (const [_, tile] of tiles) {
ctx.save()
ctx.translate(tile.x, tile.y)
- const comps = TILES[tile.kind] ?? FALLBACK_TILE
+ const comps = TILES[data.tile_names[tile.kind]] ?? FALLBACK_TILE
for (const c of comps) {
c(ctx)
}
diff --git a/test-client/protocol.ts b/test-client/protocol.ts
index 707c09a3..d5cb2034 100644
--- a/test-client/protocol.ts
+++ b/test-client/protocol.ts
@@ -1,7 +1,13 @@
-export type ID = number;
export type Vec2 = [number, number]
-export type Item = string
-export type Tile = string
+export type PlayerID = number
+export type ItemID = number
+export type ItemIndex = number
+export type TileIndex = number
+
+export interface Gamedata {
+ item_names: string[],
+ tile_names: string[],
+}
export type PacketS =
{ join: { name: string } }
@@ -9,16 +15,15 @@ export type PacketS =
| { position: { pos: Vec2, rot: number } }
| { interact: { pos: Vec2, edge: boolean } }
-
export type PacketC =
- { joined: { id: ID } }
- | { add_player: { id: ID, name: string, hand?: [number, Item] } }
- | { remove_player: { id: ID } }
- | { position: { player: ID, pos: Vec2, rot: number } }
- | { take_item: { item: ID, player: ID } }
- | { put_item: { item: ID, pos: Vec2 } }
- | { produce_item: { id: ID, pos: Vec2, kind: Item } }
- | { consume_item: { id: ID, pos: Vec2 } }
+ { joined: { id: PlayerID, data: Gamedata } }
+ | { add_player: { id: PlayerID, name: string, hand?: [ItemID, ItemIndex] } }
+ | { remove_player: { id: PlayerID } }
+ | { position: { player: PlayerID, pos: Vec2, rot: number } }
+ | { take_item: { item: ItemID, player: PlayerID } }
+ | { put_item: { item: ItemID, pos: Vec2 } }
+ | { produce_item: { id: ItemID, pos: Vec2, kind: ItemIndex } }
+ | { consume_item: { id: ItemID, pos: Vec2 } }
| { set_active: { tile: Vec2 } }
- | { update_map: { pos: Vec2, tile: Tile } }
+ | { update_map: { pos: Vec2, tile: TileIndex } }