/* Hurry Curry! - a game about cooking Copyright 2024 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use bincode::{ config::{standard, Configuration, Limit, LittleEndian, Varint}, Decode, Encode, }; use glam::{IVec2, Vec2}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, fmt::Display, }; pub use glam; pub mod movement; pub const VERSION: (u32, u32) = (2, 1); pub const BINCODE_CONFIG: Configuration> = standard().with_limit(); #[derive( Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash, )] #[serde(transparent)] pub struct PlayerID(pub i64); #[derive( Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash, )] #[serde(transparent)] pub struct ItemIndex(pub usize); #[derive( Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash, )] #[serde(transparent)] pub struct TileIndex(pub usize); #[derive( Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash, )] #[serde(transparent)] pub struct RecipeIndex(pub usize); #[derive( Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash, )] #[serde(transparent)] pub struct DemandIndex(pub usize); #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct MapMetadata { name: String, players: usize, difficulty: i32, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)] #[rustfmt::skip] pub struct ClientGamedata { pub current_map: String, pub item_names: Vec, pub tile_names: Vec, pub tile_collide: Vec, pub tile_interact: Vec, pub map_names: HashSet, // for compat with game jam version pub maps: HashMap, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "snake_case", tag = "type")] pub enum PacketS { Join { name: String, character: i32, }, Leave, Movement { #[bincode(with_serde)] direction: Vec2, boosting: bool, #[bincode(with_serde)] pos: Option, }, Interact { #[bincode(with_serde)] pos: Option, }, Collide { player: PlayerID, #[bincode(with_serde)] force: Vec2, }, Communicate { message: Option, persist: bool, }, #[serde(skip)] #[bincode(skip)] /// For internal use only ReplaceHand { item: Option, }, /// For use in replay sessions only ReplayTick { dt: f64, }, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "snake_case")] pub enum Message { Text(String), Item(ItemIndex), Effect(String), } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "snake_case", tag = "type")] pub enum PacketC { Version { minor: u32, major: u32, supports_bincode: bool, }, Init { id: PlayerID, }, Data { data: ClientGamedata, }, AddPlayer { id: PlayerID, #[bincode(with_serde)] position: Vec2, character: i32, name: String, }, RemovePlayer { id: PlayerID, }, Position { player: PlayerID, #[bincode(with_serde)] pos: Vec2, rot: f32, boosting: bool, }, MoveItem { from: ItemLocation, to: ItemLocation, }, SetItem { location: ItemLocation, item: Option, }, SetProgress { item: ItemLocation, progress: Option, warn: bool, }, UpdateMap { #[bincode(with_serde)] tile: IVec2, kind: Option, neighbors: [Option; 4], }, Collide { player: PlayerID, #[bincode(with_serde)] force: Vec2, }, Communicate { player: PlayerID, message: Option, persist: bool, }, ServerMessage { text: String, }, Score { points: i64, demands_failed: usize, demands_completed: usize, time_remaining: Option, }, SetIngame { state: bool, lobby: bool, }, Error { message: String, }, /// For use in replay sessions only ReplayStart, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Copy, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] pub enum ItemLocation { Tile(#[bincode(with_serde)] IVec2), Player(PlayerID), } impl Display for ItemLocation { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ItemLocation::Tile(pos) => write!(f, "tile({pos})"), ItemLocation::Player(PlayerID(id)) => write!(f, "player({id})"), } } }