前回からの続きです。各行動パターン(均等・坂・崖・ローテ)に従って行動決定SRがコールされます。
- SR:$02672D モンスター行動決定
略 | |||
---|---|---|---|
$02676C | LDA $246E | A=$246E | |
$02676F | ASL | A< <1 | |
$026770 | TAX | X=A | |
$026771 | JSR $67AD | SR: $($0267AD+X) | |
$026774 | BCS #$27 | if(c==on) goto $02679D | |
略 |
ローテーションについては戦闘行動1>8の順で基本回していくというだけなのでまあいいとして、残りの均等・崖・坂の決定ルールはすべてここに書かれています。下記のコードを読む前に以下の知識を頭に入れておくと意味がわかりやすいです。「戦闘行動番号」とは各モンスターに設定されている8種類の戦闘行動のインデックスのことです。実際の戦闘行動ID(打撃攻撃が#$01、メラが#$06)とは違うので注意してください。また、戦闘行動番号はここでは戦闘行動1~8というように表現していますが、実際の値は0~7で表現されているので若干紛らわしいですが注意してください。
アドレス | 意味 |
---|---|
7E246C | 対象のモンスターのグループの同一ターン連発不可フラグ(テンポラリ) |
7E246E | 対象のモンスターの思考パターンSRへのオフセット |
7E2470 | 決定した戦闘行動番号(0~7) |
同一ターン連発不可フラグとは「連発不可の戦闘行動番号が同一ターン中で既に実行されているか」を記録するものです。下位ビットから戦闘行動1>8に対応しており、戦闘行動1が連発不可で実行済みなら#$01、戦闘行動8が連発不可で実行済みなら#$80、のようになっています。実際にあるかは不明ですが、全戦闘行動が連発不可で実行済みなら当然のごとく#$FFとなります。
- SR:$0267B5 行動パターンに応じた行動決定_SR_0000
$0267B5 | JSR $67DC | SR: $0267DC | 行動パターンに応じた戦闘行動インデックス決定(均等,丘,崖 決められないc=on) |
---|---|---|---|
$0267B8 | BCS #$12 | if(c==on) goto $0267CC | |
$0267BA | LDA $2470 | A=$2470 | |
$0267BD | STA $00 | DP($00)=A | |
$0267BF | JSL $C2C573 | SR: $02C573 引数:1#$00 | モンスター行動関連情報取得(実際の戦闘行動ID取得) |
$0267C4 | STA $242A | $242A=A | |
$0267C7 | JSR $68ED | SR: $0268ED | 選ばれた戦闘行動を実行するべきか(するべきでないc=on) |
$0267CA | BCS #$01 | if(c==on) goto $0267CD | |
$0267CC | RTS | return | |
$0267CD | LDA $2470 | A=$2470 | |
$0267D0 | JSL $C014F2 | SR: $0014F2 | 最大8ビットのビットマスク作成 |
$0267D4 | ORA $246C | Aor=$246C | 選択された戦闘行動インデックスを選択不可に追加する |
$0267D7 | STA $246C | $246C=A | |
$0267DA | BRA #$D9 | goto $0267B5 | もう1回選び直し |
このSRがモンスターの戦闘行動を決める大枠です。1)SR:$0267DCでどの戦闘行動番号を採用するのかが決定されます。この際に連発不可フラグも使用されますが、これについては後回しにします。2)選択された戦闘行動番号に対応して実際に実行される戦闘行動IDが取得されSR: $0268EDでその行動を実行するべきか判断します。3)実行してOKとなればそのまま対象選択に移りますが、実行するべきでないと判断された場合(例:自分がマホトーンにかかっている、マホカンタが既にかかっているのに更にマホカンタを実行しようとしている)、その戦闘行動番号を連発不可フラグに加え1)に戻って再選択する、という流れになっているようです。再選択時には2)で判断した戦闘行動番号は除外されるので、何回か繰り返せば最終的に行動が決定する、というようになっています。「連発不可フラグ」という表現をしましたが、ここでは実質「選択不可フラグ」と言い換えてもいいかもしれません。連発不可フラグが1~8まですべて埋まっている場合は「打撃攻撃(戦闘行動ID:1)」が選択されるようになっています。
- SR:$0267DC 行動パターンに応じた戦闘行動番号決定(均等,丘,崖)
$0267DC | LDA $246C | A=$246C | |
---|---|---|---|
$0267DF | CMP #$00FF | A>=#$00FF? | 連発不可フラグが全部埋まっているか? |
$0267E2 | BCC #$0A | if(c==off) goto $0267EE | |
$0267E4 | BNE #$02 | if(z==off) goto $0267E8 | |
$0267E6 | SEC | c=on | |
$0267E7 | RTS | return | 埋まっている場合は決められないというメッセージをコール元に返す |
$0267E8 | STA $C2D13F | $02D13F=A | 意味不明 |
$0267EC | SEC | c=on | |
$0267ED | RTS | return | |
$0267EE | STA $00 | DP($00)=A | |
$0267F0 | PHY | Push Y | |
$0267F1 | SEP #$20 | m=on(A/M:8b) | |
$0267F3 | LDY #$0000 | Y=#$0000 | |
$0267F6 | LDX $2472 | X=$2472 | |
$0267F9 | LDA #$00 | A=#$00 | |
$0267FB | LSR $00 | DP($00)>>1 | |
$0267FD | BCS #$05 | if(c==on) goto $026804 | |
$0267FF | CLC | c=off | |
$026800 | ADC $C268CD,X | A+=($0268CD+X+c) | |
$026804 | INX | X++ | |
$026805 | INY | Y++ | |
$026806 | CPY #$0008 | Y>=#$0008? | |
$026809 | BCC #$F0 | if(c==off) goto $0267FB | |
$02680B | DEC | A– | |
$02680C | JSL $C0133E | SR: $00133E | 乱数発生 00-A A(1B) |
$026810 | PHA | Push A | |
$026811 | LDY #$0000 | Y=#$0000 | |
$026814 | LDX $2472 | X=$2472 | |
$026817 | LDA $246C | A=$246C | |
$02681A | STA $00 | DP($00)=A | |
$02681C | PLA | Pull A | |
$02681D | LSR $00 | DP($00)>>1 | |
$02681F | BCS #$07 | if(c==on) goto $026828 | |
$026821 | SEC | c=on | |
$026822 | SBC $C268CD,X | A-=($0268CD+X+!c) | |
$026826 | BCC #$07 | if(c==off) goto $02682F | |
$026828 | INX | X++ | |
$026829 | INY | Y++ | |
$02682A | CPY #$0007 | Y>=#$0007? | |
$02682D | BCC #$EE | if(c==off) goto $02681D | |
$02682F | STY $2470 | $2470=Y | |
$026832 | STZ $2471 | $2471=#$00 | |
$026835 | REP #$20 | m=off(A/M:16b) | |
$026837 | PLY | Pull Y | |
$026838 | CLC | c=off | |
$026839 | RTS | return |
なにやら長い処理が並んでいますが、やっていることは「戦闘行動番号1~8のどれをルーレットに載せるか連発不可フラグを見ながら作成し、ダーツを投げて決める」というだけです。
行動1 | 行動2 | 行動3 | 行動4 | 行動5 | 行動6 | 行動7 | 行動8 | |
---|---|---|---|---|---|---|---|---|
均等 | 32 | 32 | 32 | 32 | 32 | 32 | 32 | 32 |
坂 | 18 | 22 | 26 | 30 | 34 | 38 | 42 | 46 |
崖 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 200 |
ローテ | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 |
この分布を見ながら例を挙げると、崖の場合、連発不可フラグが1個もたっていない場合は戦闘行動8が80%近く選択される歪なルーレットになるが、戦闘行動8に連発不可フラグが立っていた場合、戦闘行動8を除いた戦闘行動1~7(合計値:56)だけのルーレットが作成され、それぞれ選択される確率が大幅に上がる、ということになります。この連発不可フラグ(というか選択不可フラグ)はモンスターの構成、PC側の状態などで変わるため、データで設定した以上にバリエーション豊かな行動をモンスターがしてくる、ということになります。
さて、ここで当初の目標であった「ゾーマはなぜいてつく波動を1ターンに連発するのか」という疑問に戻りたいと思います。光ゾーマ(モンスターID:#$88)の戦闘行動は以下のように設定されています。
行動1 | 行動2 | 行動3 | 行動4 | 行動5 | 行動6 | 行動7 | 行動8 | |
---|---|---|---|---|---|---|---|---|
行動 | マヒャド | 吹雪 | 攻撃 | 攻撃 | 攻撃 | 波動 | 吹雪 | 波動 |
連発不可 | ◯ | ◯ | ☓ | ☓ | ☓ | ◯ | ◯ | ◯ |
凍てつく波動にはどちらも連発不可が付いていますが、これは行動6が選ばれたら行動6を再度選ばないというだけで、行動8が選ばれる可能性が残されています(逆もまた然り)。行動パターンは「均等」なので2回とも凍てつく波動が選択されるのは2/8☓1/7=1/28(多分)となり、長丁場になるゾーマ戦では比較的よく出くわすということになるのではと思われます。同様に凍える吹雪の2連発も同じ確率で発生します。ちなみに闇ゾーマは凍てつく波動は1つしか設定されていないので(連発不可もON)、この現象は起こり得ない、ということになります。
次回は「選択された戦闘行動をモンスターがどうやって実行する/しないを判断しているか」を見てこの追加分の解説は終わりにします。
コメント
二回いてつくはどうになる確率は2/8×1/7=1/28ではないでしょうか?
たしかにそうですね。修正しておきます。ご指摘ありがとうございました。