Replacing all recipe ingredient with another.

Place to get help with not working mods / modding interface.
kasandraen
Long Handed Inserter
Long Handed Inserter
Posts: 51
Joined: Wed May 27, 2015 11:00 pm
Contact:

Replacing all recipe ingredient with another.

Post by kasandraen »

Hi, I'va made this script:

Code: Select all

function ReplaceAllIngredientFluidWithFluid(Fluid1 , Fluid2)
	for i, recipe in pairs(data.raw.recipe) do
		for v, ingredient in pairs(data.raw.recipe[recipe.name].ingredients) do
			if ingredient.type == "fluid" then
				if ingredient.name == Fluid1 then
					ingredient.type = "fluid"
					ingredient.name = Fluid2
				end
			end
		end
	end
end	
to replace all fluid with another one (say change all recipe that uses water to use a new fluid named clean-water) and it works, but I tried changing it to do the same to items, but it doesnt work

Code: Select all

function ReplaceAllIngredientItemWithItem(Item1 , Item2)
	for i, recipe in pairs(data.raw.recipe) do
		for v, ingredient in pairs(data.raw.recipe[recipe.name].ingredients) do
			if ingredient.type == "item" then
				if ingredient.name == Item1 then
					ingredient.name = Item2
					ingredient.amount = ingredient.amount
				end
			end
		end
	end
Are you able to see what I did wrong? :P or does it even work the same way??
daniel34
Global Moderator
Global Moderator
Posts: 2761
Joined: Thu Dec 25, 2014 7:30 am
Contact:

Re: Replacing all recipe ingredient with another.

Post by daniel34 »

Recipe ingredients (items) can be confusing, most of them don't have a set type (type is nil) and ingredient.name is also nil most of the time.

You should be able to check if it's an item type by testing if ingredient.type == nil or ingredient.type == "item".
If you have determined that it is an item then check if ingredient.name is nil, in that case use ingredient[1] instead.
quick links: log file | graphical issues | wiki
kasandraen
Long Handed Inserter
Long Handed Inserter
Posts: 51
Joined: Wed May 27, 2015 11:00 pm
Contact:

Re: Replacing all recipe ingredient with another.

Post by kasandraen »

daniel34 wrote:Recipe ingredients (items) can be confusing, most of them don't have a set type (type is nil) and ingredient.name is also nil most of the time.

You should be able to check if it's an item type by testing if ingredient.type == nil or ingredient.type == "item".
If you have determined that it is an item then check if ingredient.name is nil, in that case use ingredient[1] instead.
Got it working, Thanks!

For future reference if anyone else needs it:

Code: Select all

function ReplaceAllIngredientItemWithItem(Item1 , Item2)
	for i, recipe in pairs(data.raw["recipe"]) do
		for v, ingredient in pairs(data.raw["recipe"][recipe.name].ingredients) do
			if ingredient.name == Item1 then
				RemoveFromRecipe(recipe.name,Item1)
				AddToRecipe(recipe.name, Item2, ingredient.amount)
			elseif ingredient[1] == Item1 then
				RemoveFromRecipe(recipe.name,Item1)
				AddToRecipe(recipe.name, Item2, ingredient[2])
			end
		end
	end
end	
User avatar
Ober3550
Inserter
Inserter
Posts: 32
Joined: Sun Jan 15, 2017 9:01 am
Contact:

Re: Replacing all recipe ingredient with another.

Post by Ober3550 »

Thanks! This was useful for fixing the two different concrete recipes in angels and vanilla!
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Replacing all recipe ingredient with another.

Post by eradicator »

For future readers reference i'm gonna leave some code here. Recipes are generally difficult to work with. They can specify inputs and outputs in different formats and places. For example the OPs code does not consider normal= and expensive= difficulties (probably because they didn't exist back then :p).

Here's my attempt at converting any recipe to a "standard" form (as of 0.16.51):
(This is not well tested, please use it as a reference only.)

Code: Select all

--normalizes a recipe to use normal/expensive and fully specified products notation
local function get_normalized_recipe(recipe)
  local r = util.table.deepcopy(recipe)
  if (not r.normal) and (r.energy_required or r.ingredients or 
                         r.result or r.results)
    then
    --generates a "normal" node if the recipe uses direct specification
    r.normal = {
      enabled         = r.enabled,
      hidden          = r.hidden, --TODO: test if hidden belongs here
      energy_required = r.energy_required,
      ingredients     = r.ingredients,
      result          = r.result,
      result_count    = r.result_count,
      results         = r.results
      }
    r.enabled,r.hidden,r.energy_required,r.ingredients,r.result,r.result_count,r.results
      = nil,nil,nil,nil,nil,nil,nil
    end
  for _,difficulty in pairs{'normal','expensive'} do
    if r[difficulty] then
      local r = r[difficulty]
      --generate a "results" node from singular results and force type specification
      if r.result then
        r.results = {{type='item',name=r.result,amount=r.result_count or 1}}
      elseif r.results then
        for _,result in pairs(r.results) do
          result.type = result.type or 'item'
          end
        end
      --normalize ingredients to full format
      if r.ingredients then
        for i,ingredient in pairs(r.ingredients) do
          if not ingredient.name then
            r.ingredients[i] = {type='item',name=ingredient[1],amount=ingredient[2]}
            end
          end
        end
      end
    end
  return r
  end
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Post Reply

Return to “Modding help”