diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-03-11 21:18:12 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-03-11 21:18:36 +0100 |
| commit | 4a9314f235bd3c556cec4f70177d8f7438d59559 (patch) | |
| tree | d021352543a01d1eb325e202be7ee8b9c936eda4 | |
| parent | 93fbbf687de7e3b3b27e150c455cef2ac4d4c303 (diff) | |
| download | hurrycurry-4a9314f235bd3c556cec4f70177d8f7438d59559.tar hurrycurry-4a9314f235bd3c556cec4f70177d8f7438d59559.tar.bz2 hurrycurry-4a9314f235bd3c556cec4f70177d8f7438d59559.tar.zst | |
buttons server-side code
| -rw-r--r-- | data/maps/lobby.yaml | 8 | ||||
| -rw-r--r-- | data/palettes.yaml | 2 | ||||
| -rw-r--r-- | server/data/src/entities.rs | 15 | ||||
| -rw-r--r-- | server/data/src/lib.rs | 28 | ||||
| -rw-r--r-- | server/protocol/src/lib.rs | 1 | ||||
| -rw-r--r-- | server/src/entity/button.rs (renamed from server/src/entity/book.rs) | 23 | ||||
| -rw-r--r-- | server/src/entity/mod.rs | 6 |
7 files changed, 58 insertions, 25 deletions
diff --git a/data/maps/lobby.yaml b/data/maps/lobby.yaml index 920d9efc..a573ce2a 100644 --- a/data/maps/lobby.yaml +++ b/data/maps/lobby.yaml @@ -47,7 +47,7 @@ tiles: "h": floor counter rolling-board "e": stove -i=pot "f": stove -i=pan - "x": floor counter book --book + "x": floor counter book --button=book "o": oven "a": counter -i=foodprocessor "Z": freezer @@ -56,9 +56,9 @@ tiles: "i": counter deep-fryer -i=basket "S": floor screen - "b": floor button-base button:reject - "j": floor button-base - "d": floor button-base button:accept + "b": floor button-base button:reject --button=vote-no + "j": floor button-base --button=map-selector + "d": floor button-base button:accept --button=vote-yes "0": floor crate:rice "1": floor crate:steak diff --git a/data/palettes.yaml b/data/palettes.yaml index 2e2c63b0..c86039df 100644 --- a/data/palettes.yaml +++ b/data/palettes.yaml @@ -14,7 +14,7 @@ default: "d": floor counter deep-fryer -i=basket "r": floor counter rolling-board "e": floor counter cutting-board - "h": floor counter book --book + "h": floor counter book --button=book "A": floor crate:steak "B": floor crate:coconut diff --git a/server/data/src/entities.rs b/server/data/src/entities.rs index 5c874441..135e4b78 100644 --- a/server/data/src/entities.rs +++ b/server/data/src/entities.rs @@ -16,6 +16,7 @@ */ +use clap::ValueEnum; use hurrycurry_protocol::{ ItemIndex, TileIndex, glam::{IVec2, Vec2}, @@ -72,8 +73,9 @@ pub enum EntityDecl { spacing: f32, smoothing: f32, }, - Book { + Button { pos: IVec2, + action: ButtonAction, }, Pedestrians { spawn_delay: f32, @@ -98,8 +100,17 @@ pub enum EntityDecl { }, } +#[derive(Debug, Clone, Copy, Deserialize, Serialize, ValueEnum)] +#[serde(rename_all = "snake_case")] +pub enum ButtonAction { + Book, + VoteYes, + VoteNo, + MapSelector, +} + #[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(rename_all = "kebab-case")] +#[serde(rename_all = "snake_case")] pub enum GateCondition { All(Vec<GateCondition>), Any(Vec<GateCondition>), diff --git a/server/data/src/lib.rs b/server/data/src/lib.rs index d09c3ca3..06233d1e 100644 --- a/server/data/src/lib.rs +++ b/server/data/src/lib.rs @@ -24,7 +24,7 @@ pub mod registry; use crate::{ book::book, - entities::EntityDecl, + entities::{ButtonAction, EntityDecl}, recipes::{RecipeDecl, load_recipes}, registry::{ItemTileRegistry, filter_unused_tiles_and_items}, }; @@ -71,8 +71,8 @@ fn default_recipes() -> String { #[derive(Parser)] struct TileArgs { tiles: Vec<String>, - #[clap(long)] - book: bool, + #[clap(short, long)] + button: Option<ButtonAction>, #[clap(long)] chef_spawn: bool, #[clap(long)] @@ -146,6 +146,7 @@ pub fn build_gamedata( let mut chef_spawn = None; let mut customer_spawn = None; let mut initial_map = HashMap::new(); + let mut interactable_empty_extra = HashSet::new(); for (y, line) in map_in.map.iter().enumerate() { for (x, char) in line.chars().enumerate() { @@ -163,7 +164,10 @@ pub fn build_gamedata( .iter() .cloned() .map(|t| reg.register_tile(t)) - .collect(); + .collect::<Vec<_>>(); + let Some(top) = tiles.last().copied() else { + continue; + }; let item = ts.item.clone().map(|i| reg.register_item(i)); initial_map.insert(pos, (tiles, item)); @@ -173,8 +177,9 @@ pub fn build_gamedata( if ts.customer_spawn { customer_spawn = Some(pos.as_vec2() + Vec2::splat(0.5)); } - if ts.book { - entities.push(EntityDecl::Book { pos }); + if let Some(action) = ts.button { + interactable_empty_extra.insert(top); + entities.push(EntityDecl::Button { pos, action }); } if ts.demand_sink { entities.push(EntityDecl::DemandSink { pos }); @@ -194,7 +199,6 @@ pub fn build_gamedata( } let chef_spawn = chef_spawn.ok_or(anyhow!("map has no chef spawn"))?; - for mut e in map_in.entities.clone() { match &mut e { EntityDecl::Customers { unknown_order, .. } => { @@ -249,6 +253,9 @@ pub fn build_gamedata( ), tile_placeable_any: tiles_flagged(&tile_flags, &tiles, 'a'), tile_interactable_empty: tiles_flagged(&tile_flags, &tiles, 'e') + .union(&interactable_empty_extra) + .copied() + .collect::<HashSet<_>>() .union(&tile_interactable_empty_bc_recipe(&recipes)) .copied() .collect(), @@ -357,9 +364,10 @@ fn tiles_flagged( for (i, tile) in tiles.iter().enumerate() { let (kind, _params) = tile.split_once(":").unwrap_or((tile, "")); if let Some(flags) = tile_flags.get(kind) - && flags.contains(flag) { - out.insert(TileIndex(i)); - } + && flags.contains(flag) + { + out.insert(TileIndex(i)); + } } out } diff --git a/server/protocol/src/lib.rs b/server/protocol/src/lib.rs index a276a29a..9dfcc4dd 100644 --- a/server/protocol/src/lib.rs +++ b/server/protocol/src/lib.rs @@ -321,6 +321,7 @@ pub enum Menu { Score(Score), Scoreboard(Scoreboard), Book(Book), + MapSelector, AnnounceStart, } diff --git a/server/src/entity/book.rs b/server/src/entity/button.rs index e8456591..74726253 100644 --- a/server/src/entity/book.rs +++ b/server/src/entity/button.rs @@ -17,22 +17,35 @@ */ use super::{Entity, EntityContext}; use anyhow::Result; +use hurrycurry_data::entities::ButtonAction; use hurrycurry_locale::TrError; use hurrycurry_protocol::{ItemLocation, Menu, PacketC, PlayerID, glam::IVec2}; #[derive(Debug, Clone)] -pub struct Book(pub IVec2); +pub struct Button { + pub pos: IVec2, + pub action: ButtonAction, +} -impl Entity for Book { +impl Entity for Button { fn interact( &mut self, c: EntityContext<'_>, pos: Option<ItemLocation>, _player: PlayerID, ) -> Result<bool, TrError> { - if pos == Some(ItemLocation::Tile(self.0)) { - if let Some(r) = c.replies { - r.push(PacketC::Menu(Menu::Book(c.serverdata.book.clone()))); + if pos == Some(ItemLocation::Tile(self.pos)) { + match self.action { + ButtonAction::Book => { + c.replies + .unwrap() + .push(PacketC::Menu(Menu::Book(c.serverdata.book.clone()))); + } + ButtonAction::VoteYes => {} + ButtonAction::VoteNo => {} + ButtonAction::MapSelector => { + c.replies.unwrap().push(PacketC::Menu(Menu::MapSelector)); + } } return Ok(true); } diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 8a78202b..604daf98 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -15,8 +15,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -mod book; pub mod bot; +mod button; mod campaign; mod conveyor; mod ctf_minigame; @@ -39,7 +39,7 @@ use crate::{ scoreboard::ScoreboardStore, }; use anyhow::Result; -use book::Book; +use button::Button; use campaign::{Gate, Map}; use conveyor::Conveyor; use customers::Customers; @@ -111,7 +111,7 @@ pub fn construct_entity(decl: &EntityDecl) -> DynEntity { tag_item, blocker_tile, } => Box::new(TagMinigame::new(tag_item, blocker_tile)), - EntityDecl::Book { pos } => Box::new(Book(pos)), + EntityDecl::Button { pos, action } => Box::new(Button { pos, action }), EntityDecl::ItemPortal { from, to } => Box::new(ItemPortal { from, to }), EntityDecl::PlayerPortal { from, to } => Box::new(PlayerPortal { from, to }), EntityDecl::Conveyor { from, to, speed } => Box::new(Conveyor { |