2016年9月23日金曜日

採取場の実装

前回、おしっこ臭さが役に立つものの例として、採取場を挙げました。
それで採取場のことがずっと気になっていたので、一思いに実装しました。

実装してみると、採取場というのは結構大変なものでした。

なお、採取場の仕様は以下の通り
  • 一つの採取場につき、取得できるアイテムは一種類
  • 採取できるかどうかはランダム変数を参照
  • ランダム変数は日替わりなので、有効な採取場も日替わり
  • おもらししていると、採取場は使えない

そして以下のような、イベントページ構成を想定しました。

  • 初期状態。ランダム変数を参照して、イベントの状態を切り替える(自動実行)
  • 採取可能状態。アイテム取得後、イベントを採取不可状態に切り替える
  • 採取不可状態。イベントを一時消去する(自動実行)
  • おもらしによる採取不可状態。イベントを一時消去する(自動実行)

このうち、セルフスイッチを用いて状態を判断する必要があるのは、「採取可能状態」と「採取不可状態」の2つです。

しかしここで問題が発生します。
この仕様と方式の場合、日を跨いだ後は再び初期状態に戻ってイベントの状態の切り替えが行われる必要があります。しかし、セルフスイッチを使って切り替えている以上、他のイベントからはアクセスできません。

セルフではないスイッチを使えば原理的には実現可能ですが、複数のマップに散らばった多数の採取場が重複せずに各自のスイッチを利用し、それらを漏れなく初期化することは現実的ではありません。

そこで、飛び道具としてスクリプトを使い、セルフスイッチをOFFにすることにしました。

ソースはこんな感じです。

これだけのソースですが、これを書くにはちょっとした調査を要しました。
要点は以下の2点です。

  • セルフスイッチはツクールのシステムクラスにラップされたハッシュに真偽値として保存されていて、キーは[<マップID>,<イベントID>,<スイッチ番号>]の配列である
  • GUIから入力できるマップの情報(イベントを含む)はRPG::Mapというクラスのオブジェクトとして保存されていて、このオブジェクトを取得するにはload_dataというメソッドを用いる

これだけのことを調べるのに、えらい時間がかかりました。

さて、このスクリプトではイベントの名前を参照しています。
採取場として扱うイベントは、名前に"<gathering/>"という文字列を含めることにしました。
アイテムのようにメモ欄があれば良かったのですが、まあプレイヤーに見えるところではないので、良しとしましょう。

さて、テストです。
テストデータとして、このようなイベントを作りました。
採取場初期化スクリプトではAとB、2つのセルフスイッチをOFFにする仕様としたので、このイベントではA,B二つのスイッチを使って、実行するごとに袋が2つ→1つ→0と減っていくようにしました。

袋を設置しました。右にあるレバーはスクリプト起動用です。実際には宿屋イベントの中で起動することになります。

袋を拾います。片方は1個だけ残しておきます。

マップを跨いでも有効であることを確かめたいので、別のマップにも袋を設置しました。

こちらも同様にします。

では、レバーを引きます。

袋が元に戻りました。

こっちも同様です。


以上が採取場初期化スクリプトでした。
ところで、今回は採取場の実装というタイトルにしましたが、実はまだ採取場イベント自体は出来ていません。
次回は、今回のスクリプトを前提とした、テンプレートとなるイベントを作成します。

0 件のコメント:

コメントを投稿