Advertisement
TAnatine

[*TA*] Backup Box

Jul 17th, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // [*TA*] Backup Box
  2. // A script by Tutti Anatine
  3. // Version: DEVELOPMENT
  4. key CREATOR = "95eaa123-5b83-437e-9fe9-90def840da39";
  5.  
  6. // # Contents
  7. // - [Documentation] Description
  8. // - [Documentation] Setup
  9. // - [Documentation] How to use
  10. // - [Documentation] License
  11. // - [Documentation] Known issues
  12. // - [Script] Settings
  13. // - [Script] Logic
  14. // Please read the documentation!
  15.  
  16. // # Description
  17. // This script creates a Backup Box, in which you can store items to back them
  18. // up in your inventory. You can use these to declutter your items or keep
  19. // copies of breakable objects.
  20.  
  21. // # Setup
  22. // 1. Rez a prim of your choice from the build menu, or a custom object. We'll
  23. //    refer to this as "box" from here on.
  24. // 2. Drag this script from your inventory to the box.
  25. // 3. Optional: Open the script in the box and configure the values below the
  26. //    section "Settings."
  27. // 4. Wait for the script to tell you that it's set up.
  28. // 5. Give the object a sensible name through the edit window, so you can easily
  29. //    identify it in your inventory.
  30. // 6. Take the object back into your inventory. This object is your basic backup
  31. //    box, from which you can create new ones.
  32.  
  33. // # How to use
  34. // 1. Drag your basic backup box from your inventory into the world.
  35. // 2. Place the items you want to backup into the inventory of your box. You can
  36. //    do this through the edit window, or by dragging items from your inventory
  37. //    to the box while holding the CTRL button on your keyboard.
  38. // 3. Click the box to open the menu, which allows you to set a custom name and
  39. //    optional description for the box.
  40. // 4. Once everything is ready, take the box into your inventory. From there,
  41. //    you can always drag it back into the world to unpack it from the menu.
  42.  
  43. // # License
  44. // This script is open source. You are free to use it, modify it and spread
  45. // (only) with full permissions. You are not allowed to charge money for this
  46. // script. If you have paid for it, ask for a full refund! Please do not remove
  47. // comment lines but update them if you have functionally modified the script.
  48.  
  49. // # Known issues
  50. // - Due to the way CHANGED_INVENTORY works, the script does not detect when
  51. //   no-copy items are removed from inventory.
  52. //   See also: http://wiki.secondlife.com/wiki/CHANGED_INVENTORY
  53. // - Due to limitations in llGiveInventoryList, you cannot unpack no-copy items.
  54. //   See also: http://wiki.secondlife.com/wiki/LlGiveInventoryList
  55.  
  56. // -----------------------------------------------------------------------------
  57. // Settings
  58. // -----------------------------------------------------------------------------
  59.  
  60. // Set the optional prefix for the object name
  61. string OBJECT_NAME_PREFIX = "[Backup]";
  62.  
  63. // Whether to show floating text
  64. integer ENABLE_FLOATING_TEXT = TRUE;
  65. // The color of the floating text
  66. vector FLOATING_TEXT_COLOR = <1.0, 1.0, 1.0>;
  67. // The transparency of the floating text
  68. float FLOATING_TEXT_ALPHA = 1.0;
  69.  
  70. // Whether to apply a texture to all sides of the object.
  71. integer APPLY_BOX_TEXTURE = FALSE;
  72. // The key of the texture that is applied when APPLY_BOX_TEXTURE is TRUE.
  73. key BOX_TEXTURE = "";
  74.  
  75. // The channel for the menu to communicate on. Should be negative.
  76. integer DIALOG_CHANNEL = -46346436;
  77. // The number of seconds it takes for the menu to stop listening.
  78. float DIALOG_TIMEOUT = 20.0;
  79.  
  80. // -----------------------------------------------------------------------------
  81. // Logic; do not edit below this line unless you know what you're doing!
  82. // -----------------------------------------------------------------------------
  83.  
  84. integer isReady = FALSE;
  85.  
  86. key ownerKey;
  87. list inventoryList;
  88. integer containsNoCopyItems = FALSE;
  89.  
  90. integer dialogHandler;
  91. integer isWaitingForNameInput = FALSE;
  92. integer isWaitingForDescInput = FALSE;
  93.  
  94. indexInventory()
  95. {
  96.     inventoryList = [];
  97.     containsNoCopyItems = FALSE;
  98.     string scriptName = llGetScriptName();
  99.     integer count = llGetInventoryNumber(INVENTORY_ALL);
  100.     string inventoryName;
  101.     integer ownerPerms;
  102.  
  103.     while (count--) {
  104.         inventoryName = llGetInventoryName(INVENTORY_ALL, count);
  105.         if (inventoryName != scriptName) {
  106.             ownerPerms = llGetInventoryPermMask(inventoryName, MASK_OWNER);
  107.             if (!(ownerPerms & PERM_COPY)) {
  108.                 containsNoCopyItems = TRUE;
  109.             } else {
  110.                 inventoryList += [inventoryName];
  111.             }
  112.         }
  113.     }
  114.  
  115.     if (containsNoCopyItems) {
  116.         llOwnerSay("Warning: this object contains no-copy items. Items without copy permissions cannot be unpacked automatically.");
  117.     }
  118.     updateFloatingText();
  119. }
  120.  
  121. updateFloatingText()
  122. {
  123.     if (!ENABLE_FLOATING_TEXT) {
  124.         return;
  125.     }
  126.  
  127.     string text = llGetObjectName();
  128.     if (llGetObjectDesc()) {
  129.         text += "\n" + llGetObjectDesc();
  130.     }
  131.     text += "\nNumber of contents: " + (string) llGetListLength(inventoryList);
  132.     if (containsNoCopyItems) {
  133.         text += "\nWarning: contains no-copy items!";
  134.     }
  135.  
  136.     llSetText(text, FLOATING_TEXT_COLOR, FLOATING_TEXT_ALPHA);
  137. }
  138.  
  139. clearDialogs()
  140. {
  141.     llSetTimerEvent(0.0);
  142.     llListenControl(dialogHandler, FALSE);
  143.     isWaitingForNameInput = FALSE;
  144.     isWaitingForDescInput = FALSE;
  145. }
  146.  
  147. default {
  148.     state_entry()
  149.     {
  150.         llOwnerSay("Initializing, please wait a moment.");
  151.  
  152.         ownerKey = llGetOwner();
  153.         indexInventory();
  154.  
  155.         dialogHandler = llListen(DIALOG_CHANNEL, "", ownerKey, "");
  156.         llListenControl(dialogHandler, FALSE);
  157.  
  158.         if (APPLY_BOX_TEXTURE) {
  159.             llSetTexture(BOX_TEXTURE, ALL_SIDES);
  160.         }
  161.  
  162.         isReady = TRUE;
  163.         llOwnerSay("Finished, touch to open the menu.");
  164.     }
  165.  
  166.     touch_start(integer num_detected)
  167.     {
  168.         if (!isReady) return;
  169.  
  170.         if (llDetectedKey(0) != ownerKey) {
  171.             llWhisper(0, "Only " + llKey2Name(ownerKey) + " can operate this menu.");
  172.             return;
  173.         }
  174.  
  175.         integer numberOfContents = llGetListLength(inventoryList);
  176.         list dialogOptions = ["Unpack", "Reset", "Close", "Set name", "Set descrip."];
  177.         string dialogMessage = "Please choose an option.";
  178.         dialogMessage += "\n\nObject name prefix: " + OBJECT_NAME_PREFIX;
  179.         dialogMessage += "\nNumber of items inside: " + (string) numberOfContents;
  180.  
  181.         llListenControl(dialogHandler, TRUE);
  182.         llDialog(ownerKey, dialogMessage, dialogOptions, DIALOG_CHANNEL);
  183.         llSetTimerEvent(DIALOG_TIMEOUT);
  184.     }
  185.  
  186.     listen(integer channel, string name, key id, string message) {
  187.         llSetTimerEvent(0.0);
  188.  
  189.         // Below is one "(else) if" statement, split up for improved readability
  190.         string action = llToLower(message);
  191.  
  192.         // Dialog: Close the dialog
  193.         if (action == "close") {
  194.             clearDialogs();
  195.         }
  196.  
  197.         // Dialog: Reset the script
  198.         else if (action == "reset") {
  199.             llResetScript();
  200.         }
  201.  
  202.         // Dialog: Give the inventory of the object
  203.         else if (action == "unpack") {
  204.             clearDialogs();
  205.  
  206.             if (llGetListLength(inventoryList) == 0) {
  207.                 llOwnerSay("Cannot unpack, as inventory is empty.");
  208.             } else {
  209.                 llGiveInventoryList(id, llGetObjectName(), inventoryList);
  210.                 if (containsNoCopyItems) {
  211.                     llOwnerSay("Unpacked successfully. Warning: this object contains no-copy items, which cannot be unpacked automatically. Accept the inventory offer to continue, then take no-copy items from this object manually.");
  212.                 } else {
  213.                     llOwnerSay("Unpacked successfully. Accept the inventory offer to continue.");
  214.                 }
  215.             }
  216.         }
  217.  
  218.         // Dialog: Trigger dialog to set the name of the object
  219.         else if (action == "set name") {
  220.             isWaitingForNameInput = TRUE;
  221.  
  222.             llTextBox(id, "Enter a new name.", channel);
  223.             llSetTimerEvent(DIALOG_TIMEOUT);
  224.             llOwnerSay("Provide a new name through the text box.");
  225.         }
  226.  
  227.         // Dialog: Trigger dialog to set the description of the object
  228.         else if (action == "set descrip.") {
  229.             isWaitingForDescInput = TRUE;
  230.  
  231.             llTextBox(id, "Enter a new description.", channel);
  232.             llSetTimerEvent(DIALOG_TIMEOUT);
  233.             llOwnerSay("Provide a new description through the text box.");
  234.         }
  235.  
  236.         // Text box: Set the name of the object
  237.         else if (isWaitingForNameInput) {
  238.             clearDialogs();
  239.  
  240.             string newName = message;
  241.             if (OBJECT_NAME_PREFIX) {
  242.                 newName = OBJECT_NAME_PREFIX + " " + newName;
  243.             }
  244.             llSetObjectName(newName);
  245.             llOwnerSay("Name successfully changed.");
  246.  
  247.             updateFloatingText();
  248.         }
  249.  
  250.         // Text box: Set the description of the object
  251.         else if (isWaitingForDescInput) {
  252.             clearDialogs();
  253.  
  254.             llSetObjectDesc(message);
  255.             llOwnerSay("Description successfully changed.");
  256.  
  257.             updateFloatingText();
  258.         }
  259.  
  260.         // Fallback for invalid input
  261.         else {
  262.             llOwnerSay("Invalid input: \"" + message + "\" (sender: " + name + ").");
  263.             clearDialogs();
  264.         }
  265.     }
  266.  
  267.     timer() {
  268.         clearDialogs();
  269.         llOwnerSay("Time's up! Activate the menu if you want to try again.");
  270.     }
  271.  
  272.     changed(integer change)
  273.     {
  274.         if (!isReady) return;
  275.        
  276.         if ((change & CHANGED_INVENTORY) || (change & CHANGED_ALLOWED_DROP))
  277.         {
  278.             indexInventory();
  279.         }
  280.  
  281.         if (change & CHANGED_OWNER)
  282.         {
  283.             llResetScript();
  284.         }
  285.     }
  286.  
  287.     on_rez(integer start_param)
  288.     {
  289.         llResetScript();
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement