基礎知識
戦闘関係
状態異常の中で、毒状態だと一定のタイミングで毒ダメージをくらうことになる。
どのタイミングで毒ダメージが発動し、毒ダメージ量が計算されるのかを紹介する。
タイミングだが、行動ポイント判定で味方側にターンが回る時、つまり行動ポイントが256以上から0以上256未満に変動した直後に、敵味方すべての状態異常を判定して、毒状態のキャラは毒ダメージが入る。
まず、味方キャラの判定とダメージ量計算のサブルーチンを紹介。
味方キャラは以下サブルーチンで全キャラ判定を行う。
$C1/9F5A REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/9F5C TXA ;Xレジスタの値をAレジスタに転送 $C1/9F5D ADC #$0040 ;A + $0040 $C1/9F60 TAX ;Aの値をXレジスタに転送 $C1/9F61 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/9F63 LDA $0000,x[$00:1CC0] ;Aに[$00:1C00+40x]をロード $C1/9F66 INC A ;Aをインクリメント +1 $C1/9F67 BEQ $07 [$9F70] ;ゼロフラグが立っているとき[$9F70]分岐 $C1/9F69 LDA $0001,x[$00:1CC1] ;Aに[$00:1C01+40x](戦闘状態)をロード $C1/9F6C BIT #$40 ;Aと$40で論理積(ステータスフラグ変更のみ) $C1/9F6E BNE $03 [$9F73] ;ゼロフラグが立っていないとき[$9F73]分岐 ;ゼロフラグOFF $00(戦闘離脱)、$20(味方キャラ敵対)以外 $C1/9F73 ORA #$FF ;Aと$FFで論理和 $C1/9F75 RTS ;サブルーチン戻り $C1/1DD0 BEQ $F6 [$1DC8] ;ゼロフラグが立っているとき[$1DC8]分岐 $C1/1DD2 LDA $0039,x[$00:1CF9] ;Aに[$00:1C39+40x](味方n状態異常)をロード $C1/1DD5 CMP #$FF ;Aと$FFを減算比較(ステータスレジスタ変更のみ) $C1/1DD7 BEQ $EF [$1DC8] ;ゼロフラグが立っているとき[$1DC8]分岐 ;ゼロフラグON 戦闘不能状態 $C1/1DD9 BIT #$08 ;Aと$08で論理積(ステータスフラグ変更のみ) $C1/1DDB BEQ $EB [$1DC8] ;ゼロフラグが立っているとき[$1DC8]分岐 ;ゼロフラグOFF 毒状態 $C1/1DDD JSR $1DE3 [$C1:1DE3] ;[$C1:1DE3]へジャンプ ;毒状態計算 $C1/1DE3 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1DE5 LDY $0002,x[$00:1CC2] ;Yに[$0002,x+1][$0002,x]をロード $C1/1DE8 LDA $0008,y[$00:0E08] ;Aに[$0008,y+1][$0008,y](キャラデータ現在HP 2バイト)をロード $C1/1DEB LSR A ;Aを論理右シフト (/2) $C1/1DEC LSR A ;Aを論理右シフト (/2) $C1/1DED LSR A ;Aを論理右シフト (/2) $C1/1DEE LSR A ;Aを論理右シフト (/2) $C1/1DEF BNE $03 [$1DF4] ;ゼロフラグが立っていないとき[$1DF4]分岐 ;ゼロフラグON 計算結果が0 $C1/1DF1 LDA #$0001 ;Aに$0001をロード ;ゼロフラグOFF 計算結果が0以外 $C1/1DF4 STA $10 [$00:0310] ;Aを[$00:0311][$00:0310]に書き込み $C1/1DF6 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1DF8 LDA #$01 ;Aに$01をロード $C1/1DFA STA $003A,x[$00:1CFA] ;Aを[$003A,x](被ダメージ/回復量のヒット数)に書き込み $C1/1DFD STA $003B,x[$00:1CFB] ;Aを[$003B,x](被ダメージ/回復量のヒット数)に書き込み $C1/1E00 LDA #$00 ;Aに$00をロード $C1/1E02 STA $7ECE33,x[$7E:EAF3] ;Aを[$7E:EAF3]に書き込み $C1/1E06 STA $7ECE35,x[$7E:EAF5] ;Aを[$7E:EAF5]に書き込み $C1/1E0A REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/1E0C LDA $10 [$00:0310] ;Aに[$00:0311][$00:0310]をロード $C1/1E0E STA $003C,x[$00:1CFC] ;Aを[$003C,x+1][$003C,x](被ダメージの単発値)に書き込み $C1/1E11 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1E13 LDA #$01 ;Aに$01をロード $C1/1E15 STA $10 [$00:0310] ;Aを[$00:0310]に書き込み $C1/1E17 STX $60 [$00:0360] ;Xを[$00:0360]に書き込み $C1/1E19 JSR $CBA6 [$C1:CBA6] ;[$C1:CBA6]へジャンプ
$C1/9F5A~$C1/9F75で、味方キャラアドレスから戦闘状態を判定している。
[$00:1C01+40x](xは0~3)には戦闘状態が入っているが、$40と論理積をとってゼロフラグが立つのは、$00(戦闘離脱)、$20(味方キャラ敵対)のみであり、この場合は状態異常判定をスキップする。
$C1/1DD2からが状態異常判定である。
$C1/1DD5~$C1/1DD7の$FFの減算・ゼロフラグ判定だが、状態異常は8ビットで各ビットが状態異常のON・OFFを表しているがすべてに1が立っている時は戦闘不能状態である。
よってここでゼロフラグが立つ場合は状態異常判定をスキップする。
続いて、$C1/1DD9から、状態異常と$08(%0000 1000)で論理積を取りゼロフラグ判定となる。
上から5ビット目の%0000 1000に1が立っている場合は毒状態なので、ゼロフラグが立たない場合は毒状態で確定である。
ゼロフラグが立つ場合は毒状態ではないので、サブルーチンから抜ける。
$C1/1DDDから先が、毒状態での処理となる。
$C1/1DE3~の処理を見ると、味方キャラデータの現在HP・2バイトの値を、論理右シフト4回、つまり/2を4回しているから、トータルで/$10である。
つまり、
trunc(現在HP/$10)
であるが、現在HPが$10(10進数で16)未満だと計算結果が0になる。
$C1/1DEFでゼロフラグ判定があり、計算結果が0なら$C1/1DF1で$0001をロードしている。
$C1/1DF4で、ここまでの計算結果を[$00:0311][$00:0310]に書き込んでいるが、これは、
max(trunc(現在HP/$10), 1)
と、なることがわかる。
これが毒状態のダメージ量にあたる。
$C1/1DF6以降では、毒状態のダメージ量はヒット数1、被ダメージの単発値は[$00:0311][$00:0310]と処理されており、最終的なダメージ量となる。
ここから現在HP - 毒のダメージ量の計算へと続くが、省略する。
敵キャラのサブルーチンは、アドレスこそ異なるが味方側と処理はほぼ同一である。
こちらも全ての敵キャラに対し処理を行う。
$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[$00:1B01] ;Aに[$00:1Bx1](戦闘状態)をロード $C1/E1BA BIT #$40 ;Aと$40で論理積(ステータスフラグ変更のみ) $C1/E1BC BNE $07 [$E1C5] ;ゼロフラグが立っていないとき[$E1C5]分岐 ;ゼロフラグOFF $00(戦闘離脱)、$20(敵キャラをプレイヤーが操作)以外 $C1/E1C5 LDA #$7F ;Aに$7Fをロード $C1/E1C7 RTS ;サブルーチン戻り $C1/1E4C BMI $0F [$1E5D] ;ネガティブフラグが立っているとき[$1E5D]分岐 $C1/1E4E BEQ $F9 [$1E49] ;ゼロフラグが立っているとき[$1E49]分岐 $C1/1E50 LDA $7E8F07,x[$7E:AA07] ;Aに[$7E:AAx7](敵番号xの状態異常)をロード $C1/1E54 BIT #$08 ;Aと$08で論理積(ステータスフラグ変更のみ) $C1/1E56 BEQ $F1 [$1E49] ;ゼロフラグが立っているとき[$1E49]分岐 ;ゼロフラグOFF 毒状態 $C1/1E58 JSR $1E5E [$C1:1E5E] ;[$C1:1E5E]へジャンプ ;毒状態計算 $C1/1E5E REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1E60 LDA $7E8F00,x[$7E:AA00] ;Aに[$7E:AAx1][$7E:AAx0](敵番号x現在HP 2バイト)をロード $C1/1E64 LSR A ;Aを論理右シフト (/2) $C1/1E65 LSR A ;Aを論理右シフト (/2) $C1/1E66 LSR A ;Aを論理右シフト (/2) $C1/1E67 LSR A ;Aを論理右シフト (/2) $C1/1E68 BNE $03 [$1E6D] ;ゼロフラグが立っていないとき[$1E6D]分岐 ;ゼロフラグON 計算結果が0 $C1/1E6A LDA #$0001 ;Aに$0001をロード ;ゼロフラグOFF 計算結果が0以外 $C1/1E6D STA $10 [$00:0310] ;Aを[$00:0311][$00:0310]に書き込み $C1/1E6F SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1E71 LDA #$01 ;Aに$01をロード $C1/1E73 STA $7E9002,x[$7E:AB02] ;Aを[$7E:ABx2](被ダメージ/回復量のヒット数)に書き込み $C1/1E77 STA $7E9003,x[$7E:AB03] ;Aを[$7E:ABx3](被ダメージ/回復量のヒット数)に書き込み $C1/1E7B LDA #$00 ;Aに$00をロード $C1/1E7D STA $7E9202,x[$7E:AD02] ;Aを[$7E:ADx2]に書き込み $C1/1E81 STA $7E920A,x[$7E:AD0A] ;Aを[$7E:ADxA]に書き込み $C1/1E85 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1E87 LDA $10 [$00:0310] ;Aに[$00:0311][$00:0310]をロード $C1/1E89 STA $7E9004,x[$7E:AB04] ;Aを[$7E:ABx5][$7E:ABx4](被ダメージの単発値(2バイト))に書き込み $C1/1E8D LDA #$0000 ;Aに$0000をロード $C1/1E90 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1E92 LDA #$01 ;Aに$01をロード $C1/1E94 STA $10 [$00:0310] ;Aを[$00:0310]に書き込み $C1/1E96 STZ $81 [$00:0381] ;[$00:0381]に$00を書き込み $C1/1E98 STX $60 [$00:0360] ;Xを[$00:0360]に書き込み $C1/1E9A JSR $CC72 [$C1:CC72] ;[$C1:CC72]へジャンプ
毒状態判定の時、毒ダメージを計算し、
max(trunc(現在HP/$10), 1)
が単発ダメージ量となって、ヒット数1、被ダメージの単発値(2バイト)[$7E:ABx5][$7E:ABx4]にダメージ量を書き込む、と、味方キャラと手順は全く同じ。
ダメージ計算式も変わらない。