DQ3戦闘部分解説22

戦闘行動の実体の説明がひと通り終わったので、その後の処理に戻ります。SR: $027D53の後半部分$027DA8以降から続きを見ていきます。

  • SR: $0288CF 眠り毒麻痺追加攻撃処理
0288CF PHY Push Y
0288D0 LDA $23FA A=$7E23FA ダメージ値が0ならスキップ
0288D3 BEQ #$27 if(z==on) goto $0288FC
0288D5 LDY $23E8 Y=$7E23E8
0288D8 STY $2428 $7E2428=Y
0288DB JSL $02CB32 SR: $02CB32 引数:1#$2050 引数:2#$0002 生死判定?
0288E3 BEQ #$17 if(z==on) goto $0288FC 死んでいたらスキップ
0288E5 JSL $02BE8A SR: $02BE8A 引数:1#$1C 生死判定?
0288EA BCS #$10 if(c==on) goto $0288FC 死んでいたらスキップ
0288EC LDX #$0004 X=#$0004
0288EF LDA $23EE A=$7E23EE
0288F2 CMP $028903,X A==$028903+X? 戦闘行動と眠り毒麻痺攻撃の戦闘行動IDとのマッチング
0288F6 BEQ #$06 if(z==on) goto $0288FE
0288F8 DEX X–
0288F9 DEX X–
0288FA BPL #$F6 if(n==off) goto $0288F2
0288FC PLY Pull Y
0288FD RTS return
0288FE JSR $8909 SR: $($028909+X)
028901 PLY Pull Y
028902 RTS return
  • SR: $02890F 眠り攻撃
02890F JSL $02A406 SR: $02A406 成否判定?
028913 BCC #$28 if(c==off) goto $02893D
028915 JSL $02B5D8 SR: $02B5D8 状態:眠り処理
028919 BCS #$22 if(c==on) goto $02893D
02891B JSL $02B977 SR: $02B977 パーティウィンドウ再描画?
02891F LDA #$0041 A=#$0041 戦闘メッセージ:「ねむってしまった!」
028922 PHA Push A
028923 LDY $23E8 Y=$7E23E8
028926 JSL $02CAE0 SR: $02CAE0 引数:1#$203C 引数:2#$00FF グループID取得
02892E CMP #$0004 A>=#$0004? PCor格闘場で賭けたモンスター
028931 BCS #$05 if(c==on) goto $028938
028933 LDA #$0040 A=#$0040 戦闘メッセージ:「ねむらせた!」
028936 STA $01,S Stack($01)=A
028938 PLA Pull A
028939 JSL $01A87A SR: $01A87A 戦闘メッセージ表示
02893D RTS return
  • SR: $02893E 毒攻撃
  • SR: $028956 マヒ攻撃

ほとんど一緒なので省略

  • SR: $02896D もろはのつるぎ装備時の反射ダメージ処理
02896D LDA $23F2 A=$7E23F2 ダメージ値が0ならスキップ
028970 BNE #$52 if(z==off) goto $0289C4
028972 LDX $23EE X=$7E23EE
028975 JSL $02CC25 SR: $02CC25 引数:1#$0079 引数:2#$0008 戦闘行動がもろはのつるぎの反射ダメージが発生する戦闘行動か
02897D BEQ #$45 if(z==on) goto $0289C4
02897F LDX $23E4 X=$7E23E4
028982 STX $2428 $7E2428=X 行動主体をセット
028985 JSL $02CB2B SR: $02CB2B 引数:1#$2050 引数:2#$0002 生死判定?
02898D BEQ #$35 if(z==on) goto $0289C4 死んでいたらスキップ
02898F JSL $02BE8A SR: $02BE8A 引数:1#$1C 生死判定?
028994 BCS #$2E if(c==on) goto $0289C4 死んでいたらスキップ
028996 LDA #$0015 A=#$0015 もろはのつるぎのアイテムID
028999 STA $242C $7E242C=A
02899C JSL $02B87A SR: $02B87A アイテム装備チェック
0289A0 BVC #$22 if(v==off) goto $0289C4
0289A2 LDA $23FA A=$7E23FA
0289A5 BEQ #$1D if(z==on) goto $0289C4
0289A7 PHA Push A
0289A8 LSR A>>1
0289A9 LSR A>>1
0289AA INC A++ ダメージ1/4(+1)化
0289AB STA $23FA $7E23FA=A ダメージ値セット
0289AE LDA $23E8 A=$7E23E8
0289B1 PHA Push A
0289B2 LDA $23E4 A=$7E23E4
0289B5 STA $23E8 $7E23E8=A 行動主体を行動対象としてセット
0289B8 JSL $029200 SR: $029200 ダメージ確定後の処理メイン
0289BC PLA Pull A
0289BD STA $23E8 $7E23E8=A 行動対象をもとに戻す
0289C0 PLA Pull A
0289C1 STA $23FA $7E23FA=A ダメージ値をもとに戻す
0289C4 RTS return
  • SR: $0289C5 やいばのよろい装備時の反射ダメージ処理
  • SR: $028A2C なげきのたて装備時の反射ダメージ処理

ほとんど一緒なので省略

DQ3SFC K.Mixで実装した「きせきのつるぎによる回復処理」はこの部分を真似ただけです。

次に、割と重要な「戦闘行動実行後追加処理を行う」部分について説明します。これは1回の行動で1回しか発生してはいけない部分を実装するようにします(例:メガンテ発動による術者死亡、パルプンテの並び替え処理、仲間を呼ぶ処理など)

  • SR: $028A96 戦闘行動実行後の追加処理
028A96 LDX #$0024 X=#$0024
028A99 LDA $23EE A=$7E23EE
028A9C CMP $028AAB,X A==$028AAB+X? 追加処理が必要な戦闘行動リストと現在の戦闘行動をマッチング
028AA0 BEQ #$05 if(z==on) goto $028AA7
028AA2 DEX X–
028AA3 DEX X–
028AA4 BPL #$F6 if(n==off) goto $028A9C
028AA6 RTS return
028AA7 JSR $8AD1 SR: $($028AD1+X) 対応した追加処理SRを実行する
028AAA RTS return

オリジナルでは、追加処理が実行される戦闘行動は以下のとおりです。

00 メガンテ
01 アストロン
02 フバーハ
03 じかんとまる
04 くらやみ
05 びっくり
06 キメラのつばさ
07 ならびかたかえる
08 仲間呼び(同種)
09 仲間呼び(ホイミスライム)
0A 仲間呼び(だいまじん)
0B 仲間呼び(くさったしたい)
0C 仲間呼び(ごくらくちょう)
0D 仲間呼び(ゾンビマスター)
0E いてつくはどう
0F どうぐをつかう
10 オールかいしん
11 オールザオリク
12 ルーラ

戦闘行動によっては、各キャラクターに対して実行される戦闘行動実体の中身が空で、こちらに実体が実装されているものも多いです。主に全体に影響を及ぼすものが多いですね。また例によっていくつかピックアップして解説します。

  • SR: $028B6A メガンテ追加処理
028B6A JSR $8B71 SR: $028B71 メガンテ術者死亡処理
028B6D JSR $8BA6 SR: $028BA6 意味なし?
028B70 RTS return
  • SR: $028B71 メガンテ術者死亡処理
028B71 PEA $23AE Push $23AE
028B74 PEA $0004 Push $0004
028B77 PEA $7E00 Push $7E00
028B7A JSL $09029E SR: $09029E メガンテ発動フラグチェック
028B7E BEQ #$25 if(z==on) goto $028BA5
028B80 LDA $23E4 A=$7E23E4 行動主体を対象にセット
028B83 STA $2428 $7E2428=A
028B86 LDA #$FFFF A=#$FFFF
028B89 STA $00 $000000=A 65535を減算する
028B8B JSL $02BE8A SR: $02BE8A 引数:1#$06 HP減算処理
028B90 BCC #$13 if(c==off) goto $028BA5
028B92 JSL $02B977 SR: $02B977 パーティウィンドウ再描画?
028B96 JSL $02D0C2 SR: $02D0C2 メガンテ実行時エフェクト処理
028B9A LDA #$0015 A=#$0015 戦闘メッセージID
028B9D JSL $01A87A SR: $01A87A 戦闘メッセージ:「ちからつき いきたえた」
028BA1 JSL $02B054 SR: $02B054 行動対象者を戦闘から離脱させる処理メイン
028BA5 RTS return
  • SR: $028C22 ならびかえ(パルプンテ効果)
