Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,8 @@ Custom crafting recipes must be specified in JSON files within the `config/recip
}
]
```

Recipe inputs are consumed by default. Set `consumed` to `false` for a
reusable component. It is placed in the machine for crafting, then returned
to network storage after all outputs have been collected, before the machine
can start another recipe.
5 changes: 5 additions & 0 deletions inv/Item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ function Item:init(spec)
if spec.count ~= nil then
self.count = spec.count
end

-- bool: Whether this item is consumed by the recipe. This is meaningful
-- for recipe inputs; inputs are consumed by default for compatibility
-- with existing recipes.
self.consumed = spec.consumed ~= false
end

-- Returns true if the other item satisfies the criteria specified by this Item.
Expand Down
34 changes: 33 additions & 1 deletion inv/device/Machine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ end
-- Empties an output slot of the machine and counts any crafted items.
function Machine:handleOutputSlot(item, virtSlot, realSlot)
if item then
n = self.server.invManager:pullItemsFrom(item, self, realSlot)
if self.recipe.output[virtSlot]:matches(item) then
local n = self.server.invManager:pullItemsFrom(item, self, realSlot)
self.remaining[virtSlot] = self.remaining[virtSlot] - n
if self.dest then
local outItem = self.recipe.output[virtSlot]:copy()
Expand All @@ -77,9 +77,33 @@ function Machine:handleOutputSlot(item, virtSlot, realSlot)
end
end

-- Removes all input items which the recipe did not consume from the machine.
-- These are returned to network storage just like normal machine output.
function Machine:pullNonConsumedInputs()
if not self.recipe then
return true
end
for virtSlot, input in pairs(self.recipe.input) do
if not input.consumed then
local realSlot = self:mapSlot(virtSlot)
local item = self:getItemDetail(realSlot)
if item then
local moved = self.server.invManager:pullItemsFrom(item, self, realSlot)
if moved < item.count then
return false
end
end
end
end
return true
end

-- Empties all output slots of this machine, counting the crafted items
-- and updating the machine state as necessary.
function Machine:pullOutput()
if not self.recipe then
return
end
for virtSlot, rem in pairs(self.remaining) do
local realSlot = self:mapSlot(virtSlot)
local item = self:getItemDetail(realSlot)
Expand All @@ -90,6 +114,14 @@ function Machine:pullOutput()
return
end
end

-- A non-consumed input remains in the machine after crafting. Empty it
-- before making the machine available for another recipe. If storage is
-- temporarily unable to accept it, leave the machine busy and retry on
-- the next task update.
if not self:pullNonConsumedInputs() then
return
end
self.recipe = nil
end

Expand Down