diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | data/demands.yaml | 15 | ||||
| -rw-r--r-- | data/items.yaml | 78 | ||||
| -rw-r--r-- | data/map.yaml | 21 | ||||
| -rw-r--r-- | data/recipes.ts | 118 | ||||
| -rw-r--r-- | data/tiles.yaml | 30 | ||||
| -rw-r--r-- | server/src/data.rs | 19 | ||||
| -rw-r--r-- | server/src/game.rs | 13 | ||||
| -rw-r--r-- | test-client/tiles.ts | 23 | 
9 files changed, 135 insertions, 183 deletions
| @@ -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"), | 
