Difference between revisions of "User:Void Singer/Programs"

From Second Life Wiki
Jump to navigation Jump to search
m (minor changes)
m (Replaced <source> with <syntaxhighlight>; fixed weird comments so that they are properly displayed with formatting inside the SL Wiki; cleaned up some odd lne alignments)
 
(3 intermediate revisions by 2 users not shown)
Line 15: Line 15:


=== Script ===
=== Script ===
<lsl> /*//( v7-D Enh. Color Picker v1.3 )//*/
<syntaxhighlight lang="lsl2"> //*( v7-D Enh. Color Picker v1.3 )//*/
   
   
/*//-- IMPORTANT NOTE
//*-- IMPORTANT NOTE
This Script MUST be
This Script MUST be
placed in one of the
placed in one of the
prims it is going to
prims it is going to
modify or it will not
modify or it will not
work properly!
work properly!
   
   
All Prims that are to
All prims that are to
be modified at the
be modified at the
same time MUST have
same time MUST have
the SAME NAME !!!
the SAME NAME !!!
//*/
//*/


//-- Stores owner key
//-- Stores owner key
key      gKeyOwn;
key      gKeyOwn;
//-- Stores Owner Based Channel
//-- Stores Owner Based Channel
integer  gIntChn;
integer  gIntChn;
//-- Stores User Defined Color
//-- Stores User Defined Color
vector  gColSav;
vector  gColSav;
//-- Stores which color(s) to modify
//-- Stores which color(s) to modify
integer  gIdxPnl;
integer  gIdxPnl;
//-- Stores the link number of all linked prims with the same name
//-- Stores the link number of all linked prims with the same name
list    gLstTgt;
list    gLstTgt;
//-- Stores Name of Product
//-- Stores Name of Product
string  gStrPID = "v7-D Adv Color Picker v1.3";
string  gStrPID = "v7-D Adv Color Picker v1.3";
//-- Stores buttons for the dialog
//-- Stores buttons for the dialog
list    gLstBtn = ["-1", "-8", "-64", "+1", "+8", "+64",
list    gLstBtn = ["-1", "-8", "-64", "+1", "+8", "+64",
                    "Reset", "Done!", "Save",
"Reset", "Done!", "Save",
                    "All Colors", "Red Only", "Green Only", "Blue Only"];
"All Colors", "Red Only", "Green Only", "Blue Only"];
//-- Stores programatic values of buttons
//-- Stores programatic values of buttons
list    gLstVal = [-0.003922, -0.031373, -0.250980, 0.003922, 0.031373, 0.250980,
list    gLstVal = [-0.003922, -0.031373, -0.250980, 0.003922, 0.031373, 0.250980,
                    <1.0, 1.0, 1.0>, <1.0, 0.0, 0.0>, <0.0, 1.0, 0.0>, <0.0, 0.0, 1.0>];
<1.0, 1.0, 1.0>, <1.0, 0.0, 0.0>, <0.0, 1.0, 0.0>, <0.0, 0.0, 1.0>];


//-- builds the dialog to send to the owner
//-- builds the dialog to send to the owner
uDialog(){
uDialog(){
//-- GetThe Current Color of this sets base in 0-255 range
//-- Get The Current Color of this set, base in 0-255 range
vector vColTmp = llGetColor( ALL_SIDES ) * 255;
vector vColTmp = llGetColor( ALL_SIDES ) * 255;
//-- build and send dialog to owner
//-- build and send dialog to owner
llDialog( gKeyOwn,
llDialog( gKeyOwn,
          gStrPID + "\n\nModifying "
  gStrPID + "\n\nModifying "
          + llList2String( gLstBtn, gIdxPnl )
  + llList2String( gLstBtn, gIdxPnl )
          + "\n\nCurrent Values (0-255):\n"
  + "\n\nCurrent Values (0-255):\n"
          + "R:" + (string)llRound( vColTmp.x )
  + "R:" + (string)llRound( vColTmp.x )
          + ", G:" + (string)llRound( vColTmp.y )
  + ", G:" + (string)llRound( vColTmp.y )
          + ", B:" + (string)llRound( vColTmp.z )
  + ", B:" + (string)llRound( vColTmp.z )
          + " = #" + uFlt2Byt( (integer)vColTmp.x )
  + " = #" + uFlt2Byt( (integer)vColTmp.x )
          + uFlt2Byt( (integer)vColTmp.y )
  + uFlt2Byt( (integer)vColTmp.y )
          + uFlt2Byt( (integer)vColTmp.z ),
  + uFlt2Byt( (integer)vColTmp.z ),
          llDeleteSubList( gLstBtn, gIdxPnl, gIdxPnl ),
  llDeleteSubList( gLstBtn, gIdxPnl, gIdxPnl ),
          gIntChn );
  gIntChn );
//-- set timeout to close listen
//-- set timeout to close listen
llSetTimerEvent( 60.0 );
llSetTimerEvent( 60.0 );
}
}


//-- convert float byte to hex byte
//-- convert float byte to hex byte
string uFlt2Byt( float vFltByt ){
string uFlt2Byt( float vFltByt ){
integer vIntByt = llRound( vFltByt );
integer vIntByt = llRound( vFltByt );
string vStrHex = "0123456789ABCDEF";
string vStrHex = "0123456789ABCDEF";
return llGetSubString( vStrHex, vIntByt >> 4, vIntByt >> 4 ) +
return llGetSubString( vStrHex, vIntByt >> 4, vIntByt >> 4 ) +
      llGetSubString( vStrHex, vIntByt & 15, vIntByt & 15 );
  llGetSubString( vStrHex, vIntByt & 15, vIntByt & 15 );
}
}


