DQ3戦闘部分解説7

ずいぶん更新をサボってしまいました。サボっている間にもそこそこアクセスをして頂き空振りで申し訳ありませんでした。言い訳をしておくとwww、例の自己満足以外の何者でもないDQ3(6)SFCPlugin.dllのマップ系の描画速度の改善作業をポチポチとやっていました。一応クソ遅かった戦闘背景、サブマップ、フィールドマップの描画時間を最大で2秒(手元の遅いPCベース。改善前は最低20秒くらいかかっていた)くらいまで改善することができたので、目標は達成できました。はっきり言ってこの作業は別の本丸の作業が嫌になったので気晴らしにやっていただけなので、本来の作業に戻ります。

前回PC側のコマンド入力のところまで解説しましたが、1点重要な部分が抜けていました。今回はそこだけを説明して終わりです。

  • SR: $025EC3 戦闘コマンド処理_SR_0000(直接攻撃コマンド入力処理)
025EC3 JSR $5F39 SR: $025F39 直接攻撃戦闘行動セット(対象選択不要c=on)
025EC6 BCC #$02 if(c==off) goto $025ECA
025EC8 CLC c=off
025EC9 RTS return
パーティアタックに関する処理なので割愛
025F2C ORA #$0020 Aor=#$0020 ターゲット指定(対象不確定?
025F2F JSL $C2CB70 SR: $02CB70 引数:1#$2035 引数:2#$00FE
025F37 CLC c=off
025F38 RTS return
  • SR: $025F39 直接攻撃戦闘行動セット
025F39 LDA #$0000 A=#$0000 アイテム種別:武器をセット
025F3C JSL $C2B8AA SR: $02B8AA 装備アイテムID取得
025F40 LDA $242C A=$242C
025F43 LDX #$0012 X=#$0012
025F46 CMP $C25F83,X A==$025F83+X? 複数対象武器リスト
025F4A BEQ #$14 if(z==on) goto $025F60
025F4C DEX X–
025F4D DEX X–
025F4E BPL #$F6 if(n==off) goto $025F46
025F50 LDA #$0001 A=#$0001 直接攻撃戦闘行動ID
025F53 LDX $2428 X=$2428
025F56 JSL $C2CB70 SR: $02CB70 引数:1#$2034 引数:2#$01FF 戦闘中PC情報変更
025F5E CLC c=off
025F5F RTS return
025F60 LDA #$00AC A=#$00AC グループ攻撃戦闘行動ID
025F63 CPX #$000C X>=#$000C? 全体攻撃武器の$025F83からのオフセット
025F66 BCC #$EB if(c==off) goto $025F53
025F68 LDX $2428 X=$2428
025F6B LDA #$00AD A=#$00AD 全体攻撃戦闘行動ID
025F6E JSL $C2CB70 SR: $02CB70 引数:1#$2034 引数:2#$01FF 戦闘中PC情報変更
025F76 LDA #$0041 A=#$0041 攻撃対象も「全体」でセット
025F79 JSL $C2CB70 SR: $02CB70 引数:1#$2035 引数:2#$00FE 戦闘中PC情報変更
025F81 SEC c=on
025F82 RTS return

直接攻撃部分を見ると$7E2034-35の上位7ビットの意味がわかってしまいます(下位9ビットは戦闘行動ID)。簡単に言ってしまうと

対象確定 #0x(xはキャラID)
単体、グループ(対象未確定) #2x(xはグループID)
全体攻撃 #$41

ということのようです。実際にどのキャラクターに対して行動を実行するかは実行時に決定するのがほとんどです。

(2010-11-04追記)

  • SR: $02629D 戦闘コマンド処理_SR_0005(「にげる」コマンド選択)
02629D JSL $C1E32E SR: $01E32E 引数:1#$0067 逃げたSE再生
0262A3 LDA #$0042 A=#$0042
0262A6 STA $23E4 $23E4=A
0262A9 PEA #$2011 Push #$2011
0262AC PEA #$0010 Push #$0010
0262AF PEA #$7E00 Push #$7E00
0262B2 JSL $C9029E SR: $09029E イベント戦闘かチェック
0262B6 BNE #$48 if(z==off) goto $026300
0262B8 JSR $636F SR: $02636F 確実に逃げられるか調べる(逃げられるc=on)
0262BB BCS #$22 if(c==on) goto $0262DF
0262BD JSL $C012D1 SR: $0012D1
0262C1 AND #$0003 A&=#$0003
0262C4 STA $00 DP($00)=A
0262C6 PEA #$23AF Push #$23AF
0262C9 PEA #$0003 Push #$0003
0262CC PEA #$7E00 Push #$7E00
0262CF JSL $C9029E SR: $09029E
0262D3 TAX X=A
0262D4 LDA $C2636B,X A=$02636B+X
0262D8 AND #$00FF A&=#$00FF
0262DB CMP $00 A>=DP($00)?
0262DD BCC #$21 if(c==off) goto $026300
0262DF LDA #$0003 A=#$0003
0262E2 PEA #$23AB Push #$23AB
0262E5 PEA #$000F Push #$000F
0262E8 PEA #$7E00 Push #$7E00
0262EB JSL $C902E9 SR: $0902E9
0262EF JSL $C1A867 SR: $01A867 引数:1#$0023 戦闘メッセージ表示「○○は にげだした!」
0262F5 JSL $C1A867 SR: $01A867 引数:1#$0003
0262FB LDY #$0004 Y=#$0004
0262FE CLC c=off
0262FF RTS return
026300 PEA #$23AF Push #$23AF
026303 PEA #$0003 Push #$0003
026306 PEA #$7E00 Push #$7E00
026309 JSL $C9029E SR: $09029E
02630D INC A++
02630E CMP #$0004 A>=#$0004?
026311 BCC #$03 if(c==off) goto $026316
026313 LDA #$0004 A=#$0004
026316 PEA #$23AF Push #$23AF
026319 PEA #$0003 Push #$0003
02631C PEA #$7E00 Push #$7E00
02631F JSL $C902E9 SR: $0902E9
026323 LDA #$0002 A=#$0002
026326 PEA #$23AB Push #$23AB
026329 PEA #$0030 Push #$0030
02632C PEA #$7E00 Push #$7E00
02632F JSL $C902E9 SR: $0902E9
026333 LDX #$0017 X=#$0017
026336 JSL $C2CAD9 SR: $02CAD9 引数:1#$2050 引数:2#$0002
02633E BEQ #$11 if(z==on) goto $026351
026340 JSL $C2CAD9 SR: $02CAD9 引数:1#$203C 引数:2#$00FF
026348 CMP #$0004 A>=#$0004?
02634B BCC #$04 if(c==off) goto $026351
02634D JSL $C2B52D SR: $02B52D
026351 DEX X–
026352 BPL #$E2 if(n==off) goto $026336
026354 JSL $C1A867 SR: $01A867 引数:1#$0023 戦闘メッセージ表示「○○は にげだした!」
02635A JSL $C1A867 SR: $01A867 引数:1#$0001
026360 JSL $C1A867 SR: $01A867 引数:1#$0024 戦闘メッセージ表示「しかし まわりこまれた!」
026366 LDY #$0004 Y=#$0004
026369 CLC c=off
02636A RTS return
  • SR: $02636F 確実に逃げられるか調べる(逃げられるc=on)
02636F PEA #$23AB Push #$23AB
026372 PEA #$0030 Push #$0030
026375 PEA #$7E00 Push #$7E00
026378 JSL $C9029E SR: $09029E
02637C CMP #$0001 A==#$0001?
02637F BEQ #$1F if(z==on) goto $0263A0
026381 JSL $C2C739 SR: $02C739 引数:1#$06 モンスター側のビットを立てる
026386 JSL $C2B9CE SR: $02B9CE モンスター最高レベル取得
02638A CLC c=off
02638B ADC #$000A A+=(#$000A+c) パーティとのレベル差
02638E PHA Push A
02638F LDA #$0000 A=#$0000
026392 JSL $C42FEB SR: $042FEB 引数:1#$01 引数:2#$FF 引数:3#$FF レベル取得
026399 CMP $01,S A==or>=Stack($01)?
02639B PLA Pull A
02639C BCS #$02 if(c==on) goto $0263A0
02639E CLC c=off
02639F RTS return
0263A0 SEC c=on
0263A1 RTS return

もう1点「にげる」を選んだ場合の処理を説明するのを忘れていました。この実装を見ると確実に逃げるためには(おそらく先頭のキャラクターの)レベルがモンスターの最高レベル+10以上であれば確実に逃げられるようです。モンスターの最高レベルは63なので、レベル73以上であればどこでも逃げられることになります。手軽に難易度を変更したい場合はこの部分をいじるといいでしょう。