DQ3 盾の耐性を定数ダメージカットに変更+耐性についてのお勉強他

今回の変更は個人的趣味というか別にやってもやらなくてもどうでもいいのですが、まあ勉強も兼ねてということでお付き合いください。

PC側の耐性によるダメージ減処理はSR:$02BBD5、そしてその内部でコールしているSR:$02BBF4で行っています。他の改造パッチでも実現されていますが、実は武器にも耐性を設定することが可能です。最初このSRを見たとき、「効果が重複する場合には効果が現れないのでは?」と思っていたのですが、大間違いでした。耐性によるダメージ減処理を開始する直前に元となるダメージ値が$7E2474-5にセットされ、武器→鎧→盾→兜→装飾品の順で装備品の耐性値を見て、耐性が存在する場合はこの$7E2474-5の値に対して減算処理を繰り返すため、効果が重複する場合はちゃんと重複して発生することになります。

さて、後のDQ作品では定番になっている「盾の耐性を定数ダメージカットにする」を導入することにします。耐性計算の順番をちょっと変えて武器→鎧→兜→装飾品→盾とし、さらに耐性情報に設定できる値を「ダメージカットされる定数」とします。

  • SR: $02BBF4 PC側耐性計算メイン
02BBF4 LDA #$0000 A=#$0000 武器の種別ID
02BBF7 JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得
02BBFF STA $242C $242C=A
02BC02 JSR $BC4A SR: $02BC4A 耐性を考慮したダメージ値計算
02BC05 LDA #$0001 A=#$0001 鎧の種別ID
02BC08 JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得
02BC10 STA $242C $242C=A
02BC13 JSR $BC4A SR: $02BC4A 耐性を考慮したダメージ値計算
02BC16 LDA #$0003 A=#$0003 兜の種別ID
02BC19 JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得
02BC21 STA $242C $242C=A
02BC24 JSR $BC4A SR: $02BC4A 耐性を考慮したダメージ値計算
02BC27 LDA #$0004 A=#$0004 装飾品の種別ID
02BC2A JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得
02BC32 STA $242C $242C=A
02BC35 JSR $BC4A SR: $02BC4A 耐性を考慮したダメージ値計算
02BC38 LDA #$0002 A=#$0002 盾の種別ID
02BC3B JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得
02BC43 STA $242C $242C=A
02BC46 JSR $E528 SR: $02E528 盾耐性値計算
02BC49 RTS return
  • SR: $02E528 盾耐性値計算(新SR)
02E528 PHP Push P Flag
02E529 PHX Push X
02E52A PHY Push Y
02E52B LDY #$003F Y=#$003F
02E52E JSL $C90566 SR: $090566 引数:1#$00 引数:2#$0003 引数:3#$C2D160 引数:4#$0002 引数:5#$000020 構造体アクセス
02E53D CMP $2476 A==$2476?
02E540 BNE #$14 if(z==off) goto $02E556
02E542 JSL $C90566 SR: $090566 引数:1#$00 引数:2#$0003 引数:3#$C2D160 引数:4#$0000 引数:5#$0000FF 構造体アクセス
02E551 CMP $242C A==$242C?
02E554 BEQ #$07 if(z==on) goto $02E55D
02E556 DEY Y–
02E557 BPL #$D5 if(n==off) goto $02E52E
02E559 PLY Pull Y
02E55A PLX Pull X
02E55B PLP Pull P Flag
02E55C RTS return
02E55D LDX $242A X=$242A
02E560 JSL $C2CC25 SR: $02CC25 引数:1#$0076 引数:2#$00F8 戦闘行動構造体アクセスSR
02E568 CMP #$001F A>=#$001F?
02E56B BCS #$FE if(c==on) goto $02E56B
02E56D ASL A<<1
02E56E TAX X=A
02E56F JSR $393C SR: $($02393C+X)
02E572 BEQ #$21 if(z==on) goto $02E595
02E574 JSL $C90566 SR: $090566 引数:1#$00 引数:2#$0003 引数:3#$C2D160 引数:4#$0001 引数:5#$0000FF 構造体アクセス
02E583 STA $6A DP($6A)=A
02E585 LDA $2474 A=$2474
02E588 SEC c=on
02E589 SBC $6A A-=(DP($6A)+c)
02E58B BMI #$05 if(n==on) goto $02E592 耐性計算した結果がマイナスになったらダメージを0化する必要がある
02E58D STA $2474 $2474=A
02E590 BRA #$03 goto $02E595
02E592 STZ $2474 $2474=#$00
02E595 PLY Pull Y
02E596 PLX Pull X
02E597 PLP Pull P Flag
02E598 RTS return

途中まではオリジナルの耐性計算をするSR:$02BC4Aと同じです。違うのは装備品の耐性値を取得した後、掛け算をするのではなく、引くという点だけです。ところで、実害はない潜在バグだと思うのですが、

02BC05 LDA #$0001 A=#$0001 鎧の種別ID
02BC08 JSL $C44A03 SR: $044A03 引数:1#$06 引数:2#$FD 引数:3#$FF 引数:4#$FF 装備品アイテムID取得

で、装備品のアイテムIDをAレジスタに取得するのですが、もし未装備の場合は直前で指定したAレジスタの値(この場合は#$0001)がそのまま返ってきて、その値がアイテムIDとしてセットされてしまいます。未装備の場合はc=onになるので、c=onなら直後の耐性計算をスキップする、とするのが正しい処理です。実際はアイテムID0~5の初期に登場する武器には耐性が存在しないので実害はないのですが、もしこれらに耐性を設定しようとする場合には上記のように未装備ならスキップ、という処理をはさむ必要があります。