/*
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) = (3, 0);
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 {
player: PlayerID,
},
Movement {
player: PlayerID,
#[bincode(with_serde)]
direction: Vec2,
boosting: bool,
#[bincode(with_serde)]
pos: Option,
},
Interact {
player: PlayerID,
#[bincode(with_serde)]
pos: Option,
},
Communicate {
player: PlayerID,
message: Option,
persist: bool,
},
#[serde(skip)]
#[bincode(skip)]
/// For internal use only
ReplaceHand {
player: PlayerID,
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,
},
Joined {
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],
},
Communicate {
player: PlayerID,
message: Option,
persist: bool,
},
ServerMessage {
text: String,
},
Score(Score),
SetIngame {
state: bool,
lobby: bool,
},
Error {
message: String,
},
Menu(Menu),
MovementSync {
player: PlayerID,
},
Environment {
effects: HashSet,
},
/// For use in replay sessions only
ReplayStart,
}
#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
#[serde(rename_all = "snake_case", tag = "menu", content = "data")]
pub enum Menu {
Book,
Score(Score),
}
#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)]
pub struct Score {
pub time_remaining: f64,
pub stars: u8,
pub points: i64,
pub demands_failed: usize,
pub demands_completed: usize,
pub players: usize,
pub active_recipes: usize,
pub passive_recipes: usize,
pub instant_recipes: usize,
}
#[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})"),
}
}
}