ベースウェア(SSPなど)に特定のゴーストやシェルやバルーンがインストールされているかどうかを調べる方法の説明です。
ここにあるような方法で調べておけば、たとえば特定のゴーストがいる場合にだけそのゴーストを呼び出す選択肢を表示するとか、イベントを起こすとか、そういう仕組みに使えます。
なおこのページにある内容にはSSP専用のものがあります。
情報取得変数で、カッコ1つで取得できます。
「$NOTIFYの自動保存」を有効にするのを忘れずに行ってください。
以下の情報は里々Mc154-1以前を対象とした情報です。里々Mc155-1以降は上記の情報取得変数を利用するのが、この目的のためにもっとも容易かつ安全な方法です。
まず最初に、以下の説明で「バイト値」というものを多用します。
これはゴースト名などの「どんな文字が入ってるか分からない文字列」を里々で安全に扱うためには、どうしても必要になります。
なのでよくわからないかもしれませんがreplace.txtに以下をコピペしてください。
何も見えないと思いますが、タブ文字やバイト値1と2が隠れているのでそのままコピペ推奨です。
|B1| |B2|
参考:
「ほげほげ」というゴーストがインストールされている事を確認
*installedghostname $ほげほげ導入済【タブ】0 (times,(Rの数), (when|B1|[(R(C0))]==[ほげほげ] |B1|(set,ほげほげ導入済,1) ) )
↑で立てたフラグを利用する例
*切り替えメニュー :φ _ランダム切替 _次のゴーストに切替 (when、(ほげほげ導入済)、\q[ほげほげに切替,ほげほげに切替]) *ランダム切替 :ランダム切替実行!\![change,ghost,random] *次のゴーストに切替 :次のゴーストに切替実行!\![change,ghost,sequential] *ほげほげに切替 :ほげほげに切替実行!\![change,ghost,ほげほげ]
まず最初の「ほげほげ導入済」は、「ほげほげ」というゴーストがインストールされている場合にのみ立たせたいフラグの名前です。
0を初期値として入れておいて、もし調べてもインストールされていなかったらフラグは降りている(けど変数は存在している)ようにしておきます。
ポイントになるのはinstalledghostnameというNOTIFYコマンドのSHIORI Eventです。
長くなるので、SHIORI Eventについて詳しく知りたい方は以下の記事をお読みください。
参考:
installedghostnameは、起動時などに発生し、ベースウェアにインストールされているゴースト名をリファレンスとして教えてくれるSHIORI Eventです。
まあ要は、*installedghostnameという文を用意して、その中で(R0)と書くと、インストールされているゴースト名その1、(R1)と書けばインストールされているゴースト名その2……といったように全てのゴースト名が[[(R*)>情報取得変数#l0da4eb8]に入っています。
後はそのゴースト名全部について、今探している「ほげほげ」というゴースト名と一致するものがあるかどうか調べたいですね。
文字列の比較も==でやればいいのですが、もしゴースト名が数字や+-のような演算子だけで構成されている場合、ゴースト名が計算されて変になったり、エラーになってしまう事があります。
そこで==の両辺をそれぞれ「[]」で囲います。このように前後を文字列で囲ってしまえば、両辺は数字ではなく文字列として扱ってよい事が明示されます。
|B1|という邪魔っ気なやつは里々特有の弱点が絡んだ記述なのですが、これもややこしい話なので詳しくは以下のページを参考に。
とりあえずはそういうものなんだと思って先に進んでしまっても構いません。
参考:
名前が一致すると、whenは真の場合の結果として(set,ほげほげ導入済,1)を実行し、導入済フラグが立ちます。
もし全ての名前を調べても一致する名前がなければ、フラグは立たないままです。
これが基本的な仕組みです。
ところがここで一つ困った事があります。
ユーザによってインストールされているゴーストの数は全然違うので、いったい何個(R*)を書いて比較すればいいのか解りません。
そこで登場するのがループ関数のtimesと、(Rの数)というR*が全部で何個あるか教えてくれる情報取得変数です。
これによって、R*があるだけ同じ処理を何度も繰り返してくれますから、何個書けばいいかは考えずに済みました。
利用例は、フラグが立っている場合のみメニューにそのゴーストへの切り替え項目を表示する例です。
里々のループ処理は重いので、インストールされているゴーストの数によっては目に見えて処理に時間がかかります。
どうしてもそれに耐えられない場合は、後述のプロパティシステムを使った方法も検討してみてください。
全インストール済みゴーストを記憶
*installedghostname $導入ゴーストリスト【タブ】 (set|B1|導入ゴーストリスト|B1| |B2| (times|B1|(Rの数)|B1| (R(C0))|B2| ) )
以下の関数を辞書のどこかに書いておく
@ゴースト導入済判定 (calc, (count |B1|(導入ゴーストリスト) |B1||B2|(A0)|B2| )>0 )
インストール済ゴーストのチェック例
*切り替えメニュー _ランダム切替 _次のゴーストに切替 (when、(call,ゴースト導入済判定,ほげほげ) 、\q[ほげほげに切替,ほげほげに切替] ) (when、(call,ゴースト導入済判定,ふがふが) 、\q[ふがふがに切替,ふがふがに切替] ) (when、(call,ゴースト導入済判定,ぴよぴよ) 、\q[ふがふがに切替,ぴよぴよに切替] ) *ランダム切替 :ランダム切替実行!\![change,ghost,random] *次のゴーストに切替 :次のゴーストに切替実行!\![change,ghost,sequential] *ほげほげに切替 :ほげほげに切替実行!\![change,ghost,ほげほげ] *ふがふがに切替 :ふがふがに切替実行!\![change,ghost,ふがふが] *ぴよぴよに切替 :ぴよぴよに切替実行!\![change,ghost,ぴよぴよ]
基本編と同じ部分は端折ります。
今回はループの中で、インストール済ゴーストの名前と目的の名前とを比較するのではなくて、インストール済ゴーストの名前を全部リストにして保存してしまいます。
なおその時にゴースト名の前後を「[byte2]ゴースト名1[byte2]ゴースト名2[byte2]ゴースト名3...」というように、必ずバイト値2で囲っています。
これは説明するととても長くなるので略しますが、予期せぬ不具合を防ぐために重要なので、よくわからなくても欠かさないでください。
こうして最初にリストを作っておいて、後でそのリストから特定のゴーストの名前があるかどうかを調べるわけです。
その調べるために使うのが「ゴースト導入済判定」というユーザ定義関数です。
ゴースト導入済判定内では、ssu.dllのcountという関数を使っています。
countは、ある文字列A中に含まれている文字列Bの数を数えてくれます。
これを利用すれば、導入ゴーストリストという文字列Aの中から目的のゴースト名という文字列Bを探してもらえそうですね*1。
なお今回は数と言うよりインストールされているかいないか(0か1か)が知りたいので、さらにcalcで0より大きいか否かの2値に変換しています。
SSP専用の手段です。 参考:
* \![get,property,ふがふが導入依存トーク,"ghostlist(ふがふが).name"] *ふがふが導入依存トーク :そういえば友達に「ふがふが」ってのがいてさー。 >ふがふが未導入トーク【タブ】(is_empty|B1|(R0)) え? インストールしてるの? じゃあそのうち会うこともあるかもね。 *ふがふが未導入トーク :ユーザは知らないかー。 よければインストールしてやってね。
起動中、SSPはインストールされているゴーストの情報(descript.txtに書かれている内容)などを把握しています。
そうでなければゴースト切り替えメニューにゴースト名を表示する事さえできません。
そうしたSSPが起動中に保持している情報(プロパティ)を、ゴーストから問い合わせて取得する方法が用意されています。
これをプロパティシステムと呼びます。
\![get,property,○○,××]
というさくらスクリプトのタグがこの問い合わせの方法です。
○○には「この後発生するイベント名」が入ります。
イベントってなんじゃという場合は、とりあえず「*○○」というトークを用意する必要があるんだなと思っておいてください。
なので上例ではすぐ下に「ふがふが導入依存トーク」というトークが準備されています。
××には「問い合わせの内容」が入ります。
色々ありますが、今は「ghostlist(☆☆).name」という物が入っています。
これは「☆☆」というゴーストのゴースト名を教えてください、という問い合わせです*2。
問い合わせの答えがどこでかえってくるかというと、○○というトークで(R0)と書くとその中に答えが入っています。
[[(R*)>情報取得変数#l0da4eb8]はNOTIFYイベントを使った方法でも出てきました。
さてここが肝ですが、もし問い合わせた☆☆という名前のゴーストがインストールされていない場合、(R0)は「からっぽ」で返って来ます。
そしてssu.dllにはis_emptyといって、引数がからっぽかどうかを判定する関数が用意されています(からっぽなら1、中身があれば0)。
従って、
>ふがふが未導入トーク【タブ】(is_empty|B1|(R0))
の行は結局、「問い合わせた『ふがふが』というゴーストがインストールされていなければ『ふがふが未導入トーク』にジャンプ」という意味になります。
これで、特定ゴーストがインストールされているかどうかで分岐が出来ました。
\![get,property,ふがふが導入依存トーク,ghostlist(ふがふが).name]の代わりに
\![get,property,シェルFOO存在依存トーク,"currentghost.shelllist(FOO).name"]とでもしてやれば、(is_empty|B1|(R0))は「FOO」という名前のシェルがインストールされていない場合に1、されている場合に0を返します。 これで特定シェルがインストールされているかどうかで分岐させられます。
\![get,property,バルーンBAR導入依存トーク,balloonlist(BAR).name]とでもしてやれば、(is_empty|B1|(R0))は「BAR」という名前のバルーンがインストールされていない場合に1、されている場合に0を返します。 これで特定のバルーンがインストールされているかどうかでも分岐させられます。
\![get,property,発生させるイベント名,○○]の○○部分で取得したい内容を色々かえられるので、ukadocを眺めながら試してみると色んな事ができるはずです。
\![get,property,略,ghostlist(ふがふが).name,balloonlist(BAR).name,ghostlist(ぴよぴよ).name]などと、複数の内容をいっぺんに取得することも出来ます。この場合、書いた順に「ghostlist(ふがふが).name」の返答は(R0)、「balloonlist(BAR).name」の返答は(R1)、「ghostlist(ぴよぴよ).name」の返答は(R2)に入っています。
結論:里々でもできるけどすごくめんどくさいので誰か何とかしてください
本来やってる事の「本質」はそう難しいことではありません。
NOTIFYイベントは、ベースウェアが知っている情報を教えてくれる機会を利用してインストール済かどうか判定しています。
プロパティシステムは、ベースウェアが知っている情報をこちらから問い合わせる仕組みを利用してインストール済かどうか判定しています。
しかしこのインストール済判定という課題は、里々というSHIORIにとってかなり不得意な分野の問題をたくさん含んでいます。
一つには、里々はループ処理が遅いために、不定数のReferenceをもつSHIORI Eventの処理をしにくいこと。
そしてもう一つは、里々は文字列処理が非常に苦手であり、特に他の作者のゴースト名やシェル名のような、あらかじめ内容を把握できない任意文字列を安全に処理するために、苦し紛れの曲芸が必要になってしまうことです*3。
そのような問題への対策のために、このページでは不要な行数をだいぶ費やした上に、なお容量を得ない説明がたびたび登場しています。
これらの問題をもっとスマートに解決する方法は……まあなんか……里々でこんなことをやらずにYAYAでも華和梨でも使うとか……。*4
誰かがSAORIを用意してくれるか、いっそ里々が機能を備えてくれるのを待ちましょう!→記事を書いたら1日でやってくださいました!