import fs from "fs"; import { checkIcons, dataRawPath, getJsonData, scriptOutputPath } from "./helpers/file.helper.ts"; import type { DataRawDump, Item, Machine, Module, Quality, RecipeCategory, Signal, } from "./factorio-process-data.models.js"; import { groupPrototypes, type Group } from "./helpers/groups.helper.ts"; import { parseRecipe, type Recipe } from "./helpers/recipes.helper.ts"; import type { ProcessedData } from "./factorio-process-data.models.ts"; import { buildIconTextureMap, walkForIcons } from "./helpers/icons.helper.ts"; import path from "path"; //const modsPath = `${factorioPath}/mods`; // const tempPath = "./scripts/temp"; // const tempIconsPath = `${tempPath}/icons`; const isHidden = (o: unknown) => !(o as { hidden?: boolean }).hidden; /** * Extract machines. */ function extractMachines(data: DataRawDump): Machine[] { return Object.values(data["assembling-machine"]) .filter(isHidden) .map((machine) => ({ name: machine.name, icon: `entity/${machine.name}.png`, crafting_categories: machine.crafting_categories, crafting_speed: machine.crafting_speed, allowed_effects: machine.allowed_effects, module_slots: machine.module_slots, selection_box: machine.selection_box, effect_receiver: machine.effect_receiver, })); } /** * Extract modules. */ function extractModules(data: DataRawDump): Module[] { return Object.values(data.module) .filter(isHidden) .map((module) => ({ name: module.name, icon: `item/${module.name}.png`, subgroup: module.subgroup, category: module.category, tier: module.tier, order: module.order, effect: module.effect, })); } // TODO : Add quality Modules and quality Machines /** * All the keys that contain item‑like entities. */ const ITEM_KEYS = [ "item", "ammo", "armor", "capsule", "gun", "item-with-entity-data", "module", "rail-planner", "repair-tool", "selection-tool", "spidertron-remote", "space-platform-starter-pack", "tool", "fluid", ] as const; /** * Extract all items (and item‑like things) from the raw dump. */ function extractItems(dataRaw: DataRawDump): Record { return ITEM_KEYS.reduce((acc: Record, key) => { const data = dataRaw[key]; if (data) Object.values(data) .filter(isHidden) .forEach((item) => { const isFluid = item.type === "fluid"; acc[item.name] = { name: item.name, icon: `${isFluid ? "fluid" : "item"}/${item.name}.png`, subgroup: item.subgroup ?? (isFluid ? "fluid" : "other"), order: item.order, }; }); return acc; }, {}); } export async function processData(outputFolder: string) { const data = getJsonData(dataRawPath) as DataRawDump; const items = extractItems(data); const machines = extractMachines(data); const modules = extractModules(data); const recipeCategories: RecipeCategory[] = Object.values(data["recipe-category"]) .filter(isHidden) .map((c) => ({ name: c.name, subgroup: c.subgroup, order: c.order })); const recipes = Object.values(data["recipe"]) .filter(isHidden) .map((o) => parseRecipe(o, items)); const qualityLevels: Quality[] = Object.values(data.quality) .filter(isHidden) .map((o) => ({ ...o, icon: `quality/${o.name}.png`, })); const recipeGroup: Array> = groupPrototypes(recipes, data, false); const signals: Array = []; for (let item of Object.values(items)) { signals.push({ name: item.name, subgroup: item.subgroup ?? "", icon: item.icon, order: item.order, }); } const virtualSignals = Object.values(data["virtual-signal"]).filter(isHidden); for (let vs of virtualSignals) { signals.push({ name: vs.name, subgroup: vs.subgroup ?? "", icon: `virtual-signal/${vs.name}.png`, order: vs.order, }); } for (let quality of qualityLevels) { signals.push({ name: quality.name, subgroup: quality.subgroup ?? "", icon: quality.icon, order: quality.order, }); } const signalGroup: Array> = groupPrototypes(signals, data, false); const output: ProcessedData = { qualityLevels, machines, modules, recipeCategories, recipeGroup, signalGroup, }; fs.mkdirSync(outputFolder, { recursive: true }); fs.writeFileSync( path.resolve(outputFolder, "data.json"), JSON.stringify(output, null, 2), "utf-8" ); const icons = new Set(); walkForIcons(output, icons); const iconsList = Array.from(icons).sort(); checkIcons(iconsList); await buildIconTextureMap(iconsList, scriptOutputPath, outputFolder); console.log(`✅ Done - data written to ${outputFolder}`); }