Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local comp = require("component")
- local transposer = comp.transposer
- local sides = require("sides")
- local interrupted = false
- -- Lists of trades we generate based on the drawers
- local trades = {}
- -- List of transposers connected to the network
- local transposers = {}
- -- Trade controller which is used to define trades and their costs
- local tradeController = comp.inventory_controller
- if tradeController == nil then
- io.stderr:write("ERROR 1: You must attach an Adapter with an inventory controller upgrade in it to assign trades")
- os.exit()
- end
- -- #### CONFIG SECTION ####
- -- The side of the adapter the trade's drawer controller is placed on.
- local tradeControllerSide = sides.up
- -- The sides of the transposer for the storage drawer setup to get bought items
- local storageSide = sides.up
- -- The side of the trash can or inventory to dump items (USE A TRASH CAN)
- local trashCanSide = sides.south
- -- The input chest side.
- local inputChestSide = sides.up
- -- The side to output items
- local outputChestSide = sides.north
- -- #### END OF CONFIG SECTION ####
- -- Get the size of the trade controller we want to make
- local tradeSizes = tradeController.getInventorySize(tradeControllerSide)
- -- Creates a trade table and returns it
- local function createTrade(itemToBuy, purchaseItem)
- local tbl = {}
- tbl.item = itemToBuy
- tbl.cost = purchaseItem
- return tbl
- end
- -- Comapres certain asspects of the 2 items
- local function compareItems(item1, item2)
- local matches = 0
- if item1.name == item2.name then
- matches = matches + 1
- end
- if item1.damage == item2.damage then
- matches = matches + 1
- end
- if item1.maxDamage == item2.maxDamage then
- matches = matches + 1
- end
- if item1.maxSize == item2.maxSize then
- matches = matches + 1
- end
- if item1.label == item2.label then
- matches = matches + 1
- end
- if matches == 5 then
- return true
- else
- return false
- end
- end
- -- Gets the trade for the item we are selling
- local function getTradeForCostItem(costItem)
- for i=1, #trades do
- tradeCostItem = trades[i]["cost"]
- if compareItems(costItem, tradeCostItem) then
- return trades[i]
- end
- end
- return nil
- end
- -- Get's the slot for the item the user is buying. Uses label because
- local function getStorageSlotOfItem(item, storageProxy)
- local maxSlots = storageProxy.getInventorySize(storageSide)
- for slot=1, maxSlots do
- itemStack = storageProxy.getStackInSlot(storageSide, slot)
- if itemStack ~= nil then
- if item.label == itemStack.label then
- return slot
- end
- end
- end
- return nil
- end
- -- Lists all trades.
- local function listTrades()
- print("Available Trades:")
- -- Loop over all trades
- for i=1, #trades do
- purchaseItemName = trades[i]["item"].label
- purchaseItemAmount = trades[i]["item"].size
- costItem = trades[i]["cost"].label
- costItemAmount = trades[i]["cost"].size
- print("Item to buy: " .. purchaseItemName .. " x " .. purchaseItemAmount .. " for: " .. costItem .. " x " .. costItemAmount)
- end
- end
- -- Obtain the addresses of all transposers
- local function initTransposers()
- for address, name in component.list("transposer", true) do
- --print(name .. " at: " .. address)
- table.insert(transposers, component.proxy(address))
- end
- if #transposers ~= 2 then
- io.stderr:write("ERROR 2: You must have exactly two transposers connected to the system")
- os.exit()
- end
- end
- local function getFirstEmptySlot(side, proxy)
- local maxSlots = proxy.getInventorySize(side)
- for slot=1, maxSlots do
- itemStack = proxy.getStackInSlot(side, slot)
- if itemStack == nil then
- return slot
- end
- end
- io.stderr:write("ERROR 3: No empty slot was found for the inventory on side: " .. side)
- end
- local function removeIfAvailable(item, required, userInputProxy)
- local numItems = 0
- local slotsWithItem = {}
- local maxSlots = userInputProxy.getInventorySize(inputChestSide)
- for slot=1, maxSlots do
- itemStack = userInputProxy.getStackInSlot(inputChestSide, slot)
- if itemStack ~= nil then
- if compareItems(item, itemStack) then
- table.insert(slotsWithItem, slot)
- numItems = numItems + itemStack.size
- end
- end
- end
- local removed = 0
- if numItems >= required then
- for i=1, #slotsWithItem do
- slot = slotsWithItem[i]
- itemStack = userInputProxy.getStackInSlot(inputChestSide, slot)
- stackSize = itemStack.size
- -- If the stack contains more than or the right amount of items, remove the required amount and return
- if stackSize >= required then
- userInputProxy.transferItem(inputChestSide, trashCanSide, required, slot, getFirstEmptySlot(trashCanSide, userInputProxy))
- return true
- else
- if removed < required then
- to_remove = required - removed
- if to_remove < stackSize then
- userInputProxy.transferItem(inputChestSide, trashCanSide, to_remove, slot, getFirstEmptySlot(trashCanSide, userInputProxy))
- return true
- elseif to_remove >= stackSize then
- userInputProxy.transferItem(inputChestSide, trashCanSide, stackSize, slot, getFirstEmptySlot(trashCanSide, userInputProxy))
- removed = removed + stackSize
- end
- end
- end
- end
- if removed == required then
- return true
- end
- else
- return false
- end
- end
- local function handleInterrupt()
- interrupted = true
- return false
- end
- -- Loops over items in trade controller to build trades for the shop
- for slot=1, tradeSizes do
- itemStack = tradeController.getStackInSlot(tradeControllerSide, slot)
- if itemStack ~= nil then
- if slot % 2 == 0 then
- itemStack2 = tradeController.getStackInSlot(tradeControllerSide, slot + 1)
- if itemStack2 ~= nil then
- local trade = createTrade(itemStack, itemStack2)
- table.insert(trades, trade)
- end
- end
- end
- end
- initTransposers()
- listTrades()
- local storageProxy
- local userInputProxy
- -- Obtain which transposer is the storage one
- for i=1, #transposers do
- proxy = transposers[i]
- invSize = proxy.getInventorySize(storageSide)
- -- Loop over all slots in the proxy's storage side
- for slot=1, invSize do
- -- Get the item in the current slot
- itemStack = proxy.getStackInSlot(storageSide, slot)
- -- If it's not an empty slot
- if itemStack ~= nil then
- -- Get the size
- size = itemStack.size
- -- If the size is greater than 10000, that likely means it't the provider side of the setup to provide bought items
- if size >= 10000 then
- -- Set the storage proxy and set the user input proxy.
- if i == 1 then
- storageProxy = transposers[1]
- userInputProxy = transposers[2]
- else
- userInputProxy = transposers[1]
- storageProxy = transposers[2]
- end
- break
- end
- end
- end
- end
- event.listen("interrupted", handleInterrupt)
- while interrupted == false do
- local maxSlots = userInputProxy.getInventorySize(inputChestSide)
- for slot=1, maxSlots do
- itemStack = userInputProxy.getStackInSlot(inputChestSide, slot)
- -- If the item is not nil, get the trade for that item
- if itemStack ~= nil then
- trade = getTradeForCostItem(itemStack)
- -- If there is a valid trade, Retrieve the data from the trade and try to get the storage slot of the item on the provider side
- if trade ~= nil then
- buyItem = trade.item
- costItem = trade.cost
- storageSlot = getStorageSlotOfItem(buyItem, storageProxy)
- -- If it finds the item in the storage system. Try to transfer the items if they have enough. If they do, give them the purchase item and break the loop to loop over the chest again.
- if storageSlot ~= nil then
- test = removeIfAvailable(costItem, costItem.size, userInputProxy)
- if test == true then
- storageProxy.transferItem(storageSide, outputChestSide, buyItem.size, storageSlot, getFirstEmptySlot(outputChestSide, storageProxy))
- break
- end
- end
- end
- end
- end
- -- Scan the inventory once a second
- os.sleep(1)
- end
- -- Code that runs at the end of the program after getting interrupted
- print("Exiting trade program...")
- os.sleep(1)
- os.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement