DQ3戦闘部分解説19

今回は戦闘行動実行SRのうち、特徴的なものをピックアップして解説します。

  • SR: $028DA9 直接攻撃後半
028DA9JSR $8DB0SR: $028DB0直接攻撃基本ダメージ計算
028DACJSR $8E70SR: $028E70ダメージ確定メイン
028DAFRTLreturn

  • SR: $028DB0 直接攻撃基本ダメージ計算
028DB0LDX $23E4X=$23E4攻撃主体インデックスをXにセット
028DB3LDY $23E8Y=$23E8攻撃対象インデックスをYにセット
028DB6JSL $02CA62SR: $02CA62 引数:1#$2041守備力取得
028DBCLSRA>>1守備力を1/2する(2)
028DBDPHAPush A
028DBEJSL $02CA5BSR: $02CA5B 引数:1#$203F攻撃力取得
028DC4STA $02DP($02)=A
028DC6PHAPush A
028DC7LSRA>>1
028DC8LSRA>>1
028DC9LSRA>>1攻撃力を1/8する(3)
028DCASTA $04DP($04)=A
028DCCPLAPull A
028DCDSECc=on
028DCESBC $01,SA-=Stack($01)攻撃力-守備力1/2(4)
028DD0STA $00DP($00)=A
028DD2PLAPull A
028DD3JSL $02CAD9SR: $02CAD9 引数:1#$203C 引数:2#$00FF攻撃主体のグループ番号取得
028DDBCMP #$0005A>=#$0005?PC側か
028DDEBCS #$04if(c==on) goto $028DE4
028DE0JSR $8E0ESR: $028E0Eモンスター直接攻撃ダメージ計算
028DE3RTSreturn
028DE4JSR $8DEBSR: $028DEBPC側直接攻撃ダメージ計算
028DE7JSR $8E4ASR: $028E4APC側直接攻撃ダメージ補正
028DEARTSreturn

ダメージ算出に当たって使用されるファクターは

  1. 攻撃力($02)
  2. 攻撃力1/8($04)
  3. 攻撃力-守備力1/2($00)

です。

  • SR: $028E0E モンスター直接攻撃ダメージ計算
028E0ELDA $00A=DP($00)
028E10BMI #$06if(n==on) goto $028E183)がマイナスか
028E12LDA $04A=DP($04)
028E14CMP $00A>=DP($00)?
028E16BCC #$1Bif(c==off) goto $028E332)<3)か
028E18LDA $02A=DP($02)
028E1ACMP #$0010A>=#$0010?攻撃力が16以上か
028E1DBCS #$0Aif(c==on) goto $028E29攻撃力が16以上か
028E1FJSL $0012D1SR: $0012D1乱数発生 $00-FF
028E23AND #$0001A&=#$00011/2の確率で1ダメージ
028E26STA $00DP($00)=A
028E28RTSreturn
028E29LDA $04A=DP($04)
028E2BDECA–
028E2CJSL $00133ESR: $00133E0~(2)-1の間で乱数発生
028E30STA $00DP($00)=A
028E32RTSreturn
028E33LDA $02A=DP($02)
028E35CMP #$0008A>=#$0008?攻撃力が8以上か
028E38BCC #$E5if(c==off) goto $028E1F
028E3AJSL $001472SR: $001472$63-99の乱数発生
028E3ELDX #$0000X=#$0000
028E41JSL $0010D6SR: $0010D6$00,X(3B)=A(1B)*$00,X(2Byte) (3)*$63-99の間の乱数
028E45LDA $01A=DP($01)上2バイトだけ使う
028E47STA $00DP($00)=A
028E49RTSreturn

  • SR: PC側直接攻撃ダメージ計算
028DEBLDA $00A=DP($00)
028DEDBMI #$15if(n==on) goto $028E04
028DEFCMP #$0002A>=#$0002?
028DF2BCC #$10if(c==off) goto $028E04
028DF4JSL $001472SR: $001472$63-99の乱数発生
028DF8LDX #$0000X=#$0000
028DFBJSL $0010D6SR: $0010D6$00,X(3B)=A(1B)*$00,X(2Byte) (3)*$63-99の間の乱数
028DFFLDA $01A=DP($01)
028E01STA $00DP($00)=A上2バイトだけ使う
028E03RTSreturn
028E04JSL $0012D1SR: $0012D1乱数発生 $00-FF
028E08AND #$0001A&=#$00011/2の確率で1ダメージ
028E0BSTA $00DP($00)=A
028E0DRTSreturn
  • SR: $028E4A 味方直接攻撃ダメージ補正
028E4ALDA $23F2A=$23F2
028E4DCMP #$0001A==#$0001?
028E50BNE #$13if(z==off) goto $028E65
028E52LSR $00DP($00)>>1
028E54LSR $00DP($00)>>1
028E56LSR $00DP($00)>>1ダメージ値を1/8する
028E58LDA #$0002A=#$0002
028E5BJSL $00133ESR: $00133E乱数発生 00-A A(1B)
028E5FINCA++
028E60CLCc=off
028E61ADC $00A+=DP($00)
028E63STA $00DP($00)=A
028E65RTSreturn

「DQ3 ダメージ値」で検索すると見つかる計算式どおりの実装です(当たり前ですが)。$028E4Aはいまいち何をしてるか不明です。パーティアタック時のダメージ計算のようにも見えます。SR: $028E70をコールする直前はダメージ値は$00にセットされていることが期待されています。

  • SR: $028E70 ダメージ確定メイン
028E70LDA #$0000A=#$0000
028E73PEA $23AEPush $23AE
028E76PEA $0010Push $0010
028E79PEA $7E00Push $7E00
028E7CJSL $0902E9SR: $0902E9会心・痛恨が起きないフラグをクリア
028E80JSL $028E92SR: $028E92ゾンビキラー・ドラゴンキラーによるダメージアップチェック
028E84JSL $028EFBSR: $028EFBダメージ確定メイン
028E88LDA $00A=DP($00)
028E8ASTA $23FA$23FA=A
028E8DJSL $029200SR: $029200ダメージ確定後の処理メイン
028E91RTSreturn

  • SR: $028E92 ゾンビキラー・ドラゴンキラーによるダメージアップチェック
028E92PHPPush P Flag
028E93REP #$30m=off(A/M:16b), x=off(X/Y:16b)
028E95PHAPush A
028E96PHXPush X
028E97PHYPush Y
028E98PHBPush DB
028E99PEA $7E7EPush $7E7E
028E9CPLBPull DB
028E9DPLBPull DB
028E9ELDA $23E4A=$23E4
028EA1STA $2428$2428=A
028EA4LDA #$0000A=#$0000アイテム種別:武器をセット
028EA7JSL $02B8AASR: $02B8AA装備アイテムID取得
028EABLDA $242CA=$242C
028EAESTA $245C$245C=A
028EB1LDX #$0000X=#$0000
028EB4LDA $23EEA=$23EE
028EB7CMP $028F8B,XA==$028F8B+X?単体攻撃のみ?
028EBBBEQ #$07if(z==on) goto $028EC4
028EBDDEXX–
028EBEDEXX–
028EBFBPL #$F6if(n==off) goto $028EB7
028EC1LDX #$8000X=#$8000
028EC4STX $245E$245E=X
028EC7LDA $23EEA=$23EE
028ECAASLA<<1
028ECBTAXX=A
028ECCLDA $022BE0,XA=$022BE0+X
028ED0TAXX=A
028ED1LDA $02007A,XA=$02007A+X
028ED5AND #$0010A&=#$0010
028ED8BEQ #$13if(z==on) goto $028EED戦闘行動が種族特効ONの行動か
028EDALDX #$0002X=#$0002
028EDDLDA $245CA=$245C
028EE0AND #$00FFA&=#$00FF
028EE3CMP $028F99,XA==$028F99+X?装備武器が種族特効武器リストにマッチするか
028EE7BEQ #$07if(z==on) goto $028EF0
028EE9DEXX–
028EEADEXX–
028EEBBPL #$F6if(n==off) goto $028EE3
028EEDLDX #$8000X=#$8000該当しない場合は最上位ビットをONにする
028EF0STX $2460$2460=X種族特効ダメージ計算用SRオフセット
028EF3PLBPull DB
028EF4REP #$30m=off(A/M:16b), x=off(X/Y:16b)
028EF6PLYPull Y
028EF7PLXPull X
028EF8PLAPull A
028EF9PLPPull P Flag
028EFARTLreturn

  • SR: $028EFB ダメージ確定メイン
028EFBPHPPush P Flag
028EFCPHBPush DB
028EFDREP #$30m=off(A/M:16b), x=off(X/Y:16b)
028EFFPEA $7E7EPush $7E7E
028F02PLBPull DB
028F03PLBPull DB
028F04LDA $23E8A=$23E8
028F07ASLA<<1
028F08TAXX=A
028F09LDA $02CBD3,XA=$02CBD3+X
028F0DSTA $0ADP($0A)=AキャラクターアドレスorモンスターIDセット
028F0FTAXX=A
028F10LDA $2049,XA=$2049+X
028F13STA $2420$2420=A
028F16LDA $2050,XA=$2050+X
028F19AND #$0001A&=#$0001
028F1CSTA $241E$241E=A
028F1FLDA $23EEA=$23EE
028F22ASLA<<1
028F23TAXX=A
028F24LDA $022BE0,XA=$022BE0+X
028F28STA $08DP($08)=A戦闘行動戦闘アドレスセット
028F2AJSR $8F4BSR: $028F4B複数攻撃武器ダメージカット計算
028F2DJSR $8F82SR: $028F82意味なし?
028F30JSR $9015SR: $029015バイキルト時のダメージ値計算
028F33JSR $903ESR: $02903E会心痛恨処理メイン
028F36JSR $8F90SR: $028F90種族特効時のダメージ加算
028F39JSR $913ESR: $02913EPC側ダメージ系耐性計算
028F3CJSR $9179SR: $029179フバーハ時のダメージ軽減計算
028F3FJSR $919BSR: $02919B防御時のダメージ軽減計算
028F42JSR $91A8SR: $0291A8耐性によるダメージ調整
028F45JSR $91DFSR: $0291DF毒針装備時の一撃必殺失敗(1ダメージ)
028F48PLBPull DB
028F49PLPPull P Flag
028F4ARTLreturn

このSRで耐性等を考慮したダメージ値の調整を行います。呪文ダメージなど、固定範囲のダメージ値の場合はこのSRをコールする前には数値設定($022EE0-)の範囲の値がセットされた状態でこのSRが呼ばれることになります。

  • SR: $028F4B 複数攻撃武器ダメージカット計算
028F4BLDA $23EEA=$23EE
028F4ECMP #$00ACA==#$00AC?戦闘行動がグループ攻撃か
028F51BEQ #$05if(z==on) goto $028F58
028F53CMP #$00ADA==#$00AD?戦闘行動が全体攻撃か
028F56BNE #$1Dif(z==off) goto $028F75
028F58LDA $23DAA=$23DA何体目を攻撃しているか?
028F5BDECA–
028F5CCMP #$0005A>=#$0005?
028F5FBCC #$03if(c==off) goto $028F64
028F61LDA #$0005A=#$00055体目以降は33/256で固定
028F64ASLA<<1
028F65TAXX=A
028F66LDA $028F76,XA=$028F76+Xダメージ低減率取得
028F6ALDX #$0000X=#$0000
028F6DJSL $001146SR: $001146$00,x=A(1Byte)*$00,x
028F71LDA $01A=DP($01)上位2バイトを使用
028F73STA $00DP($00)=A
028F75RTSreturn

  • SR: $029015 バイキルト時のダメージ値計算
029015LDX $08X=DP($08)
029017LDA $020079,XA=$020079+X
02901BAND #$0020A&=#$0020戦闘行動がバイキルトに依存するか
02901EBEQ #$1Dif(z==on) goto $02903D
029020LDA $23E4A=$23E4
029023ASLA<<1
029024TAXX=A
029025LDA $02CBD3,XA=$02CBD3+X
029029TAXX=A
02902ALDA $2051,XA=$2051+X
02902DAND #$0008A&=#$0008行動主体がバイキルト中か
029030BEQ #$0Bif(z==on) goto $02903D
029032LDA $23DAA=$23DA攻撃対象が現在実行中の行動の何番目か(1からカウント)
029035DECA–
029036ORA $23D8Aor=$23D8現在の攻撃が何回目か
029039BNE #$02if(z==off) goto $02903D複数対象攻撃の2体目以降or複数回数攻撃の2回目以降だと0にならないのでバイキルトの対象外になる
02903BASL $00DP($00)<<1ダメージ値を単純に2倍化
02903DRTSreturn

この計算式を見ると、バイキルトとは「攻撃力を2倍化するのではなく、ダメージ値を2倍化する」というのがその実体であることがわかります。

(12/03追記)

  • SR: $02903E 会心・痛恨判定
02903ELDA $23AEA=$23AE
029041AND #$0010A&=#$0010会心・痛恨が発生しない条件(バイキルト中?)
029044BNE #$20if(z==off) goto $029066
029046JSL $02B774SR: $02B774毒針ヒット判定?
02904ACMP #$0001A==#$0001?毒針ヒット?
02904DBEQ #$14if(z==on) goto $029063
02904FCMP #$0002A==#$0002?外れ
029052BEQ #$12if(z==on) goto $029066
029054JSR $90A7SR: $0290A7特殊武器会心判定(会心c=on)
029057BCS #$0Aif(c==on) goto $029063
029059JSR $90D1SR: $0290D1痛恨判定(会心c=on)
02905CBCS #$05if(c==on) goto $029063
02905EJSR $9067SR: $029067会心判定(会心c=on)
029061BCS #$03if(c==on) goto $029066
029063JSR $90E9SR: $0290E9会心痛恨処理
029066RTSreturn

$23AEの4ビット目はおそらくバイキルト中にセットされるフラグです。「バイキルト中には会心・痛恨は発生しない」という実装ですね。

  • SR: $0290A7 特殊武器会心判定
0290A7LDX #$0000X=#$0000
0290AALDA $245CA=$245C装備武器取得?
0290ADAND #$00FFA&=#$00FF
0290B0CMP #$0010A==#$0010?まじんのおのアイテムID
0290B3BEQ #$08if(z==on) goto $0290BD
0290B5INXX++
0290B6CMP #$0014A==#$0014?破壊の剣アイテムID
0290B9BEQ #$02if(z==on) goto $0290BD
0290BBCLCc=off
0290BCRTSreturn
0290BDLDA $0290CF,XA=$0290CF+X特殊武器会心率分母配列から分母をセット
0290C1AND #$00FFA&=#$00FF
0290C4JSL $00133ESR: $00133E乱数発生 00-A A(1B)
0290C8CMP #$0000A==#$0000?0なら会心
0290CBBNE #$EEif(z==off) goto $0290BB
0290CDSECc=on
0290CERTSreturn

まじんのおの、破壊の剣のアイテムIDがハードコードされています。特殊防具回避率のようにアイテムID、分母を1レコードに持った配列で実装しそうなものですが、そうしていないようです。従ってまじんのおの、破壊の剣以外で会心率を別途設定したい、という場合はプログラムを書く必要があります。(自分は特に必要性を感じないのでパス)

  • SR: $0290D1 痛恨判定
0290D1LDA $23EEA=$23EE
0290D4CMP #$0002A==#$0002?戦闘行動が「つうこん」か
0290D7BNE #$0Eif(z==off) goto $0290E7
0290D9LDA #$0007A=#$0007痛恨率分母設定
0290DCJSL $00133ESR: $00133E乱数発生 00-A A(1B)
0290E0CMP #$0000A==#$0000?1/8で痛恨
0290E3BNE #$02if(z==off) goto $0290E7
0290E5SECc=on
0290E6RTSreturn
0290E7CLCc=off
0290E8RTSreturn

モンスター側の痛恨の一撃は戦闘行動として#$002:つうこんが設定されていない限りは通常攻撃でも痛恨の一撃は発生しない、ということになります。

  • SR: $029067 会心判定
029067LDX $23E4X=$23E4
02906ASTX $2428$2428=X
02906DJSL $02CAD9SR: $02CAD9 引数:1#$203C 引数:2#$00FFグループID取得
029075CMP #$0005A>=#$0005?行動主体がPC側か
029078BCC #$2Bif(c==off) goto $0290A5
02907AJSL $02BE8ASR: $02BE8A 引数:1#$24職業ID取得
02907FBCS #$18if(c==on) goto $029099
029081CMP #$0001A==#$0001?職業がぶとうかか
029084BNE #$13if(z==off) goto $029099
029086JSL $02C240SR: $02C240 引数:1#$0Aレベル取得
02908BCMP #$0005A>=#$0005?レベルが5以上か
02908EBCC #$09if(c==off) goto $029099
029090PHAPush A
029091JSL $0012D1SR: $0012D1乱数発生 $00-FF
029095CMP $01,SA==or>=Stack($01)?レベルを閾値として使用
029097PLAPull A
029098RTSreturn
029099JSL $0012D1SR: $0012D1乱数発生 $00-FF
02909DAND #$003FA&=#$003F1/48の確率
0290A0SECc=on
0290A1BNE #$02if(z==off) goto $0290A5
0290A3CLCc=off
0290A4RTSreturn
0290A5SECc=on
0290A6RTSreturn

広く知られているとおり、Lv5以上のぶとうかの会心発生率について職業特性として(レベル+1)/256となるように実装されていることがわかります。それ以外は1/48です。

  • SR: $0290E9 会心痛恨発生処理
0290E9JSL $01E32ESR: $01E32E 引数:1#$005FSE再生?
0290EFLDA #$0009A=#$0009戦闘メッセージID:「かいしんの いちげき」
0290F2PHAPush A
0290F3LDX $23E4X=$23E4
0290F6JSL $02CAD9SR: $02CAD9 引数:1#$203C 引数:2#$00FFグループID取得
0290FECMP #$0005A>=#$0005?行動主体がPC側か
029101BCS #$05if(c==on) goto $029108
029103LDA #$000AA=#$000A戦闘メッセージID:「つうこんの いちげき」
029106STA $01,SStack($01)=A
029108PLAPull A
029109JSL $01A87ASR: $01A87A戦闘メッセージ表示
02910DLDA #$0001A=#$0001
029110PEA $23ADPush $23AD
029113PEA $0020Push $0020
029116PEA $7E00Push $7E00
029119JSL $0902E9SR: $0902E9RAM上情報変更
02911DLDX $23E4X=$23E4
029120JSL $02CA5BSR: $02CA5B 引数:1#$203F攻撃力取得
029126STA $00DP($00)=A
029128LSRA>>1攻撃力1/2
029129PHAPush A
02912AJSL $0014A3SR: $0014A3$5A-83の乱数発生
02912ELDX #$0000X=#$0000
029131JSL $0010D6SR: $0010D6$00,X(3B)=A(1B)*$00,X(2Byte)
029135LDA $01A=DP($01)攻撃力に乱数をかけて上1バイトを使用
029137CLCc=off
029138ADC $01,SA+=Stack($01)攻撃力1/2に加算
02913ASTA $00DP($00)=Aダメージ値決定
02913CPLAPull A
02913DRTSreturn

会心・痛恨時のダメージ計算は攻撃力1/2+攻撃力*(0.35~0.51)で計算され、対象の防御力が無視されることがわかります。

  • SR: $028F90 種族特効時のダメージ加算
028F90LDX $2460X=$2460種族特効ダメージ用計算SRへのオフセット
028F93BMI #$03if(n==on) goto $028F98なし(#$8000)のときはスキップ)
028F95JSR $8F9DSR: $($028F9D+X)
028F98RTSreturn

  • SR: $028FA1 ドラゴンキラー装備時のドラゴン系へのダメージ計算
028FA1LDA $241EA=$241E対象がモンスター?
028FA4BNE #$1Eif(z==off) goto $028FC4
028FA6LDA $2420A=$7E2420モンスターID?
028FA9ASLA<<1
028FAATAXX=A
028FABLDA $132500,XA=$132500+Xモンスター基本情報へのオフセット取得
028FAFTAXX=A
028FB0LDA $130002,XA=$130002+X
028FB4AND #$0040A&=#$0040対象がドラゴンか
028FB7BEQ #$0Bif(z==on) goto $028FC4
028FB9LDA $23AEA=$23AE
028FBCAND #$0010A&=#$0010バイキルト中?
028FBFBNE #$04if(z==off) goto $028FC5
028FC1JSR $9004SR: $02900416~32を加算
028FC4RTSreturn
028FC5LDA #$0018A=#$0018バイキルト中は固定ダメージ24を加算?
028FC8CLCc=off
028FC9ADC $00A+=DP($00)
028FCBSTA $00DP($00)=A
028FCDRTSreturn

  • SR: $028FCE ゾンビキラー装備時のゾンビ系へのダメージ計算
028FCELDA $23EEA=$23EE
028FD1PHAPush A
028FD2LDA #$001BA=#$001B戦闘行動IDをニフラムに差し替え
028FD5STA $23EE$23EE=A
028FD8LDA $23AEA=$23AE
028FDBAND #$0010A&=#$0010バイキルト中?
028FDEBNE #$0Dif(z==off) goto $028FED
028FE0JSR $A3EBSR: $02A3EB耐性を考慮して成否判定+PC側耐性計算?
028FE3BCC #$03if(c==off) goto $028FE8
028FE5JSR $9004SR: $02900416~32を加算
028FE8PLAPull A
028FE9STA $23EE$23EE=A
028FECRTSreturn
028FEDLDA $00A=DP($00)
028FEFPHAPush A
028FF0LDA #$0018A=#$0018
028FF3STA $00DP($00)=A
028FF5JSR $A3CESR: $02A3CE
028FF8LDA $00A=DP($00)
028FFACLCc=off
028FFBADC $01,SA+=Stack($01)
028FFDSTA $01,SStack($01)=A
028FFFPLAPull A
029000STA $00DP($00)=A
029002BRA #$E4goto $028FE8

ゾンビキラーも同じ…とおもったら、なんとゾンビ系フラグは使用されずに、ニフラム耐性が使用されているようです。86氏のDQ3Plusパッチに「ゾンビキラー効果対象をニフラム耐性→ゾンビ系bitに変更」という記述がありましたが、この部分をドラゴン特効と同じように変更しているものと思われます(未確認)。

コメント

  1. タカオ より:

    「会心・痛恨時のダメージ計算は攻撃力1/2+攻撃力*(0.3~0.57)で計算」とありますが、要は0.8~1.07という振れ幅だということですよね。
     しかし例えば攻撃力丁度400にして会心出させてみたところ、いくらやっても実測ダメージが340~404の区間、つまり0.85~1.01倍相当に止どまり(平均値こそ0.5%しか差がありませんが)理論値より更に狭まっているのは何故でしょうか。、
     必要ならば検証用のセーブデータをお送りすることも可能ですので、ご教示して頂けませんでしょうか。よろしくお願いします。m(._.)m

    管理者より返信:

    $5A(90)、$83(131)の$100(256)に対する割合の記述が間違っていたので修正しました。それぞれ0.35、0.51なので実測通りということでしょう。

  2. 匿名 より:

    「Lv5以上のぶとうかの会心発生率について職業特性としてレベル/255」とあるので、乱数は1~255の範囲で発生するということでしょうか?0~255だと式と合わなかったので。

    管理者より返信:

    たしかにそうですね。修正しておきます。ご指摘ありがとうございました。

  3. 匿名 より:

    乱数とレベルが等号の場合も会心なので、(レベル+1)/256ではないでしょうか?

    管理者より返信:

    たしかにそうですね。修正しておきます。ご指摘ありがとうございました。

タイトルとURLをコピーしました