diff options
| author | Dave Seikel | 2018-05-20 23:17:24 +1000 |
|---|---|---|
| committer | Dave Seikel | 2018-05-20 23:17:24 +1000 |
| commit | 9dd74045373c39d8a35a59f3c2801b0348a44a9b (patch) | |
| tree | b3cdc4ba800ffa44b98291ce12a0eb1c9ad809e4 /~MLP lite tools.lsl | |
| parent | Initial commit (diff) | |
| download | MLP-lite-9dd74045373c39d8a35a59f3c2801b0348a44a9b.zip MLP-lite-9dd74045373c39d8a35a59f3c2801b0348a44a9b.tar.gz MLP-lite-9dd74045373c39d8a35a59f3c2801b0348a44a9b.tar.bz2 MLP-lite-9dd74045373c39d8a35a59f3c2801b0348a44a9b.tar.xz | |
Initial commit.
This is the current alpha version, it was time to put it somewhere.
Diffstat (limited to '')
| -rw-r--r-- | ~MLP lite tools.lsl | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/~MLP lite tools.lsl b/~MLP lite tools.lsl new file mode 100644 index 0000000..b8e9925 --- /dev/null +++ b/~MLP lite tools.lsl | |||
| @@ -0,0 +1,595 @@ | |||
| 1 | // | ||
| 2 | // MLP lite v3.0 for OpenSim | ||
| 3 | // Based on the original MLP - MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License) | ||
| 4 | // This code has bounced around the Second Life and OpenSim for over a decade, with various people working on it. | ||
| 5 | // MLP lite for OpenSim is almost a complete rewrite by onefang rejected. | ||
| 6 | |||
| 7 | string Version = "MLP lite tools v3.0 alpha"; | ||
| 8 | |||
| 9 | key Owner; | ||
| 10 | integer Channel; | ||
| 11 | |||
| 12 | list Need = []; | ||
| 13 | string Todo = ""; | ||
| 14 | |||
| 15 | // NOTE - This one uses \n to separate sub lists, coz | is used in some of the commands. | ||
| 16 | list Menus; // List of menus. | ||
| 17 | integer MENU_NAME = 0; // Name of menu. | ||
| 18 | integer MENU_AUTH = 1; // Authorised users of menu - 0 = owner, 1 = group, 2 = all | ||
| 19 | integer MENU_COLOURS = 2; // \n spearated list of ball colours. | ||
| 20 | integer MENU_ENTRIES = 3; // \n separated list of entries. | ||
| 21 | integer MENU_CMDS = 4; // \n separated list of commands, matching the entries. | ||
| 22 | integer MENU_SWAPS = 5; // \n separated list of colour sets. | ||
| 23 | integer MENU_STRIDE = 6; | ||
| 24 | |||
| 25 | string Pose = ""; | ||
| 26 | list Poses; // List of poses. | ||
| 27 | integer POSE_NAME = 0; // Name of pose. | ||
| 28 | integer POSE_ANIM = 1; // | separated animations. | ||
| 29 | integer POSE_EMOTE = 2; // | separated emotions and timers list. | ||
| 30 | integer POSE_POSROT = 3; // | separated posiiton and rotation pairs. | ||
| 31 | integer POSE_STRIDE = 4; | ||
| 32 | |||
| 33 | list Props; // List of props. | ||
| 34 | integer PROP_NAME = 0; // Name of prop, which should match a POSE name. | ||
| 35 | integer PROP_OBJECT = 1; // | separated names of props in inventory. | ||
| 36 | integer PROP_POSROT = 2; // | separated position and rotation pairs. | ||
| 37 | integer PROP_STRIDE = 3; | ||
| 38 | |||
| 39 | list Sounds; | ||
| 40 | integer SOUND_NAME = 0; | ||
| 41 | integer SOUND_INV = 1; | ||
| 42 | integer SOUND_STRIDE = 2; | ||
| 43 | |||
| 44 | string LIST_SEP = "$!#"; // Used to seperate lists when sending them as strings. | ||
| 45 | |||
| 46 | // The various link messages. The first lot are historical. | ||
| 47 | //integer OLD_TOUCH = -1; // msg = "PRIMTOUCH" | ||
| 48 | integer OLD_POSEB = 0; // msg = "POSEB" id = pose name | ||
| 49 | // // Also CHECK1 and CHECK2 instead of pose name. | ||
| 50 | integer OLD_STOP = 1; // msg = "STOP" | ||
| 51 | //integer OLD_REF = 8; // msg = RefPos id = RefRot | ||
| 52 | integer OLD_SITS = -11000; // msg = ball number|anim name id = avatar key | ||
| 53 | integer OLD_STANDS = -11001; // msg = ball number id = avatar key | ||
| 54 | integer OLD_ANIM = -11002; // msg = ball number|anim name id = avatar key | ||
| 55 | //integer SEQ_CMD = -12001; // msg = ~sequencer command | ||
| 56 | integer OLD_CMD = -12002; // msg = menu command for ~MLP id = user key | ||
| 57 | |||
| 58 | integer MLP_CMD = -13001; // A command that ~MLP dealt with, so other scripts can hook it. | ||
| 59 | integer TOOL_DATA = -13002; // Get Menus, Poses, Props, or Sounds list. | ||
| 60 | integer MLP_DATA = -13003; // Set Menus, Poses, Props, or Sounds list. | ||
| 61 | integer MLP_POSE = -13004; // doPose(pose, type); | ||
| 62 | integer MLP_UNKNOWN = -13005; // ~MLP doesn't know this command, might be for other scripts. | ||
| 63 | |||
| 64 | // Types for doPose(), | ||
| 65 | integer POSES_POSE = -14001; // Change pose, even if it's changing to the same pose. | ||
| 66 | integer POSES_SWAP = -14002; // Swap poses. | ||
| 67 | integer POSES_DUMP = -14003; // Dump or save poses. | ||
| 68 | integer POSES_Z = -14004; // Change height. | ||
| 69 | |||
| 70 | integer PERMS_CT = PERM_COPY | PERM_TRANSFER; | ||
| 71 | |||
| 72 | |||
| 73 | integer listFindString(list lst, string name, integer stride) | ||
| 74 | { | ||
| 75 | integer f = llListFindList(lst, [name]); | ||
| 76 | integer ix = f / stride; | ||
| 77 | |||
| 78 | // Round to nearest stride. | ||
| 79 | ix = ix * stride; | ||
| 80 | |||
| 81 | // Sanity check, make sure we found a name, not something else, else do it the slow way. | ||
| 82 | if ((-1 != f) && (ix != f)) | ||
| 83 | { | ||
| 84 | integer l = llGetListLength(lst); | ||
| 85 | integer i; | ||
| 86 | |||
| 87 | f = -1; | ||
| 88 | for (i = 0; i < l; i += stride) | ||
| 89 | { | ||
| 90 | if (llList2String(lst, i) == name) | ||
| 91 | { | ||
| 92 | f = i; | ||
| 93 | i = l; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | return f; | ||
| 98 | } | ||
| 99 | |||
| 100 | integer findMenu(string name) | ||
| 101 | { | ||
| 102 | return listFindString(Menus, name, MENU_STRIDE); | ||
| 103 | } | ||
| 104 | |||
| 105 | list reportPose() | ||
| 106 | { | ||
| 107 | list result = []; | ||
| 108 | integer l = llGetListLength(Poses); | ||
| 109 | integer i; | ||
| 110 | |||
| 111 | for (i = 0; i < l; i += POSE_STRIDE) | ||
| 112 | { | ||
| 113 | list prs = llParseString2List(llList2String(Poses, i + POSE_POSROT), ["|"], []); | ||
| 114 | string r = "{" + llList2String(Poses, i) + "} "; | ||
| 115 | integer m = llGetListLength(prs); | ||
| 116 | integer j; | ||
| 117 | |||
| 118 | for (j = 0; j < m; j++) | ||
| 119 | r += llList2String(prs, j); | ||
| 120 | result += [r]; | ||
| 121 | } | ||
| 122 | |||
| 123 | return result; | ||
| 124 | } | ||
| 125 | |||
| 126 | list reportProp() | ||
| 127 | { | ||
| 128 | list result = []; | ||
| 129 | integer l = llGetListLength(Props); | ||
| 130 | integer i; | ||
| 131 | |||
| 132 | for (i = 0; i < l; i += PROP_STRIDE) | ||
| 133 | { | ||
| 134 | list obs = llParseString2List(llList2String(Props, i + PROP_OBJECT), ["|"], []); | ||
| 135 | list prs = llParseString2List(llList2String(Props, i + PROP_POSROT), ["|"], []); | ||
| 136 | string r = "|" + llList2String(Props, i) + "|"; | ||
| 137 | integer m = llGetListLength(prs); | ||
| 138 | integer j; | ||
| 139 | |||
| 140 | // See ~MLP lite props for a comment about why this is different from reportPose(). | ||
| 141 | for (j = 0; j < m; j++) | ||
| 142 | r += llList2String(obs, j) + "|" + osReplaceString(llList2String(prs, j), "><", ">/<", -1, 0); | ||
| 143 | result += [r]; | ||
| 144 | } | ||
| 145 | |||
| 146 | return result; | ||
| 147 | } | ||
| 148 | |||
| 149 | list checkPerms(string name, integer type) | ||
| 150 | { | ||
| 151 | list ans = []; | ||
| 152 | integer i = llGetInventoryNumber(type); | ||
| 153 | integer p; | ||
| 154 | |||
| 155 | while (i-- > 0) | ||
| 156 | { | ||
| 157 | string a = llGetInventoryName(type, i); | ||
| 158 | |||
| 159 | ans += [a]; | ||
| 160 | p = llGetInventoryPermMask(a, MASK_OWNER); | ||
| 161 | if (PERMS_CT != (p & PERMS_CT)) | ||
| 162 | llSay(0, name + " '" + a + "' does not have copy or transfer permissions for the owner."); | ||
| 163 | p = llGetInventoryPermMask(a, MASK_NEXT); | ||
| 164 | if (PERMS_CT != (p & PERMS_CT)) | ||
| 165 | llSay(0, name + " '" + a + "' does not have copy or transfer permissions for the next owner."); | ||
| 166 | } | ||
| 167 | return ans; | ||
| 168 | } | ||
| 169 | |||
| 170 | checkConfig() | ||
| 171 | { | ||
| 172 | list ans; | ||
| 173 | integer l = llGetListLength(Poses); | ||
| 174 | integer m; | ||
| 175 | integer i; | ||
| 176 | integer j; | ||
| 177 | integer f; | ||
| 178 | |||
| 179 | llSay(0, "Checking most things..."); | ||
| 180 | ans = checkPerms("Animation", INVENTORY_ANIMATION); | ||
| 181 | for (i = 0; i < l; i += POSE_STRIDE) | ||
| 182 | { | ||
| 183 | string name = llList2String(Poses, i + POSE_NAME); | ||
| 184 | |||
| 185 | if ("" == llList2String(Poses, i + POSE_POSROT)) | ||
| 186 | llSay(0, "No .POSITIONS* entry for '" + name + "'."); | ||
| 187 | else if ("" == llList2String(Poses, i + POSE_ANIM)) | ||
| 188 | { | ||
| 189 | if (("default" != name) && ("stand" != name)) | ||
| 190 | llSay(0, "No .MENUITEMS* entry for '" + name + "'."); | ||
| 191 | } | ||
| 192 | else | ||
| 193 | { | ||
| 194 | list anims = llParseString2List(llList2String(Poses, i + POSE_ANIM), ["|"], []); | ||
| 195 | |||
| 196 | m = llGetListLength(anims); | ||
| 197 | for (j = 0; j < m; j++) | ||
| 198 | { | ||
| 199 | string aname = llList2String(anims, j); | ||
| 200 | |||
| 201 | if (aname != "") | ||
| 202 | { | ||
| 203 | if ((aname != "stand") && (aname != "sit_ground")) | ||
| 204 | { | ||
| 205 | if (llGetSubString(aname, -1, -1) == "*") | ||
| 206 | aname = llGetSubString(aname, 0, -2); | ||
| 207 | else | ||
| 208 | { | ||
| 209 | f = llSubStringIndex(aname, "::"); | ||
| 210 | if (-1 != f) | ||
| 211 | aname = llGetSubString(aname, 0, f - 1); | ||
| 212 | } | ||
| 213 | |||
| 214 | if (llGetInventoryType(aname) != INVENTORY_ANIMATION) | ||
| 215 | llSay(0, "Animation '" + aname + "' is not in inventory (ok for build-in animations, otherwise check)."); | ||
| 216 | f = llListFindList(ans, aname); | ||
| 217 | if (-1 != f) | ||
| 218 | ans = llDeleteSubList(ans, f, f); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | if (0 < llGetListLength(ans)) | ||
| 225 | llSay(0, "These animations are not in any config cards - " + llList2CSV(llListSort(ans, 1, TRUE))); | ||
| 226 | |||
| 227 | ans = checkPerms("Object", INVENTORY_OBJECT); | ||
| 228 | l = llGetListLength(Props); | ||
| 229 | f = llListFindList(ans, "~ball"); | ||
| 230 | if (-1 != f) | ||
| 231 | ans = llDeleteSubList(ans, f, f); | ||
| 232 | for (i = 0; i < l; i += PROP_STRIDE) | ||
| 233 | { | ||
| 234 | list objs = llParseStringKeepNulls(llList2String(Props, i + PROP_OBJECT), ["|"], []); | ||
| 235 | |||
| 236 | m = llGetListLength(objs); | ||
| 237 | for (j = 0; j < m; j++) | ||
| 238 | { | ||
| 239 | string s = llList2String(objs, j); | ||
| 240 | |||
| 241 | f = llListFindList(ans, s); | ||
| 242 | if (-1 != f) | ||
| 243 | ans = llDeleteSubList(ans, f, f); | ||
| 244 | else | ||
| 245 | llSay(0, "Object '" + s + "' is not in inventory."); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | if (0 < llGetListLength(ans)) | ||
| 249 | llSay(0, "These objects are not in any config cards - " + llList2CSV(llListSort(ans, 1, TRUE))); | ||
| 250 | |||
| 251 | ans = checkPerms("Sound", INVENTORY_SOUND); | ||
| 252 | l = llGetListLength(Sounds); | ||
| 253 | if (l) | ||
| 254 | { | ||
| 255 | for (i = 0; i < l; i += SOUND_STRIDE) | ||
| 256 | { | ||
| 257 | string s = llList2String(Sounds, i + SOUND_INV); | ||
| 258 | |||
| 259 | // TODO - No idea why checkPerms() is handing me ["", ""]. | ||
| 260 | if (llStringLength(s)) | ||
| 261 | { | ||
| 262 | f = llListFindList(ans, s); | ||
| 263 | if (-1 != f) | ||
| 264 | ans = llDeleteSubList(ans, f, f); | ||
| 265 | else | ||
| 266 | llSay(0, "Sound '" + s + "' is not in inventory."); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | } | ||
| 270 | if (0 < llGetListLength(ans)) | ||
| 271 | llSay(0, "These sounds are not in any config cards - " + llList2CSV(llListSort(ans, 1, TRUE))); | ||
| 272 | |||
| 273 | l = llGetListLength(Poses); | ||
| 274 | for (i = 0; i < l; i += MENU_STRIDE) | ||
| 275 | { | ||
| 276 | string name = llList2String(Menus, i + MENU_NAME); | ||
| 277 | |||
| 278 | ans = llParseStringKeepNulls(llList2String(Menus, i + MENU_CMDS), ["\n"], []); | ||
| 279 | if (12 < llGetListLength(ans)) | ||
| 280 | llSay(0, "To many menu items in '" + name + "' menu."); | ||
| 281 | m = llGetListLength(ans); | ||
| 282 | for (j = 0; j < m; j++) | ||
| 283 | { | ||
| 284 | string cmd = llList2String(ans, j); | ||
| 285 | |||
| 286 | if ("TOMENU " == llGetSubString(cmd, 0, 6)) | ||
| 287 | { | ||
| 288 | cmd = llGetSubString(cmd, 7, -1); | ||
| 289 | if (-1 == findMenu(cmd)) | ||
| 290 | llSay(0, "Menu '" + cmd + "' not found."); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | list scripts = llParseStringKeepNulls("memory menu menucfg pos pose poser prop props run timeout", [""],[]); | ||
| 296 | list found = []; | ||
| 297 | |||
| 298 | ans = checkPerms("Script", INVENTORY_SCRIPT); | ||
| 299 | l = llGetListLength(scripts); | ||
| 300 | for (i = 0; i < l; i++) | ||
| 301 | { | ||
| 302 | f = llListFindList(ans, ["~" + llList2String(scripts, i)]); | ||
| 303 | if (-1 != f) | ||
| 304 | { | ||
| 305 | found += ["~" + llList2String(scripts, i)]; | ||
| 306 | ans = llDeleteSubList(ans, f, f); | ||
| 307 | } | ||
| 308 | } | ||
| 309 | for (i = 1; i < 9; i++) | ||
| 310 | { | ||
| 311 | f = llListFindList(ans, ["~poser " + i]); | ||
| 312 | if (-1 != f) | ||
| 313 | { | ||
| 314 | found += ["~poser " + i]; | ||
| 315 | ans = llDeleteSubList(ans, f, f); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | f = llListFindList(ans, ["~ball"]); | ||
| 319 | if (-1 != f) | ||
| 320 | { | ||
| 321 | found += ["~ball"]; | ||
| 322 | ans = llDeleteSubList(ans, f, f); | ||
| 323 | llSay(0, "There is a '~ball' script, it should be in the '~ball' object, and in any prop objects."); | ||
| 324 | llSay(0, "There is a '~ball' script, it should NOT be in this '" + llGetObjectName() + "' object."); | ||
| 325 | } | ||
| 326 | f = llListFindList(ans, ["~sequencer"]); | ||
| 327 | if (-1 != f) | ||
| 328 | { | ||
| 329 | ans = llDeleteSubList(ans, f, f); | ||
| 330 | llSay(0, "There is a '~sequencer' script, which you wont need unless you where using the old MLP sequences."); | ||
| 331 | llSay(0, "If any old '.SEQUENCER' cards are in use, try them, see if it still works."); | ||
| 332 | } | ||
| 333 | if (0 < llGetListLength(found)) | ||
| 334 | llSay(0, "These scripts are likely left overs from an older MLP, you can probably remove them - " + llList2CSV(llListSort(found, 1, TRUE))); | ||
| 335 | |||
| 336 | |||
| 337 | f = llListFindList(ans, ["~MLP lite for OpenSim"]); | ||
| 338 | if (-1 != f) | ||
| 339 | ans = llDeleteSubList(ans, f, f); | ||
| 340 | else | ||
| 341 | llSay(0, llGetScriptName() + " says it wants '~MLP lite for OpenSim'."); | ||
| 342 | f = llListFindList(ans, ["~MLP lite tools"]); | ||
| 343 | if (-1 != f) | ||
| 344 | ans = llDeleteSubList(ans, f, f); | ||
| 345 | else | ||
| 346 | llSay(0, llGetScriptName() + " != ~MLP lite tools!"); | ||
| 347 | |||
| 348 | list cards = checkPerms("Notecard", INVENTORY_NOTECARD); | ||
| 349 | l = llGetListLength(cards); | ||
| 350 | f = -1; | ||
| 351 | for (i = 0; i < l; i++) | ||
| 352 | { | ||
| 353 | string crd = llList2String(cards, i); | ||
| 354 | |||
| 355 | if (llSubStringIndex(crd, ".SEQUENCES") == 0) | ||
| 356 | llSay(0, "Old MLP sequences might be in notecard - '" + crd + "'."); | ||
| 357 | if (llSubStringIndex(crd, ".PROPS") == 0) | ||
| 358 | f = i; | ||
| 359 | } | ||
| 360 | if (-1 == f) | ||
| 361 | { | ||
| 362 | f = llListFindList(ans, ["~MLP lite props"]); | ||
| 363 | if (-1 != f) | ||
| 364 | llSay(0, "'~MLP lite props' script is not needed if there are no .PROPS* cards."); | ||
| 365 | } | ||
| 366 | else | ||
| 367 | { | ||
| 368 | f = llListFindList(ans, ["~MLP lite props"]); | ||
| 369 | if (-1 == f) | ||
| 370 | llSay(0, "'~MLP lite props' script is needed if there are .PROPS* cards."); | ||
| 371 | } | ||
| 372 | |||
| 373 | |||
| 374 | llSay(0, "Checks completed."); | ||
| 375 | } | ||
| 376 | |||
| 377 | doMenu(key id) | ||
| 378 | { | ||
| 379 | llDialog(id, Version, [ | ||
| 380 | "All poses", " ", "Quit tools", | ||
| 381 | "Height>>", "Pose match>>", "Adjust pos>>", | ||
| 382 | "RELOAD", "RESET", "REDECORATE", | ||
| 383 | "CHECK", "DUMP", "SAVE" | ||
| 384 | ], Channel); | ||
| 385 | } | ||
| 386 | |||
| 387 | doHeight(key id) | ||
| 388 | { | ||
| 389 | llDialog(id, Version, [ | ||
| 390 | " ", " ", "Back", | ||
| 391 | "Z-1", "Z-5", "Z-25", | ||
| 392 | "Z+1", "Z+5", "Z+25" | ||
| 393 | ], Channel); | ||
| 394 | } | ||
| 395 | |||
| 396 | getData(string name) | ||
| 397 | { | ||
| 398 | Need += [name]; | ||
| 399 | llMessageLinked(LINK_SET, TOOL_DATA, "", name); | ||
| 400 | } | ||
| 401 | |||
| 402 | default | ||
| 403 | { | ||
| 404 | state_entry() | ||
| 405 | { | ||
| 406 | Owner = llGetOwner(); | ||
| 407 | Channel = (integer) ("0x" + llGetSubString((string) llGetKey(), -4, -1) + 1); | ||
| 408 | llListen(Channel, "", Owner, ""); | ||
| 409 | } | ||
| 410 | |||
| 411 | link_message(integer from, integer num, string str, key id) | ||
| 412 | { | ||
| 413 | if (((0 == num) && ("POSEB" == str)) || ((1 == num) && ("STOP" == str))) | ||
| 414 | ; | ||
| 415 | else if ((MLP_UNKNOWN == num) && ("TOOLS" == str)) | ||
| 416 | doMenu(id); | ||
| 417 | else if ((MLP_POSE == num) || (OLD_CMD == num) || (MLP_CMD == num) || (MLP_UNKNOWN == num) | ||
| 418 | || (OLD_SITS == num) || (OLD_STANDS == num) || (OLD_ANIM == num)) | ||
| 419 | ; | ||
| 420 | else if ((TOOL_DATA == num) && ("" == str)) | ||
| 421 | ; | ||
| 422 | else if ((TOOL_DATA == num) && ("" != str)) | ||
| 423 | { | ||
| 424 | list data = llParseStringKeepNulls(llGetSubString(str, llStringLength(LIST_SEP), -1), [LIST_SEP], []); | ||
| 425 | integer f = llListFindList(Need, id); | ||
| 426 | |||
| 427 | if ("Menus" == id) | ||
| 428 | Menus = data; | ||
| 429 | else if ("Poses" == id) | ||
| 430 | Poses = data; | ||
| 431 | else if ("Props" == id) | ||
| 432 | Props = data; | ||
| 433 | else if ("Sounds" == id) | ||
| 434 | Sounds = data; | ||
| 435 | if (-1 != f) | ||
| 436 | { | ||
| 437 | integer i; | ||
| 438 | |||
| 439 | Need = llDeleteSubList(Need, f, f); | ||
| 440 | if (0 == llGetListLength(Need)) | ||
| 441 | { | ||
| 442 | if ("CHECK" == Todo) | ||
| 443 | { | ||
| 444 | checkConfig(); | ||
| 445 | Todo = ""; | ||
| 446 | } | ||
| 447 | else if ("DUMP" == Todo) | ||
| 448 | { | ||
| 449 | string objectName = llGetObjectName(); | ||
| 450 | list report = reportPose(); | ||
| 451 | integer l = llGetListLength(report); | ||
| 452 | |||
| 453 | llSetObjectName("."); | ||
| 454 | llOwnerSay(".POSITIONS---------------------------------------------------------------"); | ||
| 455 | for (i = 0; i < l; i++) | ||
| 456 | llOwnerSay(llList2String(report, i)); | ||
| 457 | llOwnerSay(".PROPS-------------------------------------------------------------------"); | ||
| 458 | report = reportProp(); | ||
| 459 | l = llGetListLength(report); | ||
| 460 | for (i = 0; i < l; i++) | ||
| 461 | llOwnerSay(llList2String(report, i)); | ||
| 462 | llOwnerSay("-------------------------------------------------------------------------"); | ||
| 463 | llSetObjectName(objectName); | ||
| 464 | Todo = ""; | ||
| 465 | } | ||
| 466 | else if ("SAVE" == Todo) | ||
| 467 | { | ||
| 468 | i = llGetInventoryNumber(INVENTORY_NOTECARD); | ||
| 469 | list cards = []; | ||
| 470 | |||
| 471 | llSay(0, "Backing up old cards."); | ||
| 472 | while (i-- > 0) | ||
| 473 | { | ||
| 474 | string item = llGetInventoryName(INVENTORY_NOTECARD, i); | ||
| 475 | |||
| 476 | if ((llSubStringIndex(item, ".POSITIONS") == 0) || (llSubStringIndex(item, ".PROPS") == 0)) | ||
| 477 | cards += [llGetInventoryName(INVENTORY_NOTECARD, i)]; | ||
| 478 | } | ||
| 479 | i = llGetListLength(cards); | ||
| 480 | while (i-- > 0) | ||
| 481 | { | ||
| 482 | string item = llList2String(cards, i); | ||
| 483 | |||
| 484 | osMakeNotecard(".backup" + item, llParseStringKeepNulls(osGetNotecard(item), ["\n"], [])); | ||
| 485 | llRemoveInventory(item); | ||
| 486 | } | ||
| 487 | |||
| 488 | osMakeNotecard(".POSITIONS", reportPose()); | ||
| 489 | llSay(0, "Current ball positions saved to the .POSITIONS notecard."); | ||
| 490 | if (llGetListLength(Props)) | ||
| 491 | { | ||
| 492 | osMakeNotecard(".PROPS", reportProp()); | ||
| 493 | llSay(0, "Current props positions saved to the .PROPS notecard."); | ||
| 494 | } | ||
| 495 | Todo = ""; | ||
| 496 | } | ||
| 497 | else if ("All poses" == Todo) | ||
| 498 | { | ||
| 499 | |||
| 500 | f = llGetListLength(Menus); | ||
| 501 | for (i = 0; i < f; i += MENU_STRIDE) | ||
| 502 | { | ||
| 503 | string name = llList2String(Menus, i + MENU_NAME); | ||
| 504 | list cmds = llParseStringKeepNulls(llList2String(Menus, i + MENU_CMDS), ["\n"], []); | ||
| 505 | integer l = llGetListLength(cmds); | ||
| 506 | integer j; | ||
| 507 | |||
| 508 | llOwnerSay("Running through all the poses in menu '" + name + "'."); | ||
| 509 | for (j = 0; j < l; j++) | ||
| 510 | { | ||
| 511 | string p = llList2String(cmds, j); | ||
| 512 | |||
| 513 | if ("POSE " == llGetSubString(p, 0, 4)) | ||
| 514 | { | ||
| 515 | string pose = llGetSubString(p, 5, -1); | ||
| 516 | |||
| 517 | llMessageLinked(LINK_SET, OLD_CMD, "TOMENU " + name, Owner); | ||
| 518 | llMessageLinked(LINK_SET, MLP_POSE, (string) POSES_POSE, pose); | ||
| 519 | llSleep(5.0); | ||
| 520 | } | ||
| 521 | } | ||
| 522 | } | ||
| 523 | llMessageLinked(LINK_SET, OLD_CMD, "STOP", Owner); | ||
| 524 | llOwnerSay("Finished all poses."); | ||
| 525 | Todo = ""; | ||
| 526 | } | ||
| 527 | } | ||
| 528 | } | ||
| 529 | } | ||
| 530 | else | ||
| 531 | llOwnerSay(llGetScriptName() + " Unknown link message " + num + ", " + str); | ||
| 532 | } | ||
| 533 | |||
| 534 | listen(integer channel, string name, key id, string button) | ||
| 535 | { | ||
| 536 | if ("CHECK" == button) | ||
| 537 | { | ||
| 538 | Todo = button; | ||
| 539 | getData("Menus"); | ||
| 540 | getData("Poses"); | ||
| 541 | if (llGetInventoryType("~MLP lite props") == INVENTORY_SCRIPT) | ||
| 542 | getData("Props"); | ||
| 543 | getData("Sounds"); | ||
| 544 | } | ||
| 545 | else if ("DUMP" == button) | ||
| 546 | { | ||
| 547 | // Save any edits to the current pose first. | ||
| 548 | llMessageLinked(LINK_SET, MLP_POSE, (string) POSES_DUMP, NULL_KEY); | ||
| 549 | getData("Poses"); | ||
| 550 | if (llGetInventoryType("~MLP lite props") == INVENTORY_SCRIPT) | ||
| 551 | getData("Props"); | ||
| 552 | Todo = button; | ||
| 553 | } | ||
| 554 | else if ("SAVE" == button) | ||
| 555 | { | ||
| 556 | // Save any edits to the current pose first. | ||
| 557 | llMessageLinked(LINK_SET, MLP_POSE, (string) POSES_DUMP, NULL_KEY); | ||
| 558 | getData("Poses"); | ||
| 559 | if (llGetInventoryType("~MLP lite props") == INVENTORY_SCRIPT) | ||
| 560 | getData("Props"); | ||
| 561 | Todo = button; | ||
| 562 | } | ||
| 563 | else if ("All poses" == button) | ||
| 564 | { | ||
| 565 | getData("Menus"); | ||
| 566 | Todo = button; | ||
| 567 | } | ||
| 568 | else if ("RESET" == button || "RELOAD" == button || "REDECORATE" == button) | ||
| 569 | llMessageLinked(LINK_SET, OLD_CMD, button, Owner); | ||
| 570 | else if ("Height>>" == button) | ||
| 571 | { | ||
| 572 | doHeight(id); | ||
| 573 | return; | ||
| 574 | } | ||
| 575 | else if ("Z" == llGetSubString(button, 0, 0)) | ||
| 576 | { | ||
| 577 | integer i = (integer) llGetSubString(button, 1, 10); | ||
| 578 | integer Zoffset = (integer) llGetObjectDesc() + i; | ||
| 579 | |||
| 580 | llSetObjectDesc((string) Zoffset); | ||
| 581 | llMessageLinked(LINK_SET, MLP_POSE, (string) POSES_Z, NULL_KEY); | ||
| 582 | llOwnerSay("Height Adjustment: change by " + (string) i + "cm, new offset: " + (string) Zoffset + "cm."); | ||
| 583 | doHeight(id); | ||
| 584 | return; | ||
| 585 | } | ||
| 586 | else if ("Back" == button) | ||
| 587 | ; | ||
| 588 | else if ("Quit tools" == button) | ||
| 589 | { | ||
| 590 | llMessageLinked(LINK_SET, OLD_CMD, "TOMENU", Owner); | ||
| 591 | return; | ||
| 592 | } | ||
| 593 | doMenu(id); | ||
| 594 | } | ||
| 595 | } | ||
