Difference between revisions of "Random AV Profile Projector"

From Second Life Wiki
Jump to navigation Jump to search
Line 7: Line 7:
<lsl>
<lsl>
// ~ RANDOM AV PROFILE PICTURE PROJECTOR v5.1 by Debbie Trilling ~
// ~ RANDOM AV PROFILE PICTURE PROJECTOR v5.1 by Debbie Trilling ~
 
// *** This script randomly selects an AV from a crowd & then displays their
// *** This script randomly selects an AV from a crowd & then displays their
// profile picture as texture on a prim and/or a 'holographic' image projected above the prim***
// profile picture as texture on a prim and/or a 'holographic' image projected above the prim***
 
// Free to use as you wish by under condition that the title and this introduction remain in place,
// Free to use as you wish by under condition that the title and this introduction remain in place,
// and that due credit continues to be given to Moriash Moreau, Jana Kamachi and Solar Alter, and
// and that due credit continues to be given to Moriash Moreau, Jana Kamachi and Solar Alter, and
// Debbie Trilling.
// Debbie Trilling.
 
// TOUCH to switch ON and OFF
// TOUCH to switch ON and OFF
 
// ** PARAMETERS THAT YOU CAN CHANGE **
// ** PARAMETERS THAT YOU CAN CHANGE **
 
 
//************************
//************************
// GENERAL PARAMETERS
// GENERAL PARAMETERS
Line 25: Line 25:
// how often in seconds the sensor fires
// how often in seconds the sensor fires
float RepeatTime = 35.00;
float RepeatTime = 35.00;
 
// sensor range in meters. Maximum 96m but in practice 10 to 30m because of particle draw distance
// sensor range in meters. Maximum 96m but in practice 10 to 30m because of particle draw distance
float Range = 25.00;
float Range = 25.00;
 
// sets the number of consecutive times that the scanner is allowed to operate without having located an AV within range
// sets the number of consecutive times that the scanner is allowed to operate without having located an AV within range
// eg: if RepeatTime = 60.0 seconds and TotalNoScansAllowed = 30, then the toy will operate for 1800 seconds (60x30, or 30 minutes) without locating
// eg: if RepeatTime = 60.0 seconds and TotalNoScansAllowed = 30, then the toy will operate for 1800 seconds (60x30, or 30 minutes) without locating
// anyone before it automatically powers down. Set to '0' to disable the auto-off function
// anyone before it automatically powers down. Set to '0' to disable the auto-off function
integer TotalNoScansAllowed = 20;
integer TotalNoScansAllowed = 20;
 
// sets whether the DefaultTexture will be textured/projected when the toy is switched OFF. 'TRUE' to texture/project; 'FALSE' to have no texturing/projection when off
// sets whether the DefaultTexture will be textured/projected when the toy is switched OFF. 'TRUE' to texture/project; 'FALSE' to have no texturing/projection when off
integer ProjectDefaultTexture = TRUE;
integer ProjectDefaultTexture = TRUE;
 
// texture palette of UUID's. One will be randomly selected for display when an AV without a profile pic is selected
// texture palette of UUID's. One will be randomly selected for display when an AV without a profile pic is selected
list DefaultTexture = ["7cfd684e-2141-941c-eac8-bd439f0d5a9f", "d02531dd-491c-45b5-2cab-2e47ec81ec0d", "c3eebd9e-ee92-a16f-f906-bc275928df86"];
list DefaultTexture = ["7cfd684e-2141-941c-eac8-bd439f0d5a9f", "d02531dd-491c-45b5-2cab-2e47ec81ec0d", "c3eebd9e-ee92-a16f-f906-bc275928df86"];
 
 
//************************
//************************
// PARTICLE EMISSION PARAMETERS
// PARTICLE EMISSION PARAMETERS
Line 46: Line 46:
// set to TRUE to display the profile picture as a particle 'holographic' image above the prim
// set to TRUE to display the profile picture as a particle 'holographic' image above the prim
integer DisplayBanner = TRUE;
integer DisplayBanner = TRUE;
 
// width size in meters of the projected image (max 4.00)
// width size in meters of the projected image (max 4.00)
float Size = 2.50;
float Size = 2.50;
 
// height above object the centre of projected image will be (theoretical max. 50.0, in practice 2.0 to 10.0))
// height above object the centre of projected image will be (theoretical max. 50.0, in practice 2.0 to 10.0))
float Height = 2.50;
float Height = 2.50;
 
 
//************************
//************************
// PRIM TEXTURE PARAMETERS
// PRIM TEXTURE PARAMETERS
Line 59: Line 59:
// set to TRUE to texture the prim with the profile picture on ALL_SIDES
// set to TRUE to texture the prim with the profile picture on ALL_SIDES
integer TexturePrim = TRUE;
integer TexturePrim = TRUE;
 
// the following 'Prim*' parameters effect the prim only if ProjectDefaultTexture and/or TexturePrim = FALSE
// the following 'Prim*' parameters effect the prim only if ProjectDefaultTexture and/or TexturePrim = FALSE
// if either = TRUE then the prim is automatically set to solid blank white with full bright
// if either = TRUE then the prim is automatically set to solid blank white with full bright
// texture to use for the prim when toy is OFF
// texture to use for the prim when toy is OFF
key PrimTexture = "5748decc-f629-461c-9a36-a35a221fe21f";
key PrimTexture = "5748decc-f629-461c-9a36-a35a221fe21f";
 
// set to TRUE to turn on Full Bright on ALL_SIDES when the toy is OFF
// set to TRUE to turn on Full Bright on ALL_SIDES when the toy is OFF
integer PrimFullBright = FALSE;
integer PrimFullBright = FALSE;
 
// vector for the prim colour when toy is OFF
// vector for the prim colour when toy is OFF
vector PrimColour = <0.0, 0.0, 0.0>;
vector PrimColour = <0.0, 0.0, 0.0>;
 
// set the alpha of the prim from 0.0 (clear) to 1.0 (solid) for when toy is OFF
// set the alpha of the prim from 0.0 (clear) to 1.0 (solid) for when toy is OFF
float PrimAlpha = 1.00;
float PrimAlpha = 1.00;
 
 
//************************
//************************
// SHOUTOUT PARAMETERS
// SHOUTOUT PARAMETERS
Line 80: Line 80:
// set to 'TRUE' to give a 'ShoutOut' to the AV once they have been selected; 'FALSE' for no 'ShoutOut'
// set to 'TRUE' to give a 'ShoutOut' to the AV once they have been selected; 'FALSE' for no 'ShoutOut'
integer ShoutOut = TRUE;
integer ShoutOut = TRUE;
 
// text to 'ShoutOut' when an AV's profile is projected. Text will be preceeded by their name, eg: "<AV Name>'s face is up in lights!"
// text to 'ShoutOut' when an AV's profile is projected. Text will be preceeded by their name, eg: "<AV Name>'s face is up in lights!"
string ShoutOutText = "'s face is up in lights!";
string ShoutOutText = "'s face is up in lights!";
 
 
 
 
//************************  
//************************
// ** DO NOT CHANGE BELOW THIS LINE **
// ** DO NOT CHANGE BELOW THIS LINE **
//************************  
//************************
 
string URL_FORUMTHREAD = "http://forums.secondlife.com/showthread.php?t=225692";
string URL_FORUMTHREAD = "http://forums.secondlife.com/showthread.php?t=225692";
string URL_WIKIPAGE = "http://wiki.secondlife.com/wiki/User:Debbie_Trilling";
string URL_WIKIPAGE = "http://wiki.secondlife.com/wiki/User:Debbie_Trilling";
Line 110: Line 110:




 
 
GiveShoutOut()
GiveShoutOut()
{
{
    // any interaction with selected AV (give Inventory items etc) can safely be done from this function
// any interaction with selected AV (give Inventory items etc) can safely be done from this function
    // this function will only execute if ShoutOut == TRUE
// this function will only execute if ShoutOut == TRUE
 
    //although fondly calling it a 'ShoutOut', it actually makes more sense to keep within the 20m range of llSay
//although fondly calling it a 'ShoutOut', it actually makes more sense to keep within the 20m range of llSay
    llSay(0, llKey2Name(AVKey) + ShoutOutText);
llSay(0, llKey2Name(AVKey) + ShoutOutText);
 
}
}
 
 
ProjectTexture()
ProjectTexture()
{
{
    // are we going to use a default texture when toy is OFF?
// are we going to use a default texture when toy is OFF?
    if (ProjectDefaultTexture)
if (ProjectDefaultTexture)
    {  
{
        if (TexturePrim)
if (TexturePrim)
        {
{
            // using a default texture; if putting texture on the prim, let's make sure it is solid white, blank. full bright
// using a default texture; if putting texture on the prim, let's make sure it is solid white, blank. full bright
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0 ]);
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0 ]);
        }
}
        else
else
        {
{
// not texturing the prim, so apply the prom preferences
// not texturing the prim, so apply the prom preferences
            ApplyPrimPrefs();
ApplyPrimPrefs();
        }
}
        ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
    }
}
    else
