1st necessity of SL

Ever since I noticed that many sims contain 1000's of wonderful objects with fancy effects and 1000's active scripts that use valuable simresources while no-one is around to enjoy it, I wanted to script something simple to offload those resources and give the visitor a better experience.

 

That's why I made this little script: '1st necessity of SL' that could and should be used in any project that doesn't need to be active all the time.

 

We are building a better place, together :)

 

// Improve SecondLife's performance!
// Start with your own(ned) modifyable scripts/objects.
//
// This will disable your rootprim's script(s) when no-one is around to use/admire it
// thus stop wasting valuable sim-resources
// 
// Measured script time is 0.002 ms on average. 
//
// - don't use it for rental stuff or sorts, not everything is suitable -
//
// Free to use, please use it. Improvements are welcome.
// // Thank you Norton Burns for the testing and feedback :)
//
// Beer Dailey
//
// Don't reset this script or take it back in inventory when you're not within the set distance 
// or you'll get unpredictable results !!
// 
// modify below to suit your needs
 
//////////////////////////////////
float   distance = 48;   // scan range 
integer delay = 10;      // repeat scan every 10 seconds.
 
// added 
// (gnore specific scripts, some scripts need to be off after initial setups
// There's a bug that resets scripts in off state after a sim restart, so when activated again they re-initialise.
// I've no fix for that.
//
list ignore_scripts = ["major script", "even worse script"]; 
 
integer debug = FALSE;   // for debugging purposes, set it to TRUE to see what it's controlling
 
 
//////////////////////////////////////
// no need to modify the code below //
//////////////////////////////////////
 
integer g_active = FALSE;  // if FALSE disable all other scripts  
                           // changed TRUE into FALSE cos of some bug with rezzing, thank you LordGregGreg Back :)
list control_scripts;      // list for all scriptnames
 
