まずは、こちらの記事で《はやぶさバッヂ》という裏トレーナー界隈では有名などうぐについて予習をお願いします。
《はやぶさバッヂ》の挙動はある程度理解を示してもらえたでしょうか
では、本題に移ります
先ほどの記事ではメインメモリ0xD0E1が登場しましたが
今回必要になるメインメモリは0xD036になります。
このメモリは、野生ポケモンとエンカウントするための数値で基本は00ですが、
この数値に書き込まれることでその数値に適したメモリが書き込まれます。
要は草むらや洞窟を歩いていてBitが立ったらエンカウント...といった具合にね。
で、なぜこの0xD036が出てきたかというとこのメモリに任意の数値を書き込むことができれば、トレーナー戦であろうが強制的に好きな野生のポケモンと出会うことが理論上可能になるわけです。
しかし現実的に可能でしょうか?
実は10年以上前に、このメモリを利用したバグが発見されています。
当ブログでも紹介した
を利用した方法です。
詳細は割愛しますが、《てへ》でAを押し『はい』『いいえ』の選択肢が出てきたらBでキャンセルを押すと表示されているどうぐ欄の一番上を自動的に使用します。
そのどうぐが《ポケモンのふえ》であればテキストメッセージが流れた直後に唐突にエンカウントが始まります。
そのエンカウントするポケモンは0xD036で書き込まれた数値に一致するポケモンになるわけです(21であればミュウになります)
いわゆる【ポケモンを呼ぶ笛】というバグ技であり、その由縁となっています。
ちなみに原理は判明しており
1.どうぐ欄を開くと現在の画面のマップチップ情報が0xCD7Cから先に360byteコピーされます
この時、0xCD7Cは画面の左上、0xCD7Dは画面の左上のひとつ右、画面の右上に到達したら画面の左上の真下の・・・と右下までコピーします。
2.どうぐを使った瞬間に、0xCF78に使った道具の番号「0x7B」が保存され、さらに0xCD68-0xCD7Bの20byteにどうぐ名がコピーされます。このコピーは固定長です
0xCD68から、終端文字の0x50が現れるまでのデータを0xCF45から先にコピーします。ここで、20byte以内に0x50がないとそのまま画面のデータを読んでコピーを続け、0xCF78に保存されている道具の番号を破壊します。
3.どうぐ使用時の処理に入ります。0xCF78に入っているどうぐ番号を読み込み、該当のどうぐの処理に飛びます。
4.戦闘中判定になっているため、戦闘中に使えないどうぐならオーキドのことば、それ以外なら使用した時の処理を行います。
結果判定
戦闘中に使えないどうぐであった場合(じてんしゃ等)
どうぐ欄にある一番上のどうぐを使用し、ポケモンとエンカウントします
戦闘中に使えてなおかつポケモンに選ぶどうぐであった場合(キズぐすり等)
ホワイトアウトォ!します。
戦闘中に使えて直接処理するどうぐであった場合(ヨクアタール等)
ゲームを破壊するものになります。
0xD036にアクセスする前に0x50が来るどうぐであった場合(名前の長いどうぐ等)
壁抜けモードになります。
この方法が確立されていることにより、現実的に可能であることは証明されました。
Q,E,D,
このままでは【ポケモンを呼ぶ笛】の解説記事になってしまうところでした。
とにかく、0xD036はそういったメモリであることを理解してもらえばOKです。
しかし上記の方法には致命的な問題があります。
それは、主人公が今いる位置のマップチップに影響されるということでした。
説明にもあるように、画面のデータを読んでコピーを行うわけです。
同じく《てへ》を用いる闇市での商品のラインナップと似通っていますね。
なぜ致命的かというと、画面の描写というのはマップによって必ず決まっており、逆に言えば用意されているマップの数値に該当するポケモンとしか出会えないのです。
ここで31番目セレクトによる画面を異次元に飛ばすという発想が出てきた方は賢いです。
一緒にこのゲームを検証しましょう。(ぇ
では、151匹。ひいては255個分用意されているエンカウントテーブルすべてと自由に遭遇する方法はないのでしょうか?
Fifth法なら確かにとくしゅの実数値を1~255に変えることで自由なエンカウントは可能ですが、とくしゅの実数値を1単位で変えるのは手間がかかるうえにそのポケモンは成長させずに置いておかないといけないデメリットもあります。
さて、ここで初歩的な部分に振り返ってみましょう。
0xD036はどこにスタックしてあるメモリなのでしょうか?
化石変換に必要である0xD68Eは手持ち32番目のポケモンの取得経験値下位bitでした
そして答えはいつだってメモリの中にあります。
手持ち35番目のポケモンが習得しているわざのPPアドレスと一致しています。
PPであれば簡単に調整できる数値ですね。
ということは、残りPP21に調整したわざをセレクトバグで入れ替えてあげれば?
ざんねんながら書き換わっただけです。
なぜなら、わざを入れ替えられるのは戦闘中のみであり既にポケモンと戦闘が開始してしまっているからです。
戦闘自体をリセットしてあげないといけません。
ただ離脱するとフィールド画面に戻ってしまうのでせっかく書き換えた数値もリセットされてしまいます。
では戦闘を起こしたままフィールドに戻す方法が必要になりますよね?
そうです、ここで登場する救世主こそ、《はやぶさバッヂ》なのです。
手順としては以下のようになります。
1.どうぐの35番目でセレクト(パソコンに預けているどうぐでもOK)します
2.戦闘に入り、ポケモンのわざでセレクトします
3.はやぶさバッヂを使います
4.セレクトしたわざの残りPPと一致する内部番号のポケモンとエンカします
5.ボールで捕獲するもよし、トレーナーなら戦ってもよしです
副作用として、手持ち1番目のポケモンのとくしゅ実数値と2番目のポケモンのこうげき努力値を書き換えてしまいますのでポケモンの並び順には注意しましょう。
また、疑問に思った方もいることでしょう。
あれ・・・?PPは最大56までしかないから内部番号57以降のポケモンとは会えないのでは、と
ご安心ください。きちんと解答が用意されています。
PPの数値というのは、そもそも内部アドレスでは
メモリ上のPP値(1番目のポケモンの1番目の技ならD148)から
画面上に表示されるPP値への変換は、ROM03:6882CHので計算されています。
戦闘中においてはメモリ上のPP数値を元に、[and 3F]する処理が入っています
そのため最高値は63となります。
なので改造等でPPをFFにしても D8 and3F = 18H = 24となってしまうわけです。
つよさをみるで表示するorポケモンセンターで回復した場合は
PP=X+(わざの基礎PP値/5)*ポイントアップの使用回数
Xは(現在PP and C0)+基本PP値とする
以上の計算式に則って決定されます。
例:はたく(PP35)にポイントアップを1回使用した場合
はたくの基礎PP値は35(23H)です。
この数値にポイントアップ1回なので、
D148の値は、23→(ポイントアップ+40H)→63→6Aとなります。
実際のPP値は計算式に則り PP=35+35/5x1=42 となるわけです。
そしてポイントアップ使用時の処理でD148がFFを越えるようだと、
「このポケモンにはつかえません」となる処理が入っているので、
3回はOK!だけど4回目はNGとなるのです。
<補足>
「ポイントアップ使用回数」の解説をします
具体的なのは次の5行です
1 ld a,(hl) hlにPP値が入っている
2 swap a
3 and 0F
4 srl a
5 srl a
ポイントアップ1回使用で+40hされるので、例えば「きのこのほうし(0F)」にポイントアップを3回使うと
0F+40+40+40=CF です。この数字を元にします
1行目:ld a,(hl)で、aの値が読まれます(CF)
2行目:swap aで、aの上位下位ビットが入れ替わります。つまり CF→FC
3行目:FC(11111100) and 0F(00001111)なので要するに下位4ビットを取り出す a=0C
4行目:srl a は右に1ビットずらします。つまり/2 00001100→00000110
5行目:もう一度 srl a で、00000110→00000011 ←3になります
ということでポイントアップで+40Hというのはプログラム処理においても都合が良かったのです
解答に戻ります
例:ミュウツーに会いたい場合
ポイントアップを2回使用した ⇒64が2回書き込まれる わざの残りPPを3にします
3+64*2=131になり、内部番号131のミュウツーとエンカウントできます
というわけで、《はやぶさバッヂ》による任意エンカウント方法でした
ちなみに、《なかよしバッヂ》が使える環境であれば当然そっちの方が非常に速くて簡単です。なので任意コード実行をしたくないという方向けの紹介になります
まぁ、任意コード実行もこの0xD036の数値を3番目のどうぐの個数で書き換えてるわけですが(,,Ծ‸Ծ,,)
ふりそでのカレンちゃんといつでも戦える任意コードください(切実)