Advertisement
Christine_Jacobs

Second Life: Easy Item-Switcher (RLV req.)

Dec 28th, 2014
460
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   The MIT License (MIT)
  3.  
  4.   Copyright (c) 2015 Christine Jacobs
  5.  
  6.   Permission is hereby granted, free of charge, to any person obtaining a copy of
  7.   this software and associated documentation files (the "Software"), to deal in
  8.   the Software without restriction, including without limitation the rights to
  9.   use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10.   the Software, and to permit persons to whom the Software is furnished to do so,
  11.   subject to the following conditions:
  12.  
  13.   The above copyright notice and this permission notice shall be included in all
  14.   copies or substantial portions of the Software.
  15.  
  16.   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18.   FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19.   COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20.   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23.  
  24. /*
  25.     Script by Christine Jacobs
  26.     (ChristineJacobs Resident)
  27.  
  28.     1. Purpose
  29.     This script aims to make changing of items with different styles (such as different colors) easier for the wearer and for other players by providing an intuitive menu.
  30.    
  31.     2. Requirements
  32.     -a RLV-compatible viewer is required, RLV has to be activated and all attach- and detach-RLV-commands must not be blacklisted
  33.    
  34.     3. Preparation:
  35.         1. Make sure you have a #RLV-folder set up.
  36.         2. Create a sub-folder. [Example: "Shirt by SomeCreator"]
  37.         3. Build an item on the floor (go to a sandbox if you need a place where you're allowed to do so).
  38.         4. Pick it up and attack it to your avatar.
  39.         5. Resize and reshape it. It will be the area an user can click on to bring up this scripts menu, so make sure that it is at an intuitive position and that it doesn't cover another item (because then you won't be able to click on this one). Set the transparency of the texture to 100% (CTRL+ALT+T shows transparency, in case you loose it).
  40.         6. Detach the new created items. Move it to the folder which you've created in step 2. Give it a name. If you want your item to be accessed by other add ":public" to its name.
  41.         7. Create sub-folders for all the items you want to control with this script. The name has to be unique in its folder and has to start with a question mark (?). It also has to contain : and the text following it has to be the same as the name of the item which you have created before. If you add another : followed by "default" this item will be auto-attached when you attach the item from step 6.
  42.         8. Attach your item from step 3-6. Enjoy :-)
  43.    
  44.     [Example folder-structure:
  45.         #RLV
  46.         ->    Shirts
  47.             ->    Shirt by SomeCreator
  48.                 ->    Shirt:public (Prim) [see step 6]
  49.                 ->    ?Blue:Shirt:Default
  50.                     ->    BlueShirt (Mesh)
  51.                     ->    Alpha-Mask
  52.                 ->    ?Green:Shirt
  53.                     ->    GreenShirt (Mesh)
  54.                     ->    Alpha-Mask
  55.                 ->    ?White:Shirt
  56.                     ->    WhiteShirt (Mesh)
  57.                     ->    Alpha-Mask
  58.     ]
  59. */
  60.  
  61. string sGroup;  //the group of items to address with this script
  62. string sTopFolder;  //the folder this object is in
  63. list lMenuItems;    //[Label,Foldername]
  64. integer iMenuItemDefault;
  65.  
  66. integer iChannelMenu;
  67. integer iChannelRLVResponseFolder;
  68. integer iChannelRLVResponseSubFolder;
  69.  
  70. integer iListenMenu;
  71. integer iListenRLVRespone;
  72.  
  73.  
  74. integer iTimerTimeForMenuResponse = 60; //the time the script should wait for a response from the user of the menu in seconds
  75. integer iTimerTimeEndMenuResponse;
  76.  
  77. integer iTimerTimeForRLVResponse = 30; //the time the script should wait for a response from the viewer in seconds
  78. integer iTimerTimeEndRLVResponse;
  79.  
  80. integer iAccessPublic;
  81.  
  82. integer iMenuPage;
  83.  
  84. attachById(integer iId){
  85.     if(iId >= 0){
  86.         detach();
  87.    
  88.         string sFolder = llList2String(lMenuItems,iId*2+1);
  89.         llOwnerSay("@attachover:"+sTopFolder+"/"+sFolder+"=force");
  90.     }
  91. }
  92.  
  93. attachDefault(){
  94.     if(iMenuItemDefault >= 0){
  95.         attachById(iMenuItemDefault);
  96.     }
  97. }
  98.  
  99. list buttonsOrder(list lButtons)
  100. {
  101.     //source: http://wiki.secondlife.com/wiki/LlDialog/de
  102.     return llList2List(lButtons, -3, -1) + llList2List(lButtons, -6, -4)
  103.          + llList2List(lButtons, -9, -7) + llList2List(lButtons, -12, -10);
  104. }
  105.  
  106. channelsReset(){
  107.     listenStop();
  108.     iChannelMenu = intRandom(1001,2147483600);
  109.     iChannelRLVResponseFolder= iChannelMenu + 1;
  110.     iChannelRLVResponseSubFolder= iChannelMenu + 2;
  111. }
  112.  
  113. detach(){
  114.     integer i;
  115.     for(i=0;i<llGetListLength(lMenuItems);i+=2){
  116.         llOwnerSay("@detach:"+sTopFolder+"/"+llList2String(lMenuItems,i+1)+"=force");
  117.     }        
  118. }
  119.  
  120. folderParse(string sMessage){
  121.     integer i;
  122.     integer iStringIndex;
  123.     string sItem;
  124.     list lItems = llParseString2List(sMessage,[","],[]);
  125.     list lItem;
  126.     string sLabel;
  127.    
  128.     lMenuItems = [];
  129.    
  130.     for(i=0;i<llGetListLength(lItems);i++){
  131.         sItem = llList2String(lItems,i);
  132.        
  133.         if(llGetSubString(sItem,0,0) == "?"){
  134.            
  135.             lItem = llParseString2List(sItem,[":"],[]);
  136.  
  137.             if(llGetListLength(lItem) > 1 && llToLower(llList2String(lItem,1)) == sGroup){
  138.                
  139.                 if(llGetListLength(lItem) > 2 && llToLower(llList2String(lItem,2)) == "default"){
  140.                     iMenuItemDefault = llGetListLength(lMenuItems)/2;
  141.                 }
  142.                 sLabel = llGetSubString(llList2String(lItem,0),1,22);
  143.                 lMenuItems += [sLabel,sItem];
  144.             }
  145.            
  146.         }
  147.     }    
  148. }
  149.  
  150. listenStartMenu(){
  151.     listenStopMenu();        
  152.  
  153.     iListenMenu = llListen(iChannelMenu,"",NULL_KEY,"");
  154.  
  155.     timerMenuReset();  
  156. }
  157.  
  158. listenStartRLVFolder(){
  159.     listenStopRLV();
  160.     iListenRLVRespone = llListen(iChannelRLVResponseFolder, "" , llGetOwner(), "");
  161.     iTimerTimeEndRLVResponse = llGetUnixTime() + iTimerTimeForRLVResponse ;
  162.     llSetTimerEvent(5);
  163. }
  164.  
  165. listenStartRLVSubFolder(){
  166.     listenStopRLV();
  167.     iListenRLVRespone = llListen(iChannelRLVResponseSubFolder, "" , llGetOwner(), "");
  168.     iTimerTimeEndRLVResponse = llGetUnixTime() + iTimerTimeForRLVResponse ;
  169.     llSetTimerEvent(5);
  170. }
  171.  
  172.  
  173.  
  174. listenStop(){
  175.     listenStopMenu();
  176.     listenStopRLV();
  177. }
  178.  
  179. listenStopMenu(){
  180.     llListenRemove(iListenMenu);
  181.     iTimerTimeEndMenuResponse = 0;
  182. }
  183.  
  184. listenStopRLV(){
  185.     llListenRemove(iListenRLVRespone);
  186.     iTimerTimeEndRLVResponse = 0;
  187. }
  188.  
  189. integer intRandom(integer min, integer max){
  190.     return min + (integer)(llFrand(max - min + 1));
  191. }
  192.  
  193.  
  194.  
  195. menu(key kAvatar){
  196.     listenStartMenu();        
  197.  
  198.     list lButtons = buttonsOrder(menuItems(iMenuPage));  
  199.    
  200.     llDialog(kAvatar,"Please select an item",lButtons,iChannelMenu);
  201.  
  202. }
  203.  
  204. list menuItems(integer iPage){
  205.     integer i;
  206.  
  207.     list lItems;
  208.  
  209.     for(i=iPage*18;i<llGetListLength(lMenuItems)-1 && i<(iPage+1)*18;i+=2){
  210.         lItems += llList2String(lMenuItems,i);
  211.     }  
  212.    
  213.     if(iPage > 0){
  214.         lItems += ["«"];    
  215.     }else{
  216.         lItems += [" "];
  217.     }
  218.     lItems += ["Cancel"];
  219.     if(llGetListLength(lMenuItems) > (iPage+1)*18){
  220.         lItems += ["»"];    
  221.     }else{
  222.         lItems += [" "];
  223.     }
  224.    
  225.     return lItems;
  226. }
  227.  
  228.  
  229.  
  230. menuResponse(key kId, string sMessage){
  231.     timerMenuReset();
  232.     if(sMessage == "Cancel"){
  233.         listenStopMenu();
  234.     }else if (sMessage == "«"){
  235.         if(iMenuPage>0){
  236.             iMenuPage--;
  237.            
  238.         }
  239.         menu(kId);
  240.     }else if (sMessage == "»"){
  241.         if(llGetListLength(lMenuItems)>(iMenuPage+1)*18){
  242.             iMenuPage++;
  243.            
  244.         }
  245.         menu(kId);
  246.     }else{
  247.         integer iIndex = llListFindList(lMenuItems,[sMessage]);
  248.         attachById(iIndex/2);
  249.         menu(kId);
  250.     }
  251. }
  252.  
  253. nameParse(){
  254.     list lName = llParseString2List(llGetObjectName(),[":"],[]);
  255.     sGroup = llToLower(llList2String(lName,0));
  256.    
  257.     if(llGetListLength(lName) > 0 && llToLower(llList2String(lName,1)) == "public"){
  258.         iAccessPublic = 1;
  259.     }else{
  260.         iAccessPublic = 0;
  261.     }
  262. }
  263.  
  264. startup(){
  265.     iMenuItemDefault = -1;    
  266.  
  267.  
  268.     nameParse();
  269.    
  270.     channelsReset();
  271.     listenStartRLVFolder();
  272.     llSleep(0.1); //give the script some time to realize where it is
  273.     llOwnerSay("@getpath="+(string)iChannelRLVResponseFolder);    
  274. }
  275.  
  276. timerMenuReset(){
  277.     llSetTimerEvent(5);
  278.     iTimerTimeEndMenuResponse = llGetUnixTime() +iTimerTimeForMenuResponse;  
  279. }
  280.  
  281. default{
  282.     attach(key kId){
  283.         if(kId== NULL_KEY){
  284.             //the item has been dettached, clean up everything
  285.             listenStop();
  286.         }else{
  287.             //the item has been attached
  288.             startup();
  289.         }
  290.     }
  291.    
  292.     listen( integer iChannel, string sName, key kId, string sMessage){
  293.         if(iChannel == iChannelRLVResponseFolder){
  294.             sTopFolder = sMessage;
  295.             listenStartRLVSubFolder();
  296.             llOwnerSay("@getinv:"+sTopFolder+"="+(string)iChannelRLVResponseSubFolder);
  297.         }else if(iChannel == iChannelRLVResponseSubFolder){
  298.             folderParse(sMessage);
  299.             attachDefault();
  300.             listenStopRLV();
  301.         }else if(iChannel == iChannelMenu){
  302.             if(kId == llGetOwner() || iAccessPublic == 1){
  303.                 menuResponse(kId,sMessage);
  304.             }
  305.         }
  306.     }
  307.    
  308.     state_entry(){
  309.         startup();
  310.     }
  311.    
  312.     timer(){
  313.         integer time = llGetUnixTime();
  314.         if(iTimerTimeEndRLVResponse < time){
  315.             listenStopRLV();
  316.         }
  317.        
  318.         if(iTimerTimeEndMenuResponse < time){
  319.             listenStopMenu();
  320.         }
  321.        
  322.        
  323.         if(iTimerTimeEndMenuResponse < time && iTimerTimeEndRLVResponse < time){
  324.             llSetTimerEvent(0);  
  325.         }
  326.    
  327.        
  328.     }
  329.      
  330.     touch_start(integer iDetected){
  331.         key kAvatar = llDetectedKey(0);
  332.         if(kAvatar == llGetOwner()){
  333.             iMenuPage = 0;
  334.             menu(kAvatar);
  335.         }else if(iAccessPublic == 1){
  336.             iMenuPage = 0;
  337.             menu(kAvatar);
  338.         }
  339.     }
  340.      
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement