OCs Exoplanetary Expansion

by OC1024

Adds many alternative recipes mostly based on the foundry, but also for the EM plant. Enables many recipes to be crafted in the foundry and EM plant if fitting

Content
2 months ago
2.0
407
Factorio: Space Age Icon Space Age Mod
Manufacturing

b Muluna Compat and another signal to recipe issue

a month ago
(updated a month ago)

First of all, my English isn't very good, so the following was translated using Google Translate. Please forgive any inaccuracies:

Main Text: Oh my god, my circuitry for ten foundries to produce a bunch of materials (copper, iron, steel, wires, gears, etc.) is malfunctioning, mostly due to your recipes.

If I output a steel signal, the foundries will use some inexplicable items to produce materials. Perhaps the problem isn't with you, because I'm playing a Raz modpack, which is full of mods. However, I can offset this by outputting an equal amount of negative steel signals through a judgment circuit. Fortunately, there's the molten steel signal. As long as the circuit outputs a molten steel signal of 1, I can use the molten steel recipe to produce materials. So far, my circuitry hasn't had any problems; it just encounters a recipe mismatch and uses a judgment processor to convert the recipe.

Until I went to Muluna (I started on Vulcan), it turned out that inputting the Automation Core recipe worked correctly before aluminum was unlocked in Muluna. The foundry received the Automation Core recipe and used molten copper and iron. After going to the moon and unlocking aluminum, the circuit inputting the Automation Core changed to using aluminum plates to make it. Yes, aluminum plates, not even molten aluminum. Because the signal didn't have your recipe signal, I couldn't even use the circuit to change it.

Because I'm a coding novice, I tried writing a patch using AI:
-- 9. 把铸造厂和电磁工厂配方作为信号 (并修复缺失图标)

local function ensure_icon(recipe)
if recipe.icon or recipe.icons then return end

if recipe.main_product then
    local prod = data.raw.item[recipe.main_product] or data.raw.fluid[recipe.main_product]
    if prod then
        recipe.icon = prod.icon
        recipe.icons = prod.icons
        recipe.icon_size = prod.icon_size or 64
        return
    end
end

local results = recipe.results or (recipe.normal and recipe.normal.results)
if results and results[1] then
    local r = results[1]
    local name = r.name or r[1]
    local prod = data.raw.item[name] or data.raw.fluid[name]
    if prod then
        recipe.icon = prod.icon
        recipe.icons = prod.icons
        recipe.icon_size = prod.icon_size or 64
        return
    end
end

recipe.icon = "__base__/graphics/icons/signal/signal_X.png"
recipe.icon_size = 64

end

-- 仅锁定铸造厂、电磁工厂以及组装机实际用到的核心分类
local target_signal_categories = {
["metallurgy"] = true, -- 铸造厂 (原版)
["moulding"] = true, -- 铸造厂 (OC模组里的自动化核心等)
["electromagnetics"] = true, -- 电磁工厂
["crafting"] = true, -- 组装机 (绝大部分普通配方)
["crafting-with-fluid"] = true -- 组装机 (需要流体参与的配方)
}

for _, recipe in pairs(data.raw.recipe) do
-- 精准匹配,不搞模糊搜索
if recipe.category and target_signal_categories[recipe.category] then

    -- 强制打破引擎限制,避免崩溃并生成信号
    recipe.allow_intermediates = true
    recipe.allow_as_intermediate = true

    recipe.allow_decomposition = true
    recipe.show_amount_in_title = true
    ensure_icon(recipe)
end

end

The code ran successfully, and it gave me a lot of other signals, but the automated core recipe signals for molten copper and molten iron are still not being used.

Your mod is very good; hopefully you can resolve the recipe issue.

a month ago
(updated a month ago)

Additionally, I sorted your recipes in my patch file. Because some recipe sequences are reversed—the original and K2 recipes have iron first and copper second, but some of your module recipes have copper first and iron second—this caused fluid connection confusion. I wrote code using AI to successfully correct this:
-- 辅助函数区 (提取公共逻辑,减少重复代码与内存分配)


-- 获取配方的真实首要产物名
local function get_primary_result_name(recipe)
if recipe.result then return recipe.result end
if recipe.results and recipe.results[1] then return recipe.results[1].name or recipe.results[1][1] end
if recipe.normal then
if recipe.normal.result then return recipe.normal.result end
if recipe.normal.results and recipe.normal.results[1] then return recipe.normal.results[1].name or recipe.normal.results[1][1] end
end
return recipe.name
end

-- 遍历配方的所有材料节点 (普通/正常难度/昂贵难度),执行回调函数
local function process_recipe_ingredients(recipe, callback)
if recipe.ingredients then callback(recipe.ingredients, recipe) end
if recipe.normal and recipe.normal.ingredients then callback(recipe.normal.ingredients, recipe) end
if recipe.expensive and recipe.expensive.ingredients then callback(recipe.expensive.ingredients, recipe) end
end

-- 8. 全局修改铸造厂类配方的流体接口顺序 (强制铁在铜前,主要针对OC模组)

-- 锁定目标:铸造厂所使用的配方类别。
-- 根据截图,这里填写的是 "castra-metallurgy"
local target_categories = {
["castra-metallurgy"] = true,
-- 如果未来发现其他机器(比如高级铸造厂)用的是别的类别,直接在下面追加:
-- ["advanced-metallurgy"] = true,
}

for recipe_name, recipe in pairs(data.raw.recipe) do
-- 获取配方的类别,如果没有显式定义,原版默认归类为 "crafting"
local category = recipe.category or "crafting"

-- 只有属于目标类别的配方,才进行扫描和接口调换
if target_categories[category] then
    process_recipe_ingredients(recipe, function(ingredients)
        local iron_idx = nil
        local copper_idx = nil

        -- 遍历寻找铁和铜所在的序列号
        for i, ing in ipairs(ingredients) do
            local name = ing.name or ing[1]
            if name then
                if string.find(name, "iron") then 
                    iron_idx = i 
                elseif string.find(name, "copper") then 
                    copper_idx = i 
                end
            end
        end

        -- 如果两者都存在,且铜排在铁前面,则互相交换位置
        if iron_idx and copper_idx and (copper_idx < iron_idx) then
            local temp = ingredients[copper_idx]
            ingredients[copper_idx] = ingredients[iron_idx]
            ingredients[iron_idx] = temp

            -- log("已修复流体顺序的配方: " .. recipe_name) -- 需要调试时可取消注释
        end
    end)
end

end

a month ago
(updated a month ago)

I took a look at my path mod code and realized that the problem with the automation core had been there for a long time. I solved it by canceling its production in the foundry... Oh, maybe this time I can succeed by adding the aluminum automation core?

-- 1. 改自动化核心配方 (OCs_foundary_expansion)

if mods["OCs_foundary_expansion"] then
if not data.raw["recipe-category"]["automation-core-emp"] then
data:extend({{ type = "recipe-category", name = "automation-core-emp" }})
end

for _, entity_type in pairs({"character", "assembling-machine"}) do
    for _, entity in pairs(data.raw[entity_type]) do
        if entity.crafting_categories then
            for _, cat in pairs(entity.crafting_categories) do
                if cat == "crafting" or cat == "electromagnetics" then
                    table.insert(entity.crafting_categories, "automation-core-emp")
                    break -- 匹配到一个就足够,跳出内层循环
                end
            end
        end
    end
end

-- 将需要修改的自动化核心配方统一放进列表遍历,避免代码重复
local target_cores = {
    "kr-automation-core", 
    "kr-automation-core-from-aluminum"
}

for _, core_name in pairs(target_cores) do
    if data.raw.recipe[core_name] then
        data.raw.recipe[core_name].category = "automation-core-emp"
        log("Successfully set " .. core_name .. " to allow Assemblers + EMP")
    end
end

end

a month ago

Thanks for the report. Please give me some time to read through it and find the core issue. Then I hope to find a solution.

a month ago
(updated a month ago)

Thanks for the report. Please give me some time to read through it and find the core issue. Then I hope to find a solution.

The "kr-automation-core" and "kr-automation-core-from-aluminum" recipes have been removed from the foundry. Now, inputting the automation core signal will use the recipes that use molten iron and molten copper。

a day ago

Thanks for the report. Please give me some time to read through it and find the core issue. Then I hope to find a solution.

I used Gemini Pro to write a large amount of patch code to fix your recipes; the work is largely complete, except for the signals. I’ve identified why the signals were missing while the recipes remained: the recipes are dynamically generated. This dynamic generation—especially if implemented within data-final-fixes—results in recipes existing without corresponding signals; furthermore, it can negatively impact the Recycler.
Fortunately, since your mod primarily adds new recipes, placing the code in data-final-fixes shouldn't be an issue.
With the 2.1 update approaching, I suggest a major rewrite of the mod; ideally, all existing recipes should be explicitly defined in recipe.lua.
As for recipe balancing, I’ll provide the code for you.

a day ago

local util = require("util")


-- 辅助函数区

local function get_primary_result_name(recipe)
if recipe.result then return recipe.result end
if recipe.results and recipe.results[1] then return recipe.results[1].name or recipe.results[1][1] end
return recipe.name
end

local function process_recipe_ingredients(recipe, callback)
if recipe.ingredients then callback(recipe.ingredients, recipe) end
end


-- 1. 调整特定配方结构 (流体顺序与替换)

-- 全局修改铸造厂类配方的流体接口顺序 (强制铁在铜前)
local target_categories = { ["castra-metallurgy"] = true, ["metallurgy"] = true }
for recipe_name, recipe in pairs(data.raw.recipe) do
local category = recipe.category or "crafting"
if target_categories[category] then
process_recipe_ingredients(recipe, function(ingredients)
local iron_idx, copper_idx = nil, nil
for i, ing in ipairs(ingredients) do
if ing.type == "fluid" then
if ing.name == "molten-iron" then iron_idx = i
elseif ing.name == "molten-copper" then copper_idx = i end
end
end
if iron_idx and copper_idx and (copper_idx < iron_idx) then
local temp = ingredients[copper_idx]
ingredients[copper_idx] = ingredients[iron_idx]
ingredients[iron_idx] = temp
end
end)
end
end


-- 2. 增删配方与产能标签 (合并清理版)

-- 将需要删除的配方统一放到一个表里管理
local recipes_to_remove = {
"oc-casting-kr-imersium-gear-wheel",
"oc-casting-kr-imersium-beam",
"oc-casting-kr-imersium-plate",
}

-- 遍历并统一清理配方和相关科技解锁
for _, target_recipe in ipairs(recipes_to_remove) do
if data.raw.recipe[target_recipe] then
-- 1. 删除配方本体
data.raw.recipe[target_recipe] = nil

    -- 2. 遍历所有科技,清理涉及该配方的解锁或产能加成
    for _, tech in pairs(data.raw.technology) do
        if tech.effects then
            for i = #tech.effects, 1, -1 do
                local effect = tech.effects[i]
                if (effect.type == "unlock-recipe" or effect.type == "change-recipe-productivity") and effect.recipe == target_recipe then
                    table.remove(tech.effects, i)
                end
            end
        end
    end
end

end

The above code represents the modifications I made to your mod in data-updates.lua.
It primarily implements two functions:
1. Fluid sorting: Since some of your recipes were not sorted, I have standardized the order.
2. Removal of three recipes: These recipes have already been introduced in the K2SO update, so you can safely remove them; the K2 recipes do not require water.

a day ago

The data-final-fixes.lua code is 20,000 characters long, which exceeds the reply limit. Do you have Discord? I’d like to send the code to you there.
It primarily handles three things:
1. It automatically rebalances and recursively processes recipes based on current settings, even if they aren't defined correctly in recipe.lua (I only implemented this for the Foundry; I was too lazy to modify the Electromagnetic Plant—honestly, using AI to tweak and refine that section took me a whole week of constant adjustments!).
2. It enables production capabilities for certain recipes—ones you had forgotten to include.
3. It disables the use of Foundries for two engine recipes—I had to do this because of a lack of signal data; otherwise, it would interfere with my smart production system. Well, I suppose that’s just me being a bit obsessive-compulsive.

Finally, I suggest adding compatibility for Muluna. Since Muluna adds aluminum, having both K2SO and Muluna enabled would allow for the automated casting of cores.

a day ago

My discord name is just the same as here with small letters, oc1024.
I am very interested on how you or the AI tries to fix that issue.
The Muluna compatibility sounds like a good next project, after I fix upcoming issues with 2.1 and this current circuit-related issue.

New response