2022年6月7日火曜日

menu IDって何のID?

 NPCと会話するとincoming 0x034でmenu idが送られてきますが、このmenu idって何のテーブルのIDなのか良くわからなかったので、WEB検索して少し調べてみました。

https://www.reddit.com/r/FFXIPrivateServers/comments/tcxycb/xievents_ffxis_event_vm_fully_reversed/

https://github.com/atom0s/XiEvents

英語ですが上記のリンクが参考になりました。そして、結論から言うと、Zone Events DATファイルの中のイベントスクリプトのID(EvectExecNum)でした。かなりややこしいデータ構造なので、備忘録代わりに簡単にさらっと書いてみます。なお、変数名は上記リンクのものをそのまま使用しています。

まず、例えばルルデの庭のDATファイル群は以下のようになっていて

zone id: 243
エリア名: Ru'Lude Gardens
Zone Entities:  ROM/27/52.DAT
Zone Events:   ROM/21/52.DAT
Zone Dialogs/Strings:  ROM/25/52.DAT(English)

一番下のZone Dialogs/StringsのDATファイルの中にはNPCがしゃべる実際のテキストデータが格納されています。たとえば、シグネットをかけてやろう、などの文とかです。なお、このテキストデータのIDは、incoming 0x02AのMessage IDとして使われています。エリチェンする度にハッピーパワーのログが表示されたりしますが、あれは0x02Aで送られてきており、そのとき指定されるのがこのテキストデータのIDとなります。(ただし、Message IDの最上位ビットをクリアする必要があります。それとバージョンアップの度にMessage IDはコロコロと値が変わるので扱いづらいです)

windower の lib/dialog.lua の function dialog.get_entry(dat, id) を使うと、datファイルとMessage IDを引数として渡すことで、対応するエリアのDATファイルからIDで指定されたテキストデータを取得することができます。

なお、引数である dat には function dialog.open_dat_by_zone_id(zone_id, language) の返り値をそのまま代入します。(処理が終わったらクローズ処理が必要です)

ここまでの話はそんなに難しくないのでよいのですが、ここから難しくなります。


Zone Events DATファイルの話をします。

まず、上記のリンクに書かれていることによると、NPCとおしゃべりをするとクライアントプログラムは裏でEventVM(仮想マシン)を動かしているとのことです。例えば、シグネットをかけてやろう、においては、文字を表示したり、ユーザーの選択を待ったり、NPCに口パクをさせたり、ユーザーにエフェクトをかけたりなど、いろいろな処理が行われますが、そういった処理が、どの順番でどういうタイミングで実行されるのかをスクリプトのようにくみ上げ、それをバイトコード列としてあらかじめDATファイルに記録しておき、実行時にそれを動的に解釈して処理を実施しています。また、カットシーンのNPCの動きなども仮想マシンで処理されていおり、汎用性の高いスクリプトのようです。

どういう順番でどういう処理をするのかという指示データはバイトコード列(EventData)としてZone Events DATファイルに格納されていて、そのバイトコード列のIDが menu id です。つまり、イベントスクリプトのIDです。なお、これは、かなりざっくりした説明で、実際にはもっと細かくデータ構造がくみ上げられています。

バイトコード列はマシン語のようにオペコードとオペランドの列になっていて、たとえばオペコード0x1Dはオペランドで指定した文字列を表示する命令になっています。

例えば、0x1D 0x04 0x80というバイト列の場合、0x04が表示する文字列の番号になっていて、これはImidData[0x04]で指定されているテキストデータを表示するという意味になります。ImidDataもZone Events DATファイルに記録されているデータで、Message IDの配列となっているようです。なのでオペランドは間接参照のようですね。ですが、これは0x80の場合のみで、0x80以外の場合はワークメモリ(Work_Zone)を参照したりします。

上記のリンクのすべてを読みこなせているわけではないので、これ以上の細かい部分の説明はできませんが大枠ではこんなところです。

で、一番肝心なことですが、menu idの意味が分かったとしてそれが何の役にたつのかという質問の答えは、現状はたいして役には立たないかも^^)vという回答になりそうです。