| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- import type { FluidProductPrototype, ItemProductPrototype, RecipePrototype } from "../lua-api/models.ts";
- import type { Item } from "../process-data.models.ts";
- export type Ingredient = {
- type: "fluid" | "item";
- itemId: string;
- amount: number;
- };
- export type Recipe = {
- name: string;
- icon?: string;
- subgroup: string;
- order?: string;
- /** The [category](prototype:RecipeCategory) of this recipe. Controls which machines can craft this recipe.
- The built-in categories can be found [here](https://wiki.factorio.com/Data.raw#recipe-category). The base `"crafting"` category can not contain recipes with fluid ingredients or products. */
- category?: string;
- additional_categories?: string[];
- /** The amount of time it takes to make this recipe. Must be `> 0.001`. Equals the number of seconds it takes to craft at crafting speed `1`. */
- energy_required?: number;
- /** Whether the recipe is allowed to have the extra inserter overload bonus applied (4 * stack inserter stack size). */
- allow_inserter_overload?: boolean;
-
- allow_productivity?: boolean;
- allow_quality?: boolean;
- allow_speed?: boolean;
- /** Used to determine how many extra items are put into an assembling machine before it's considered "full enough". See [insertion limits](https://wiki.factorio.com/Inserters#Insertion_limits).
- If set to `0`, it instead uses the following formula: `1.166 / (energy_required / the assembler's crafting_speed)`, rounded up, and clamped to be between`2` and `100`. The numbers used in this formula can be changed by the [UtilityConstants](prototype:UtilityConstants) properties `dynamic_recipe_overload_factor`, `minimum_recipe_overload_multiplier`, and `maximum_recipe_overload_multiplier`. */
- overload_multiplier?: number;
- ingredients?: Ingredient[];
- results?: Array<ItemProductPrototype | FluidProductPrototype>;
- };
- export function getRecipeIcon(recipe: RecipePrototype, mainProduct: Item | undefined): string {
- if (recipe.icons || recipe.icon) return `recipe/${recipe.name}.png`;
- if (mainProduct && mainProduct.icon) return mainProduct.icon;
- console.warn(`No icon found for :${recipe.name}`);
- return "";
- }
- export function getRecipeSubGroup(recipe: RecipePrototype, mainProduct: Item | undefined): string {
- if (recipe.subgroup) return recipe.subgroup;
- if (mainProduct) return mainProduct.subgroup;
- return "other";
- }
- export function getMainProductName(recipe: RecipePrototype): string {
- if (recipe.results?.length == 1) {
- return recipe.results[0].name;
- } else if (recipe.results && recipe.main_product) {
- const mainProduct = recipe.main_product;
- const result = recipe.results.find((r) => r.name === mainProduct);
- if (result) {
- return result.name;
- }
- throw new Error(`Main product '${mainProduct}' declared by recipe '${recipe.name}' not found in results`);
- }
- return "";
- }
- export function parseRecipe(recipe: RecipePrototype, itemsMap: Record<string, Item>): Recipe {
- const rawIngredient = Array.isArray(recipe.ingredients) ? recipe.ingredients : [];
- const ingredients = rawIngredient.map((i) => ({ itemId: i.name, amount: i.amount, type: i.type }));
- const mainProduct = itemsMap[getMainProductName(recipe)];
- const r: Recipe = {
- name: recipe.name,
- icon: getRecipeIcon(recipe, mainProduct),
- subgroup: getRecipeSubGroup(recipe, mainProduct),
- energy_required:recipe.energy_required,
- allow_inserter_overload:recipe.allow_inserter_overload,
- overload_multiplier:recipe.overload_multiplier,
- order: recipe.order ?? mainProduct.order,
- category: recipe.category ?? "crafting",
- additional_categories: recipe.additional_categories,
- ingredients,
- results: recipe.results,
- };
- if (recipe.category) r.category = recipe.category;
- if (recipe.additional_categories) r.additional_categories = recipe.additional_categories;
- if (recipe.allow_productivity) r.allow_productivity = true;
- if (recipe.allow_quality) r.allow_quality = true;
- if (recipe.allow_speed) r.allow_speed = true;
- return r;
- }
|