028C22 LDA #$0000 A=#$0000
028C25 STA $2484 $7E2484=A
028C28 STA $2486 $7E2486=A
028C2B STA $2488 $7E2488=A
028C2E STA $248A $7E248A=A
028C31 STA $4054 $7E4054=A
028C34 INC A++
028C35 STA $4056 $7E4056=A
028C38 INC A++
028C39 STA $4058 $7E4058=A
028C3C INC A++
028C3D STA $405A $7E405A=A
028C40 JSL $04297C SR: $04297C 引数:1#$01 引数:2#$FE パーティ人数取得(人数をXにセット)
028C46 DEX X–
028C47 BMI #$0F if(n==on) goto $028C58
028C49 TXA A=X
028C4A ASL A<<1
028C4B TAY Y=A
028C4C JSL $043115 SR: $043115 引数:1#$01 引数:2#$FE 引数:3#$FF 現在HP取得(HPをAにセット)
028C53 STA $2484,Y $7E2484+Y=A
028C56 BRA #$EE goto $028C46
028C58 LDX #$0000 X=#$0000
028C5B TXY Y=X
028C5C LDA $2484,X A=$7E2484+X
028C5F CMP $2486,Y A>=$7E2486+Y?
028C62 BCS #$1C if(c==on) goto $028C80
028C64 LDA $2484,X A=$7E2484+X
028C67 PHA Push A
028C68 LDA $2486,Y A=$7E2486+Y
028C6B STA $2484,X $7E2484+X=A
028C6E PLA Pull A
028C6F STA $2486,Y $7E2486+Y=A
028C72 LDA $4054,X A=$7E4054+X
028C75 PHA Push A
028C76 LDA $4056,Y A=$7E4056+Y
028C79 STA $4054,X $7E4054+X=A
028C7C PLA Pull A
028C7D STA $4056,Y $7E4056+Y=A
028C80 INY Y++
028C81 INY Y++
028C82 CPY #$0006 Y>=#$0006 ?
028C85 BCC #$D5 if(c==off) goto $028C5C
028C87 INX X++
028C88 INX X++
028C89 CPX #$0006 X>=#$0006 ?
028C8C BCC #$CD if(c==off) goto $028C5B
028C8E JSL $042B6A SR: $042B6A 並び替え?
028C92 JSL $02B977 SR: $02B977 パーティウィンドウ再描画?
028C96 LDA #$0042 A=#$0042
028C99 STA $23E8 $7E23E8=A
028C9C JSL $01A867 SR: $01A867 引数:1#$0079 戦闘メッセージ:「ならびかたが かわった」
028CA2 RTS return

この処理も最近まで謎だったのですが、完全ランダムではなく、どうやら「HPの高い順に並び替えをする」という処理をしているようです。言われてみるとたしかに、HPの高い順だったような。

  • SR: $028CF1 仲間を呼ぶ(ホイミスライム)
028CF1 LDA #$000A A=#$000A ホイミスライムのモンスターID
028CF4 JSR $8D14 SR: $028D14 仲間を呼んだ場合のモンスター追加メイン
028CF7 RTS return
  • SR: $028D14 仲間を呼んだ場合のモンスター追加メイン
028D14 STA $2420 $7E2420=A
028D17 STA $2424 $7E2424=A
028D1A LDA #$0000 A=#$0000
028D1D STA $241E $7E241E=A
028D20 STA $2422 $7E2422=A
028D23 JSL $02B7ED SR: $02B7ED モンスターを追加できるか判定(追加できないc=on)?
028D27 BCS #$1D if(c==on) goto $028D46
028D29 JSL $02AB00 SR: $02AB00 新規キャラクター追加
028D2D LDA $2428 A=$7E2428
028D30 CMP #$FFFF A==#$FFFF?
028D33 BEQ #$11 if(z==on) goto $028D46
028D35 STA $23E8 $7E23E8=A
028D38 JSL $01A867 SR: $01A867 引数:1#$008F 戦闘メッセージ:「〇〇が あらわれた」
028D3E LDX $2428 X=$7E2428
028D41 JSL $02B52D SR: $02B52D 戦闘中キャラクター行動情報初期化
028D45 RTS return
028D46 JSL $01A867 SR: $01A867 引数:1#$0090 戦闘メッセージ:「しかし たすけはこなかった」
028D4C RTS return

SR: $02B7EDより下は画面中にモンスターを新しく表示するだけのスペースが有るかどうかの判定をしているようで、用途の分からないRAMアドレスが頻出します。自分も何をやってるかいまいちよくわかりません。