active_scripts( integer active )
{
    if(g_active == active) return; else g_active = active;  //flip TRUE/FALSE
 
    integer a;
    for ( a = 0; a 

 

Script Vitality plug-in

There are so-called dead areas around SL where scripts are not allowed to run. There are always reasons for the land owner to set their land that way but this can brak some devices. This is a work-around the dead areas. The idea is to use vehicle technology: As soon a script takes avatar control (like vehicle do) the script and all other scripts in same prim keep running.

 

However, this solution increases lag a few, and must be used with care. Use it only for devices that must really keep running at any place, and do not use this tecnology already by themselves.

 

For lag reasons, only the control of the PageUp key is taken (this key is seldom used) and the control event handler is empty, i.e. no code is executed whenever the key is hit. Also the refreshing timer is set on low rate (15 seconds) which makes the script vulnerable agains releasing conrols by mistake, but in most cases the script retakes the avatar control in time before entering dead area.

 

DISCLAIMER

 

You can use this script in your project, if commercial or not. If you modify the script, please extend the script header by your name and update notes.

 

This script is provided as is. Although tested and found as error-free, no responsibility is taken for any misuse of the script, or damage caused by using it.

 

Plugin script

 

//----------------------------------------------------------------------------
// Script Vitality - keeps the script itself and all scripts in same prim 
// running also in 'dead' areas, those areas where scrpts are not allowed.
// This works simply by taking avatar controls. Should the resident click
// the "Release Controls" button, the vitality feature will break.
//
// To prevent this failure, if releasing controls hapened in an 'alive'
// area, i.e. where scripts are allowed, it retakes the control after 15
// seconds. If that hapened in a dead area, there is no option for the
// script to become alive.
//
// Usage: Just put the sctipt in the prim running scripts you want keep
// alive and avoid klicking the "Release Controls" button :) Please also
// keep in mind that this solution increases lag a bit. Every vehicle takes
// controls (it is how they work) and some AOs use also this technology.
// This script is hence not necessary for that devices. Thus, do not simply
// put this script in every scripted device, but check first if the device
// stops working in dead areas, and use this script than.
//
// Dead areas are not for fun no script areas, please respect it too.
//
// This script is universal, You will have to remove parts of the code
// depends on the special script purpose:
// 
// * Remove the section [On/Off] (the event link_message) if you want the
//   script to run permanently.
//
// * Remove the section [Owner change] completelly if you'l release the
//   device without transfer permission. Otherwise remove one of the
//   event handlers depend on if the owner always changes while the device
//   is not rezzed/worn or not.
//
// More info in the sections.
//
// Author  Jenna Felton
// Version 1.0
//----------------------------------------------------------------------------
 
key kOwner;
 
default {
    //--- [Core] -------------------------------------------------------------
 
    // Core section, basical script functionality.
 
    state_entry() {
        kOwner = llGetOwner();
        llRequestPermissions(kOwner, PERMISSION_TAKE_CONTROLS);
        llSetTimerEvent(15.0);
    }
 
    run_time_permissions(integer perm) {
        if(perm & PERMISSION_TAKE_CONTROLS) llTakeControls(CONTROL_DOWN, TRUE, TRUE);
    }
 
    timer() {
        if(llGetPermissions() & PERMISSION_TAKE_CONTROLS) return;
        llRequestPermissions(kOwner, PERMISSION_TAKE_CONTROLS);
    }
 
    // This is the magic. Even if empty the event handler makes the script
    // to keep the avatar's control. The script itself does not use it.
    control(key name, integer levels, integer edges) {;}
 
    //--- [On/Off] -----------------------------------------------------------
 
    // Allows to toggle the script (the vitality) on and off. You can
    // remove the event handler if you want the script run permanently.
    // If you keep this event, than you can use this code in other
    // script to toggle vitality on and off:
    //
    // llMessageLinked(LINK_SET, -1006192203, "1", ""); // vitality ON
    // llMessageLinked(LINK_SET, -1006192203, "0", ""); // vitality OFF
    //
    link_message(integer sender, integer number, string message, key id) {
        if (number != -1006192203) return; // JFSVC
 
        if (message == "1") {
            llRequestPermissions(kOwner, PERMISSION_TAKE_CONTROLS);
            llSetTimerEvent(15.0);
        }
        else {
            llReleaseControls();
            llSetTimerEvent(0.0);
        }
    }
 
    //--- [Owner change] -----------------------------------------------------
 
    // The changed and on_rez event handlers are used to notice the
    // owner change of the object. If you plan to make the object
    // no transfer, you can even remove both events. Handling the
    // owner change is important to keep control of right avatar.
    // Please use also one of the both handlers, never both. If you
    // are not sure what event handler to use, use the changed and
    // remove on_rez event handler.
 
    // The changed event is triggered if the object changes the
    // owner, but also if the object changes the shape or the
    // inventory or is simply moved to other sim. Use this event
    // if the device can be transferred to other avatar while it
    // is rezzed inworld, like a furniture or a scripted animal.
    changed(integer what) {
        if (what & CHANGED_OWNER) {
            llReleaseControls();
            llResetScript();
        }
    }
 
    // on_rez is triggered if the object is worn from inventory
    // or rezzed. Use this event if you build an attachment or
    // another device that is given between avatars or objects
    // but is never given/sold while it is rezzed inworld.
    on_rez(integer start)   {
        if (llGetOwner() != kOwner) {
            llReleaseControls();
            llResetScript();
        }
    }
}

 

 

How To Use

 

Copy the code in a new script, use a mono script engine (the script takes less than 16kB memory). The script is universal, so you will have to remove parts of the script later in your real projects:

  • You not need the On/Off section if you want run the script permanently.

You not need the Owner change section if you will not give the device away, otherwise

    • You can remove the on_rez event if the device might be sold/given while being inworld,
    • otherwise you can remove the changed section.
    • Test script

        • The test script also demonstrates how to toggle the vitality plugin on and off. To test the (unchanged) plugin script abowe, create a wodden box and put this script into:
          • default {
                state_entry() {
                    llSetTimerEvent(0.0);
                    llSetPrimitiveParams([
                        PRIM_SIZE, <.15, .15, .15>,
                        PRIM_TEXTURE, ALL_SIDES, "e470eec7-0c82-98b2-ac3c-dee6e2b3b4e7", <1 .0, 1.0, .0>, ZERO_VECTOR, .0]);
             
                    state ON;
                }
            }
             
            state ON {
                state_entry() {
                    llOwnerSay("--- ON ---");
                    llSetTimerEvent(10.0);
                    llSetColor(<1 .0, 1.0, .0>, ALL_SIDES);
             
                    llMessageLinked(LINK_SET, -1006192203, "1", ""); // vitality ON
                }
             
                timer() {
                    llOwnerSay("--- alive ---");
                }
             
                touch_start(integer number) {
                    state OFF;
                    }
            }
             
            state OFF {
                state_entry() {
                    llOwnerSay("--- OFF ---");
                    llSetTimerEvent(10.0);
                    llSetColor(<.5, .5, .0>, ALL_SIDES);
             
                    llMessageLinked(LINK_SET, -1006192203, "0", ""); // vitality OFF
                }
             
                timer() {
                    llOwnerSay("--- alive ---");
                }
             
                touch_start(integer number) {
                    state ON;
                }
            }

             

          • Pick the box into your inventory and attach it to HUD. The box will say alive every 10 seconds and response on touches. Do not use the plugin script yet, but teleport in any dead area. The test script will stop reporting and response on touches, it is dead.

          •  

            Now teleport back to a place where scripts are allowed to run, klick the test box until it says ON and put the vitality plugin into the test box. The vitality plugin is running by default, so it is in sync with the test script that is in ON state.

          •  

            Now teleport back into dead area. The test script contonues running. If you klick the test box now, the test script sends a deactivating message to the plugin script. The script deactivates and the test script stops running.

          •  

            To reactivate the plugin script, you have to go back to an alive area and click the test box again. Hence, if you want keep the script toggle-able, do not toggle it off in a no-script area.

Grid Status Updater ( V20 )

Checks the Second Life Grid Status every five minutes to see if there are any new issues. If there are it will IM you.

 

 

Drop this script onto any prim that is currently not expected to do something else (e.g. a wall or floor etc) and let it run. If it is in an attachment it will work fine but, only while you are logged in. The script will maintain the name of the prim (or object if in a root) but when sending an update will use a special name set by you.

// V20 //
 
string feed_url = "http://status.secondlifegrid.net/feed/"; // From where we draw our updates.
 
string alert_name = "Grid Status Update"; // What we call the object while it messages us.
 
string my_proper_name; // Used to store the memory of the name of the object when dormant.
 
key owner; // Used to store the owners UUID.
 
string last; // Used to store the last update so we can tell if the latest is new.
 
key iq; // Used to verify the source of the HTTPRequest.
 
list exchange = [" [...]","...",
                 "”","\"",
                 "“","\"",
                 "’","'",
                 ">",">",
                 "&","&",
                 ">",">",
                 "&","&"];
 
string MultiStringReplace(string src, list thisnthats)
{
    integer index = 0;
    integer lc = 0;
    integer ll = llGetListLength(thisnthats);
    string this;
    do
    {
        this = llList2String(thisnthats, lc);
        ++lc;
        while((index = llSubStringIndex(src, this)) != -1)
        src = llInsertString(llDeleteSubString(src, index, (index + (llStringLength(this) - 1))), index, llList2String(thisnthats, lc));
    }
    while((++lc) ") + 6), -1);
                string latest = llStringTrim(llGetSubString(body, (llSubStringIndex(body, "") - 1)), STRING_TRIM);
                if(latest != last)
                {
                    last = latest;
                    string dnt = llGetSubString(body, (llSubStringIndex(body, "") + 9), (llSubStringIndex(body, "") - 10));
                    llSetObjectName(alert_name);
                    llInstantMessage(owner, "/me \n\nISSUE --> " + MultiStringReplace(llGetSubString(body, (llSubStringIndex(body, "") + 7),
                                                                                     (llSubStringIndex(body, "") - 1)), exchange) + 
                                            "\n\nTIME --> " + llGetSubString(dnt, -5, -1) + ", " + (llGetSubString(dnt, 0, -7) + " (UTC)") +
                                            "\n\nLATEST --> " + MultiStringReplace(latest, exchange) +
                                            "\n\nVISIT --> " + llGetSubString(feed_url, 0, -6));
                    llSetObjectName(my_proper_name);
                }
            }
            else
            {
                llSleep(30.0);
                iq = llHTTPRequest(feed_url, [], "");
            }
        }
    }
}

 

Basic Sim Status Button Indicator HUD

// Generic Sim Status Button Indicator
// HUD / 1 prim
// by Ackley Bing
// January 2013
//
// A HUD button for remote monitoring of sims.
// Color indicates the sim status
// Green = SIM available
// When the sim goes down it turns red/black
//
// To use put this in a prim and attach to your preferred HUD location.
// Go to the sim you want to monitor and and click the prim
// Click and HOLD the hud button to choose another sim.
//
// Modify // Attach / Connect this to your HUD/Vehicle/etc any way you like.
 
integer listenhandle;
string region;
key datarequestID;
 
vector SimStutus2Color(string data)
{
    if ( data == "up" ) return <0.0,1.0,0.0>; // green
    else if ( data == "down" ) return <1 .0,0.0,0.0>; // red
    else if ( data == "starting" || data == "stopping" ) return <1 .0,1.0,0.0>; // yellow
    else return <0.0,0.0,0.0>; // black
}
 
default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);
        llSetPrimitiveParams([PRIM_COLOR, 4, SimStutus2Color(""), 1.0]);
    }
    touch_start(integer n)
    {
        llResetTime();
        llSetTimerEvent(30.0);
    }
    touch_end(integer n)
    {
        if(llGetTime()<5 .0 && region != "") datarequestID=llRequestSimulatorData(region,DATA_SIM_STATUS);
        else llDialog(llGetOwner(), "Monitor Sim Status for "+llGetRegionName()+"?", ["Yes","No"], (listenhandle = llListen(1, "", llGetOwner(), "")));
    }
    listen(integer channel, string name, key id, string message)
    {
        if (message=="Yes") datarequestID=llRequestSimulatorData(region=llGetRegionName(),DATA_SIM_STATUS);
        if (message=="No" && region=="") llSetPrimitiveParams([PRIM_COLOR, 4, SimStutus2Color(""), 1.0]);
    }
    timer()
    {
        if (listenhandle) llListenRemove(listenhandle--);
        if (region!="") llRequestSimulatorData(region,DATA_SIM_STATUS);
    }
    dataserver(key requested, string data)
    {
        if (requested==datarequestID) llOwnerSay("http://maps.secondlife.com/secondlife/"+llEscapeURL(region)+" is "+data+(string)(datarequestID=""));
        llSetPrimitiveParams([PRIM_COLOR, 4, SimStutus2Color(data), 1.0]);
    }
    run_time_permissions(integer perms)
    {
        llTakeControls((perms && PERMISSION_TAKE_CONTROLS)*CONTROL_BACK, TRUE, TRUE);
    }
}

 

