Page 1 of 1

OSSL

Posted: Wed Jan 14, 2015 10:24 pm
by Graham Mills
I thought I would start an occasional thread for scripts that make use of the OpenSim-specific OSSL commands.

The first one is very simple and helps your avatar walk faster (or, alternatively, much faster). Rez a prim and add the following script.

Code: Select all

default
{
    touch_start(integer i)
    {
        osSetSpeed(llDetectedKey(0), 5.0);
    }
}
Touch the prim and enjoy super-fast walking. You can cancel the effect by changing 5.0 to 1.0 or by relogging.

Joining a group

Posted: Sat Feb 14, 2015 12:04 pm
by Graham Mills
Another simple one. Create an object with a suitable texture or hovertext, deed it to the group in question and add the following code. In Firestorm touching the object will show a Join/Decline/Info dialog for the object's group. The user is IM'd instructions and notified if there is an issue. Very useful for classes where preregistration isn't feasible. Hopefully the groups system will make it redundant in due course.

Code: Select all

default
{
    touch_start(integer i)
    {
        integer n = osInviteToGroup(llDetectedKey(0));
        if (n==0)
        {
            llInstantMessage(llDetectedKey(0), "You are invited to join the group. Press the Join button.");
        }
        else
        {
             llInstantMessage(llDetectedKey(0), "Problem joining group, e.g. already joined");
        }
    }
}
PS: Yes, it's a bit lazy because I'm assuming only one avatar touches at a time.

Putting text on a prim with wordwrap

Posted: Fri Aug 28, 2015 9:02 pm
by Graham Mills
This code mainly comes from Nebadon Izumi's Noteboard v2.0 which does a fine job of displaying 31 lines of 50 characters from a notecard but not afaik wrapping it. Accordingly I have added some wordwrap code from JasX together with a few other minor changes.

Paragraphs are best represented on the notecard with two linebreaks, i.e. a blank line between paragraphs. I have no idea how you stop text appearing on all sides -- the easiest fix is to hide it with other prims or set the face to the same colour as the text.

Code: Select all

// NoteBoard Script v2.0
// Updated 2014-06-19
// Created by Michael Emory Cerquoni
// Modified by Graham Mills_2 @ Kitely
// This script requires Deva Vu Sans Mono font be installed (http://dejavu-fonts.org/wiki/Main_Page)
// on linux put the .ttf files in ~/.fonts and restart simulator
// on windows place .ttf files in c:\windows\fonts and restart simulator
//Adds word wrap to INPUT, specified by ROWLENGTH and returns a string separated by SEPARATOR (recommended 

string name;

//jasx
//http://jasx.org/?p=libjas
string WrapText(string input, integer rowlength){
    list para = llParseString2List(input,["\n\n"],[]);
    integer n; string input2;
    integer i; list rows; string thisrow;
    string separator = "\n";
    for(n=0;n<llGetListLength(para);n++)
    {
        input2 = llList2String(para, n);
        list words = llParseString2List(input2,[" "],[]);
        while(i<llGetListLength(words))
        {
            string this = llList2String(words,i)+" ";
            if((llStringLength(this)+llStringLength(thisrow)) <= rowlength && i+1 != llGetListLength(words))
            {
                thisrow+=this;
            }
            else
            {
                if(i+1 == llGetListLength(words))thisrow+=this;
                rows+=[thisrow];
                thisrow = this;
            }
            i++;
        }
    }
    return llDumpList2String(rows, separator);
} 

draw_text()
{
// get the first notecard in inventory (default max is 255 lines and would not show in std chat)
    // each Line Return is reflected in output
    string name = llGetInventoryName(INVENTORY_NOTECARD,0);
    if(name == "") 
    {
        llSay(0,"There is no notecard in prim inventory.  Please place a notecard with some text in the prim to display it's contents");
        return;
    }
    if(osGetNumberOfNotecardLines(name) > 31) 
    {
        llSay(0,"Too Many Lines in your notecard, limit is 31 and you have " + (string)osGetNumberOfNotecardLines(name));
        return;
    }
    else
    {
        string output;
        integer m;
        string txt;
        for(m=0;m<osGetNumberOfNotecardLines(name);m++)
        {
            txt = osGetNotecardLine(name, m);
            if(llStringLength(txt)>3)
            {
                output += WrapText(txt, 50)+"\n\n";
            }
            else
            {
                output+=txt;
            }
        }            
        string CommandList = ""; // Storage for our drawing commands
        string FontName = "DejaVu Sans Mono"; // Arial is the default font used, if unspecified
        integer FontSize = 24;     // default to 24 point for sample

        CommandList = osSetFontName(CommandList, FontName);
        CommandList = osSetFontSize(CommandList, FontSize);
        CommandList = osMovePen(CommandList, 10, 15);
        CommandList = osDrawText(CommandList, output);

    // Now draw the image
        osSetDynamicTextureData( "", "vector", CommandList, "width:1024,height:1024", 0 );
    }
}

default
{
    state_entry()
    {
         llSay(0,"Touch to see osGetNotecard read in a notecard and display the text retrieved"); 
    }
    
    touch_end(integer num)
    {
        draw_text();
    }
    
    on_rez(integer start_param)
    {
        draw_text();
    }
    
    changed(integer c)
    {
        if (c & CHANGED_REGION_START)
        {
            draw_text();
        }
    } 
}

Re: OSSL

Posted: Fri Mar 17, 2017 1:36 pm
by Graham Mills
One potential source of annoyance or embarrassment is the presence of an under-dressed avatar. The following script outlines a possible strategy for handling this by teleporting the avatar to a changing room. The script would require substantial modification to work satisfactorily at world-scale -- this is just proof-of-concept code that requires the avatar to touch a prim containing the script. The prim needs to be owned by the World Manager or Owner.

The script works by creating an appearance card in the prim for the avatar, counting the number of lines in the card and teleporting the avatar if the count is below a set limit. Again, the figure of 100 is somewhat arbitrary and requires further investigation. You could also use osGetGender to make the teleport destination conditional.

Code: Select all

string NAME;
key AVATAR;
integer LIMIT = 100;
vector CHANGING_ROOM = <128,128, 25>;

default
{
    touch_start(integer n)
    {
        AVATAR = llDetectedKey(0);
        NAME = llKey2Name(AVATAR);
        osAgentSaveAppearance(AVATAR, NAME);
        llSetTimerEvent(5.0);
    }
    
    timer()
    {
        if (osGetNumberOfNotecardLines(NAME) < LIMIT)
        {
            llInstantMessage(AVATAR, "Possible wardrobe malfunction");
            osTeleportAgent(AVATAR, CHANGING_ROOM, ZERO_VECTOR);
           
        }
        llSetTimerEvent(0.0);
    }
}

Re: OSSL

Posted: Fri Jun 16, 2017 5:43 pm
by Graham Mills
The scratch code below is intended to demonstrate the use of OSSL to get and set terrain height. It is intended for use with a 256x256 m region/world. As ever, make sure you have a satisfactory backup before trying it.

Put the script in a prim positioned well above the maximum intended terrain level. Touch the prim and you should see four options: recorder, flatten, terra and plant (although plant doesn't work in this version). Selecting the recorder option creates a series of 31 notecards stored in the prim. These contain terrain height values determined by the topography of the current world. Selecting flatten creates a flat terrain at 21 m. Finally, terra restores the terrain from the values stored in the notecards (make sure your avatar is hovering above the new terrain or it will be catapaulted to 700+ m as the new terrain is formed).

There is presently no management of the notecards so if you want to reuse the script you first need to delete the notecards manually. Also, as the script uses a fixed channel for the dialog, prims may suffer cross-talk, i.e. have only one prim rezzed. You are free to use and, indeed, improve the code but please respect the intellectual property of terrain creators.

You can get a brief glimpse of the script operating alongside a functional plant state: https://twitter.com/vrsimility/status/8 ... 9734266880

Code: Select all

default
{
    state_entry()
    {
        llListen(-101, "", NULL_KEY, "");
    }
     
    touch_start(integer n)
    {
        llDialog(llDetectedKey(0), "Options", ["flatten", "recorder", "terra", "plant"], -101); 
    }   
    
    listen(integer c, string name, key id, string msg)
    {
        if (msg == "flatten")
        {
            state flatten;
        }
        else if (msg == "recorder")
        {
            state recorder; //need to delete existing nc
        }
        else if (msg == "terra")
        {
            state terra;
        }
        else if (msg == "plant")
        {
            //state plant;
        }
    }
}

state terra
{
    state_entry()
    {
        integer x;
        integer y;
        integer nc = 0;
        integer i;
        list heights;
        for (nc = 0; nc < 31; nc++)
        {
            heights = heights + llParseString2List(osGetNotecard("terrain_"+(string)nc), ["\n"], []);
        }
        i = 0;
        for (x = 1; x < 256; x++)
        {
            for (y = 1; y < 256; y++)
            {
                osSetTerrainHeight(x, y, llList2Float(heights, i));
                i++;
            }
        }
        osTerrainFlush();
        state default;
    }
}
    
state flatten
{    
    state_entry()
    {
        integer x;
        integer y;
        for (x = 1; x < 256; x++)
        {
            for (y = 1; y < 256; y++)
            {
                osSetTerrainHeight(x, y, 21.0);
            }
        }
        osTerrainFlush();
        state default;
    }
}   
    
 
state recorder
{    
    state_entry()
    {
        integer x;
        integer y;
        list heights = [];
        integer nc = 0;
        llOwnerSay("Please wait");
        for(x = 1; x < 255; x++)
        {
            for(y = 1; y < 255; y++)
            {
                heights = heights + [llGetSubString((string)osGetTerrainHeight(x, y), 0, 4)];
            }
            if ((x % 8 == 0) && (x > 0))
            {
                osMakeNotecard("terrain_"+(string)nc, heights);
                heights = [];
                nc++;
            }    
        }
        llOwnerSay("Done");
        state default;
    }
}