2013/12/22

通り抜けできるプリム

友達から質問が来て、「オブジェクトでリンクしてる一部のプリムだけファントムにしたいときどうすればいいの?」について調べてみました。

お風呂にリンクしている水の部分だけ通り抜けるようにしたいときとかですね。

通り抜けができる「ファントム」というのは、オブジェクト全体の性質みたいで、子プリムだけファントムとかはできません。
以前は、子プリムに仕込む裏技スクリプトがよく使われていたらしいですが、最近ではそれは必要ないそうです。
オブジェクト全体の「ファントム」とは別に、子プリムに次のような設定をします。

オブジェクトの「Edit(編集)」>「Edit linked parts(リンク部分を編集)」にチェックしてプリムを選び、「Features(特徴)」>「Physics Shape Type(実像の種類)」を「None(なし)」に設定。

これでそのプリムは通り抜けできるようになります。
ただしこの設定は子プリムだけで、親プリムにはできません。

(最近スクリプトネタがないな~
…実は上にちょっと書いた「裏技スクリプト」を紹介しようとして、よく調べたら、「もう必要なかった」のでした!><)

2013/11/18

範囲内に入った人をお知らせ

(写真に出ている名前はでたらめです^^)

レーダーでは、HUDの上の表示とは別に、チャット範囲に入った人、近く・遠くの範囲に入った人をお知らせする機能がありますが、人数の多いSIMでは、時々遠くの人で動いてないはずなのに、何回も「Long Range: 誰々」というお知らせが来ることがあります。

これは、センサーで検知する人数を制限しているためです。
制限人数以上にSIMに人がいると、近い順から調べて人数分の「範囲内の人」リストを作ります。
ここで、誰かが近くにテレポートして来ると、リストを更新して、1番遠かった人はリストから外れます。
そのあとで、今度は誰かがいなくなって人数が減ると、リスト更新のとき、さっき外れた人がまたリストに入るので、お知らせがくるというわけです。

制限人数をたくさんにしておけば、そういうことがなくなるはずですが、センサーで検知できる人数は最大16人なので、それより増やすことはできません。

制限人数を設定するには、チャットで「/3n 16」のようにタイプしてください。(「」内)
「/3n」だけなら、今の設定数を表示します。
また「/3」だけ打つと、ほかの設定方法を含め、簡単な説明を表示します。

2013/09/25

文字列のバイト数を数える

(消えてしまった1年前の記事の焼き直しです^^)
(写真に出ている名前はでたらめです^^)

フリーのレーダーのもうひとつの不満は、HUDの上の表示が長いと勝手に切れてしまうことでした。
遠くの人から表示するので、肝心のチャット範囲の人が表示されないこともあります。
そこでこのレーダーでは、近い人優先で文字数制限内に納まるようにしました。
文字数制限といってますが、実際にはバイト数で254バイトまでです。
英数字だけの名前なら文字数=バイト数なのですが、日本語などは1文字=3バイトだったりします。
「文字数」を数える llStringLength() 関数はありますが、「バイト数」を数える関数は?…
…ありましたね~^^
integer strlenB(string str){
  string esc = llEscapeURL(str);
  string wk = (string)llParseString2List(esc,["%"],[]);
  return llStringLength(wk) * 2 - llStringLength(esc);
}
…参考:「jinkoさんSL日記」
http://jinko.slmame.com/e602732.html
(ちょっと改造しています)

llEscapeURL() という関数がありまして、これは英数字以外の記号や日本語のような複数バイト文字の各バイトを「%xx」(xは0~9またはA~F)の形の文字列で置き換えます。
これで作った新しい文字列(上のスクリプトでesc)は
・英数字はそのまま(バイト数も変わらず)
・英数字以外のバイトは置き換わって、バイト数は2づつ増える(1バイト→3バイト)
・置き換わると「%xx」の形になるので、「%」の数=もとの英数字以外のバイト数
ここで「%」を数えるのですが、一気に llParseString2List() で「%」を区切り文字として捨てながらリストに分解、すぐつなぎ直して文字列(上のスクリプトでwk)にするという荒業を使います^^
これはescから「%」を抜くためで、もとの英数字以外のバイト数=escの長さ-wkの長さ、になります。
escの長さ=もとのバイト数+もとの英数字以外のバイト数×2(増えた分)、ですから、
もとのバイト数=escの長さ-(escの長さ-wkの長さ)×2=wkの長さ×2-escの長さ、というわけです。

これでバイト数を計算しながら、制限いっぱいまで表示する人を増やします。

2013/09/24

レーダーで表示名[本名]を表示

(消えてしまった1年前の記事の焼き直しです^^)

私の店で1番売れているのは、だれでも持っていそうな、ありふれた「レーダー」
まわりにいる人の名前と距離を教えてくれます。
それまで自分もフリーのを使ってましたが、ちょこちょこ不満もあるので、友だちの要望もあって、自作しました。
なので、使い勝手はそのフリーのとほとんど同じです。

