//? Is is a good idea? Probably not. interface Recipe { tile?: string, inputs: (string | null)[], outputs: (string | null)[], action: "instant" | "passive" | "active" duration?: number warn?: boolean } const all_items = new Set() 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 => 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} }`); } function cut(from: string, to?: string) { out({ action: "active", duration: 2, tile: "cuttingboard", inputs: [from], outputs: [to ?? ("sliced-" + from)] }) } function cook(from: string, to?: string) { const i = from.endsWith("-pot") ? from : from + "-pot" const o = (to ?? ("cooked-" + from)) + "-pot" if (!from.endsWith("-pot")) out({ action: "instant", inputs: ["pot", from], outputs: [i] }) out({ action: "passive", duration: 20, tile: "stove", inputs: [i], outputs: [o] }) out({ action: "passive", duration: 5, tile: "stove", inputs: [o], outputs: ["burned-pot"], warn: true }) } function mix(from: string, to?: string) { const i = from + "-mixer" const o = (to ?? (from + "-juice")) + "-mixer" out({ action: "instant", inputs: ["mixer", from], outputs: [i] }) out({ action: "active", duration: 3, inputs: [i], outputs: [o] }) } function bake(from: string, to?: string) { const o = (to ?? ("cooked-" + from)) out({ action: "passive", duration: 25, tile: "oven", inputs: [from], outputs: [o] }) out({ action: "passive", duration: 15, 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", "mixer"].includes(ic)) return [iparts.join("-"), ic] return [ifull, null] } function combine(container: string, ...inputs: string[]) { 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() while (1) { 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 open.push(parts) out({ action: "instant", inputs: [c, ifull], outputs: [o, ic] }) } } } out({ action: "active", duration: 2, tile: "sink", inputs: ["dirty-plate"], outputs: ["plate"] }) crate("tomato") crate("raw-steak") crate("flour") crate("herbs") cut("tomato") cook("raw-steak", "steak") combine("plate", "steak-pot", "sliced-tomato", "bread") mix("flour", "dough") out({ action: "instant", inputs: ["dough-mixer"], outputs: ["mixer", "dough"] }) bake("dough", "bread") mix("tomato") combine("pot", "herbs", "tomato-juice-mixer") cook("herbs-tomato-juice-pot", "tomato-soop") out({ action: "instant", inputs: ["tomato-soop-pot", "plate"], outputs: ["pot", "tomato-soop-plate"] }) auto_trash()