Skip to content

Instantly share code, notes, and snippets.

@eric-wieser
Last active August 9, 2024 02:47
Show Gist options
  • Save eric-wieser/4468548 to your computer and use it in GitHub Desktop.
Save eric-wieser/4468548 to your computer and use it in GitHub Desktop.
A library to make inventory management with computercraft turtles more straightforward

itemset

Provide an api to keep track of named items, and make sure you never throw away the last one.

Loading

local ItemSet = dofile('itemset')

Initialization

local items = ItemSet.new {charcoal = 1, sapling = 2, bonemeal = 3, dirt = 4, log = 5, cobble = 16}

Input

if items:blockUpIs('dirt') then
  print("You're not going to space today")
elseif items:blockIs('charcoal') then
  print("That's not even possible")
else
  print(("I'm on a %s"):format(items:blockDown() or "unknown thing")
end

Output

Builds a cobblestone pillar, using as many stacks of cobble as there are in the inventory (leaving one behind). Then drops 100 cobble, and all the saplings.

repeat
  turtle.up()
  print("What a lovely pillar this will be")
until not items:placeDown('cobble')

items:drop('log', 100)
items:drop('sapling')
items:refuelWith('charcoal', 20)

assert(items:count('sapling') == 0)

Method list

  • :slot(name) - return the slot used to define the named item
  • :count(name) - the number of usable items remaining (all but one)
  • :block(), :blockUp(), blockDown() - the identity of the block next to the turtle, if known
  • :blockIs(name), :blockUpIs(name), blockDownIs(name) - check the block next to the turtle is the named item
  • :place(name), :placeUp(name), placeDown(name) - place a block, picking from the highest-numbered slot containing that item
  • :drop(name[, n]), :dropUp(name[, n]), dropDown(name[, n]) - drops n (or all) blocks of a certain type, always holding onto one
  • :refuelWith(name[, n]) - refuel with n (or all) blocks of a certain type, always holding onto one
local ItemSet = {}
ItemSet.__index = ItemSet
ItemSet.new = function(mapping)
return setmetatable({mapping=mapping}, ItemSet)
end
-- internal functions
local _useItem = function(self, fn, name)
local i = self:slot(name)
turtle.select(i)
for j = 16, 1, -1 do
if turtle.compareTo(j) and (i ~= j or turtle.getItemCount(j) > 1) then
return fn()
end
end
return false
end
local _useItems = function(self, fn, name, n)
local i = self:slot(name)
local dropped = 0
for j = 16, 1, -1 do
turtle.select(j)
if turtle.compareTo(i) then
local count = turtle.getItemCount(j)
if i == j then count = count - 1 end
if n and dropped + count > n then
return fn(n - dropped)
elseif count > 0 then
local success = fn(count)
if not success then return false end
end
dropped = dropped + count
end
end
return n == 0 or dropped > 0
end
local _withItems = function(self, fn, name)
turtle.select(self:slot(name))
return fn()
end
local _findName = function(self, predicate)
for name in pairs(self.mapping) do
if predicate(self, name) then
return name
end
end
end
-- methods
do
-- get the slot defined in the mapping
ItemSet.slot = function(self, name)
return self.mapping[name] or error(('%s is not a known item!'):format(name))
end
-- count the number of items of a certain type
ItemSet.count = function(self, name)
turtle.select(self:slot(name))
local count = -1 -- one item must remain to check identity
for j = 1, 16 do
if turtle.compareTo(j) then
count = count + turtle.getItemCount(j)
end
end
return count
end
-- returns the name of the block, as a string, or nil
ItemSet.block = function(self) return _findName(self, ItemSet.blockIs) end
ItemSet.blockUp = function(self) return _findName(self, ItemSet.blockUpIs) end
ItemSet.blockDown = function(self) return _findName(self, ItemSet.blockDownIs) end
-- check if the block is of a certain type. `i:blockIs('wood')` is more efficient than `i:block() == 'wood'`
ItemSet.blockIs = function(self, name) return _withItems(self, turtle.compare, name) end
ItemSet.blockUpIs = function(self, name) return _withItems(self, turtle.compareUp, name) end
ItemSet.blockDownIs = function(self, name) return _withItems(self, turtle.compareDown, name) end
-- place a block of a certain type
ItemSet.place = function(self, name) return _useItem(self, turtle.place, name) end
ItemSet.placeUp = function(self, name) return _useItem(self, turtle.placeUp, name) end
ItemSet.placeDown = function(self, name) return _useItem(self, turtle.placeDown, name) end
-- drop a block of a certain type
ItemSet.drop = function(self, name, n) return _useItems(self, turtle.drop, name, n) end
ItemSet.dropUp = function(self, name, n) return _useItems(self, turtle.dropUp, name, n) end
ItemSet.dropDown = function(self, name, n) return _useItems(self, turtle.dropDown, name, n) end
ItemSet.refuelWith = function(self, name) return _useItems(self, turtle.refuel, name, n) end
end
return ItemSet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment