DQ3 ゲストキャラクター概念の追加1(戦闘中編1)

「特定のイベント中にしか仲間にならないキャラクター」というのを実装したいと思ったわけですが*1、通常のキャラクターと何が違うかというと、「戦闘中自分で操作できない」「アイテム欄を操作できない」「全滅条件が異なる」等が挙げられます。そのうち「戦闘中自分で操作できない」はAIを実装しない限り実現できないので諦めるとして、残りの2つについて実装してみることにします。

まず「全滅条件を変える」ですが、今回は「過去テドンイベント中に1人でも死んだら全滅」「幽霊船イベント中にPC側3人が死ぬorゲストキャラクターが死ぬ」の2つについて実装してみました。オリジナルの実装をよく理解すればその仕組みの中で実装可能です。とっかかりとして「全滅条件を特定の状況で変える」とは、戦闘終了判定の処理に例外処理を加えてやればいいということで、その処理を解析していくところから作業を始めます。

  • SR: $02B32F 戦闘終了時フラグセット?
02B356JSR $B3C5SR: $02B3C5PC側行動可能チェック

  • SR: $02B3C5 PC側行動可能チェック
02B3C5JSL $C2C739SR: $02C739 引数:1#$08行動可能チェック用マスクデータ作成
02B3CAJSL $C2C766SR: $02C766 引数:1#$00行動可能フラグセット・死亡キャラクターはフラグをOFFにする
02B3CFPEA #$2011Push #$2011
02B3D2PEA #$0040Push #$0040
02B3D5PEA #$7E00Push #$7E00格闘場の戦闘かチェック
02B3D8JSL $C9029ESR: $09029ERAM上情報取得
02B3DCBNE #$05if(z==off) goto $02B3E3
02B3DEJSL $C2C7C6SR: $02C7C6 引数:1#$28PC側行動可能フラグセット・麻痺キャラクターはフラグをOFFにする
02B3E3LDA $00A=DP($00)
02B3E5ORA $02Aor=DP($02)
02B3E7RTSreturn

  • SR: $02C739 行動可能チェック用マスクデータ作成
02C739PHPPush P Flag
02C73AREP #$30m=off(A/M:16b) x=off(X/Y:16b)
02C73CPHAPush A
02C73DPHXPush X
02C73EPHYPush Y
02C73FPHBPush DB
02C740PEA #$7E7EPush #$7E7E
02C743PLBPull DB
02C744PLBPull DB
02C745LDA #$FFFFA=#$FFFF下位から1ビットが戦闘中各キャラクターに相当する
02C748STA $2434$2434=A
02C74BLDA #$00FFA=#$00FF3バイト=24ビット分
02C74ESTA $2436$2436=A
02C751JSR $C7FBSR: $02C7FB呼び出し元の後の1バイトを引数として取得し行動可能フラグセット
02C754LDA $2438A=$2438
02C757STA $00DP($00)=A
02C759LDA $243AA=$243A
02C75CSTA $02DP($02)=A
02C75EPLBPull DB
02C75FREP #$30m=off(A/M:16b) x=off(X/Y:16b)
02C761PLYPull Y
02C762PLXPull X
02C763PLAPull A
02C764PLPPull P Flag
02C765RTLreturn

  • SR: $02C8F0 戦闘中各種フラグ作成用アドレスリスト_SR_0004
02C8F0LDA $203C,YA=$203C+Y
02C8F3AND #$00FFA&=#$00FF
02C8F6CMP #$0004A==or>=#$0004?キャラクターがPC側か格闘場で賭けたモンスターか
02C8F9RTSreturn

  • SR: $02C766 行動可能フラグセット
02C766PHPPush P Flag
02C767REP #$30m=off(A/M:16b) x=off(X/Y:16b)
02C769PHAPush A
02C76APHXPush X
02C76BPHYPush Y
02C76CPHBPush DB
02C76DPEA #$7E7EPush #$7E7E
02C770PLBPull DB
02C771PLBPull DB
02C772LDA $00A=DP($00)既にセット済みのフラグに対してのみマスクする
02C774STA $2434$2434=A
02C777LDA $02A=DP($02)既にセット済みのフラグに対してのみマスクする
02C779STA $2436$2436=A
02C77CJSR $C7FBSR: $02C7FB呼び出し元の後の1バイトを引数として取得し行動可能フラグセット
02C77FLDA $2438A=$2438
02C782STA $00DP($00)=A
02C784LDA $243AA=$243A
02C787STA $02DP($02)=A
02C789PLBPull DB
02C78AREP #$30m=off(A/M:16b) x=off(X/Y:16b)
02C78CPLYPull Y
02C78DPLXPull X
02C78EPLAPull A
02C78FPLPPull P Flag
02C790RTLreturn

  • SR: $02C8C8 戦闘中各種フラグ作成用アドレスリスト_SR_0000
02C8C8JSL $C2BE8ASR: $02BE8A 引数:1#$1C生死判定
02C8CDBCS #$02if(c==on) goto $02C8D1
02C8CFSECc=on
02C8D0RTSreturn
02C8D1CLCc=off
02C8D2RTSreturn

このSRを見ると戦闘終了の判定方法がわかります。DP($00~02)の3バイトを使って各1ビットが戦闘中の各キャラクター(0~23)を表現します。まず、SR: $02C739を使ってPC側に相当するビットを立てます(生死問わず)。次にSR: $02C766をコールしてONになっているビットに対して”のみ”生死判定を行い、死亡時にはビットをOFFにしていきます。SR: $C2C7C6も同様に麻痺しているキャラクターのビットをOFFにしています。この3つのSRをコールした時点でDP($00~02)には死亡していなくて麻痺していないキャラクターのビットだけがONになっている状態になります。従って、DP($00)とDP($02)を足して0でない場合はPC側は全滅していない、と判断出来ます。長くなったので続きは次回。

*1:DQ4のオーリンみたいなキャラクター

コメント

タイトルとURLをコピーしました