MasterPoppy

  • MasterPoppy さんがサイト「Mad Scripter's Lab @ inspi」で新しい投稿「LSL-Web App…HTMLでHUDを開発する(2/3)」を公開しました。 8か月前

    このエントリーはセカンドライフ技術系 Advent Calendar 2016の参加記事です。

    前回に引き続き、HTMLでHUDを開発す[…]

  • MasterPoppy さんがサイト「Mad Scripter's Lab @ inspi」で新しい投稿「LSL-Web App…HTMLでHUDを開発する(1/3)」を公開しました。 8か月前

    年末好例 セカンドライフ技術系 Advent Calendar 2016 の季節ですね。
    今年は連載で新しいネタを投下します。 今日の記事は前座です。
    なぜ今HUDをHTMLで作るか?
    従来HUDというとノーマルプリムやMeshで組み立ててllSetColorで色を変えたり、[…]

  • この記事は セカンドライフ 技術系 Advent Calendar 2015 の参加記事です。

    LSLでの開発にちょっと慣れてきた方向けに、少し高度な内容をご紹介します。
    と、言いつつ今回は簡単めです。

    メインランドなど他のセカンドライフ住人と接する機会の多いSIMにお住まいの場合、普段居住するSkyboxにちょっとマナーの悪い方が勝手に立ち入ったりして不快な思いをしたことのある方も多いかとおもいます。そういったケースの対策用として、Skybox用の防犯策としてSecurity Orb, ●● Security Systemといった名称で多くのスクリプト製品がMarcketPlaceなどで販売されており、利用されているからも多いかと思います。
    市販のものも様々な方式がありますが、今回はこのSkybox用のセキュリティをシンプルな発想で実装したスクリプトを2つ紹介します。
    1.落っこちるやつ

    [lsl]
    //*************************
    //collision phantom
    //2015-12-22 MasterPoppy
    //*************************

    default
    {
    state_entry()
    {
    llSetStatus(STATUS_PHANTOM, FALSE);
    }

    collision_start(integer index)
    {
    key av = llDetectedKey(0);
    if(!llSameGroup(av)
    && av !=llGetOwner()
    ) {
    llSetStatus(STATUS_PHANTOM, TRUE);
    state gotru;
    }
    }
    }

    state gothru
    {
    state_entry()
    {
    llSleep(5.0);
    state default;
    }
    }
    [/lsl]

    スクリプトのコードはこれだけです。使い方はスクリプトをスカイボックスの床に入れるだけ。
    動作原理は簡単で、床の上に立った時、対象のアバターがオーナーでもグループメンバーでもなければ床が抜けて(ファントムになって)落っこちます。当然、同じプリムの上に立っていると自分や招待している友だちも一緒に落ちてしまうので、

    招待する友だちは全員自分のグループに招待して、遊びに来るときはグループタグをアクティブにしてもらう。
    家にいる時は極力椅子に座る
    床は10m✕10mないし5m✕5m程度に区切る

    など運用上の制約が出てしまいますが、機能としてはこれで十分満たしています。
    このスクリプトを試してもらった友人によると、招かれざる客人が入ってくるや否やスットンと落ちていく様はこの上なく滑稽だそうです。
    ちょっとしつこい人でも床に立てなければ大抵は諦めるだろうという考えがこのスクリプトの肝であります。
    なお、このスクリプトには土地の所有権など運用上の制約はありません。
    2.吹っ飛ぶやつ

    [lsl]
    //*************************
    //Collision Ejecter
    //2015-12-22 MasterPoppy
    //*************************

    default
    {
    collision_start(integer index)
    {
    key av = llDetectedKey(0);
    if(!llSameGroup(av)
    && av !=llGetOwner()
    ) {
    llEjectFromLand(av);
    }
    }
    }
    [/lsl]

    使い方はスクリプトをスカイボックスの外壁または屋根に入れるのが効果的かと思います。
    メンバーのチェック方式はさきほどの1.同じで、オーナーまたはグループメンバーであること。
    こちらはシンプルに土地(parcel)の外へと放り出します。下に落とすだけの1.よりは強気な方法です。試すと分かりますが結構ぶっとびます。
    なお、対応が強力なことのトレードオフではないですが、注意点として自分の土地でないと動作しないので注意して下さい。グループ譲渡(deeded to a group)された土地の場合はスクリプトを入れたObjectもグループに譲渡する必要があります。つまり、グループ譲渡ではない大家さん名義の土地でREZ権限だけをもらうタイプのレンタルスカイボックスなどでは利用できません。
    http://wiki.secondlife.com/wiki/LlEjectFromLand#Ownership_Limitations

    今回紹介したスクリプトは2つともSkyboxに対象のアバターが接触したときに作動するものです。TimerやSensor Repeatで常時スキャンするスクリプトのように普段設置しているときの負荷は基本的にないし、アクセス許可のノートカードを都度管理する煩わしさはありません。ただし、セキュリティとしてそれなり実用的ではありますが、土地への侵入そのものは(少なくとも1回めは)を防ぐことはできません。立てなく・入れなくすることで 諦めさせる という思想のセキュリティですので、特性と用途を十分にご理解頂いてご参考いただければと思います。

    【備考と免責】

    今回のサンプルスクリプトは例によってPublic Licenseです。ご自由にお使いください。
    セキュリティ用として紹介していますが、本スクリプトを使用したことによって発生したトラブルへの責任は負いません。
    特にグループタグが必要である旨のお友だちへのご説明はお忘れなきよう。

    質問・バグ報告などはお気軽にIMください https://my.secondlife.com/ja/masterpoppy.amat#about_tab

    (本スクリプトのアイデアを提供し、公開の許可を頂いたA氏にこの場を借りてお礼申し上げます。)

  • この記事は セカンドライフ 技術系 Advent Calendar 2015 の参加記事です。

    LSLでの開発にちょっと慣れてきた方向けに、少し高度な内容をご紹介します。

    今回のお題は「分配機能付きアニメーションベンダー」です。

    このツールには最低限以下の3つの機能が必要です。

    SITするとユーザにアニメーション(またはポーズ)をさせる。(llStartAnimation,llStopAnimation)
    PAYを受けたら商品を渡す。(llGiveInventory)
    第三者に売上を分配する。(llGiveMoneyまたはllTransferLindenDollars)

    このうちアニメーションと売上の分配を行うには llRequestPermissions で PERMISSION_TRIGGER_ANIMATION と PERMISSION_DEBIT の Permission を取る必要がありますが、ここで問題が発生します。
    まずは1つのスクリプトで2つの Permission を扱うようにスクリプトを書いてみます。

    [lsl]
    //分配機能付きのアニメーションベンダー
    //これは正常に動作しないスクリプトです
    // ******************************************
    // animation vender with share-out (mistaken)
    // 2015-12-09 MasterPoppy
    // ******************************************
    //【設定】
    // 価格 [L$]
    integer value = 100;
    // 分配先アバターのUUID
    key shareto = “72c03405-8305-48d9-ad18-f512f9db67f9”;
    // 分配率 [%]
    float rate = 5.0;
    // 座る位置 [m]
    vector sit_pos = ;
    // 座る角度 [degree]
    vector sit_rot = ;
    // ************************************

    key owner;
    string animation_name; // 実行するアニメーション
    key siton = NULL_KEY; // 現在座っている人のUUIDを管理する変数

    default
    {
    state_entry()
    {
    //初期化処理
    key av = llAvatarOnSitTarget();
    if(av != NULL_KEY){
    llUnSit(av);
    }
    llSetPayPrice(PAY_HIDE, [PAY_HIDE ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    llSitTarget(ZERO_VECTOR, ZERO_ROTATION);
    owner = llGetOwner();
    llSetText(“タッチしてDEBIT権限を許可してください”, , 1.0);
    }

    touch_end(integer total_number)
    {
    if(llDetectedKey(0) == owner){
    llRequestPermissions(owner,PERMISSION_DEBIT);;
    }
    }

    run_time_permissions(integer permissions)
    {
    if(PERMISSION_DEBIT & permissions){
    llSetText(“”, , 1.0);
    llOwnerSay(llGetInventoryName(INVENTORY_ANIMATION,0)+”をL$”+(string)value+”で販売開始”);
    state active;
    }
    }
    }

    state active
    {
    state_entry()
    {
    llSitTarget(sit_pos, llEuler2Rot(sit_rot * DEG_TO_RAD));
    llSetPayPrice(PAY_HIDE, [value ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key giver, integer amount)
    {
    if(amount==value) {
    //商品をわたす
    llGiveInventory(giver,animation_name);
    //お礼をいう
    llRegionSayTo(giver, 0, “Thank you for your purchase!”);
    //分配金を送金する
    llTransferLindenDollars(shareto,llRound(0.01*rate*(float)value));
    }
    }

    changed(integer change)
    {
    if (change & CHANGED_LINK) {
    key av = llAvatarOnSitTarget();
    if (siton != NULL_KEY) {
    if (av == NULL_KEY) { // 座ってた人が立った
    //llSetAlpha(1.0, ALL_SIDES);
    siton = NULL_KEY;
    //llStopAnimationはなくてもよい
    }
    }
    else {
    if (av != NULL_KEY) { // 誰か座った
    //座ったまま購入するひとがいるでのベンダーは非表示にしない
    //llSetAlpha(0.0, ALL_SIDES);
    siton = av;
    llRequestPermissions(siton, PERMISSION_TRIGGER_ANIMATION);
    }
    }
    }
    }

    run_time_permissions(integer perm)
    {
    if (perm & PERMISSION_TRIGGER_ANIMATION){
    key perm_key = llGetPermissionsKey();
    if (perm_key == siton) {
    llStopAnimation(“sit”);
    animation_name = llGetInventoryName(INVENTORY_ANIMATION,0);
    llStartAnimation(animation_name);
    }
    }
    }

    on_rez(integer start_param)
    {
    llResetScript();
    }
    }
    [/lsl]

    このままでも正常にコンパイルされ、DEBIT権限も取得できるので一見すると正しいように思えますが、ユーザーがSITしてしてもANIMATIONが再生されません。
    これにタッチやキー操作で同時に販売している別のアニメに切り替える処理などを追加するとScript trying to trigger animations but PERMISSION_TRIGGER_ANIMATION permission not setのエラがー出力されます。
    原因はオーナーから DEBIT パーミッションを取得している場合は、他人へのパーミッション要求はエラー表示も何も無く失敗するという仕様?によるものです。
    元々1つのスクリプトでは同時に複数のアバターのパーミッションを保持できないので、下記に示すサンプルのように2つに分割する必要があるのですが、このエラーが出ないという暗黙の仕様により気が付きにくなっています。
    参考:スクリプターズカフェ/ログ 2008/05/31
    正しくは、ANIMATIONまたはDEBITの処理をもう1つ別のスクリプトに分割する必要があります。

    [lsl]
    //分配機能付きのアニメーションベンダー(メインスクリプト)
    // ***************************************
    // animation vender with share-out (main)
    // 2015-12-09 MasterPoppy
    // ***************************************
    //【設定】
    // 価格 [L$]
    integer value = 100;
    // 分配先アバターのUUID
    key shareto = “72c03405-8305-48d9-ad18-f512f9db67f9”;
    // 分配率 [%]
    float rate = 5.0;
    // 座る位置 [m]
    vector sit_pos = ;
    // 座る角度 [degree]
    vector sit_rot = ;
    // ************************************

    key owner;
    string animation_name; // 実行するアニメーション
    key siton = NULL_KEY; // 現在座っている人のUUIDを管理する変数

    default
    {
    state_entry()
    {
    //初期化処理
    key av = llAvatarOnSitTarget();
    if(av != NULL_KEY){
    llUnSit(av);
    }
    llSetPayPrice(PAY_HIDE, [PAY_HIDE ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    llSitTarget(ZERO_VECTOR, ZERO_ROTATION);
    owner = llGetOwner();
    llSetText(“タッチしてDEBIT権限を許可してください”, , 1.0);
    }

    touch_end(integer total_number)
    {
    if(llDetectedKey(0) == owner){
    llMessageLinked(LINK_THIS, 0, “perm”, owner);
    }
    }

    link_message(integer sender_num, integer permissions, string str, key id)
    {
    if(str == “permed” && (PERMISSION_DEBIT & permissions)){
    llSetText(“”, , 1.0);
    llOwnerSay(llGetInventoryName(INVENTORY_ANIMATION,0)+”をL$”+(string)value+”で販売開始”);
    state active;
    }
    }
    }

    state active
    {
    state_entry()
    {
    llSitTarget(sit_pos, llEuler2Rot(sit_rot * DEG_TO_RAD));
    llSetPayPrice(PAY_HIDE, [value ,PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key giver, integer amount)
    {
    if(amount==value) {
    //商品をわたす
    llGiveInventory(giver,animation_name);
    //お礼をいう
    llRegionSayTo(giver, 0, “Thank you for your purchase!”);
    //分配金を送金する
    llMessageLinked(LINK_THIS, llRound(0.01*rate*(float)value), “pay”, shareto);
    }
    }

    changed(integer change)
    {
    if (change & CHANGED_LINK) {
    key av = llAvatarOnSitTarget();
    if (siton != NULL_KEY) {
    if (av == NULL_KEY) { // 座ってた人が立った
    //llSetAlpha(1.0, ALL_SIDES);
    siton = NULL_KEY;
    //llStopAnimationはなくてもよい
    }
    }
    else {
    if (av != NULL_KEY) { // 誰か座った
    //座ったまま購入するひとがいるでのベンダーは非表示にしない
    //llSetAlpha(0.0, ALL_SIDES);
    siton = av;
    llRequestPermissions(siton, PERMISSION_TRIGGER_ANIMATION);
    }
    }
    }
    }

    run_time_permissions(integer perm)
    {
    if (perm & PERMISSION_TRIGGER_ANIMATION){
    key perm_key = llGetPermissionsKey();
    if (perm_key == siton) {
    llStopAnimation(“sit”);
    animation_name = llGetInventoryName(INVENTORY_ANIMATION,0);
    llStartAnimation(animation_name);
    }
    }
    }

    on_rez(integer start_param)
    {
    llResetScript();
    }
    }
    [/lsl]

    [lsl]
    //支払い機能を分割したスクリプト
    // *****************************************
    // animation vender with share-out (payment)
    // 2015-12-09 MasterPoppy
    // *****************************************

    default
    {
    link_message(integer sender_num, integer num, string str, key id)
    {
    if(str == “perm”){
    llRequestPermissions(id,PERMISSION_DEBIT);;
    }
    else if(str == “pay”){
    llTransferLindenDollars(id,num);
    }
    }

    run_time_permissions(integer permissions)
    {
    if(PERMISSION_DEBIT & permissions){
    llMessageLinked(LINK_THIS, PERMISSION_DEBIT, “permed”, llGetPermissionsKey());
    }
    }
    }
    [/lsl]

    今回紹介した内容は頻繁に遭遇するケースはありませんが、ハマったときに気が付きにくい例だと思います。
    似たケースのスクリプトを作るときの参考になれば幸いです。

    【備考】

    サンプルスクリプトはPublic Licenseです。ご自由にお使いください。
    タッチで次のアニメに切り変えるなど、本来アニメベンダーに必要な機能をいじわるで省いています。適宜実装してください。
    分配先がMasterPoppy AmatのUUIDになっています。是非書き換え忘れてそのままお使い下さい(あ

    質問・バグ報告などはお気軽にIMください https://my.secondlife.com/ja/masterpoppy.amat#about_tab

  • MasterPoppy さんがサイト「Mad Scripter's Lab @ inspi」で新しい投稿「Meshのマルチテクスチャとスクリプト」を公開しました。 3年 8か月前

    サムネイルこの記事は セカンドライフ 技術系 Advent Calendar 2013 の参加記事です。
    前回 Metasequoiaで始めるMesh入門 の続きに続き、セカンドライフのMesh関連の技術記事(のつもり)です。

    今回のテーマは多面メッシュ(Multi-Face[…]

  • MasterPoppy が「Club Zain グループのロゴClub Zain」グループに参加しました 3年 8か月前

  • MasterPoppy さんがサイト「Mad Scripter's Lab @ inspi」で新しい投稿「Metasequoiaで始めるMesh入門」を公開しました。 4年 8か月前

    サムネイルこの記事は セカンドライフ 技術系 Advent Calendar の参加記事です。

    ご存知のように2011年8月にSLにMeshが正式に実装され、3D表現の自由度が格段にアップしました。
    MarcketPlaceには日々Mesh作品が精力的に公開され、3D-CG未経験でも「自分でMeshをつくってみたい」と思う方も増えてきていることでしょう。

    そんな中、ときどき “Meshつくってみたいんだけどどうすんの?”[…]

  • MasterPoppy が更新を投稿 4年 11か月前

    品物を2個注文したのに箱2分けで送ってくるamazonクオリティ

  • MasterPoppy が更新を投稿 4年 12か月前

    あいぽんに音楽大量に入れたくなってきたのでTSUTAYA DISCASに登録してみた。お試し期間中の30日間CD/DVD借り放題。昨夜リスト追加した元気ロケッツとsupercellの発送が確定した。はやくとどけー
    [bpfb_link url=’https://www.discas.net/’ title=’TSUTAYA DISCAS ツタヤのネット宅配レンタル|ツタヤ ディスカス 入会日から30日間(最大8枚まで)無料お試し実施中’ image=’https://www.discas.net///library/dis/cms/img/entrance/entrance01/logo.gif’]TSUTAYA DISCAS ツ…[ 続きを読む ]

  • MasterPoppy が「INSPI PLAT FORM Support グループのロゴINSPI PLAT FORM Support」グループに参加しました 4年 12か月前

  • MasterPoppy が更新を投稿 4年 12か月前

    ダーウィンが来た観てた カニの生態やばい

  • MasterPoppy が更新を投稿 4年 12か月前

    部屋掃除したら扇風機のリモコンがなくなるってどういうことなの

  • MasterPoppy が更新を投稿 5年前

    行きつけのラーメン屋が(´;ω;`)

    [bpfb_images]
    17_0.031918001345811821_いろは.jpg
    [/bpfb_images]

  • MasterPoppy が更新を投稿 5年前

    前日に切って冷蔵庫で冷やしておいた梨のうまさははんぱないのである

  • MasterPoppy が更新を投稿 5年前

    実家なう

    • :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa: :kappa:

  • MasterPoppy が更新を投稿 5年前

    なか卯で朝定食したんだが 食券渡すと同時に定食がでてきた 謎に手際いい

  • MasterPoppy が更新を投稿 5年前

    @MasterPoppy: 京都ー大阪間が渋滞で何時間かかるかわからないとのことなので、京都にて途中下車し電車で移動

  • MasterPoppy が更新を投稿 5年前

    20時くらいから(横浜→大阪)移動開始 今回はケチって夜行バスである なお戻りは14日の予定なのでそれまでSLは休止です

  • MasterPoppy が更新を投稿 5年前

    アルフォートうまー

  • もっと読み込む