Afforess / Factorio-Stdlib

Factorio Standard Library Project
ISC License
161 stars 45 forks source link

add_ingredient issue #146

Open Nexela opened 4 years ago

Nexela commented 4 years ago

https://mods.factorio.com/mod/stdlib/discussion/5dc42f6770ee0d000c1786f4

fabriceni commented 4 years ago

Hi, I have the same problem with the mods pypetroleumhandling_1.6.0 and aai-industry_0.4.1 in 0.18.1 despite the addition of the 3 functions. But no problem in 0.17.79.

Mernom commented 3 years ago

I've opened a pull request that should fix this issue.

drdozer commented 2 years ago

What is the 'correct' behaviour here? To not crash obviously, but what should add_ingredients ideally do if the ingredient already there? There are 2 situations. a) the ingredient is already there with the same number, or b) it's there with a different number. What's the logic for resolving a difference in the number of items? Do you replace it or raise an error or leave it unchanged?

drdozer commented 2 years ago
--- Add an ingredient to an ingredients table.
--- If the ingredient exists, replace the item count
-- @tparam table ingredients
-- @tparam Congepts.ingredient to add
-- @return bool true if replaced, false if added
local function add_or_replace(ingredients, ing)
    for i, ingredient in pairs(ingredients or {}) do
        if ing.name == ingredient.name then
            ingredient.amount = ing.amount
            return true
        end
    end

    ingredients[#ingredients + 1] = ingredient
    return false
end

--- Add an ingredient to a recipe.
-- @tparam string|Concepts.ingredient normal
-- @tparam[opt] string|Concepts.ingredient|boolean expensive
-- @treturn Recipe
function Recipe:add_ingredient(normal, expensive)
    if self:is_valid() then
        normal, expensive = get_difficulties(normal, expensive)

        if self.normal then
            if normal then
                add_or_replace(self.normal.ingredients, normal)
            end
            if expensive then
                add_or_replace(self.expensive.ingredients, expensive)
            end
        elseif normal then
            add_or_replace(self.ingredients, normal)
        end
    end
    return self
end
Recipe.add_ing = Recipe.add_ingredient
Mernom commented 2 years ago

There's also the situation of it being present as a catalyst. Should the catalyst property be inherited to the new entry?

Nexela commented 2 years ago

Well I will admit progress on this has been slow. Really slow

The goal of the whole data library is to fail silently in most cases as it uses an 'if this then that kind of thing'

If an ingredient exists then update the count

If it was a catalyst and now it's not, remove the catalyst.

On Thu, Sep 9, 2021, 12:45 PM Mernom @.***> wrote:

There's also the situation of it being present as a catalyst. Should the catalyst property be inherited to the new entry?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/Afforess/Factorio-Stdlib/issues/146#issuecomment-916265098, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKTFYBI3ISRHPTWXKH7TO3UBDQD3ANCNFSM4KKO5U6A .

drdozer commented 2 years ago

I think my code can be updated to handle catalysts fairly easily. Otherwise I think it does the job.

Mernom commented 2 years ago
--- Add an ingredient to a recipe.
-- @tparam string|Concepts.ingredient normal
-- @tparam[opt] string|Concepts.ingredient|boolean expensive
-- @treturn Recipe
function Recipe:add_ingredient(normal, expensive)
    if self:is_valid() then
        normal, expensive = get_difficulties(normal, expensive)

        if self.normal then
            if normal then
                add_or_replace(self.normal.ingredients, normal)
            end
            if expensive then
                add_or_replace(self.expensive.ingredients, expensive)
            end
        elseif normal then
            add_or_replace(self.ingredients, normal)
        end
    end
    return self
end
Recipe.add_ing = Recipe.add_ingredient

This whole thing can probably just be handled under something like this

for _, diff in pairs  (proto, proto.normal, proto.expensive) do
  if diff.ingredients then
    stuff
  end
end