ベースウェア(SSPなど)に特定のゴーストやシェルやバルーンがインストールされているかどうかを調べる方法の説明です。~
ここにあるような方法で調べておけば、たとえば特定のゴーストがいる場合にだけそのゴーストを呼び出す選択肢を表示するとか、イベントを起こすとか、そういう仕組みに使えます。~
なおこのページにある内容には''SSP専用''のものがあります。~
~
----
#contents
----
~
*里々バージョンMc155-1以降の場合 [#c24a8e53]
[[情報取得変数>情報取得変数#yc9319e3]]で、カッコ1つで取得できます。~
「[[$NOTIFYの自動保存>特殊変数#qe216ebc]]」を有効にするのを忘れずに行ってください。~
~
''&color(#0000ff){以下の情報は里々Mc154-1以前を対象とした情報です。里々Mc155-1以降は上記の情報取得変数を利用するのが、この目的のためにもっとも容易かつ安全な方法です。};''
*事前準備 [#b96748b2]
まず最初に、以下の説明で「[[バイト値>内部関数#c2695bea]]」というものを多用します。~
これはゴースト名などの「どんな文字が入ってるか分からない文字列」を里々で安全に扱うためには、どうしても必要になります。~
なのでよくわからないかもしれませんが''[[replace.txt>ファイル構成#sb0ae987]]に以下をコピペ''してください。~
何も見えないと思いますが、''タブ文字やバイト値1と2が隠れているのでそのままコピペ''推奨です。~
 |B1|	
 |B2|	
*NOTIFYイベントを使う・基本編 [#f39b3ef6]
参考:
- [[ukadoc「SHIORI Event」>http://ssp.shillest.net/ukadoc/manual/list_shiori_event.html]](外部サイト)

**サンプル [#k4c579b8]
「ほげほげ」というゴーストがインストールされている事を確認
 *installedghostname
 $ほげほげ導入済【タブ】0
 (times,(Rの数),
   (when|B1|[(R(C0))]==[ほげほげ]
     |B1|(set,ほげほげ導入済,1)
   )
 )
↑で立てたフラグを利用する例
 *切り替えメニュー
 :φ
 _ランダム切替
 _次のゴーストに切替
 (when、(ほげほげ導入済)、\q[ほげほげに切替,ほげほげに切替])
 *ランダム切替
 :ランダム切替実行!\![change,ghost,random]
 *次のゴーストに切替
 :次のゴーストに切替実行!\![change,ghost,sequential]
 *ほげほげに切替
 :ほげほげに切替実行!\![change,ghost,ほげほげ]

**解説 [#rd108346]
まず最初の「ほげほげ導入済」は、「ほげほげ」というゴーストがインストールされている場合にのみ立たせたいフラグの名前です。~
0を初期値として入れておいて、もし調べてもインストールされていなかったらフラグは降りている(けど変数は存在している)ようにしておきます。~
~
ポイントになるのは[[installedghostname>http://ssp.shillest.net/ukadoc/manual/list_shiori_event.html#installedghostname]]というNOTIFYコマンドのSHIORI Eventです。~
長くなるので、SHIORI Eventについて詳しく知りたい方は以下の記事をお読みください。~
参考:
- [[栞としての里々>栞としての里々#gc01536d]]
- [[ukadoc「補足:SHIORI Eventとは」>http://ssp.shillest.net/ukadoc/manual/memo_shiorievent.html]](外部サイト)

~
installedghostnameは、起動時などに発生し、ベースウェアにインストールされているゴースト名をリファレンスとして教えてくれるSHIORI Eventです。~
まあ要は、*installedghostnameという文を用意して、その中で(R0)と書くと、インストールされているゴースト名その1、(R1)と書けばインストールされているゴースト名その2……といったように全てのゴースト名が[[(R*)>情報取得変数#l0da4eb8]に入っています。~
後はそのゴースト名全部について、今探している「ほげほげ」というゴースト名と一致するものがあるかどうか調べたいですね。~
~
文字列の比較も==でやればいいのですが、もしゴースト名が数字や+-のような演算子だけで構成されている場合、ゴースト名が計算されて変になったり、エラーになってしまう事があります。~
そこで==の両辺をそれぞれ「[]」で囲います。このように前後を文字列で囲ってしまえば、両辺は数字ではなく文字列として扱ってよい事が明示されます。~
~
|B1|という邪魔っ気なやつは里々特有の弱点が絡んだ記述なのですが、これもややこしい話なので詳しくは以下のページを参考に。~
とりあえずはそういうものなんだと思って先に進んでしまっても構いません。~
参考:
- [[引数区切り文字問題>関数#wbedea1a]]
- [[when,times,while,forでバイト値を引数区切り文字にする場合の注意>関数#ebbcd3ea]]

~
名前が一致すると、[[when>内部関数#c8fbcc67]]は真の場合の結果として[[(set,ほげほげ導入済,1)>内部関数#v0928166]]を実行し、導入済フラグが立ちます。~
もし全ての名前を調べても一致する名前がなければ、フラグは立たないままです。~
これが基本的な仕組みです。~
~
ところがここで一つ困った事があります。~
ユーザによってインストールされているゴーストの数は全然違うので、いったい何個(R*)を書いて比較すればいいのか解りません。~
そこで登場するのがループ関数の[[times>内部関数#ad356074]]と、[[(Rの数)>情報取得変数#ge7589c6]]というR*が全部で何個あるか教えてくれる情報取得変数です。~
これによって、R*があるだけ同じ処理を何度も繰り返してくれますから、何個書けばいいかは考えずに済みました。~
~
利用例は、フラグが立っている場合のみメニューにそのゴーストへの切り替え項目を表示する例です。~

**補足 [#i0bcafcc]
- もしゴースト起動中に新たにゴーストがインストールされたり、削除された場合、その都度installedghostnameが発生しますので、情報は基本的には常に最新の状態であると考えてよいです。
- installedghostnameの代わりに[[installedshellname>http://ssp.shillest.net/ukadoc/manual/list_shiori_event.html#installedshellname]]ならあなたのゴーストにインストールされているシェルのリスト、[[installedballoonname>http://ssp.shillest.net/ukadoc/manual/list_shiori_event.html#installedballoonname]]ならSSPにインストールされているバルーンのリストが(R*)に入っています。~
基本的なスクリプトは変わりません。文の名前だけそれぞれ*installedshellnameなどとします。~
変数名も「シェルほげげ導入済」などと、自分で解りやすく工夫してみてください。~
※シェル、バルーンはMATERIAだと動きません。

**長所と短所 [#ocdc57ff]
:長所|
比較的簡単だし記述も短いし利用もシンプル。
:短所|
ユーザの環境(特にインストールされているゴーストの総数)によっては起動などに時間がかかるようになる。~
インストール確認の対象とするゴースト数が増えるたびにinstalledghostnameの書き換えが必要な上、数が増えるほど処理時間も比例して延びる。

里々のループ処理は重いので、インストールされているゴーストの数によっては目に見えて処理に時間がかかります。~
どうしてもそれに耐えられない場合は、後述のプロパティシステムを使った方法も検討してみてください。





*NOTIFYイベントを使う・応用編 [#fae7c5a5]
**サンプル [#yc758d58]
全インストール済みゴーストを記憶
 *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,ぴよぴよ]

**解説 [#sce19a89]
基本編と同じ部分は端折ります。~
~
今回はループの中で、インストール済ゴーストの名前と目的の名前とを比較するのではなくて、''インストール済ゴーストの名前を全部リストにして保存''してしまいます。~
なおその時にゴースト名の前後を「[byte2]ゴースト名1[byte2]ゴースト名2[byte2]ゴースト名3...」というように、必ずバイト値2で囲っています。~
これは説明するととても長くなるので略しますが、予期せぬ不具合を防ぐために重要なので、よくわからなくても欠かさないでください。~
~
こうして最初にリストを作っておいて、後でそのリストから特定のゴーストの名前があるかどうかを調べるわけです。~
その調べるために使うのが「ゴースト導入済判定」という[[ユーザ定義関数>call関数]]です。~
ゴースト導入済判定内では、ssu.dllの[[count>外部関数/ssu#f2d7afd3]]という関数を使っています。~
countは、ある文字列A中に含まれている文字列Bの数を数えてくれます。~
これを利用すれば、導入ゴーストリストという文字列Aの中から目的のゴースト名という文字列Bを探してもらえそうですね((厳密には[byte2]ゴースト名[byte2]と言う文字列を探していますが、これには不幸な偶然を避ける意味があります。一つは文字列に含まれる部分文字列がたまたま探している文字列と一致するケース(例ゴースト「さくら」を探している時に「あさくら」というゴーストがインストールされていたために「さくら」が検出される)、もう一つは文字列の並びによって偶然生じた部分文字列(たとえば「ゆかりさん」と「じゅうななさい」を並べると「さんじゅうなな」が取り出せるように)がたまたま探している文字列と一致するケースの、二つのケースを回避するために、全ての項目を「文字列中に出現しないことが期待される文字=バイト値」で囲ってしまうことで安全を確保しています。))。~
なお今回は数と言うよりインストールされているかいないか(0か1か)が知りたいので、さらに[[calc>外部関数/ssu#q39c9268]]で0より大きいか否かの2値に変換しています。

**長所と短所 [#u9c49a6f]
:長所|
インストールを確認したい対象を後から増やしたい場合も、installedghostnameは二度といじらなくてよい。~
増やしたからといって処理時間も増えない。
:短所|
里々でループを回すのでやっぱり処理に時間がかかる。~
保存した情報の利用にcallによる関数呼び出しが必要なので不慣れだと戸惑う?~





*プロパティシステムを使う [#kfc04b0a]
SSP専用の手段です。
参考:
- [[プロパティシステム]]
- [[ukadoc「プロパティシステム」>http://ssp.shillest.net/ukadoc/manual/list_propertysystem.html]](外部サイト)

**サンプル [#xa528b5a]
 *
 \![get,property,ふがふが導入依存トーク,"ghostlist(ふがふが).name"]
 
 *ふがふが導入依存トーク
 :そういえば友達に「ふがふが」ってのがいてさー。
 >ふがふが未導入トーク【タブ】(is_empty|B1|(R0))
 え? インストールしてるの?
 じゃあそのうち会うこともあるかもね。
 
 *ふがふが未導入トーク
 :ユーザは知らないかー。
 よければインストールしてやってね。
**解説 [#c5074abe]
起動中、SSPはインストールされているゴーストの情報(descript.txtに書かれている内容)などを把握しています。~
そうでなければゴースト切り替えメニューにゴースト名を表示する事さえできません。~
~
そうしたSSPが起動中に保持している情報(プロパティ)を、ゴーストから問い合わせて取得する方法が用意されています。~
これをプロパティシステムと呼びます。~

~
 \![get,property,○○,××]
というさくらスクリプトのタグがこの問い合わせの方法です。~
~
○○には「この後発生するイベント名」が入ります。~
イベントってなんじゃという場合は、とりあえず「*○○」というトークを用意する必要があるんだなと思っておいてください。~
なので上例ではすぐ下に「ふがふが導入依存トーク」というトークが準備されています。~
~
××には「問い合わせの内容」が入ります。~
色々ありますが、今は「ghostlist(☆☆).name」という物が入っています。
これは「☆☆」というゴーストのゴースト名を教えてください、という問い合わせです((そもそも☆☆にゴースト名書いてるのにそのゴースト名教えろってなんじゃと思われるかもしれませんが、本来はこれで「name」の部分を「sakuraname」と書くと本体側のキャラクター名がわかったり、「path」と書くとフォルダパスがわかったりします。また☆☆の側に本体側キャラクター名をいれて、ゴースト名を聞く事もできます。))。
~
問い合わせの答えがどこでかえってくるかというと、○○というトークで(R0)と書くとその中に答えが入っています。~
[[(R*)>情報取得変数#l0da4eb8]はNOTIFYイベントを使った方法でも出てきました。~
~
さてここが肝ですが、もし問い合わせた☆☆という名前のゴーストがインストールされていない場合、(R0)は「からっぽ」で返って来ます。~
そしてssu.dllには[[is_empty>外部関数/ssu#x9343bf4]]といって、引数がからっぽかどうかを判定する関数が用意されています(からっぽなら1、中身があれば0)。~
従って、
 >ふがふが未導入トーク【タブ】(is_empty|B1|(R0))
の行は結局、「問い合わせた『ふがふが』というゴーストがインストールされていなければ『ふがふが未導入トーク』にジャンプ」という意味になります。~
これで、特定ゴーストがインストールされているかどうかで分岐が出来ました。~

**補足 [#g5d06697]
- もし上例で
 \![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>http://ssp.shillest.net/ukadoc/manual/list_propertysystem.html]]を眺めながら試してみると色んな事ができるはずです。
- ちなみに
 \![get,property,略,ghostlist(ふがふが).name,balloonlist(BAR).name,ghostlist(ぴよぴよ).name]
などと、複数の内容をいっぺんに取得することも出来ます。この場合、書いた順に「ghostlist(ふがふが).name」の返答は(R0)、「balloonlist(BAR).name」の返答は(R1)、「ghostlist(ぴよぴよ).name」の返答は(R2)に入っています。~
それぞれ(is_empty|B1|(R1))などとすれば、存在しているかどうか確かめられるのも同じです。
**長所と短所 [#d30ceb77]
:長所|
SSPにゴースト名の検索を任せられるので処理が速い。~
:短所|
一度SHIORI Eventを発生させる必要があるので、処理の流れが複雑になりがちる。~
多くの場所で似たような事をたくさんやる場合に何度も同じような事をやるのが面倒くさい。





*まとめ [#j038f69e]
''結論:里々でもできるけどすごくめんどくさいので誰か何とかしてください''~
~
本来やってる事の「本質」はそう難しいことではありません。~
NOTIFYイベントは、ベースウェアが知っている情報を教えてくれる機会を利用してインストール済かどうか判定しています。~
プロパティシステムは、ベースウェアが知っている情報をこちらから問い合わせる仕組みを利用してインストール済かどうか判定しています。~
~
しかしこのインストール済判定という課題は、里々というSHIORIにとってかなり不得意な分野の問題をたくさん含んでいます。~
一つには、里々はループ処理が遅いために、不定数のReferenceをもつSHIORI Eventの処理をしにくいこと。~
そしてもう一つは、里々は文字列処理が非常に苦手であり、特に他の作者のゴースト名やシェル名のような、''あらかじめ内容を把握できない任意文字列''を''安全に処理する''ために、苦し紛れの''曲芸''が必要になってしまうことです((具体的にいえば、文字列と引数区切り字や演算子のようなものの区別がつかないし、それどころか数値との区別もつけ難いし、配列がないからリストも単なる文字列として扱うはめになってセパレータと普通の文字列の区別を考えないといけないし……といった問題の解決に「普通の文字列中に出現しない事が期待される文字」としてバイト値を用い、しかもそれがwhenやtimesなどの区切り値として出現する場合は、括弧で(バイト値、1)などと呼び出すと不具合がおきるために、即値として書かれる必要がある、など。))。~
そのような問題への対策のために、このページでは不要な行数をだいぶ費やした上に、なお容量を得ない説明がたびたび登場しています。~
~
これらの問題をもっとスマートに解決する方法は……&size(12){まあなんか……};&size(10){里々でこんなことをやらずにYAYAでも華和梨でも使うとか……。};((里々ディスではなくて、どのSHIORIにも得手不得手がありますが、インストール状況の判定には里々の苦手が濃縮されてるんです……。))~
誰かがSAORIを用意してくれるか、%%いっそ里々が機能を備えてくれるのを待ちましょう!%%→記事を書いたら1日でやってくださいました!~

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS