Has anyone got a clever way to alter recipe output using technology?

Place to get help with not working mods / modding interface.
Post Reply
Doctor_Willis
Burner Inserter
Burner Inserter
Posts: 15
Joined: Tue Sep 26, 2023 11:45 am
Contact:

Has anyone got a clever way to alter recipe output using technology?

Post by Doctor_Willis »

I'm trying to build a mod that alters an ore refining process, so as players complete a research item, they receive additional output from a recipe.
The thing is though, the technology can't be dependant on any other technology.
For example, the default recipe is: 1 mixed-ore -> 1 bronze-ore.
Then, if the player unlocks gold-processing, the recipe becomes: 1 mixed-ore -> 1 bronze-ore + 1 gold-ore.
Or they can do the same for silver-processing: 1 mixed-ore -> 1 bronze-ore + 1 silver-ore.

Then, they can choose to unlock the other technology, and the recipe become 1 mixed-ore -> 1 bronze-ore + 1 silver-ore + 1 gold-ore.

I thought I'd be able to achieve this by initially setting probabilities for gold and silver ore to 0, then alter them with an on_research_finished script, but have run into the problem of no longer being in the prototype stage, so the script can't access 'data'.

What I've got so far is below, and I'd appreciate any help I can get.

item.lua

Code: Select all

local mixedOreItem = {
    type = "item",
    name = "mixed-ore-item",
    localised_description = {"item-description.mixed-ore-item"},
    icon = "__base__/graphics/icons/stone.png",
    icon_size = 64,
    icon_mipmaps = 4,
    subgroup = "raw-resource",
    order = "a[mixed-ore-item]",
    stack_size = 50
}

local goldOreItem = {
    type = "item",
    name = "gold-ore-item",
    localised_description = {"item-description.gold-ore-item"},
    icon = "__base__/graphics/icons/uranium-ore.png",
    icon_size = 64,
    icon_mipmaps = 4,
    subgroup = "raw-resource",
    order = "b[gold-ore-item]",
    stack_size = 50
}

local silverOreItem = {
    type = "item",
    name = "silver-ore-item",
    localised_description = {"item-description.silver-ore-item"},
    icon = "__base__/graphics/icons/iron-ore.png",
    icon_size = 64,
    icon_mipmaps = 4,
    subgroup = "raw-resource",
    order = "c[silver-ore-item]",
    stack_size = 50
}

local bronzeOreItem = {
    type = "item",
    name = "bronze-ore-item",
    localised_description = {"item-description.bronze-ore-item"},
    icon = "__base__/graphics/icons/copper-ore.png",
    icon_size = 64,
    icon_mipmaps = 4,
    subgroup = "raw-resource",
    order = "d[bronze-ore-item]",
    stack_size = 50
}

data:extend{
    mixedOreItem,
    goldOreItem,
    silverOreItem,
    bronzeOreItem
}
recipe.lua

Code: Select all

local refineOre ={
    type = "recipe",
    name = "ore-refining-recipe",
    category = "crafting",
    subgroup = "raw-material",
    enabled = true,
    icon = "__base__/graphics/icons/stone.png",
    icon_size = 64,
    icon_mipmaps = 4,
    energy_required = 1,
    ingredients = {
        {type = "item", name = "mixed-ore-item", amount = 1}
    },
    results = {
        {type="item",name="bronze-ore-item",probability=1,amount_min=1,amount_max=1},
        {type="item",name="silver-ore-item",probability=0,amount_min=1,amount_max=1},
        {type="item",name="gold-ore-item",probability=0,amount_min=1,amount_max=1}
    },
}

data:extend{
    refineOre
}
technology.lua:

Code: Select all

local refineGoldOreTech = {
    type = "technology",
    name = "refine-gold-ore-tech",
    icon = "__base__/graphics/technology/military-science-pack.png",
    icon_size = 256, icon_mipmaps = 4,
    effects = {
        {
            type = "unlock-recipe",
            recipe = "ore-refining-recipe"
        }
    },
    unit = {
        count = 1,
        ingredients = {{"automation-science-pack", 1}},
        time = 1
    },
    order = "a"
}

local refineSilverOreTech = {
    type = "technology",
    name = "refine-silver-ore-tech",
    icon = "__base__/graphics/technology/logistic-science-pack.png",
    icon_size = 256, icon_mipmaps = 4,
    effects = {
        {
            type = "unlock-recipe",
            recipe = "ore-refining-recipe"
        }
    },
    unit = {
        count = 1,
        ingredients = {{"automation-science-pack", 1}},
        time = 1
    },
    order = "a"
}

data:extend{
    refineGoldOreTech,
    refineSilverOreTech
}
control.lua (Non functioning)

Code: Select all

local function adjustProbabilities(player)
    if player.force.technologies["refine-silver-ore-tech"].researched then
        data.raw.recipe["ore-refining-recipe"].results[2].probability = 1
    end
    if player.force.technologies["refine-gold-ore-tech"].researched then
        data.raw.recipe["ore-refining-recipe"].results[3].probability = 1
    end
end

script.on_event(defines.events.on_research_finished, function(event)
    adjustProbabilities(game.players[event.player_index])
end)

User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 319
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: Has anyone got a clever way to alter recipe output using technology?

Post by Stringweasel »

Unfortunately it's not possible with the approach you described. This would require you creating multiple recipes in the data state, one for each technology level. Then when the technology is researched you would have to loop over all entities that exist and change the recipe to the newer one. As well as hide the old recipes in all menus and only show the newer one.

It has some edge cases though, like what happens with blueprints that have the old recipe is placed. Or even harder, what happens if an old blueprinted recipe is placed over an entity with the new recipe. There's currently no (easy) way to detect this, and the entity would then be overwritten with the old recipe.

Pyanodon has a mechanism like this called T.U.R.D. I think. It has some mechanism that allows recipes to be "improved". Not sure though, haven't played it, but you could have a look in their code on how they implemented it.
Alt-F4 Author | Factorio Modder
Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby

Doctor_Willis
Burner Inserter
Burner Inserter
Posts: 15
Joined: Tue Sep 26, 2023 11:45 am
Contact:

Re: Has anyone got a clever way to alter recipe output using technology?

Post by Doctor_Willis »

Thanks for the tip. I'll check out Pyanodon.

The edge cases you mentioned wouldn't be a problem, though. I'm building a small custom scenario, and I'm being extremely limiting with what the player has access to, and blueprints aren't on that list.

User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 319
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: Has anyone got a clever way to alter recipe output using technology?

Post by Stringweasel »

I was curious and found the code: https://github.com/pyanodon/pyalienlife ... d/turd.lua

Functions of interest are `recipe_replacement` and `Turd.events.on_built`. Seems like they don't handle the case of old blueprints like I described, or at least didn't see it at first glance.


... also gotta love the Pyanodon naming scheme
Alt-F4 Author | Factorio Modder
Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby

Post Reply

Return to “Modding help”