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

| 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グループで大量に出現した場合などは後から呼ばれた仲間も集中攻撃をするので対象になったキャラクターにはスカラを掛けるなど対策をした方がいいかもしれません。普通にやるなら王者の剣や稲妻の剣で一掃なんでしょうが。
コメント