DQ3戦闘部分解説17

  • SR: $027F10 行動後追加メッセージ表示
027F10 LDX #$0050 X=#$0050 オフセットの最後尾
027F13 LDA $23EE A=$23EE 現在の戦闘行動
027F16 CMP $C27F25,X A==$027F25+X? 追加メッセージ配列とのつきあわせ
027F1A BEQ #$05 if(z==on) goto $027F21
027F1C DEX X–
027F1D DEX X–
027F1E BPL #$F6 if(n==off) goto $027F16
027F20 RTS return
027F21 JSR $7F77 SR: $($027F77+X) 対応したSRを呼び出す
027F24 RTS return

「行動後追加メッセージ」というのは王者の剣を使った直後に表示される「とどろく らいめいが くうきを ひきさく!」のメッセージ表示のことを指します。現在の戦闘行動と行動後追加メッセージを表示する戦闘行動配列($027F25-)を後ろからつきあわせ、一致するものがあった場合は、同じ順番で並んでいる行動後追加メッセージ表示用SR配列($027F77-)を呼び出す、というものです。この方式はほかにも何箇所か使われているので覚えておくといいでしょう。

  • SR: $027B52 ターゲット確定?(詳細不明のため省略)
  • SR: $027DD1 メガンテ実行時の結果選択処理
027DD1 LDA $23EE A=$23EE
027DD4 CMP #$001A A==#$001A? 戦闘行動がメガンテか
027DD7 BNE #$27 if(z==off) goto $027E00
027DD9 LDX $23E4 X=$23E4
027DDC JSL $C2CAD9 SR: $02CAD9 引数:1#$203C 引数:2#$00FF
027DE4 CMP #$0005 A>=#$0005? 行動主体がモンスターか
027DE7 BCS #$17 if(c==on) goto $027E00
027DE9 JSL $C012D1 SR: $0012D1 乱数発生 $00-FF
027DED LSR A>>1
027DEE BCS #$10 if(c==on) goto $027E00 1/2の確率でくだけちる
027DF0 LDA #$0001 A=#$0001
027DF3 PEA #$23AD Push #$23AD
027DF6 PEA #$0040 Push #$0040
027DF9 PEA #$7E00 Push #$7E00
027DFC JSL $C902E9 SR: $0902E9 RAM上情報変更
027E00 RTS return
  • SR: $028426 戦闘行動が対象に有効か調べる(無効c=on)
028426 PHY Push Y
028427 LDX $23EE X=$23EE 戦闘行動をXにセット
02842A LDY $23E8 Y=$23E8 行動対象をYにセット
02842D STY $2428 $2428=Y
028430 JSL $C2CB32 SR: $02CB32 引数:1#$2050 引数:2#$0002
028438 BEQ #$2A if(z==on) goto $028464
02843A JSR $84DE SR: $0284DE 戦闘行動の対象が生者のみの場合に対象が生きているか判定?
02843D BCS #$25 if(c==on) goto $028464
02843F JSR $8467 SR: $028467 戦闘行動がくしゃみ($CA)で対象が行動主体か?
028442 BCS #$20 if(c==on) goto $028464
028444 JSR $84BB SR: $0284BB
028447 JSR $848A SR: $02848A くしゃみメイン処理
02844A JSR $8475 SR: $028475
02844D JSR $857E SR: $02857E 行動対象がアストロン中の処理
028450 BCS #$12 if(c==on) goto $028464
028452 JSR $85C5 SR: $0285C5 行動対象がマホカンタ中の処理
028455 BCS #$D9 if(c==on) goto $028430
028457 JSR $8690 SR: $028690 直接攻撃回避判定
02845A BCS #$08 if(c==on) goto $028464
02845C JSR $84F2 SR: $0284F2 直接攻撃ヒット判定
02845F BCS #$03 if(c==on) goto $028464
028461 PLY Pull Y
028462 CLC c=off
028463 RTS return
028464 PLY Pull Y
028465 SEC c=on
028466 RTS return
  • SR: $02857E 行動対象がアストロン中の処理
02857E JSL $C2CC47 SR: $02CC47 引数:1#$007A 引数:2#$0004 戦闘行動がアストロンに依存するか
028586 CLC c=off
028587 BEQ #$3B if(z==on) goto $0285C4
028589 JSL $C2BE8A SR: $02BE8A 引数:1#$20 アストロン残りターン数取得
02858E BCC #$34 if(c==off) goto $0285C4
028590 PEA #$23AE Push #$23AE
028593 PEA #$0008 Push #$0008
028596 PEA #$7E00 Push #$7E00
028599 JSL $C9029E SR: $09029E RAM上情報取得
02859D BNE #$24 if(z==off) goto $0285C3
02859F LDA $23E8 A=$23E8
0285A2 PHA Push A
0285A3 LDA $23E6 A=$23E6
0285A6 STA $23E8 $23E8=A
0285A9 JSL $C1A867 SR: $01A867 引数:1#$006E 「てつのかたまりとなり…」メッセージ表示
0285AF PLA Pull A
0285B0 STA $23E8 $23E8=A
0285B3 LDA #$0001 A=#$0001
0285B6 PEA #$23AE Push #$23AE
0285B9 PEA #$0008 Push #$0008
0285BC PEA #$7E00 Push #$7E00
0285BF JSL $C902E9 SR: $0902E9 RAM上情報変更
0285C3 SEC c=on
0285C4 RTS return
  • SR: $0285C5 行動対象がマホカンタ中の処理
0285C5 PEA #$23AD Push #$23AD
0285C8 PEA #$0004 Push #$0004
0285CB PEA #$7E00 Push #$7E00
0285CE JSL $C9029E SR: $09029E すでにマホカンタ中ならもう反射しない?
0285D2 CLC c=off
0285D3 BNE #$2F if(z==off) goto $028604
0285D5 JSL $C2BE8A SR: $02BE8A 引数:1#$00 HP取得(なぜ?)
0285DA STA $247C $247C=A
0285DD JSR $8659 SR: $028659 行動種別がマホカンタに影響されるか?
0285E0 BCC #$22 if(c==off) goto $028604
0285E2 JSR $867B SR: $02867B 行動対象がマホカンタ中?
0285E5 BCC #$1D if(c==off) goto $028604
0285E7 JSR $8605 SR: $028605 マホカンタ処理前半
0285EA LDY $23E4 Y=$23E4
0285ED STY $2428 $2428=Y
0285F0 STY $23E8 $23E8=Y
0285F3 LDA #$0001 A=#$0001
0285F6 PEA #$23AD Push #$23AD
0285F9 PEA #$0004 Push #$0004
0285FC PEA #$7E00 Push #$7E00
0285FF JSL $C902E9 SR: $0902E9 マホカンタ中フラグON?
028603 SEC c=on
028604 RTS return

ちょっと中途半端ですが、今回はここまでにします。

(11/25追記)
エントリを分けるのはどうかと思ったのでここに追記。

  • SR: $028690 直接攻撃回避判定
028690 LDA $23F2 A=$23F2
028693 BNE #$38 if(z==off) goto $0286CD
028695 JSL $C2CC47 SR: $02CC47 引数:1#$0079 引数:2#$0010 攻撃により我に返る(直接攻撃扱い?)
02869D BEQ #$2E if(z==on) goto $0286CD
02869F JSL $C2B774 SR: $02B774 会心・毒針ヒット関連?
0286A3 CMP #$0001 A==#$0001?
0286A6 BEQ #$25 if(z==on) goto $0286CD
0286A8 JSL $C2BE8A SR: $02BE8A 引数:1#$16 マヒ状態取得
0286AD BCS #$1E if(c==on) goto $0286CD
0286AF JSL $C2CB32 SR: $02CB32 引数:1#$2047 引数:2#$00FF 眠りの深さ取得
0286B7 BNE #$14 if(z==off) goto $0286CD
0286B9 JSR $86EC SR: $0286EC 行動主体者が混乱している場合のターゲット変更?
0286BC BCS #$0F if(c==on) goto $0286CD
0286BE JSR $873E SR: $02873E 回避判定(通常)
0286C1 BCC #$0C if(c==off) goto $0286CF
0286C3 JSR $875F SR: $02875F 回避判定(特殊)
0286C6 BCC #$07 if(c==off) goto $0286CF
0286C8 JSR $86DB SR: $0286DB タップダンス中の回避判定?
0286CB BCC #$02 if(c==off) goto $0286CF
0286CD CLC c=off
0286CE RTS return
0286CF JSL $C2B6D9 SR: $02B6D9 直接攻撃ミス効果音
0286D3 JSL $C1A867 SR: $01A867 引数:1#$0010 「すばやくみをかわした!」メッセージ表示
0286D9 SEC c=on
0286DA RTS return
  • SR: $02869F 会心・毒針ヒット関連?
02B774 PHP Push P Flag
02B775 PHB Push DB
02B776 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B778 PEA #$7E7E Push #$7E7E
02B77B PLB Pull DB
02B77C PLB Pull DB
02B77D PHX Push X
02B77E PHY Push Y
02B77F LDA $2428 A=$2428
02B782 PHA Push A
02B783 LDX $23E4 X=$23E4
02B786 STX $2428 $2428=X
02B789 LDY $23EE Y=$23EE
02B78C LDA $23F2 A=$23F2
02B78F BNE #$52 if(z==off) goto $02B7E3
02B791 JSL $C2CC2C SR: $02CC2C 引数:1#$0079 引数:2#$0040 会心の一撃が発生する行動か
02B799 BEQ #$48 if(z==on) goto $02B7E3
02B79B LDA #$0000 A=#$0000 アイテム種別:武器をセット
02B79E JSL $C2B8AA SR: $02B8AA 装備アイテムID取得
02B7A2 LDA $242C A=$242C
02B7A5 CMP #$0009 A==#$0009? 装備アイテムが毒針か
02B7A8 BNE #$0A if(z==off) goto $02B7B4
02B7AA JSL $C2CC2C SR: $02CC2C 引数:1#$007A 引数:2#$0020 毒針で即死が発生する行動か
02B7B2 BNE #$2F if(z==off) goto $02B7E3
02B7B4 JSL $C2CAD9 SR: $02CAD9 引数:1#$2051 引数:2#$0008 バイキルト中?
02B7BC BEQ #$0A if(z==on) goto $02B7C8
02B7BE JSL $C2CC2C SR: $02CC2C 引数:1#$0079 引数:2#$0020 バイキルトの対象になる行動か
02B7C6 BNE #$1B if(z==off) goto $02B7E3
02B7C8 JSL $C2CAD9 SR: $02CAD9 引数:1#$2052 引数:2#$0001 オール会心中?
02B7D0 BNE #$16 if(z==off) goto $02B7E8
02B7D2 CPY #$00B6 Y==#$00B6? 戦闘行動が「ころぶ」か
02B7D5 BEQ #$11 if(z==on) goto $02B7E8
02B7D7 LDA #$0000 A=#$0000
02B7DA PLX Pull X
02B7DB STX $2428 $2428=X
02B7DE PLY Pull Y
02B7DF PLX Pull X
02B7E0 PLB Pull DB
02B7E1 PLP Pull P Flag
02B7E2 RTL return
02B7E3 LDA #$0002 A=#$0002
02B7E6 BRA #$F2 goto $02B7DA
02B7E8 LDA #$0001 A=#$0001 ヒット?
02B7EB BRA #$ED goto $02B7DA
02B7ED PHP Push P Flag
02B7EE REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B7F0 PHA Push A
02B7F1 PHX Push X
02B7F2 PHY Push Y
02B7F3 PHB Push DB
02B7F4 PEA #$7E7E Push #$7E7E
02B7F7 PLB Pull DB
02B7F8 PLB Pull DB
02B7F9 LDX #$0000 X=#$0000
02B7FC LDA $23FE,X A=$23FE+X
02B7FF CMP $2420 A==$2420?
02B802 BEQ #$40 if(z==on) goto $02B844
02B804 INX X++
02B805 INX X++
02B806 CPX #$0008 X>=#$0008?
02B809 BCC #$F1 if(c==off) goto $02B7FC
02B80B LDX #$0000 X=#$0000
02B80E TXA A=X
02B80F JSL $C2C739 SR: $02C739 引数:1#$02
02B814 LDA $00 A=DP($00)
02B816 ORA $02 Aor=DP($02)
02B818 BEQ #$1E if(z==on) goto $02B838
02B81A INX X++
02B81B CPX #$0004 X>=#$0004?
02B81E BCC #$EE if(c==off) goto $02B80E
02B820 LDX #$0000 X=#$0000
02B823 LDA $240E,X A=$240E+X
02B826 BEQ #$2A if(z==on) goto $02B852
02B828 INX X++
02B829 INX X++
02B82A CPX #$0008 X>=#$0008?
02B82D BCC #$F4 if(c==off) goto $02B823
02B82F PLB Pull DB
02B830 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B832 PLY Pull Y
02B833 PLX Pull X
02B834 PLA Pull A
02B835 PLP Pull P Flag
02B836 SEC c=on
02B837 RTL return
02B838 STX $2426 $2426=X
02B83B PLB Pull DB
02B83C REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B83E PLY Pull Y
02B83F PLX Pull X
02B840 PLA Pull A
02B841 PLP Pull P Flag
02B842 CLC c=off
02B843 RTL return
02B844 TXA A=X
02B845 LSR A>>1
02B846 STA $2426 $2426=A
02B849 PLB Pull DB
02B84A REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B84C PLY Pull Y
02B84D PLX Pull X
02B84E PLA Pull A
02B84F PLP Pull P Flag
02B850 CLC c=off
02B851 RTL return
02B852 TXA A=X
02B853 LSR A>>1
02B854 STA $2426 $2426=A
02B857 LDY #$0017 Y=#$0017
02B85A JSL $C2CAE0 SR: $02CAE0 引数:1#$203C 引数:2#$00FF
02B862 CMP $2426 A==$2426?
02B865 BNE #$07 if(z==off) goto $02B86E
02B867 STY $2428 $2428=Y
02B86A JSL $C2AD55 SR: $02AD55 戦闘中RAM領域を1キャラクター分0で初期化
02B86E DEY Y–
02B86F BPL #$E9 if(n==off) goto $02B85A
02B871 PLB Pull DB
02B872 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
02B874 PLY Pull Y
02B875 PLX Pull X
02B876 PLA Pull A
02B877 PLP Pull P Flag
02B878 CLC c=off
02B879 RTL return

やたらと長いこのSRですが、おそらくはヒット判定でしょう。後半はパーティアタック時のヒット判定なのでは、と推測します。

  • SR: $02873E 回避判定(通常)
02873E JSL $C2C240 SR: $02C240 引数:1#$0C 回避率分子取得
028743 PHA Push A
028744 JSL $C2CAE0 SR: $02CAE0 引数:1#$203C 引数:2#$00FF グループID取得
02874C CMP #$0004 A==or>=#$0004? PCor格闘場で賭けたモンスターか
02874F LDA #$003F A=#$003F 回避率分母に63をセット
028752 BCS #$03 if(c==on) goto $028757
028754 LDA #$002F A=#$002F 回避率分母に47をセット
028757 JSL $C0133E SR: $00133E 乱数発生 00-A A(1B)
02875B CMP $01,S A==or>=Stack($01)?
02875D PLA Pull A
02875E RTS return

$02873Eで取得した回避率分子よりも$028757で作成した乱数が小さければ回避ということになります。これを見ると、モンスターのほうが回避確率が高い(分母が小さいので)、ということがわかります。回避率分子はモンスター側は各モンスターに設定されている回避率分子の値を、PC側は1を固定で返すようになっています。K.Mixではこの部分をいじってすばやさに応じた分子を返すように変えました。

  • SR: $02875F 回避判定(特殊)
02875F PHX Push X
028760 LDA #$0001 A=#$0001 アイテム種別:鎧をセット
028763 JSL $C2B8AA SR: $02B8AA 装備アイテムID取得
028767 LDA $242C A=$242C
02876A LDX #$003C X=#$003C
02876D CMP $C2D220,X A==$02D220+X? 特殊回避防具配列のアイテムIDとマッチしているか
028771 BEQ #$08 if(z==on) goto $02877B
028773 DEX X–
028774 DEX X–
028775 DEX X–
028776 DEX X–
028777 BPL #$F4 if(n==off) goto $02876D
028779 BRA #$0B goto $028786
02877B LDA $C2D222,X A=$02D222+X マッチしていれば回避率(分母)を取得
02877F JSL $C0133E SR: $00133E 乱数発生 00-A A(1B)
028783 CLC c=off
028784 BEQ #$01 if(z==on) goto $028787
028786 SEC c=on
028787 PLX Pull X
028788 RTS return

回避判定(通常)で回避できなかった場合は回避判定(特殊)が実行されます。したがって、PC側の回避率は

1-(1-通常回避率)*(1-特殊回避率)

という式になることになります(多分)。また、このSRを見てわかるとおり、特殊回避防具としてセットできるのは鎧のみです。DQ3 Extended1.44では特殊回避防具を拡張できるようになっていますが、鎧以外のアイテムに特殊回避率をセットしても意味がないので注意してください。

  • SR: $0284F2 直接攻撃ヒット判定
0284F2 PHY Push Y
0284F3 LDY $23E4 Y=$23E4
0284F6 JSR $8525 SR: $028525 攻撃主体がマヌーサ時の攻撃ヒット判定(c=onヒット)
0284F9 BCC #$08 if(c==off) goto $028503
0284FB JSR $854B SR: $02854B まじんのおの装備時の攻撃ヒット判定(c=onヒット)
0284FE BCC #$03 if(c==off) goto $028503
028500 PLY Pull Y
028501 CLC c=off
028502 RTS return
028503 PLY Pull Y
028504 JSL $C2B6D9 SR: $02B6D9 直接攻撃ミス効果音
028508 LDA #$000E A=#$000E
02850B PHA Push A
02850C JSL $C2CAE0 SR: $02CAE0 引数:1#$203C 引数:2#$00FF
028514 CMP #$0004 A>=#$0004?
028517 BCS #$05 if(c==on) goto $02851E
028519 LDA #$000D A=#$000D
02851C STA $01,S Stack($01)=A
02851E PLA Pull A
02851F JSL $C1A87A SR: $01A87A 戦闘メッセージID
028523 SEC c=on
028524 RTS return
  • SR: $028525 攻撃主体がマヌーサ時の攻撃ヒット判定(c=onヒット)
028525 LDA $23F2 A=$23F2
028528 BNE #$1F if(z==off) goto $028549
02852A JSL $C2CC47 SR: $02CC47 引数:1#$0079 引数:2#$0002 戦闘行動がマヌーサに影響されるか
028532 BEQ #$15 if(z==on) goto $028549
028534 JSL $C2CB32 SR: $02CB32 引数:1#$2051 引数:2#$0004 行動主体がマヌーサ中か
02853C BEQ #$0B if(z==on) goto $028549
02853E JSL $C012D1 SR: $0012D1 乱数発生 $00-FF
028542 AND #$0001 A&=#$0001 1/2の確率でミス
028545 BNE #$02 if(z==off) goto $028549
028547 CLC c=off ミス
028548 RTS return
028549 SEC c=on ヒット
02854A RTS return
  • SR: $02854B まじんのおの装備時の攻撃ヒット判定(c=onヒット)
02854B LDA $23F2 A=$23F2
02854E BNE #$2C if(z==off) goto $02857C
028550 JSL $C2CC47 SR: $02CC47 引数:1#$007A 引数:2#$0008 戦闘行動がまじんのおのに依存するか
028558 BEQ #$22 if(z==on) goto $02857C
02855A LDA $2428 A=$2428
02855D PHA Push A
02855E STY $2428 $2428=Y
028561 LDA #$0010 A=#$0010 まじんのおののアイテムID
028564 STA $242C $242C=A
028567 JSL $C2B87A SR: $02B87A アイテム装備チェック
02856B PLA Pull A
02856C STA $2428 $2428=A
02856F BVC #$0B if(v==off) goto $02857C v=onで装備している
028571 JSL $C012D1 SR: $0012D1 乱数発生 $00-FF
028575 AND #$0007 A&=#$0007 1/8の確率でミス
028578 BNE #$02 if(z==off) goto $02857C
02857A CLC c=off ミス
02857B RTS return
02857C SEC c=on ヒット
02857D RTS return

どちらもダメージが発生しない回避とミスですが、「すばやく みをかわした」は攻撃対象の回避が成功したことを意味し、「ミス! ダメージを受けない」は攻撃主体の攻撃が空振りした、という違いがあることがわかります。