[Hack] カンケツセンのアタリ位置を弄ろう

Hack

EventGeyser::stateEnterIdle_()

恐らくカンケツセンのいろんなパラメータを弄っているのはここ。

シード値をA304Eに固定して実験しているので、乱数によってアタリの位置がズレることはありません。

また、検証ステージとして一番狭くて便利な満潮ポラリスを採用しました。

満潮ポラリス

何もコードを入れない場合のカンケツセンのアタリの位置は以下の通り。

Seed12345
1C3FDDEAB
A304EAEDEE
18264EDABEE

shuffle(sead::Random *)

ランダムな値から配列をシャッフルして返す関数。

配列にカンケツセンのアタリ位置の順番が載っているのではないかと仮定し、ここの返り値を固定すれば常に同じところがアタリになるのではないかと考えました。

MOV	X0, #0

それを実現する5.1.0向けのコードは以下の通りです。

// sead::PtrArrayImpl::shuffle() always return 0 [tkgling]
@disabled
006DBFD4 000080D2

これを適応させたところ、どちらのシード値に対しても常にアタリのカンケツセンがBになりました。

BじゃなくてAになってほしいんだよなあ…

キンシャケルートも決定できるかと思ったけど、どうもそうではないみたい。

少なくとも通常ポラリスで二通りのルートを確認しました。

// Only close SuccPos [tkgling]
@enabled
006DC018 1F2003D5

アタリのカンケツセンだけ閉じるので、一度全開けすればどこがアタリかわかります。

これ、応用すれば最初からどこがアタリかわかりそうな気がしますね。

setIsSpoutSucc(bool)

カンケツセンがアタリかどうかを判定してくれそうな関数。

が、使い方がいまいちわからないのでどうしようもない。

setFirstSpawnGeyserPos()

カンケツセンの初期アタリ位置を求めてくれそうな関数。

アセンブラじゃさっぱりわからんのだが、C++擬似コードに変換するとなんとなくわかってくる。

float __fastcall Game::Coop::EnemySakelienGeyser::setFirstSpawnGeyserPos(float *a1, float *a2)
{
  float v2; // s2
  float v3; // s3
  float v4; // s1
  float result; // s0

  v2 = a1[227] * 20.0;
  v3 = a2[2];
  v4 = a2[1] - (float)(a1[226] * 20.0);
  a1[601] = *a2 - (float)(a1[225] * 20.0);
  result = v3 - v2;
  a1[602] = v4;
  a1[603] = v3 - v2;
  return result;
}

しかしながら、なぜ20をかけていたりするのかはよくわからない。

calcGoalGeyser()

キンシャケのゴール位置を求める関数と思われるが、長いので書きたくない。

が、関数の最後にsead::Random::getU32(void)が使われていることからキンシャケルートはランダムに決まると見てよさそうだ。

もちろん、これは擬似乱数なのでイカッチャでリトライした場合に同じルートを通るのは言うまでもない。

EventGeyser::setupGeyser()

あんまりみてないけど、ひょっとしたら何か弄れるかもしれない。

まとめ

カンケツセンのアタリの位置を変えることには成功した。

が、任意の場所を指定することができずいろんな値を代入しても常に同じ位置がアタリになってしまう。

また、ゴール位置を決めることもできないのでルートが適当になる。

更に、バイナリを直接編集してクライアントと同期している感じもしないので、同期ズレを起こす可能性がある。

ただ、この付近にカンケツセンのアタリを求める式があるのはほぼ間違いないので、近い将来にシード値からカンケツセンのアタリを見つける公式が見つかるかもしれない。

記事は以上。

コメント

タイトルとURLをコピーしました