Page 1 of 1

How to check false condition? recipe.enabled = nil/true/false

Posted: Tue Feb 04, 2020 1:44 pm
by darkfrei
How to check false condition?

We have three cases:
1) Some recipes have no definition (it means recipe.enabled = true) https://wiki.factorio.com/Prototype/Recipe#enabled
2) Some have recipe.enabled = true
3) Some have recipe.enabled = false

I need the bool "enabled".
The easy way as
local enabled = recipe.enabled gives wrong information by the case 1), but works for case 2) and 3).

Re: How to check false condition? recipe.enabled = nil/true/false

Posted: Tue Feb 04, 2020 1:54 pm
by Deadlock989

Code: Select all

function is_recipe_enabled(recipe)
    return (recipe.enabled == nil) or recipe.enabled
end

Re: How to check false condition? recipe.enabled = nil/true/false

Posted: Tue Feb 04, 2020 1:59 pm
by Bilka
Do you want to handle normal/expensive?

Re: How to check false condition? recipe.enabled = nil/true/false

Posted: Tue Feb 04, 2020 2:30 pm
by darkfrei
Bilka wrote: Tue Feb 04, 2020 1:59 pm Do you want to handle normal/expensive?
I'm using

Code: Select all

local handlers = recipe.normal and {recipe.normal, recipe.expensive} or {recipe}
for i, handler in pairs (handlers) do
  local enabled = (handler.enabled == nil) and true or handler.enabled
end
Or in this code just

Code: Select all

local handler = recipe.normal or recipe
local enabled = (handler.enabled == nil) and true or handler.enabled

Re: How to check false condition? recipe.enabled = nil/true/false

Posted: Tue Feb 04, 2020 3:05 pm
by eradicator
If the default is treated as "true" there's no way around the == nil comparison sadly :|.

Code: Select all

function default_enabled_bool  (x) return x or (x == nil) end
function default_disabled_bool (x) return not not x       end

--test:
default_enabled_bool(nil  ) --true
default_enabled_bool(true ) --true
default_enabled_bool(false) --false

default_disabled_bool(nil  ) --false
default_disabled_bool(true ) --true
default_disabled_bool(false) --false
In recipes "enabled" is part of the difficulty though, so it might be enabled in one difficulty and disabled in another. So there's no one answer to the question. Also keep in mind that "recipe.normal" can be either a boolean or a table.

Edit:
Untested, let's see what stupid edge case i missed...

Code: Select all

local function isdifficulty(x)
  if (type(x) == 'boolean') then return x end
  if (type(x) == 'table'  ) then return default_enabled_bool(x.enabled) end
  end
  
local function xor(a,b) return (a and not b) or (b and not a) or false end

local function isenabled (r) --[[input recipe prototype here]]

  if xor( (r.normal ~= nil), (r.expensive ~= nil) ) then --[[exactly one difficulty]]
    local x
    if (r.normal ~= nil) then x = isdifficulty(r.normal   )
    else                      x = isdifficulty(r.expensive)
      end
    return {normal = x,expensive = x}
      
  elseif (r.normal == nil) and (r.expensive == nil) then --[[no difficulty]]
    local x = default_enabled_bool(r.enabled)
    return {normal = x,expensive = x}
    
  else --[[both difficulties]]
    return {normal = isdifficulty(r.normal),expensive = isdifficulty(r.expensive)}

    end    
  end
Edit2:
Well, as all constructs abusing "a or b" style syntactic sugar this might fails if the difficulty node is boolean false :|. (i.e. "r.normal = false, r.expensive = {ingredients=...}")

Edit3:
Hopefully that fixes it?