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


コメント