Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local retMsg = "" -- Used to elaborate things when returning booleans from functions
- local numFilters = 0 -- Number of filter slots
- local invNumBlocksByType = {} -- Number of blocks in our inventory, grouped by block type
- local invNumBlocksByTypeInStack = {} -- Number of blocks in our inventory in the currently filling slot, grouped by block type
- local invNumBlocksTotal = 0 -- Total number of blocks in our inventory
- local invNumEmptySlots = 0 -- Number of empty slots in our inventory
- local itemDrops = {} -- Does the block drop itself or something else, or multiple types ["unknown"|"self"|"other"|"multiple"]
- local dropCount = {} -- Number of items dropped per block
- -- Initialize the inventory related tables
- function initInventory()
- local num = 0
- local firstEmpty = 0
- local currentFilter = 0
- local didStack = false
- local stackedWith = 0
- invNumBlocksTotal = 0
- -- FIXME TODO: check for auto-refuel enabled
- local lastSlot = 16
- -- Note: We don't touch the last slot if we are using the auto-refuel feature
- for i = 1, lastSlot do
- num = turtle.getItemCount(i)
- -- Items in the current slot
- if num > 0 then
- -- Sort the filter items starting from slot 1 so that there are no empty slots in between.
- -- First, check if the current slot can be stacked with a previous one
- turtle.select(i)
- for k = 1, i - 1 do
- -- The current slot's item matches a previous slot
- if turtle.compareTo(k) == true then
- -- Stack the items, but only if they all fit into the previous slot
- if turtle.getItemSpace(k) >= num then
- turtle.transferTo(k, num)
- didStack = true
- stackedWith = k
- -- FIXME if the items do not fit into one slot, then a second
- -- duplicate filter is created
- end
- break
- end
- end
- -- The current slot contains a unique item, it did not match any of the previous filters
- if didStack == false then
- -- There have been empty slots before, but the current slot is not empty
- if firstEmpty > 0 then
- -- turtle.select(i)
- turtle.transferTo(firstEmpty, num)
- local j = firstEmpty + 1
- firstEmpty = 0
- for j = j, i do
- if turtle.getItemCount(j) == 0 then
- firstEmpty = j
- break
- end
- end
- end
- -- Initialize and calculate the inventory/filtering related things
- currentFilter = currentFilter + 1
- invNumBlocksByType[currentFilter] = num
- invNumBlocksByTypeInStack[currentFilter] = num
- invNumBlocksTotal = invNumBlocksTotal + num
- itemDrops[currentFilter] = "unknown"
- dropCount[currentFilter] = -1
- else -- didStack
- -- Update the inventory/filtering related things since we moved some items
- invNumBlocksByType[stackedWith] = invNumBlocksByType[stackedWith] + num
- invNumBlocksByTypeInStack[stackedWith] = invNumBlocksByTypeInStack[stackedWith] + num
- invNumBlocksTotal = invNumBlocksTotal + num
- end
- didStack = false
- elseif firstEmpty == 0 then
- firstEmpty = i
- end
- end
- numFilters = currentFilter
- invNumEmptySlots = 16 - numFilters
- return true
- end
- -- Get the block type for the block we are about to dig
- -- (block type == filter number, or 0 for unknown/forbidden)
- function getBlockType(side)
- local func = turtle.compare
- local filtNum = 0 -- Initialise to invalid filter (= no match)
- if side == nil then
- elseif side == "up" then
- func = turtle.compareUp
- elseif side == "down" then
- func = turtle.compareDown
- end
- -- Compare the block to all of the filters, until we get a match
- for i = 1, numFilters do
- turtle.select(i)
- if func() == true then
- -- TODO add the block type to a table
- filtNum = i
- break
- end
- end
- -- turtle.select(1) -- Move the selection back to the first slot
- -- TODO add the block type to a table
- return filtNum
- end
- -- Identify the block properties (ie. what does it drop, and how many)
- function identifyBlockDrops(side, blockType)
- local invBefore = {}
- local invAfter = {}
- local changedSlots = {}
- local numChangedSlots = 0
- local num = 0
- local dig = turtle.dig
- if side == nil then
- elseif side == "up" then
- dig = turtle.digUp
- elseif side == "down" then
- dig = turtle.digDown
- end
- -- FIXME temporary easy solution. Are there (relevant) blocks that drop more than 2 item types?
- if invNumEmptySlots >= 2 then
- local lastSlot = 16
- for i = 1, lastSlot do
- invBefore[i] = turtle.getItemCount(i)
- end
- turtle.select(1)
- -- turtle.select(blockType)
- if dig() == false then
- retMsg = "couldNotDig"
- return false
- end
- for i = 1, lastSlot do
- num = turtle.getItemCount(i)
- invAfter[i] = num
- if num ~= invBefore[i] then
- changedSlots[numChangedSlots] = i
- numChangedSlots = numChangedSlots + 1
- end
- end
- -- Only one slot changed
- if numChangedSlots == 1 then
- -- The changed slot was the filter itself
- if changedSlots[0] == blockType then
- -- It dropped a single item
- if (invAfter[blockType] - invBefore[blockType]) == 1 then
- itemDrops[blockType] = "selfSingle"
- else -- It dropped multiple items (no such block exists, right???)
- itemDrops[blockType] = "selfMultiple"
- end
- else -- The block did not drop itself
- -- It dropped a single item
- if (invAfter[changedSlots[0]] - invBefore[changedSlots[0]]) == 1 then
- itemDrops[blockType] = "otherSingle"
- else -- It dropped multiple items
- itemDrops[blockType] = "otherMultiple"
- end
- end
- else -- More than one slot changed
- for i = 0, numChangedSlots - 1 do
- if (invAfter[changedSlots[i]] - invBefore[changedSlots[i]]) > 1 then
- itemDrops[blockType] = "multipleMultiple"
- return true
- end
- end
- itemDrops[blockType] = "multipleSingle"
- -- FIXME quick hax version
- -- if (invAfter[changedSlots[0]] - invBefore[changedSlots[0]]) == 1
- -- and (invAfter[changedSlots[1]] - invBefore[changedSlots[1]]) == 1 then
- -- itemDrops[blockType] = "multipleSingle"
- -- else
- -- itemDrops[blockType] = "multipleMultiple"
- -- end
- end
- return true
- end
- retMsg = "insufficientSpaceForIdentification"
- return false
- end
- -- Check if we are allowed to dig the block
- function canDig(side)
- local blockType = getBlockType(side)
- -- Matching filter found: allowed to dig, if we have space in the inventory
- if blockType > 0 then
- -- Unidentified block type, try to find out what it drops
- if itemDrops[blockType] == "unknown" then
- if identifyBlockDrops(side, blockType) == false then
- return false
- end
- end
- -- Already identified block, check if we have space
- -- FIXME temporary easy solution. Are there (relevant) blocks that drop more than 2 item types?
- if invNumEmptySlots >= 2 then
- return true
- elseif invNumEmptySlots >= 1 and (itemDrops[blockType] == "self" or itemDrops[blockType] == "other") then
- return true
- end
- end
- retMsg = "notAllowed"
- return false
- end
- initInventory()
- print("numFilters: " .. numFilters)
- print("invNumBlocksTotal: " .. invNumBlocksTotal)
- print("invNumEmptySlots: " .. invNumEmptySlots)
- --print("invNumBlocksByType: ")
- --for key, value in pairs (invNumBlocksByType) do
- -- print("invNumBlocksByType[" .. tostring(key) .. "]: " .. tostring(value))
- --end
- --print("invNumBlocksByTypeInStack: ")
- --for key, value in pairs (invNumBlocksByTypeInStack) do
- -- print("invNumBlocksByTypeInStack[" .. tostring(key) .. "]: " .. tostring(value))
- --end
- --print("itemDrops: ")
- for key, value in pairs (itemDrops) do
- print("itemDrops[" .. tostring(key) .. "]: " .. tostring(value))
- end
- --print("dropCount: ")
- --for key, value in pairs (dropCount) do
- -- print("dropCount[" .. tostring(key) .. "]: " .. tostring(value))
- --end
- local blockType = getBlockType("front")
- print("getBlockType(): " .. tostring(blockType))
- --local ret = identifyBlockDrops("front", blockType)
- --print("identifyBlockDrops(): " .. tostring(ret))
- --print("retMsg: " .. retMsg)
- ret = canDig("front")
- print("canDig(): " .. tostring(ret))
- print("retMsg: " .. retMsg)
- for key, value in pairs (itemDrops) do
- print("itemDrops[" .. tostring(key) .. "]: " .. tostring(value))
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement