import { Container, ItemStack } from "$/common/inventory.ts"; import { CRAFTING_RESULT_SLOT } from "$/common/protocol.ts"; export interface CraftingRecipe { width: number; height: number; pattern: (string | undefined)[]; result: { id: string; count: number }; } const recipes: CraftingRecipe[] = [ { width: 3, height: 3, pattern: [ "bworld:planks", "bworld:planks", "bworld:planks", "bworld:planks", undefined, "bworld:planks", "bworld:planks", "bworld:planks", "bworld:planks", ], result: { id: "bworld:chest", count: 1 }, }, { width: 3, height: 3, pattern: [ "bworld:stone", "bworld:stone", "bworld:stone", "bworld:stone", undefined, "bworld:stone", "bworld:stone", "bworld:stone", "bworld:stone", ], result: { id: "bworld:furnace", count: 1 }, }, { width: 1, height: 1, pattern: [ "bworld:log", ], result: { id: "bworld:planks", count: 2 }, }, { width: 1, height: 2, pattern: [ "bworld:planks", "bworld:planks", ], result: { id: "bworld:stick", count: 2 }, }, { width: 3, height: 3, pattern: [ "bworld:planks", "bworld:planks", "bworld:planks", undefined, "bworld:stick", undefined, undefined, "bworld:stick", undefined, ], result: { id: "bworld:wood_pickaxe", count: 1 }, }, ]; function get_crafting_grid(crafting: Container): (string | undefined)[] { const grid: (string | undefined)[] = []; for (let i = 0; i < 9; i++) { grid.push(crafting.get_item(i)?.type_id); } return grid; } function matches_recipe(grid: (string | undefined)[], recipe: CraftingRecipe): boolean { for (let y = 0; y <= 3 - recipe.height; y++) { for (let x = 0; x <= 3 - recipe.width; x++) { let match = true; for (let gy = 0; gy < 3; gy++) { for (let gx = 0; gx < 3; gx++) { const grid_index = gy * 3 + gx; if (gx >= x && gx < x + recipe.width && gy >= y && gy < y + recipe.height) { const recipe_index = (gy - y) * recipe.width + (gx - x); if (grid[grid_index] !== recipe.pattern[recipe_index]) { match = false; break; } } else if (grid[grid_index] !== undefined) { match = false; break; } } if (!match) break; } if (match) return true; } } return false; } // puts what the grid makes in the result slot export function update_crafting_result(crafting: Container) { const grid = get_crafting_grid(crafting); const recipe = recipes.find((recipe) => matches_recipe(grid, recipe)); crafting.set_item(CRAFTING_RESULT_SLOT, recipe ? new ItemStack(recipe.result.id, recipe.result.count) : undefined); } export function consume_recipe_items(crafting: Container) { for (let i = 0; i < 9; i++) { const slot = crafting.get_slot(i); if (slot.has_item()) { slot.amount = slot.amount! - 1; } } }