Difference between revisions of "User:Void Singer/Programs"
Jump to navigation
Jump to search
Void Singer (talk | contribs) m (New Freebies) |
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) |
||
(7 intermediate revisions by 2 users not shown) | |||
Line 15: | Line 15: | ||
=== Script === | === Script === | ||
< | <syntaxhighlight lang="lsl2"> //*( 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 !!! | |||
//*/ | //*/ | ||
key | //-- Stores owner key | ||
integer | key gKeyOwn; | ||
//-- Stores Owner Based Channel | |||
integer gIntChn; | |||
integer | //-- Stores User Defined Color | ||
vector gColSav; | |||
string | //-- Stores which color(s) to modify | ||
list | integer gIdxPnl; | ||
//-- Stores the link number of all linked prims with the same name | |||
list gLstTgt; | |||
list | //-- 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 ); | |||
} | } | ||
string | //-- 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{ | 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 | 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. //*/ | |||
//*-- --//*/</syntaxhighlight> | |||
/* | |||
Free to copy, use, modify, distribute, or sell, with attribution. | |||
(C) | |||
Void Singer [https://wiki.secondlife.com/wiki/User:Void_Singer] | |||
All usages must contain a plain text copy of the previous 2 lines. | |||
//*/</ | |||
:[[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 192: | Line 215: | ||
|content= | |content= | ||
=== Features === | === Features === | ||
* Next/ | * 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 199: | Line 222: | ||
=== Script (Fast Response Version) === | === Script (Fast Response Version) === | ||
< | <syntaxhighlight lang="lsl2">//*-- 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; /* | integer gIdxTgt; //*-- Index of Target --//*/ | ||
list gLstLMs; /* | list gLstLMs; //*-- List of Landmarks --//*/ | ||
list gLstLoc; /* | list gLstLoc; //*-- List of Locations--//*/ | ||
key gKeySec; /* | key gKeySec; //*-- Key for Security checking dataserver calls --//*/ | ||
float gFltTmt = 5.0; /* | float gFltTmt = 5.0; //*-- Float for Timeout (dataserver calls & inventory changes) --//*/ | ||
default{ | 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 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. | //* 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. //*/ | ||
//*/</ | //*-- --//*/</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) === | ||
< | <syntaxhighlight lang="lsl2">//*-- 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 --//*/ | |||
integer gIdxTgt; /* | |||
string gStrLMN; /* | |||
vector gPosLoc; /* | |||
key gKeySec; /* | |||
uUpdateLM( integer vIntCng ){ | 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{ | 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. //*/ | |||
//*-- --//*/</syntaxhighlight> | |||
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]] | |||
}} | |||
{{void-box | |||
|title=v7-D Advanced Visitor Greeter | |||
|content= | |||
=== Features: === | |||
* Reduced Spam | |||
* Easily Modified | |||
* Multiple Configurations | |||
=== Script === | |||
<syntaxhighlight lang="lsl2">//*( 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. | //* 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. //*/ | ||
//*/</ | //*-- --//*/</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. //*/
//*-- --//*/
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. //*/
//*-- --//*/
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. //*/
//*-- --//*/
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. //*/
//*-- --//*/
Questions or Comments?
Feel free to leave me a note on my User Talk page.