Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- #############################################################
- -- h2turtle API
- -- version 0.2
- -- Turtle API for ComputerCraft 1.65 or over
- -- required function: "turtle.getItemDetail()", "turtle.getItemDetail()"
- -- (c) 2015 hevohevo, License: MIT
- -- twitter: @hevohevo, http://hevohevo.hatenablog.com/
- -- ##############################################################
- -- API List
- -- h2turtle.sortInventory()
- -- インベントリ内のアイテムを整理し並べ替える
- -- h2turtle.collectItem()
- -- インベントリ内のアイテムをまとめる
- -- h2turtle.getItemCountAll(item_name_str, [damage])
- -- インベントリ内のアイテム(名前・ダメージ値指定)の総数を返す
- -- h2turtle.selectItem(item_name_str, [damage])
- -- アイテム(名前・ダメージ値指定)があるスロットを選択する
- -- h2turtle.getEmptySlot()
- -- 空のスロット番号を返す
- -- h2turtle.selectEmptySlot()
- -- 空のスロットを選択する
- -- h2turtle.changeItems(slot0, slot1, tmp_slot)
- -- slot0とslot1のアイテムを入れ替える。なおtmp_slotは入れ替えるときの一時アイテム置き場。必須。
- -- h2turtle.digFor(block_names_tbl) / digUpFor() / digDownFor()
- -- 指定したブロック名(部分一致、複数可)と**マッチした**ブロックだけ採掘
- -- 例:block_names_tbl = {{"dirt",0}, "stone", {"wood",1}}
- -- h2turtle.digExcept(block_names_tbl) / digUpExcept() / digDownExcept()
- -- 指定したブロック名(部分一致、複数可)と**マッチしない**ブロックだけ採掘
- -- h2turtle.isBlock(block_names_tbl) / isUpBlock() / isDownBlock() => true/false, マッチした名前
- -- 隣接ブロックが指定したブロック名とマッチするかどうかを返す
- -- h2turtle.placeItem(item_name, item_damage) / placeUpItem() / placeDownItem()
- -- 指定したアイテム名(部分一致)とマッチしたアイテムを使用(設置)する
- -- h2turtle.waitForEnoughItems(required_qty, item_name, [item_damage])
- -- 指定した個数、指定したアイテム(ダメージ値)がインベントリに入るまで待つ
- -- ## prompt
- -- h2turtle.promptYN(prompt_msg) => true/false
- -- Yes/Noを聞いてくるプロンプト
- -- h2turtle.promptValue(prompt_msg, default_value) => (string)value
- -- 値を入力するよう促してくる、デフォルト値付き
- -- ##############################################################
- -- 上記、ブロック名リストにマッチするかどうかを判定するサブ関数
- function _matchNames(names, block_name, block_meta)
- for i,p in ipairs(names) do
- if type(p)=="table" then
- if string.match(block_name, p[1]) and block_meta == p[2] then
- return true, p
- end
- else
- if string.match(block_name, p) then
- return true, p
- end
- end
- end
- return false, "No block to match"
- end
- function _isBlock(names, inspect_func)
- local status, detail = inspect_func()
- if not status then return false end -- その方向にブロックなかったらfalse
- return _matchNames(names, detail["name"], detail["metadata"])
- end
- function isBlock(names)
- return _isBlock(names, turtle.inspect)
- end
- function isUpBlock(names)
- return _isBlock(names, turtle.inspectUp)
- end
- function isDownBlock(names)
- return _isBlock(names, turtle.inspectDown)
- end
- -- 各種digFor/digExcept関数を作るための元関数
- function _digFor(tbl, inspect_func, dig_func, except_flag)
- if type(tbl) ~= "table" then return dig_func() end
- local status, value = inspect_func()
- print(value["name"])
- if status then
- -- ブロックが存在するとき
- if _matchNames(tbl, value["name"], value["metadata"]) then
- if except_flag then -- 除外フラグtrueならマッチしたときに何もしない
- return false, "Find an exception block"
- else
- return dig_func()
- end
- else
- if except_flag then -- 除外フラグfalseならマッチしたときに採掘
- return dig_func()
- else
- return false, "No block to match"
- end
- end
- else
- -- ブロックが存在しないとき
- return dig_func()
- end
- end
- -- 各方向の関数を定義
- -- digFor/digExcept, digUpFor/digUpExcept, digDownFor/digDownExcept
- function digFor(tbl)
- return _digFor(tbl, turtle.inspect, turtle.dig, false)
- end
- function digExcept(tbl)
- return _digFor(tbl, turtle.inspect, turtle.dig, true)
- end
- function digUpFor(tbl)
- return _digFor(tbl, turtle.inspectUp, turtle.digUp, false)
- end
- function digUpExcept(tbl)
- return _digFor(tbl, turtle.inspectUp, turtle.digUp, true)
- end
- function digDownFor(tbl)
- return _digFor(tbl, turtle.inspectDown, turtle.digDown, false)
- end
- function digDownExcept(tbl)
- return _digFor(tbl, turtle.inspectDown, turtle.digDown, true)
- end
- -- インベントリ内にバラバラに入っているアイテムをできるだけまとめる
- -- turtle.transferTo(slot [, quantity]), 1/27作
- function collectItem()
- local selected_slot = turtle.getSelectedSlot()
- for i=1,16 do
- local detail = turtle.getItemDetail(i)
- if detail then -- スロットになにかアイテムある
- for j=i,16 do
- local detail2 = turtle.getItemDetail(j)
- if detail2 and detail["name"]==detail2["name"] and detail["damage"]==detail2["damage"] then
- turtle.select(j)
- turtle.transferTo(i)
- end
- end
- else -- スロットにアイテムない
- end
- end
- turtle.select(selected_slot)
- end
- -- turtle.getItemCounrt(slot_num) , 1/27作
- -- 発展→ getItemCountAll(item_name, damage) => アイテム総数
- function getItemCountAll(item_name, damage)
- local count = 0
- for i=1,16 do
- local detail = turtle.getItemDetail(i)
- if detail then -- スロットになにかアイテムある
- if string.match(detail["name"],item_name) then -- アイテム名がマッチする
- if damage == nil or damage==detail["damage"] then -- ダメージ値の指定があり、それが一致する
- count = count + detail["count"]
- end
- else -- アイテム名がマッチしない
- end
- else -- スロットにアイテムない
- end
- end
- return count
- end
- -- selectItem(name, damage) , 1/26作
- -- スロット内を探し、name(damage値指定があるときはそれも)とマッチするアイテムを選択する。
- function selectItem(name,damage)
- -- local selected_slot = turtle.getSelectedSlot()
- for i=1,16 do
- local item = turtle.getItemDetail(i)
- if type(item)=="table" then -- スロットに何かアイテム
- -- print("slot=",i," ",item["name"]," ",item["damage"])
- if string.match(item["name"],name) then -- 指定アイテムの名前と一致
- if damage==nil or damage == item["damage"] then -- ダメージ値指定がない、または指定と一致
- turtle.select(i)
- return true, item["count"]
- else -- 名前は一致したがダメージ値が違う
- -- do nothing
- end
- else -- 指定アイテムの名前と不一致
- -- do nothing
- end
- else -- スロット内にアイテムなし
- -- do nothing
- end
- end
- -- turtle.select(selected_slot)
- return false, "No item to match"
- end
- -- スロット番号の小さいほうから探し、空っぽのスロットを選択する。
- function selectEmptySlot()
- for i=1, 16 do
- local item = turtle.getItemDetail(i)
- if item == nil then
- turtle.select(i)
- return true
- end
- end
- return false
- end
- -- スロット番号の小さいほうから探し、空っぽのスロット番号を返す
- function getEmptySlot()
- for i=1, 16 do
- if turtle.getItemCount(i) == 0 then
- return i
- end
- end
- return false
- end
- -- slot0とslot1のアイテムを入れ替える。tmp_slotは入れ替え時に用いる一時アイテム置き場
- function changeItems(slot0, slot1, tmp_slot)
- if slot0 == slot1 then return end -- slot0とslot1が同じならすぐ終了
- if turtle.getItemCount(tmp_slot)>0 then return false, "tmp_slot must be empty." end
- if turtle.getItemCount(slot1)>0 then -- 移動先slot1が埋まっている
- if turtle.getItemCount(slot0)>0 then -- 移動先slot0も埋まっているので、一時置き場を使おう
- turtle.select(slot1)
- turtle.transferTo(tmp_slot) -- slot1のアイテムを退避
- turtle.select(slot0)
- turtle.transferTo(slot1) -- slot0のアイテムをslot1に移動
- turtle.select(tmp_slot)
- turtle.transferTo(slot0) -- 退避スロットのアイテムをslot1に移動
- else -- 移動先slot0があいているので slot1からslot0へ移動させよう
- turtle.select(slot1)
- turtle.transferTo(slot0)
- end
- else
- turtle.select(slot0)
- turtle.transferTo(slot1) -- slot0のアイテムをslot1に移動
- end
- end
- -- table.sort()で用いる比較関数の定義。名前順でダメージ値の順。
- -- _compare({name="minecraft:dirt", damage=0}, {name="minecraft:wool", damage=1})
- -- => true (名前のアルファベット順で左の方が前だから)
- -- _compare({name="minecraft:wool", damage=3}, {name="minecraft:wool", damage=1})
- -- => false (名前は同じだがダメージ値が後の方が小さいので)
- local function _compare(detail0, detail1)
- -- 引数がおかしいとエラー終了
- assert(detail0 and detail1 and detail0["name"] and detail1["name"] and detail0["damage"] and detail1["damage"])
- if detail0["name"] < detail1["name"] then
- return true -- detail0が名前順で前ならばtrue
- elseif detail0["name"] == detail1["name"] then
- -- detail0の名前が同じならばdamage値が小さければtrue
- return detail0["damage"] <= detail1["damage"]
- else
- return false -- detail0が名前順で後ろならばfalse
- end
- end
- -- ###################################################################
- function sortInventory()
- local tmp_slot = 16
- collectItem() -- まずは整理しようね。
- -- スロット16(tmp_slot)があいてない場合はエラー返して終了するよ
- if turtle.getItemCount(tmp_slot) > 0 then
- local empty_slot = getEmptySlot()
- if empty_slot == false then -- 空ける場所もないのでfalse終了
- return false, "Slot "..tmp_slot.." must be empty."
- else
- turtle.select(tmp_slot)
- turtle.transferTo(empty_slot)
- collectItem()
- end
- end
- -- インベントリアイテムの情報を収集するよ
- local items = {}
- for i=1,15 do
- local item = turtle.getItemDetail(i)
- if item then -- スロットにアイテムあります。
- table.insert(items, item)
- else
- -- スロットは空です。
- end
- end
- table.sort(items, _compare) -- 文字列順にソートじゃい。比較用関数は自分で作ったの使っています。
- for i,_item in ipairs(items) do
- selectItem(_item["name"], _item["damage"])
- local slot0 = turtle.getSelectedSlot()
- print(slot0..'->'..i)
- changeItems(slot0, i, tmp_slot)
- end
- end
- -- #######################################################
- function _placeItem(_place_func, item_name, item_damage)
- local place_func = _place_func or turtle.place
- if selectItem(item_name, item_damage) then
- -- マッチするアイテムあり
- return place_func()
- else
- -- マッチするアイテムなし
- return false, "No item to match"
- end
- end
- function placeItem(item_name, item_damage)
- return _placeItem(turtle.place, item_name, iem_damage)
- end
- function placeUpItem(item_name, item_damage)
- return _placeItem(turtle.placeUp, item_name, iem_damage)
- end
- function placeDownItem(item_name, item_damage)
- return _placeItem(turtle.placeDown, item_name, iem_damage)
- end
- function waitForEnoughItems(required_qty, item_name, item_damage)
- local ppItem = function(item_name, item_damage, current_qty, required_qty)
- if item_damage then
- print(string.format("%s(%d): %d/%d", item_name, item_damage, current_qty,required_qty))
- else
- print(string.format("%s: %d/%d", item_name, current_qty, required_qty))
- end
- end
- local current_qty = h2turtle.getItemCountAll(item_name, item_damage)
- while current_qty < required_qty do
- ppItem(item_name, item_damage, current_qty, required_qty)
- os.sleep(0.5)
- os.pullEvent("turtle_inventory")
- current_qty = h2turtle.getItemCountAll(item_name, item_damge)
- end
- ppItem(item_name, item_damage, current_qty, required_qty)
- end
- -- ####################################
- -- prompt
- function promptValue(prompt_msg, default_value)
- assert(default_value, "promptValue(prompt_msg, default_value)")
- prompt_msg = prompt_msg or "Please input"
- prompt_msg = prompt_msg.." [\""..default_value.."\"]: "
- print(prompt_msg)
- term.write(" >>")
- local inputed_value = read()
- if inputed_value == "" then
- -- 入力なしのエンターキーならば、デフォルト値を返す
- return default_value
- else
- return inputed_value
- end
- end
- function promptYN(prompt_msg)
- prompt_msg = prompt_msg or "ok? ([y]/n): "
- local pattern_tbl = {
- yes=true, y=true, Y=true, Yes=true,
- no=false, No=false, n=false, N=false
- }
- while true do
- term.write(prompt_msg)
- local value = read()
- if value=="" then
- return true
- else
- local tmp = pattern_tbl[value]
- if tmp ~= nil then return tmp end
- -- tmp==nil すなわち、意味不明文字列の場合に再入力を促す
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement