はじめに
何度も検討を続けてきた黒曜石生成プログラムですが、とりあえずこれが最終形ということで使い方と簡単なプログラム解説をします。
紹介動画はこちら。
プログラムのインストール
「obisigen」という名前でプログラムをダウンロード
> pastebin get ZknGLgxE obsigen
使い方
1. 最初に、施設を建築する
「引数」としてbuild
を与えてプログラム実行。
> obsigen build
なお、建設する施設の位置、サイズは以下のとおり。
T: タートル初期位置、B: ブロック 幅4、奥行き4、高さ3の施設。 BBBB BBBB BBBB BBBB T
2a. (施設建築済)黒曜石を自動生成する
プログラム実行前に、タートルの右にあるチェストにレッドストーンを入れておくこと。
「引数」としてobsidian
を与えてプログラム実行。レッドストーンの数だけ黒曜石を生成。
> obsigen obsidian
2b. (施設建築済)丸石を自動生成する
「引数」としてcobble
を与えてプログラム実行。
「引数」生成する個数
は省略してもよい。そのときは64個(configで変更可能)。
> obsigen cobble 64
2c. (施設建築済)焼石を自動生成する
なお、焼石を回収するためにはシルクタッチ(と燃料)が必要。 - シルクタッチタートルの紹介(More Turtles Modの紹介) - Minecraftとタートルと僕
「引数」としてstone
を与えてプログラム実行
「引数」生成する個数
は省略してもよい。そのときは64個(configで変更可能)。
> obsigen stone 64
ソースコード
コード解説
ソースコードそのものの掲載は、300行近くて長すぎるので省略(だいたい建設関連のコードせい)。
重要な部分のみ抜粋。
設定(config)項目
各種必要アイテムを入れるスロット番号など。特に変更することはないと思いますが、
あえて変更するならば、プログラム実行時に生成個数を省略したときのデフォルト生成個数である「DEFAULT_GENERATE_QTY = 64」あたり。
メイン(main)部分
local args = {...} local targets = "cobble" if args and isInclude({"build", "cobble", "obsidian", "stone"}, args[1]) then target = args[1] else print("program-name arg1 arg2") print(" arg1: build/cobble/obsidian/stone") print(" arg2: quantity (optional)") assert(false, "Invalid argument(s)") end if target == "build" then print('Start: ',target) waitForEnoughFuel(MIN_FUEL_LEVEL, FUEL_SLOT) waitForEnoughItems("40 Blocks", 40, BLOCK_SLOT) waitForEnoughItems("3 Glasses", 3, GLASS_SLOT) waitForEnoughItems("a Water-Bucket", 1, WATER_SLOT) waitForEnoughItems("3 Chests", 3, CHEST_SLOT) build1() build2() build3() else local maxCount = tonumber(args[2]) or DEFAULT_GENERATE_QTY waitForEnoughItems("a Lava-Bucket", 1, LAVA_SLOT) waitForEnoughItems("a BLOCK", 1, BLOCK_SLOT) switchWaterDirection(target) if target == 'stone' then print('Start: ',target,' ',maxCount) local p = peripheral.wrap("right") assert((p and p.digSilkTouch), "required: SilkTouch Turtle") waitForEnoughFuel(maxCount,FUEL_SLOT) generateStone(maxCount, p.digSilkTouch) elseif target == 'cobble' then print('Start: ',target,' ',maxCount) generateStone(maxCount, turtle.dig) elseif target == 'obsidian' then print('Start: ',target) maxCount = generateObsidian() end print('Generate ',target,': ',maxCount) if maxCount > 0 then print((os.clock() - sTime)/maxCount,'(sec/piece)') end end
L1-10)引数の処理
- 引数として許されるのは、"build", "cobble", "obsidian", "stone"のみ。
- テーブルを集合として扱うライブラリ欲しいわ。
- それ以外の引数だったり、そもそも引数がなかったらエラーメッセージ。
それ以降のIF文入れ子構造
if target == "build" then -- (必要アイテムがもらえるまで待つ処理) -- (実際に建設をする処理) else -- (各種ブロックを生成するための前処理) -- (ブロック設置して、水の流れる向きを変えたりとか) if target == 'stone' then -- (焼石の生成) -- (回収にdigSilkTouch()使っています) elseif target == 'cobble' then -- (丸石の生成) -- (回収に普通のdig()を使っています) elseif target == 'obsidian' then -- (黒曜石の生成) end -- (終了メッセージ) end
おわりに
このプログラムで面倒だったのは2箇所。溶岩設置&撤去のタイミングの時間調整部分と、建設の部分でした。
特に、施設の断面図を並べて、頭の中でタートルの動きや向きを考えてシミュレーションしつつ、タートルの移動・ブロック設置関数を考えるのが面倒でした。 これってもっと直感的にできないかなぁと悩み中。
たとえば思いつきだけど、
section = {} section[1]={2,1,2,1,2} section[2]={1,2,1,2,1} section[3]={2,1,0,1,2} section[4]={1,2,1,2,1} section[5]={2,1,2,1,2}
みたいに床面の設計図テーブル(断面図)をあらかじめ用意しておけば、それを使ってブロックを敷き詰めてくれるAPI関数があると便利かも?
ちなみに断面図の数字は、タートルのインベントリ番号に対応。0=空白。
すでにブロックがあるときには、手持ちのブロックと比較して違うなら張り替えるような感じで。
そして1層目、2層目と積み重ねていって建築する。
なんだか3Dプリンタみたい・・・作ってみる。