Region Stats as Graphical Floating Text ( V3 )

// V3 //
 
integer on = TRUE;
 
Switch()
{
    if(on)
    {
        llSetTimerEvent(0.0);
        llSetText("Click Me to Enable Region Stats Display\n \n ", <1 .0, 1.0, 0.0>, 1.0);
    }
    else
    {
        llSetText("Gathering Region Stats...\n \n ", <1 .0, 1.0, 0.0>, 1.0);
        llSetTimerEvent(2.5);
    }
    on = (!on);
}
 
DisplayStats()
{
    integer count;
    string d = "";
    string f = "";
    integer fps = (llRound((llGetRegionFPS() * 2.0) + 10.0) / 10);
    integer dilation = llRound((llGetRegionTimeDilation() * 10.0));
    integer combo = (dilation + fps);
    while((++count) , 1.0);
}
 
string GetCondition(integer c) // Obviously you can change this wording if you like.
{                              // I just thought of "health" and went with it.
    if(c == 40)
    return "TRANSCENDENT";
    else if(c > 35)
    return "ATHLETIC";
    else if(c > 30)
    return "HEALTHY";
    else if(c > 25)
    return "AVERAGE";
    else if(c > 20)
    return "ILL";
    else if(c > 15)
    return "DYING";
    else if(c > 10)
    return "CRITICAL";
    else
    return "DEAD?";
}
 
default
{
    state_entry()
    {
        Switch();
    }
    touch_start(integer nd)
    {
        Switch();
    }
    timer()
    {
        DisplayStats();
    }
}