経験値振り分けても減らない PSでHBPを使って探していた 「〜〜減らない」系のコードですが HBPの無いPS2DISでもある程度探す事が出来ます ただし、最大値検索をマスターしてる事が最低条件です。 サモンナイトシリーズの経験値の最大値は 前作で探した時に「9999900(98961C)」と判明しています システム的に考えて、最新作の3でもこれは変わらないと思われるので 下4ケタの961Cで検索すれば最大値チェックが見つかりそうです 早速検索すると、数箇所候補が出てきますが 一番最初にヒットした場所の分岐をいじってみた所 戦闘終了後にトータル経験値が9999900になっています 一回の検索ですぐに最大値チェックの場所が見つかりました(笑) ちなみに、すぐ下で98967Fで比較している場所もあり これも分岐を潰してみた所、戦闘後に所持金も最大になりました。このプログラムを見る限りでは gpレジスタ+81f8(符号拡張されているので正確にはマイナス7E08) のアドレスにトータル経験値が格納されているようです (ちなみに所持金はgp+81f4です) この情報を元に、マトリックスのフォーカスを探すのに似た方法で 経験値を振り分ける時のプログラムを探して見ましょう gpレジスタ自体は、基本的に最初に設定された数値のままで 途中で変更する事がありません(例外あり?) なので、他の関数(ルーチン)で経験値を扱う時にも gpレジスタ+81f8で読み込まれる可能性が非常に高いと考えられます 81F8で16bit検索して、数値をロード後に 減算してストアしてる場所が無いか候補の中から探します すると、001f2560でヒットした周辺は この条件(減算後ストア)を満たしている事が分かりました
他のヒット場所では加算後にストアする場所が多いので そこは獲得経験値を計算している場所と思われますが 「加算命令でマイナス値を加算して減らす」という可能性もあるので 念の為に準候補として頭に入れておきましょう。 001F2564にあるsubu命令、ここで経験値振り分け時に トータル経験値から減算している可能性が高いです 早速潰してみようと思いますが、普通にnopで潰すだけではなく v1−a0=v1という処理を、v1−zero=v1に変えてみましょう subu v1,v1,a0を subu v1,v1,zeroに書き換えればいいので PS2DISの行編集機能で命令を数値に変換します
変換後の数値が出たらあとはコード化するだけ A01F2564 00601823 〜暗号化〜 9C8AA68C 1476CFC8 実際に使ってみると、振り分けてもトータル経験値に影響は無し でも、経験値を獲得する時にはしっかり増加するので やはりここは獲得時にだけ使われる場所の様です 最大値チェックを探すだけで、HBPも使わずに アドレスの離れた命令を追跡する事が出来ました これは他のソフトでも応用が効く事が多いので覚えておきましょう。 今回はここで終わりにしようかと思いましたが ついでにもう2つ、場所がかなり近いので簡単に紹介します この経験値減算命令のすぐ上に気になる数値があります 0001863C、10進数に直すと99900ですね この数値はレベルアップに必要な経験値の上限なので ここを000003E8に書き換えてしまえば 「どんなにレベルアップしても必要経験値1000」コードが出来ますが 消費100均一コードを作ってあるので、これはボツってます(笑) そしてもう1つのコード紹介ですが 経験値減算後に、addiu命令で0001が加算される数値があります 単純に考えて、経験値が減って0001増える物なので ここでレベルの数値も増加してるなと考えました 前作で探した時には32(50)が上限だったので addiu v1,v1,$0001 を addiu v1,zero,$0032 に書き換えて見た所、レベルアップ後に50になり それ以降レベルアップする事が出来ません、予想通りでした。 ここから下方向へプログラムを探せばステータス関連の宝庫です(笑)