DQ6戦闘部分解説1

DQ6 Extendedの作成はまあ順調に進んでおり、ひとつの山だと思っていた移動中のメッセージを解凍した状態でROMに書き戻し+デコードプログラムの変更は1日であっさり終わってしまいました(デコードプログラムの部分はDQ3 Extendedの該当箇所を真似ただけなので大したことはやってないのですが)。セーブデータの拡張が必要なアイテムの前に戦闘行動とモンスターの拡張作業を先にやっていますが、モンスター数の変更は意外とやるべきことが多そうでまだまともに動いていません。戦闘が始まると即全滅扱いになったり、それを直したら今度は味方が混乱状態になったりと、さすがに公開前にひと通りのテストプレイは必要な感じです。

今回から新たなネタとしてDQ6の戦闘部分の解析をしていこうと思います。AIに関してはすでに解析済みなのでそこだけ飛ばします。大部分はすでに解析の終わっているDQ3の戦闘部分と同じと思われますが、「だいたい同じだから」といって飛ばさずに解説していこうと思います。

  • SR: $0233B7 戦闘メインループ
0233B7 PHP Push P Flag
0233B8 PHB Push DB
0233B9 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
0233BB PEA #$7E7E Push #$7E7E
0233BE PLB Pull DB
0233BF PLB Pull DB
0233C0 JSL $C47A93 SR: $047A93 時の砂使用時に備えて戦闘開始時の状態をバックアップ
0233C4 JSL $C2345E SR: $02345E 戦闘中使用RAM領域初期化
0233C8 JSL $C23474 SR: $023474 PC側戦闘中情報セット
0233CC JSL $C234A4 SR: $0234A4 モンスター側戦闘中情報セット
0233D0 JSL $C2BF22 SR: $02BF22 時の砂使用時処理
0233D4 PEA #$2514 Push #$2514
0233D7 PEA #$001E Push #$001E
0233DA PEA #$7E00 Push #$7E00
0233DD JSL $C92965 SR: $092965 RAM上情報取得
0233E1 BNE #$43 if(z==off) goto $023426
0233E3 JSL $C23555 SR: $023555
0233E7 JSL $C236A9 SR: $0236A9 アストロン解除処理
0233EB JSL $C23803 SR: $023803 戦闘コマンド入力
0233EF JSL $C2BF22 SR: $02BF22 時の砂使用時処理
0233F3 PEA #$2514 Push #$2514
0233F6 PEA #$001E Push #$001E
0233F9 PEA #$7E00 Push #$7E00
0233FC JSL $C92965 SR: $092965 RAM上情報取得
023400 BNE #$24 if(z==off) goto $023426
023402 JSL $C2375D SR: $02375D 1ターン中の素早さ値決定
023406 JSL $C241C4 SR: $0241C4 行動開始前リセット処理
02340A JSL $C23F73 SR: $023F73
02340E JSL $C2541B SR: $02541B
023412 PEA #$2514 Push #$2514
023415 PEA #$001E Push #$001E
023418 PEA #$7E00 Push #$7E00
02341B JSL $C92965 SR: $092965 RAM上情報取得
02341F BNE #$05 if(z==off) goto $023426
023421 JSR $342F SR: $02342F 格闘場ターン数カウント処理(ターン数オーバーc=on)
023424 BCC #$C1 if(c==off) goto $0233E7
023426 JSL $C2ACFF SR: $02ACFF 戦闘終了判定
02342A BCS #$98 if(c==on) goto $0233C4
02342C PLB Pull DB
02342D PLP Pull P Flag
02342E RTL return

これが戦闘処理のメインループです。例によって通常戦闘、ボス戦、スライム格闘場、デスタムーアvsダークドレアムのイベント戦闘まで全てをこの中で行います。

  • SR: $047A93 時の砂使用時に備えて戦闘開始時の状態をバックアップ
047A93 PHP Push P Flag
047A94 PHB Push DB
047A95 SEI i=on
047A96 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
047A98 PHA Push A
047A99 PHX Push X
047A9A PHY Push Y
047A9B PEA #$7E7E Push #$7E7E
047A9E PLB Pull DB
047A9F PLB Pull DB
047AA0 LDX #$3EA0 X=#$3EA0 作戦IDから各キャラクターデータまでをバックアップ
047AA3 LDY #$2800 Y=#$2800 $7E2800-2D75に退避する
047AA6 LDA $0000,X A=$0000+X
047AA9 STA $0000,Y $0000+Y=A
047AAC INY Y++
047AAD INY Y++
047AAE INX X++
047AAF INX X++
047AB0 CPX #$4415 X>=#$4415?
047AB3 BCC #$F1 if(c==off) goto $047AA6
047AB5 PLY Pull Y
047AB6 PLX Pull X
047AB7 PLA Pull A
047AB8 PLB Pull DB
047AB9 PLP Pull P Flag
047ABA RTL return

まずは最初のSRから。DQ6では時の砂があるため、戦闘中に戦闘開始時に戻るケースがあります。いつでもその状態に戻れるように作戦、ふくろのアイテム、所持金(ぐんたいよびで減るから)、各キャラクターのステータスなどをまるごとバックアップしておく必要があります。処理自体はクイックセーブ、クイックロードのように特定の領域の値を別の場所にまるごとコピーしておくだけです。