TOP > プログラミング関係解説&調査 > 向き補正(1)

向き補正(1)

当ページの内容は、ある程度のプログラミングの知識を必要とする。
まず、プログラミング関係解説&調査をひととおり読んでいただきたい。

戦闘時には、向きによる補正がかかる。
具体的には、攻撃時のレベルに関係する一部計算式に向きの補正がかかる。
ダメージ計算には自レベルと敵レベルが関わるし、命中判定も攻撃をくらう側のレベルの値が判定に必要である。

向きについては戦闘関係の解説 > 向きで説明しているが、■が右下向きなら、周囲のマスとの位置関係は以下のようになる。
「正」が正面、「側」が側面、「背」が背面である。

背背背側側
背背背側側
背背正正
側側正正正
側側正正正

複数マスにまたがる敵などは以下のようになり、●が味方とすると、●が敵を攻撃したら敵を正面から攻撃したことになる。

背背背背側側
背背背背側側
背背■■正正
背背正正
側側正正正
側側正正正正

「側」のマスから攻撃すれば側面からの攻撃、「背」のマスから攻撃すれば背面からの攻撃である。
この場合、敵はそれぞれ、自身のレベルから側面補正または背面補正を引いた値でダメージ量などを計算することになる。

複数マスにまたがる敵からの攻撃については少しややこしくなるので、次ページから詳しく説明している。

メモリアドレス

向き補正に関するメモリアドレスは以下の通り。

向き補正

味方キャラ

味方キャラデータ29の、

  • 上4ビット:背後補正
  • 下4ビット:側面補正

また、シナリオ別キャラデータの、

  • +$1C:側面補正
  • +1D:背面補正

である。

敵キャラ

敵キャラデータ29の、

  • 上4ビット:背後補正
  • 下4ビット:側面補正

戦闘中のキャラの向き

味方キャラ
味方キャラ番号アドレス
1$00:1C1D
2$00:1C5D
3$00:1C9D
4$00:1CDD
数値向き
$00右下
$01左下
$02右上
$03左上
敵キャラ

敵番号nの敵の向きは$00:1Bn4に入る。

数値向き
$00右下
$40左下
$80右上
$C0左上

サブルーチン

以下、味方が敵を攻撃する場合と、敵が味方を攻撃する場合の2パターンに分けて解説する。

味方が敵を攻撃する場合

先に結論を言うと、

アドレス内容
$7E:ABn0敵番号nの現在のレベル
$7E:ABnB敵番号nの向き補正 (正面:$00, 側面:$01, 背面:$80)
$7E:ABnA敵番号nの向き補正込みのレベル

というように値が入り、後の計算に使われるようになっている。
敵は0~Eまで最大で15体だから、向き補正込みのレベルの値は、$7E:AB0A, $7E:AB1A, $7E:AB2A, ……, $7E:ABEAに入ることになる。
この値は該当の敵を攻撃する度に更新されていくことになる。

まず、1×1マスサイズの味方キャラが敵を攻撃する場合について説明する。
今回はレベル6のアキラがレベル7のクルセイダーRSを「ローキック」で攻撃する場合を例として説明する。
クルセイダーRSの側面補正は8、背面補正は12とかなり大きめ。
この戦闘ではクルセイダーRSは敵番号E

まず、クルセイダーRS右下向き、アキラ左上向きで、下配置のようにクルセイダーの正面から攻撃する。

□□□□□□□
□□□□□□
□□□□□□
□□□□ア□□
□□□□□□□
□□□□□□□
□□□□□□□

座標は左上を原点とし、右方向をX軸、下方向をY軸として表す。
つまり、X座標は左から0~6、Y座標は上から0~6とカウントする。
アキラの位置は(4,3)になる。
複数マスにまたがる敵は左上マス位置を座標としているので、クルセイダーRSの座標は上側マスにあたる(3,1)である。

$C1/E061 LDX $78    [$00:0378]   ;Xに[$00:0378]をロード
$C1/E063 LDA $79    [$00:0379]   ;Aに[$00:0379]をロード
$C1/E065 CMP #$1C                ;Aと$1Cを減算比較(ステータスレジスタ変更のみ)
$C1/E067 BEQ $02    [$E06B]      ;ゼロフラグが立っているとき[$E06B]分岐
$C1/E06B LDA $0018,x[$00:1C18]   ;Aに[$00:1C18](アキラ キャラ位置のマス目のX座標)をロード
$C1/E06E STA $12    [$00:0312]   ;Aを[$00:0312]に書き込み
$C1/E070 LDA $0019,x[$00:1C19]   ;Aに[$00:1C19](アキラ キャラ位置のマス目のY座標)をロード
$C1/E073 STA $13    [$00:0313]   ;Aを[$00:0313]に書き込み
$C1/E075 RTS                     ;サブルーチン戻り

敵を攻撃する時の向き補正は、敵の向き・座標と味方の座標で決まる。
まず上のサブルーチンで、攻撃する味方キャラ、今回はアキラの現在の位置のマス目の座標を読み込む。
今回はアキラのマス目の座標が(4,3)であり、それぞれ[$00:1C18][$00:1C19]に入っているのだが、これをそれぞれ[$00:0312][$00:0313]にコピーする。

$C1/E0B6 BEQ $FB    [$E0B3]      ;ゼロフラグが立っているとき[$E0B3]分岐
;(中略)
$C1/E0D0 LDA $7E9000,x[$7E:ABE0] ;Aに[$7E:ABE0](敵LV(現在値))をロード
$C1/E0D4 STA $10    [$00:0310]   ;A(敵LV(現在値))を[$00:0310]に書き込み
;(中略)
$C1/E0F4 JSR $E127  [$C1:E127]   ;[$C1:E127]へジャンプ

$C1/E0B6$C1/E0F4は主に回避属性周りの処理だが、$C1/E0D0$C1/E0D4で敵LV(現在値)が[$00:0310]にコピーされる。
この敵LV(現在値)は、バフ・デバフなどで増減されている場合はその値が入っている。
クルセイダーRSのレベルは7なので、バフ・デバフが適用されていない限り、[$00:0310]$07が書き込まれる。

この先が位置と向きの判定になるのだが、分岐が多く少々ややこしいので、ひとまず敵が右下向きかつ正面からの攻撃という前提で処理を追ってみよう。

$C1/E127 LDY $0002,x[$00:1BE2]   ;Yに[$00:1BE2]をロード
$C1/E12A LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E12D BIT #$80                ;Aと$80で論理積(ステータスフラグ変更のみ)
$C1/E12F BEQ $0E    [$E13F]      ;ゼロフラグが立っているとき[$E13F]分岐
;ゼロフラグON 向きが$80(右上)か$C0(左上)以外
$C1/E13F LDA $13    [$00:0313]   ;Aに[$00:0313](アキラ マス目のY座標)をロード
$C1/E141 CMP $000B,x[$00:1BEB]   ;Aと[$00:1BEB](敵位置のマス目のY座標)を減算比較(ステータスレジスタ変更のみ)
$C1/E144 BCC $21    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
$C1/E146 BRA $00    [$E148]      ;フラグにかかわりなく常に分岐[$E148]
$C1/E148 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E14B BIT #$40                ;Aと$40で論理積(ステータスフラグ変更のみ)
$C1/E14D BEQ $0E    [$E15D]      ;ゼロフラグが立っているとき[$E15D]分岐
;ゼロフラグON 向きが$40(左下)以外=右下向き確定
$C1/E15D LDA $12    [$00:0312]   ;Aに[$00:0312](アキラ マス目のX座標)をロード
$C1/E15F CMP $000A,x[$00:1BEA]   ;Aと[$00:1BEA](敵位置のマス目のX座標)を減算比較(ステータスレジスタ変更のみ)
$C1/E162 BCC $03    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
$C1/E164 LDA #$00                ;Aに$00をロード
$C1/E166 RTS                     ;サブルーチン戻り
;
$C1/E0F7 STA $7E900B,x[$7E:ABEB] ;A($00)を[$7E:ABEB]に書き込み
$C1/E0FB BEQ $21    [$E11E]      ;ゼロフラグが立っているとき[$E11E]分岐
$C1/E11E LDA $10    [$00:0310]   ;Aに[$00:0310](敵LV(現在値))をロード
$C1/E120 STA $7E900A,x[$7E:ABEA] ;A(敵LV(現在値))を[$7E:ABEA]に書き込み
$C1/E124 BRA $8D    [$E0B3]      ;フラグにかかわりなく常に分岐[$E0B3]
$C1/E0B3 JSR $E1A9  [$C1:E1A9]   ;[$C1:E1A9]へジャンプ

敵番号nの敵の向きは[$00:1Bn4]に入り、今回は敵番号Eなので、$C1/E12A[$00:1BE4]をロードするが、敵の向きは右下向きなので[$00:1BE4]には$00が入っている。
まず、$C1/E12D$80で論理積をとりゼロフラグ判定をしている。
右上向き($80)または左上向き($C0)なら、$80と論理積を取ると$80になるからゼロフラグは立たない。
右下向き($00)または左下向き($40)なら、$80と論理積を取ると$00になるからゼロフラグが立つ。
ゼロフラグが立たない時は右上向きか左上向き、ゼロフラグが立つ時は右下向きか左下向きということになり、敵の向きが右下向きならゼロフラグが立ち$C1/E13Fへ進む。

$C1/E13Fで、先程の味方キャラのマス目のY座標をロードし、[$00:1BEB](敵位置のマス目のY座標)と減算比較する。
アキラの座標は(4,3)、クルセイダーRSの座標は(3,1)
よって3 - 1 = 2で正の数となり、減算で繰り下がりが発生しないことから、キャリーフラグが立つ。
キャリーフラグが立つのは減算で0以上の時だから、「クルセイダーRSはY軸でアキラと同じまたはアキラより上にいる」という時にキャリーフラグが立つことになる。
この時は$C1/E146に進む。

$C1/E148からは、敵の向きが左下向き($40)かどうかのゼロフラグ判定である。
ゼロフラグが立つ時は右下向きで確定ということになり$C1/E15Dへ進む。

$C1/E15Dからは、アキラのX座標から敵のX座標を減算比較し、キャリーフラグ分岐を行っている。
4 - 3 = 1で正の数となり、減算で繰り下がりが発生しないことから、キャリーフラグが立つ。
よってそのまま処理が進み、A$00をロードして、$C1/E166でサブルーチンが終了する。

$C1/E0F7以降を見てみると、Aの値は[$7E:ABEB]に書き込まれ、ゼロフラグが立っているので$C1/E11Eに飛び、[$00:0310](敵LV(現在値))がそのまま[$7E:ABEA](向き補正ありのレベル)に書き込まれている。
[$7E:ABEB]に書き込まれる値で、向き補正が決まっているのである。
$C1/E166までの処理で、[$7E:ABEB]$00が書き込まれる時は、向き補正なし、つまり正面からの攻撃と判断されている。
では、少し振り返って、どういう判断がされたか見てみる。

$C1/E15Dに進んだ時点で、クルセイダーRSが右下向きなのは確定である。
更に、クルセイダーRSとアキラの位置関係だが、座標の減算比較から、

  • クルセイダーRSはY軸でアキラと同じまたはアキラより上にいる
  • クルセイダーRSはX軸でアキラと同じまたはアキラより左にいる

という判定がされている。
クルセイダーRSの座標は上のマスの扱いだから、クルセイダーRSを基準とすると、アキラはクルセイダーRSより右側かつ下側にいる、ということになる。

□□□□□□□
□□□■■■
□□□■■■
□□□■■■■
□□□■■■■
□□□■■■■
□□□■■■■

上の■のどこかにアキラがいる、ということであり、これを「正面向き」と判定して、向きによるレベル補正がされないのである。

もしこれが横幅もある大型の敵の場合でも、左上マスが敵座標の基準だから、

□□□□□□□
□□敵敵■■■
□□■■■
□□■■■■■
□□■■■■■
□□■■■■■
□□■■■■■

正面の位置は上のように判定されることになる。

では、側面だとどうなるか。

□□□□□□□
□□□□□□
□□□□□□
□□ア□□□□
□□□□□□□
□□□□□□□
□□□□□□□

クルセイダーRSは右下向きのまま、アキラは左下から攻撃する。側面からの攻撃である。
今回は、アキラの位置は(2,3)になる。
クルセイダーRSの座標は(3,1)のまま。

$C1/E127 LDY $0002,x[$00:1BE2]   ;Yに[$00:1BE2]をロード
$C1/E12A LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E12D BIT #$80                ;Aと$80で論理積(ステータスフラグ変更のみ)
$C1/E12F BEQ $0E    [$E13F]      ;ゼロフラグが立っているとき[$E13F]分岐
;ゼロフラグON 向きが$80(右上)か$C0(左上)以外
$C1/E13F LDA $13    [$00:0313]   ;Aに[$00:0313](アキラ マス目のY座標)をロード
$C1/E141 CMP $000B,x[$00:1BEB]   ;Aと[$00:1BEB](敵位置のマス目のY座標)を減算比較(ステータスレジスタ変更のみ)
$C1/E144 BCC $21    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
$C1/E146 BRA $00    [$E148]      ;フラグにかかわりなく常に分岐[$E148]
$C1/E148 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E14B BIT #$40                ;Aと$40で論理積(ステータスフラグ変更のみ)
$C1/E14D BEQ $0E    [$E15D]      ;ゼロフラグが立っているとき[$E15D]分岐
;ゼロフラグON 向きが$40(左下)以外=右下向き確定
$C1/E15D LDA $12    [$00:0312]   ;Aに[$00:0312](アキラ マス目のX座標)をロード
$C1/E15F CMP $000A,x[$00:1BEA]   ;Aと[$00:1BEA](敵位置のマス目のX座標)を減算比較(ステータスレジスタ変更のみ)
$C1/E162 BCC $03    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
;[$00:0312]-[$00:1BEA]=2-3で負の値、キャリーOFF
$C1/E167 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E16A BIT #$80                ;Aと$80で論理積(ステータスフラグ変更のみ)
$C1/E16C BEQ $09    [$E177]      ;ゼロフラグが立っているとき[$E177]分岐
;ゼロフラグON 向きが$80(右上)か$C0(左上)以外
$C1/E177 LDA $000B,x[$00:1BEB]   ;Aに[$00:1BEB](敵位置のマス目のY座標)をロード
$C1/E17A CLC                     ;キャリーフラグクリア
$C1/E17B ADC $0005,y[$00:1A45]   ;A + [$00:1A45](敵の縦幅)
$C1/E17E DEC A                   ;Aをデクリメント -1
$C1/E17F CMP $13    [$00:0313]   ;A($02)と[$00:0313](アキラ マス目のY座標=3)を減算比較(ステータスレジスタ変更のみ)
$C1/E181 BCC $20    [$E1A3]      ;キャリーフラグが立っていないとき[$E1A3]分岐
;$02-[$00:0313]=2-3で負の値、キャリーOFF
$C1/E1A3 LDA #$01                ;Aに$01をロード
$C1/E1A5 RTS                     ;サブルーチン戻り

正面向きとの違いは$C1/E162のキャリーフラグ分岐からである。
今回はアキラのX座標が2なので、[$00:0312] - [$00:1BEA] = 2 - 3でキャリーフラグが立たず、$C1/E167の分岐先にジャンプする。
つまり、敵よりもアキラが左にいる場合の飛び先である。

$C1/E167$C1/E16Cで、再び[$00:1BE4](敵の向き)と$80で論理積を取りゼロフラグ判定だが、これはゼロフラグが立つから$C1/E177にジャンプである。
$C1/E177からはY座標の判定だが、今回は敵の縦幅を考慮している。
敵のY座標 + [$00:1A45](敵の縦幅) - 1」と、アキラのY座標との減算比較である。
敵のY座標 + [$00:1A45](敵の縦幅) - 1」は敵の一番上のマスのY座標である。
クルセイダーRSでいえば、高さ2マスのキャラだが、座標は上側のマス基準である。
下側のマスのY座標は上の計算で算出できる。
よって、「敵の一番下のマスのY座標」と、アキラのY座標との減算比較になる。
結果、$02 - [$00:0313] = 2 - 3で負の値だからキャリーフラグが立ち、$C1/E1A3にジャンプして$01Aにロードし、サブルーチンが戻る。

$C1/E0F7 STA $7E900B,x[$7E:ABEB] ;Aを[$7E:ABEB]に書き込み
$C1/E0FB BEQ $21    [$E11E]      ;ゼロフラグが立っているとき[$E11E]分岐
$C1/E0FD BMI $09    [$E108]      ;ネガティブフラグが立っているとき[$E108]分岐
$C1/E0FF LDA $003D,y[$00:1A7D]   ;Aに[$00:1A7D](敵データ29 背後補正/側面補正)をロード
$C1/E102 AND #$0F                ;A($C8)と$0Fで論理積
$C1/E104 STA $11    [$00:0311]   ;A($08)を[$00:0311]に書き込み
$C1/E106 BRA $0B    [$E113]      ;フラグにかかわりなく常に分岐[$E113]
$C1/E113 LDA $10    [$00:0310]   ;Aに[$00:0310]($07)(敵LV(現在値))をロード
$C1/E115 SEC                     ;キャリーフラグON
$C1/E116 SBC $11    [$00:0311]   ;A($07) - [$00:0311]($08)
$C1/E118 STA $10    [$00:0310]   ;A($FF)を[$00:0310]に書き込み
$C1/E11A BCS $02    [$E11E]      ;キャリーフラグが立っているとき[$E11E]分岐
$C1/E11C STZ $10    [$00:0310]   ;[$00:0310]に$00を書き込み
$C1/E11E LDA $10    [$00:0310]   ;Aに[$00:0310]($00)をロード
$C1/E120 STA $7E900A,x[$7E:ABEA] ;A($00)を[$7E:ABEA]に書き込み
$C1/E124 BRA $8D    [$E0B3]      ;フラグにかかわりなく常に分岐[$E0B3]
$C1/E0B3 JSR $E1A9  [$C1:E1A9]   ;[$C1:E1A9]へジャンプ

側面からの攻撃だと[$7E:ABEB]に入るのは$01となり、$C1/E0FB$C1/E0FDでゼロフラグもネガティブフラグも立たないから、$C1/E0FFに進む。
つまりここからは側面からの攻撃の処理である。
[$00:1A7D](敵データ29 背後補正/側面補正)をロードして、$0Fと論理積を取ることで、下1桁、つまり側面補正の値を取り出し、[$00:0311]に書き込む。
クルセイダーRSなら、[$00:0311]に入るのは$08である。
$C1/E113から、レベルの値の処理である。
キャリーフラグをONにして、

[$00:0310](敵LV(現在値)) - [$00:0311](側面補正)

を計算する。
クルセイダーRSなら、キャリー分考慮で、

$107 - $08 = $FF

となる。
つまり現在レベルより、側面補正の方が大きいので、側面補正を考慮するとレベルが負の値になってしまう。
この場合は$C1/E11Aでキャリーフラグ分岐になり、[$00:0310]$00を書き込み、Aにロードする。
最終的に、[$7E:ABEA]にはAの値が入るから、

[$7E:ABEA] = [$00:0310](敵LV(現在値)) - [$00:0311](側面補正)
ただし減算結果が負の値の時は0とする

と、いうことになる。
[$7E:ABEA]が、向き補正が入ったレベルの値となる。

今回は、

  • クルセイダーRS(の一番下側のマス)はY軸でアキラより上にいる
  • クルセイダーRSはX軸でアキラより右にいる

という条件を満たしているので、側面の位置は以下のように判定されたことになる。

□□□□□□□
□□□□□□
□□□□□□
■■■□□□□
■■■□□□□
■■■□□□□
■■■□□□□

では、背面から攻撃した場合も確認しておこう。

□□□□□□□
□□□□□□
□□ア□□□
□□□□□□□
□□□□□□□
□□□□□□□
□□□□□□□

クルセイダーRSは右下向きのまま、アキラは左から攻撃する。
今回は、アキラの位置は(2,2)になる。
クルセイダーRSの座標は(3,1)のまま。

$C1/E127 LDY $0002,x[$00:1BE2]   ;Yに[$00:1BE2]をロード
$C1/E12A LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E12D BIT #$80                ;Aと$80で論理積(ステータスフラグ変更のみ)
$C1/E12F BEQ $0E    [$E13F]      ;ゼロフラグが立っているとき[$E13F]分岐
;ゼロフラグON 向きが$80(右上)か$C0(左上)以外
$C1/E13F LDA $13    [$00:0313]   ;Aに[$00:0313]をロード
$C1/E141 CMP $000B,x[$00:1BEB]   ;Aと[$00:1BEB]を減算比較(ステータスレジスタ変更のみ)
$C1/E144 BCC $21    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
$C1/E146 BRA $00    [$E148]      ;フラグにかかわりなく常に分岐[$E148]
$C1/E148 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4]をロード
$C1/E14B BIT #$40                ;Aと$40で論理積(ステータスフラグ変更のみ)
$C1/E14D BEQ $0E    [$E15D]      ;ゼロフラグが立っているとき[$E15D]分岐
;ゼロフラグON 向きが$40(左下)以外=右下向き確定
$C1/E15D LDA $12    [$00:0312]   ;Aに[$00:0312](アキラ マス目のX座標)をロード
$C1/E15F CMP $000A,x[$00:1BEA]   ;Aと[$00:1BEA](敵位置のマス目のX座標)を減算比較(ステータスレジスタ変更のみ)
$C1/E162 BCC $03    [$E167]      ;キャリーフラグが立っていないとき[$E167]分岐
;[$00:0312]-[$00:1BEA]=2-3で負の値、キャリーOFF
$C1/E167 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E16A BIT #$80                ;Aと$80で論理積(ステータスフラグ変更のみ)
$C1/E16C BEQ $09    [$E177]      ;ゼロフラグが立っているとき[$E177]分岐
;ゼロフラグON 向きが$80(右上)か$C0(左上)以外
$C1/E177 LDA $000B,x[$00:1BEB]   ;Aに[$00:1BEB](敵位置のマス目のY座標)をロード
$C1/E17A CLC                     ;キャリーフラグクリア
$C1/E17B ADC $0005,y[$00:1A45]   ;A + [$00:1A45](敵の縦幅)
$C1/E17E DEC A                   ;Aをデクリメント -1
$C1/E17F CMP $13    [$00:0313]   ;Aと[$00:0313](アキラ マス目のY座標=2)を減算比較(ステータスレジスタ変更のみ)
$C1/E181 BCC $20    [$E1A3]      ;キャリーフラグが立っていないとき[$E1A3]分岐
;$02-[$00:0313]=2-2で0、キャリーON
$C1/E183 BRA $00    [$E185]      ;フラグにかかわりなく常に分岐[$E185]
$C1/E185 LDA $0004,x[$00:1BE4]   ;Aに[$00:1BE4](敵の向き(右下$00/左下$40/右上$80/左上$C0))をロード
$C1/E188 BIT #$40                ;Aと$40で論理積(ステータスフラグ変更のみ)
$C1/E18A BEQ $09    [$E195]      ;ゼロフラグが立っているとき[$E195]分岐
;ゼロフラグON 向きが$40(左下)以外=右下向き確定
$C1/E195 LDA $000A,x[$00:1BEA]   ;Aに[$00:1BEA](敵位置のマス目のX座標)をロード
$C1/E198 CLC                     ;キャリーフラグクリア
$C1/E199 ADC $0004,y[$00:1A44]   ;A + [$00:1A44](敵の横幅)
$C1/E19C DEC A                   ;Aをデクリメント -1
$C1/E19D CMP $12    [$00:0312]   ;Aと[$00:0312](アキラ マス目のX座標=2)を減算比較(ステータスレジスタ変更のみ)
$C1/E19F BCC $02    [$E1A3]      ;キャリーフラグが立っていないとき[$E1A3]分岐
;$03-[$00:0312]=3-2で正の値、キャリーON
$C1/E1A1 BRA $03    [$E1A6]      ;フラグにかかわりなく常に分岐[$E1A6]
$C1/E1A6 LDA #$80                ;Aに$80をロード
$C1/E1A8 RTS                     ;サブルーチン戻り

$C1/E181までは側面の処理と同じだが、今回はアキラのY座標が2なので、$C1/E181でキャリーフラグが立ち$C1/E183に進む。
その先で[$00:1BE4](敵の向き)と$40で論理積をとりゼロフラグ判定だが、これは$C1/E14Dの処理と同じでゼロフラグが立ち、向きが右下向き確定で$C1/E195に進む。
$C1/E195からX座標の判定で、敵の横幅[$00:1A44]を考慮した判定になる。
敵のX座標 + [$00:1A44](敵の横幅) - 1」と、アキラのX座標との減算比較である。
敵の一番右のマスの座標とアキラのX座標で減算比較となり、$03 - [$00:0312] = 3 - 2でキャリーフラグがONだから、$C1/E1A1に進む。
A$80をロードしてサブルーチン終了。

$C1/E0F7 STA $7E900B,x[$7E:ABEB] ;Aを[$7E:ABEB]に書き込み
$C1/E0FB BEQ $21    [$E11E]      ;ゼロフラグが立っているとき[$E11E]分岐
$C1/E0FD BMI $09    [$E108]      ;ネガティブフラグが立っているとき[$E108]分岐
$C1/E108 LDA $003D,y[$00:1A7D]   ;Aに[$00:1A7D](敵データ29 背後補正/側面補正)をロード
$C1/E10B LSR A                   ;Aを論理右シフト (/2)
$C1/E10C LSR A                   ;Aを論理右シフト (/2)
$C1/E10D LSR A                   ;Aを論理右シフト (/2)
$C1/E10E LSR A                   ;Aを論理右シフト (/2)
$C1/E10F AND #$0F                ;Aと$0Fで論理積
$C1/E111 STA $11    [$00:0311]   ;Aを[$00:0311]に書き込み
$C1/E113 LDA $10    [$00:0310]   ;Aに[$00:0310]($07)(敵LV(現在値))をロード
$C1/E115 SEC                     ;キャリーフラグON
$C1/E116 SBC $11    [$00:0311]   ;A - [$00:0311]
$C1/E118 STA $10    [$00:0310]   ;Aを[$00:0310]に書き込み
$C1/E11A BCS $02    [$E11E]      ;キャリーフラグが立っているとき[$E11E]分岐
$C1/E11C STZ $10    [$00:0310]   ;[$00:0310]に$00を書き込み
$C1/E11E LDA $10    [$00:0310]   ;Aに[$00:0310]をロード
$C1/E120 STA $7E900A,x[$7E:ABEA] ;Aを[$7E:ABEA]に書き込み
$C1/E124 BRA $8D    [$E0B3]      ;フラグにかかわりなく常に分岐[$E0B3]
$C1/E0B3 JSR $E1A9  [$C1:E1A9]   ;[$C1:E1A9]へジャンプ

[$7E:ABEB]に書き込まれる値は$80になり、これが背面からの攻撃時に[$7E:ABEB]に入る値である。
$C1/E0FB$C1/E0FDの判定で、ゼロフラグOFF、ネガティブフラグONとなり、$C1/E108に進む。
[$00:1A7D](敵データ29)を論理右シフト4回、つまり$10で割り、更に$0Fと論理積を取るので、上1桁が取り出せる。
これが背後補正の値で、[$00:0311]に書き込まれる。
クルセイダーRSだと[$00:0311]$0Cが書き込まれる。
後の処理は側面補正時と同じで、

[$7E:ABEA] = [$00:0310](敵LV(現在値)) - [$00:0311](背後補正)
ただし減算結果が負の値の時は0とする

ということになる。

今回は、

  • クルセイダーRS(の一番下側のマス)はY軸でアキラと同じ、またはアキラより下にいる
  • クルセイダーRS(の一番右側のマス)はX軸でアキラと同じ、またはアキラより右にいる

という条件を満たしているので、背面の位置は以下のように判定されたことになる。

■■■■□□□
■■■□□□
■■■□□□
□□□□□□□
□□□□□□□
□□□□□□□
□□□□□□□

以上、クルセイダーRSが右下向きの場合に絞って3パターン説明したが、どちら向きであっても、敵の座標、向き、サイズ、及び味方の座標から、味方が敵を攻撃する時の敵の向き補正を判定していることがわかる。
全ての分岐を説明するとややこしくなるため省略するが、結局、サブルーチンは、

アドレス内容
$C1/E127$C1/E1A8味方が敵を攻撃する時、向き補正を判定して[$7E:ABnB]に書き込む値をAにロードする
$C1/E0F7$C1/E0B3味方が敵を攻撃する時、向き補正[$7E:ABnB]から、向き補正したレベルの値を[$7E:ABnA]に書き込む

と、いうことになる。

ここまでが味方が敵を攻撃する時だが、逆の場合、敵が味方を攻撃する時はどうなるかを次ページで見ていく。



このページをシェアする

上へ