Created
March 5, 2013 05:35
-
-
Save sk89q/5088260 to your computer and use it in GitHub Desktop.
Request system we used that let you put what you wanted in a book, and then it would supply your ender pouch with the items
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Remote Request | |
by sk89q | |
]]-- | |
function periph(side) | |
while true do | |
local p = peripheral.wrap(side) | |
if p then return p end | |
os.sleep(1) | |
end | |
end | |
function wrap(str, limit) | |
local here = 1 | |
return str:gsub("(%s+)()(%S+)()", | |
function(sp, st, word, fi) | |
if fi - here > limit then | |
here = st | |
return "\n" .. word | |
end | |
end) | |
end | |
function prototype(parent, t) | |
if not t then | |
t = parent | |
parent = nil | |
end -- when there is no inheritance | |
local t = t or {} | |
local mt = { __index = t } | |
setmetatable(t, { | |
__call = function(_, ...) | |
local obj = setmetatable({}, mt) | |
if obj.__construct then obj:__construct(unpack(arg)) end | |
return obj | |
end, | |
__index = parent | |
}) | |
return t | |
end | |
function trim(s) | |
return s:match("^%s*(.*)"):match("(.-)%s*$") | |
end | |
local Transport = prototype({ | |
__construct = function(self, ...) | |
self.paths = arg | |
end, | |
transferTo = function(self, id, amount) | |
for i = 1, #self.paths do | |
local sorter = path[1] | |
local from = path[2] | |
local to = path[3] | |
sorter.extract(from, id, to, amount) | |
end | |
end, | |
transferFrom = function(self, id, amount) | |
for i = #self.paths, 1, -1 do | |
local sorter = path[1] | |
local to = path[2] -- reversed | |
local from = path[3] | |
sorter.extract(from, id, to, amount) | |
end | |
end, | |
listFrom = function(self) | |
local path = self.paths[1] | |
return path[1].list(path[2]) | |
end, | |
listTo = function(self) | |
local path = self.paths[#self.paths] | |
return path[1].list(path[3]) | |
end | |
}) | |
local Printer = prototype({ | |
__construct = function(self, printer) | |
self.printer = printer | |
end, | |
print = function(self, title, text) | |
self.printer.newPage() | |
self.printer.setPageTitle(title) | |
local w, h = self.printer.getPageSize() | |
local lineNo = 1 | |
for token in string.gmatch(text, "[^\n]+") do | |
for line in string.gmatch(wrap(token, w), "[^\n]+") do | |
-- may need new page! | |
if lineNo > h then | |
lineNo = 1 | |
if not self.printer.endPage() then | |
return false | |
end | |
self.printer.newPage() | |
self.printer.setPageTitle(title) | |
w, h = self.printer.getPageSize() | |
end | |
self.printer.setCursorPos(1, lineNo) | |
self.printer.write(line) | |
lineNo = lineNo + 1 | |
end | |
end | |
return self.printer.endPage() | |
end | |
}) | |
local Requester = prototype({ | |
cobbleISorterId = 538962333, | |
triggerAmount = 1, | |
__construct = function(self, sorter, side, sharedSide) | |
self.sorter = sorter | |
self.side = side | |
self.sharedSide = sharedSide | |
end, | |
isTriggered = function(self) | |
local items = self.sorter.list(self.side) | |
if items == nil then return end -- inventory missing | |
for id, amount in pairs(items) do | |
if id == self.cobbleISorterId and amount == self.triggerAmount then | |
return true | |
end | |
end | |
return false | |
end, | |
pull = function(self, id, amount) | |
self.sorter.extract(self.side, self.cobbleISorterId, self.sharedSide, self.triggerAmount) | |
self.sorter.extract(self.side, id, self.sharedSide, amount) | |
-- return what the trigger item is | |
return unpack({self.cobbleISorterId, self.triggerAmount}) | |
end, | |
distribute = function(self, left, silent) | |
local items = self.sorter.list(self.sharedSide) | |
if items == nil then return end -- inventory missing | |
for id, amount in pairs(items) do | |
if left <= 0 then | |
print("Ran out of items!", id) | |
return 0 | |
end | |
local n = math.min(left, amount) | |
left = left - n -- remove from # of items we still need | |
if not silent then | |
print("Moving ", n, "x (isorter)", id) | |
end | |
self.sorter.extract(self.sharedSide, id, self.side, n) | |
end | |
return left -- how many we were unable to send? | |
end | |
}) | |
local Match = prototype({ | |
__construct = function(self, uid, name, amount, confidence) | |
self.uid = uid | |
self.name = name | |
self.amount = amount | |
self.confidence = confidence | |
end | |
}) | |
local Request = prototype({ | |
__construct = function(self, name, amount) | |
self.name = name | |
self.amount = amount | |
self.match = nil | |
end, | |
getConfidence = function(self, name) | |
local test = self.name:lower() | |
local name = name:lower() | |
if string.sub(name, 1, string.len(test)) == test then | |
return 1/math.abs(#test - #name) | |
else | |
return 0 | |
end | |
end, | |
setMatch = function(self, match) | |
if self.match == nil or match.confidence > self.match.confidence then | |
self.match = match | |
end | |
end | |
}) | |
local RequestManager = prototype({ | |
bookISorterId = 551348637, -- isorter ID, UPDATE LATER | |
bookId = 386, -- book and quill ID | |
__construct = function(self, queryPipe, requestPipe, sorter, storeSide, processSide) | |
self.queryPipe = queryPipe | |
self.requestPipe = requestPipe | |
self.sorter = sorter | |
self.storeSide = storeSide | |
self.processSide = processSide | |
end, | |
execute = function(self, requester) | |
-- pull the book and destroy the trigger | |
local id, amount = requester:pull(self.bookISorterId, 1) | |
self.sorter.extract(self.storeSide, id, self.processSide, amount) | |
local requested = self:read() | |
-- move the book back | |
requester:distribute(1, true) | |
if #requested > 0 then -- only if some were parsed correctly! | |
local left = self:request(requested) | |
if left > 0 then | |
local limit = 30 | |
for i = 1, limit do -- keep trying to send until we give up or finish | |
os.sleep(1) -- just wait a bit | |
left = requester:distribute(left) | |
if left == 0 then break end -- finish successfully | |
limit = 30 | |
print("Still ", left, " item(s) left!") | |
end | |
print("Finished request with ", left, " item(s) left") | |
else | |
print("No items successfully requested") | |
end | |
end | |
end, | |
read = function(self) | |
local requested = {} -- returned | |
-- ask the request pipe for items | |
self.queryPipe.getAvailableItems() | |
-- look for the book | |
local event, items = os.pullEvent("available_items_return") | |
for _, item in ipairs(items) do | |
local uid = item[1] | |
local amount = item[2] | |
local id = self.queryPipe.getItemID(uid) | |
-- book and quill | |
if id == self.bookId then | |
local nbt = self.queryPipe.getNBTTagCompound(uid) | |
local pages = nbt.value.pages.value | |
local text = "" | |
for _, v in ipairs(pages) do | |
text = text .. v.value .. "\n" | |
end | |
for k, v in string.gmatch(text, "([0-9]+) +([^0-9]+)") do | |
table.insert(requested, Request(trim(v), tonumber(k))) | |
end | |
end | |
end | |
return requested | |
end, | |
request = function(self, requested) | |
local expected = 0 -- keep track of the number of items that we want | |
self.requestPipe.getAvailableItems() | |
local event, items = os.pullEvent("available_items_return") | |
for _, item in ipairs(items) do | |
local uid = item[1] | |
local amount = item[2] | |
local name = self.requestPipe.getItemName(uid) | |
if name ~= "" then -- empty names are bad! | |
for k, request in ipairs(requested) do | |
-- does it match? | |
local confidence = request:getConfidence(name) | |
if confidence > 0 then | |
local n = math.min(amount, request.amount) | |
request:setMatch(Match(uid, name, n, confidence)) | |
end | |
end | |
end | |
end | |
-- loop over and request | |
for k, request in ipairs(requested) do | |
local match = request.match | |
if match then | |
print("Requesting ", match.amount, "x ", match.name) | |
expected = expected + match.amount | |
self.requestPipe.makeRequest(match.uid, match.amount) -- request! | |
else | |
print("Couldn't find ", request.amount, "x ", request.name) | |
end | |
end | |
return expected | |
end | |
}) | |
-------------- | |
local down = 0 | |
local up = 1 | |
local north = 2 | |
local south = 3 | |
local west = 4 | |
local east = 5 | |
local sorter1 = periph("left:yellow") | |
local sorter2 = periph("right:yellow") | |
local queryPipe = periph("back") | |
local requestPipe = periph("top") | |
local printerBlock = periph("right:blue") | |
--[[ | |
local printer = Printer(printerBlock) | |
printer.print("TEST", "testing") | |
local transport = Transport( | |
{sorter2, south, north}, {sorter2, south, north}) | |
skcraft.dump(transport:listTo()) | |
]]-- | |
local requesters = { | |
Requester(sorter1, west, south), | |
Requester(sorter1, north, south), | |
Requester(sorter1, east, south), | |
Requester(sorter1, up, south), | |
Requester(sorter2, west, north), | |
Requester(sorter2, south, north), | |
Requester(sorter2, east, north), | |
Requester(sorter2, up, north), | |
} | |
local reqMan = RequestManager(queryPipe, requestPipe, sorter2, north, up) | |
print("Remote Request activated") | |
while true do | |
for _, requester in ipairs(requesters) do | |
if requester:isTriggered() then | |
reqMan:execute(requester) | |
end | |
end | |
os.sleep(1) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment