DQ6戦闘部分解説6

ようやく戦闘コマンドを入力するところまで来ました。

  • SR:$023803 戦闘コマンド入力
023803 PHP Push P Flag
023804 PHB Push DB
023805 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
023807 PEA #$7E7E Push #$7E7E
02380A PLB Pull DB
02380B PLB Pull DB
02380C PEA #$2513 Push #$2513
02380F PEA #$0003 Push #$0003
023812 PEA #$7E00 Push #$7E00
023815 JSL $C92965 SR: $092965
023819 CMP #$0002 A>=#$0002? 強襲状態ならコマンド入力をスキップ
02381C BCS #$57 if(c==on) goto $023875
02381E PEA #$2011 Push #$2011
023821 PEA #$0010 Push #$0010
023824 PEA #$7E00 Push #$7E00
023827 JSL $C92965 SR: $092965
02382B BNE #$4B if(z==off) goto $023878 格闘場ならコマンド入力をスキップ
02382D JSL $C2E939 SR: $02E939 引数:1#$00
023832 LDA #$0006 A=#$0006 PCのみ対象
023835 JSL $C2E966 SR: $02E966 引数:1#$02 ターゲット情報セット(味方で生存)
02383A JSL $C2E966 SR: $02E966 引数:1#$04 ターゲット情報セット(味方でグループIDが6?)
02383F JSL $C2E9C6 SR: $02E9C6 引数:1#$18 ターゲット情報セット(起きている)
023844 JSL $C2E9C6 SR: $02E9C6 引数:1#$50 ターゲット情報セット(休み中でない)
023849 LDA $00 A=DP($00)
02384B ORA $02 Aor=DP($02)
02384D BEQ #$29 if(z==on) goto $023878 コマンド入力をする必要のあるキャラクターがいるか
02384F JSL $C2CAC6 SR: $02CAC6
023853 JSR $3890 SR: $023890 行動情報リセット(PCのみ全部)
023856 LDA #$0001 A=#$0001
023859 JSL $C3B4F9 SR: $03B4F9
02385D LDA #$00D4 A=#$00D4 戦闘方針ウィンドウID
023860 JSL $C37236 SR: $037236 ウィンドウ描画+ユーザー入力を得る(キャンセルc=on)
023864 BCS #$E9 if(c==on) goto $02384F
023866 ASL A< <1
023867 TAX X=A
023868 JSR $38B3 SR: $($0238B3+X)
02386B BCS #$E2 if(c==on) goto $02384F
02386D JSL $C2CAC6 SR: $02CAC6
023871 JSL $C2CA59 SR: $02CA59
023875 PLB Pull DB
023876 PLP Pull P Flag
023877 RTL return
023878 JSR $3890 SR: $023890 行動情報リセット(PCのみ全部)
02387B JSL $C42B1C SR: $042B1C 引数:1#$01 引数:2#$FD パーティ人数取得
023881 DEY Y–
023882 BMI #$F1 if(n==on) goto $023875
023884 JSL $C2BB34 SR: $02BB34
023888 STX $258B $258B=X
02388B JSR $3965 SR: $023965
02388E BRA #$F1 goto $023881

このSRの中で戦闘コマンド入力処理を全て行っています。強襲時・格闘場の場合はコマンド入力をスキップ、PC側にコマンド入力ができるキャラクターがいなければスキップ等の判断を行っています。SR: $02E939、$02E966、$02E9C6は、DP($00)からDP($02)までの24ビットをフラグに見立てて戦闘中のキャラクターインデックスのそれぞれが条件に該当していればON、していなければOFFにするというもののようです。SR: $02E939のみ#$FFFFFFで初期化します。残りはすでにONになっているフラグに対してのみON/OFFの判断を行います。DP($00)とDP($02)をORするのは全て0になっているかを簡単に判別するためです。これをうまく使えばランダムターゲットの戦闘行動時にターゲットにするモンスターを安全に決定することができます。まず「敵のみ」のフラグをONにしてその中で「生存している」「戦闘に参加している」をONにすればその時点で存在しているインデックスのみフラグが立っている状態が出来上がります。これをビットの立っている中からランダム選択をするSR: $000F81に渡せばAレジスタに選択されたインデックスの値が入るのでそいつをターゲットにすればいい、ということになります。DQ3 K.Mixでぐんたいよびを実装した最初期の時点ではこの部分の解析をすっ飛ばしていたので自力でバグバグなランダムターゲットのコードを書く羽目になりましたが、この仕組がわかっていれば労力を使わず安全性の高いコードが書けたわけです。次回はまず戦闘方針ウィンドウ処理(たたかう、さくせん、にげる、いれかえ)の部分を見てから1人分の戦闘コマンドの処理を見ていくことにします。