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 '~MLP lite tools.lsl')
-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 | } | ||