DQ3戦闘部分解説11

モンスター側のターゲッティングについて解説します。前回は以下のSRの上1つまで終わっています。

  • SR:$0265DA モンスター行動決定(個別)
0265DA PHP Push P Flag
0265DB REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
0265DD PHA Push A
0265DE PHX Push X
0265DF PHY Push Y
0265E0 PHB Push DB
0265E1 PEA #$7E7E Push #$7E7E
0265E4 PLB Pull DB
0265E5 PLB Pull DB
0265E6 JSR $672D SR: $02672D モンスター行動決定+対象決定
0265E9 JSR $65F7 SR: $0265F7 並び順に依存する戦闘行動の対象決定補正
0265EC JSR $66AB SR: $0266AB 集中攻撃時の対象決定補正
0265EF PLB Pull DB
0265F0 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
0265F2 PLY Pull Y
0265F3 PLX Pull X
0265F4 PLA Pull A
0265F5 PLP Pull P Flag
0265F6 RTL return

モンスターの1回の行動決定+対象決定はこのSRで全て決定されます。複数回行動するモンスターはこのSRが複数回コールされます。通常の対象決定は一番目のSR: $02672Dで行われますが、一部補正が必要な行動はその後の2つのSRで補正しています。

  • SR: $0265F7 並び順による狙われやすさ調整
0265F7 LDX $2428 X=$2428 行動主体IDをセット?
0265FA JSL $C2CAD9 SR: $02CAD9 引数:1#$203C 引数:2#$00FF グループID取得
026602 CMP #$0005 A>=#$0005? PC側ならスキップ
026605 BCS #$17 if(c==on) goto $02661E
026607 LDY $242A Y=$242A 戦闘行動IDをセット?
02660A JSL $C2CC2C SR: $02CC2C 引数:1#$007A 引数:2#$0002 並び順による狙われやすさがON?
026612 BEQ #$0A if(z==on) goto $02661E
026614 JSL $C2C240 SR: $02C240 引数:1#$0E 知能パターン取得
026619 BEQ #$03 if(z==on) goto $02661E バカならスキップ
02661B JSR $661F SR: $02661F 並び順に依存するターゲット確定処理
02661E RTS return
  • SR: $02661F 並び順に依存するターゲット確定処理
02661F LDA #$0005 A=#$0005 グループIDをセット
026622 JSL $C2C739 SR: $02C739 引数:1#$02 グループIDが5のものだけビットON
026627 JSL $C2C766 SR: $02C766 引数:1#$00 生存者だけビットをONにする
02662C JSL $C270E1 SR: $0270E1 対象数カウント
026630 BEQ #$25 if(z==on) goto $026657 対象数が0ならなにもしない?
026632 DEC A–
026633 ASL A<<1
026634 TAX X=A
026635 JSR $6658 SR: $($026658+X) 並び順に依存する対象決定
026638 LDY #$0000 Y=#$0000
02663B TYX X=Y
02663C JSL $C43F87 SR: $043F87 引数:1#$01 引数:2#$FD 引数:3#$FF 生死判定?
026643 AND #$0010 A&=#$0010
026646 BNE #$05 if(z==off) goto $02664D
026648 CPX $00 X==DP($00)?
02664A BEQ #$04 if(z==on) goto $026650
02664C INX X++
02664D INY Y++
02664E BRA #$EC goto $02663C
026650 JSL $C2AF66 SR: $02AF66 対象者の戦闘中キャラクタインデックスを取得
026654 STX $2430 $2430=X
026657 RTS return
  • SR:$026660 並び順に依存する対象決定_SR_0000(生存人数1人)
026660 STZ $00 DP($00)=#$00
026662 RTS return
  • SR:$026663 並び順に依存する対象決定_SR_0001(生存人数2人)
026663 STZ $00 DP($00)=#$00
026665 LDA #$0006 A=#$0006
026668 JSL $C0133E SR: $00133E 乱数発生 00-A A(1B)
02666C CMP #$0004 A>=#$0004?
02666F BCC #$02 if(c==off) goto $026673
026671 INC $00 DP($00)++
026673 RTS return
  • SR:$026674 並び順に依存する対象決定_SR_0002(生存人数3人)
026674 STZ $00 DP($00)=#$00
026676 LDA #$0008 A=#$0008
026679 JSL $C0133E SR: $00133E 乱数発生 00-A A(1B)
02667D CMP #$0004 A>=#$0004?
026680 BCC #$09 if(c==off) goto $02668B
026682 INC $00 DP($00)++
026684 CMP #$0007 A>=#$0007?
026687 BCC #$02 if(c==off) goto $02668B
026689 INC $00 DP($00)++
02668B RTS return
  • SR:$02668C 並び順に依存する対象決定_SR_0003(生存人数4人)
02668C STZ $00 DP($00)=#$00
02668E LDA #$0009 A=#$0009
026691 JSL $C0133E SR: $00133E 乱数発生 00-A A(1B)
026695 CMP #$0004 A>=#$0004?
026698 BCC #$10 if(c==off) goto $0266AA
02669A INC $00 DP($00)++
02669C CMP #$0007 A>=#$0007?
02669F BCC #$09 if(c==off) goto $0266AA
0266A1 INC $00 DP($00)++
0266A3 CMP #$0009 A>=#$0009?
0266A6 BCC #$02 if(c==off) goto $0266AA
0266A8 INC $00 DP($00)++
0266AA RTS return

SR: $02C739, SR: $02C766はターゲット関連でよく出てくるSRです。戦闘に参加しているキャラクター24体をビットフラグにして扱うためのSRです。SR: $02C739で、対象のビットを確定し(今回の例ではグループIDが5のものだけビットを立てる)、SR: $02C766で既に立っているビットのうち生存しているキャラクターのビットだけ残します。この手の処理は戦闘終了時にも行われ、敵方について生存ビットを調べ、味方について生存ビットを調べ、どちらかが生存者が0になったら終わり、ということで戦闘終了判定を行なっています。ここでは、SR: $0270E1で得られた生存数に応じて異なるターゲット選択SR群($026658-)がコールされます。このSRではアリアハン城内2Fの兵士の言葉通り、先頭にいればいるほどターゲットになる確率が高くなるようになっています。確率は以下のようになっています。

1人目 2人目 3人目 4人目
1人生存 100%
2人生存 57% 43%
3人生存 44% 33% 22%
4人生存 40% 30% 20% 10%

SR: $02661Fの後半はSR: $($026658+X)によって得られた「何番目のキャラクターを狙うか」に従って実際に狙うべきキャラクターを探しています。生存人数3人で2番目を狙うという決定をした場合でも2番目のキャラクターを対象とすればいいわけではなく、死人がいたらそのキャラクターを飛ばして2番目を狙う、というようにしなくてはいけません。さらにパルプンテの効果によってキャラクターの戦闘中の並び順が変わっていることもあるため、その時点での並び順から戦闘中のキャラクターIDを逆引きする必要があります。

  • SR: $0266AB 集中攻撃時のターゲット確定
0266AB LDY $242A Y=$242A 戦闘行動IDをセット
0266AE JSL $C2CC2C SR: $02CC2C 引数:1#$0079 引数:2#$0080 集中攻撃に影響されるか
0266B6 BEQ #$11 if(z==on) goto $0266C9
0266B8 JSL $C2C240 SR: $02C240 引数:1#$14 集中攻撃をするモンスターか
0266BD BEQ #$0A if(z==on) goto $0266C9
0266BF JSL $C2C240 SR: $02C240 引数:1#$0E 知能パターン取得
0266C4 BEQ #$03 if(z==on) goto $0266C9
0266C6 JSR $66CA SR: $0266CA 集中攻撃時のターゲット確定
0266C9 RTS return
  • SR: $0266CA 集中攻撃時のターゲット確定
0266CA LDY $2428 Y=$2428
0266CD JSL $C2CAE0 SR: $02CAE0 引数:1#$203C 引数:2#$00FF グループIDを取得
0266D5 CMP #$0005 A>=#$0005? PC側ならスキップ
0266D8 BCS #$31 if(c==on) goto $02670B
0266DA TAX X=A
0266DB LDA $2462,X A=$2462+X グループごとの集中攻撃ターゲットを取得
0266DE AND #$00FF A&=#$00FF
0266E1 STA $2430 $2430=A
0266E4 CMP #$00FF A==#$00FF? 集中攻撃ターゲットが未設定
0266E7 BEQ #$05 if(z==on) goto $0266EE
0266E9 JSR $670C SR: $02670C 集中攻撃ターゲットが生きているか?
0266EC BCC #$1D if(c==off) goto $02670B
0266EE JSR $7040 SR: $027040 モンスター行動対象候補列挙
0266F1 JSL $C2C766 SR: $02C766 引数:1#$00 生者のみ残す
0266F6 PHX Push X
0266F7 LDX #$0000 X=#$0000
0266FA JSL $C01407 SR: $001407 dp,Xの1になっているビットをランダムで0にする?
0266FE PLX Pull X
0266FF BCC #$0A if(c==off) goto $02670B
026701 STA $2430 $2430=A 攻撃対象に設定
026704 SEP #$20 m=on(A/M:8b)
026706 STA $2462,X $2462+X=A 集中攻撃ターゲットとして記憶
026709 REP #$20 m=off(A/M:16b)
02670B RTS return

ここをまじめに解析すると「集中攻撃」とは「グループごとに選択したターゲットを戦闘終了後まで相手が死ぬ(or離脱)まで攻撃し続ける」というものであることがわかります。$7E2462-5にグループ(0~3)ごとに選択されたターゲットの情報が保持されており、集中攻撃をするモンスター(集中攻撃フラグON、知能がバカ以外)が集中攻撃のフラグがONになっている戦闘行動(基本的に打撃攻撃)についてこの情報が使用されます。集中攻撃をしてくるモンスターはあまり多くなく、おばけありくい、キャットフライ、ミイラ男、マドハンド、デーモンソードだけです。マドハンドなどは1グループで大量に出現した場合などは後から呼ばれた仲間も集中攻撃をするので対象になったキャラクターにはスカラを掛けるなど対策をした方がいいかもしれません。普通にやるなら王者の剣や稲妻の剣で一掃なんでしょうが。