不満の第一は、最近の「表示名」に対応してないこと、それと「Resident」だらけでうっとおしいことです。
スクリプトでは、表示名[本名]の形で表示し、「Resident」は省きます。
string agentName(key id) {
  string legacy=llKey2Name(id); // 本名
  list names=llParseString2List(legacy,[" "],[]);
  if (llList2String(names,1)=="Resident")
      legacy=llList2String(names,0); // Resident省く
  string display=llGetDisplayName(id);
  if (display==legacy||display==""||display=="???")
      return legacy; // 本名のみ表示
  else return display+"["+legacy+"]";
}
表示名が"???"とは、そういうケースもあるようなので、そんな場合は表示名をあきらめます。

このレーダーは、フリーに対抗して(^^)L$25 で売ってます:
SLマーケットプレイス
https://marketplace.secondlife.com/p/lovemax-RADAR-HUD-MyRadar/3959760
築地場外市場(SLurl)
http://slurl.com/secondlife/TSUKIJI/80/55/22/
LOVEHO Dmart(SLurl)
http://slurl.com/secondlife/LOVEHO/189/180/23/

2013/09/21

部外者を土地から追い出す!

友だちの依頼で作ったセキュリティシステムなんですが、部外者を追い出すとき、「土地」全体を調べてます。
(写真はイメージです(^^)

スクリプトはこんな感じ:
default { 
  state_entry() {
    llSetTimerEvent(Cycle);
  }
  timer() { // 一定時間ごとに
    list agents=llGetAgentList(
        AGENT_LIST_REGION,[]);
        // 土地にいる人を調べる
    key id;
    integer n=llGetListLength(agents);
    integer i=0;
    for(; i<n; ++i) {
      id=llList2Key(agents,i);
      if (id!=llGetOwner() && llSameGroup(id)==FALSE)
        llTeleportAgentHome(id); // 部外者はホームに強制送還
    }
  }
}
llGetAgentList() という関数で、センサーと違って距離の制限なしに、地上からはるか上空までどこにいても調べられます。
パラメーターの AGENT_LIST_REGION はSIM全体を調べるという指定で、このほか1区画だけ、オーナーが所有する区画全部、というような指定もできます。
[] には条件リストを入れるらしいですが、今はまだ準備中みたいです。

LlGetAgentList - Second Life Wiki

このセキュリティシステムの本体は、実はすご~~く強力で、設定も複雑になっちゃったので、一般には売り出してません(^^;
でもまあ、ご興味ある方には、個別にご相談に乗りますので、ご連絡ください。(^^)v

2013/09/19

スタッフボードからIM

スタッフボードは、タッチでスタッフとIMができるようにしてます。
でも実は、アバター同士のIMを直接開くスクリプト関数はないのです。
どうするかというと、ビューワーからIMを起動する方法があって、それを使います。
ビューワーで表示するメッセージ文中に「secondlife:///app/agent/(相手のキー)/im」があると、そこにリンクが張られて、クリックするとIMのウィンドウが開くのです。
公式ビューワーだとメニューの表示メッセージでこれができますが、できないビューワーもあるので、ボタンを用意して、メッセージのチャットログから開くようにします。

右の写真は、Firestorm ビューワーの画面で、メニューに「IM lovemax」というのが 「secondlife:///app/…」から置き換わって表示されています。(公式ビューワーも同様)
showMenu() { // メニューを出す
  OpenIM = "secondlife:///app/agent/" + (string)StaffId + "/im";
  list buttons = ["IM"];
  string message = "\nIM: 下線またはボタンをクリック"
      +" Click Underline or Button\n" + OpenIM;
  if (llGetInventoryNumber(INVENTORY_NOTECARD)) {
    Note = llGetInventoryName(INVENTORY_NOTECARD,0);
    buttons += ["Note"];
    message += "\nNote: ノートもらえます Get Note";
  }
  Handle = llListen(Channel,"",Id,"");
  llDialog(Id,message,buttons+["Cancel"],Channel);
}

default {
  touch_start(integer num) {
    Id = llDetectedKey(0); // タッチした人
    // (実際にはスタッフIDを調べてから)
    showMenu(); // メニューを出す
  }
  listen(integer ch,string na,key id,string msg) {
    if (msg=="IM") llInstantMessage(Id,
          "チャットログで下線をクリックしてください"
          +" Click Underline on Chat Log\n"+OpenIM);
    else if (msg=="Note") llGiveInventory(Id,Note);
    llListenRemove(Handle);
  }
}


左の写真は、Cool VL ビューワーの画面で、メニューの文字「secondlife:///app/…」はそのままです。
[IM]ボタンを押すとボードからメッセージが送られてきて、それをチャットログで見たのが右の写真です。
文字「secondlife:///app/…」のところにリンクがあり、クリックすれば、IMのウィンドウが開きます。

2013/09/18

簡単登録スタッフボード

友だちの依頼で作った「スタッフボード」です。
カフェとかによくある、チップを入れられるやつですね。
オンライン表示、ノートももらえて、IM連絡もできます。
一番気に入ってもらったのは、スタッフの登録が超簡単なことです。
未登録のボードに、スタッフがタッチするだけで、名前とIDとプロフの写真が登録されます。

登録部分のスクリプトはこんな感じ:
default { 
  touch_start(integer num) {
    if (llGetObjectName()
        !="Staff Board") return;
      // すでに名前が登録済みなら無視
    key id=llDetectedKey(0);
      // タッチした人
    if (llSameGroup(id)==FALSE) return;
      // スタッフでないなら無視
    llSetObjectName(llDetectedName(0)); // 名前をオブジェクト名に登録
    llSetObjectDesc((string)id); // IDをオブジェクト説明に登録
    llHTTPRequest("http://world.secondlife.com/resident/"
        +(string)id,[HTTP_METHOD,"GET"],"");
      // プロフの写真を設定するために問合せ
  }
  http_response(key query,integer status,list meta,string body) {
    // 問合せの応答
    string find="<meta name='imageid' content='";
      // 応答内容から特定の文字列を見つける
      // (「'」は実際には「"」で「\"」のように書く)
    integer head=llSubStringIndex(body,find)+llStringLength(find);
      // 画像IDの先頭
    string texture=llGetSubString(body,head,head+35);
      // 画像ID(35字)
    if ((key)texture) llSetTexture(texture,Face);
      // IDが有効ならそのテクスチャーを貼る
  }
}

プロフィール写真は、本人の了解なしに使うのは問題があるわけですが、この場合はスタッフ登録のときに了解があったということでOKにしましょう(^^)

参考にしたサンプルスクリプト:
http://wiki.secondlife.com/wiki/Get_Profile_Picture

このスタッフボードは、「MyStaffBoard」という名前で売ってます:
SLマーケットプレイス
https://marketplace.secondlife.com/p/lovemax-Online-Tip-Board-MyStaffBoard/5177159
築地場外市場(SLurl)
http://slurl.com/secondlife/TSUKIJI/80/55/22/
LOVEHO Dmart(SLurl)
http://slurl.com/secondlife/LOVEHO/189/180/23/

2013/09/17

小判ぎっしり千両箱

友だちの依頼で「千両箱」を作りました。
蓋にタッチすると、ギイッと開いて、中には小判がぎっしり!!
大きさはちゃんと「慶長小判」のサイズをもとにしてます。

スクリプトはこんな感じです:
default { 
  state_entry() { // 最初は閉じる
    Sound = llGetInventoryName(
        INVENTORY_SOUND,0); // 音
    if (Sound) llPlaySound(Sound,1.0);
    llSetLocalRot(ZERO_ROTATION);
  }
  touch_start(integer num) { // タッチ
    if (Open) llResetScript();
      // 開いてればリセットで閉じる
    else { // 閉じてれば開く
      if (Sound) llPlaySound(Sound,1.0);
      llSetLocalRot(llEuler2Rot(DEG_TO_RAD*Angle)); 
      Open = TRUE;
      llSetTimerEvent(TimeOut); // 時間切れ設定
    }
  }
  timer() {
    llResetScript(); // 時間切れリセットで閉じる
  }
}
蓋のプリムは、回転するところが蝶番になるように、1/4にカットしてあります。

お札の詰まったジュラルミンケースも頼まれました。
1万円札で3億円分入る大きさにしました。

中身のテクスチャーを作ろうとしたら、いきなり画像加工ソフトに、「お札の画像を編集しちゃだめ」と怒られてびっくり。
ちゃんと見張ってるひとがいるんですね~(^^;

2013/09/16

引越先から戻ってきました

引越先から戻ってきました。
引越先のブログのシステムが調子悪いとかで、表示されず、しかも回復の見込みが立ってないそうなのです。
前も一度全部データが消えてしまったこともあったし…(TT)。

で、引越した理由というのが、単に、スクリプトをきれいに表示できる、ということだけでした。
そこで、このブログにも同じような方法があるかも、と思って調べたら…
ありましたね~。
「Code Prettify」というのを使うんだそうです。
しかもこれを自動的に設定できるプログラムを作られた方もいて、設定は本当に簡単です。

コードをハイライトする「Code Prettify」ウィジェット

これを使って設定し、「むふふなHUD(2012/06/16)」の記事のスクリプトの部分を書き換えてみました。
その前の記事「むふふな変身」は前のままなので、比べてみると、どう違うがかわかります。