Smithing table

This commit is contained in:
2026-09-25 23:48:29 -03:00
parent 9237152aa1
commit 8f32a59bd6
15 changed files with 279 additions and 13 deletions
+6
View File
@@ -258,6 +258,12 @@ function right_click(container: Container, index: number, cursor: Cursor) {
slot.amount = half;
}
// whether take_output would take it
export function can_take_output(item: ItemStack, cursor: Cursor): boolean {
const holding = cursor.item;
return !holding || (holding.type_id === item.type_id && holding.max_amount - holding.amount >= item.amount);
}
// output slots (furnace result, crafting result) can only be taken from, all at once
// returns whether it was taken
export function take_output(item: ItemStack, cursor: Cursor): boolean {
+4
View File
@@ -191,6 +191,8 @@ export interface RecipeApi {
fuel_value(item: Id): number; // burn time in ticks, 0 if it isn't fuel
is_fuel(item: Id): boolean;
is_smeltable(item: Id): boolean;
// the smithing recipe for these items, whatever the material's count. addition is the optional third item
smithing(tool: Id, material: Id, addition?: Id): { result: Id; material_count: number } | undefined;
}
// guis
@@ -233,6 +235,8 @@ export interface ContainerScreenOptions {
filter?: SlotFilter;
// can only be taken from, all at once, like the furnace result
output_only?: boolean;
// runs when a player takes from an output_only slot, before they get it. false stops them taking it
on_take?: (item: ItemStack) => boolean;
}[];
// height of the screen's area in slots, fits the layout and bars when not set
rows?: number;
+18 -2
View File
@@ -78,7 +78,15 @@ export type RecipeJson =
result: { id: string; count: number };
}
| { type: "furnace"; input: string; output: { id: string; count: number }; cook_time: number }
| { type: "fuel"; item: string; burn_time: number };
| { type: "fuel"; item: string; burn_time: number }
// upgrades a tool at a smithing table, with some of a material and maybe one more item
| {
type: "smithing";
tool: string;
material: { id: string; count: number };
addition?: string;
result: string;
};
// the crafting grid's format, see server/game/crafting.ts
export interface GridRecipe {
@@ -447,8 +455,16 @@ export function validate_recipe(json: unknown): Problems {
problems.push("burn_time must be a positive number of ticks");
}
break;
case "smithing":
problems.push(
...validate_id(json.tool, "tool"),
...validate_stack(json.material, "material"),
...validate_id(json.result, "result"),
);
if (json.addition !== undefined) problems.push(...validate_id(json.addition, "addition"));
break;
default:
problems.push('type must be "shaped", "furnace" or "fuel"');
problems.push('type must be "shaped", "furnace", "fuel" or "smithing"');
}
return problems;
}
+12
View File
@@ -50,6 +50,7 @@ export class RecipeBook {
shaped: GridRecipe[] = [];
furnace = new Map<string, { output: { id: string; count: number }; cook_time: number }>();
fuel = new Map<string, number>();
smithing: Extract<RecipeJson, { type: "smithing" }>[] = [];
ores: OreJson[] = [];
}
@@ -98,6 +99,17 @@ export function register_mod_data(mods: { id: string; data: ModData }[]): Recipe
case "fuel":
recipes.fuel.set(recipe.item, recipe.burn_time);
break;
case "smithing":
if (
recipes.smithing.some((other) =>
other.tool === recipe.tool && other.material.id === recipe.material.id &&
other.addition === recipe.addition
)
) {
fail(`two smithing recipes for ${recipe.tool} with ${recipe.material.id}`);
}
recipes.smithing.push(recipe);
break;
}
}
recipes.ores.push(...data.ores);