基礎知識
戦闘関係
技の中には特殊なタイプの技が幾つかある。
| タイプ | 説明 | 技 |
|---|---|---|
| 外すとダメージ | 命中しなかった場合、使用者がダメージ | ズドゲラデイン Fシュタイナー トルネードプレス |
| 自爆999ダメージ | 技使用後に自身が999ダメージ | シッポはイヤーン 爆発 爆発(反撃) 気化爆発 デーモンズダンス |
| HP振り分け | 周囲回復、その分自身にダメージ。回復技判定 | ラブヒーリング |
| 自滅 | 使用時に自身のHPが0になる。回復技判定 | 死にまする! |
これらの中で、いくつかのタイプについては世界の合言葉は森部様に説明がある。
Fシュタイナー等の外すとダメージの技は、自分にその技で背面から攻撃したダメージ。
ラブヒーリングは、周囲の人のHPを回復した分、自分がダメージを受けるので、
例えばマザーテイルとパピーテイル沢山を巻き込んで、
πをつかってマザーテイルにラブヒーリングを使わせると結構なダメージが出る。
実際の処理について、サブルーチンを調べてみたので紹介していく。
まず、タイプ関係のメモリアドレスについて説明する。
技使用中、敵も味方も$7E:9010~$7E:9028に技データ00~34が入る(次技使用直前まで値が残る)。
$7E:901D)上4ビットは、技のタイプ関係の値の合計値が入る。
| 上4ビット | 内容 |
|---|---|
| $0 | 通常 |
| $2 | 範囲が周囲 |
| $4 | 反撃専用 |
| $8 | 回復 |
$7E:9025)技データ13の上4ビットが$8未満:
| 数値 | タイプ |
|---|---|
| $3 | 吸収 |
| $7 | 外すとダメージ |
| $8 | 自爆999ダメージ |
技データ13の上4ビットが$8以上:
| 数値 | タイプ |
|---|---|
| $3 | HP振り分け |
| $8 | 自滅 |
まずは、命中しなかった場合、使用者がダメージをくらう技について紹介する。
ズドゲラデイン・Fシュタイナー・トルネードプレスの3種類が該当する。
敵が回避した場合だけではなく、カラマスに攻撃した場合も、使用者がダメージをくらう。
ここでは例として、高原が「トルネードプレス」をカラマスに使用した場合のサブルーチンを追いかけてみる。
技使用後の処理は以下のとおり。
;敵の被ヒット数判定(ループ処理) $C1/E1A9 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/E1AB TXA ;Xレジスタの値をAレジスタに転送 $C1/E1AC ADC #$0010 ;A + $0010 $C1/E1AF TAX ;Aの値をXレジスタに転送 $C1/E1B0 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/E1B2 CPX #$1C00 ;Xと$1C00を減算比較(ステータスレジスタ変更のみ) $C1/E1B5 BEQ $11 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 $C1/E1B7 LDA $0001,x ;Aに[$0001,x](敵の戦闘状態)をロード $C1/E1BA BIT #$40 ;Aと$40(味方キャラが敵状態)で論理積(ステータスフラグ変更のみ) $C1/E1BC BNE $07 [$E1C5] ;ゼロフラグが立っていないとき[$E1C5]分岐 ;ゼロフラグOFF $C1/E1BE CMP #$80 ;Aと$80(敵総数+1の敵番号)を減算比較(ステータスレジスタ変更のみ) $C1/E1C0 BEQ $06 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 $C1/E1C2 LDA #$00 ;Aに$00をロード $C1/E1C4 RTS ;サブルーチン戻り ;ゼロフラグON $C1/E1C5 LDA #$7F ;Aに$7Fをロード $C1/E1C7 RTS ;サブルーチン戻り $C1/D83C BEQ $FB [$D839] ;ゼロフラグが立っているとき[$D839]分岐 $C1/D83E BMI $0A [$D84A] ;ネガティブフラグが立っているとき[$D84A]分岐 $C1/D840 LDA $7E9003,x ;Aに[$7E:ABx3](敵の被ヒット数)をロード $C1/D844 BEQ $02 [$D848] ;ゼロフラグが立っているとき[$D848]分岐 ;ゼロフラグOFF $C1/D846 INC $10 [$00:0310] ;[$00:0310]をインクリメント +1 ;ゼロフラグON $C1/D848 BRA $EF [$D839] ;フラグにかかわりなく常に分岐[$D839] ; $C1/D839 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ ; $C1/D84A LDA $10 [$00:0310] ;Aに[$00:0310]をロード $C1/D84C ORA $83 [$00:0383] ;Aと[$00:0383]で論理和 $C1/D84E AND #$FF ;Aと$FFで論理積 $C1/D850 RTS ;サブルーチン戻り $C1/C3FD BNE $35 [$C434] ;ゼロフラグが立っていないとき[$C434]分岐 $C1/C3FF JSR $D7BB [$C1:D7BB] ;[$C1:D7BB]へジャンプ
$C1/E1A9~で、技を出した後の敵の戦闘状態をチェックし、敵が「味方キャラが敵状態」や戦闘不能でない場合、$C1/D840で[$7E:ABx3](敵番号xの被ヒット数)を調べ、1ヒット以上の時は[$00:0310]をインクリメント(+1)、そうでなければ何もしない、を敵全員に行う。
つまり、敵に攻撃が命中しているかどうかの判定である。
このループ処理の結果、敵に攻撃が1ヒットもしなかった、つまり攻撃が命中しなかった場合、$C1/D84Aで[$00:0310]は$00が入ったまま。
$C1/D850でAに$00が入った状態でサブルーチンが戻り、$C1/C3FDでゼロフラグが立っているので$C1/C3FFに進んで、更に$C1/D7BBにジャンプする。
つまり、この先は敵に攻撃がヒットしていない場合の処理である。
$C1/D7BB LDA #$00 ;Aに$00をロード $C1/D7BD ORA $1C3B [$00:1C3B] ;Aと[$00:1C3B](味方の被ヒット数)で論理和 $C1/D7C0 ORA $1C7B [$00:1C7B] ;Aと[$00:1C7B](味方の被ヒット数)で論理和 $C1/D7C3 ORA $1CBB [$00:1CBB] ;Aと[$00:1CBB](味方の被ヒット数)で論理和 $C1/D7C6 ORA $1CFB [$00:1CFB] ;Aと[$00:1CFB](味方の被ヒット数)で論理和 $C1/D7C9 RTS ;サブルーチン戻り $C1/C402 BNE $30 [$C434] ;ゼロフラグが立っていないとき[$C434]分岐 $C1/C404 JSR $C3DD [$C1:C3DD] ;[$C1:C3DD]へジャンプ
更に$C1/D7BB~で、味方へのヒット数(回復技も当たれば1ヒット以上とする)も調べる。
$00と味方へのヒット数の論理和を取り続けるのだが、敵への攻撃技なら味方へは1ヒットもしないから、$C1/D7C9でAに入っているのは$00である。
よって、$C1/C402でゼロフラグ分岐で$C1/C404に進み、$C1/C3DDにジャンプする。
この時点で「敵にも味方にも、技が1ヒットもしていない」状態である。
$C1/C3DD LDA $7E9025[$7E:9025] ;Aに[$7E:9025](技データ21)をロード $C1/C3E1 AND #$F0 ;Aと$F0で論理積 $C1/C3E3 CMP #$70 ;Aと$70を減算比較(ステータスレジスタ変更のみ) $C1/C3E5 BNE $03 [$C3EA] ;ゼロフラグが立っていないとき[$C3EA]分岐 $C1/C3E7 JSR $D851 [$C1:D851] ;[$C1:D851]へジャンプ
ここで、[$7E:9025](技データ21)をロードする。
$C1/C3E1で$F0と論理積を取るから上4ビットを取り出している。
更に、$C1/C3E3で$70と減算比較しているが、上4ビットの値が7なのはタイプが「外すとダメージ」である。
| 数値 | タイプ |
|---|---|
| $3 | 吸収 |
| $7 | 外すとダメージ |
| $8 | 自爆999ダメージ |
よって、$C1/C3E5でゼロフラグが立つのは、ズドゲラデイン・Fシュタイナー・トルネードプレスのいずれかの技をミスした時のみになる。
「トルネードプレス」の[$7E:9025](技データ21)の値は$70なので、攻撃をミスした場合$C1/C3E7に進む。
この先が、「外すとダメージ」で技を外した時の処理になる。
少し処理を飛ばして、重要な部分が以下から。
$C1/C40F REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/C411 LDA #$03E7 ;Aに$03E7をロード $C1/C414 STA $003C,x ;Aを[$003C,x+1][$003C,x](被ダメージの単発値2バイト)に書き込み $C1/C417 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/C419 LDA #$01 ;Aに$01をロード $C1/C41B STA $003B,x ;Aを[$003B,x](ヒット数)に書き込み $C1/C41E STA $003A,x ;Aを[$003A,x](被ダメージ/回復量のヒット数)に書き込み $C1/C421 LDA #$00 ;Aに$00をロード $C1/C423 STA $7ECE33,x ;Aを[$7ECE33,x]に書き込み $C1/C427 STA $7ECE34,x ;Aを[$7ECE34,x]に書き込み $C1/C42B JSR $C39D [$C1:C39D] ;[$C1:C39D]へジャンプ
高原が味方キャラ1の場合、$00:1C00~$00:1C3Fに各種データが入ることになるが、上処理で、以下のようにアドレスに値が入ることになる。
| アドレス | 内容 | 値 |
|---|---|---|
$00:1C3D~$00:1C3C | 被ダメージの単発値2バイト | $03E7 (999) |
$00:1C3B | ヒット数 | $01 |
$00:1C3A | 被ダメージ/回復量のヒット数 | $01 |
$7E:EA33 | - | $00 |
$7E:EA34 | - | $00 |
被ダメージ量に999が書き込まれるので、このままだと高原に999ダメージが入ってしまう。
以降の処理で分岐していく。
$C1/C39D LDX $78 [$00:0378] ;Xに[$00:0378]をロード $C1/C39F STX $60 [$00:0360] ;Xを[$00:0360]に書き込み $C1/C3A1 LDY $5A [$00:035A] ;Yに[$00:035A]をロード $C1/C3A3 PHY ;Yをスタックへプッシュ $C1/C3A4 STX $5A [$00:035A] ;Xを[$00:035A]に書き込み $C1/C3A6 STX $10 [$00:0310] ;Xを[$00:0310]に書き込み $C1/C3A8 LDA $7E9025[$7E:9025] ;Aに[$7E:9025](技データ21)をロード $C1/C3AC AND #$F0 ;Aと$F0で論理積 $C1/C3AE CMP #$80 ;Aと$80を減算比較(ステータスレジスタ変更のみ) $C1/C3B0 BEQ $03 [$C3B5] ;ゼロフラグが立っているとき[$C3B5]分岐 $C1/C3B2 JSR $D900 [$C1:D900] ;[$C1:D900]へジャンプ
ここで[$7E:9025](技データ21)の上4ビットを取り出し、$80かどうか判定している。
| 数値 | タイプ |
|---|---|
| $3 | 吸収 |
| $7 | 外すとダメージ |
| $8 | 自爆999ダメージ |
つまり、先の処理は自爆999ダメージ用の準備で、[$7E:9025](技データ21)から技のタイプが「自爆999ダメージ」が判定されたら、$C1/C3B0でゼロフラグが立つから$C1/C3B5にジャンプする。
「トルネードプレス」の場合はゼロフラグが立たず、$C1/C3B2に進み$C1/D900にジャンプする。
$C1/D900 LDA $7E900B[$7E:900B] ;Aに[$7E:900B](技データ10)をロード $C1/D904 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/D906 AND #$0003 ;Aと$0003で論理積 $C1/D909 ADC $10 [$00:0310] ;A + [$00:0311][$00:0310] $C1/D90B TAX ;Aの値をXレジスタに転送 $C1/D90C SEP #$21 ;キャリーフラグON Aレジスタは8bit幅 $C1/D90E LDA $81 [$00:0381] ;Aに[$00:0381](技データ13($7E:901D))をロード $C1/D910 BPL $1A [$D92C] ;ネガティブフラグが立っていないとき[$D92C]分岐 ;ネガティブフラグOFF $C1/D92C LDA $0034,x ;Aに[$0034,x](速(現在値))をロード $C1/D92F STA $26 [$00:0326] ;Aを[$00:0326]に書き込み $C1/D931 LDX $10 [$00:0310] ;Xに[$00:0310]をロード $C1/D933 LDA $002E,x ;Aに[$002E,x](LV(現在値) - 背面補正)をロード $C1/D936 STA $25 [$00:0325] ;Aを[$00:0325]に書き込み $C1/D938 LDA $7ECE35,x ;Aに[$7ECE35,x]をロード $C1/D93C STA $17 [$00:0317] ;Aを[$00:0317]に書き込み $C1/D93E JSR $77CE [$C1:77CE] ;[$C1:77CE]へジャンプ
ここからは、「トルネードプレス」自爆時のダメージ量計算である。
技使用中、$7E:900Bには技データ10が入っている。
$C1/D906で$0003と論理積を取っているから、下2ビットを取り出している。
下2ビットは敵依存ステータスと防御力依存係数を兼用した値で、対応は以下の通り。
| 16進数 | 2進数 | 敵依存 ステータス | 防御力 依存係数 |
|---|---|---|---|
| $0 | %00 | 力 | 1/4 |
| $1 | %01 | 速 | 1/2 |
| $2 | %10 | 体 | 1 |
| $3 | %11 | 知 | 0 |
つまり$C1/D906で、敵依存ステータスの$00~$03のいずれかがAに入る。
「トルネードプレス」の[$7E:900B](技データ10) = $29で、$0003と論理積を取ると$0001。
「トルネードプレス」は速依存(かつ防御力依存係数1/2)である。
$C1/D909で[$00:0311][$00:0310]を加算するが、ここには戦闘中の味方キャラ開始アドレスが入っている。
1人目なら$1C00、2人目以降は+$40の値になる。
高原が1人目なら、$1C00 + $0001 = $1C01となる。
Xに入る値は依存ステータスにより$1C00~$1C03のいずれかになることがわかる。
この値は$C1/D90BでXレジスタに転送される。
$C1/D90Eでロードする[$00:0381]だが、上処理より前で以下の処理がある。
$C1/D1B2 LDA $7E901D[$7E:901D] ;Aに[$7E:901D](技データ13)をロード $C1/D1B6 STA $81 [$00:0381] ;Aを[$00:0381]に書き込み
[$00:0381]には技データ13が入っていて、$C1/D910でネガティブフラグを判定している。
技データ13の上1ビットが1なら回復技、0ならそれ以外であり、ネガティブフラグがONになるのなら回復技ということになる。
「トルネードプレス」の技データ13は$06、回復技ではないため、ネガティブフラグがOFFの飛び先$C1/D92Cへ進む。
$C1/D92Cで$0034,xをロードするが、Xにはさきほど$1C01が書き込まれたから、ロードするアドレスは[$00:1C35]。
これは高原の速(現在値)である。
ここまでの処理から、Xには$1C00~$1C03のいずれかが入っているから、味方1人目なら、
| アドレス | 内容 |
|---|---|
$00:1C34 | 力(現在値) |
$00:1C35 | 速(現在値) |
$00:1C36 | 体(現在値) |
$00:1C37 | 知(現在値) |
以上のように、敵依存ステータスに合わせた値がロードされる。
敵依存ステータスは、技使用時、技を当てる相手が何のステータスに依存しているかを示しているが、ここで読み込むのは高原自身のステータスである。
「トルネードプレス」自爆時、自身を攻撃したという扱いでダメージ量を計算するのだろうということがここからだいたい推測できる。
以降は、味方1人目なら、下のようにコピー先アドレスに値を入れる。nは依存ステータス値(0~3)。
| アドレス | 内容 | コピー先 |
|---|---|---|
[$00:1C3n] | 敵依存ステータス | [$00:0326] |
[$00:1C2E] | LV(現在値) - 背面補正 | [$00:0325] |
[$7E:EA35] | - | [$00:0317] |
[$00:1C2E]に入る、「LV(現在値) - 背面補正」がポイントである。
最終的に$C1/D93Eで、$C1/77CEにジャンプする。
$C1:77CE~$C1:783Aは単発ダメージ計算のサブルーチンである。
ダメージ計算式の解説で紹介しているので参照していただきたい。
処理の最初を見てみると、
$C1/77CE LDA #$08 ;Aに$08をロード $C1/77D0 CLC ;キャリーフラグクリア $C1/77D1 ADC $7E900C[$7E:900C] ;A + [$7E:900C](技LV+自LV) $C1/77D5 BCC $02 [$77D9] ;キャリーフラグが立っていないとき[$77D9]分岐 $C1/77D9 SEC ;キャリーフラグON $C1/77DA SBC $25 [$00:0325] ;A - [$00:0325](LV(現在値) - 背面補正) $C1/77DC BCC $08 [$77E6] ;キャリーフラグが立っていないとき[$77E6]分岐
$C1/77DAの「A - [$00:0325]」だが、味方が敵を攻撃する場合だったら、ここまでの処理で[$00:0325]に敵LVが入る。
だが、今回は[$00:0325]に高原自身の「LV(現在値) - 背面補正」が入っている。
もうひとつ、
$C1/7813 SEC ;キャリーフラグON $C1/7814 SBC $26 [$00:0326] ;A - [$00:0326] $C1/7816 LSR A ;Aを論理右シフト (/2)
$C1/7814のA - [$00:0326]だが、[$00:0326]にはさきほど、「トルネードプレス」の敵依存ステータスとして高原のステータスを書き込んだ。
敵攻撃時は敵の「敵依存ステータス」が入るが今回は自身の「敵依存ステータス」が入ることになる。
味方が敵を攻撃する場合との違いは以上の2点。
味方が敵を攻撃する時の単発ダメージ量計算式は、
((min(max((8+技LV+自LV-敵LV),1),24)
であるが、この中の「敵LV」の部分が「LV(現在値) - 背面補正」に、「敵能力値」が「敵能力値を自身のステータスからロードした値」に変わる。
結局、自分自身を背面方向から「トルネードプレス」で攻撃した時のダメージ量が計算される、ということになる。
この後は乱数ブレの計算など、通常のダメージ量計算を行って最終的なダメージ量が決まる。
先に一度[$00:1C3D][$00:1C3C](被ダメージの単発値2バイト)に自爆ダメージ用の$03E7(999)が書き込まれたが、正しい値が上書きされることになる。
今回はわざとカラのマスに攻撃したが、敵に攻撃した結果命中しなかった場合も、敵へのヒット数判定で同様に処理されるため、全体のサブルーチンは変わらない。
「外すとダメージ」タイプは命中しない時にのみ自身にダメージという条件が必要だが、「自爆999ダメージ」は条件などなく、「自爆999ダメージ」のフラグがついている技を使用した時に必ず発動する。
よって、「外すとダメージ」タイプのように敵味方に攻撃が命中したかどうかを判定する必要はない。
味方側で「自爆999ダメージ」の技は、「金の死装」使用時の技「デーモンズダンス」しかない。
よってここでは「デーモンズダンス」発動時のサブルーチンを例に説明する。
「自爆999ダメージ」とはいえ攻撃技なので、範囲内に敵がいればダメージを与えるし、「デーモンズダンス」の場合は範囲内の毒フィールドも作るのだが、以下では主に自身へのダメージ部分について説明する。
先の「外すとダメージ」タイプの処理の途中、$C1/C40Fから、「自爆999ダメージ」関係の処理が始まっていたので、そこから紹介していく。
今回も仲間1人目が「デーモンズダンス」を使用した前提でアドレスを記す。
$C1/C40F REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/C411 LDA #$03E7 ;Aに$03E7をロード $C1/C414 STA $003C,x ;Aを[$003C,x+1][$003C,x](被ダメージの単発値2バイト)に書き込み $C1/C417 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/C419 LDA #$01 ;Aに$01をロード $C1/C41B STA $003B,x ;Aを[$003B,x](ヒット数)に書き込み $C1/C41E STA $003A,x ;Aを[$003A,x](被ダメージ/回復量のヒット数)に書き込み $C1/C421 LDA #$00 ;Aに$00をロード $C1/C423 STA $7ECE33,x ;Aを[$7ECE33,x]に書き込み $C1/C427 STA $7ECE34,x ;Aを[$7ECE34,x]に書き込み $C1/C42B JSR $C39D [$C1:C39D] ;[$C1:C39D]へジャンプ
先に説明した通り、この処理で、使用者(味方キャラ)の被ダメージの単発値に$03E7(999)、ヒット数が$01と書き込まれる。
| アドレス | 内容 | 値 |
|---|---|---|
$00:1C3D~$00:1C3C | 被ダメージの単発値2バイト | $03E7 (999) |
$00:1C3B | ヒット数 | $01 |
$00:1C3A | 被ダメージ/回復量のヒット数 | $01 |
$7E:EA33 | - | $00 |
$7E:EA34 | - | $00 |
$C1/C39D LDX $78 [$00:0378] ;Xに[$00:0378]をロード $C1/C39F STX $60 [$00:0360] ;Xを[$00:0360]に書き込み $C1/C3A1 LDY $5A [$00:035A] ;Yに[$00:035A]をロード $C1/C3A3 PHY ;Yをスタックへプッシュ $C1/C3A4 STX $5A [$00:035A] ;Xを[$00:035A]に書き込み $C1/C3A6 STX $10 [$00:0310] ;Xを[$00:0310]に書き込み $C1/C3A8 LDA $7E9025[$7E:9025] ;Aに[$7E:9025](技データ21)をロード $C1/C3AC AND #$F0 ;Aと$F0で論理積 $C1/C3AE CMP #$80 ;Aと$80を減算比較(ステータスレジスタ変更のみ) $C1/C3B0 BEQ $03 [$C3B5] ;ゼロフラグが立っているとき[$C3B5]分岐 ;ゼロフラグON(自爆999ダメージ) $C1/C3B5 LDX $5A [$00:035A] ;Xに[$00:035A]をロード $C1/C3B7 JSR $CF13 [$C1:CF13] ;[$C1:CF13]へジャンプ
$C1/C3A8~で[$7E:9025](技データ21)の上4ビットが$8かどうか、つまりタイプが「自爆999ダメージ」かを判定する。
「自爆999ダメージ」の場合は$C1/C3B0でゼロフラグが立つから、$C1/C3B5に処理が進む。
この後は、単発ダメージ量$03E7(999)、ヒット数は$01としてダメージ量計算が進む。
味方キャラの場合、最大HPは999なので必ず戦闘不能になるのだが、ダメージ計算や残りHPの計算などは通常通りに行われる。
最終的には、ダメージ量$03E7が[$7E:EA2F][$7E:EA2E]に入って、味方キャラの現在HP[$00:0E09][$00:0E08]と差を取っていく。
$C1/CBC2 LDY $2134 [$00:2134] ;Yに[$00:2134]をロード $C1/CBC5 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/CBC7 LDY $0002,x ;Yに[$0002,x+1][$0002,xをロード $C1/CBCA LDA $0008,y ;Aに[$0008,y+1][$0008,y](現在HP)をロード $C1/CBCD SEC ;キャリーフラグON $C1/CBCE SBC $7ECE2E,x ;A - [$7ECE2E,x+1][$7ECE2E,x]($03E7) $C1/CBD2 BCS $03 [$CBD7] ;キャリーフラグが立っているとき[$CBD7]分岐 $C1/CBD4 LDA #$0000 ;Aに$0000をロード $C1/CBD7 JSR $CE60 [$C1:CE60] ;[$C1:CE60]へジャンプ ;(中略) $C1/CBDA STA $0008,y ;A($0000)を[$0008,y+1][$0008,y](現在HP)に書き込み $C1/CBDD TAY ;Aの値をYレジスタに転送 $C1/CBDE SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/CBE0 LDA #$FF ;Aに$FFをロード $C1/CBE2 RTS ;サブルーチン戻り
$C1/CBCEの減算が、[$00:0E09][$00:0E08](現在HP) - [$7E:EA2F][$7E:EA2E]($03E7)であり、味方キャラのHPは$03E7(999)以下だから、計算結果は0または負の数である。
減算結果でキャリーフラグが立つことになり、$C1/CBDAで、$0000を[$00:0E09][$00:0E08](現在HP)に書き込む。
つまり、残りHPが0になり戦闘不能になる。
タイプが「HP振り分け」なのは「ラブヒーリング」のみ。
SF編のマザーテイルの使用技であり、最終編のみの回復アイテム「マジカルウッド」使用時にも「ラブヒーリング」が使える。
タイプが「HP振り分け」は回復技の扱いなので、回復技のサブルーチンも通り回復量の計算をするが、その後の処理が変わってくる。
単発回復量計算は上リンク先で紹介しているが、その後、単発回復量×ヒット数で実際の回復量を計算するサブルーチンがある。
HP回復自体は範囲回復技の処理として通常通り行われるのだが、その後、使用者がダメージをくらう処理はどのように計算されているのかを紹介する。
先に答えを書くと、
「ラブヒーリング」使用者のダメージ量 = trunc(範囲内のキャラの「回復後のHP-回復前のHP」を合計した値/2)+1
となる。
回復技による回復量計算値ではなく、実際にキャラが回復したHPの量、「回復後のHP-回復前のHP」で計算するのがポイント。
例えばHPが満タンのキャラを回復し、技の回復量として250と緑色の文字で表示されたとしても、満タンのキャラのHPの回復量は0である。
最大HPが200のキャラの現在HPが150で、技の回復量として250と緑色の文字で表示されたとしても、実際に回復するのは200-150=50である。
というように実際に回復した量だけを合計して計算する。
もし、味方が4人いて、4キャラともHPが満タンの時に「ラブヒーリング」を使うと、
使用者のダメージ量 = trunc(範囲内のキャラの「回復後のHP-回復前のHP」を合計した値/2)+1
= trunc((0+0+0+0)/2)+1
= 1
となり、最低でも1はダメージをくらうことになる。
味方が4人いて、全員が50ずつHPが減っている状態の時に「ラブヒーリング」を使い、全キャラHPが全回復した場合、
使用者のダメージ量 = trunc(範囲内のキャラの「回復後のHP-回復前のHP」を合計した値/2)+1
= trunc((50+50+50+50)/2)+1
= 101
回復後に101ダメージを食らう、という仕組みである。
つまり、「範囲内のキャラのHP回復量を合計した値」を登録するメモリアドレスが必要なのだが、それが[$7E:9EF1][$7E:9EF0]の2バイトになる。
技使用時に、$C1/D29D~$C1/D2BBで、[$7E:9EF0]~[$7E:9EF6]にすべて$00を入れて初期化してから処理を行っている。
以下では、回復処理後についてざっと紹介する。
この直前で、回復技の単発回復量×ヒット数を計算し、乗算の解が[$00:2135][$00:2134]に入った状態である。
[$7E:9EF1][$7E:9EF0]は初期化された状態で、2バイトだから$0000が入っていることになる。
$C1/CB87 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/CB89 LDY $0002,x ;Yに[$0002,x+1][$0002,x]をロード $C1/CB8C LDA $0008,y ;Aに[$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP)をロード $C1/CB8F ADC $2134 [$00:2134] ;A + [$00:2135][$00:2134](回復技の単発回復量×ヒット数) $C1/CB92 CMP $000A,y ;Aと[$000A,y+1][$000A,y](シナリオ別キャラデータ 最大HP)を減算比較(ステータスレジスタ変更のみ) $C1/CB95 BCC $03 [$CB9A] ;キャリーフラグが立っていないとき[$CB9A]分岐 ;キャリーフラグON(回復後、最大HP<現在HP) $C1/CB97 LDA $000A,y ;Aに[$000A,y+1][$000A,y](シナリオ別キャラデータ 最大HP)をロード ;キャリーフラグOFF $C1/CB9A JSR $CE60 [$C1:CE60] ;[$C1:CE60]へジャンプ $C1/CE60 STA $20 [$00:0320] ;A(回復後HP)を[$00:0321][$00:0320]に書き込み $C1/CE62 SEC ;キャリーフラグON $C1/CE63 SBC $0008,y ;A - [$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP = 回復前HP) $C1/CE66 BCS $11 [$CE79] ;キャリーフラグが立っているとき[$CE79]分岐 ;キャリーフラグOFF $C1/CE68 LDA $0008,y ;Aに[$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP = 回復前HP)をロード $C1/CE6B SEC ;キャリーフラグON $C1/CE6C SBC $20 [$00:0320] ;A - [$00:0321][$00:0320](回復後HP) $C1/CE6E BRA $09 [$CE79] ;フラグにかかわりなく常に分岐[$CE79] ;キャリーフラグON $C1/CE79 CLC ;キャリーフラグクリア $C1/CE7A ADC $7E9EF0[$7E:9EF0] ;A + [$7E:9EF1][$7E:9EF0] $C1/CE7E BPL $03 [$CE83] ;ネガティブフラグが立っていないとき[$CE83]分岐 ;ネガティブフラグON $C1/CE80 LDA #$FFFF ;Aに$FFFFをロード ;ネガティブフラグOFF $C1/CE83 STA $7E9EF0[$7E:9EF0] ;Aを[$7E:9EF1][$7E:9EF0]に書き込み $C1/CE87 LDA $20 [$00:0320] ;Aに[$00:0321][$00:0320]をロード $C1/CE89 RTS ;サブルーチン戻り
処理を整理すると、$C1/CB87~$C1/CB9Aは、
「キャラの現在HP」+「回復技の単発回復量×ヒット数」
を計算して、回復後のHPの値を決めるサブルーチンである。
「キャラの現在HP」+「回復技の単発回復量×ヒット数」が「キャラの最大HP」を越えてしまう場合は、$C1/CB97で、「回復後のHPの値」=「キャラの最大HP」に変更している。
$C1/CE60~の処理で、「回復後のHP-回復前のHP」を計算し、[$7E:9EF1][$7E:9EF0]に加算している。
$C1/CE79~を見ると、[$7E:9EF1][$7E:9EF0]は初期値が0で、「回復後のHP-回復前のHP」を次々加算する処理であることがわかる。
また、[$7E:9EF1][$7E:9EF0]が$FFFFを越えたら$FFFFに上書き、という分岐も行っている。
上の$C1/CB87~$C1/CB9A、$C1/CE60~$C1/CE89を、回復技範囲内にいたキャラ分すべて行うと、[$7E:9EF1][$7E:9EF0]には、範囲内のキャラの「回復後のHP-回復前のHP」の合計値が入る、ということになる。
この後だが、[$7E:9EF1][$7E:9EF0]を「被ダメージの単発値」として扱って、総ダメージ量 = 被ダメージの単発値×ヒット数の計算を行っている。
防御力依存係数も考慮して総ダメージ量の計算も行うのだが、「ラブヒーリング」は防御力依存0なので結局ダメージ量算出には関係しない。
ヒット数も1なので、結局、総ダメージ量 = 被ダメージの単発値になる。
長くなるので、重要な箇所を抜粋する。
以下では被ダメージの単発値×ヒット数の乗算の解が[$00:2135][$00:2134]に入っている。
要するに、[$7E:9EF1][$7E:9EF0]がそのまま[$00:2135][$00:2134]に入った状態と考えて良い。
また、防御依存なら[$00:0321][$00:0320]に防御の値が入るのだが、防御依存ではないため[$00:0321][$00:0320] = $0000である。
$C1/CDE7 STZ $22 [$00:0322] ;[$00:0322]に$00を書き込み $C1/CDE9 STZ $23 [$00:0323] ;[$00:0323]に$00を書き込み $C1/CDEB LDA $77 [$00:0377] ;Aに[$00:0377]をロード $C1/CDED AND #$0F ;Aと$0Fで論理積 $C1/CDEF CMP #$08 ;Aと$08を減算比較(ステータスレジスタ変更のみ) $C1/CDF1 BNE $17 [$CE0A] ;ゼロフラグが立っていないとき[$CE0A]分岐 $C1/CE0A RTS ;サブルーチン戻り ; $C1/CD9F REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/CDA1 LDA $2134 [$00:2134] ;Aに[$00:2135][$00:2134](総ダメージ量)をロード $C1/CDA4 SEC ;キャリーフラグON $C1/CDA5 SBC $20 [$00:0320] ;A(総ダメージ量) - [$00:0321][$00:0320]($0000) $C1/CDA7 BCS $03 [$CDAC] ;キャリーフラグが立っているとき[$CDAC]分岐 $C1/CDAC STA $20 [$00:0320] ;A(総ダメージ量)を[$00:0321][$00:0320]に書き込み $C1/CDAE LDA $7ECE35,x ;Aに[$7ECE35,x+1][$7ECE35,x]をロード $C1/CDB2 AND #$00FF ;Aと$00FFで論理積 $C1/CDB5 BEQ $04 [$CDBB] ;ゼロフラグが立っているとき[$CDBB]分岐 $C1/CDB7 LSR $20 [$00:0320] ;[$00:0321][$00:0320](総ダメージ量)を論理右シフト (/2) $C1/CDB9 INC $20 [$00:0320] ;[$00:0321][$00:0320](総ダメージ量)をインクリメント +1 $C1/CDBB LDA $20 [$00:0320] ;Aに[$00:0321][$00:0320](総ダメージ量)をロード $C1/CDBD CLC ;キャリーフラグクリア $C1/CDBE ADC $22 [$00:0322] ;A(総ダメージ量) + [$00:0323][$00:0322]($0000) $C1/CDC0 CMP #$03E7 ;Aと$03E7を減算比較(ステータスレジスタ変更のみ) $C1/CDC3 BCC $03 [$CDC8] ;キャリーフラグが立っていないとき[$CDC8]分岐 ;キャリーフラグON $C1/CDC5 LDA #$03E7 ;Aに$03E7をロード ;キャリーフラグOFF $C1/CDC8 STA $7ECE2E,x ;Aを[$7ECE2E,x+1][$7ECE2E,x]に書き込み
最終的に$C1/CDACで総ダメージ量が[$00:0321][$00:0320]に入る。
$C1/CDB7~が重要で、[$00:0321][$00:0320]を論理右シフト(/2)してインクリメント+1し、この計算値と$03E7(999)を比較して999以上なら999として、$C1/CDC8で[$7ECE2E,x+1][$7ECE2E,x]に書き込んでいる。
[$7ECE2E,x+1][$7ECE2E,x]に入った値は、
trunc(「回復後のHP-回復前のHP」合計値)/2 + 1
であり、最終的にこの値が使用者へのダメージ量になる。
;(中略) $C1/CBC7 LDY $0002,x ;Yに[$0002,x+1][$0002,x]をロード $C1/CBCA LDA $0008,y ;Aに[$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP)をロード $C1/CBCD SEC ;キャリーフラグON $C1/CBCE SBC $7ECE2E,x ;A - [$7ECE2E,x+1][$7ECE2E,x] $C1/CBD2 BCS $03 [$CBD7] ;キャリーフラグが立っているとき[$CBD7]分岐 ;キャリーフラグOFF $C1/CBD4 LDA #$0000 ;Aに$0000をロード ;キャリーフラグON $C1/CBD7 JSR $CE60 [$C1:CE60] ;[$C1:CE60]へジャンプ ;(中略) $C1/CBDA STA $0008,y ;Aを[$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP)に書き込み
最後に、シナリオ別キャラデータの現在HPから[$7ECE2E,x+1][$7ECE2E,x]を減算し、キャリーフラグが立つ、つまり減算して0以下ならAに$0000を書き込んで、シナリオ別キャラデータの現在HPを上書きし、処理終了である。