else
    {
{
        // we're not doing anything when the toy is OFF; change the prim to user preferences
// we're not doing anything when the toy is OFF; change the prim to user preferences
        llParticleSystem([]);
llParticleSystem([]);
        ApplyPrimPrefs();
ApplyPrimPrefs();
    }
}
}
}
 
ApplyPrimPrefs()
ApplyPrimPrefs()
{
{
    llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, PrimFullBright,
llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, PrimFullBright,
        PRIM_TEXTURE, ALL_SIDES, PrimTexture, <1.000000, 1.000000, 0.000000>, <0.000000, 0.000000, 0.000000>, 0.000000, PRIM_COLOR, ALL_SIDES, PrimColour, PrimAlpha ]);
PRIM_TEXTURE, ALL_SIDES, PrimTexture, <1.000000, 1.000000, 0.000000>, <0.000000, 0.000000, 0.000000>, 0.000000, PRIM_COLOR, ALL_SIDES, PrimColour, PrimAlpha ]);
}
}
 
 
ParticleStart(key texture)
ParticleStart(key texture)
{
{
    if (DisplayBanner)
if (DisplayBanner)
    {
{
        //core code by Moriash Moreau. Adapted to suit by Debbie Trilling
//core code by Moriash Moreau. Adapted to suit by Debbie Trilling
        llParticleSystem([
llParticleSystem([
            PSYS_PART_FLAGS, 0,
PSYS_PART_FLAGS, 0,
            PSYS_SRC_PATTERN, 4,
PSYS_SRC_PATTERN, 4,
            PSYS_PART_START_ALPHA, 0.50,
PSYS_PART_START_ALPHA, 0.50,
            PSYS_PART_END_ALPHA, 0.50,
PSYS_PART_END_ALPHA, 0.50,
            PSYS_PART_START_COLOR, <1.0,1.0,1.0>,
PSYS_PART_START_COLOR, <1.0,1.0,1.0>,
            PSYS_PART_END_COLOR, <1.0,1.0,1.0>,
PSYS_PART_END_COLOR, <1.0,1.0,1.0>,
            PSYS_PART_START_SCALE, <Size * 1.6 ,Size,0.00>,
PSYS_PART_START_SCALE, <Size * 1.6 ,Size,0.00>,
            PSYS_PART_END_SCALE, <Size * 1.6,Size,0.00>,
PSYS_PART_END_SCALE, <Size * 1.6,Size,0.00>,
            PSYS_PART_MAX_AGE, 1.20,
PSYS_PART_MAX_AGE, 1.20,
            PSYS_SRC_MAX_AGE, 0.00,
PSYS_SRC_MAX_AGE, 0.00,
            PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
            PSYS_SRC_ANGLE_BEGIN, 0.00,
PSYS_SRC_ANGLE_BEGIN, 0.00,
            PSYS_SRC_ANGLE_END, 0.00,
PSYS_SRC_ANGLE_END, 0.00,
            PSYS_SRC_BURST_PART_COUNT, 8,
PSYS_SRC_BURST_PART_COUNT, 8,
            PSYS_SRC_BURST_RADIUS, Height,
PSYS_SRC_BURST_RADIUS, Height,
            PSYS_SRC_BURST_RATE, 0.10,
PSYS_SRC_BURST_RATE, 0.10,
            PSYS_SRC_BURST_SPEED_MIN, 0.00,
PSYS_SRC_BURST_SPEED_MIN, 0.00,
            PSYS_SRC_BURST_SPEED_MAX, 0.00,
PSYS_SRC_BURST_SPEED_MAX, 0.00,
            PSYS_SRC_OMEGA, <0.00,0.00,0.00>,
PSYS_SRC_OMEGA, <0.00,0.00,0.00>,
            PSYS_SRC_TEXTURE, texture]);
PSYS_SRC_TEXTURE, texture]);
    }
}
 
    if (TexturePrim)
if (TexturePrim)
    {
{
        llSetTexture(texture, ALL_SIDES);
llSetTexture(texture, ALL_SIDES);
    }
}
}
}
 
AnnounceWelcome()
AnnounceWelcome()
{
{
    llOwnerSay(
llOwnerSay(
        "\nThank you for your interest in this product created by Debbie Trilling at The Particle Crucible.");
"\nThank you for your interest in this product created by Debbie Trilling at The Particle Crucible.");
}
}
 
 
ShutDown()
ShutDown()
{
{
    llSensorRemove();
llSensorRemove();
llListenRemove(ListenChannel);
llListenRemove(ListenChannel);
    Power = FALSE;
Power = FALSE;
    ProjectTexture();
ProjectTexture();
}
}
 
 
default
default
{
{
 
    on_rez(integer start_param)
on_rez(integer start_param)
    {
{
        // reset script on rez
// reset script on rez
        AnnounceWelcome();
AnnounceWelcome();
        llResetScript();
llResetScript();
    }
}
 
    changed( integer change )
changed( integer change )
    {
{
        if(change & CHANGED_OWNER )
if(change & CHANGED_OWNER )
        {
{
            // reset script on change of owner
// reset script on change of owner
            AnnounceWelcome();
AnnounceWelcome();
            llResetScript();
llResetScript();
        }
}
    }
}
 
    state_entry()
state_entry()
    {
{
        //initialise system
//initialise system
        llParticleSystem([]);
llParticleSystem([]);
        ObjectOwner = llGetOwner();
ObjectOwner = llGetOwner();
        OwnerName = llKey2Name(ObjectOwner);
OwnerName = llKey2Name(ObjectOwner);
        llSetObjectName(ObjectName + Version);
llSetObjectName(ObjectName + Version);
        llSetObjectDesc("Supplied free by " + Author + "'s " + Supplier);
llSetObjectDesc("Supplied free by " + Author + "'s " + Supplier);
        ProjectTexture();
ProjectTexture();
        llOwnerSay("\nTOUCH the " + ObjectName + " to switch it ON and OFF.");
llOwnerSay("\nTOUCH the " + ObjectName + " to switch it ON and OFF.");
    }
}
 
    touch_start(integer total_number)
touch_start(integer total_number)
    {
{
        if (llDetectedKey(0) == ObjectOwner)
if (llDetectedKey(0) == ObjectOwner)
        {
{
            // operation by Owner Only
// operation by Owner Only
            if (Power)
if (Power)
            {
{
                // touch to OFF
// touch to OFF
                ShutDown();
ShutDown();
                llOwnerSay("\nThe " + ObjectName + " is now switched OFF.");
llOwnerSay("\nThe " + ObjectName + " is now switched OFF.");
            }
}
            else
else
            {
{
                // touch to ON
// touch to ON
                Power = TRUE;
Power = TRUE;
                NoSensorCounter = 0;
NoSensorCounter = 0;
                llSensorRepeat("",NULL_KEY,AGENT,Range,PI,RepeatTime);
llSensorRepeat("",NULL_KEY,AGENT,Range,PI,RepeatTime);
                llOwnerSay("\nThe " + ObjectName + " is now switched ON. Please wait...");
llOwnerSay("\nThe " + ObjectName + " is now switched ON. Please wait...");
            }
}
        }
}
        else
else
        {
{
            // touched by someone other than Owner. Send them a message & a dialog box of options
// touched by someone other than Owner. Send them a message & a dialog box of options
DetectedUser = llDetectedKey(0);
DetectedUser = llDetectedKey(0);
llInstantMessage(DetectedUser, "\nThank you for your interest in the " + ObjectName + " created by " + Author + "\nThe dialog menu offers a number of options.");
llInstantMessage(DetectedUser, "\nThank you for your interest in the " + ObjectName + " created by " + Author + "\nThe dialog menu offers a number of options.");
Line 265: Line 265:
list MenuItems = ["LearnMore","GetScript"];
list MenuItems = ["LearnMore","GetScript"];
string MenuText = "MAIN MENU: Please make a selection within " + (string)llFloor(DialogTimeout)  + " seconds.\n- LearnMore: Read the forum thread on this product\n- GetScript: Get yourself a free copy of this script";
string MenuText = "MAIN MENU: Please make a selection within " + (string)llFloor(DialogTimeout)  + " seconds.\n- LearnMore: Read the forum thread on this product\n- GetScript: Get yourself a free copy of this script";
            // if already on 'Exclude List', give opportunity to clear their name, else give opportunity to exclude their name
// if already on 'Exclude List', give opportunity to clear their name, else give opportunity to exclude their name
if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 )
if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 )
{
{
Line 281: Line 281:
llDialog(DetectedUser, MenuText, MenuItems, CommChannel);
llDialog(DetectedUser, MenuText, MenuItems, CommChannel);
llSetTimerEvent(DialogTimeout);
llSetTimerEvent(DialogTimeout);
        }
}
    }
}
 
 
    sensor(integer total_number)
sensor(integer total_number)
    {
{
        // save the AV key in case it is needed for a 'ShoutOut'
// save the AV key in case it is needed for a 'ShoutOut'
        AVKey = llDetectedKey((integer)llFrand(total_number));
AVKey = llDetectedKey((integer)llFrand(total_number));
        // core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling
// core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling
        llHTTPRequest( URL_RESIDENT + (string)AVKey,[HTTP_METHOD,"GET"],"");
llHTTPRequest( URL_RESIDENT + (string)AVKey,[HTTP_METHOD,"GET"],"");
    }
}
 
 
    no_sensor()
no_sensor()
    {
{
        // counts the number of times that the scanner doesn't find anyone in range. If TotalNoScansAllowed is set to greater than zero, automatically powers down the toy
// counts the number of times that the scanner doesn't find anyone in range. If TotalNoScansAllowed is set to greater than zero, automatically powers down the toy
        // when the number of no_sensors exceeds TotalNoScansAllowed. However, this functionality is disabled if TotalNoScansAllowed is set to zero.
// when the number of no_sensors exceeds TotalNoScansAllowed. However, this functionality is disabled if TotalNoScansAllowed is set to zero.
        NoSensorCounter++;
NoSensorCounter++;
        if ((NoSensorCounter > TotalNoScansAllowed) && (TotalNoScansAllowed > 0))
if ((NoSensorCounter > TotalNoScansAllowed) && (TotalNoScansAllowed > 0))
        {
{
            ShutDown();
ShutDown();
            llInstantMessage(ObjectOwner, "\nThe " + ObjectName + " has been automatically switched OFF as no Agents have been detected within the set timeframe.");
llInstantMessage(ObjectOwner, "\nThe " + ObjectName + " has been automatically switched OFF as no Agents have been detected within the set timeframe.");
        }
}
        else
else
        {
{
            ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
        }
}
    }
}
 
 
    http_response(key req,integer stat, list met, string body)
http_response(key req,integer stat, list met, string body)
    {
{
        // core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling
// core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling
        integer s1 = 0;
integer s1 = 0;
        integer s2 = 0;
integer s2 = 0;
        integer s1l= 0;
integer s1l= 0;
        integer s2l= -3;
integer s2l= -3;
        s1 = llSubStringIndex(body,"<img alt=\"profile image\" src=\"http://secondlife.com/app/image/");
s1 = llSubStringIndex(body,"<img alt=\"profile image\" src=\"http://secondlife.com/app/image/");
        s1l = llStringLength("<img alt=\"profile image\" src=\"http://secondlife.com/app/image/");
s1l = llStringLength("<img alt=\"profile image\" src=\"http://secondlife.com/app/image/");
        s2 = llSubStringIndex(body,"\" class=\"parcelimg\" />");
s2 = llSubStringIndex(body,"\" class=\"parcelimg\" />");
 
        if(s1 == -1)
if(s1 == -1)
        {
{
            // selected AV doesn't have a profile picture, so use the default instead
// selected AV doesn't have a profile picture, so use the default instead
            ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
        }
}
        else
else
        {
{
            //check whether this was the texture used last time
//check whether this was the texture used last time
            if ((key)llGetSubString(body,s1+s1l,s2+s2l) == LastTexture)
if ((key)llGetSubString(body,s1+s1l,s2+s2l) == LastTexture)
            {
{
                // same profile pic as last time. so display a random default instead
// same profile pic as last time. so display a random default instead
                ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture))));
                // clear the last texture out
// clear the last texture out
                LastTexture = "";
LastTexture = "";
            }
}
            else
else
            {
{
// are they on the KillJoyListing? if so, we had better pander to their delicate sensibilities & display a random default texture instead
// are they on the KillJoyListing? if so, we had better pander to their delicate sensibilities & display a random default texture instead
if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 )
if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 )
Line 346: Line 346:
}
}
else
else
{
{
                // different profile from last time & not on KillJoyListing, so display it
// different profile from last time & not on KillJoyListing, so display it
                ParticleStart((key)llGetSubString(body,s1+s1l,s2+s2l));
ParticleStart((key)llGetSubString(body,s1+s1l,s2+s2l));
                // save the key for comparison purposes next time tho'
// save the key for comparison purposes next time tho'
                LastTexture = (key)llGetSubString(body,s1+s1l,s2+s2l);
LastTexture = (key)llGetSubString(body,s1+s1l,s2+s2l);
 
                // give a 'ShoutOut', if set to do so
// give a 'ShoutOut', if set to do so
                if (ShoutOut)
if (ShoutOut)
                {
{
                    GiveShoutOut();
GiveShoutOut();
                }
}
}
}
            }
}
        }
}
    }
}




Line 368: Line 368:
llListenRemove(ListenChannel);
llListenRemove(ListenChannel);
message = llToLower(message);
message = llToLower(message);
 
if (message == "learnmore")
if (message == "learnmore")
{
{
Line 392: Line 392:
}
}
}
}
 
timer()
timer()
{
{
llSetTimerEvent(0.0);
llSetTimerEvent(0.0);
Line 399: Line 399:
}
}


 
//default end
//default end
}
}


</lsl>
</lsl>

Revision as of 11:16, 10 January 2008

~ RANDOM AV PROFILE PICTURE PROJECTOR v5.1 by Debbie Trilling ~

Profile: http://wiki.secondlife.com/wiki/User:Debbie_Trilling

<lsl> // ~ RANDOM AV PROFILE PICTURE PROJECTOR v5.1 by Debbie Trilling ~

// *** This script randomly selects an AV from a crowd & then displays their // profile picture as texture on a prim and/or a 'holographic' image projected above the prim***

// Free to use as you wish by under condition that the title and this introduction remain in place, // and that due credit continues to be given to Moriash Moreau, Jana Kamachi and Solar Alter, and // Debbie Trilling.

// TOUCH to switch ON and OFF

// ** PARAMETERS THAT YOU CAN CHANGE **


//************************ // GENERAL PARAMETERS //************************ // how often in seconds the sensor fires float RepeatTime = 35.00;

// sensor range in meters. Maximum 96m but in practice 10 to 30m because of particle draw distance float Range = 25.00;

// sets the number of consecutive times that the scanner is allowed to operate without having located an AV within range // eg: if RepeatTime = 60.0 seconds and TotalNoScansAllowed = 30, then the toy will operate for 1800 seconds (60x30, or 30 minutes) without locating // anyone before it automatically powers down. Set to '0' to disable the auto-off function integer TotalNoScansAllowed = 20;

// sets whether the DefaultTexture will be textured/projected when the toy is switched OFF. 'TRUE' to texture/project; 'FALSE' to have no texturing/projection when off integer ProjectDefaultTexture = TRUE;

// texture palette of UUID's. One will be randomly selected for display when an AV without a profile pic is selected list DefaultTexture = ["7cfd684e-2141-941c-eac8-bd439f0d5a9f", "d02531dd-491c-45b5-2cab-2e47ec81ec0d", "c3eebd9e-ee92-a16f-f906-bc275928df86"];


//************************ // PARTICLE EMISSION PARAMETERS //************************ // set to TRUE to display the profile picture as a particle 'holographic' image above the prim integer DisplayBanner = TRUE;

// width size in meters of the projected image (max 4.00) float Size = 2.50;

// height above object the centre of projected image will be (theoretical max. 50.0, in practice 2.0 to 10.0)) float Height = 2.50;


//************************ // PRIM TEXTURE PARAMETERS //************************ // set to TRUE to texture the prim with the profile picture on ALL_SIDES integer TexturePrim = TRUE;

// the following 'Prim*' parameters effect the prim only if ProjectDefaultTexture and/or TexturePrim = FALSE // if either = TRUE then the prim is automatically set to solid blank white with full bright // texture to use for the prim when toy is OFF key PrimTexture = "5748decc-f629-461c-9a36-a35a221fe21f";

// set to TRUE to turn on Full Bright on ALL_SIDES when the toy is OFF integer PrimFullBright = FALSE;

// vector for the prim colour when toy is OFF vector PrimColour = <0.0, 0.0, 0.0>;

// set the alpha of the prim from 0.0 (clear) to 1.0 (solid) for when toy is OFF float PrimAlpha = 1.00;


//************************ // SHOUTOUT PARAMETERS //************************ // set to 'TRUE' to give a 'ShoutOut' to the AV once they have been selected; 'FALSE' for no 'ShoutOut' integer ShoutOut = TRUE;

// text to 'ShoutOut' when an AV's profile is projected. Text will be preceeded by their name, eg: "<AV Name>'s face is up in lights!" string ShoutOutText = "'s face is up in lights!";



//************************ // ** DO NOT CHANGE BELOW THIS LINE ** //************************

string URL_FORUMTHREAD = "http://forums.secondlife.com/showthread.php?t=225692"; string URL_WIKIPAGE = "http://wiki.secondlife.com/wiki/User:Debbie_Trilling"; string URL_RESIDENT = "http://world.secondlife.com/resident/"; key LastTexture = ""; integer Power = FALSE; integer NoSensorCounter = 0; key AVKey = ""; key DetectedUser = ""; key ObjectOwner = ""; string OwnerName = ""; string ObjectName = "Profile Projector"; string Author = "Debbie Trilling"; string Supplier = "The Particle Crucible"; string Version = " v5.1"; integer ListenChannel; float DialogTimeout = 20.0; list KillJoyListing = [];



GiveShoutOut() { // any interaction with selected AV (give Inventory items etc) can safely be done from this function // this function will only execute if ShoutOut == TRUE

//although fondly calling it a 'ShoutOut', it actually makes more sense to keep within the 20m range of llSay llSay(0, llKey2Name(AVKey) + ShoutOutText);

}


ProjectTexture() { // are we going to use a default texture when toy is OFF? if (ProjectDefaultTexture) { if (TexturePrim) { // using a default texture; if putting texture on the prim, let's make sure it is solid white, blank. full bright llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0 ]); } else { // not texturing the prim, so apply the prom preferences ApplyPrimPrefs(); } ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture)))); } else { // we're not doing anything when the toy is OFF; change the prim to user preferences llParticleSystem([]); ApplyPrimPrefs(); } }

ApplyPrimPrefs() { llSetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES, PrimFullBright, PRIM_TEXTURE, ALL_SIDES, PrimTexture, <1.000000, 1.000000, 0.000000>, <0.000000, 0.000000, 0.000000>, 0.000000, PRIM_COLOR, ALL_SIDES, PrimColour, PrimAlpha ]); }


ParticleStart(key texture) { if (DisplayBanner) { //core code by Moriash Moreau. Adapted to suit by Debbie Trilling llParticleSystem([ PSYS_PART_FLAGS, 0, PSYS_SRC_PATTERN, 4, PSYS_PART_START_ALPHA, 0.50, PSYS_PART_END_ALPHA, 0.50, PSYS_PART_START_COLOR, <1.0,1.0,1.0>, PSYS_PART_END_COLOR, <1.0,1.0,1.0>, PSYS_PART_START_SCALE, <Size * 1.6 ,Size,0.00>, PSYS_PART_END_SCALE, <Size * 1.6,Size,0.00>, PSYS_PART_MAX_AGE, 1.20, PSYS_SRC_MAX_AGE, 0.00, PSYS_SRC_ACCEL, <0.0,0.0,0.0>, PSYS_SRC_ANGLE_BEGIN, 0.00, PSYS_SRC_ANGLE_END, 0.00, PSYS_SRC_BURST_PART_COUNT, 8, PSYS_SRC_BURST_RADIUS, Height, PSYS_SRC_BURST_RATE, 0.10, PSYS_SRC_BURST_SPEED_MIN, 0.00, PSYS_SRC_BURST_SPEED_MAX, 0.00, PSYS_SRC_OMEGA, <0.00,0.00,0.00>, PSYS_SRC_TEXTURE, texture]); }

if (TexturePrim) { llSetTexture(texture, ALL_SIDES); } }

AnnounceWelcome() { llOwnerSay( "\nThank you for your interest in this product created by Debbie Trilling at The Particle Crucible."); }


ShutDown() { llSensorRemove(); llListenRemove(ListenChannel); Power = FALSE; ProjectTexture(); }


default {

on_rez(integer start_param) { // reset script on rez AnnounceWelcome(); llResetScript(); }

changed( integer change ) { if(change & CHANGED_OWNER ) { // reset script on change of owner AnnounceWelcome(); llResetScript(); } }

state_entry() { //initialise system llParticleSystem([]); ObjectOwner = llGetOwner(); OwnerName = llKey2Name(ObjectOwner); llSetObjectName(ObjectName + Version); llSetObjectDesc("Supplied free by " + Author + "'s " + Supplier); ProjectTexture(); llOwnerSay("\nTOUCH the " + ObjectName + " to switch it ON and OFF."); }

touch_start(integer total_number) { if (llDetectedKey(0) == ObjectOwner) { // operation by Owner Only if (Power) { // touch to OFF ShutDown(); llOwnerSay("\nThe " + ObjectName + " is now switched OFF."); } else { // touch to ON Power = TRUE; NoSensorCounter = 0; llSensorRepeat("",NULL_KEY,AGENT,Range,PI,RepeatTime); llOwnerSay("\nThe " + ObjectName + " is now switched ON. Please wait..."); } } else { // touched by someone other than Owner. Send them a message & a dialog box of options DetectedUser = llDetectedKey(0); llInstantMessage(DetectedUser, "\nThank you for your interest in the " + ObjectName + " created by " + Author + "\nThe dialog menu offers a number of options."); integer CommChannel = (-200000 - ((integer)llFrand(12345) * -1)); list MenuItems = ["LearnMore","GetScript"]; string MenuText = "MAIN MENU: Please make a selection within " + (string)llFloor(DialogTimeout) + " seconds.\n- LearnMore: Read the forum thread on this product\n- GetScript: Get yourself a free copy of this script"; // if already on 'Exclude List', give opportunity to clear their name, else give opportunity to exclude their name if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 ) { // they are on the 'Exclude List' so give opportunity to clear their name MenuItems = MenuItems + (list)"IncludeMe"; MenuText = MenuText + "\n- IncludeMe: Have the " + ObjectName + " include you in on the fun!"; } else { // they are not on the 'Exclude List' so give opportunity to add their name MenuItems = MenuItems + (list)"ExcludeMe"; MenuText = MenuText + "\n- ExcludeMe: Have the " + ObjectName + " ignore your presence"; } ListenChannel = llListen(CommChannel, "", DetectedUser, ""); llDialog(DetectedUser, MenuText, MenuItems, CommChannel); llSetTimerEvent(DialogTimeout); } }


sensor(integer total_number) { // save the AV key in case it is needed for a 'ShoutOut' AVKey = llDetectedKey((integer)llFrand(total_number)); // core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling llHTTPRequest( URL_RESIDENT + (string)AVKey,[HTTP_METHOD,"GET"],""); }


no_sensor() { // counts the number of times that the scanner doesn't find anyone in range. If TotalNoScansAllowed is set to greater than zero, automatically powers down the toy // when the number of no_sensors exceeds TotalNoScansAllowed. However, this functionality is disabled if TotalNoScansAllowed is set to zero. NoSensorCounter++; if ((NoSensorCounter > TotalNoScansAllowed) && (TotalNoScansAllowed > 0)) { ShutDown(); llInstantMessage(ObjectOwner, "\nThe " + ObjectName + " has been automatically switched OFF as no Agents have been detected within the set timeframe."); } else { ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture)))); } }


http_response(key req,integer stat, list met, string body) { // core code by Jana Kamachi and Solar Alter. Adapted to suit by Debbie Trilling integer s1 = 0; integer s2 = 0; integer s1l= 0; integer s2l= -3; s1 = llSubStringIndex(body,"<img alt=\"profile image\" src=\"http://secondlife.com/app/image/"); s1l = llStringLength("<img alt=\"profile image\" src=\"http://secondlife.com/app/image/"); s2 = llSubStringIndex(body,"\" class=\"parcelimg\" />");

if(s1 == -1) { // selected AV doesn't have a profile picture, so use the default instead ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture)))); } else { //check whether this was the texture used last time if ((key)llGetSubString(body,s1+s1l,s2+s2l) == LastTexture) { // same profile pic as last time. so display a random default instead ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture)))); // clear the last texture out LastTexture = ""; } else { // are they on the KillJoyListing? if so, we had better pander to their delicate sensibilities & display a random default texture instead if (llListFindList(KillJoyListing, (list)llKey2Name(AVKey)) != -1 ) { // they are on the 'Exclude List' ParticleStart((key)llList2String(DefaultTexture, (integer)llFrand((float)llGetListLength(DefaultTexture)))); } else { // different profile from last time & not on KillJoyListing, so display it ParticleStart((key)llGetSubString(body,s1+s1l,s2+s2l)); // save the key for comparison purposes next time tho' LastTexture = (key)llGetSubString(body,s1+s1l,s2+s2l);

// give a 'ShoutOut', if set to do so if (ShoutOut) { GiveShoutOut(); } } } } }


listen(integer channel, string name, key id, string message) { llSetTimerEvent(0.0); llListenRemove(ListenChannel); message = llToLower(message);

if (message == "learnmore") { llLoadURL(DetectedUser, "Thank you for choosing to learn more about the " + ObjectName + ".\nThis link will take you to the relevant SL forum thread.", URL_FORUMTHREAD); } else if (message == "getscript") { llLoadURL(DetectedUser, "Thank you for choosing to look at the script for the " + ObjectName + ".\nThis link will allow you to get your own copy.", URL_WIKIPAGE); } else if (message == "excludeme") { KillJoyListing = KillJoyListing + llKey2Name(DetectedUser); llInstantMessage(DetectedUser, "You have been added to the 'Exclude List' and the " + ObjectName + " will now ignore your presence"); } else if (message == "includeme") { KillJoyListing = llDeleteSubList(KillJoyListing, llListFindList(KillJoyListing, (list)llKey2Name(DetectedUser)), llListFindList(KillJoyListing, (list)llKey2Name(DetectedUser))); llInstantMessage(DetectedUser, "You has been removed from the 'Exclude List' and the " + ObjectName + " looks forward to selecting you!"); } else { llInstantMessage(DetectedUser, "Unrecognised option or selection made from a timed-out menu."); } }

timer() { llSetTimerEvent(0.0); llListenRemove(ListenChannel); }


//default end }

</lsl>