Last active
July 13, 2021 06:36
-
-
Save BryanHaley/1d2d9f3fca18607cf4dd80480eb63780 to your computer and use it in GitHub Desktop.
COMPUTERCRAFT: Point of sale machine for potato vending machine
This file contains 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
-- Globals | |
STATES = {} | |
CURRENT_STATE = nil | |
NUM_SLOTS = 16 | |
PRICES = { | |
["minecraft:coal"] = 1, | |
["minecraft:iron_ingot"] = 6, | |
["minecraft:diamond"] = 45, | |
["minecraft:netherite_ingot"] = 100, | |
["minecraft:bone_meal"] = 2, | |
["minecraft:arrow"] = 4 | |
} | |
-- Utils | |
function succ() | |
for i = 1, NUM_SLOTS, 1 do | |
turtle.suck() | |
end | |
end | |
function empty_inventory() | |
for i = 1, NUM_SLOTS, 1 do | |
turtle.select(i) | |
turtle.drop() | |
end | |
end | |
-- State machine | |
function sm_switch_states(new_state, args) | |
if (CURRENT_STATE ~= nil) then | |
CURRENT_STATE:exit() | |
end | |
CURRENT_STATE = new_state | |
CURRENT_STATE:enter(args) | |
end | |
-- States | |
-- Idle: Waits for someone to throw it items | |
IDLE_STATE = {} | |
function IDLE_STATE:enter(args) | |
empty_inventory() | |
end | |
function IDLE_STATE:execute() | |
-- Succ then check inventory for changes. Can't use event because it is blocking. | |
succ() | |
for i = 1, NUM_SLOTS, 1 do | |
local x = turtle.getItemDetail(i) | |
if (x ~= nil) then | |
sm_switch_states(STATES['exchange'], nil); | |
return | |
end | |
end | |
os.sleep(0.25) | |
end | |
function IDLE_STATE:exit() | |
-- Do nothing | |
end | |
-- Exchange: Calculates the value of items in inventory and drops them into store chest | |
EXCHANGE_STATE = {} | |
function EXCHANGE_STATE:enter(args) | |
-- Do nothing | |
end | |
function EXCHANGE_STATE:execute() | |
-- Go through inventory and calculate value | |
local value = 0 | |
for i = 1, NUM_SLOTS, 1 do | |
x = turtle.getItemDetail(i) | |
if (x ~= nil) then | |
if PRICES[x["name"]] ~= nil then | |
value = value + (x['count'] * PRICES[x["name"]]) | |
turtle.dropDown() | |
else | |
turtle.drop() | |
end | |
end | |
end | |
if (value > 0) then | |
sm_switch_states(STATES['dispense'], value) | |
return | |
else | |
sm_switch_states(STATES['idle'], nil) | |
return | |
end | |
end | |
function EXCHANGE_STATE:exit() | |
-- Make sure inventory is empty | |
empty_inventory() | |
end | |
-- Dispense: Grab potatoes from the chest and dispense them | |
DISPENSE_STATE = { num_potatoes = 0 } | |
function DISPENSE_STATE:enter(args) | |
if (args == 0 or not args) then | |
sm_switch_states(STATES['idle'], nil) | |
return | |
end | |
DISPENSE_STATE.num_potatoes = args | |
end | |
function DISPENSE_STATE:execute() | |
while (DISPENSE_STATE.num_potatoes > 0) do | |
local num_thrown = DISPENSE_STATE:grab_and_throw(DISPENSE_STATE.num_potatoes) | |
DISPENSE_STATE.num_potatoes = DISPENSE_STATE.num_potatoes - num_thrown | |
end | |
sm_switch_states(STATES['idle'], nil) | |
return | |
end | |
function DISPENSE_STATE:grab_and_throw(num_to_grab) | |
turtle.turnRight() | |
turtle.turnRight() | |
for i = 1, math.floor(num_to_grab/64), 1 do | |
success = turtle.suck(64) | |
if not success then break end | |
end | |
turtle.suck(num_to_grab%64) | |
-- Check how many potatoes we're actually going to throw | |
local num_thrown = 0 | |
for i = 1, NUM_SLOTS, 1 do | |
x = turtle.getItemCount(i) | |
num_thrown = num_thrown + x | |
end | |
turtle.turnLeft() | |
turtle.turnLeft() | |
empty_inventory() | |
return num_thrown | |
end | |
function DISPENSE_STATE:exit() | |
-- Make sure inventory is empty | |
empty_inventory() | |
end | |
-- Main thread | |
STATES['idle'] = IDLE_STATE | |
STATES['exchange'] = EXCHANGE_STATE | |
STATES['dispense'] = DISPENSE_STATE | |
sm_switch_states(STATES['idle'], nil) | |
while (true) do | |
CURRENT_STATE:execute() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment