DQ3戦闘部分解説16

  • SR: $027D53 戦闘行動実行処理メイン
027D53 STZ $23DA $23DA=#$00
027D56 STZ $2458 $2458=#$00
027D59 STZ $245A $245A=#$00
027D5C JSR $7E9D SR: $027E9D パルプンテ結果決定
027D5F JSR $7F10 SR: $027F10 行動後追加Msg表示?
027D62 JSR $7B52 SR: $027B52
027D65 LDA $00 A=DP($00)
027D67 STA $23EA $23EA=A
027D6A LDA $02 A=DP($02)
027D6C STA $23EC $23EC=A
027D6F JSL $C2CE9A SR: $02CE9A エフェクト描画
027D73 JSR $7DC4 SR: $027DC4 遊び人の火遊び処理
027D76 JSL $C28375 SR: $028375 1キャラクター行動開始時変数初期化処理
027D7A LDY #$0000 Y=#$0000
027D7D STZ $23FA $23FA=#$00
027D80 LDA #$0000 A=#$0000
027D83 PEA #$23AD Push #$23AD
027D86 PEA #$007F Push #$007F
027D89 PEA #$7E00 Push #$7E00
027D8C JSL $C902E9 SR: $0902E9 RAM上情報変更
027D90 JSR $7DD1 SR: $027DD1 メガンテ実行時の効果決定(即死かダメージか)
027D93 JSR $8400 SR: $028400 1キャラクター行動開始時変数初期化処理
027D96 BCS #$22 if(c==on) goto $027DBA
027D98 JSR $8426 SR: $028426 戦闘行動が対象に有効か調べる(無効c=on)
027D9B BCS #$1D if(c==on) goto $027DBA
027D9D JSR $8795 SR: $028795
027DA0 JSR $87B9 SR: $0287B9 一撃必殺武器ヒット判定(ヒットc=on)
027DA3 BCS #$15 if(c==on) goto $027DBA
027DA5 JSR $885E SR: $02885E 戦闘行動実体SR実行
027DA8 JSR $88B3 SR: $0288B3 攻撃により目が覚めた・我に返った処理
027DAB JSR $7E01 SR: $027E01 眠り毒麻痺追加攻撃処理
027DAE JSR $88CF SR: $0288CF もろはのつるぎ装備時の反射ダメージ処理
027DB1 JSR $896D SR: $02896D やいばのよろい装備時の反射ダメージ処理
027DB4 JSR $89C5 SR: $0289C5 なげきのたて装備時の反射ダメージ処理
027DB7 JSR $8A2C SR: $028A2C
027DBA INY Y++
027DBB CPY #$0018 Y>=#$0018?
027DBE BCC #$BD if(c==off) goto $027D7D
027DC0 JSR $8A96 SR: $028A96 戦闘行動追加処理
027DC3 RTS return

ここが実際の戦闘行動を実行している部分です。ポイントは「戦闘行動は参加キャラクター分全部に対して実行するかどうかの判断を行う」という点です。$027D7D-BEまでが1キャラクター分の実行部分に相当します。ターゲット情報(1体,グループ, 全体など)と照らし合わせて、#$01~$17までのキャラクターが実行対象になるかを判断して($027D98)、対象である場合のみ実行する、というようになっています。戦闘行動($020060-)の「行動プログラムアドレス」で指定している開始アドレスは$027DA5で呼ばれます。つまり、「行動プログラムアドレス」に記述されている処理は「対象1体に対してのみの処理」を記述することが期待されます。対象選択は「対象数」「選択対象」の値でコントロールすることになります。また、メガンテの術者死亡処理など1回だけ実行させたい処理は$027DC0で呼ばれるように設定する必要があります。

  • SR: $027E9D パルプンテ結果決定
027E9D LDA $23EE A=$23EE
027EA0 CMP #$0048 A==#$0048? 戦闘行動がパルプンテの場合
027EA3 BNE #$07 if(z==off) goto $027EAC
027EA5 JSL $C2CE9A SR: $02CE9A エフェクト描画
027EA9 JSR $7EAD SR: $027EAD パルプンテ結果選択処理
027EAC RTS return
  • SR: $027EAD パルプンテ結果選択処理
027EAD LDA #$FFFF A=#$FFFF
027EB0 STA $00 DP($00)=A
027EB2 STZ $02 DP($02)=#$00
027EB4 PEA #$2011 Push #$2011
027EB7 PEA #$0020 Push #$0020
027EBA PEA #$7E00 Push #$7E00
027EBD JSL $C9029E SR: $09029E イベント戦闘かチェック
027EC1 BEQ #$07 if(z==on) goto $027ECA
027EC3 LDA $00 A=DP($00)
027EC5 AND #$E504 A&=#$E504 イベント戦闘の場合は一部の結果は選択対象外にする
027EC8 STA $00 DP($00)=A
027ECA LDX #$0000 X=#$0000
027ECD JSL $C01407 SR: $001407 乱数発生 $0000-FFFF dp,Xの1になっているビットをランダムで0にする?
027ED1 BCC #$FE if(c==off) goto $027ED1
027ED3 ASL A<<1
027ED4 TAX X=A
027ED5 LDA $C27EF0,X A=$027EF0+X パルプンテ結果配列から結果の戦闘行動を取得する
027ED9 JSR $75C6 SR: $0275C6
027EDC STA $242A $242A=A
027EDF LDA $23E4 A=$23E4
027EE2 STA $2428 $2428=A
027EE5 JSL $C270F2 SR: $0270F2
027EE9 LDA $2430 A=$2430
027EEC STA $23E6 $23E6=A
027EEF RTS return

パルプンテ実行時の結果の選択は、SR: $001407をコールして、#$FFFFの中からランダムでビットをOFFにしていき、ONになっているビットが1つだけになるまで繰り返し(c=onで判定)、その際にONになっているビットの下から数えて何番目か(例:0008なら3、1000なら12)をAレジスタにセットさせることで、パルプンテ結果戦闘行動IDの配列($027EF0-)へのオフセット作っています。イベント戦闘フラグがONになっている場合は、都合の悪い結果(全員会心、くだけちる)などはビットをOFFにして元から選択されないようになっています。$E504=1110010100000100なので、実行されるのはべホイミ(味方)、べホマラー(味方)、オールザオリク、ならびかたかえる、やまびこ、オールキアリクだけ、ということになります。ちなみにK.Mixで実装した「遊び人の使える遊び」の選択はこの部分をパクった参考にしたものです。次回以降のエントリで説明しますが、毒針等の一撃死も同様で、イベント戦闘中には発生しないようになっています。