Advertisement
masa-

CC Turtle Devel: identifyBlockDrops v1

Apr 12th, 2013
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.08 KB | None | 0 0
  1. local retMsg = ""               -- Used to elaborate things when returning booleans from functions
  2. local numFilters = 0            -- Number of filter slots
  3. local invNumBlocksByType = {}           -- Number of blocks in our inventory, grouped by block type
  4. local invNumBlocksByTypeInStack = {}    -- Number of blocks in our inventory in the currently filling slot, grouped by block type
  5. local invNumBlocksTotal = 0     -- Total number of blocks in our inventory
  6. local invNumEmptySlots = 0      -- Number of empty slots in our inventory
  7. local itemDrops = {}            -- Does the block drop itself or something else, or multiple types ["unknown"|"self"|"other"|"multiple"]
  8. local dropCount = {}            -- Number of items dropped per block
  9.  
  10.  
  11. -- Initialize the inventory related tables
  12. function initInventory()
  13.     local num = 0
  14.     local firstEmpty = 0
  15.     local currentFilter = 0
  16.     local didStack = false
  17.     local stackedWith = 0
  18.     invNumBlocksTotal = 0
  19.  
  20.     -- FIXME TODO: check for auto-refuel enabled
  21.     local lastSlot = 16
  22.     -- Note: We don't touch the last slot if we are using the auto-refuel feature
  23.     for i = 1, lastSlot do
  24.         num = turtle.getItemCount(i)
  25.  
  26.         -- Items in the current slot
  27.         if num > 0 then
  28.             -- Sort the filter items starting from slot 1 so that there are no empty slots in between.
  29.  
  30.             -- First, check if the current slot can be stacked with a previous one
  31.             turtle.select(i)
  32.             for k = 1, i - 1 do
  33.                 -- The current slot's item matches a previous slot
  34.                 if turtle.compareTo(k) == true then
  35.                     -- Stack the items, but only if they all fit into the previous slot
  36.                     if turtle.getItemSpace(k) >= num then
  37.                         turtle.transferTo(k, num)
  38.                         didStack = true
  39.                         stackedWith = k
  40.                         -- FIXME if the items do not fit into one slot, then a second
  41.                         -- duplicate filter is created
  42.                     end
  43.                     break
  44.                 end
  45.             end
  46.  
  47.             -- The current slot contains a unique item, it did not match any of the previous filters
  48.             if didStack == false then
  49.                 -- There have been empty slots before, but the current slot is not empty
  50.                 if firstEmpty > 0 then
  51. --                  turtle.select(i)
  52.                     turtle.transferTo(firstEmpty, num)
  53.                     local j = firstEmpty + 1
  54.                     firstEmpty = 0
  55.                     for j = j, i do
  56.                         if turtle.getItemCount(j) == 0 then
  57.                             firstEmpty = j
  58.                             break
  59.                         end
  60.                     end
  61.                 end
  62.                 -- Initialize and calculate the inventory/filtering related things
  63.                 currentFilter = currentFilter + 1
  64.                 invNumBlocksByType[currentFilter] = num
  65.                 invNumBlocksByTypeInStack[currentFilter] = num
  66.                 invNumBlocksTotal = invNumBlocksTotal + num
  67.                 itemDrops[currentFilter] = "unknown"
  68.                 dropCount[currentFilter] = -1
  69.             else -- didStack
  70.                 -- Update the inventory/filtering related things since we moved some items
  71.                 invNumBlocksByType[stackedWith] = invNumBlocksByType[stackedWith] + num
  72.                 invNumBlocksByTypeInStack[stackedWith] = invNumBlocksByTypeInStack[stackedWith] + num
  73.                 invNumBlocksTotal = invNumBlocksTotal + num
  74.             end
  75.  
  76.             didStack = false
  77.         elseif firstEmpty == 0 then
  78.             firstEmpty = i
  79.         end
  80.     end
  81.  
  82.     numFilters = currentFilter
  83.     invNumEmptySlots = 16 - numFilters
  84.  
  85.     return true
  86. end
  87.  
  88.  
  89. -- Get the block type for the block we are about to dig
  90. -- (block type == filter number, or 0 for unknown/forbidden)
  91. function getBlockType(side)
  92.     local func = turtle.compare
  93.     local filtNum = 0 -- Initialise to invalid filter (= no match)
  94.  
  95.     if side == nil then
  96.     elseif side == "up" then
  97.         func = turtle.compareUp
  98.     elseif side == "down" then
  99.         func = turtle.compareDown
  100.     end
  101.  
  102.     -- Compare the block to all of the filters, until we get a match
  103.     for i = 1, numFilters do
  104.         turtle.select(i)
  105.         if func() == true then
  106.             -- TODO add the block type to a table
  107.             filtNum = i
  108.             break
  109.         end
  110.     end
  111.  
  112. --  turtle.select(1) -- Move the selection back to the first slot
  113.     -- TODO add the block type to a table
  114.     return filtNum
  115. end
  116.  
  117.  
  118. -- Identify the block properties (ie. what does it drop, and how many)
  119. function identifyBlockDrops(side, blockType)
  120.     local invBefore = {}
  121.     local invAfter = {}
  122.     local changedSlots = {}
  123.     local numChangedSlots = 0
  124.     local num = 0
  125.     local dig = turtle.dig
  126.  
  127.     if side == nil then
  128.     elseif side == "up" then
  129.         dig = turtle.digUp
  130.     elseif side == "down" then
  131.         dig = turtle.digDown
  132.     end
  133.  
  134.     -- FIXME temporary easy solution. Are there (relevant) blocks that drop more than 2 item types?
  135.     if invNumEmptySlots >= 2 then
  136.         local lastSlot = 16
  137.         for i = 1, lastSlot do
  138.             invBefore[i] = turtle.getItemCount(i)
  139.         end
  140.  
  141.         turtle.select(1)
  142.         -- turtle.select(blockType)
  143.  
  144.         if dig() == false then
  145.             retMsg = "couldNotDig"
  146.             return false
  147.         end
  148.  
  149.         for i = 1, lastSlot do
  150.             num = turtle.getItemCount(i)
  151.             invAfter[i] = num
  152.  
  153.             if num ~= invBefore[i] then
  154.                 changedSlots[numChangedSlots] = i
  155.                 numChangedSlots = numChangedSlots + 1
  156.             end
  157.         end
  158.  
  159.         -- Only one slot changed
  160.         if numChangedSlots == 1 then
  161.             -- The changed slot was the filter itself
  162.             if changedSlots[0] == blockType then
  163.                 -- It dropped a single item
  164.                 if (invAfter[blockType] - invBefore[blockType]) == 1 then
  165.                     itemDrops[blockType] = "selfSingle"
  166.                 else -- It dropped multiple items (no such block exists, right???)
  167.                     itemDrops[blockType] = "selfMultiple"
  168.                 end
  169.             else -- The block did not drop itself
  170.                 -- It dropped a single item
  171.                 if (invAfter[changedSlots[0]] - invBefore[changedSlots[0]]) == 1 then
  172.                     itemDrops[blockType] = "otherSingle"
  173.                 else -- It dropped multiple items
  174.                     itemDrops[blockType] = "otherMultiple"
  175.                 end
  176.             end
  177.         else -- More than one slot changed
  178.             for i = 0, numChangedSlots - 1 do
  179.                 if (invAfter[changedSlots[i]] - invBefore[changedSlots[i]]) > 1 then
  180.                     itemDrops[blockType] = "multipleMultiple"
  181.                     return true
  182.                 end
  183.             end
  184.  
  185.             itemDrops[blockType] = "multipleSingle"
  186.  
  187.             -- FIXME quick hax version
  188. --          if (invAfter[changedSlots[0]] - invBefore[changedSlots[0]]) == 1
  189. --              and (invAfter[changedSlots[1]] - invBefore[changedSlots[1]]) == 1 then
  190. --              itemDrops[blockType] = "multipleSingle"
  191. --          else
  192. --              itemDrops[blockType] = "multipleMultiple"
  193. --          end
  194.         end
  195.  
  196.         return true
  197.     end
  198.  
  199.     retMsg = "insufficientSpaceForIdentification"
  200.     return false
  201. end
  202.  
  203.  
  204. -- Check if we are allowed to dig the block
  205. function canDig(side)
  206.     local blockType = getBlockType(side)
  207.  
  208.     -- Matching filter found: allowed to dig, if we have space in the inventory
  209.     if blockType > 0 then
  210.         -- Unidentified block type, try to find out what it drops
  211.         if itemDrops[blockType] == "unknown" then
  212.             if identifyBlockDrops(side, blockType) == false then
  213.                 return false
  214.             end
  215.         end
  216.  
  217.         -- Already identified block, check if we have space
  218.         -- FIXME temporary easy solution. Are there (relevant) blocks that drop more than 2 item types?
  219.         if invNumEmptySlots >= 2 then
  220.             return true
  221.         elseif invNumEmptySlots >= 1 and (itemDrops[blockType] == "self" or itemDrops[blockType] == "other") then
  222.             return true
  223.         end
  224.     end
  225.  
  226.     retMsg = "notAllowed"
  227.     return false
  228. end
  229.  
  230.  
  231. initInventory()
  232.  
  233. print("numFilters: " .. numFilters)
  234. print("invNumBlocksTotal: " .. invNumBlocksTotal)
  235. print("invNumEmptySlots: " .. invNumEmptySlots)
  236.  
  237. --print("invNumBlocksByType: ")
  238. --for key, value in pairs (invNumBlocksByType) do
  239. --  print("invNumBlocksByType[" .. tostring(key) .. "]: " .. tostring(value))
  240. --end
  241.  
  242. --print("invNumBlocksByTypeInStack: ")
  243. --for key, value in pairs (invNumBlocksByTypeInStack) do
  244. --  print("invNumBlocksByTypeInStack[" .. tostring(key) .. "]: " .. tostring(value))
  245. --end
  246.  
  247. --print("itemDrops: ")
  248. for key, value in pairs (itemDrops) do
  249.     print("itemDrops[" .. tostring(key) .. "]: " .. tostring(value))
  250. end
  251.  
  252. --print("dropCount: ")
  253. --for key, value in pairs (dropCount) do
  254. --  print("dropCount[" .. tostring(key) .. "]: " .. tostring(value))
  255. --end
  256.  
  257. local blockType = getBlockType("front")
  258. print("getBlockType(): " .. tostring(blockType))
  259.  
  260. --local ret = identifyBlockDrops("front", blockType)
  261. --print("identifyBlockDrops(): " .. tostring(ret))
  262. --print("retMsg: " .. retMsg)
  263.  
  264. ret = canDig("front")
  265. print("canDig(): " .. tostring(ret))
  266. print("retMsg: " .. retMsg)
  267.  
  268. for key, value in pairs (itemDrops) do
  269.     print("itemDrops[" .. tostring(key) .. "]: " .. tostring(value))
  270. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement