-- generate lookup for tech by recipe local stacking_techs = {} function get_tech(ingredients) local found = nil for name, tech in pairs(stacking_techs) do found = tech local t = table.deepcopy(tech.packs) for _, pack in ipairs(ingredients) do if t[pack[1]] then t[pack[1]] = nil else found = nil break end end if found and next(t) == nil then return found end end local tech_name = "deadlock-stacking" for _, pack in ipairs(ingredients) do tech_name = tech_name .. "--" .. pack[1] end log("Preparing new stacking tech " .. tech_name) local raw = { type = "technology", name = tech_name, icon = "__deadlock-beltboxes-loaders__/graphics/deadlock-stacking.png", icon_size = 128, -- Factorio seems to fill in prerequisites for the ingredients. -- Good enough for me. -- prerequisites = {}, unit = { count = 10, ingredients = { }, time = 15, }, effects = nil, order = "a-f-a", } local tech = { raw = raw, packs = {}, } for _, pack in ipairs(ingredients) do table.insert(raw.unit.ingredients, {pack[1], 1}) tech.packs[pack[1]] = true end stacking_techs[tech_name] = tech return tech end function add_stack(tech, item_name) local name = string.format("deadlock-stacks-stack-%s", item_name) if tech.raw.effects == nil then -- first effect, add tech for real log("Activating " .. tech.raw.name) tech.raw.effects = {} data:extend({tech.raw}) end table.insert(tech.raw.effects, { recipe = name, type = "unlock-recipe" }) end local recipe_to_tech = {} for name, tech in pairs(data.raw.technology) do local stacking_tech = get_tech(tech.unit.ingredients) if tech.effects then for _, effect in ipairs(tech.effects) do if effect.recipe then log("Recipe " .. effect.recipe .. " = " .. stacking_tech.raw.name) recipe_to_tech[effect.recipe] = stacking_tech end end end end -- generate lookup for techs by item local item_to_techs = {} for name, recipe in pairs(data.raw.recipe) do local tech = recipe_to_tech[name] if tech == nil then -- items that aren't locked behind technologies get automation as requirement tech = get_tech({{"automation-science-pack", 1}}) end log("Item " .. name .. " = " .. tech.raw.name) local results = {{name = recipe.result}} if recipe.results then results = recipe.results end if recipe.normal then results = {{name = recipe.normal.result}} if recipe.normal.results then results = recipe.normal.results end end for _, result in ipairs(results) do item_to_techs[result.name] = item_to_techs[result.name] or {} item_to_techs[result.name][tech.raw.name] = tech end end -- create stacks for everything else for name, item in pairs(data.raw["item"]) do --log("Checking stack for " .. name) if string.sub(name, 1, 15) == "deadlock-stack-" then --log(" - already a stack itself") elseif item.stack_size <= 10 then --log(" - skipping, stack size <= 10") elseif data.raw.item[string.format("deadlock-stack-%s", name)] then --log(" - already stacked") else if item_to_techs[name] then if item.icon_size and (item.icon_size ~= 32 and item.icon_size ~= 64 and item.icon_size ~= 128) then log("Wrong icon_size for " .. name .. ": " .. item.icon_size) else log("Create stack for " .. name) deadlock.add_stack(name, item.icon, nil, item.icon_size or 32) for tech_name, tech in pairs(item_to_techs[name]) do log(" - adding " .. name .. " to " .. tech_name) add_stack(tech, name) end end else log("No tech activating " .. name) end end end -- hit the subgroups again to cover any added since data.lua load for _, group in pairs(data.raw["item-group"]) do if not data.raw["item-subgroup"][string.format("stacks-%s", group.name)] then data:extend({ { type = "item-subgroup", name = string.format("stacks-%s", group.name), group = group.name, order = "zzzzz", }, }) end end