TOP > プログラミング関係解説&調査 > 功夫編・修行(その2)

功夫編・修行(その2)

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

前ページの続き。
ここでは、修行におけるレベルアップ時の処理と、修行場所によるステータスアップについて説明する。

修行では、ステータスアップ関連の処理が特殊である。
功夫編用サブルーチンとなっている。

レベルアップ時は、HPのみ特定値分アップする。

キャラHP増加量
ユン12
レイ18
サモ60

また、レベルアップとは関係なく、修行場所により、戦闘終了時に特定のステータスがアップする。
修行場所だが、戦闘に入ると、$00:0041の上6ビットに戦闘時の背景の番号が入り(詳しく調べていないので未確定。他シナリオでも戦闘に入った時に値が入るので共通処理と思われる)、その値で区別している。

場所$00:0041ステータス上昇値
山頂$6C5
竹林$145
道場$185

シナリオ別キャラデータのステータス関係のアドレスは以下の通り。
今回は知の値は関係ないが(修行では上がらない)、一応一緒に載せておく。

ユンレイサモ内容
$00:0F08$00:0F48$00:0F88現在HP(下位バイト)
$00:0F09$00:0F49$00:0F89現在HP(上位バイト)
$00:0F0A$00:0F4A$00:0F8A最大HP(下位バイト)
$00:0F0B$00:0F4B$00:0F8B最大HP(上位バイト)
$00:0F10$00:0F50$00:0F90力(力+装備上昇分)
$00:0F11$00:0F51$00:0F91
$00:0F12$00:0F52$00:0F92力(装備上昇分)
$00:0F13$00:0F53$00:0F93速(速+装備上昇分)
$00:0F14$00:0F54$00:0F94
$00:0F15$00:0F55$00:0F95速(装備上昇分)
$00:0F16$00:0F56$00:0F96体(体+装備上昇分)
$00:0F17$00:0F57$00:0F97
$00:0F18$00:0F58$00:0F98体(装備上昇分)
$00:0F19$00:0F59$00:0F99知(知+装備上昇分)
$00:0F1A$00:0F5A$00:0F9A
$00:0F1B$00:0F5B$00:0F9B知(装備上昇分)

レベルアップ時のHP処理

戦闘終了時の処理の順番は、レベルアップした場合はレベルアップ処理(HP処理→技習得)→修行場所によるステータスアップ処理である。
まず、レベルアップした場合におけるステータス関係の処理から説明するが、修行時はHPしか上昇しない。
上昇量は、味方キャラデータ27の値から計算される。

レベルアップ処理 > ステータス上昇値で、レベルアップ時のHP上昇量は味方キャラデータ27の値から計算されることを紹介した。
HP上昇量計算は少しややこしいが(詳細は上リンク先参照)、ほとんどのキャラで乱数計算による上昇値のブレが生じるようになっている。
だが、修行時のみ、乱数計算は行わない。
味方キャラデータ27の下6ビットの値が固定値として加算される。

味方キャラデータ27の値は以下の通り。

キャラアドレス下6ビット
ユン$D5:0270$8C$0C
レイ$D5:029D$92$12
サモ$D5:02CA$FC$3C

以下が、修行におけるレベルアップ時のHP処理になる。

$C1/2451 LDA $D5001B,x           ;Aに[$D5001B,x](味方キャラデータ27)をロード
$C1/2455 AND #$3F                ;Aと$3Fで論理積
$C1/2457 BRA $07    [$2460]      ;フラグにかかわりなく常に分岐[$2460]
$C1/2460 STA $10    [$00:0310]   ;Aを[$00:0310]に書き込み
$C1/2462 STZ $11    [$00:0311]   ;[$00:0311]に$00を書き込み
$C1/2464 REP #$21                ;Aを16bit幅に変更、キャリーフラグクリア
$C1/2466 LDA $000A,y[$00:0F4A]   ;Aに[$000A,y+1][$000A,y](シナリオ別キャラデータ 最大HP)をロード
$C1/2469 ADC $10    [$00:0310]   ;A + [$00:0311][$00:0310]
$C1/246B CMP #$03E7              ;Aと$03E7(10進数999)を減算比較(ステータスレジスタ変更のみ)
$C1/246E BCC $03    [$2473]      ;キャリーフラグが立っていないとき[$2473]分岐
;キャリーフラグON
$C1/2470 LDA #$03E7              ;Aに$03E7をロード
;キャリーフラグOFF
$C1/2473 STA $000A,y[$00:0F4A]   ;Aを[$000A,y+1][$000A,y](シナリオ別キャラデータ 最大HP)に書き込み
$C1/2476 STA $0008,y[$00:0F48]   ;Aを[$0008,y+1][$0008,y](シナリオ別キャラデータ 現在HP)に書き込み

処理は通常のレベルアップ時に比べるとシンプルである。
味方キャラデータ27の下6ビットの値の値を取り出すために、$C1/2455$3F(%0011 1111)と論理積を取る。
その計算値を[$00:0310]に、[$00:0311]$00を書き込んでから、$C1/2464で16bitモードに切り替える。
$C1/2466で、弟子のシナリオ別キャラデータの最大HPの値を2バイトで読み込み、$C1/2469[$00:0311][$00:0310]を加算する。
[$00:0311][$00:0310]はさきほど、上1ビットに$00を入れ、[$00:0310]に味方キャラデータ27の下6ビットが入った。
つまり、味方キャラデータ27のHP上昇量の基礎値部分を、シナリオ別キャラデータの最大HPに足したことになる。

$C1/246Bで、加算の結果を$03E7(10進数999)と比較している。
つまり、加算したことで最大HPが999を越えていないか、$C1/246Eでキャリーフラグにて判定をする。
キャリーフラグが立つ場合は999以上であり、$C1/2470A$03E7を読み込むことで、最大HPを999に変更する。
キャリーフラグが立たない場合は999未満であり、加算後の値がそのまま、新たなシナリオ別キャラデータの最大HPにセットされる。
同時に、シナリオ別キャラデータの現在HP(2バイト)のデータにもセットされて、処理終了である。
他ステータスには一切処理が入らない。

ここから、修行では、HPのみ「味方キャラデータ27の下6ビット」分上昇し、他ステータスは上がらないことがわかる。
HPの上昇値も、通常の戦闘におけるレベルアップ時とは異なり、乱数に左右されず固定値となる。

場所によるステータス処理

修行中は、戦闘が終了する度に、修行を行った弟子のステータスがアップする。

場所$00:0041ステータス上昇値
山頂$6C5
竹林$145
道場$185

修行場所は、$00:0041の上6ビットの値(おそらく戦闘背景の番号にあたる)で区別している。
修行以外でも戦闘開始時、$00:0041に戦闘背景の番号が入る。
竹林の虎や、レイが弟子になる時の戦闘などの戦闘では$00:0041 = $14だし、道場の修行前の弟子三連戦も$00:0041 = $18である。
なお、今回、上表に乗せている$00:0041の値は、下2ビットがすべて%00なので、$00:0041の値はそのまま上6ビットの値と同値である。

もうひとつ、修行中は、戦闘中の味方キャラデータの2人目に弟子のデータの一部が入る。
本来、修行での味方キャラは老師だけで、$00:1C00$00:1C3Fに入るのだが、弟子のデータの一部は$00:1C40~にも入る。
$00:1C40に入るキャラID以外は、おそらく修行用の専用値である。
$00:1C41には戦闘状態が入るが、$20は修行における対戦相手の値であろう。
$00:1C42$00:1C43の値で、弟子毎に呼び出すアドレスを計算しているようである。

アドレスユンレイサモ
$00:1C40$09$0A$0B
$00:1C41$20$20$20
$00:1C42$00$40$80
$00:1C43$0F$0F$0F
$00:1C44$08$09$0A

以下が、修行時のステータス処理のサブルーチンである。

$C1/230E LDX #$1C40              ;Xに$1C40をロード
$C1/2311 LDY $0002,x[$00:1C42]   ;Yに[$00:1C43][$00:1C42]をロード
$C1/2314 LDA $0041  [$00:0041]   ;Aに[$00:0041]をロード
$C1/2317 AND #$FC                ;Aと$FCで論理積
$C1/2319 LDX #$FEDC              ;Xに$FEDCをロード
$C1/231C CMP #$18                ;Aと$18を減算比較(ステータスレジスタ変更のみ)
$C1/231E BEQ $19    [$2339]      ;ゼロフラグが立っているとき[$2339]分岐
$C1/2320 LDX #$FECB              ;Xに$FECBをロード
$C1/2323 INY                     ;Yをインクリメント +1
$C1/2324 INY                     ;Yをインクリメント +1
$C1/2325 INY                     ;Yをインクリメント +1
$C1/2326 CMP #$14                ;Aと$14を減算比較(ステータスレジスタ変更のみ)
$C1/2328 BEQ $0F    [$2339]      ;ゼロフラグが立っているとき[$2339]分岐
$C1/232A LDX #$FEEA              ;Xに$FEEAをロード
$C1/232D INY                     ;Yをインクリメント +1
$C1/232E INY                     ;Yをインクリメント +1
$C1/232F INY                     ;Yをインクリメント +1
$C1/2330 CMP #$6C                ;Aと$6Cを減算比較(ステータスレジスタ変更のみ)
$C1/2332 BEQ $05    [$2339]      ;ゼロフラグが立っているとき[$2339]分岐

弟子により変わるのは、$C1/2311における[$00:1C43][$00:1C42]のロードで、

キャラ[$00:1C43][$00:1C42]
ユン$0F00
レイ$0F40
サモ$0F80

以上がYにロードされる。
40ずつズレることで、後々のキャラデータの呼び出し位置もアドレスが40ずつずれ、各弟子のデータを呼び出せることになる。

続いて、$C1/2314[$00:0041]をロードしている。この値は先に書いた通りに戦闘背景の番号で、修行場所の判別に使っている。
$C1/2317で、[$00:0041]$FCで論理積を取ってから、この値を、

アドレス処理XY
$C1/231C$18と減算比較(道場)X:FEDCY:0F?0+0
$C1/2326$14と減算比較(竹林)X:FECBY:0F?0+3
$C1/2330$6Cと減算比較(山頂)X:FEEAY:0F?0+6

の順に判定し、ゼロフラグが立つ、つまり同値なら$C1/2339にジャンプしている。
つまり、修行場所による分岐が入る。
分岐で飛ぶ前のXYの値が変更されていくという点がポイント。

いずれかの値と一致した場合の$C1/2339~の処理は以下の通り。

$C1/2339 LDA $0011,y             ;Aに[$0011,y](力/速/体)をロード
$C1/233C CLC                     ;キャリーフラグクリア
$C1/233D ADC #$05                ;A + $05
$C1/233F CMP #$63                ;Aと$63(10進数99)を減算比較(ステータスレジスタ変更のみ)
$C1/2341 BCC $02    [$2345]      ;キャリーフラグが立っていないとき[$2345]分岐
;キャリーフラグON
$C1/2343 LDA #$63                ;Aに$63(10進数99)をロード
;キャリーフラグOFF
$C1/2345 STA $0011,y             ;Aを[$0011,y](力/速/体)に書き込み
$C1/2348 CLC                     ;キャリーフラグクリア
$C1/2349 ADC $0012,y             ;A + [$0012,y](力/速/体(装備上昇分))
$C1/234C STA $0010,y             ;Aを[$0010,y](力/速/体(力/速/体+装備上昇分))に書き込み
$C1/234F JSR $476E  [$C1:476E]   ;[$C1:476E]へジャンプ

$C1/2339で呼び出す[$0011,y]だが、$0011Yの値を加えると、ちょうど修行場所にあったステータスのアドレスが呼び出せる。
たとえば、「レイが山頂で修行」の場合、Y = $0F40 + 6なので、[$0011,y] = $0011 + $0F46 = $0F57である。
$00:0F57は、下表の通り、レイの「体」にあたる。

ユンレイサモ
$00:0F10$00:0F50$00:0F90力(力+装備上昇分)
$00:0F11$00:0F51$00:0F91
$00:0F12$00:0F52$00:0F92力(装備上昇分)
$00:0F13$00:0F53$00:0F93速(速+装備上昇分)
$00:0F14$00:0F54$00:0F94
$00:0F15$00:0F55$00:0F95速(装備上昇分)
$00:0F16$00:0F56$00:0F96体(体+装備上昇分)
$00:0F17$00:0F57$00:0F97
$00:0F18$00:0F58$00:0F98体(装備上昇分)

弟子のステータスに$C1/233D$05を加算し、$C1/233Fで加算後に$63(10進数99)を越えていないか判定。
$63以上はキャリーフラグが立って、A$63(10進数99)を上書きすることで、加算後の値を$63に変更する。
キャリーフラグが立っていない、つまり$63未満なら、その値がそのまま新たな[$0011,y](力/速/体)として書き込まれる。

[$0012,y]、つまりステータスの+1のアドレスには、現在の装備による該当ステータスのステータス補正分の値が入っている。
よって、素のステータス[$0011,y][$0012,y]を加算すると、ステータス+装備分のステータスとなり、これを[$0010,y]に書き込んで、処理終了となる。

上の処理を見る限り、素のステータス+装備による補正値で0未満になったり、256以上になる場合の分岐処理がない。
功夫編の修行前までに入手できる装備品は限られており、力・速・体にマイナス補正が入る装備はないので、0未満になる場合を考慮する必要はないし、「ドンブリ」の体+4、「ちゅうかなべ」の体+2、「キリンのくつ」の速+20では、素のステータス+装備補正で256を越えることもありえない。
ということで、通常のレベルアップであれば考慮されていたオーバーフロー関係の分岐処理は、功夫編の修行では行われないようである。


おまけとして、修行関係の進行フラグの値も載せておく。
各シナリオでは、$00:11F?がカウンター、$00:12??に各種フラグの値($00$01のいずれかが立つ)が入るが、修行では以下のようにフラグが記録され、最終的に弟子の誰が伝承者になるかも以下の値から決定される。

アドレス内容
$00:11F0各地の修行回数累計。山頂・竹林・道場それぞれで$00$04、竹林・道場は開始になる度にリセット。
$00:11F1ユンの修行回数
$00:11F2レイの修行回数
$00:11F3サモの修行回数
$00:123A修行(山頂)開始
$00:123B修行(山頂)終了
$00:123C修行(竹林)開始
$00:123D修行(竹林)終了
$00:123E修行(道場)開始
$00:123F修行(道場)終了

ちなみに、山頂で一度でもレイに修行をすると、山頂の修行後に専用の会話になるが、判定は以下の通り。

$C0/2704 LDA $00,x  [$00:11F2]   ;Aに[$00:11F2](レイの修行回数)をロード
$C0/2706 CMP $8E01,y[$7F:A1CE]   ;Aと[$7F:A1CE]を減算比較(ステータスレジスタ変更のみ)
$C0/2709 BNE $07    [$2712]      ;ゼロフラグが立っていないとき[$2712]分岐

[$7F:A1CE] = $00なので、$C0/2706の減算比較でゼロフラグが立つのは、レイの修行回数が0回の時のみ。
よって、レイに修行を1回以上行っておくと、専用会話が見られることになる。



このページをシェアする

上へ