DQ3戦闘部分解説3

今回は戦闘中に各種情報にアクセスするSRを見ていきます。よく出てくるSRは

  • 戦闘行動構造体アクセスSR
  • 固定情報(モンスターの耐性情報など)アクセスSR
  • 戦闘中情報取得/更新SR

です。大概の処理はこれらのSRを駆使すれば事足ります。
(※2016-10-15更新)

  • 戦闘中キャラクター情報取得系SR群(結果はAにセット)
アドレス 引数1 引数2 ビットシフト インデックス指定
$02CA5B オフセット X
$02CA62 オフセット Y
$02CAD9 オフセット ビットマスク あり X
$02CAE0 オフセット ビットマスク あり Y
$02CB2B オフセット ビットマスク あり(バグ?) X
$02CB32 オフセット ビットマスク なし Y

ここでいう「ビットシフトの有無」というのは得られた値を右(下位ビット)に寄せるかどうか、ということです。具体的には

  • SR:$027C68 MP切れ・マホトーン・呪いで行動できないか決定する
027CA1 JSL $C2CB32 SR: $02CB32 引数:1#$2051 引数:2#$0002 戦闘中キャラクター情報取得 インデックス:Y(ビットシフトなし)
027CA9 BNE #$23 if(z==off) goto $027CCE マホトーン中なら動作を変える

このSRをコールして対象がマホトーン中だった場合、Aレジスタには#$0002がセットされて返ってきます。このSRをビットシフトありの$02CAE0に変えると#$0001がセットされて返ってきます。大抵は上記のようにON/OFFのみをチェックしているので問題ありませんが、返ってきた値をみて動作を変えるような場合は注意が必要です。ここで1点問題になるのがXをインデックスにとるSR: $02CAD9とSR: $02CB2Bです。

  • SR:$02CAD9 戦闘中キャラクター情報取得 インデックス:X(ビットシフトあり)
02CAD9 PHP Push P Flag
02CADA PHB Push DB
02CADB REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02CADD TXA A=X
02CADE BRA #$05 goto $02CAE5
  • SR:$02CB2B 戦闘中キャラクター情報取得 インデックス:X(ビットシフトあり)
02CB2B PHP Push P Flag
02CB2C PHB Push DB
02CB2D REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02CB2F TXA A=X
02CB30 BRA #$B3 goto $02CAE5 実体へのジャンプ先がSR: $02CAD9と同じ

この周辺のSRはインデックスをXに取るSRは実体を持たず、実体はインデックスをYに取るSRの途中に飛ばして無駄な重複を省いています。問題はSR: $02CB2Bの方で、ジャンプ先がビットシフトありのSRの途中になっています。したがって、「インデックスをXに取るSRでビットシフトなしのSRは存在しない」状態になっています。恐らくバグではないかと思いますが、実際にSR: $02CB2Bをコールしている箇所(27箇所)を調べてみましたが、たまたま問題ないケースでした(DQ3 K.MixではこれらのSRの違いを余り意識していなかったのでごちゃ混ぜで使いまくっていました)。どれもON/OFFのチェックでしか使っていないか、ビットマスクがシフトの必要のない#$00FFや#$01FFだったので問題がなかったようです。顕在化はしませんが潜在的なバグとも言えます。

  • 戦闘中キャラクター情報変更系SR群
アドレス 引数1 引数2 ビットシフト インデックス指定 セット値
$02CA98 オフセット X A
$02CB70 オフセット ビットマスク あり X A
$02CB79 オフセット ビットマスク あり Y A
  • 戦闘行動構造体取得系SR群(結果はAにセット)
アドレス 引数1 引数2 インデックス指定
$2CC03 オフセット X
$2CC0A オフセット Y
$2CC25 オフセット ビットマスク X
$2CC2C オフセット ビットマスク Y
$2CC47 オフセット ビットマスク(3バイトにまたがる場合) X
$2CC4E オフセット ビットマスク(3バイトにまたがる場合) Y

「オフセット」は1レコード目の開始アドレス(2バイト)+オフセットを意味します。例えば戦闘中キャラクター情報の素早さ(オフセット:#$14-)の場合には1レコード目の開始アドレス(7E)2020+0014で2034を指定しています。戦闘行動構造体へのアクセスは拡張パッチとオリジナルで戦闘行動構造体の場所が変わっているのでこの値が異なります。バンク$02には戦闘行動構造体にアクセスしている場所が無数にありますが、その1つ1つを書き換える作業をしたわけで作業をした方(多分86氏)にはマジ感謝です。

戦闘中情報取得/変更については、以前にも載せましたが、他とまとめて再掲します。

  • SR: $02BE8A 戦闘中情報取得/変更($7E2428に対象インデックスがセットされていることが前提)
引数 意味
00 現HP取得
02 現HP変更
04 HP加算処理
06 HP減算処理
08 現MP取得
0A 現MP変更
0C MP加算処理
0E MP減算処理
10 毒かチェック on:毒 off:毒でない
12 毒回復
14 毒にする
16 麻痺かチェック on:麻痺 off:麻痺でない
18 麻痺回復
1A 麻痺にする
1C 生死判定 on:死亡 off:生きている
1E 毒麻痺HP回復?
20 アストロン残りターン数取得
22 敵味方判定 on:敵 off:味方
24 職業ID取得
26 時間を止めたキャラクター情報取得
28 混乱かチェック on:混乱 off:混乱でない
2A 混乱回復
2C 混乱にする
2E 性別取得
  • SR: $02C240 キャラクター固定情報取得($7E2428に対象インデックスがセットされていることが前提)
引数 意味
00 最大HP取得
02 最大MP取得
04 攻撃力取得
06 守備力取得
08 素早さ取得
0A レベル取得
0C 回避率分子取得
0E 知能パターン取得(モンスターのみ有効?)
10 行動回数情報取得(モンスターのみ有効?)
12 自然回復量取得(モンスターのみ有効?)
14 集中攻撃情報取得(モンスターのみ有効?)
16 現在の戦闘行動に対応する耐性情報取得

これらのSRは対象がPCであろうがモンスターであろうが有効です。内部で対象のキャラクターの敵味方フラグを見て対応するSR配列を呼び出すことでラップしているため、コールする側ではPCであろうがモンスターであろうが意識する必要がありません。ここは非常によく出来てると思います。