Advertisement
hevohevo

ComputerCraft Tutorial: Turtle165 API

Jan 31st, 2015
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.52 KB | None | 0 0
  1. -- #############################################################
  2. -- Turtle165 API
  3.  
  4. -- Turtle API for ComputerCraft 1.65 or over
  5. --     required function: "turtle.getItemDetail()"
  6.  
  7. -- (c) 2015 hevohevo, License: MIT
  8. -- twitter: @hevohevo, http://hevohevo.hatenablog.com/
  9.  
  10.  
  11. -- ##############################################################
  12. -- API List
  13.  
  14. -- Turtle165.sortInventory()
  15. --        インベントリ内のアイテムを整理し並べ替える
  16. -- Turtle165.collectItem()
  17. --        インベントリ内のアイテムをまとめる
  18. -- Turtle165.getItemCountAll(item_name_str, [damage])
  19. --        インベントリ内のアイテム(名前・ダメージ値指定)の総数を返す
  20. -- Turtle165.selectItem(item_name_str, [damage])
  21. --        アイテム(名前・ダメージ値指定)があるスロットを選択する
  22. -- Turtle165.getEmptySlot()
  23. --        空のスロット番号を返す
  24. -- Turtle165.selectEmptySlot()
  25. --        空のスロットを選択する
  26. -- Turtle165.changeItems(slot0, slot1, tmp_slot)
  27. --        slot0とslot1のアイテムを入れ替える。なおtmp_slotは入れ替えるときの一時アイテム置き場。必須。
  28. -- ##############################################################
  29.  
  30.  
  31.  
  32. -- インベントリ内にバラバラに入っているアイテムをできるだけまとめる
  33. -- turtle.transferTo(slot [, quantity]), 1/27作
  34. function collectItem()
  35.   local selected_slot = turtle.getSelectedSlot()
  36.   for i=1,16 do
  37.     local detail = turtle.getItemDetail(i)
  38.     if detail then -- スロットになにかアイテムある
  39.       for j=i,16 do
  40.         local detail2 = turtle.getItemDetail(j)
  41.         if detail2 and detail["name"]==detail2["name"] and detail["damage"]==detail2["damage"] then
  42.           turtle.select(j)
  43.           turtle.transferTo(i)
  44.         end
  45.       end
  46.     else -- スロットにアイテムない
  47.     end
  48.   end
  49.   turtle.select(selected_slot)
  50. end
  51.  
  52.  
  53. -- turtle.getItemCounrt(slot_num) , 1/27作
  54. -- 発展→ getItemCountAll(item_name, damage) => アイテム総数
  55. function getItemCountAll(item_name, damage)
  56.   local count = 0
  57.   for i=1,16 do
  58.     local detail = turtle.getItemDetail(i)
  59.     if detail then  -- スロットになにかアイテムある
  60.       if string.match(detail["name"],item_name) then  -- アイテム名がマッチする
  61.         if damage == nil or damage==detail["damage"] then  -- ダメージ値の指定があり、それが一致する
  62.           count = count + detail["count"]
  63.         end
  64.       else  -- アイテム名がマッチしない
  65.       end
  66.     else  -- スロットにアイテムない
  67.     end
  68.   end
  69.   return count
  70. end
  71.  
  72. -- selectItem(name, damage) , 1/26作
  73. -- スロット内を探し、name(damage値指定があるときはそれも)とマッチするアイテムを選択する。
  74. function selectItem(name,damage)
  75.   -- local selected_slot = turtle.getSelectedSlot()
  76.  
  77.   for i=1,16 do
  78.     local item = turtle.getItemDetail(i)
  79.     if type(item)=="table" then -- スロットに何かアイテム
  80.       -- print("slot=",i," ",item["name"]," ",item["damage"])
  81.       if string.match(item["name"],name) then -- 指定アイテムの名前と一致
  82.         if damage==nil or damage == item["damage"] then -- ダメージ値指定がない、または指定と一致
  83.           turtle.select(i)
  84.           return true, item["count"]
  85.         else -- 名前は一致したがダメージ値が違う
  86.           -- do nothing
  87.         end
  88.       else -- 指定アイテムの名前と不一致
  89.         -- do nothing
  90.       end
  91.     else -- スロット内にアイテムなし
  92.       -- do nothing
  93.     end
  94.   end
  95.   -- turtle.select(selected_slot)
  96.   return false, "No item to match"
  97. end
  98.  
  99. -- スロット番号の小さいほうから探し、空っぽのスロットを選択する。
  100. function selectEmptySlot()
  101.   for i=1, 16 do
  102.     local item = turtle.getItemDetail(i)
  103.     if item == nil then
  104.       turtle.select(i)
  105.       return true
  106.     end
  107.   end
  108.   return false
  109. end
  110.  
  111. -- スロット番号の小さいほうから探し、空っぽのスロット番号を返す
  112. function getEmptySlot()
  113.   for i=1, 16 do
  114.     if turtle.getItemCount(i) == 0 then
  115.       return i
  116.     end
  117.   end
  118.   return false
  119. end
  120.  
  121. -- slot0とslot1のアイテムを入れ替える。tmp_slotは入れ替え時に用いる一時アイテム置き場
  122. function changeItems(slot0, slot1, tmp_slot)
  123.   if slot0 == slot1 then return end -- slot0とslot1が同じならすぐ終了
  124.   if turtle.getItemCount(tmp_slot)>0 then return false, "tmp_slot must be empty." end
  125.   if turtle.getItemCount(slot1)>0 then -- 移動先slot1が埋まっている
  126.     if turtle.getItemCount(slot0)>0 then -- 移動先slot0も埋まっているので、一時置き場を使おう
  127.       turtle.select(slot1)
  128.       turtle.transferTo(tmp_slot) -- slot1のアイテムを退避
  129.       turtle.select(slot0)
  130.       turtle.transferTo(slot1) -- slot0のアイテムをslot1に移動
  131.       turtle.select(tmp_slot)
  132.       turtle.transferTo(slot0) -- 退避スロットのアイテムをslot1に移動
  133.     else -- 移動先slot0があいているので slot1からslot0へ移動させよう
  134.       turtle.select(slot1)
  135.       turtle.transferTo(slot0)
  136.     end
  137.   else
  138.     turtle.select(slot0)
  139.     turtle.transferTo(slot1) -- slot0のアイテムをslot1に移動
  140.   end
  141. end
  142.  
  143.  
  144. -- table.sort()で用いる比較関数の定義。名前順でダメージ値の順。
  145. --   _compare({name="minecraft:dirt", damage=0}, {name="minecraft:wool", damage=1})
  146. --     => true   (名前のアルファベット順で左の方が前だから)
  147. --   _compare({name="minecraft:wool", damage=3}, {name="minecraft:wool", damage=1})
  148. --     => false   (名前は同じだがダメージ値が後の方が小さいので)
  149. local function _compare(detail0, detail1)
  150.   -- 引数がおかしいとエラー終了
  151.   assert(detail0 and detail1 and detail0["name"] and detail1["name"] and detail0["damage"] and detail1["damage"])
  152.  
  153.   if detail0["name"] < detail1["name"] then
  154.     return true -- detail0が名前順で前ならばtrue
  155.   elseif detail0["name"] == detail1["name"] then
  156.     -- detail0の名前が同じならばdamage値が小さければtrue
  157.     return detail0["damage"] <= detail1["damage"]
  158.   else
  159.     return false -- detail0が名前順で後ろならばfalse
  160.   end
  161.    
  162. end
  163.  
  164. -- ###################################################################
  165. function sortInventory()
  166.   local tmp_slot = 16
  167.   collectItem() -- まずは整理しようね。
  168.  
  169.   -- スロット16(tmp_slot)があいてない場合はエラー返して終了するよ
  170.   if turtle.getItemCount(tmp_slot) > 0 then
  171.     local empty_slot = getEmptySlot()
  172.     if empty_slot == false then -- 空ける場所もないのでfalse終了
  173.       return false, "Slot "..tmp_slot.." must be empty."
  174.     else
  175.       turtle.select(tmp_slot)
  176.       turtle.transferTo(empty_slot)
  177.       collectItem()
  178.     end
  179.   end
  180.  
  181.   -- インベントリアイテムの情報を収集するよ
  182.   local items = {}
  183.   for i=1,15 do
  184.     local item = turtle.getItemDetail(i)
  185.     if item then -- スロットにアイテムあります。
  186.       table.insert(items, item)
  187.     else
  188.       -- スロットは空です。
  189.     end
  190.   end
  191.   table.sort(items, _compare) -- 文字列順にソートじゃい。比較用関数は自分で作ったの使っています。
  192.  
  193.   for i,_item in ipairs(items) do
  194.     selectItem(_item["name"], _item["damage"])
  195.     local slot0 = turtle.getSelectedSlot()
  196.     print(slot0..'->'..i)
  197.     changeItems(slot0, i, tmp_slot)
  198.   end
  199. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement