基礎知識
戦闘関係
現代編のワタナベイベントは、グレート・エイジャが左上向きかつ、「カミツキ(青)」を高原がくらった時に低確率で発生する(高原の向きなど、高原の状態は関係ない)が、実際の確率はどの程度で、プログラム内ではどうやって計算しているのだろうか。
(ちなみにリメイク版だとワタナベイベント発生条件が異なるので、リメイク版攻略を参照のこと)
調査の結果だけ先に述べると、
現代編のワタナベイベントは、グレート・エイジャが左上向きの状態で、高原 日勝が「カミツキ(青)」をくらった時に10/256(約4%)の確率で発生する。
具体的には、「カミツキ(青)」のモーションの終わる寸前にワタナベイベント判定用の乱数0~255を生成し、その乱数が128~137だったら、エイジャが左上向きかどうかを判定した後、ワタナベイベントが発生する。
おそらくこれで合っているはずである。
高原の向きや位置など、高原のステータスは関係しない。エイジャも左上向き以外の条件はない。
また、条件を満たせば、一度の戦闘中に何度でも発生する。
以下では具体的な計算方法やプログラムを紹介する。
現代編のワタナベイベントは、エイジャが左上向きかつ、「カミツキ(青)」のモーションを出している間に、「続けてワタナベイベントのモーションを出すかどうか」を乱数で判定して、発生させるかどうかを決めている。
技のダメージ量やヒット数計算は、技決定後から技のモーションが入るまでに行われるのに対し、ワタナベイベント判定は技のモーション中に行われるという違いがある。おそらく、「ほいこーろー」が踊りながら次の踊りを続けるかどうか判定しているのと似たようなものなのだろう。
技のモーションは技ごとに決まっているが、そのモーションを戦闘フィールド上のどの位置に出すか、攻撃側と攻撃される側の位置(戦闘フィールド上の座標)から毎フレーム計算している。
「カミツキ(青)」でいえば、エイジャが攻撃相手に飛びかかる技だから、「エイジャのドット絵を、どの方向にどの距離、どの速度で移動させ、どの位置に青い光のエフェクトを出すか」を、エイジャの位置と高原の位置から計算しなければならない。
方向と距離の計算なので、三角関数や、線型代数学のベクトル・行列に関係した計算になるのだろうと思うが、現代編のワタナベイベントには関係しない話なので、ここではそこまで踏み込まない。
「カミツキ(青)」の場合は、エイジャが「カミツキ(青)」の通常モーションを終えるタイミング、つまり元から居たマスに戻る寸前くらいに、ワタナベイベントを発生させるかどうか、戦闘用乱数を使って判定を行う。
モーションの計算と同時進行なためか、サブルーチンは少々ややこしくなっている。
なお、グレート・エイジャが左上向きかどうかは、乱数計算の後に行っている。
つまり、エイジャの向きに関係なく、「カミツキ(青)」を出した時には必ず乱数計算をしている。
乱数がワタナベイベントが発生する条件を満たしている場合のみ、その後にエイジャの向きを判定し、左上向きだった時はワタナベイベントを発生させている。
現代編のワタナベイベント判定は、「カミツキ(青)」のモーションの計算サブルーチンに組み込まれている。つまり、定数を変えつつループ処理を繰り返す中で、「カミツキ(青)」のモーションの最後に「続けてワタナベイベントのモーションを出すかどうか」を判断している。
その定数は、今回で言えば$D5:B375~$D5:B37Cに最初から入っている値になる。
バンク$D5には、ゲーム内の各種データ(味方・敵の各種データ類)が入っており、その中の技モーションに関するデータの一部だと思われる(未調査)。
その他、モーション関連の未調査のメモリの値も幾つかあるが、とりあえず今回の目的は確率計算方法なので触れない。
$D5:B375~$D5:B37Cの値は以下のとおりである。
「カミツキ(青)」のモーション計算に使われる定数の中の一部及び、ワタナベイベント判定用の数値が含まれている。
| アドレス | 数値 |
|---|---|
$D5:B375 | $88 |
$D5:B376 | $00 |
$D5:B377 | $70 |
$D5:B378 | $D8 |
$D5:B379 | $00 |
$D5:B37A | $FC |
$D5:B37B | $90 |
$D5:B37C | $B3 |
もうひとつ、今回の判定でキーポイントになるのが、メモリアドレス[$7E:A010][$7E:A011]である。
[$7E:A0??]は、技のモーション関係の値が次々更新されていくのだが、[$7E:A010][$7E:A011]は最初にどちらにも$00が入って以降、エイジャの技の中で、「カミツキ(青)」のワタナベイベント判定時及びワタナベイベント中にのみ計算値が入り、ワタナベイベントの後は再び$00が入る、というアドレスである。
ただし、単純に乱数の値が入るのではない。
「カミツキ(青)」のワタナベイベント判定は、上にも記した通りに技のモーション計算のサブルーチン中で行われる。
「カミツキ(青)」でモーションの最後にエイジャが元の位置に戻ってきたあたり、$C1/A666~$C1/A6F7で、「カミツキ(青)」モーション計算用の$D5:B375~の値が計算用に呼び出され、以下のように配置される。
| アドレス | 数値 | 配置先アドレス |
|---|---|---|
$D5:B375 | $88 | [$00:0310] |
$D5:B376 | $00 | [$00:0311] |
$D5:B377 | $70 | [$00:0312] |
$D5:B378 | $D8 | - |
$D5:B379 | $00 | - |
$D5:B37A | $FC | - |
$D5:B37B | $90 | - |
$D5:B37C | $B3 | - |
また、ここまでの計算で、$00:031C~$00:031Fに以下のように値が入る。
| アドレス | 数値 |
|---|---|
[$00:031C] | $78 |
[$00:031D] | $B3 |
[$00:031E] | $00 |
[$00:031F] | $A0 |
この後に、戦闘用乱数の計算で紹介した、$C1/6150~$C1/61A4で戦闘用乱数を2回連続で生成する。
本作の戦闘用乱数は、次の乱数の計算用に、1~4つ前の乱数が保存されており、以下アドレスに入る。
$00:0338(乱数4)$00:0339(乱数3)$00:033A(乱数2)$00:033B(乱数1)よって、2回連続で乱数を生成すると、1回目に生成した乱数は[$00:033A]、2回目に生成した乱数は[$00:033B]及び、アキュムレータAに入る。
以下では、最初に生成した乱数[$00:033A]を『乱数2』、二度目に生成した新しい方の乱数[$00:033B]を『乱数1』とする。
[$7E:A010]と[$7E:A011]の計算具体的なサブルーチンを紹介する。
前半部は、上で述べた[$7E:A010][$7E:A011]に入れる値を計算するサブルーチンである。
符号付8bit x 8bitの掛け算が何度か行われている。
符号付8bit x 8bitの掛け算は、[$00:4202]に被乗数、[$00:4203]に乗数をセットすると、答え(16bit)の上位バイトが[$00:4217]、下位バイトが[$00:4216]に入る。
$C1/A842 LDA $11 [$00:0311] ;Aに[$00:0311]=$00をロード $C1/A844 STA $4202 [$00:4202] ;符号付8bit x 8bit 被乗数[$00:0311]=$00 $C1/A847 LDA $3A [$00:033A] ;Aに[$00:033A]=『乱数2』をロード $C1/A849 STA $4203 [$00:4203] ;符号付8bit x 8bit 乗数[$00:033A]=『乱数2』 $C1/A84C NOP ;乗算待ち時間 $C1/A84D NOP ;乗算待ち時間 $C1/A84E NOP ;乗算待ち時間 $C1/A84F NOP ;乗算待ち時間 $C1/A850 LDA $4217 [$00:4217] ;符号付8bit x 8bitの計算結果上位バイト=$00*『乱数2』 $C1/A853 STA $16 [$00:0316] ;[$00:0316]=$00*『乱数2』=$00 $C1/A855 LDA $3B [$00:033B] ;Aに[$00:033B]=『乱数1』をロード $C1/A857 STA $4203 [$00:4203] ;符号付8bit x 8bit 乗数([$00:033B]=『乱数1』) $C1/A85A NOP ;乗算待ち時間 $C1/A85B NOP ;乗算待ち時間 $C1/A85C CLC ;キャリーフラグをクリア $C1/A85D LDA $16 [$00:0316] ;Aに[$00:0316]=$00をロード $C1/A85F ADC $4216 [$00:4216] ;$00+符号付8bit x 8bitの計算結果下位バイト=$00 $C1/A862 STA $16 [$00:0316] ;[$00:0316]=$00 $C1/A864 LDA #$00 ;Aに$00をロード $C1/A866 ADC $4217 [$00:4217] ;A+[$00:4217]=$00 $C1/A869 STA $17 [$00:0317] ;A(=$00)を[$00:0317]に書き込み $C1/A86B LDA $12 [$00:0312] ;Aに[$00:0312]=$70をロード $C1/A86D STA $4202 [$00:4202] ;符号付8bit x 8bit被乗数 [$00:0312]=$70 $C1/A870 LDA $3A [$00:033A] ;Aに[$00:033A]=『乱数2』をロード $C1/A872 STA $4203 [$00:4203] ;符号付8bit x 8bit 乗数 [$00:033A]=『乱数2』 $C1/A875 NOP ;乗算待ち時間 ※$70*『乱数2』 $C1/A876 NOP ;乗算待ち時間 $C1/A877 LDA $16 [$00:0316] ;Aに[$00:0316]=$00をロード $C1/A879 CLC ;キャリーフラグをクリア $C1/A87A ADC $4216 [$00:4216] ;A($00)+「$70*『乱数2』の下位バイト」 $C1/A87D STA $16 [$00:0316] ;A(=$70*『乱数2』の下位バイト)を[$00:0316]に書き込み $C1/A87F LDA $17 [$00:0317] ;Aに[$00:0317]=$00をロード $C1/A881 ADC $4217 [$00:4217] ;A($00)+「$70*『乱数2』の上位バイト」 $C1/A884 STA $17 [$00:0317] ;A(=$70*『乱数2』の上位バイト)を[$00:0317]に書き込み $C1/A886 LDA #$00 ;Aに$00をロード $C1/A888 ADC #$00 ;A+$00=$00 $C1/A88A STA $18 [$00:0318] ;A(=$00)を[$00:0318]に書き込み $C1/A88C LDA $3B [$00:033B] ;Aに[$00:033B]=『乱数1』をロード $C1/A88E STA $4203 [$00:4203] ;符号付8bit x 8bit 乗数([$00:033B]=『乱数1』) $C1/A891 NOP ;乗算待ち時間 ※[$00:4202]には[$00:0312]=$70が $C1/A892 NOP ;乗算待ち時間 ※入ったままなので、$70*『乱数1』 $C1/A893 CLC ;キャリーフラグをクリア $C1/A894 LDA $17 [$00:0317] ;Aに[$00:0317](=$70*『乱数2』の上位バイト)をロード $C1/A896 ADC $4216 [$00:4216] ;A+「$70*『乱数1』の下位バイト」 $C1/A899 STA $17 [$00:0317] ;Aを[$00:0317]に書き込み $C1/A89B LDA $18 [$00:0318] ;Aに[$00:0318]=$00をロード $C1/A89D ADC $4217 [$00:4217] ;A(=$00)+「$70*『乱数1』の上位バイト」 $C1/A8A0 STA $18 [$00:0318] ;A(=「$70*『乱数1』の上位バイト」)を[$00:0318]に書き込み $C1/A8A2 LDA $10 [$00:0310] ;Aに[$00:0310]=$88をロード $C1/A8A4 AND #$0F ;A($88)と$0Fで論理積=$08 $C1/A8A6 ASL A ;A($08)算術左シフト(*2) $08*2=$10 $C1/A8A7 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/A8A9 AND #$00FF ;$A810と$00FFで論理積=$0010 $C1/A8AC ADC $1E [$00:031E] ;A(=$0010)+[$00:031E]=$A010 $C1/A8AE TAX ;Aレジスタの値をXレジスタに転送(X=$A010) $C1/A8AF LDA $11 [$00:0311] ;[$00:0311]=$00,[$00:0312]=$70をAにロード(16bit幅)=$7000 $C1/A8B1 LSR A ;A(=$7000)論理右シフト(/2) $7000/2=$3800 $C1/A8B2 STA $19 [$00:0319] ;Aを[$00:0319][$00:0320]に書き込み [$00:0319]=$00,[$00:0320]=$38 $C1/A8B4 LDA $17 [$00:0317] ;[$00:0318][$00:0317]をロード $C1/A8B6 SEC ;キャリーフラグを立てる $C1/A8B7 SBC $19 [$00:0319] ;[$00:0318][$00:0317] - $3800 $C1/A8B9 CLC ;キャリーフラグをクリア $C1/A8BA ADC $7E0000,x[$7E:A010] ;A+[$7E:A011][$7E:A010]=A+$0000 $C1/A8BE STA $7E0000,x[$7E:A010] ;Aを[$7E:A011][$7E:A010]に書き込み $C1/A8C2 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/A8C4 LDX $1C [$00:031C] ;[$00:031C]=$B378 $C1/A8C6 BRL $FDF2 [$A6BB] ;フラグにかかわりなく常に分岐[$A6BB]
途中からかなり入り組んでわかりにくくなったが、途中までは16bit×16bitの乗算を行っている。
つまり、[$00:0312][$00:0311]を16ビット(16進数4桁)の値、『乱数2』『乱数1』を16ビットの値として扱い、[$00:0312][$00:0311]×『乱数2』『乱数1』を部分的に計算している。
今回は[$00:0312]が$70、[$00:0311]が$00なので、$7000×『乱数2』『乱数1』ということである。
16bit×16bitの答えは32ビット(16進数8桁)だが、その中の上4桁分が[$00:0318][$00:0317]に入ったことになっている。
最終的に、[$7E:A010]と[$7E:A011]に入る値は、以下のようにして決まったことになる。
[$7E:A010] = (「$70*『乱数2』」の結果の上位バイト部分+「$70*『乱数1』」の結果の下位バイト)の下位バイト[$7E:A011] = 「$70*『乱数1』」の結果の上位バイト部分 - $38※16bitで考えると、
[$7E:A011][$7E:A010] = [$7E:A011][$7E:A010] + ([$00:0318][$00:0317] - [$00:0312][$00:0311]/2)
ただし[$00:0318][$00:0317] = [$00:0311]*『乱数1』の上位バイト + [$00:0312]*『乱数2』の上位バイト + [$00:0312]*『乱数1』の下位バイト
……というような感じか(自信はないが)。
乱数($00~$FF)に$70を掛け算した場合、結果の上位バイト部分は$00~$6Fに限定され、下位バイトは下1桁が必ず0の$00, $10, $20, $30, $40 ~, $D0, $E0, $F0になる。
少しややこしいのが、$C1/A8B7のSBC $19の減算である。
16bitモードでアキュムレータAから[$00:0319]を引き算しろ、ということになり、[$00:0319]=$00,[$00:0320]=$38なので、
A - $3800
の計算である。
また、この時点でのAは、上2桁が[$00:0318]の値、下2桁が[$00:0317]の値である。
$3800の下2桁は00なので、引き算しても、下2桁はAの下2桁のままである。つまり[$00:0317]のままである。
上2桁だけ見ると、
[$00:0318] - $38
ということになるが、[$00:0318]が$38より小さいと、答えが負の値になってしまう。
だが、引き算の前の$C1/A8B6でキャリーフラグが立っているため、本来2桁の値の[$00:0318]の上に「1」を付けて3桁とし、繰り下がりを考慮して計算することになる。
例えば、[$00:0318]が$10だったら、$38より小さいから、キャリーフラグにより、
$110 - $38
と、3桁目に「1」をつけて計算し、答えが「$D8」になる。
なお、この時点の[$00:0318] = 「$70*『乱数1』の結果の上位バイト部分」である。
つまり、[$00:0318]に入っているのは、$00~$6Fのどれかである。
$00~$37の時はキャリーフラグで繰り下がりが発生する引き算、$38以上は繰り下がりが発生しない引き算である。
結局、[$7E:A011]は、$C8~$FF、$00~$38のいずれかの値、ということがわかる。
[$7E:A011]の値は、後々でワタナベイベント発生確率に関係してくる。
[$7E:A010]と[$7E:A011]の値が決まった後の続きを見ていこう。
ここからがワタナベイベントの判定である。
関係のあるサブルーチンだけ紹介していく。
計算前に、再び「カミツキ(青)」モーション計算用の$D5:B375~の値が計算用に呼び出され、以下のように配置される。
先に呼び出し済みの$D5:B375~$D5:B377はここまでの計算で使ってしまったため、以降では不要である。
呼び出し先の[$00:0310]~[$00:0314]に、$D5:B378~$D5:B37Cを入れている。
| アドレス | 数値 | 移動先アドレス |
|---|---|---|
$D5:B375 | $88 | - |
$D5:B376 | $00 | - |
$D5:B377 | $70 | - |
$D5:B378 | $D8 | [$00:0310] |
$D5:B379 | $00 | [$00:0311] |
$D5:B37A | $FC | [$00:0312] |
$D5:B37B | $90 | [$00:0313] |
$D5:B37C | $B3 | [$00:0314] |
更に、以下の値も使用する。
[$00:031C]は値が更新されている。
| アドレス | 数値 |
|---|---|
[$00:031C] | $7D |
[$00:031D] | $B3 |
[$00:031E] | $00 |
[$00:031F] | $A0 |
以下、$C1/AFB0から16bitモードだが、この時点のAには$AF10が入っている。
$C1/AFAB LDA $10 [$00:0310] ;Aに[$00:0310]=$D8をロード $C1/AFAD AND #$0F ;A(=$D8)と$0Fの論理積 = $08 $C1/AFAF ASL A ;Aを算術左シフト $08*2 = $10 $C1/AFB0 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/AFB2 AND #$00FF ;A(=$AF10)と$00FFで論理積 = $0010 $C1/AFB5 ADC $1E [$00:031E] ;A(=$AF10)+$A000 = $A010 $C1/AFB7 TAX ;A(=$A010)をXレジスタに転送(X=$A010) $C1/AFB8 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/AFBA LDA $7E0000,x[$7E:A010] ;Aに[$7E:A010]をロード $C1/AFBE AND $11 [$00:0311] ;A(=[$7E:A010])と[$00:0311](=$00)と論理積 $C1/AFC0 BNE $0D [$AFCF] ;ゼロフラグが立っていないとき[$AFCF]分岐 $C1/AFC2 LDA $7E0001,x[$7E:A011] ;A(=[$7E:A011])をロード $C1/AFC6 AND $12 [$00:0312] ;A(=[$7E:A011])と[$00:0312](=$FC)と論理積 $C1/AFC8 BNE $05 [$AFCF] ;ゼロフラグが立っていないとき[$AFCF]分岐 $C1/AFCA LDX $1C [$00:031C] ;Xに[$00:031C](=$B37D)をロード $C1/AFCC BRL $F6EC [$A6BB] ;フラグにかかわりなく常に分岐[$A6BB]
$C1/AFAB~$C1/AFB8は、[$7E:A010]と[$7E:A011]を呼び出すためのアドレス位置の数値($A010)を計算している。
この後の$C1/AFBAからがワタナベイベントの判定になる。
まず、$C1/AFBEにて、[$7E:A010]と[$00:0311]=$00で論理積をとり、ゼロフラグが立つかどうかを確認している。
8bitモードなので、何かの16進数2桁と$00で論理積ということになるが、どんな数値でも$00と論理積を取れば結果は$00である。
[$00:0311]に入る値は変数だから、「カミツキ(青)」モーション計算時では$00が入っていたというだけで、他モーションでは他の値が入り、何かしら他の分岐に使うのだろう(未確認)。
何はともあれ、ここでは必ずゼロフラグが立って、$C1/AFC2の処理に進む。
ついで、[$7E:A011]と[$00:0312](=$FC)と論理積をとっている。
次の判定はゼロフラグが立つかどうかである。
ここがワタナベイベント判定の分岐で、ゼロフラグが立つとそのままサブルーチンが進みワタナベイベントが発生する。
ゼロフラグが立たない場合は[$AFCF]へ分岐、ワタナベイベントは発生しない。
厳密には、ここでゼロフラグが立った後、更にエイジャの向きを判定して、左上向きの時だけワタナベイベントが発生するが、とりあえず乱数関係の話を進める。
話を戻し、[$7E:A011]と$FCの論理積の計算について考えてみよう。
論理積は、数値を2進法にしてそれぞれの位を比較し、両方とも1なら1、それ以外は0にする演算である。
$FCは2進法だと%1111 1100である。
%1111 1100と論理積で0になる数値は、%0000 00??である。
つまり、
%0000 0000 = $00
%0000 0001 = $01
%0000 0010 = $02
%0000 0011 = $03
この4種類しかない。
[$7E:A011]と$FCの論理積でゼロフラグが立つのは、[$7E:A011]が$00, $01, $02, $03の時であり、ワタナベイベントが発生する。
ということになる。
[$7E:A011]は、上で計算済みであるが、
[$7E:A011] = 「$70*『乱数1』」の結果の上位バイト部分 - $38
※キャリーフラグが立った状態で減算するので負の数にはならない
であり、$C8~$FF、$00~$38のいずれかの値になることが判明している。
[$7E:A011]が$00~$03の時だけワタナベイベントが発生である。
キャリーフラグを立てて繰り下がりが起きた時の値は$C8~$FFだから、繰り下がりが起きた時点でワタナベイベントが発生しないことがわかる。
最終的に、『乱数1』しかワタナベイベント判定に関わっていなかったということがわかった。
結局、『乱数1』がどの範囲だと、ワタナベイベントが発生することになるのだろうか。
ここからは『乱数1』を「R」とする。
[$7E:A011] = 「$70*R」の結果の上位バイト部分 - $38
ということになるが、「$70*R」の結果(16進数4桁)の上位バイト部分(上2桁)は、結局、小数点位置をふたつ左に移動した、「$70*R」÷$100のことである、とこれまでにも紹介した通りである。
この時に小数点以下が切り捨てになる点も注意。
よって、
[$7E:A011] = $70*R/$100 - $38
ワタナベイベントが発生するのは、
$00 ≦ $70*R/$100 - $38 ≦ $03
ただし$70*R/$100≧$38
ということになる。
この条件を満たすRは、$80~$89になる。
(計算する時にちょっとややこしいため、$70*R/$100≧$38の前提で不等式全体に$38を足して、$38 ≦ $70*R/$100 ≦ $3Bと考えても良い)
以上から、乱数$00~$FF(10進数0~255)のうち、$80~$89(10進数128~137)の時のみワタナベイベントが発生するので、確率としては10/256でワタナベイベント発生、ということが判明した。
10/256≒0.0391なので、だいたい4%である。
低すぎるというほどでもないが、高確率でもない、絶妙な確率になっている。
仮に「カミツキ(青)」を50回くらった場合、1回以上ワタナベイベントが発生する確率は、
1-(1-(10/256))^50 ≒ 0.864
86%程度である。100回まで増やせば98%程度まで上がる。
50回くらえばそこそこの確率で、100回くらえばほぼ確実に一度は見られる確率になる。
とはいえ、エイジャは「カミツキ(青)」より「カミツキ(黄)」を優先して出してくること、高原が毒状態なら比較的「カミツキ(青)」が出やすいがその状態を維持することが難しいこと(「気合いため」でHP回復すると毒状態も回復する、「気合いため」のHP回復量が「カミツキ」のダメージをギリギリ相殺できる程度)、といった理由から、本気で見たい場合は倒されるのを覚悟で何戦も粘る必要がある。
それでも条件がわかっていれば、長くても1時間少々くらい踏ん張れば見られるだけ有情なイベントである。
本作の場合、レアなドロップアイテムを狙う方がよほど手間と時間がかかることは、やりこみ勢なら知っての通りであろう。
また、条件さえ満たせば、一度の戦闘中に何度でもワタナベイベントが発生する。
リメイク版では、エイジャが右上向きまたは左上向きで「カミツキ(青)」を出すとワタナベイベントが確実に発生、と条件が変更されて、条件を知らずに普通にプレイしているだけでも見られるケースが増えた。ただしリメイク版では、一度の戦闘にワタナベイベントが発生するのは一度だけである。
ここまでの話は、エイジャが左上向き前提で進めてきたような雰囲気になってしまったが、最初に記したとおり、実際にはエイジャが「カミツキ(青)」を出した時、エイジャの向きに関係なく上の乱数判定は起きている。
そして、[$7E:A011]が$00~$03の時は、向きに関係なく、上のサブルーチンの$C1/AFCCに到達して続きの計算を行うことになる。
つまり、向き判定は乱数での判定の後である。
どこで判定しているのかを、最後に説明する。
まず、敵の向きはどこに記録されているかだが、1番目の敵、この戦闘で言えばエイジャの向きは[$00:1B04]に記録される。
入る値は、以下の4種類である。
| 向き | 数値 |
|---|---|
| 右下 | $00 |
| 左下 | $40 |
| 右上 | $80 |
| 左上 | $C0 |
向きの値[$00:1B04]は、技モーション中などに何度も読み込まれているが、「カミツキ(青)」のワタナベイベント用の判定のため(他の判定に使われているかは未確認)、別途以下のサブルーチンでも読み込まれている。
$C1/2ADD LDA $0004,y[$00:1B04] ;X:A000 Y:1B00 Aに[$00:1B04]を読み込み $C1/2AE0 ROL A ;X:A000 Y:1B00 Aを左ローテート $C1/2AE1 ROL A ;X:A000 Y:1B00 Aを左ローテート $C1/2AE2 AND #$01 ;X:A000 Y:1B00 Aと$01で論理積 $C1/2AE4 ORA $10 [$00:0310] ;X:A000 Y:1B00 Aと[$00:0310](=$00)で論理和 $C1/2AE6 ORA #$38 ;X:A000 Y:1B00 Aと$38で論理和 $C1/2AE8 STA $7E001D,x[$7E:A01D] ;X:A000 Y:1B00 Aを[$7E:A01D]に書き込み
左ローテートというのは16進数2桁の数値を2進数8桁で見た時に、数値を1つ左に動かす処理のこと。
ただしキャリーフラグの桁溢れ分も考慮して左に動かすので、実質9桁をぐるぐると回転させるイメージである。
たとえば、左上向きの$C0は、2進数だと%1100 0000で、この時点ではキャリーフラグがないから、「0 1100 0000」を左に1ずつ回し、一番左のキャリー分が一番右に入るという計算になる。
つまり、「0 1100 0000」→「1 1000 0000」→「1 0000 0001」で、2回左ローテートした結果はキャリー分の一番上を除いた%0000 0001=$01となる。
そのほか、細かい計算は省くが、最終的に計算結果が[$7E:A01D]に収まっており、後々で[$7E:A01D]が向き判定に使われる。
[$7E:A01D]に入る値は以下の通り。
| 向き | [$7E:A01D] |
|---|---|
| 右下 | $38 |
| 左下 | $38 |
| 右上 | $38 |
| 左上 | $79 |
実は左ローテート2回の時点で、$C0以外は$00になってしまうため、上のように左上向きだけ$79、他の向きは$38となる。
もうこの時点で、[$7E:A01D]=$79の時だけワタナベイベントを発生させるのだろう、とわかっただろう。
実際の判定方法は少し違うが似たようなものである。
では、[$7E:A011]が$00~$03が判定された先のサブルーチンを見てみる。
向きに関係するところのみ掲載する。
アドレス指定が重要なので、Xの値も併記する。
$C1/A717 LDA $D50000,x[$D5:B37F] ;X:B37F Aに[$D5:B37F](=$40)をロード $C1/A71B STA $12 [$00:0312] ;X:B37F A(=$40)を[$00:0312]に書き込み ;(中略) $C1/AFC2 LDA $7E0001,x[$7E:A01D] ;X:A01C Aに[$7E:A01D](=$79)をロード $C1/AFC6 AND $12 [$00:0312] ;X:A01C A(=[$7E:A01D])と[$00:0312](=$40)で論理積 $C1/AFC8 BNE $05 [$AFCF] ;X:A01C ゼロフラグが立っていないとき[$AFCF]分岐
$C1/AFC6が分岐である。
この時点で、[$7E:A01D]には上記の向きからの計算値($38か$79)、[$00:0312]は[$D5:B37F]から呼び出した$40が入っている。
[$7E:A01D]と$40で論理積を取ると、$38と$40の論理積は$00、$79と$40の論理積は$40である。
よって、次の$C1/AFC8は、「左上向きの時だけゼロフラグが立たないので[$AFCF]へ」という条件での分岐になる。
ここで向き判定確定で、今度こそワタナベイベントが発生決定、ということである。