Last active
December 15, 2023 20:47
-
-
Save MacChuck/780d80cbcb7b457500e0030f921ab43f to your computer and use it in GitHub Desktop.
Turtle Cafe
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
print("ID: "..os.getComputerID().." Label: "..os.getComputerLabel()) | |
turtle = 34 | |
os.loadAPI("touchpoint") | |
peripheral.find("modem", rednet.open) | |
mon = peripheral.wrap("top") | |
mon.setTextScale(.7) | |
monW,monH = mon.getSize() | |
local pageFood = touchpoint.new("top") | |
local pageManager = touchpoint.new("top") | |
local pageWait = touchpoint.new("top") | |
local pageAlert = touchpoint.new("top") | |
local t | |
os.startTimer(1) | |
function emptyFunc() | |
--do nothing | |
end | |
function managerScreen() | |
t = pageManager | |
t:draw() | |
end | |
function alertScreen() | |
pageAlert:add("No Fuel",emptyFunc,1,2,monW,2,colors.red,colors.red) | |
pageAlert:add("notify",emptyFunc,1,4,monW,4,colors.red,colors.red) | |
pageAlert:add("management",emptyFunc,1,5,monW,5,colors.red,colors.red) | |
t = pageAlert | |
t:draw() | |
end | |
function multiOrder() | |
rednet.send(turtle,{"Sandwich",30}) | |
end | |
-- Functions for ordering food and empty function should be swapped around and reworked. | |
-- The default/nil behavior is to send the name of the button over rednet. | |
pageFood:add("Order Here",emptyFunc,2,1,monW-2,1,colors.black,colors.black) | |
pageFood:add("", managerScreen,monW-1,1,monW,1,colors.black,colors.black) | |
pageFood:add("Fried Rice", nil, 1,2,monW,2, colors.green, colors.lime) | |
pageFood:add("Caramel", nil, 1,3,monW,3, colors.green, colors.lime) | |
pageFood:add("Cheesecake", nil, 1,4,monW,4, colors.green, colors.lime) | |
pageFood:add("Coffee Cake", nil, 1,5,monW,5, colors.green, colors.lime) | |
pageFood:add("Sweet Roll", nil, 1,6,monW,6, colors.green, colors.lime) | |
pageFood:add("Sandwich", nil, 1,7,monW,7, colors.green, colors.lime) | |
pageFood:add("Sushi", nil, 1,8,monW,8, colors.green, colors.lime) | |
pageFood:add("Coffee", nil, 1,9,monW,9, colors.green, colors.lime) | |
pageFood:add("Hot Chocolate", nil, 1,10,monW,10, colors.green, colors.lime) | |
pageWait:add("Cooking...",emptyFunc,1,2,monW,2,colors.black,colors.black) | |
pageManager:add("Manager",emptyFunc,1,1,monW,1,colors.red,colors.red) | |
pageManager:add("Cake", nil, 1,2,monW,2, colors.green, colors.lime) | |
pageManager:add("Sandwich",multiOrder,1,3,monW-5,3,colors.green,colors.lime) | |
pageManager:add("x30",emptyFunc,monW-4,3,monW,3,colors.green,colors.green) | |
t = pageFood | |
t:draw() | |
function waitScreen() | |
t = pageWait | |
t:draw() | |
end | |
function menuScreen() | |
t = pageFood | |
t:draw() | |
end | |
function callButton(name) | |
if t.buttonList[name].func ~= nil then | |
t.buttonList[name].func() | |
else | |
rednet.send(turtle,name) | |
end | |
end | |
while true do | |
local event, p1, msg, proto = t:handleEvents(os.pullEvent()) | |
if event == "button_click" then | |
t:flash(p1) | |
callButton(p1) | |
elseif event == "rednet_message" then | |
if p1 == turtle then | |
if msg == "cooking" then waitScreen() | |
elseif msg == "served" then menuScreen() | |
elseif msg == "lowfuel" then alertScreen() | |
end | |
end | |
elseif event == "timer" then | |
os.startTimer(10) | |
end | |
end |
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
print("ID: "..os.getComputerID().." Label: "..os.getComputerLabel()) | |
controlComputer = 31 | |
peripheral.find("modem",rednet.open) | |
arg1,arg2 = ... | |
-- update function and arg check | |
function update() | |
shell.run( "rm", shell.getRunningProgram() ) -- Delete the current program | |
shell.run( "pastebin", "get", "BehPqTT7", shell.getRunningProgram() ) -- Update it | |
print("updated, please restart") | |
error("exiting intentionally") | |
end | |
if (arg1 ~= nil) and (string.lower(arg1) == "update") then | |
update() | |
end | |
os.startTimer(1) | |
-- Bowls and cups are using slot 16 | |
-- Crafting uses the lower right 9 squares | |
-- current location and counter position | |
curLoc = 0 | |
counter = "front" --left, right, front, rear | |
--workstation locations | |
--using location 0 for home to trigger and undock if needed | |
fridge1 = 1 | |
fridge2 = 2 | |
kettle = 3 | |
pot = 4 | |
shelf = 5 | |
cocoa = 6 | |
milk = 7 | |
serve = 4 | |
--recipes/menu | |
-- key / workstation, ingredients | |
-- workstations determine if/what shelf item should be used | |
menu = {} | |
menu["Caramel"] = {"none","caramel"} | |
menu["Cheesecake"] = {"none","cheesecake"} | |
menu["Coffee Cake"] = {"none","coffee cake"} | |
menu["Sandwich"] = {"crafting","bread","bacon","tomato","cabbage"} | |
menu["Sweet Roll"] = {"milk","bread"} | |
menu["Hot Chocolate"] = {"cocoa"} | |
menu["Coffee"] = {"kettle","coffee beans","coffee beans"} | |
menu["Fried Rice"] = {"pot", "rice","egg","carrot","onion"} | |
menu["Sushi"] = {"special","rice","salmon","salmon"} | |
menu["Cake"] = {"special","milk","milk","milk","sugar","egg","sugar","wheat","wheat","wheat"} | |
-- table copying function from | |
-- https://gist.github.com/tylerneylon/81333721109155b2d244 | |
function copyTable(obj, seen) | |
-- Handle non-tables and previously-seen tables. | |
if type(obj) ~= 'table' then return obj end | |
if seen and seen[obj] then return seen[obj] end | |
-- New table; mark it as seen and copy recursively. | |
local s = seen or {} | |
local res = {} | |
s[obj] = res | |
for k, v in pairs(obj) do res[copyTable(k, s)] = copyTable(v, s) end | |
return setmetatable(res, getmetatable(obj)) | |
end | |
function inspectName() | |
s,d = turtle.inspect() | |
if s then | |
return d.name | |
else | |
return "" | |
end | |
end | |
function home() | |
if inspectName():find("computer_advanced") then | |
-- already home | |
else | |
while turtle.down() do | |
-- move down to the floor | |
end | |
for i = 1,4 do | |
if inspectName():find("stairs") then --found counter | |
turtle.turnLeft() --face "right" | |
turtle.up() --above counter | |
break | |
elseif inspectName():find("fridge") then --found fridge | |
turtle.turnRight() --face "right" | |
break | |
elseif inspectName():find("computer") then | |
turtle.turnLeft() | |
break | |
end | |
turtle.turnLeft() | |
end | |
while turtle.forward() do end --move to window by computer | |
turtle.turnRight() | |
turtle.forward() | |
turtle.down() | |
end | |
curLoc = 0 | |
counter = "front" | |
end | |
function unHome() | |
turtle.turnRight() | |
counter = "left" | |
turtle.turnRight() | |
counter = "rear" | |
turtle.up() | |
turtle.forward() | |
curLoc = 1 | |
end | |
function fuelCheck() | |
if turtle.getFuelLevel() < 30 then | |
rednet.send(controlComputer,"lowfuel") | |
print("Insert Fuel") | |
while turtle.getFuelLevel() < 30 do | |
os.sleep(3) | |
turtle.select(1) | |
turtle.refuel() | |
end | |
rednet.send(controlComputer,"served") --reset the order screen to the default | |
end | |
end | |
function faceLeft() | |
if counter == "front" then | |
turtle.turnRight() | |
elseif counter == "rear" then | |
turtle.turnLeft() | |
elseif counter == "right" then | |
turtle.turnRight() turtle.turnRight() | |
end | |
counter = "left" | |
end | |
function faceRight() | |
if counter == "front" then | |
turtle.turnLeft() | |
elseif counter == "rear" then | |
turtle.turnRight() | |
elseif counter == "left" then | |
turtle.turnLeft() turtle.turnLeft() | |
end | |
counter = "right" | |
end | |
function faceWork() | |
if counter == "front" then | |
turtle.turnRight() turtle.turnRight() | |
elseif counter == "right" then | |
turtle.turnLeft() | |
elseif counter == "left" then | |
turtle.turnRight() | |
end | |
counter = "rear" | |
end | |
function faceCounter() | |
if counter == "rear" then | |
turtle.turnRight() turtle.turnRight() | |
elseif counter == "left" then | |
turtle.turnLeft() | |
elseif counter == "right" then | |
turtle.turnRight() | |
end | |
counter = "front" | |
end | |
function goTo(destination) | |
-- If we're in the home location, unhome before moving left to right | |
if curLoc == 0 then | |
unHome() | |
curLoc = 1 | |
end | |
distance = curLoc - destination | |
if destination > curLoc then | |
faceLeft() | |
for i=1,math.abs(distance) do | |
turtle.forward() | |
end | |
elseif destination < curLoc then | |
faceRight() | |
for i=1,math.abs(distance) do | |
turtle.forward() | |
end | |
end | |
curLoc = destination | |
end | |
function getIngredient(item) | |
if item == nil then | |
--no item requested | |
return 0 | |
end | |
print("looking for "..item) | |
fridge = peripheral.wrap("front") | |
size = fridge.size() | |
for i=1,size do | |
if fridge.getItemDetail(i) ~= nil then | |
if fridge.getItemDetail(i).displayName:lower():find(item) then | |
--print("Found "..item.." in slot "..i) | |
fridge.pushItems("front",1,64,size) --move item 1 to last slot | |
fridge.pushItems("front",i,64,1) --move found item to slot 1 | |
fridge.pushItems("front",size,64,i) --move item in last slot to original slot for found item | |
turtle.suck(1) | |
return 1 --found the item and grabbed it, stop looking | |
end | |
end | |
end | |
end | |
function gatherIngredients(recipe) | |
--table to use for shorter searching of the 2nd fridge if necessary | |
local recipeCopy = copyTable(recipe) | |
turtle.select(1) | |
itemsFound = 1 --starting at 1 to skip workstation keyword in the count | |
-- fridge 1 | |
goTo(fridge1) | |
faceWork() | |
for i = 2,#recipe do | |
if getIngredient(recipe[i]) then | |
itemsFound = itemsFound + 1 | |
recipeCopy[i] = nil --clear this item from the 2nd fridge ingredient list | |
end | |
end | |
-- fridge 2 | |
if itemsFound < #recipe then | |
goTo(fridge2) | |
faceWork() | |
for i = 2,#recipeCopy do | |
getIngredient(recipeCopy[i]) | |
end | |
end | |
end | |
function potCooking(recipe) | |
--get dish | |
goTo(shelf) | |
faceWork() | |
turtle.select(16) --dish in slot 16 | |
getIngredient("bowl") | |
--fill pot | |
goTo(pot) | |
faceWork() | |
turtle.drop() --add dish from 16 | |
turtle.select(1) | |
turtle.up() | |
turtle.forward() | |
for i=1,#recipe do | |
turtle.select(i) | |
turtle.dropDown() | |
end | |
--get food | |
turtle.back() | |
turtle.down() | |
turtle.select(1) | |
repeat until(turtle.suck()) | |
end | |
function kettleCooking() | |
--get dish | |
goTo(shelf) | |
faceWork() | |
turtle.select(16) --dish to slot 16 | |
getIngredient("bottle") | |
--fill kettle | |
goTo(kettle) | |
faceWork() | |
turtle.drop() --add bottle from 16 | |
turtle.select(1) | |
turtle.up() | |
turtle.forward() | |
turtle.dropDown() | |
k = peripheral.wrap("bottom") | |
k.pushItems("bottom",1,1,2) --1 item in first slot of kettle to 2nd slot | |
turtle.select(2) --2nd ingredient if a 2 item recipe | |
turtle.dropDown() | |
--get food | |
turtle.back() | |
turtle.down() | |
turtle.select(1) | |
repeat until(turtle.suck()) | |
end | |
function useSpout(ordered) | |
turtle.select(1) | |
turtle.down() | |
turtle.drop() | |
d = peripheral.wrap("front") | |
repeat until(d.getItemDetail(1).displayName:find(ordered)) | |
turtle.suck() | |
turtle.up() | |
end | |
function milkSpout(ordered) | |
goTo(milk) | |
faceWork() | |
useSpout(ordered) | |
end | |
function cocoaSpout(ordered) | |
--get dish | |
goTo(shelf) | |
faceWork() | |
turtle.select(1) --dish to slot 1 | |
getIngredient("bottle") | |
goTo(cocoa) | |
faceWork() | |
useSpout(ordered) | |
end | |
function sortAndCraft(count) | |
grid = {16,15,14,12,11,10,8,7,6} | |
g = 1 | |
for s=count,1,-1 do | |
turtle.select(s) | |
for i=1,turtle.getItemCount(s) do | |
turtle.transferTo(grid[g],1) | |
g = g + 1 | |
end | |
end | |
turtle.select(1) | |
turtle.craft() | |
end | |
function craftSushi() | |
--find which slots the rice and fish are in | |
riceSlot = 0 | |
fishSlot = 0 | |
for i=1,4 do | |
if turtle.getItemCount(i) > 0 then | |
if turtle.getItemDetail(i).name:find("rice") then | |
riceSlot = i | |
elseif turtle.getItemDetail(i).name:find("salmon") then | |
fishSlot = i | |
end | |
end | |
end | |
--get the rice into slot 1 | |
turtle.select(fishSlot) | |
turtle.transferTo(8) | |
fishSlot = 8 | |
turtle.select(riceSlot) | |
turtle.transferTo(1) | |
-- cook the rice in slot 1 | |
potCooking({"rice"}) | |
-- move the fish back to slot 2 | |
turtle.select(fishSlot) | |
turtle.transferTo(2) | |
--make the sushi | |
sortAndCraft(4) | |
--find the bowl | |
for i=1,16 do | |
if turtle.getItemCount(i) > 0 then | |
if turtle.getItemDetail(i).name:find("bowl") then | |
turtle.select(i) | |
break | |
end | |
end | |
end | |
--store the bowl | |
goTo(shelf) | |
faceWork() | |
turtle.drop() | |
end | |
function craftCake() | |
--BUG: not very resiliant due to being a shaped crafting recipe, should search and sort by name in the turtle to make better. | |
-- free up slot 1 | |
for i = 9,1,-1 do | |
turtle.select(i) | |
turtle.transferTo(i+1) | |
end | |
--get 3 bottles | |
goTo(shelf) | |
faceWork() | |
turtle.select(1) | |
for i = 1,3 do | |
getIngredient("bottle") | |
end | |
--fill bottles | |
milkSpout("Milk") | |
--split sugar | |
turtle.select(4) turtle.transferTo(5) | |
turtle.select(2) turtle.transferTo(4,1) | |
--craft the cake | |
sortAndCraft(9) | |
--find and store the empty bottles | |
goTo(shelf) | |
faceWork() | |
for i=1,16 do | |
if turtle.getItemCount(i) > 0 then | |
if turtle.getItemDetail(i).name:find("bottle") then | |
turtle.select(i) | |
turtle.drop() | |
end | |
end | |
end | |
end | |
function serveFood() | |
goTo(serve) | |
faceCounter() | |
turtle.select(1) --test with crafty turtle, may need to use another slot or search | |
turtle.drop() | |
end | |
function cook(ordered) | |
rednet.send(controlComputer,"cooking") | |
--clear terminal before showing crafting status | |
term.clear() | |
term.setCursorPos(1,1) | |
-- load recipe | |
recipe = menu[ordered] | |
workstation = recipe[1] | |
gatherIngredients(recipe) | |
if workstation == "none" then | |
--no workstation or crafting, just serve | |
elseif workstation == "milk" then | |
milkSpout(ordered) | |
elseif workstation == "cocoa" then | |
cocoaSpout(ordered) | |
elseif workstation == "pot" then | |
potCooking(recipe) | |
elseif workstation == "kettle" then | |
kettleCooking() | |
elseif workstation == "crafting" then | |
sortAndCraft(#recipe) | |
elseif workstation == "special" then | |
if ordered == "Sushi" then | |
craftSushi() | |
elseif ordered == "Cake" then | |
craftCake() | |
end | |
end | |
serveFood() | |
rednet.send(controlComputer,"served") | |
-- check fuel after each craft | |
fuelCheck() | |
end | |
--Check fuel and go home on startup before doing anything else | |
fuelCheck() | |
home() | |
--multicraft | |
function multicraft(ordered,qty) | |
for i = 1,qty do | |
cook(ordered) | |
end | |
end | |
--launch args override | |
if (arg1 ~= nil) and (arg1 ~= "update") then | |
if (arg2 ~= nil) then | |
for i=1,arg2 do | |
cook(arg1) | |
end | |
else | |
cook(arg1) | |
end | |
end | |
while true do | |
local evt,sid,msg,proto = os.pullEvent() | |
if evt == "rednet_message" then | |
if sid == controlComputer then | |
if type(msg) == "string" then | |
print("Order for: "..msg) | |
cook(msg) | |
elseif type(msg) == "table" then | |
print("Order for: "..msg[1].." x"..msg[2]) | |
multicraft(msg[1],msg[2]) | |
end | |
end | |
elseif evt == "timer" then | |
os.startTimer(30) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment