4.13. モンスター

4.13.1. 解析
4.13.1.1. $C22B54 - モンスター構造体へのポインタ配列
4.13.1.2. JSL $C2F119 によるデータ取得
4.13.1.3. JSL $C2F120 によるデータ取得
4.13.1.4. JSL $C2F136 によるデータ取得
4.13.1.5. JSL $C2F13D によるデータ取得
4.13.1.6. JSL $C2F153 によるデータ取得
4.13.1.7. JSL $C2F15A によるデータ取得
4.13.1.8. $C20154 - モンスター構造体
4.13.2. TODO リスト

この文書では、$C20154 に定義されているモンスター構造体の解析結果を説明する。 先人の手で「モンスター構造体データが $C20154 に存在する」ことが判明している。 これを出発点に、可能な限り、構造体の仕組みを解明する。

以下のことは、解析前に既知だと仮定する。

4.13.1. 解析

モンスター構造体の各メンバー解析の方法は、 アイテムや戦闘行動のデータ構造体等のそれと同じ方法をとる。 これらの構造体は、密接に関連しているメンバーが存在するので、 実際には同時に解析することになった。

4.13.1.1. $C22B54 - モンスター構造体へのポインタ配列

アイテム構造体へのポインタ配列や、 戦闘行動構造体へのポインタ配列と同じ役割を果たす。 格納されているデータは、モンスター ID に対応するモンスターのデータが格納されているアドレスだ。 ただし、この値を #$C20154 に加算したものが正確なアドレスだ。

C2/2B54:    0000 // 0000 [表示なし]
C2/2B56:    2A00 // 0001 ぶちスライム
C2/2B58:    5400 // 0002 ファーラット
C2/2B5A:    7E00 // 0003 マンドラゴラ
C2/2B5C:    A800 // 0004 おばけなめくじ
C2/2B5E:    D200 // 0005 ねずこうもり
C2/2B60:    FC00 // 0006 リップス
C2/2B62:    2601 // 0007 オニオーン
C2/2B64:    5001 // 0008 テンツク
C2/2B66:    7A01 // 0009 きりかぶこぞう
...

4.13.1.2. JSL $C2F119 によるデータ取得

X をモンスター ID にセットした直後に呼び出し、 さらに構造体のアドレスを 2 バイトの「実引数」を指定してから、 そこに格納されている値をアキュームレータにロードするサブルーチンの呼び出しだ。

下の例は、アドレス #$C20178 + sizeof(モンスター構造体) * x から値を取得するものだ。 実装は、上式の乗算部分をあらかじめ配列しておいた $C22B54 モンスターデータポインタ配列 に格納されている値を利用している。

C2/EC22:    DA          PHX 
C2/EC23:    AA          TAX 
C2/EC24:    2219F1C2    JSR $C2F119         ■(RTL+2) a = モンスターID X の最大 HP
            7801        // $C20178: HP
C2/EC2A:    FA          PLX 
C2/EC2B:    60          RTS

4.13.1.3. JSL $C2F120 によるデータ取得

JSL $C2F119 によるデータ取得Y バージョンだ。

4.13.1.4. JSL $C2F136 によるデータ取得

X をモンスター ID でセットした直後に呼び出し、 さらに構造体のアドレスを 4 バイトの「実引数」を指定してから、 そこに格納されている値をアキュームレータにロードするサブルーチンの呼び出しだ。 4 バイトの内訳は、最初の 2 バイトが構造体内部のどこかを指すアドレスであり、 最後の 2 バイトがビットマスクだ。 マスク後、それを右シフトして数値化したものをアキュームレータにロードする。

C2/6FE1:    AA          TAX 
C2/6FE2:    2236F1C2    JSR $C2F136         ■(RTL+4) a = モンスター ID X の「みかわし」
            6501
            1C00        // みかわし

4.13.1.5. JSL $C2F13D によるデータ取得

JSL $C2F136 によるデータ取得Y バージョンだ。

4.13.1.6. JSL $C2F153 によるデータ取得

X をモンスター ID でセットした直後に呼び出し、 さらに構造体のアドレスを 4 バイトの「実引数」を指定してから、 そこに格納されている値をアキュームレータにロードするサブルーチンの呼び出しだ。 4 バイトの内訳は、最初の 2 バイトが構造体内部のどこかを指すアドレスであり、 最後の 2 バイトがビットマスクだ。 マスク後の値をアキュームレータにロードする。

このサブルーチンは、どこからも呼び出されている気配がない。

4.13.1.7. JSL $C2F15A によるデータ取得

JSL $C2F153 によるデータ取得Y バージョンだ。

このサブルーチンは、どこからも呼び出されている気配がない。

4.13.1.8. $C20154 - モンスター構造体

構造体一個あたりのデータ格納レイアウトを以下に示す。

表 4.32 $C20154 モンスター構造体 メモリレイアウト

Byte:Bit 80 40 20 10 08 04 02 01
00 次のバイトの下位ビットへ続く
01 不明 B [00] 耐性[00]:メラ 不明 A [00] 戦闘行動[0]
02 次のバイトの下位ビットへ続く
03 不明 B [01] 耐性[01]:ギラ 不明 A [01] 戦闘行動[1]
04 次のバイトの下位ビットへ続く
05 不明 B [02] 耐性[02]:イオ 不明 A [02] 戦闘行動[2]
06 次のバイトの下位ビットへ続く
07 不明 B [03] 耐性[03]:ヒャド 不明 A [03] 戦闘行動[3]
08 次のバイトの下位ビットへ続く
09 不明 B [04] 耐性[04]:バギ 不明 A [04] 戦闘行動[4]
0A 次のバイトの下位ビットへ続く
0B 不明 B [05] 耐性[05]:デイン 不明 A [05] 戦闘行動[5]
0C 次のバイトの下位ビットへ続く
0D レベル すばやさ
0E 次のバイトの下位ビットへ続く
0F 行動タイプ アイテム確率 攻撃力
10 次のバイトの下位ビットへ続く
11 仲間確率 みかわし 守備力
12 次のバイトの下位ビットへ続く 耐性[07]:ラリホー 耐性[06]:マヌーサ
13 ゴールド
14 次のバイトの下位ビットへ続く
15 メタル系 耐性[0A]:マホトラ 耐性[09]:ニフラム 耐性[08]:ザキ 不明 C [00]
16 次のバイトの下位ビットへ続く
17 ドラゴン系 耐性[0D]:ルカニ 耐性[0C]:メダパニ 耐性[0B]:マホトーン 不明 C [01]
18 耐性[11]:踊りふうじ 耐性[10]:やすみ 耐性[0F]:毒 耐性[0E]
19 耐性[15]:まひ 耐性[14]:たたき 耐性[13]:吹雪 耐性[12]:炎
1A 耐性[19] 耐性[18] 耐性[17] 耐性[16]:ぐんたい
1B 耐性[1D] 耐性[1C] 耐性[1B] 耐性[1A]
1C 未使用 スライム系 そら系 ゾンビ系 初期確率 耐性[1E]
1D 集中攻撃 自動回復 複数回 不明 D
1E モンスターイメージ ID
1F MP
20 アイテム ID
21 次のバイトの下位ビットへ続く
22 未使用 不明 B [06] 初期状態 パレット ID
23 未使用
24 HP
25
26 経験値
27
28 モンスター名文字列 ID
29

不明 A, B, C, D のメンバーは、解読していないが、 それ以外のメンバーは解読に成功したので、それぞれに名前をつけておいた。 以下、その説明をする。

戦闘行動[00-05]

モンスターが戦闘中にとり得る戦闘行動 ID のリスト。

耐性[00-1E]

モンスターの呪文耐性だ。 プログラム中では耐性 0E, 17-1E は未参照のようだ。

すばやさ

モンスターのすばやさだ。

レベル

モンスターのレベルだ。

攻撃力

戦闘におけるモンスターの攻撃力の初期値だ。

アイテム確率

戦闘終了後にモンスターが宝箱を落とすことがある。 その確率を決定するために用いられる値を格納する配列のインデックスだ。 解説については Shingo Endo 氏解析資料 [URL1] に詳しい。

行動タイプ

正直に言うと、ここは解読し切っていない。 しかし、モンスターの行動パターンを決めるメンバーだ。

守備力

戦闘におけるモンスターの守備力の初期値だ。

みかわし

モンスターがある種の攻撃 (戦闘行動の「かわす」フラグが 1 のものと考えられる) をかわす確率を決める値を格納する配列のインデックス値(添え字)だ。 下のサブルーチン終了時点での carry が、「みかわし」するかどうかを決める。 これによると、みかわし値が 4 だと完璧に攻撃を避けられるように見える。 もっとも、メンバーのサイズは 2 ビットしかないので、あり得ない。

.dataarea LDA $C27001,X - みかわし確率テーブル
C2/7001:    00
C2/7002:    03
C2/7003:    0C
C2/7004:    30
C2/7005:    C0
@end
..routine みかわし確率計算
C2/7006:    48          PHA 
C2/7007:    A9BF00      LDA #$00BF
C2/700A:    22280FC0    JSR $C00F28         ■乱数
C2/700E:    C301        CMP $01,S
C2/7010:    68          PLA 
C2/7011:    60          RTS
@end
仲間確率

戦闘終了後に、倒したモンスターが起き上がって仲間になりたそうにすることがある。 その確率を決定するために用いられる値を格納する配列のインデックスだ。 解説については Shingo Endo 氏解析資料 [URL1] に詳しい。

ゴールド

戦闘終了後に、モンスターから得られるゴールドの金額だ。

メタル系

このビットが 1 であるモンスターに対しては、基本ダメージ値が

  • 「メタルぎり」で 1.5 倍になる。

  • 「せいすい」でゼロとなる。

ドラゴン系

このビットが 1 であるモンスターに対しては、基本ダメージ値が

  • 「ドラゴンぎり」で 1.5 倍になる。

  • 「ドラゴンキラー」装備時の攻撃で 1.5 倍になる。

初期確率

このビットが 1 であるモンスターには、 戦闘開始時にラリホーまたはマホカンタがあらかじめ効いていることがある。

ゾンビ系

このビットが 1 であるモンスターに対しては、基本ダメージ値が

  • 「ゾンビぎり」で 1.5 倍になる。

  • 「ゾンビキラー」装備時の攻撃で 1.5 倍になる。

  • 「グランドクロス」で 333/256 倍になる。約 1.3 倍。

そら系

このビットが 1 であるモンスターに対しては、基本ダメージ値が 「とびひざげり」で 1.5 倍になる。

スライム系

このビットが 1 であるモンスターはスライム系らしい。 「らしい」というのは、全モンスター構造体データをダンプして確認した結果、 このビットが立っているモンスターが、 「~スライム」 「スライム~」 「はぐれメタル」 「メタルキング」 「チャンプ」 であるので、そう判断したに過ぎないということだ。

複数回

モンスターが 1 ターンに行動する回数が 1 でないとき、 この値が重要な意味を持つ。

自動回復

ターン終了後、秘密裡に HP が回復するモンスターがいる。 それについては、回復度を表現する構造体配列のインデックスを示す。

.routine a = HP の自動回復分 @$258B
C2/C431:    08          PHP 
省略
C2/C43B:    AE8B25      LDX $258B           // 今はモンスター ID と思ってよい 
C2/C43E:    22A7EFC2    JSR $C2EFA7         ■(RTL+4) $64 = a = $7E##[arg00-01],@x & arg[02-03]
            4F20
            FF01
C2/C446:    C90001      CMP #$0100
C2/C449:    B00B        BCS $C456           if(a < 0100h){
C2/C44B:    AA          TAX 
C2/C44C:    2236F1C2    JSR $C2F136             ■(RTL+4) a = $C2##arg[00-01],@x & arg[02-03]
            7101
            3000        // 自動回復
C2/C454:    8009        BRA $C45F           }
省略
C2/C45F:    0A          ASL A
C2/C460:    AA          TAX                 x = a <<= 1;
C2/C461:    BF7FC4C2    LDA $C2C47F,X
C2/C465:    EB          XBA
C2/C466:    29FF00      AND #$00FF          AH = 00h, AL = 下にある配列上位バイト;
C2/C469:    22280FC0    JSR $C00F28         ■乱数系
C2/C46D:    48          PHA 
C2/C46E:    BF7FC4C2    LDA $C2C47F,X
C2/C472:    29FF00      AND #$00FF
C2/C475:    18          CLC 
C2/C476:    6301        ADC $01,S
C2/C478:    8301        STA $01,S           a = 乱数 + 下にある配列下位バイト;
C2/C47A:    68          PLA                 // 戻り値
省略
C2/C47E:    6B          RTL
@end
.dataarea $C2C47F,X - 自動回復
C2/C47F:   0000 //  0 + rnd(0..0)
C2/C481:   1008 // 16 + rnd(0..8)
C2/C483:   2C0C // 44 + rnd(0..12)
C2/C485:   5A14 // 90 + rnd(0..20)
@end
集中攻撃

このメンバーが 0 でないモンスターは、 誰を攻撃するのかを決めるための(特別な)サブルーチンを呼ぶことがある。 そのサブルーチンのアドレス配列のインデックス + 1 を持つ。

モンスターグラフィック ID

詳細は調査していないが、画面に描画するグラフィックを決める値だ。 例えば、「バブルスライム」「はぐれメタル」におけるこのメンバーの値は同じだ。

MP

モンスターの最大 MP だ。 ただし、255 が格納されているものについては、 モンスターパラメータの初期化時に 65535 にセットする。 これはプログラムにより、MP が無制限であることを意味する。

アイテム ID

戦闘終了後に最後に倒したモンスターが宝箱を落とすことがある。 そのアイテム ID だ。

初期状態

初期確率ビットが 1 であるモンスターが、 戦闘開始直後にラリホーまたはマホカンタ状態であることがある。 そのどちらの状態なのかを示すビットだ。

表 4.33 初期状態

0 ラリホー
1 マホカンタ


HP

モンスターの最大 HP だ。

経験値

戦闘終了後に倒したモンスターから得られる経験値だ。

モンスター名文字列 ID

ウィンドウに表示するモンスター名を表す文字列データの ID だ。

4.13.2. TODO リスト

  • 不明メンバー A, B, C, D の解析

  • 「すばやさ」 「レベル」 「行動タイプ」 「スライム系」 「複数回」 「集中攻撃」の完全な意味を知る