読者です 読者をやめる 読者になる 読者になる

Minecraftとタートルと僕

PCゲームMinecraftのMOD「ComputerCraft」の情報を集めたニッチなブログです。

黒曜石・焼石自動生成プログラム改(プログラム紹介編)

チュートリアル Lua ComputerCraft Minecraft

はじめに

何度も検討を続けてきた黒曜石生成プログラムですが、とりあえずこれが最終形ということで使い方と簡単なプログラム解説をします。

紹介動画はこちら。

プログラムのインストール

「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

ソースコード

http://pastebin.com/ZknGLgxE

コード解説

ソースコードそのものの掲載は、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プリンタみたい・・・作ってみる。