ホーム > セレクトバグ, プログラミング > 「ボックスから引き出したレベル」とは

「ボックスから引き出したレベル」とは

初代ポケモンの手持ちポケモン領域には頭から3byte目に「ボックスから引き出したレベル」のデータが入っています。
これとは別に後ろから11byte目には「現在のレベル」のデータを保持しています。おそらく使われていない前者はなんのためのものなのかずっと疑問だったのですが、ボックス領域のデータ構造をみていて納得。
実際にプログラムを読んだわけではないので裏は取っていません。そのうちやりたい。

まず手持ちデータ44byteをCの構造体であらわしたものがこれ。

unsigned char species; // 種族
unsigned char current_hp[2]; // 現在HP
unsigned char box_level; // 引き取りレベル
unsigned char status; // 状態フラグ
unsigned char type[2]; // タイプ
unsigned char item; // 初代のレア度 金銀の持ち物
unsigned char waza[4]; // わざ
unsigned char trainerid[2]; // ID
unsigned char exp[3]; // 経験値
unsigned char hp_exp[2]; // HP努力値
unsigned char atk_exp[2]; // 攻撃努力値
unsigned char def_exp[2]; // 防御努力値
unsigned char spd_exp[2]; // 素早さ努力値
unsigned char spc_exp[2]; // 特殊努力値
unsigned char ab_pot; // AB個体値
unsigned char sc_pot; // SC個体値
unsigned char pp[4]; // 上位2bitはポイントアップ使用回数 下位6bitが実際のPP
unsigned char level;
unsigned char max_hp[2]; // 最大HP
unsigned char atk[2]; // 攻撃
unsigned char def[2]; // 防御
unsigned char spd[2]; // 素早さ
unsigned char spc[2]; // 特殊

つぎにボックスデータ33byteを同様にCの構造体であらわしたものがこれ。

unsigned char species; // ポケモンの中身の種別
unsigned char current_hp[2]; // HP現在値
unsigned char level; // レベル
unsigned char status; // ステータス異常フラグ
unsigned char type[2]; // タイプ
unsigned char item; // 持ち物
unsigned char waza[4]; // 技
unsigned char trainerid[2]; // ID
unsigned char exp[3]; // 経験値
unsigned char hp_exp[2]; // HP努力値
unsigned char atk_exp[2]; // 攻撃努力値
unsigned char def_exp[2]; // 防御努力値
unsigned char spd_exp[2]; // 素早さ努力値
unsigned char spc_exp[2]; // 特殊努力値
unsigned char ab_pot; // AB個体値
unsigned char sc_pot; // SC個体値
unsigned char pp[4]; // PP

名前や親名は一番最後にまとめて入っています。なぜだろう。

ほぼ同じ構造ですがボックスデータはレベル、最大HP、各ステータス実数値の合計11byteが削られています。これらはボックス内では必要ないデータなので1匹でも多くボックスに入れるために削られているのでしょう。
(セーブ容量に関してはポケモンストーリーという本に苦労話が書かれていたと思います。読んだのが10年くらい前なのでよく覚えていませんが。今度また借りてこよう。)

さて、この構造はほぼかぶっているので手持ちからボックスへは頭から33byteをコピーすればよさそうです。
この時現在のレベルは失われますが、経験値から再計算できるので問題あり・・・ました。
ボックスから引き出す時の一覧にはレベルもあわせて表示されます。
おそらくこのために預けたレベルを頭から3byte目に記録します。

引き出す時は逆に、ボックス側から33byteをコピーして、破棄したステータスを再計算して残り11byteを埋めます。これが「バグったステータスのポケモンをボックスに預けると正常化される」理由でしょう。
ボックス内でのレベルは放置され、そのまま残ったままになるわけです。

・・・どーしてそこをレベル領域にはしなかったんだろうなー

余談:容量とボックス
ボックスにも手持ちと同じように「見かけ上の種族」領域が別にあります。なので見た目と中身が一致していなくても両方が保持されます。
(育て屋のデータ領域はまだ見ていませんが、挙動から推測すると多分育て屋領域には見かけ上の種族領域はないと思います。)
ところでその見かけ上の種別領域1byteと現在HP2byte、残りPPの数値部分6bit x 4(上位2bitだけはポイントアップ領域なので技4つ分をまとめて1byteにおしこむ)、状態異常領域1byte、タイプ領域2byteを削れば一匹当たり8byte、ボックスあたり240byteあくのであと6匹くらい入ったんじゃないかな・・・
きりよく30にしたかったのかもしれませんが。

5/9追記:タイトルを書き忘れていたのを修正

2015/5/25追記

ようやく実証実験しました。というのは簡単で、経験値とレベルが一致していないポケモンを作ってボックスに預けて引き出すだけ。
経験値的にはLv100のポケモンのレベルをLv99に書き変え、ボックスに預けるとレベル表示は「Lv99」となります。
そのポケモンを引き出すとレベル表示は「100」になります。データの3バイト目は99(0x63)でした。

よって、3byte目については以下の通りです。
・ボックスに預けるとき、現在ステータスのレベル情報を3byte目にコピーする。
・ボックス中でのレベル表示時は再計算せずに3byte目のデータをそのまま表示する。
・ボックスから引き出すとき、レベルは経験値を元に再計算される。3byte目はそのまま取り残される。
・3byte目は実は「ボックスから引き出した時のレベル」ではなく「ボックスに預けた時のレベル」だった。(通常はこれらは一致する。)

広告
  1. まだコメントはありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。