uSetCol( vector vColUse ){
uSetCol( vector vColUse ){
//-- Clamp Color ranges
//-- Clamp Color ranges
vColUse = <(vColUse.x * (vColUse.x > 0.0) - 1.0) * (vColUse.x < 1.0) + 1.0,
vColUse = <(vColUse.x * (vColUse.x > 0.0) - 1.0) * (vColUse.x < 1.0) + 1.0,
          (vColUse.y * (vColUse.y > 0.0) - 1.0) * (vColUse.y < 1.0) + 1.0,
  (vColUse.y * (vColUse.y > 0.0) - 1.0) * (vColUse.y < 1.0) + 1.0,
          (vColUse.z * (vColUse.z > 0.0) - 1.0) * (vColUse.z < 1.0) + 1.0>;
  (vColUse.z * (vColUse.z > 0.0) - 1.0) * (vColUse.z < 1.0) + 1.0>;
//-- loop through all prims with our name and set them
//-- loop through all prims with our name and set them
integer vIntTmp = gLstTgt != [];
integer vIntTmp = gLstTgt != [];
do{
do{
Line 96: Line 96:
gKeyOwn = llGetOwner();
gKeyOwn = llGetOwner();
gIntChn = (integer)("0xF" + llGetSubString( (string)gKeyOwn, 1, 7 ));
gIntChn = (integer)("0xF" + llGetSubString( (string)gKeyOwn, 1, 7 ));
//-- get the target prim name from current prim
//-- get the target prim name from current prim
string vStrTID = llGetObjectName();
string vStrTID = llGetObjectName();
//-- get the number of prims in the sets
//-- get the number of prims in the sets
integer vIntTmp = llGetNumberOfPrims();
integer vIntTmp = llGetNumberOfPrims();
//-- Check all prims; store ones with our name
//-- Check all prims; store ones with our name
do{
do{
if (llGetLinkName( vIntTmp ) == vStrTID){
if (llGetLinkName( vIntTmp ) == vStrTID){
Line 106: Line 106:
}
}
}while (~(--vIntTmp));
}while (~(--vIntTmp));
//-- avoid dumping the changed event if one is queued
//-- avoid dumping the changed event if one is queued
llSetTimerEvent( 0.01 );
llSetTimerEvent( 0.01 );
}
}
Line 118: Line 118:
timer(){
timer(){
//-- stop timer and exit state
//-- stop timer and exit state
llSetTimerEvent( 0.0 );
llSetTimerEvent( 0.0 );
state sRdy;
state sRdy;
Line 125: Line 125:


state sRdy{
state sRdy{
//-- touch trigger for the dialog (remove next five lines if not needed)
//-- touch trigger for the dialog (remove next five lines if not needed)
touch_end( integer vIntNul ){
touch_end( integer vIntNul ){
if (llDetectedKey( 0 ) == gKeyOwn){
if (llDetectedKey( 0 ) == gKeyOwn){
Line 132: Line 132:
}
}
//-- link message trigger for the dialog (remove next seven lines if not needed)
//-- link message trigger for the dialog (remove next seven lines if not needed)
link_message( integer vIntNul, integer vIntNull, string vStrCmd, key vKeyOwn ){
link_message( integer vIntNul, integer vIntNull, string vStrCmd, key vKeyOwn ){
if (gStrPID == vStrCmd){ //-- string must match product name
if (gStrPID == vStrCmd){ //-- string must match product name
Line 151: Line 151:
state sRun{
state sRun{
state_entry(){
state_entry(){
//-- set default color to modify (9=all, 10=red, 11=green, 12=blue)
//-- set default color to modify (9=all, 10=red, 11=green, 12=blue)
gIdxPnl = 9;
gIdxPnl = 9;
//-- Open Listen to owner only
//-- Open Listen to owner only
llListen( gIntChn, "", gKeyOwn, "" );
llListen( gIntChn, "", gKeyOwn, "" );
//-- send dialog
//-- send dialog
uDialog();
uDialog();
}
}
listen( integer vIntNul, string vStrNul, key vKeyNul, string vStrCmd ){
listen( integer vIntNul, string vStrNul, key vKeyNul, string vStrCmd ){
//-- check which button was pressed
//-- check which button was pressed
integer vIntCmd = llListFindList( gLstBtn, (list)vStrCmd );
integer vIntCmd = llListFindList( gLstBtn, (list)vStrCmd );
if (~vIntCmd){ //-- if input matches a valid button
if (~vIntCmd){ //-- if input matches a valid button
if (6 > vIntCmd){ //-- Cmd 0-5 (add or subtract a color amount)
if (6 > vIntCmd){ //-- Cmd 0-5 (add or subtract a color amount)
//-- multiply to change, by the modification filter, and apply it to the current color
//-- multiply to change, by the modification filter, and apply it to the current color
uSetCol( llList2Float( gLstVal, vIntCmd ) * llList2Vector( gLstVal, gIdxPnl - 3 ) + llGetColor( ALL_SIDES ) );
uSetCol( llList2Float( gLstVal, vIntCmd ) * llList2Vector( gLstVal, gIdxPnl - 3 ) + llGetColor( ALL_SIDES ) );
}else if (9 > vIntCmd){ //-- Cmd 6-8
}else if (9 > vIntCmd){ //-- Cmd 6-8
if (6 == vIntCmd){
if (6 == vIntCmd){
//-- reset to last saved color
//-- reset to last saved color
uSetCol( gColSav );
uSetCol( gColSav );
}else if (7 == vIntCmd){
}else if (7 == vIntCmd){
//-- claer the dialog tiemout and return to ready state (this removes the listen)
//-- claer the dialog tiemout and return to ready state (this removes the listen)
llSetTimerEvent( 0.0 );
llSetTimerEvent( 0.0 );
state sRdy;
state sRdy;
}else{
}else{
//-- save current color and inform user
//-- save current color and inform user
gColSav = llGetColor( ALL_SIDES );
gColSav = llGetColor( ALL_SIDES );
llOwnerSay( gStrPID + ": Color saved." );
llOwnerSay( gStrPID + ": Color saved." );
Line 182: Line 182:
gIdxPnl = vIntCmd;
gIdxPnl = vIntCmd;
}
}
//-- reopen the dialog for further changes
//-- reopen the dialog for further changes
uDialog();
uDialog();
}
}
Line 202: Line 202:
}
}


/*//--                          License Text                          --//*/
//*--                          License Text                          --//*/
/*// Free to copy, use, modify, distribute, or sell, with attribution.  //*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.  //*/
/*//   (C)2010 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*    (C)2010 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*// All usages must contain a plain text copy of the previous 2 lines.  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/</lsl>
//*--                                                                  --//*/</syntaxhighlight>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}
}}
Line 215: Line 215:
|content=
|content=
=== Features ===
=== Features ===
* Next/Pevious Landmark Buttons.
* Next/Previous Landmark Buttons.
* Hovertext Display of Landmark Name.
* Hovertext Display of Landmark Name.
* Auto-Wrapping of Next/Previous Targets.
* Auto-Wrapping of Next/Previous Targets.
Line 222: Line 222:


=== Script (Fast Response Version) ===
=== Script (Fast Response Version) ===
<lsl>/*//-- v7-D Enhanced Landmark Mapper v1.2f --//*/
<syntaxhighlight lang="lsl2">//*-- v7-D Enhanced Landmark Mapper v1.2f --//*/


/*//-- Requirements:
//*-- Requirements:
3 linked Prims (minimum)
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
currently displayed Landmark name. Recommended to rename landmarks.
//*/
//*/


integer gIdxTgt; /*//-- Index of Target --//*/
integer gIdxTgt; //*-- Index of Target --//*/
list    gLstLMs; /*//-- List of Landmarks --//*/
list    gLstLMs; //*-- List of Landmarks --//*/
list    gLstLoc; /*//-- List of Locations--//*/
list    gLstLoc; //*-- List of Locations--//*/


key    gKeySec;      /*//-- Key for Security checking dataserver calls --//*/
key    gKeySec;      //*-- Key for Security checking dataserver calls --//*/
float  gFltTmt = 5.0; /*//-- Float for Timeout (dataserver calls & inventory changes) --//*/
float  gFltTmt = 5.0; //*-- Float for Timeout (dataserver calls & inventory changes) --//*/


default{
default{
Line 243: Line 243:
llOwnerSay( "Rebuilding Database" );
llOwnerSay( "Rebuilding Database" );
gIdxTgt = llGetInventoryNumber( INVENTORY_LANDMARK );
gIdxTgt = llGetInventoryNumber( INVENTORY_LANDMARK );
/*//-- Grab Landmark Names For Display --//*/
//*-- Grab Landmark Names For Display --//*/
if (gIdxTgt){
if (gIdxTgt){
while(gIdxTgt){
while(gIdxTgt){
gLstLMs = (list)llGetInventoryName( INVENTORY_LANDMARK, --gIdxTgt ) + gLstLMs;
gLstLMs = (list)llGetInventoryName( INVENTORY_LANDMARK, --gIdxTgt ) + gLstLMs;
}
}
/*//-- Get First LM Location --//*/
//*-- Get First LM Location --//*/
gKeySec = llRequestInventoryData( llList2String( gLstLMs, gIdxTgt = (gLstLMs != []) - 1 ) );
gKeySec = llRequestInventoryData( llList2String( gLstLMs, gIdxTgt = (gLstLMs != []) - 1 ) );
/*//-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
//*-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
/*//-- negative indices would've been nice if they were supported by the Req.Inv.Data call --//*/
//*-- negative indices would've been nice if they were supported by the Req.Inv.Data call --//*/
llSetTimerEvent( gFltTmt );
llSetTimerEvent( gFltTmt );
}else{
}else{
Line 261: Line 261:
dataserver( key vKeySec, string vStrLoc ){
dataserver( key vKeySec, string vStrLoc ){
/*//-- verify we're getting our data, not another scripts --//*/
//*-- verify we're getting our data, not another scripts --//*/
if (gKeySec == vKeySec){
if (gKeySec == vKeySec){
/*//-- Store Location Vector --//*/
//*-- Store Location Vector --//*/
gLstLoc = (list)((vector)vStrLoc + llGetRegionCorner()) + gLstLoc;
gLstLoc = (list)((vector)vStrLoc + llGetRegionCorner()) + gLstLoc;
if (gIdxTgt){
if (gIdxTgt){
/*//-- Get Next LM Location --//*/
//*-- Get Next LM Location --//*/
gKeySec = llRequestInventoryData( llList2String( gLstLMs, --gIdxTgt ) );
gKeySec = llRequestInventoryData( llList2String( gLstLMs, --gIdxTgt ) );
llSetTimerEvent( gFltTmt );
llSetTimerEvent( gFltTmt );
}else{
}else{
/*//-- Clear Timeout Because Timers Cross States --//*/
//*-- Clear Timeout Because Timers Cross States --//*/
llSetTimerEvent( 0.0 );
llSetTimerEvent( 0.0 );
state sReady;
state sReady;
Line 289: Line 289:
state sReady{
state sReady{
state_entry(){
state_entry(){
/*//-- Set The Initial Display --//*/
//*-- Set The Initial Display --//*/
llSetText( llList2String( gLstLMs, gIdxTgt ), <1.0, 0.0, 0.0>, 1.0 );
llSetText( llList2String( gLstLMs, gIdxTgt ), <1.0, 0.0, 0.0>, 1.0 );
llOwnerSay( "Ready" );
llOwnerSay( "Ready" );
Line 295: Line 295:
touch_end( integer vIntNul ){
touch_end( integer vIntNul ){
/*//-- Check if a prim named "prev" or "next" was touched --//*/
//*-- Check if a prim named "prev" or "next" was touched --//*/
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
if (~vIntTst){
if (~vIntTst){
/*//-- Update Index Target --//*/
//*-- Update Index Target --//*/
gIdxTgt += ((vIntTst > 0) - (vIntTst == 0));
gIdxTgt += ((vIntTst > 0) - (vIntTst == 0));
/*//-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
//*-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
/*//-- Update Display --//*/
//*-- Update Display --//*/
llSetText( llList2String( gLstLMs, (gIdxTgt %= (gLstLMs != [])) ), <1.0, 0.0, 0.0>, 1.0 );
llSetText( llList2String( gLstLMs, (gIdxTgt %= (gLstLMs != [])) ), <1.0, 0.0, 0.0>, 1.0 );
/*//-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
//*-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
/*//-- "gInCnt %= " allows us to wrap our references so they don't go out of range --//*/
//*-- "gInCnt %= " allows us to wrap our references so they don't go out of range --//*/
}else{
}else{
/*//-- Trigger map for any other touched prim in this object --//*/
//*-- Trigger map for any other touched prim in this object --//*/
llMapDestination( llGetRegionName(), llList2Vector( gLstLoc, gIdxTgt ) - llGetRegionCorner(), ZERO_VECTOR );
llMapDestination( llGetRegionName(), llList2Vector( gLstLoc, gIdxTgt ) - llGetRegionCorner(), ZERO_VECTOR );
}
}
Line 314: Line 314:
changed( integer vBitChg ){
changed( integer vBitChg ){
if (CHANGED_INVENTORY & vBitChg){
if (CHANGED_INVENTORY & vBitChg){
/*//-- give the user more time to add new LMs before we recompile our database lists. --//*/
//*-- give the user more time to add new LMs before we recompile our database lists. --//*/
/*//-- We could check the count too, but don't in case the change was a change of name --//*/
//*-- We could check the count too, but don't in case the change was a change of name --//*/
llSetTimerEvent( gFltTmt );
llSetTimerEvent( gFltTmt );
}
}
Line 325: Line 325:
}
}
   
   
/*//--                          License Text                          --//*/
//*--                          License Text                          --//*/
/*// Free to copy, use, modify, distribute, or sell, with attribution.  //*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.  //*/
/*//   (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*// All usages must contain a plain text copy of the previous 2 lines.  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/</lsl>
//*--                                                                  --//*/</syntaxhighlight>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]


=== Script (Small Code Version) ===
=== Script (Small Code Version) ===
<lsl>/*//-- v7-D Enhanced Landmark Mapper v1.2s --//*/
<syntaxhighlight lang="lsl2">//*-- v7-D Enhanced Landmark Mapper v1.2s --//*/
   
   
/*//-- Requirements:
//*-- Requirements:
3 linked Prims (minimum)
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
currently displayed Landmark name. Recommended to rename landmarks.
//*/
//*/


integer gIdxTgt; /*//-- Index of Target LM --//*/
integer gIdxTgt; //*-- Index of Target LM --//*/
string  gStrLMN; /*//-- String of Landmark Name --//*/
string  gStrLMN; //*-- String of Landmark Name --//*/
vector  gPosLoc; /*//-- Position of Location --//*/
vector  gPosLoc; //*-- Position of Location --//*/
key    gKeySec; /*//-- Key for Security checking dataserver calls --//*/
key    gKeySec; //*-- Key for Security checking dataserver calls --//*/


uUpdateLM( integer vIntCng ){
uUpdateLM( integer vIntCng ){
Line 353: Line 353:
if (vIntCnt){
if (vIntCnt){
gIdxTgt = (vIntCnt + gIdxTgt + vIntCng) % vIntCnt;
gIdxTgt = (vIntCnt + gIdxTgt + vIntCng) % vIntCnt;
/*//-- " + vIntCnt" correct for positive index needed by Req.Inv.Dat. --//*/
//*-- " + vIntCnt" correct for positive index needed by Req.Inv.Dat. --//*/
/*//-- " % vIntCnt" range limit for current LM count --//*/
//*-- " % vIntCnt" range limit for current LM count --//*/
gStrLMN = llGetInventoryName( INVENTORY_LANDMARK, gIdxTgt );
gStrLMN = llGetInventoryName( INVENTORY_LANDMARK, gIdxTgt );
gKeySec = llRequestInventoryData( gStrLMN );
gKeySec = llRequestInventoryData( gStrLMN );
Line 360: Line 360:
}
}
else{
else{
/*//-- Uh Oh, set a default of current sim, center, ground level --//*/
//*-- Uh Oh, set a default of current sim, center, ground level --//*/
llSetText( "Out Of Order, No Landmarks Present", <1.0, 0.0, 0.0>, 1.0 );
llSetText( "Out Of Order, No Landmarks Present", <1.0, 0.0, 0.0>, 1.0 );
gPosLoc = <128.0, 128.0, 0.0>;
gPosLoc = <128.0, 128.0, 0.0>;
Line 372: Line 372:
dataserver( key vKeySec, string vStrLoc ){
dataserver( key vKeySec, string vStrLoc ){
/*//-- verify we're getting our data, not another scripts --//*/
//*-- verify we're getting our data, not another scripts --//*/
if (gKeySec == vKeySec){
if (gKeySec == vKeySec){
/*//-- Clear the timeout --//*/
//*-- Clear the timeout --//*/
llSetTimerEvent( 0.0 );
llSetTimerEvent( 0.0 );
/*//-- Store/Display New Target --//*/
//*-- Store/Display New Target --//*/
gPosLoc = (vector)vStrLoc + llGetRegionCorner();
gPosLoc = (vector)vStrLoc + llGetRegionCorner();
llSetText( gStrLMN, <1.0, 0.0, 0.0>, 1.0 );
llSetText( gStrLMN, <1.0, 0.0, 0.0>, 1.0 );
Line 383: Line 383:
touch_end( integer vIntNul ){
touch_end( integer vIntNul ){
/*//-- Check if a prim named "prev" or "next" was touched --//*/
//*-- Check if a prim named "prev" or "next" was touched --//*/
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
if (~vIntTst){
if (~vIntTst){
uUpdateLM( (vIntTst > 0) - (vIntTst == 0) );
uUpdateLM( (vIntTst > 0) - (vIntTst == 0) );
/*//-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
//*-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
}else{
}else{
/*//-- Trigger map for any other touched prim in this object --//*/
//*-- Trigger map for any other touched prim in this object --//*/
llMapDestination( llGetRegionName(), gPosLoc - llGetRegionCorner(), ZERO_VECTOR );
llMapDestination( llGetRegionName(), gPosLoc - llGetRegionCorner(), ZERO_VECTOR );
}
}
Line 395: Line 395:
timer(){
timer(){
/*//-- Make Sure Landmark didn't get deleted before trying to to read it again --//*/
//*-- Make Sure Landmark didn't get deleted before trying to to read it again --//*/
if (INVENTORY_LANDMARK == llGetInventoryType( gStrLM )){
if (INVENTORY_LANDMARK == llGetInventoryType( gStrLM )){
llOwnerSay( "Dataserver Response Timed Out. Unable To Change Destination; Trying Again" );
llOwnerSay( "Dataserver Response Timed Out. Unable To Change Destination; Trying Again" );
gKeySec = llRequestInventoryData( gStrLMN );
gKeySec = llRequestInventoryData( gStrLMN );
}else{ /*//-- Landmark no longer exists in inventory, set a safe default --//*/
}else{ //*-- Landmark no longer exists in inventory, set a safe default --//*/
uUpdateLM( 0 );
uUpdateLM( 0 );
}
}
Line 405: Line 405:
}
}
   
   
/*//--                          License Text                          --//*/
//*--                          License Text                          --//*/
/*// Free to copy, use, modify, distribute, or sell, with attribution.  //*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.  //*/
/*//   (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*// All usages must contain a plain text copy of the previous 2 lines.  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/</lsl>
//*--                                                                  --//*/</syntaxhighlight>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}
}}
Line 423: Line 423:


=== Script ===
=== Script ===
<lsl>/*//( v7-D Advanced Avatar Greeter v1.4.1 Annotated )//*/
<syntaxhighlight lang="lsl2">//*( v7-D Advanced Avatar Greeter v1.4.2 Annotated )//*/


/*//-- NOTE:
//*-- Notes:
Remove Any Instances Of "(gLstAvs = []) + " Or "(gLstTms = []) + " When Compiling This
This script attempts (within the limits of LSL) to only greet avatars once per timeout period.
  Script To MONO. They Are Provided For LSO Memory Conservation And Do Nothing In MONO
The timeout period start when they leave, and favors not re-greeting frequent visitors (perceived as spam).
//*/
   
Remove Lines marked **Dynamic Memory Limitation Section** if you are sure of the max avs you want to store.
Remove Lines marked **Timeout Culling Section** if you want to greet the same avatar only once.
--//*/


list    gLstAvs;       /*//-- List Of Avatars Keys Greeted --//*/
//*-- Core Variables --//*/
list    vLstChk;       /*//-- List Of Single Av Key Checked During Sensor Processing --//*/
list    gLstAvs;         //-- List Of Avatars Keys Greeted
integer vIdxLst;       /*//-- Index Of Checked Item In List (reused) --//*/
list    vLstChk;         //-- List Of Single Av Key Checked During Sensor Processing
integer gIntMax = 500; /*//-- Maximum Number of Names To Store --//*/
integer vIdxLst;         //-- Index Of Checked Item In List (reused)
/*//-- Previous Code Line PreSet to Ease Removing Dynamic Memory Limitation Code --//*/
integer gIntMax = 500;   //-- Maximum Number of Names To Store (ignored if Dynamic Memory used)


/*//-- Next Code Line  Belongs to Dynamic Memory Limitation Section --//*/
//*-- Next Line: **Dynamic Memory Limitation Section** --//*/
integer int_MEM = 1000; /*//-- memory to preserve for safety (Needs to be > ~700)--//*/
integer cINT_MEM = 1024; //-- Memory bytes to preserve for safety (Needs to be > ~768)


/*//-- Start Av Culling Section --//*/
//*-- Start **Timeout Culling Section** --//*/
integer gIntPrd = 172800; /*//-- Number Of Seconds After Detection To Store Av --//*/
integer gIntTmt = 172800; //-- Number Of Seconds since last visit to store Av
integer vIntNow;          /*//-- Integer To Store Current Time During Sensor Processing --//*/
integer vIntNow;          //-- Integer To Store Current Time During Sensor Processing
list    gLstTms;          /*//-- List Of Most Recent Times Avs Were Greeted At --//*/
list    gLstTms;          //-- List Of Most Recent Times Avs Were Greeted At  
list    vLstTmt;          /*//-- List To Store Timeout During Sensor Processing --//*/
list    vLstTmt;          //-- List To Store Calculated Timeout During Sensor Processing
/*//-- End Av Culling Section --//*/
//*-- End **Timeout Culling Section** --//*/


default{
default{
state_entry(){
state_entry(){
/*//-- Next Code Line Belongs To Dynamic Memory Limitation Section --//*/
//-- Next Line: **Dynamic Memory Limitation Section**
gIntMax = int_MEM;                   /*//-- Override Max if Dynamic Memory Limitation is in use --//*/
gIntMax = cINT_MEM;                 //--< **Dynamic Memory Limitation Section**
llSensor( "", "", AGENT, 95.0, PI ); /*//-- Pre-Fire Sensor For Immediate Results --//*/
llSensor( "", "", AGENT, 95.0, PI ); //-- Pre-Fire Sensor for immediate results
llSetTimerEvent( 30.0 );            /*//-- Sensor Repeat Frequency --//*/
llSetTimerEvent( 30.0 );            //-- How often (in seconds) to look for new people
}
}
timer(){
timer(){
llSensor( "", "", AGENT, 95.0, PI ); /*//-- Look For Avatars --//*/
llSensor( "", "", AGENT, 95.0, PI ); //-- Look for avatars
}
}
sensor( integer vIntTtl ){
sensor( integer vIntSns ){ //-- Get "now" and "timeout" once, saving timeout as a list for eas of use
/*//-- Save Current Timer to Now, Then Add Period and Save To Timeout--//*/
vLstTmt = (list)(gIntTmt + (vIntNow = llGetUnixTime())); //--< **Timeout Culling Section**
vLstTmt = (list)(gIntPrd + (vIntNow = llGetUnixTime()));
do{ //-- Have we greeted these av's in our time frame?
/*//-- Previous Code Line Belongs to Av Culling Section --//*/
if (~(vIdxLst = llListFindList( gLstAvs, (vLstChk = (list)llDetectedKey( --vIntSns )) ))){
@Building;{
gLstAvs = vLstChk + llDeleteSubList( gLstAvs, vIdxLst, vIdxLst ); //-- prevents spamming frequent visitors
/*//-- Is This Av Already In Our List? --//*/
gLstTms = vLstTmt + llDeleteSubList( gLstTms, vIdxLst, vIdxLst ); //--< **Timeout Culling Section**
if (~(vIdxLst = llListFindList( gLstAvs, (vLstChk = (list)llDetectedKey( --vIntTtl )) ))){
}else{ //-- New Av, greet and save
/*//-- Delete The Old Entries & Add New Entries to Preserve Order --//*/
llRegionSayTo( (string)vLstChk, 0, "Hello " + llDetectedName( vIntSns ) );
gLstAvs = llDeleteSubList( (gLstAvs = []) + gLstAvs, vIdxLst, vIdxLst ) + vLstChk;
gLstAvs = llList2List( vLstChk + gLstAvs, 0, gIntMax );
/*//-- Next Code Line Belongs to Av Culling Section --//*/
gLstTms = llList2List( vLstTmt + gLstTms, 0, gIntMax ); //--< **Timeout Culling Section**
gLstTms = llDeleteSubList( (gLstTms = []) + gLstTms, vIdxLst, vIdxLst ) + vLstTmt;
}
}
else{
}while (vIntSns);
/*//-- Oo Goody, Hi New Av! Add Them To The Lists & Preserve Max List Size--//*/
//*-- Start **Dynamic Memory Limitation Section** --//*/
llInstantMessage( (string)vLstChk, "Hello " + llDetectedName( vIntTtl ) );
if (cINT_MEM == gIntMax){            //-- check value to see if we need to do this, should happen 1 time only
gLstAvs = llList2List( (gLstAvs = []) + vLstChk + gLstAvs, 0, gIntMax );
if (cINT_MEM > llGetFreeMemory()){ //-- are we running out of free space?
/*//-- Next Code Line Belongs to Av Culling Section --//*/
gIntMax = ~([] != gLstAvs);     //-- Limit list to current_length - 1 to prevent stack/heap collision
gLstTms = llList2List( (gLstTms = []) + vLstTmt + gLstTms, 0, gIntMax );
}
}
}if (vIntTtl) jump Building;
} //*-- End **Dynamic Memory Limitation Section** --//*/
//*-- Start **Timeout Culling Section** --//*/
/*//-- Start Dynamic Memory Limitation Section --//*/
if (vIdxLst = (gLstTms != [])){
/*//-- Only lower Max List Size Once For Saftey --//*/
if (int_MEM == gIntMax){
/*//-- do we have plenty of room in the script? --//*/
if (int_MEM > llGetFreeMemory()){
/*//-- running out of room, set the Max list size lower --//*/
gIntMax = ~([] != gLstAvs);
}
}
/*//-- End Dynamic Memory Limitation Section --//*/
/*//-- Start Av Culling Section --//*/
/*//-- do we have keys? --//*/
if (vIdxLst = llGetListLength( gLstTms )){
/*//-- Do Any Need Culled? --//*/
if (vIntNow > llList2Integer( gLstTms, --vIdxLst )){
if (vIntNow > llList2Integer( gLstTms, --vIdxLst )){
/*//-- Find The Last Index that hasn't hit timeout status --//*/
@Loop;          //-- Find first index of avatars whose time since last greeting expired
@TheirBones; if (--vIdxLst) if (vIntNow > llList2Integer( gLstTms, vIdxLst )) jump TheirBones;
if (--vIdxLst){ //-- special loop structure to emulate short circuiting, while preserving vIndLst
/*//-- Thin the herd --//*/
if (vIntNow < llList2Integer( gLstTms, vIdxLst )){
jump Loop;
}
} //-- Next 2 Lines: Remove Avs whose time has expired
gLstAvs = llList2List( (gLstAvs = []) + gLstAvs, 0, vIdxLst );
gLstAvs = llList2List( (gLstAvs = []) + gLstAvs, 0, vIdxLst );
gLstTms = llList2List( (gLstTms = []) + gLstTms, 0, vIdxLst );
gLstTms = llList2List( (gLstTms = []) + gLstTms, 0, vIdxLst );
}
}
}
} //*-- End **Timeout Culling Section** --//*/
/*//-- End Av Culling Section --//*/
}
}
}
}


/*//--                          License Text                          --//*/
//*--                          License Text                          --//*/
/*// Free to copy, use, modify, distribute, or sell, with attribution.  //*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.  //*/
/*//   (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
/*//   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*// All usages must contain a plain text copy of the previous 2 lines.  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
/*//--                                                                  --//*/</lsl>
//*--                                                                  --//*/</syntaxhighlight>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}
}}

Latest revision as of 13:04, 24 January 2024

v7-D Enh. Color Picker

Features:

  • Dialog driven.
  • Save and Recall.
  • Full 16 million+ colors.
  • Colors multiple linked prims at once.
  • Compatible with standard color picker displays.

Script

 //*( v7-D Enh. Color Picker v1.3 )//*/
 
//*-- IMPORTANT NOTE
This Script MUST be
placed in one of the
prims it is going to
modify or it will not
work properly!
 
All prims that are to
be modified at the
same time MUST have
the SAME NAME !!!
//*/

//-- Stores owner key
key      gKeyOwn;
//-- Stores Owner Based Channel
integer  gIntChn;
//-- Stores User Defined Color
vector   gColSav;
//-- Stores which color(s) to modify
integer  gIdxPnl;
//-- Stores the link number of all linked prims with the same name
list     gLstTgt;
//-- Stores Name of Product
string   gStrPID = "v7-D Adv Color Picker v1.3";
//-- Stores buttons for the dialog
list     gLstBtn = ["-1", "-8", "-64", "+1", "+8", "+64",
					"Reset", "Done!", "Save",
					"All Colors", "Red Only", "Green Only", "Blue Only"];
//-- Stores programatic values of buttons
list     gLstVal = [-0.003922, -0.031373, -0.250980, 0.003922, 0.031373, 0.250980,
					<1.0, 1.0, 1.0>, <1.0, 0.0, 0.0>, <0.0, 1.0, 0.0>, <0.0, 0.0, 1.0>];

//-- builds the dialog to send to the owner
uDialog(){
	//-- Get The Current Color of this set, base in 0-255 range
	vector vColTmp = llGetColor( ALL_SIDES ) * 255;
	//-- build and send dialog to owner
	llDialog( gKeyOwn,
			  gStrPID + "\n\nModifying "
			  + llList2String( gLstBtn, gIdxPnl )
			  + "\n\nCurrent Values (0-255):\n"
			  + "R:" + (string)llRound( vColTmp.x )
			  + ", G:" + (string)llRound( vColTmp.y )
			  + ", B:" + (string)llRound( vColTmp.z )
			  + " = #" + uFlt2Byt( (integer)vColTmp.x )
			  + uFlt2Byt( (integer)vColTmp.y )
			  + uFlt2Byt( (integer)vColTmp.z ),
			  llDeleteSubList( gLstBtn, gIdxPnl, gIdxPnl ),
			  gIntChn );
	//-- set timeout to close listen
	llSetTimerEvent( 60.0 );
}

//-- convert float byte to hex byte
string uFlt2Byt( float vFltByt ){
	integer vIntByt = llRound( vFltByt );
	string vStrHex = "0123456789ABCDEF";
	return llGetSubString( vStrHex, vIntByt >> 4, vIntByt >> 4 ) +
		   llGetSubString( vStrHex, vIntByt & 15, vIntByt & 15 );
}

uSetCol( vector vColUse ){
	//-- Clamp Color ranges
	vColUse = <(vColUse.x * (vColUse.x > 0.0) - 1.0) * (vColUse.x < 1.0) + 1.0,
			   (vColUse.y * (vColUse.y > 0.0) - 1.0) * (vColUse.y < 1.0) + 1.0,
			   (vColUse.z * (vColUse.z > 0.0) - 1.0) * (vColUse.z < 1.0) + 1.0>;
	//-- loop through all prims with our name and set them
	integer vIntTmp = gLstTgt != [];
	do{
		llSetLinkColor( llList2Integer( gLstTgt, --vIntTmp ), vColUse, ALL_SIDES );
	}while (vIntTmp);
}


default{
	state_entry(){
		gKeyOwn = llGetOwner();
		gIntChn = (integer)("0xF" + llGetSubString( (string)gKeyOwn, 1, 7 ));
		//-- get the target prim name from current prim
		string	vStrTID = llGetObjectName();
		//-- get the number of prims in the sets
		integer vIntTmp = llGetNumberOfPrims();
		//-- Check all prims; store ones with our name
		do{
			if (llGetLinkName( vIntTmp ) == vStrTID){
					gLstTgt += (list)vIntTmp;
			}
		}while (~(--vIntTmp));
		//-- avoid dumping the changed event if one is queued
		llSetTimerEvent( 0.01 );
	}
	
	//-- reset script to prevent errors from link or owner changes
	changed( integer vBitChg ){
		if ((CHANGED_LINK | CHANGED_OWNER) & vBitChg){
			llResetScript();
		}
	}
	
	timer(){
		//-- stop timer and exit state
		llSetTimerEvent( 0.0 );
		state sRdy;
	}
}

state sRdy{
	//-- touch trigger for the dialog (remove next five lines if not needed)
	touch_end( integer vIntNul ){
		if (llDetectedKey( 0 ) == gKeyOwn){
			state sRun;
		}
	}
	
	//-- link message trigger for the dialog (remove next seven lines if not needed)
	link_message( integer vIntNul, integer vIntNull, string vStrCmd, key vKeyOwn ){
		if (gStrPID == vStrCmd){ //-- string must match product name
			if (gKeyOwn == vKeyOwn){ //-- key must match owner
				state sRun;
			}
		}
	}
	
	//-- reset script to prevent errors from link or owner changes
	changed( integer vBitChg ){
		if ((CHANGED_LINK | CHANGED_OWNER) & vBitChg){
			llResetScript();
		}
	}
}

state sRun{
	state_entry(){
		//-- set default color to modify (9=all, 10=red, 11=green, 12=blue)
		gIdxPnl = 9;
		//-- Open Listen to owner only
		llListen( gIntChn, "", gKeyOwn, "" );
		//-- send dialog
		uDialog();
	}
	
	listen( integer vIntNul, string vStrNul, key vKeyNul, string vStrCmd ){
		//-- check which button was pressed
		integer vIntCmd = llListFindList( gLstBtn, (list)vStrCmd );
		if (~vIntCmd){ //-- if input matches a valid button
			if (6 > vIntCmd){ //-- Cmd 0-5 (add or subtract a color amount)
				//-- multiply to change, by the modification filter, and apply it to the current color
				uSetCol( llList2Float( gLstVal, vIntCmd ) * llList2Vector( gLstVal, gIdxPnl - 3 ) +	llGetColor( ALL_SIDES ) );
			}else if (9 > vIntCmd){ //-- Cmd 6-8
				if (6 == vIntCmd){
					//-- reset to last saved color
					uSetCol( gColSav );
				}else if (7 == vIntCmd){
					//-- claer the dialog tiemout and return to ready state (this removes the listen)
					llSetTimerEvent( 0.0 );
					state sRdy;
				}else{
					//-- save current color and inform user
					gColSav = llGetColor( ALL_SIDES );
					llOwnerSay( gStrPID + ": Color saved." );
				}
			}else if (13 > vIntCmd){ //-- Cmd 9-12 (change modification filter)
				gIdxPnl = vIntCmd;
			}
			//-- reopen the dialog for further changes
			uDialog();
		}
	}
	
	timer(){
		 //-- timeout the dialog so that the listen isn't left open, return to ready state (this removes the listen)
		llSetTimerEvent( 0.0 );
		llOwnerSay( gStrPID + ": Color Dialog Timed Out." );
		state sRdy;
	}
	
	//-- reset script to prevent errors from link or owner changes
	changed( integer vBitChg ){
		if ((CHANGED_LINK | CHANGED_OWNER) & vBitChg){
			llResetScript();
		}
	}
}

//*--                           License Text                           --//*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
//*    (C)2010 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
//*--                                                                  --//*/
Return to top

v7-D Enh. Landmark-2-Map

Features

  • Next/Previous Landmark Buttons.
  • Hovertext Display of Landmark Name.
  • Auto-Wrapping of Next/Previous Targets.
  • Works as a HUD or a Free-Standing Object.
  • Warning on No Landmarks Found (with safe default).

Script (Fast Response Version)

//*-- v7-D Enhanced Landmark Mapper v1.2f --//*/

//*-- Requirements:
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
//*/

integer gIdxTgt; //*-- Index of Target --//*/
list    gLstLMs; //*-- List of Landmarks --//*/
list    gLstLoc; //*-- List of Locations--//*/

key     gKeySec;       //*-- Key for Security checking dataserver calls --//*/
float   gFltTmt = 5.0; //*-- Float for Timeout (dataserver calls & inventory changes) --//*/

default{
	state_entry(){
		llOwnerSay( "Rebuilding Database" );
		gIdxTgt = llGetInventoryNumber( INVENTORY_LANDMARK );
		//*-- Grab Landmark Names For Display --//*/
		if (gIdxTgt){
			while(gIdxTgt){
				gLstLMs = (list)llGetInventoryName( INVENTORY_LANDMARK, --gIdxTgt ) + gLstLMs;
			}
			//*-- Get First LM Location --//*/
			gKeySec = llRequestInventoryData( llList2String( gLstLMs, gIdxTgt = (gLstLMs != []) - 1 ) );
			//*-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
			//*-- negative indices would've been nice if they were supported by the Req.Inv.Data call --//*/
			llSetTimerEvent( gFltTmt );
		}else{
			gLstLMs = (list)"Out Of Order, No Landmarks Present";
			gLstLoc = (list)<128.0, 128.0, 0.0>;
			state sReady;
		}
	}
	
	dataserver( key vKeySec, string vStrLoc ){
		//*-- verify we're getting our data, not another scripts --//*/
		if (gKeySec == vKeySec){
			//*-- Store Location Vector --//*/
			gLstLoc = (list)((vector)vStrLoc + llGetRegionCorner()) + gLstLoc;
			if (gIdxTgt){
				//*-- Get Next LM Location --//*/
				gKeySec = llRequestInventoryData( llList2String( gLstLMs, --gIdxTgt ) );
				llSetTimerEvent( gFltTmt );
			}else{
				//*-- Clear Timeout Because Timers Cross States --//*/
				llSetTimerEvent( 0.0 );
				state sReady;
			}
		}
	}
	
	timer(){
		if (gKeySec){
			llOwnerSay( "Dataserver Response Timed Out, auto retry in " + (string)((integer)gFltTmt) + " seconds" );
			gKeySec = "";
		}else{
			llResetScript();
		}
	}
}

state sReady{
	state_entry(){
		//*-- Set The Initial Display --//*/
		llSetText( llList2String( gLstLMs, gIdxTgt ), <1.0, 0.0, 0.0>, 1.0 );
		llOwnerSay( "Ready" );
	}
	
	touch_end( integer vIntNul ){
		//*-- Check if a prim named "prev" or "next" was touched --//*/
		integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
		if (~vIntTst){
			//*-- Update Index Target --//*/
			gIdxTgt += ((vIntTst > 0) - (vIntTst == 0));
			//*-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
			
			//*-- Update Display --//*/
			llSetText( llList2String( gLstLMs, (gIdxTgt %= (gLstLMs != [])) ), <1.0, 0.0, 0.0>, 1.0 );
			//*-- (gLstLMs != []) == llGetListLength( gLstLMs ) --//*/
			//*-- "gInCnt %= " allows us to wrap our references so they don't go out of range --//*/
		}else{
			//*-- Trigger map for any other touched prim in this object --//*/
			llMapDestination( llGetRegionName(), llList2Vector( gLstLoc, gIdxTgt ) - llGetRegionCorner(), ZERO_VECTOR );
		}
	}
	
	changed( integer vBitChg ){
		if (CHANGED_INVENTORY & vBitChg){
			//*-- give the user more time to add new LMs before we recompile our database lists. --//*/
			//*-- We could check the count too, but don't in case the change was a change of name --//*/
			llSetTimerEvent( gFltTmt );
		}
	}
	
	timer(){
		llResetScript();
	}
}
 
//*--                           License Text                           --//*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
//*--                                                                  --//*/
Return to top

Script (Small Code Version)

//*-- v7-D Enhanced Landmark Mapper v1.2s --//*/
 
//*-- Requirements:
3 linked Prims (minimum)
1 Named "prev" (this will be your previous landmark button)
1 Named "next" (this will be your next landmark button)
any other prim in the object will trigger the map destination for the
currently displayed Landmark name. Recommended to rename landmarks.
//*/

integer gIdxTgt; //*-- Index of Target LM --//*/
string  gStrLMN; //*-- String of Landmark Name --//*/
vector  gPosLoc; //*-- Position of Location --//*/
key     gKeySec; //*-- Key for Security checking dataserver calls --//*/

uUpdateLM( integer vIntCng ){
	integer vIntCnt = llGetInventoryNumber( INVENTORY_LANDMARK );
	if (vIntCnt){
		gIdxTgt = (vIntCnt + gIdxTgt + vIntCng) % vIntCnt;
		//*-- " + vIntCnt" correct for positive index needed by Req.Inv.Dat. --//*/
		//*-- " % vIntCnt" range limit for current LM count --//*/
		gStrLMN = llGetInventoryName( INVENTORY_LANDMARK, gIdxTgt );
		gKeySec = llRequestInventoryData( gStrLMN );
		llSetTimerEvent( 5.0 );
	}
	else{
		//*-- Uh Oh, set a default of current sim, center, ground level --//*/
		llSetText( "Out Of Order, No Landmarks Present", <1.0, 0.0, 0.0>, 1.0 );
		gPosLoc = <128.0, 128.0, 0.0>;
	}
}

default{
	state_entry(){
		uUpdateLM( 0 );
	}
	
	dataserver( key vKeySec, string vStrLoc ){
		//*-- verify we're getting our data, not another scripts --//*/
		if (gKeySec == vKeySec){
			//*-- Clear the timeout --//*/
			llSetTimerEvent( 0.0 );
			//*-- Store/Display New Target --//*/
			gPosLoc = (vector)vStrLoc + llGetRegionCorner();
			llSetText( gStrLMN, <1.0, 0.0, 0.0>, 1.0 );
		}
	}
	
	touch_end( integer vIntNul ){
		//*-- Check if a prim named "prev" or "next" was touched --//*/
		integer vIntTst = llSubStringIndex( "prevnext", llGetLinkName( llDetectedLinkNumber( 0 ) ) );
		if (~vIntTst){
			uUpdateLM( (vIntTst > 0) - (vIntTst == 0) );
			//*-- ((vIntTst > 0) - (vIntTst < 0)) same as: -1 for "prev", +1 for "next" --//*/
		}else{
			//*-- Trigger map for any other touched prim in this object --//*/
			llMapDestination( llGetRegionName(), gPosLoc - llGetRegionCorner(), ZERO_VECTOR );
		}
	}
	
	timer(){
		 //*-- Make Sure Landmark didn't get deleted before trying to to read it again --//*/
		if (INVENTORY_LANDMARK == llGetInventoryType( gStrLM )){
			llOwnerSay( "Dataserver Response Timed Out. Unable To Change Destination; Trying Again" );
			gKeySec = llRequestInventoryData( gStrLMN );
		}else{ //*-- Landmark no longer exists in inventory, set a safe default --//*/
			uUpdateLM( 0 );
		}
	}
}
 
//*--                           License Text                           --//*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
//*--                                                                  --//*/
Return to top

v7-D Advanced Visitor Greeter

Features:

  • Reduced Spam
  • Easily Modified
  • Multiple Configurations

Script

//*( v7-D Advanced Avatar Greeter v1.4.2 Annotated )//*/

//*-- Notes:
This script attempts (within the limits of LSL) to only greet avatars once per timeout period.
The timeout period start when they leave, and favors not re-greeting frequent visitors (perceived as spam).
 
Remove Lines marked **Dynamic Memory Limitation Section** if you are sure of the max avs you want to store.
Remove Lines marked **Timeout Culling Section** if you want to greet the same avatar only once.
--//*/

//*-- Core Variables --//*/
list    gLstAvs;         //-- List Of Avatars Keys Greeted
list    vLstChk;         //-- List Of Single Av Key Checked During Sensor Processing
integer vIdxLst;         //-- Index Of Checked Item In List (reused)
integer gIntMax = 500;   //-- Maximum Number of Names To Store (ignored if Dynamic Memory used)

//*-- Next Line:  **Dynamic Memory Limitation Section** --//*/
integer cINT_MEM = 1024; //-- Memory bytes to preserve for safety (Needs to be > ~768)

//*-- Start **Timeout Culling Section** --//*/
integer gIntTmt = 172800; //-- Number Of Seconds since last visit to store Av
integer vIntNow;          //-- Integer To Store Current Time During Sensor Processing
list    gLstTms;          //-- List Of Most Recent Times Avs Were Greeted At 
list    vLstTmt;          //-- List To Store Calculated Timeout During Sensor Processing
//*-- End **Timeout Culling Section** --//*/

default{
	state_entry(){
		//-- Next Line: **Dynamic Memory Limitation Section**
		gIntMax = cINT_MEM;                  //--< **Dynamic Memory Limitation Section**
		llSensor( "", "", AGENT, 95.0, PI ); //-- Pre-Fire Sensor for immediate results
		llSetTimerEvent( 30.0 );             //-- How often (in seconds) to look for new people
	}
	
	timer(){
		llSensor( "", "", AGENT, 95.0, PI ); //-- Look for avatars
	}
	
	sensor( integer vIntSns ){ //-- Get "now" and "timeout" once, saving timeout as a list for eas of use
		vLstTmt = (list)(gIntTmt + (vIntNow = llGetUnixTime())); //--< **Timeout Culling Section**
		do{ //-- Have we greeted these av's in our time frame?
			if (~(vIdxLst = llListFindList( gLstAvs, (vLstChk = (list)llDetectedKey( --vIntSns )) ))){
				gLstAvs = vLstChk + llDeleteSubList( gLstAvs, vIdxLst, vIdxLst ); //-- prevents spamming frequent visitors
				gLstTms = vLstTmt + llDeleteSubList( gLstTms, vIdxLst, vIdxLst ); //--< **Timeout Culling Section**
			}else{ //-- New Av, greet and save
				llRegionSayTo( (string)vLstChk, 0, "Hello " + llDetectedName( vIntSns ) );
				gLstAvs = llList2List( vLstChk + gLstAvs, 0, gIntMax );
				gLstTms = llList2List( vLstTmt + gLstTms, 0, gIntMax ); //--< **Timeout Culling Section**
			}
		}while (vIntSns);
		//*-- Start **Dynamic Memory Limitation Section** --//*/
		if (cINT_MEM == gIntMax){            //-- check value to see if we need to do this, should happen 1 time only
			if (cINT_MEM > llGetFreeMemory()){ //-- are we running out of free space?
				gIntMax = ~([] != gLstAvs);      //-- Limit list to current_length - 1 to prevent stack/heap collision
			}
		} //*-- End **Dynamic Memory Limitation Section** --//*/
		//*-- Start **Timeout Culling Section** --//*/
		if (vIdxLst = (gLstTms != [])){
			if (vIntNow > llList2Integer( gLstTms, --vIdxLst )){
				@Loop;          //-- Find first index of avatars whose time since last greeting expired
				if (--vIdxLst){ //-- special loop structure to emulate short circuiting, while preserving vIndLst
					if (vIntNow < llList2Integer( gLstTms, vIdxLst )){
						jump Loop;
					}
				} //-- Next 2 Lines: Remove Avs whose time has expired
				gLstAvs = llList2List( (gLstAvs = []) + gLstAvs, 0, vIdxLst );
				gLstTms = llList2List( (gLstTms = []) + gLstTms, 0, vIdxLst );
			}
		} //*-- End **Timeout Culling Section** --//*/
	}
}

//*--                           License Text                           --//*/
//*  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
//*    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
//*   Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
//*  All usages must contain a plain text copy of the previous 2 lines.  //*/
//*--                                                                  --//*/
Return to top

Questions or Comments?

Feel free to leave me a note on my User Talk page.