summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--data/demands.yaml15
-rw-r--r--data/items.yaml78
-rw-r--r--data/map.yaml21
-rw-r--r--data/recipes.ts118
-rw-r--r--data/tiles.yaml30
-rw-r--r--server/src/data.rs19
-rw-r--r--server/src/game.rs13
-rw-r--r--test-client/tiles.ts23
9 files changed, 135 insertions, 183 deletions
diff --git a/.gitignore b/.gitignore
index b7769a07..9e6b28b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
.vscode/
/test-client/*.js
/specs/*.html
+/data/recipes.yaml
diff --git a/data/demands.yaml b/data/demands.yaml
index 375eeb8b..08331587 100644
--- a/data/demands.yaml
+++ b/data/demands.yaml
@@ -1,6 +1,9 @@
-- { from: burger-meal, to: dirty-plate, duration: 15 }
-- { from: tomatoburger-meal, to: dirty-plate, duration: 20 }
-- { from: tomatosteak-meal, to: dirty-plate, duration: 20 }
-- { from: steak-meal, to: dirty-plate, duration: 15 }
-- { from: bread-meal, to: dirty-plate, duration: 15 }
-- { from: sliced-tomato-meal, to: dirty-plate, duration: 10 }
+- { from: bread-plate, to: dirty-plate, duration: 10 }
+- { from: steak-plate, to: dirty-plate, duration: 10 }
+- { from: sliced-tomato-plate, to: dirty-plate, duration: 10 }
+
+- { from: bread-steak-plate, to: dirty-plate, duration: 15 }
+- { from: bread-sliced-tomato-plate, to: dirty-plate, duration: 15 }
+- { from: sliced-tomato-steak-plate, to: dirty-plate, duration: 15 }
+
+- { from: bread-sliced-tomato-steak-plate, to: dirty-plate, duration: 20 }
diff --git a/data/items.yaml b/data/items.yaml
deleted file mode 100644
index ddca5e11..00000000
--- a/data/items.yaml
+++ /dev/null
@@ -1,78 +0,0 @@
-# tomato pipeline
-tomato:
- traits:
- - raw
- expires: 5
-sliced-tomato:
- traits:
- - food
-sliced-tomato-meal:
- traits:
- - meal
-# bread pipeline
-flour:
- traits:
- - raw
- expires: 180
-dough:
- traits:
- - bakeable
-bread:
- traits:
- - food
-bread-meal:
- traits:
- - meal
-# steak pipeline
-raw-steak:
- traits:
- - raw
- expires: 2
-steak:
- traits:
- - food
-steak-meal:
- traits:
- - meal
-
-# combination meals
-tomatosteak-meal:
- traits:
- - meal
-burger-meal:
- traits:
- - meal
-tomatoburger-meal:
- traits:
- - meal
-
-# containers
-glass:
- traits:
- - container
- - cup
- - empty-cup
-water:
- traits:
- - container
- - cup
-plate:
- traits:
- - container
- contains:
- - food
- - glass
-dirty-glass:
- traits:
- - dirty
- - glass
-dirty-plate:
- traits:
- - dirty
-
-# liquid
-liquid-water:
- traits:
- - raw
- - liquid
- expires: 1000
diff --git a/data/map.yaml b/data/map.yaml
index aa065a47..de121cc4 100644
--- a/data/map.yaml
+++ b/data/map.yaml
@@ -3,19 +3,19 @@ map:
- "|ctc.ctc.ctc.ctc.ctc.|"
- "|.....c..............|"
- "|c...c...+--www---dd-+"
- - "|tc.ctc..|##...CC#..D|"
- - "|c...c...w........~.S|"
+ - "|tc.ctc..|SS...CC#..X|"
+ - "|c...c...w........~.R|"
- "|c.......w..######..T|"
- "|tc......w..........F|"
- - "|c.....ct|##ss#oopp#X|"
+ - "|c.....ct|##ss#oo####|"
- "+---dd---+-----------+"
- "......................"
- ".........!............"
- "......................"
tiles:
- "~": chef-spawn
- "!": customer-spawn
+ "~": floor
+ "!": floor
".": floor
"+": wall
"-": wall
@@ -27,10 +27,17 @@ tiles:
"w": window
"s": sink
"o": oven
- "p": pan
+ "S": stove
"C": cuttingboard
- "S": raw-steak-crate
+ "R": raw-steak-crate
"T": tomato-crate
"F": flour-crate
"D": dirty-plate-crate
"X": trash
+
+chef_spawn: "~"
+customer_spawn: "!"
+
+items:
+ "S": pot
+ "w": plate
diff --git a/data/recipes.ts b/data/recipes.ts
index dcd73d8e..534f1e6d 100644
--- a/data/recipes.ts
+++ b/data/recipes.ts
@@ -3,74 +3,102 @@
interface Recipe {
tile?: string,
- inputs: string[],
- outputs: string[],
+ inputs: (string | null)[],
+ outputs: (string | null)[],
action: "instant" | "passive" | "active"
duration?: number
+ warn?: boolean
}
const all_items = new Set<string>()
+function auto_trash() {
+ for (const ifull of all_items) {
+ let [i, ic] = get_container(ifull)
+ if (i == "plate") continue
+ if (i == "pot") continue
+ if (i == "dirty") continue
+ if (ic == "plate") ic = "dirty-plate"
+ out({
+ action: "instant",
+ tile: "trash",
+ inputs: [ifull],
+ outputs: [ic]
+ })
+ }
+}
+
function out(r: Recipe) {
- r.inputs.forEach(i => all_items.add(i))
- r.outputs.forEach(i => all_items.add(i))
- console.log(`- { tile: ${r.tile ?? null}, inputs: ${JSON.stringify(r.inputs)}, outputs: ${JSON.stringify(r.outputs)}, action: !${r.action + " " + (r.duration ?? "")} }`);
+ r.inputs.forEach(i => i ? all_items.add(i) : void 0)
+ r.outputs.forEach(i => i ? all_items.add(i) : void 0)
+ console.log(`- { tile: ${r.tile ?? null}, inputs: ${JSON.stringify(r.inputs.filter(e => e))}, outputs: ${JSON.stringify(r.outputs.filter(e => e))}, action: !${r.action + " " + (r.duration ?? "")}, warn: ${r.warn ?? false} }`);
}
-type Component = (e: string) => void
-const cut = (new_name?: string): Component => e => {
- out({ action: "active", duration: 2, tile: "cuttingboard", inputs: [e], outputs: [new_name ?? ("sliced-" + e)] })
+function cut(from: string, to?: string) {
+ out({ action: "active", duration: 2, tile: "cuttingboard", inputs: [from], outputs: [to ?? ("sliced-" + from)] })
}
-const cook = (new_name?: string): Component => e => {
- const i = e + "-pot"
- const o = (new_name ?? ("cooked-" + e)) + "-pot"
- out({ action: "instant", inputs: ["pot", e], outputs: [i] })
- out({ action: "passive", duration: 2, tile: "stove", inputs: [i], outputs: [o] })
+function cook(from: string, to?: string) {
+ const i = from + "-pot"
+ const o = (to ?? ("cooked-" + from)) + "-pot"
+ out({ action: "instant", inputs: ["pot", from], outputs: [i] })
+ out({ action: "passive", duration: 10, tile: "stove", inputs: [i], outputs: [o] })
+ out({ action: "passive", duration: 10, tile: "stove", inputs: [o], outputs: ["burned-pot"], warn: true })
}
-const crate: Component = e => out({ action: "instant", tile: e + "-crate", inputs: [], outputs: [e], })
-
-function item(name: string, ...components: Component[]) {
- for (const f of components) {
- f(name)
- }
+function bake(from: string, to?: string) {
+ const o = (to ?? ("cooked-" + from))
+ out({ action: "passive", duration: 20, tile: "oven", inputs: [from], outputs: [o] })
+ out({ action: "passive", duration: 20, tile: "oven", inputs: [o], outputs: ["burned"], warn: true })
+}
+function crate(item: string) {
+ out({ action: "instant", tile: item + "-crate", inputs: [], outputs: [item], })
}
+function get_container(ifull: string): [string, string | null] {
+ const iparts = ifull.split("-")
+ const ic = iparts.pop()
+ if (ic && iparts.length && ["pot", "plate"].includes(ic)) return [iparts.join("-"), ic]
+ return [ifull, null]
+}
function combine(container: string, ...inputs: string[]) {
- const open = inputs.map(i => [i])
+ const open = inputs.map(ifull => {
+ const [i, ic] = get_container(ifull)
+ out({ action: "instant", inputs: [container, ifull], outputs: [i + "-" + container, ic] })
+ return [i]
+ })
+ const seen = new Set<string>()
while (1) {
- const e = open.pop()
- if (!e) break;
- const cur = e.join("-") + "-" + container
- for (const i of inputs) {
- if (e.includes(i)) continue
- const parts = [...e, i]
+ const cur = open.pop()
+ if (!cur) break;
+ const c = cur.join("-") + "-" + container
+ for (const ifull of inputs) {
+ const [i, ic] = get_container(ifull)
+ if (cur.includes(i)) continue
+ const rkey = cur.join("-") + "#" + i
+ if (seen.has(rkey)) continue
+ seen.add(rkey)
+
+ const parts = [...cur, i]
parts.sort()
const o = parts.join("-") + "-" + container
- if (all_items.has(o)) continue
open.push(parts)
out({
action: "instant",
- inputs: [cur, i],
- outputs: [o]
+ inputs: [c, ifull],
+ outputs: [o, ic]
})
}
}
}
-item("tomato", cut(), crate, cook("tomato-soop"))
-combine("plate", "steak", "sliced-tomato", "bread")
+out({ action: "active", duration: 3, inputs: ["flour"], outputs: ["dough"] })
+out({ action: "active", duration: 2, tile: "sink", inputs: ["dirty-plate"], outputs: ["plate"] })
-for (const i of all_items) {
- const parts = i.split("-");
- const container = parts.pop()!;
- if (parts.length >= 1 && ["pot", "plate"].includes(container)) {
- out({
- action: "instant",
- tile: "trash",
- inputs: [i],
- outputs: [container]
- })
- } else {
- out({ action: "instant", tile: "trash", inputs: [i], outputs: [] })
- }
-}
+crate("tomato")
+crate("raw-steak")
+crate("flour")
+crate("dirty-plate")
+cut("tomato")
+bake("dough", "bread")
+cook("raw-steak", "steak")
+combine("plate", "steak-pot", "sliced-tomato", "bread")
+auto_trash()
diff --git a/data/tiles.yaml b/data/tiles.yaml
deleted file mode 100644
index 078a6f29..00000000
--- a/data/tiles.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# kitchen
-- counter
-- watercooler:
- - accepts:
- - empty-cup
-- oven:
- - accepts:
- - bakeable
-- service:
- - accepts:
- - container
-
-# supply
-- tomato-bag:
- - generates:
- - tomato
-- flour-bag:
- - generates:
- - flour
-- freezer:
- - generates:
- - steak
-- sink:
- - accepts:
- - dirty
- - cup
-
-# customers
-- table
-- chair
diff --git a/server/src/data.rs b/server/src/data.rs
index fd268cb5..9c200e5b 100644
--- a/server/src/data.rs
+++ b/server/src/data.rs
@@ -31,7 +31,10 @@ pub struct RecipeDecl {
#[derive(Debug, Clone, Deserialize)]
pub struct InitialMap {
map: Vec<String>,
- tiles: HashMap<String, String>,
+ tiles: HashMap<char, String>,
+ items: HashMap<char, String>,
+ chef_spawn: char,
+ customer_spawn: char,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -55,7 +58,7 @@ pub struct Gamedata {
pub item_names: Vec<String>,
pub tile_names: Vec<String>,
#[serde(skip)]
- pub initial_map: HashMap<IVec2, TileIndex>,
+ pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>,
pub chef_spawn: Vec2,
pub customer_spawn: Vec2,
}
@@ -121,17 +124,17 @@ pub fn build_gamedata(
for (y, line) in map_in.map.iter().enumerate() {
for (x, tile) in line.trim().char_indices() {
let pos = IVec2::new(x as i32, y as i32);
- let mut tilename = map_in.tiles[&tile.to_string()].clone();
- if tilename == "chef-spawn" {
+ if tile == map_in.chef_spawn {
chef_spawn = pos.as_vec2();
- tilename = "floor".to_owned();
}
- if tilename == "customer-spawn" {
+ if tile == map_in.customer_spawn {
customer_spawn = pos.as_vec2();
- tilename = "floor".to_owned();
}
+ let tilename = map_in.tiles[&tile].clone();
+ let itemname = map_in.items.get(&tile).cloned();
let tile = TileIndex(register(&tile_names, tilename));
- initial_map.insert(pos, tile);
+ let item = itemname.map(|i| ItemIndex(register(&item_names, i)));
+ initial_map.insert(pos, (tile, item));
}
}
diff --git a/server/src/game.rs b/server/src/game.rs
index e4693e4a..973b257b 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -54,8 +54,17 @@ impl Game {
players: Default::default(),
tiles: Default::default(),
};
- for (&p, &t) in &gamedata.initial_map {
- g.tiles.insert(p, t.into());
+ for (&p, (tile, item)) in &gamedata.initial_map {
+ g.tiles.insert(
+ p,
+ Tile {
+ kind: *tile,
+ item: item.map(|i| Item {
+ kind: i,
+ active: None,
+ }),
+ },
+ );
}
g
}
diff --git a/test-client/tiles.ts b/test-client/tiles.ts
index 7db8f2a3..42fba268 100644
--- a/test-client/tiles.ts
+++ b/test-client/tiles.ts
@@ -92,24 +92,33 @@ const door: Component = c => {
}
const plate = [circle(0.4, "#b6b6b6", "#f7f7f7", 0.02)];
+const pot = [circle(0.35, "rgb(29, 29, 29)", "rgb(39, 39, 39)", 0.04)];
+const burned = [circle(0.3, "rgb(61, 18, 0)"), cross(0.2, "red", 0.02)]
export const FALLBACK_ITEM: Component[] = [circle(0.3, "#f0f")];
export const ITEMS: { [key: string]: Component[] } = {
+ "pot": pot,
"raw-steak": [circle(0.3, "#cc3705")],
+ "raw-steak-pot": [...pot, circle(0.3, "#cc3705")],
+ "steak-pot": [...pot, circle(0.3, "#702200")],
+ "burned-pot": [...pot, ...burned],
"steak": [circle(0.3, "#702200")],
"flour": [circle(0.3, "#d8c9c2")],
"dough": [circle(0.3, "#b38d7d")],
"bread": [circle(0.3, "#853e20")],
"tomato": [circle(0.3, "#d63838")],
+ "burned": burned,
"sliced-tomato": [circle(0.3, "#d16363", "#d63838", 0.08)],
"plate": plate,
"dirty-plate": [circle(0.4, "#947a6f", "#d3a187", 0.02)],
- "steak-meal": [...plate, ...arrange_items("steak")],
- "bread-meal": [...plate, ...arrange_items("bread")],
- "burger-meal": [...plate, ...arrange_items("bread", "steak")],
- "sliced-tomato-meal": [...plate, ...arrange_items("sliced-tomato")],
- "tomatosteak-meal": [...plate, ...arrange_items("tomato", "steak")],
- "tomatoburger-meal": [...plate, ...arrange_items("bread", "steak", "tomato")],
+
+ "steak-plate": [...plate, ...arrange_items("steak")],
+ "bread-plate": [...plate, ...arrange_items("bread")],
+ "sliced-tomato-plate": [...plate, ...arrange_items("sliced-tomato")],
+ "bread-steak-plate": [...plate, ...arrange_items("bread", "steak")],
+ "bread-sliced-tomato-plate": [...plate, ...arrange_items("bread", "sliced-tomato")],
+ "sliced-tomato-steak-plate": [...plate, ...arrange_items("sliced-tomato", "steak")],
+ "bread-sliced-tomato-steak-plate": [...plate, ...arrange_items("bread", "sliced-tomato", "steak")],
}
const table = [base("rgb(133, 76, 38)")];
@@ -130,7 +139,7 @@ export const TILES: { [key: string]: Component[] } = {
"trash": [...floor, circle(0.4, "rgb(20, 20, 20)"), cross(0.3, "rgb(90, 36, 36)")],
"sink": [base("rgb(131, 129, 161)", "rgb(177, 174, 226)", 0.2)],
"oven": [base("rgb(241, 97, 61)", "rgb(109, 84, 84)", 0.3)],
- "pan": [...counter, circle(0.4, "#444", "#999")],
+ "stove": [...counter, circle(0.4, "#444", "#999")],
"flour-crate": crate("flour"),
"dirty-plate-crate": crate("dirty-plate"),
"raw-steak-crate": crate("raw-steak"),