本節では移動コマンド「しらべる」の実装詳細について述べる。 まずは「しらべる」コマンドの対象であるオブジェクトのすべてを表現する ROM データの構造について説明する。 また、それらの構造それぞれについて、その型のオブジェクトデータを解釈して得られるテキスト CSV ファイルを提示する。 それから「しらべる」コマンドを実行するときのプログラムの手順を、可能な限りコードを引用した上で説明する。
本節では移動コマンド「しらべる」に直接関係するデータ構造を説明していく。 移動コマンド「はなす」の構造よりも複雑であり、関与するデータ型間の関係を図式で示したい。 また、これらのデータ構造には、文章だけではその役割が想像しにくい属性がある。 読者の必要に応じて 付録 B データ に収録したデータを確認しながら読んで欲しい。
アドレス $C20000
には以下に示すメモリーレイアウトの
0x11
バイト長オブジェクトが 0x14
個ほど配列されている。
これらのオブジェクトが表現するのは、宝箱、ツボ、タンス、等々というようなオブジェクトの分類項目だ。
ゲーム中にバラバラと存在する「しらべる」対象のすべてが、この配列にあるいずれか一つの要素を「共有」している。
「しらべる」対象のすべてを、この共有オブジェクトにより類別することができる。
表 4.21 構造体 $C20000
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$000F
|
ヒットテスト座標成分上限 |
#$00
|
#$00F0
|
ヒットテスト座標成分右限 |
#$01
|
#$000F
|
ヒットテスト座標成分下限 |
#$01
|
#$00F0
|
ヒットテスト座標成分左限 |
#$02
|
#$0007
|
キャラクターが上向きのときの対応座標成分オフセット |
#$02
|
#$0038
|
キャラクターが右向きのときの対応座標成分オフセット |
#$02
|
#$01C0
|
キャラクターが下向きのときの対応座標成分オフセット |
#$03
|
#$000E
|
キャラクターが左向きのときの対応座標成分オフセット |
#$03
|
#$0010
|
キャラクターが上向き禁止 |
#$03
|
#$0020
|
キャラクターが右向き禁止 |
#$03
|
#$0040
|
キャラクターが下向き禁止 |
#$03
|
#$0080
|
キャラクターが左向き禁止 |
#$04
|
#$FFFF
|
初訪問時のメッセージ |
#$06
|
#$FFFF
|
無効な方向からのメッセージ |
#$08
|
#$FFFF
|
罠であるときのメッセージ |
#$0A
|
#$FFFF
|
何もないときのメッセージ |
#$0C
|
#$FFFF
|
再訪問時のメッセージ |
#$0E
|
#$01FF
|
初訪問時の効果音 |
#$0F
|
#$03FE
|
再訪問時の効果音 |
ヒットテスト座標成分各属性は、「しらべる」対象の外見上の外接矩形を定義する数を値としてとるものだ。 「しらべる」対象の位置を基準として、これらの値で「ふくらませた」矩形を考えることができる。 「しらべる」処理では、この矩形とパーティー先頭との位置関係とに対するヒットテストを行う。
実際にデータを検証すると、ムドーの城にある魔物の像や、月鏡の塔の大鏡には大きな矩形が定義されていることがわかる。
これらはヒットテストの計算時に適用される値をとる属性だ。 パーティー先頭の座標が「しらべる」対象の外接矩形と少々ズレがあってもヒットテストが成功させるための工夫だ。
これらは「しらべる」コマンドが成功するために必要な先頭キャラクターの向きに関する条件を与える属性だ。いずれもブーリアン値をとる。 例えばタンスや看板は上向き禁止が指定されている。
この属性はメッセージ ID を値とする属性であり、「しらべる」コマンドを実行して最初にウィンドウに出力されるメッセージの ID だ。 ゲーム中に初めてこの対象を「しらべる」ときには、必ずこの値が参照される。 ただし、値がまともに設定されていないものについては「最初の」メッセージという概念がないものとして了解すること。
この属性はメッセージ ID を値とする属性であり、「しらべる」コマンドを対象が禁止する向きで実行したときに表示されるメッセージの ID だ。 「裏からはわからない」のような文言をプレイヤーに示す。
無効な方向がないものについては、この値は参照されないはずだ。
この属性はメッセージ ID を値とする属性であり、対象が罠であるときに表示されるメッセージの ID だ。
この作品では宝箱、ツボ、および井戸にしか意味をなさない属性のはずだが、タル、看板、貼り紙等、 挙句の果てには足もとについても専用メッセージが用意されている。
この属性はメッセージ ID を値とする属性であり、対象に異状がないときに表示されるメッセージの ID だ。
この属性はメッセージ ID を値とする属性であり、「しらべる」コマンドを実行して最初にウィンドウに出力されるメッセージの ID だ。 ただし、対象の調査済みフラグが存在して、かつそれがオンのときにしかこの値は参照されない。
初訪問時の効果音とは、この対象に「しらべる」コマンドを実行したときに演奏される効果音の ID を値とする属性だ。 ゲーム中に初めてこの対象を「しらべる」ときには、必ずこの値が参照される。
再訪問時の効果音とは、この対象に「しらべる」コマンドを実行したときに演奏される効果音の ID を値とする属性だ。 ただし、対象の調査済みフラグが存在して、かつそれがオンのときにしかこの値は参照されない。
本節はあくまでもあるモデルにおいての議論なので、ここで示すようなデータ構造のでっちあげが認められるだろう。 プログラム中には次に示すような構造体は存在しないが、次節以降の構造体を説明する便宜上導入しておく。 つまり、後述する実在の構造体群が、あたかも本節で導入する構造体の派生型であるかのように説明したいのだ。 よそではこの議論は通用しないので、読者は注意して欲しい。
表 4.22 「しらべる」対象抽象基底構造体
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
ブーリアン値の属性。 詳細はまだ判明していないが、ある一定のタイミングで対象データを ROM からロードするか否かを示すらしい。
対象ほとんどすべてについてこの値はゼロが設定されているのだが、 例外として「きたのどうくつ」地下 3 階にある「はぐれのさとり」、ひょうたん島の操舵輪、 「もりのみずうみ」の特殊な宝箱等には 1 が設定されている。
分類とは、4.5.1.1 構造体 $C20000
: 「しらべる」対象分類 オブジェクト ID を値とする属性だ。
この値が「足もと」「宝箱」「ツボ」「タル」等々を表現していると解釈できる。
便宜上向きと名前を付けてしまったが、この属性は必ずゼロでなければならないはずだ。 この属性には意味はないはずだが、プログラム中から確実に参照されている。
MX とは、このオブジェクトが存在する空間内のどの X 座標に配置されるかを M 座標系で表現した値をとる属性だ。 言い忘れたが、本節で登場する座標成分はすべて M 座標系で表現された値だ。
MX とは、このオブジェクトが存在する空間内のどの Y 座標に配置されるかを M 座標系で表現した値をとる属性だ。
LV とは、このオブジェクトが存在する空間内のどの「高さ」に配置されるかを示す値をとる属性だ。
LV の詳細は 4.4.1.1 構造体 $FF08DA
: 「はなす」対象簡易版 での記述を参照して欲しい。
アドレス $C83E5C
には以下に示すメモリーレイアウトの
0x07
バイト長オブジェクトが
0x14E
個配列されている。
これらは「しらべる」対象から何らかのアイテムを一度だけ入手可能であることを表現している。
表 4.23 構造体 $C83E5C: アイテム発見
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
#$03
|
#$0FF0
|
アイテム |
#$04
|
#$00F0
|
(未使用) |
#$05
|
#$FFFF
|
フラグ ID |
以下、抽象基底構造体にない属性しか記述しない(後続の構造体も同様)。
アイテムとは、この対象を「しらべる」ことによって入手できるアイテムの ID を値とする属性だ。
フラグ ID とは、この対象が調査済みであるかどうかを管理するフラグの ID を値とする属性だ。
簡単に説明すると、アドレス $7E3D2A
からブーリアンフラグが延々と配列されている。
$7E3D2A
の最下位ビットをゼロ番目として、何番目のビットかを示す値がフラグ ID だとみなせる。
アドレス $C8477E
には以下に示すメモリーレイアウトの
8 バイト長オブジェクトが 0x27
個配列されている。
これらは「しらべる」対象からいくらかのゴールドを一度だけ入手可能であることを表現している。
表 4.24 構造体 $C8477E: ゴールド発見
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
#$03
|
#$0030
|
指数 |
#$03
|
#$3FC0
|
係数 |
#$04
|
#$3FC0
|
乱数 |
#$05
|
#$00C0
|
(未使用) |
#$06
|
#$FFFF
|
フラグ ID |
指数とは、この対象から得られるゴールドを算出するのに用いられる値をとる属性の一つだ。
値が十進数表現で数桁におよぶようなものについては、Python コードの記法を用いれば、その数を F * 10 ** E
のように捉えて、
E
と F
を保持するというパターンがこの頃のドラクエにはあるようだ。
この属性はその表現法における E
の値だ。
前項の F
を値とする属性だ。
乱数とは、上記の 2 属性から定まる金額に対して、さらにボーナス額が加算される場合の、 加算値の振れ幅を示す値をとる属性だ。
残念ながら、どのゴールド発見オブジェクトについても、属性値はゼロとなっている。
アドレス $C848B6
には以下に示すメモリーレイアウトの
6 バイト長オブジェクトが 0x215
個配列されている。
これらは対象を「しらべる」ことで何らかのテキストメッセージを出力することを表現している。
もっと強く言うと、中身が空の引き出しやツボといった変哲のないオブジェクトのすべてもここに分類される。
表 4.25 構造体 $C848B6: 情報取得
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
#$03
|
#$0010
|
とうぞくのはな |
#$03
|
#$0020
|
レミラーマ |
#$03
|
#$00C0
|
(未使用) |
#$04
|
#$FFFF
|
メッセージ ID |
これはブーリアン値の属性であり、移動中のコマンド「とうぞくのはな」実行時のカウンターを増加させるかどうかを示す。
これはブーリアン値の属性であり、移動中のコマンド「レミラーマ」実行時において座標 (MX, MY) を光らせるかどうかを示す。
「しらべる」コマンドの結果として、この属性値を ID とする移動モードメッセージを出力させる。
アドレス $C85534
には以下に示すメモリーレイアウトの
7 バイト長オブジェクトが 0x11
個配列されている。
いずれも宝箱やツボがモンスターであるような対象を表現している。
表 4.26 構造体 $C85534: 罠
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
#$03
|
#$03F0
|
イベント戦 ID |
#$04
|
#$00C0
|
(未使用) |
#$05
|
#$FFFF
|
フラグ ID |
この属性値は配列 $C88DF4
のインデックスであり、
具体的には「しらべる」コマンド実行後に発生する戦闘に対するイベント戦の ID だ。
アドレス $C855AB
には以下に示すメモリーレイアウトの
9 バイト長オブジェクトが 0x7F
個配列されている。
これらのオブジェクトは、これまで見てきた分類から逸脱した振る舞いを実現するものだ。
表 4.27 構造体 $C855AB: 特殊イベント
オフセット | 桁 | 属性 |
---|---|---|
#$00
|
#$0001
|
ロードするかどうか |
#$00
|
#$003E
|
分類 |
#$00
|
#$00C0
|
向き |
#$01
|
#$01FF
|
MX |
#$02
|
#$03FE
|
MY |
#$03
|
#$000C
|
LV |
#$03
|
#$0010
|
とうぞくのはな |
#$03
|
#$0020
|
レミラーマ |
#$03
|
#$00C0
|
(未使用) |
#$04
|
#$FFFF
|
しらべる処理 |
#$06
|
#$00FF
|
|
#$07
|
#$FFFF
|
フラグ ID |
いずれも 4.5.1.5 構造体 $C848B6
: 情報取得 と同じ。
この属性は「しらべる」コマンドによって実行されるサブルーチンの開始アドレスを値とする。
サブルーチン $C0D831
が「しらべる」処理の主要部だ。
まずは主要部の手順のうち、例外的な部分を除外した流れを示す:
馬車外のメンバーで最低一人は生存状態であることを確認する。 テストに成功すれば次の工程へ進むが、失敗すれば後述の全員カンオケの場合へジャンプする。
馬車外の生存状態のパーティーメンバーを一人、 および「しらべる」処理最中であることを示すフラグを設定・保存しておく。
パーティーが何らかの乗り物を使用中であるかどうかをテストする。
これには変数 $7E85EF
の値を参照するだけでよい。
値がゼロであれば成功であり、次の工程へ進むが、さもなければ後述の何もない場合の工程にジャンプする。
サブルーチンを呼び出すことで、現在の空間内にある「しらべる」対象それぞれに対して、 それらの外接矩形領域で、パーティー先頭者の座標にオフセット量を考慮した領域を包含するものを探索する。 探索が成功すれば次の工程へ進むが、失敗すれば後述の何もない工程にジャンプする。
サブルーチンを呼び出すことで、パーティー先頭者の向きと「しらべる」対象の規定する向きとがマッチするかテストする。 内容は向きに対応するジャンプテーブルがあって、 そのそれぞれで対応する「しらべる」対象分類の「キャラクターが向き禁止」属性値を突き合わせるだけで済む。 マッチしていれば次の工程へ進むが、失敗すれば後述の無効な方向からしらべた場合の工程にジャンプする。
サブルーチンを呼び出すことで、対象に対応する RAM 内フラグが既に立っているかどうかをテストする。 立っていなければフラグを立てて次の工程へ進むが、そうでなければ後述の調査済みの場合の工程にジャンプする。
対象の型によって処理が分岐する。これによるとアイテム発見、ゴールド発見、および罠についてはそのフラグ ID に基づいてビットを参照したり更新したりする。 情報取得または特殊イベントについてはそういったことは行わない。
対象の分類の属性値を参照して処理する。 まずは初訪問時の効果音が設定されていれば、それを再生する。 次に初訪問時のメッセージをウィンドウに出力する。ただし特殊イベントの場合はこの出力がない。 最後に、しらべる対象の型によって変わる処理を行い、次の工程に進む。
対象の分類がアイテムであれば、パーティーはオブジェクトに設定されたアイテムを入手する。 万が一アイテムを表す属性値がゼロである場合は、何もないときのメッセージの出力しかしない。
演出の都合上、アイテムが「ちいさなメダル」、貴重品、それ以外の 3 通りで場合分けする。 詳細は割愛する。
パーティーのメンバーを先頭から順に、発見したアイテムを試しに追加してみる。もし成功すれば、
メッセージ #$16AE
「[C1]は[AD][B5]を 手に入れた。」 を出力する。
メンバー全員について所持品追加が失敗したら、次はふくろが利用可能かどうかをテストする。
利用可能であるときに限り、ふくろに発見したアイテムを追加し、
メッセージ #16E7
「[B5]を [C3]に入れた。」 を出力する。
なお、ここまでの追加処理を全部失敗した場合は何もしない。 調査済みのフラグを立てた後なので、プレイヤーは対象アイテムの入手機会を永遠に失うことになる。
対象の分類がゴールドであれば、獲得金額を計算してメッセージを出力してからパーティー所持金を加算する。
獲得金額の計算処理では、係数と指数を基に算術演算的に基本金額を算出し、最後に乱数を加算する。
この過程でオブジェクトの対応属性値を参照する。
乗算には汎用乗算サブルーチン $C00C9C
を利用する。
メッセージは ID #$16E8
のもので固定であり、
内容は「[C0]は[AD][BB]ゴールドを 手に入れた。」 という文言だ。
所持金を加算するには、専用サブルーチン $C42862
を呼び出す。
対象の分類が情報取得であれば、オブジェクトのメッセージ ID 属性値を基にウィンドウにメッセージを出力する。
対象の分類が罠であれば、イベント戦 ID を基に罠であるときのメッセージを完成させる。 そのメッセージをウィンドウに出力し、イベント戦 ID を基に戦闘を開始させる。 その後にフラグ ID に対応する RAM 内のビットを 1 に更新する。
対象の分類が特殊イベントであれば、属性値のしらべる処理アドレスを
$00
にロードしてジャンプする。
対象の分類が特殊イベントであれば、直ちに当サブルーチン呼び出し元に復帰する。 罠であれば、ウィンドウを消去してから当サブルーチン呼び出し元に復帰する。 それ以外の場合は、後述する後始末工程に進む。
本流の処理中に何らかのテストが失敗したときに処理される工程を以下に示す。 ここに挙げる工程それぞれにはお互いに関係しない。 また、いずれの工程の終了後も後述の後始末処理に移るものだ。
もし馬車外の全員が死亡状態であれば、メッセージ ID #$177F
の文言
「このままでは 調べられない!」 を出力する。
現在使用中の乗り物に応じてメッセージを 2 通出力する。 ただし最初のメッセージは船に乗っている場合は、海底にいるか否かで場合分けがある。 海底の場合は「[C0]は 海の底を 目をこらして[AD]みつめた。[AF]」だ。
表 4.28 配列 $C0D9EE: 何もないときのメッセージ
乗り物 | メッセージ |
---|---|
徒歩 | [C0]は 足もとを 調べた![AF] |
船 | [C0]は 水面を 目をこらして[AD]みつめた。[AF] |
ひょうたん島 | [C0]は 水面を 目をこらして[AD]みつめた。[AF] |
まほうのじゅうたん | [C0]は じゅうたんから[AD]身をのりだして 地面をながめた。[AF] |
空飛ぶベッド | [C0]は ベッドから[AD]身をのりだして 地面をながめた。[AF] |
船(屋内) | [C0]は 水面を 目をこらして[AD]みつめた。[AF] |
船(不明) | [C0]は 水面を 目をこらして[AD]みつめた。[AF] |
ペガサス | [C0]は 馬車から[AD]身をのりだして 大地をながめた。[AF] |
表 4.29 配列 $C0D9FE: 何もないときのメッセージ
乗り物 | メッセージ |
---|---|
徒歩 | しかし 何も 見つからなかった。 |
船 | しかし 何も 見つからなかった。 |
ひょうたん島 | しかし 何も 見つからなかった。 |
まほうのじゅうたん | とくに 何も 見つからなかった。 |
空飛ぶベッド | とくに 何も 見つからなかった。 |
船(屋内) | しかし 何も 見つからなかった。 |
船(不明) | しかし 何も 見つからなかった。 |
ペガサス | とくに 何も 見つからなかった。 |
対象の分類から決まる無効な方向からのメッセージ ID に基づいた文言をウィンドウに出力する。
対象の分類の属性値を参照して処理する。 まずは再訪問時の効果音が設定されていれば、それを再生する。 次に再訪問時のメッセージをウィンドウに出力する。 最後に何もないときのメッセージをウィンドウに出力する。
成功時と失敗時に共通する後処理とは「はなす」処理のそれと同様であり、 プレイヤーのコントローラー入力を待機して、ウィンドウを消去して画面内のアニメーションを再開するものだ。