ソラマメブログ

2007年04月05日

太陽がいっぱい(2)

さて、春休みが終わってしまわないうちに宿題を仕上げるようがんばりましょう。前回は透明半球に点を打つところまででした。しかし、このままでは点は時間が経つと消えてしまいます。それを残すためのスクリプトを作ります。

どうやって点を残すか、ですが、機能としては持ち主が半球をクリックしたらその時点のマーカーを保存するようにすることにします。クリックされたかはtouch_start()ハンドラで知ることができます。この中で、マーカーを半球にリンクすることで記録を残したまま持ち運べるようにします。オブジェクト製作をするときにメニューやショートカットでPrimをくっつけるあの操作をスクリプト内から実行します。このためにはllCreateLink()を実行します。しかし、llCreateLink()を実行するにはリンクしたいオブジェクトのkeyが必要です。どうすればkeyを知ることができるのでしょうか。オブジェクトのkeyを知る方法はいろいろあるのですが、自分がrezしたオブジェクトの場合object_rez()ハンドラを登録しておけばrezするたびにオブジェクトのkeyを通知してくれます。今回はこれを使うことにします。touch_start()が呼ばれた時点でkeyを知ろうと思っても手遅れなので、クリックされるかどうかに係わらずkeyを保存しておき、クリックされたらそれを使ってリンクすることにします。
ついでなのでPlotMarkerのスクリプトにも手を入れてリンクされたらTemporary属性を解除するようにしておくことにします。実際はリンクされている間はTemprary属性は親である透明半球の属性に上書きされているので消えることはないのですが。
そして、もうひとつ重要なことがあります。スクリプトの動作が世界に重要な変化を起こすと考えられる場合、たとえばお金を支出するとかアイテムを身に着けるという動作をスクリプトから実行するには許可が必要となります。具体的にどの動作に許可が必要かはLSL Wikiを参照していただくとして、オブジェクトのリンクも許可が必要な事項となっています。なので実際にこのスクリプトを実行するには許可の取得が必要です。現在スクリプトが持っている許可について参照するにはllGetPermissions()を、許可の設定にはllRequestPermissions()を使用します。llRequestPermissions()を実行すると許可設定を要求したアバターに対してダイアログが出力されます。許可設定はスクリプト中どこでやっても有効ですが、私は必要になった時点でまだ許可を得ていない場合だけ要求するようにしています。そして、許可が有効になったかどうかはrun_time_permissons()ハンドラに通知されます。もう少し正確にいうと、許可がなくなった場合も含めてスクリプトに対する許可設定が変更された時にrun_time_permissions()が呼ばれます。
長くなってしまったので今回は変更部分だけコードを載せます。透明半球に追加するのは3つのハンドラです。

    touch_start(integer t)
    {
        if ( llDetectedKey(0) != llGetOwner() ) jump noproc ;
       
        integer P = llGetPermissions() ;
        if ( !(P & PERMISSION_CHANGE_LINKS) )
        {
            llRequestPermissions( llGetOwner() ,PERMISSION_CHANGE_LINKS ) ;
        }
        else
            linkmarker() ;
       
        @noproc ;
    }
    run_time_permissions(integer p)
    {
        if ( p & PERMISSION_CHANGE_LINKS)
        {
            linkmarker() ;
        }
    }
    object_rez( key obj )
    {
        MarkerKey = obj ;
    }

そして、PlotMarker側にもひとつハンドラを追加します。

    changed(integer change)
    {
        if( change & CHANGED_LINK )
        {
            if ( llGetLinkNumber() != 0 )
            {
                llSetPrimitiveParams([ PRIM_TEMP_ON_REZ, FALSE ] ) ;
            }
        }
    }

これで好きなときに太陽の位置を透明半球にマーキングすることができます。ひとつ書き忘れたことに気がつきました。出来上がったものを作者自身でない人が使うためにはPlotMarkerをコピー可能な状態にセットしてください。そうしないと、一回目のrezでインベントリからなくなってしまうので二回目以降のllRezObject()が失敗します。


Posted by Lemonheart at 12:36│Comments(0)
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。