スクリプト:ジグソーパズルGiver
イベントの開催期間内だけ、オブジェクトをタッチした人に、中身の1個のアイテムを渡すだけのスクリプトです。
integer gOpen = 1709391600; integer gClose = 1711954800; string gItemName = "Saitama Metro 3rd Jigsaw 23.G18"; integer PeriodCheck() { integer Period; integer Time = llGetUnixTime(); return (gClose<Time)-(Time<gOpen); } default { touch_start(integer total_number) { integer P = PeriodCheck(); key Clctr = llDetectedKey(0); if (P<0){ llRegionSayTo(Clctr,0,"イベントは3月3日開始です。しばらくお待ちください。\nThis event has not started yet, will start on March 3rd."); } else if (P>0){ llSetText("イベントは終了しました。\n \nThis event period\nwas finished.",<1,1,1>,1); state ended; } else { llGiveInventory(Clctr,gItemName); } } } state ended { state_entry() { } }
記述内容の解説
グローバル変数
integer gOpen = 1709391600; integer gClose = 1711954800; string gItemName = "Saitama Metro 3rd Jigsaw 23.G18";
イベントの開始時間と終了時間のUNIX時間、渡すアイテム名です。
ユーザ定義関数
integer PeriodCheck() { integer Period; integer Time = llGetUnixTime(); return (gClose<Time)-(Time<gOpen); }
関数が呼び出された瞬間のUNIX時間を取得して、開始時間、終了時間と比較して、開催期間かどうかを判定する関数です。
比較演算子の計算結果は、LSLでは、TRUE(真)が1、FALSE(偽)が0です(他のプログラミング言語ではTRUEが-1のことがありますがLSLでは1です)。そのため、(gClose<Time)-(Time<gOpen) という式のふるまいを見ますと、開始時間より前なら、式の前半がFALSE、後半がTRUEなので、式全体では0-1で-1です。開始時間と終了時間の間なら、どちらもFALSEですから0です。終了時間より後なら、前半がTRUE、後半がFALSEなので、式全体では1-0で1になります。この関数は、この数値を返すものです。
integer変数Periodが宣言されていますが、よく見ると使っていませんでした。
defaultステート
スクリプトの起動時には何も処理させる必要がないため、state_entry()はありません。
default {
touch_startイベント
touch_start(integer total_number) {
touch_startはオブジェクトに誰かがタッチした瞬間に発生するイベントです。total_numberにはその瞬間にタッチしていたアバターの数が格納されますが、そんな偶然めったにないので、通常は1が入ると理解していますし、このイベント内でこの数値を利用することはないでしょう。
integer P = PeriodCheck();
ユーザ定義関数を呼び出してイベントの開催中かどうかを判定してinteger変数Pに格納しています。
key Clctr = llDetectedKey(0);
タッチしたアバターのkey=UUIDを取得して、key変数Clctrに格納しています。llDetectedKey の引数は、同時に検知したn-1人目のアバターという意味なのですが、2人以上になることはまず考えられないので、通常、0を使うのがお約束のようです。もし2人が全くの同時にタッチするという偶然が起こって、どちらか片方のアバターに対しての動作をしなかったとしても、普通、その人はもう1回タッチし直してくれると思います。
if (P<0){ llRegionSayTo(Clctr,0,"イベントは3月3日開始です。しばらくお待ちください。\nThis event has not started yet, will start on March 3rd."); }
変数Pが負の数のとき、つまり開催前であれば、タッチしたアバターにその旨のメッセージを伝えます。llRegionSayTo は、オブジェクトからオープンチャットには流れてくるものの自分にしか見えないメッセージを目にすることも多いと思いますが、それを実現する関数です。llSayだとその場にいる全員に聞こえてしまいます。
else if (P>0){ llSetText("イベントは終了しました。\n \nThis event period\nwas finished.",<1,1,1>,1); state ended; }
変数Pが負の数でなく、正の数のとき、つまり終了後であれば、その旨をフローティングテキストとして表示し、スクリプトの処理はこのdefaultステートから、ユーザ定義のendedステートに遷移します。
else { llGiveInventory(Clctr,gItemName); }
変数Pが負の数でなく、正の数でないとき、つまり開催中であれば、タッチしたアバターにアイテムを渡します。アイテム名が間違っていた場合やなかった場合はエラーになります。
}
touch_startイベント終わり。
}
defaultステート終わり。
endedステート
スクリプトの終了をさせるためにユーザ定義したステートです。
このステートに遷移すると何も動作をしなくなります。スクリプトを終了させるには、スクリプト自身を削除する方法もありますが、動作テストのたびに削除されるのも面倒なのでこの方法を取っています。
state ended { state_entry() { } }
スクリプト終わり。