体力、鬼力減らない

セーブデータに残っている体力の数値などを
SFXbやフリーで公開されているバイナリエディタで調べると
体力と鬼力の初期値は16進数で500になっていて
薬草や鬼薬を使用すると16進数で1E0回復する事が分かりました
ちなみに初期値は前作の鬼武者2でも500、今作でも同じようです。

そこでこの情報を基に、体力に関係するプログラムを探してみようと思います
薬草(鬼薬)を使用すると1E0増加する事が分かっているので
01E0を16bit検索で探せばもしかしたら、
体力と鬼力を回復させるプログラムが見つかるかも知れません。

しかし、実際探してみると多くの候補が出てきてしまいます
この場合は怪しい命令だけに的を絞って探しましょう
体力などを「回復=増加」させる訳ですから
addiu命令やli命令などに注意して候補先を調べます。
(li命令で値を設定してaddu命令などで増加させる事もある為)

しばらく探していると、こういう場所が見つかりました


a1レジスタに01E0を格納した後に
jal命令で0016C2B0に処理が飛ぶようになっています
早速この0016C2B0からのプログラムに怪しい部分が無いか
ジャンプしてみて調べてみましょう。

すると、このプログラムでは先頭にいきなり
「bgez a1, $0016c2ec」という命令が存在します

このbgez命令は「a1の値がzero以上だったら分岐する
zero以下であれば分岐しない」という処理をしています
とりあえず、先のプログラムでa1に01E0が格納されているので
ここは分岐したと想定して0016C2EC以降を調べます。

すると、a0+21E8のアドレスからv0に値をロードした後
a1レジスタの値をそのv0の値に加算して
すぐにa0+21E8のアドレスにストアしています

この処理を見る限りでは、ここが回復プログラムの可能性があります
試しに、addu命令でa1の値ではなくzeroを加算にしてみましょう
もしここが回復プログラムならば薬草を使用しても回復しないはずなので
「addu v0, v0, a1」「addu v0, v0, zero」に書き換え
ゲーム中に薬草を使用してみた所・・・ずばり回復しませんでした(笑)
やはりここが体力を回復するプログラムのようです。

・・・が、同時にダメージも受けないようになりました
どうやらこのプログラムはダメージの計算も行ってるようで
bgez命令で「a1の値がzero以上か以下か」チェックしてたのは
a1に回復の値ではなく「ダメージの値が入ってるか」を調べ
後の処理を少し変更する為に使われていたようです。

それらを踏まえて後の処理を見ていくと
興味深い処理が見つかりました、それがここです。

現在体力のアドレスはa0+21E8なのは先程の結果で分かりましたが
その現在体力の値をv0レジスタにロードした後
a0+21E4のアドレスからもv1レジスタに値をロードして
slt命令で比較しています、その比較結果によっては
現在体力のアドレスにa0+21E4の値が書き込まれるようになっています。

この処理は最大値チェックの動作に非常に似ていて
恐らくa0+21E4は最大体力のアドレスであると考えられます
そこで、分岐命令を潰して、常にa0+21E4の値が
書き込まれるようなコードを作って実験してみましょう。

A016C344 10200001
〜暗号化〜
9C81446C 0436E7A6

すると、ダメージを受けてもアイテムを使っても
体力が常にMAXになるようになりました
体力減らないコードの完成です(正確には体力変動でMAX)
体力以外に、この方法と全く同じ方法で鬼力のコードも見つかりました。




余談ですが、002D76B4でa1レジスタに設定している
01E0という数値を変更すれば回復値の変更コードも出来ます
この値を二分の一にすると薬草効果半分でゲーム難度は増
逆に2倍にすればちょっとだけ難易度も易しくなり
ゲームプレイの補助コードとしても使えますね。