aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-09-30 02:49:07 +0200
committermetamuffin <metamuffin@disroot.org>2025-09-30 02:49:07 +0200
commitbdf3c2d0e8221792d3adc8c82e2c2db087319701 (patch)
tree70541fc9500c1f87f119cad6504922b5c2d81b75
parentd2c793ec7632a5da8065fd52436cfd676cc96a7b (diff)
downloadhurrycurry-bdf3c2d0e8221792d3adc8c82e2c2db087319701.tar
hurrycurry-bdf3c2d0e8221792d3adc8c82e2c2db087319701.tar.bz2
hurrycurry-bdf3c2d0e8221792d3adc8c82e2c2db087319701.tar.zst
New compact map format tile declarations
-rw-r--r--data/maps/5star.yaml91
-rw-r--r--data/maps/debug.yaml118
-rw-r--r--data/maps/junior.yaml68
-rw-r--r--data/maps/lobby.yaml47
-rw-r--r--data/maps/paris.yaml76
-rw-r--r--data/maps/ring.yaml68
-rw-r--r--server/src/data/mod.rs89
-rw-r--r--server/src/server.rs2
8 files changed, 200 insertions, 359 deletions
diff --git a/data/maps/5star.yaml b/data/maps/5star.yaml
index f6ce9cd6..56d7dd25 100644
--- a/data/maps/5star.yaml
+++ b/data/maps/5star.yaml
@@ -20,7 +20,7 @@ map:
- " *''*''''''''*''''*'''*''*' "
- " ''''''''*''''''''*''''''''' "
- "'''██████████████████████''*' "
- - "'''█c..........d.......#█'''' "
+ - "'''█c..........d.......Q█'''' "
- "'''▒tc..c...c..d..vv#..Y▒'''' "
- " ''█c..ctc.ctc.█..v##..Y▒''*' "
- " ''█...ctc.ctc.w.......S█''*' "
@@ -48,72 +48,45 @@ map:
tiles:
"#": counter
- "f": counter
- "P": counter
- "v": counter
- "w": counter-window
- "W": counter-window
+ "P": counter -i=foodprocessor
+ "v": counter -i=plate
+ "w": counter-window -i=plate
+ "W": counter-window -i=glass
+ "Q": deep-fryer -xi=basket
"s": sink
"o": oven
- "S": stove
- "Y": stove
+ "S": stove -i=pot
+ "Y": stove -i=pan
"f": freezer
"C": cutting-board
- "X": trash
+ "X": trash -x
- "R": steak-crate
- "D": coconut-crate
- "V": strawberry-crate
- "F": fish-crate
- "U": rice-crate
- "T": tomato-crate
- "G": flour-crate
- "L": leek-crate
- "A": lettuce-crate
- "E": cheese-crate
+ "R": steak-crate -x
+ "D": coconut-crate -x
+ "V": strawberry-crate -x
+ "F": fish-crate -x
+ "U": rice-crate -x
+ "T": tomato-crate -x
+ "G": flour-crate -x
+ "L": leek-crate -x
+ "A": lettuce-crate -x
+ "E": cheese-crate -x
- ".": floor
- ",": floor
- "'": grass
+ ".": floor -w
+ ",": floor -w --chef-spawn
+ "'": grass -w
"t": table
- "c": chair
- "*": tree
- "!": street
- "_": street
- "-": path
- "d": door
- "█": wall
- "▒": wall-window
- "=": fence
- "^": conveyor
- "Ŧ": lamp
-
-items:
- "S": pot
- "Y": pan
- "w": plate
- "v": plate
- "W": glass
- "P": foodprocessor
+ "c": chair -w
+ "*": tree -c
+ "!": street -w --customer-spawn
+ "_": street -w
+ "-": path -w
+ "d": door -w
+ "█": wall -c
+ "▒": wall-window -c
+ "=": fence -c
+ "Ŧ": lamp -c
entities:
- !customers
scaling_factor: 0.25
-
-chef_spawn: ","
-customer_spawn: "!"
-
-walkable:
- - door
- - floor
- - chair
- - grass
- - path
- - street
-
-collider:
- - wall
- - tree
- - wall-window
- - fence
- - lamp
diff --git a/data/maps/debug.yaml b/data/maps/debug.yaml
index 06a5f8ac..6699aa84 100644
--- a/data/maps/debug.yaml
+++ b/data/maps/debug.yaml
@@ -36,63 +36,51 @@ map:
tiles:
"⌷": counter
- "f": counter
- "p": counter
+ "f": counter -i=foodprocessor
+ "p": counter -i=plate
"t": table
- "w": counter-window
"s": sink
"o": oven
"z": freezer
- "S": stove
- "T": stove
- "b": book
+ "S": stove -i=pot
+ "T": stove -i=pan
+ "b": book --book
"Y": cutting-board
- "™": deep-fryer
+ "™": deep-fryer -xi=basket
"R": rolling-board
- "0": rice-crate
- "1": steak-crate
- "2": tomato-crate
- "3": leek-crate
- "4": coconut-crate
- "5": strawberry-crate
- "6": flour-crate
- "7": fish-crate
- "8": cheese-crate
- "9": lettuce-crate
- "ß": mushroom-crate
- "?": potato-crate
- "Ü": bun-crate
- "X": trash
+ "0": rice-crate -x
+ "1": steak-crate -x
+ "2": tomato-crate -x
+ "3": leek-crate -x
+ "4": coconut-crate -x
+ "5": strawberry-crate -x
+ "6": flour-crate -x
+ "7": fish-crate -x
+ "8": cheese-crate -x
+ "9": lettuce-crate -x
+ "ß": mushroom-crate -x
+ "?": potato-crate -x
+ "Ü": bun-crate -x
+ "X": trash -x
"¹": black-hole-counter
"²": white-hole-counter
- "³": black-hole
- "⁴": white-hole
- "l": lamp
- "c": chair
- "~": floor
- ".": floor
- "'": grass
- "*": tree
- "!": path
- "_": path
- "d": door
+ "³": black-hole -w
+ "⁴": white-hole -c
+ "l": lamp -c
+ "c": chair -w
+ "~": floor -w --chef-spawn --customer-spawn
+ ".": floor -w
+ "'": grass -w
+ "*": tree -c
+ "!": path -w
+ "_": path -w
+ "d": door -w
"Æ": counter-window:blue
- "A": wall:blue
- "B": wall:red
- "C": wall:green
- "ɷ": chandelier
-
-items:
- "™": basket
- "S": pot
- "T": pan
- "w": plate
- "p": plate
- "f": foodprocessor
- "}": foodprocessor
- "]": foodprocessor
- "ö": pot
+ "A": wall:blue -c
+ "B": wall:red -c
+ "C": wall:green -c
+ "ɷ": chandelier -w
entities:
- !customers
@@ -100,38 +88,4 @@ entities:
- !item_portal { from: [20, 4], to: [20, 6] }
- !environment_effect { name: rain, on: 60, off: 40 }
- !environment_effect { name: wind, on: 60, off: 40 }
- # - !environment [night]
-
-tile_entities:
- "}": !conveyor { dir: [1, 0], filter: dough-foodprocessor }
- "]": !conveyor { dir: [1, 0], filter: tomato-juice-foodprocessor }
- "o": !conveyor { dir: [1, 0], filter: bread }
- "v": !conveyor { dir: [0, 1] }
- "^": !conveyor { dir: [0, -1] }
- ">": !conveyor { dir: [1, 0] }
- "°": !conveyor { dir: [1, 0], filter: plate }
- "+": !conveyor { dir: [1, 0], filter: tomato }
- "L": !conveyor { dir: [1, 0], filter: leek }
- "ö": !conveyor { dir: [1, 0], filter: tomato-soup-pot }
- "ü": !conveyor { dir: [1, 0], filter: tomato-soup-plate }
- "b": !book
-
-chef_spawn: "~"
-customer_spawn: "!"
-
-walkable:
- - door
- - floor
- - chair
- - grass
- - path
- - black-hole
- - chandelier
-
-collider:
- - wall
- - wall-window
- - tree
- - lamp
- - white-hole
- - deep-fryer
+ - !environment [night]
diff --git a/data/maps/junior.yaml b/data/maps/junior.yaml
index bc9472e0..f4ab3bc6 100644
--- a/data/maps/junior.yaml
+++ b/data/maps/junior.yaml
@@ -34,60 +34,32 @@ map:
tiles:
"⌷": counter
- "f": counter
- "p": counter
+ "f": counter -i=foodprocessor
+ "p": counter -i=plate
"t": table
- "w": counter-window
+ "w": counter-window -i=plate
"s": sink
"o": oven
- "S": stove
- "b": book
+ "S": stove -i=pan
+ "b": book --book
"C": cutting-board
- "R": steak-crate
- "T": tomato-crate
- "F": flour-crate
- "L": lettuce-crate
- "X": trash
+ "R": steak-crate -x
+ "T": tomato-crate -x
+ "F": flour-crate -x
+ "L": lettuce-crate -x
+ "X": trash -x
- "c": chair
- "~": floor
- ".": floor
- "'": grass
- "*": tree
- "!": path
- "_": path
- "d": door
- "▒": wall-window
- "█": wall
-
-items:
- "S": pan
- "w": plate
- "p": plate
- "f": foodprocessor
-
-chef_spawn: "~"
-customer_spawn: "!"
+ "c": chair -w
+ "~": floor -w --chef-spawn
+ ".": floor -w
+ "'": grass -w
+ "*": tree -c
+ "!": path -w --customer-spawn
+ "_": path -w
+ "d": door -w
+ "▒": wall-window -c
+ "█": wall -c
entities:
- !customers
scaling_factor: 0.25
-
-tile_entities:
- "b": !book
-
-walkable:
- - door
- - floor
- - chair
- - grass
- - path
-
-collider:
- - wall
- - wall-window
- - tree
- - steak-crate
- - tomato-crate
- - flour-crate
- - lettuce-crate
diff --git a/data/maps/lobby.yaml b/data/maps/lobby.yaml
index 479e7061..8396f475 100644
--- a/data/maps/lobby.yaml
+++ b/data/maps/lobby.yaml
@@ -33,38 +33,17 @@ map:
- "*'''''''''*''''*"
tiles:
- "1": table
- "2": table
- "3": table
- "4": table
- "5": table
- "6": table
+ "1": table -i=glass:strawberry-icecream
+ "2": table -i=plate:seared-patty,sliced-bun,sliced-lettuce,sliced-tomato
+ "3": table -i=plate:seared-steak
+ "4": table -i=plate:sliced-lettuce,sliced-tomato
+ "5": table -i=plate:nigiri
+ "6": table -i=dirty-plate
"s": sink
- "c": chair
- "~": floor
- ".": floor
- "b": book
- "'": grass
- "*": tree
- "█": wall
-
-items:
- "1": glass:strawberry-icecream
- "2": plate:seared-patty,sliced-bun,sliced-lettuce,sliced-tomato
- "3": plate:seared-steak
- "4": plate:sliced-lettuce,sliced-tomato
- "5": plate:nigiri
- "6": dirty-plate
-tile_entities:
- "b": !book
-
-chef_spawn: "~"
-customer_spawn: "!"
-
-walkable:
- - floor
- - chair
- - grass
-collider:
- - wall
- - tree
+ "c": chair -w
+ "~": floor -w --chef-spawn
+ ".": floor -w --customer-spawn
+ "'": grass -w
+ "b": book --book
+ "*": tree -c
+ "█": wall -c
diff --git a/data/maps/paris.yaml b/data/maps/paris.yaml
index 1dfd5576..e79376e6 100644
--- a/data/maps/paris.yaml
+++ b/data/maps/paris.yaml
@@ -38,64 +38,38 @@ map:
tiles:
"#": counter
- "f": counter
- "p": counter
+ "f": counter -i=foodprocessor
+ "p": counter -i=plate
"t": table
"w": counter-window
"s": sink
"o": oven
- "S": stove
- "Y": stove
+ "S": stove -i=pot
+ "Y": stove -i=pan
"C": cutting-board
- "R": steak-crate
- "T": tomato-crate
- "F": flour-crate
- "L": leek-crate
- "B": lettuce-crate
- "D": cheese-crate
- "X": trash
- "l": lamp
- "8": chandelier
- "1": ceiling-lamp
+ "R": steak-crate -x
+ "T": tomato-crate -x
+ "F": flour-crate -x
+ "L": leek-crate -x
+ "B": lettuce-crate -x
+ "D": cheese-crate -x
+ "X": trash -x
+ "l": lamp -c
+ "8": chandelier -w
+ "1": ceiling-lamp -w
- "c": chair
- ".": floor
- "'": grass
- "*": tree
- "_": path
- "~": street
- "!": street
- "-": street
- "d": door
- "█": wall
- "▒": wall-window
-
-items:
- "S": pot
- "Y": pan
- "p": plate
- "f": foodprocessor
+ "c": chair -w
+ ".": floor -w
+ "'": grass -w
+ "*": tree -c
+ "_": path -w
+ "~": street -w --chef-spawn
+ "!": street -w --customer-spawn
+ "-": street -w
+ "d": door -w
+ "█": wall -c
+ "▒": wall-window -c
entities:
- !customers
- !environment [night]
-
-
-chef_spawn: "~"
-customer_spawn: "!"
-
-walkable:
- - door
- - floor
- - chair
- - grass
- - path
- - street
- - chandelier
- - ceiling-lamp
-
-collider:
- - wall
- - tree
- - wall-window
- - lamp
diff --git a/data/maps/ring.yaml b/data/maps/ring.yaml
index 307db866..da76ac93 100644
--- a/data/maps/ring.yaml
+++ b/data/maps/ring.yaml
@@ -39,61 +39,37 @@ map:
tiles:
"#": counter
- "f": counter
+ "f": counter -i=foodprocessor
"l": sink
"o": oven
- "p": stove
- "a": stove
+ "p": stove -i=pot
+ "a": stove -i=pan
"g": freezer
"e": cutting-board
"r": rolling-board
- "X": trash
+ "X": trash -x
- "A": steak-crate
- "B": coconut-crate
- "C": cheese-crate
- "D": lettuce-crate
- "E": rice-crate
- "F": tomato-crate
- "G": flour-crate
- "H": leek-crate
+ "A": steak-crate -x
+ "B": coconut-crate -x
+ "C": cheese-crate -x
+ "D": lettuce-crate -x
+ "E": rice-crate -x
+ "F": tomato-crate -x
+ "G": flour-crate -x
+ "H": leek-crate -x
- ".": floor
- ",": floor
- "'": grass
+ ".": floor -w
+ ",": floor -w --chef-spawn
+ "'": grass -w
"t": table
- "c": chair
- "*": tree
- "!": street
- "_": street
- "d": door
- "█": wall
- "▒": wall-window
-
-items:
- "p": pot
- "a": pan
- "t": plate
- "f": foodprocessor
+ "c": chair -w
+ "*": tree -c
+ "!": street -w --customer-spawn
+ "_": street -w
+ "d": door -w
+ "█": wall -c
+ "▒": wall-window -c
entities:
- !customers
scaling_factor: 0.8
-
-chef_spawn: ","
-customer_spawn: "!"
-
-walkable:
- - door
- - floor
- - chair
- - grass
- - path
- - street
-
-collider:
- - wall
- - tree
- - wall-window
- - fence
- - lamp
diff --git a/server/src/data/mod.rs b/server/src/data/mod.rs
index 17ebd5bf..1fab912a 100644
--- a/server/src/data/mod.rs
+++ b/server/src/data/mod.rs
@@ -19,6 +19,7 @@ pub mod demands;
use crate::entity::{construct_entity, Entities, EntityDecl};
use anyhow::{anyhow, bail, Context, Result};
+use clap::Parser;
use demands::generate_demands;
use hurrycurry_bot::algos::ALGO_CONSTRUCTORS;
use hurrycurry_protocol::{
@@ -28,7 +29,7 @@ use hurrycurry_protocol::{
};
use serde::{Deserialize, Serialize};
use std::{
- collections::{BTreeMap, HashMap, HashSet},
+ collections::{BTreeMap, BTreeSet, HashMap, HashSet},
fs::{read_to_string, File},
path::PathBuf,
str::FromStr,
@@ -63,22 +64,35 @@ pub struct RecipeDecl {
#[rustfmt::skip]
#[derive(Debug, Clone, Deserialize)]
pub struct MapDecl {
- #[serde(default)] recipes: Option<String>,
map: Vec<String>,
tiles: HashMap<char, String>,
- #[serde(default)] items: HashMap<char, String>,
- collider: Vec<String>,
- walkable: Vec<String>,
- chef_spawn: char,
- customer_spawn: char,
+ #[serde(default)] recipes: Option<String>,
#[serde(default)] hand_count: Option<usize>,
#[serde(default)] entities: Vec<EntityDecl>,
- #[serde(default)] tile_entities: HashMap<char, EntityDecl>,
#[serde(default)] score_baseline: i64,
#[serde(default)] default_timer: Option<u64>,
#[serde(default)] flags: ServerdataFlags,
}
+#[derive(Parser)]
+struct TileArgs {
+ tile_name: String,
+ #[clap(short = 'c', long)]
+ collider: bool,
+ #[clap(short = 'x', long)]
+ exclusive: bool,
+ #[clap(short = 'w', long)]
+ walkable: bool,
+ #[clap(long)]
+ book: bool,
+ #[clap(long)]
+ chef_spawn: bool,
+ #[clap(long)]
+ customer_spawn: bool,
+ #[clap(short = 'i', long)]
+ item: Option<String>,
+}
+
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DemandDecl {
from: String,
@@ -92,7 +106,7 @@ pub struct DemandDecl {
pub struct Serverdata {
pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>,
pub chef_spawn: Vec2,
- pub customer_spawn: Vec2,
+ pub customer_spawn: Option<Vec2>,
pub score_baseline: i64,
pub default_timer: Option<Duration>,
pub book: Book,
@@ -240,48 +254,53 @@ pub fn build_data(
assert_eq!(r.points, None, "points specified where not possible")
}
- let mut chef_spawn = Vec2::new(0., 0.);
- let mut customer_spawn = Vec2::new(0., 0.);
+ let mut chef_spawn = None;
+ let mut customer_spawn = None;
let mut initial_map = HashMap::new();
let mut tiles_used = HashSet::new();
let mut items_used = HashSet::new();
+ let mut tile_walkable = HashSet::new();
+ let mut exclusive_tiles = BTreeSet::new();
for (y, line) in map_in.map.iter().enumerate() {
for (x, tile) in line.chars().enumerate() {
if tile == ' ' {
continue; // space is empty space
}
let pos = IVec2::new(x as i32, y as i32);
- if tile == map_in.chef_spawn {
- chef_spawn = pos.as_vec2() + Vec2::splat(0.5);
- }
- if tile == map_in.customer_spawn {
- customer_spawn = pos.as_vec2() + Vec2::splat(0.5);
- }
- let tilename = map_in
+
+ let tile_spec = map_in
.tiles
.get(&tile)
.ok_or(anyhow!("tile {tile} is undefined"))?
.clone();
+ let mut toks = shlex::split(&tile_spec).ok_or(anyhow!("tile spec quoting invalid"))?;
+ toks.insert(0, "tile-spec".to_string()); // exe name
+ let tile_spec = TileArgs::try_parse_from(toks)?;
- let itemname = map_in.items.get(&tile).cloned();
- let tile = reg.register_tile(tilename);
- let item = itemname.map(|i| reg.register_item(i));
+ let tile = reg.register_tile(tile_spec.tile_name);
tiles_used.insert(tile);
- if let Some(i) = item {
- items_used.insert(i);
- };
+ let item = tile_spec.item.map(|i| reg.register_item(i));
+ items_used.extend(item);
initial_map.insert(pos, (tile, item));
- }
- }
- for (y, line) in map_in.map.iter().enumerate() {
- for (x, tile) in line.trim().chars().enumerate() {
- let pos = IVec2::new(x as i32, y as i32);
- if let Some(ent) = map_in.tile_entities.get(&tile) {
- entities.push(construct_entity(Some(pos), ent, &reg)?);
+ if tile_spec.chef_spawn {
+ chef_spawn = Some(pos.as_vec2() + Vec2::splat(0.5));
+ }
+ if tile_spec.customer_spawn {
+ customer_spawn = Some(pos.as_vec2() + Vec2::splat(0.5));
+ }
+ if tile_spec.book {
+ entities.push(construct_entity(Some(pos), &EntityDecl::Book, &reg)?);
+ }
+ if tile_spec.walkable {
+ tile_walkable.insert(tile);
+ }
+ if tile_spec.walkable || tile_spec.collider || tile_spec.exclusive {
+ exclusive_tiles.insert(tile);
}
}
}
+ let chef_spawn = chef_spawn.ok_or(anyhow!("map has no chef spawn"))?;
entities.extend(
map_in
@@ -308,8 +327,7 @@ pub fn build_data(
let mut tile_placeable_items = BTreeMap::new();
let mut tile_interactable_empty = HashSet::new();
- for tile_name in map_in.collider.iter().chain(map_in.walkable.iter()) {
- let tile = reg.register_tile(tile_name.to_string());
+ for tile in exclusive_tiles {
let whitelist = recipes
.iter()
.filter(|r| r.tile() == Some(tile))
@@ -323,11 +341,6 @@ pub fn build_data(
tile_interactable_empty.insert(tile);
}
}
- let tile_walkable = map_in
- .walkable
- .into_iter()
- .map(|name| reg.register_tile(name))
- .collect();
let item_names = reg.items.into_inner().unwrap();
let tile_names = reg.tiles.into_inner().unwrap();
diff --git a/server/src/server.rs b/server/src/server.rs
index 14244394..d074bedd 100644
--- a/server/src/server.rs
+++ b/server/src/server.rs
@@ -268,7 +268,7 @@ impl GameServerExt for Game {
packet_out: Option<&mut VecDeque<PacketC>>,
) {
let position = custom_position.unwrap_or(match class {
- PlayerClass::Customer => serverdata.customer_spawn,
+ PlayerClass::Customer => serverdata.customer_spawn.unwrap_or(serverdata.chef_spawn),
PlayerClass::Bot | PlayerClass::Chef => serverdata.chef_spawn,
PlayerClass::Tram => Vec2::ZERO, // should always have custom location
}) + (Vec2::new(random(), random()) - 0.5);