diff options
Diffstat (limited to 'LuaSL/test2.lsl')
-rw-r--r-- | LuaSL/test2.lsl | 412 |
1 files changed, 341 insertions, 71 deletions
diff --git a/LuaSL/test2.lsl b/LuaSL/test2.lsl index 3b93b64..c72b6e2 100644 --- a/LuaSL/test2.lsl +++ b/LuaSL/test2.lsl | |||
@@ -1,108 +1,378 @@ | |||
1 | // MLPV2 Version 2.3j, by Learjeff Innis, based on | 1 | //MPLV2 Version 2.2 by Learjeff Innis, based on |
2 | //MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License) | 2 | //MLP MULTI-LOVE-POSE V1.2 - Copyright (c) 2006, by Miffy Fluffy (BSD License) |
3 | // OpenSim port by Jez Ember | 3 | // OpenSim port by Jez Ember |
4 | // Meta 7 fixes by onefang Rejected and one by Tatjana Kidd. | 4 | // Meta 7 fixes by onefang Rejected |
5 | 5 | ||
6 | integer MAX_BALLS = 6; | 6 | // v2.2 - rotate all poses, cleaner dump |
7 | 7 | ||
8 | integer ch; | 8 | integer Checking = FALSE; // whether doing consistency check |
9 | integer swap; | ||
10 | integer BallCount; | ||
11 | 9 | ||
12 | string pr1; | 10 | integer line; |
13 | string pr2; | 11 | integer PosCount; |
12 | list Poses; // list of pose names | ||
14 | 13 | ||
15 | integer Zoffset; | 14 | // indexed by same index as Poses, entry contains text string of pos/rot pairs, one for each ball in pose |
16 | 15 | ||
17 | vector RefPos; | 16 | // list Positions; |
18 | rotation RefRot; | ||
19 | 17 | ||
20 | getRefPos() { //reference position | 18 | list Positions0; |
21 | RefPos = llGetPos(); | 19 | list Positions1; |
22 | RefRot = llGetRot(); | 20 | list Positions2; |
23 | Zoffset = (integer)llGetObjectDesc(); | 21 | list Positions3; |
24 | RefPos.z += (float) Zoffset / 100.; | 22 | |
23 | vector Pos1; | ||
24 | vector Pos2; | ||
25 | vector Pos3; | ||
26 | vector Pos4; | ||
27 | vector Pos5; | ||
28 | vector Pos6; | ||
29 | vector Rot1; | ||
30 | vector Rot2; | ||
31 | vector Rot3; | ||
32 | vector Rot4; | ||
33 | vector Rot5; | ||
34 | vector Rot6; | ||
35 | integer Ballcount; | ||
36 | |||
37 | // Replacement for llListFindList which is currently broken in OSLSL | ||
38 | integer myListFind(list a, string b) { | ||
39 | integer x; | ||
40 | integer l=llGetListLength(a); | ||
41 | |||
42 | for(x=0; x<l; x++) { | ||
43 | if(llList2String(a,x) == b) { | ||
44 | return x; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | return -1; | ||
49 | } | ||
50 | |||
51 | announce() | ||
52 | { | ||
53 | llOwnerSay((string)PosCount | ||
54 | + " positions stored (" | ||
55 | + llGetScriptName() | ||
56 | + ": " | ||
57 | + (string)llGetFreeMemory() | ||
58 | + " bytes free)"); | ||
59 | } | ||
60 | |||
61 | getPosePos(string pdata) { | ||
62 | list plist = llParseString2List(pdata,[" "],[]); | ||
63 | |||
64 | Ballcount = llGetListLength(plist) / 2; | ||
65 | |||
66 | Pos1 = (vector)llList2String(plist, 0); | ||
67 | Rot1 = (vector)llList2String(plist, 1); | ||
68 | Pos2 = (vector)llList2String(plist, 2); | ||
69 | Rot2 = (vector)llList2String(plist, 3); | ||
70 | Pos3 = (vector)llList2String(plist, 4); | ||
71 | Rot3 = (vector)llList2String(plist, 5); | ||
72 | Pos4 = (vector)llList2String(plist, 6); | ||
73 | Rot4 = (vector)llList2String(plist, 7); | ||
74 | Pos5 = (vector)llList2String(plist, 8); | ||
75 | Rot5 = (vector)llList2String(plist, 8); | ||
76 | Pos6 = (vector)llList2String(plist, 10); | ||
77 | Rot6 = (vector)llList2String(plist, 11); | ||
25 | } | 78 | } |
26 | 79 | ||
27 | list Pdata; | ||
28 | 80 | ||
29 | getPosNew(string pdata) { | 81 | string adjust(integer doOffset, vector pos, vector erot, vector amt) { |
30 | Pdata = llParseString2List(pdata, [" "],[]); | 82 | if (doOffset) { |
83 | pos += amt/100.; | ||
84 | return (vround(pos) + " " + vround(erot)); | ||
85 | } | ||
86 | |||
87 | rotation amount = llEuler2Rot(amt * DEG_TO_RAD); | ||
88 | erot *= DEG_TO_RAD; | ||
89 | |||
90 | rotation oldrot = llEuler2Rot(erot); | ||
91 | rotation newrot = oldrot / amount; | ||
92 | |||
93 | erot = llRot2Euler(newrot) * RAD_TO_DEG; | ||
94 | pos = pos / amount; | ||
95 | return(vround(pos) + " " + vround(erot)); | ||
31 | } | 96 | } |
32 | 97 | ||
33 | setPos() { | 98 | adjust_all(integer doOffset, vector amt) { |
34 | pr1 = (string)((vector)llList2String(Pdata, 0) * RefRot + RefPos); | 99 | integer ix; |
35 | pr2 = (string)((vector)llList2String(Pdata, 2) * RefRot + RefPos); | 100 | integer bx; |
36 | pr1 += (string)(llEuler2Rot((vector)llList2String(Pdata, 1) * DEG_TO_RAD) * RefRot); | 101 | string data; |
37 | pr2 += (string)(llEuler2Rot((vector)llList2String(Pdata, 3) * DEG_TO_RAD) * RefRot); | 102 | for (ix = 0; ix < PosCount; ++ix) { |
38 | if (BallCount > 1) { | 103 | data = get_pose_by_index(ix); |
39 | llSay(ch+swap,pr1); //msg to ball1/2 | 104 | getPosePos(data); |
40 | llSay(ch+!swap,pr2); | 105 | |
106 | list parms = [ Pos1, Rot1, Pos2, Rot2, Pos3, Rot3, Pos4, Rot4, Pos5, Rot5, Pos6, Rot6 ]; | ||
107 | |||
108 | data = adjust(doOffset, Pos1, Rot1, amt); | ||
109 | integer ballix = 1; | ||
110 | while (ballix < Ballcount) { | ||
111 | string stuff = adjust(doOffset, llList2Vector(parms, 2*ballix), llList2Vector(parms, 2*ballix+1), amt); | ||
112 | data += " " + stuff; | ||
113 | ++ballix; | ||
114 | } | ||
115 | store_pose(data, ix); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | |||
120 | string get_pose_data(string name) { | ||
121 | integer ix = myListFind(Poses, name); | ||
122 | |||
123 | // if not found, use default positions | ||
124 | if (ix == -1) { | ||
125 | ix = 0; | ||
126 | } | ||
127 | |||
128 | return (get_pose_by_index(ix)); | ||
129 | } | ||
130 | |||
131 | |||
132 | string get_pose_by_index(integer ix) { | ||
133 | if ((ix & 3) == 0) { | ||
134 | return llList2String(Positions0, ix>>2); | ||
135 | } else if ((ix & 3) == 1) { | ||
136 | return llList2String(Positions1, ix>>2); | ||
137 | } else if ((ix & 3) == 2) { | ||
138 | return llList2String(Positions2, ix>>2); | ||
139 | } | ||
140 | return llList2String(Positions3, ix>>2); | ||
141 | } | ||
142 | |||
143 | store_pose(string data, integer ix) { | ||
144 | if ((ix & 3) == 0) { | ||
145 | Positions0 = llListReplaceList(Positions0,[ data ],ix>>2,ix>>2); | ||
146 | } else if ((ix & 3) == 1) { | ||
147 | Positions1 = llListReplaceList(Positions1,[ data ],ix>>2,ix>>2); | ||
148 | } else if ((ix & 3) == 2) { | ||
149 | Positions2 = llListReplaceList(Positions2,[ data ],ix>>2,ix>>2); | ||
150 | } else if ((ix & 3) == 3) { | ||
151 | Positions3 = llListReplaceList(Positions3,[ data ],ix>>2,ix>>2); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | |||
156 | save_pose(string name, string data) { | ||
157 | integer ix = myListFind(Poses, name); | ||
158 | if (ix == -1) { | ||
159 | add_pose(name, data); | ||
41 | } else { | 160 | } else { |
42 | llSay(ch,pr1); //msg to ball1/2 | 161 | store_pose(data, ix); |
43 | } | 162 | } |
163 | } | ||
164 | |||
165 | add_pose(string name, string data) { | ||
166 | integer ix = myListFind(Poses, name); | ||
167 | if (ix != -1) { | ||
168 | llOwnerSay("===> WARNING: Multiple .POSITIONS* entries for '" + name + "'"); | ||
169 | } else { | ||
170 | Poses += (list) name; | ||
171 | ix = ++PosCount; | ||
172 | } | ||
173 | store_pose(data, ix-1); | ||
174 | } | ||
44 | 175 | ||
176 | check_pose(string name) { | ||
45 | integer ix; | 177 | integer ix; |
46 | for (ix = 2; ix < BallCount; ++ix) { | 178 | |
47 | llSay(ch + ix, (string)((vector)llList2String(Pdata, 2*ix) * RefRot + RefPos) | 179 | // if this is the last pose, report results |
48 | + (string)(llEuler2Rot((vector)llList2String(Pdata, 2*ix + 1) * DEG_TO_RAD) * RefRot)); | 180 | if (name == "CHECK2") { |
181 | string nameA; | ||
182 | for (ix = 0; ix < llGetListLength(Poses); ++ix) { | ||
183 | nameA = llList2String(Poses, ix); | ||
184 | if (get_pose_data(nameA) != "") { | ||
185 | if (nameA != "default" && nameA != "stand") { | ||
186 | llOwnerSay("No .MENUITEMS* entry for '" + nameA + "'."); | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | llOwnerSay("Checks complete, resetting."); | ||
191 | llResetScript(); | ||
192 | } | ||
193 | |||
194 | ix = myListFind(Poses, name); | ||
195 | if (ix == -1) { | ||
196 | llOwnerSay("No .POSITIONS* entry for '" + name + "'."); | ||
197 | return; | ||
49 | } | 198 | } |
199 | save_pose(name, ""); | ||
50 | } | 200 | } |
51 | 201 | ||
52 | getChan() { | 202 | |
53 | ch = (integer)("0x"+llGetSubString((string)llGetKey(),-4,-1)); //fixed channel for prim | 203 | string vround(vector vec) { |
204 | return ("<"+round(vec.x, 3)+","+round(vec.y, 3)+","+round(vec.z, 3)+">"); | ||
54 | } | 205 | } |
55 | 206 | ||
207 | string round(float number, integer places) { | ||
208 | float shifted; | ||
209 | integer rounded; | ||
210 | string s; | ||
211 | shifted = number * llPow(10.0,(float)places); | ||
212 | rounded = llRound(shifted); | ||
213 | s = (string)((float)rounded / llPow(10.0,(float)places)); | ||
214 | rounded = llSubStringIndex(s, "."); | ||
215 | if (-1 != rounded) | ||
216 | s = llGetSubString(s,0,llSubStringIndex(s, ".")+places); | ||
217 | else | ||
218 | { | ||
219 | s += ".00000000"; | ||
220 | s = llGetSubString(s,0,llSubStringIndex(s, ".")+places); | ||
221 | } | ||
222 | return s; | ||
223 | } | ||
224 | |||
225 | dashes() { | ||
226 | llOwnerSay("_______________________________________________________________________________"); | ||
227 | llOwnerSay(""); | ||
228 | } | ||
229 | |||
230 | |||
231 | // Globals for reading card config | ||
232 | integer ConfigLineIndex; | ||
233 | list ConfigCards; // list of names of config cards | ||
234 | string ConfigCardName; // name of card being read | ||
235 | integer ConfigCardIndex; // index of next card to read | ||
236 | key ConfigQueryId; | ||
237 | |||
238 | integer next_card() | ||
239 | { | ||
240 | if (ConfigCardIndex >= llGetListLength(ConfigCards)) { | ||
241 | ConfigCards = []; | ||
242 | return (FALSE); | ||
243 | } | ||
244 | |||
245 | ConfigLineIndex = 0; | ||
246 | ConfigCardName = llList2String(ConfigCards, ConfigCardIndex); | ||
247 | ConfigCardIndex++; | ||
248 | ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); | ||
249 | llOwnerSay("Reading " + ConfigCardName); | ||
250 | return (TRUE); | ||
251 | } | ||
252 | |||
253 | |||
56 | default { | 254 | default { |
57 | state_entry() { | 255 | state_entry() { |
58 | getRefPos(); | 256 | string item; |
59 | getChan(); | 257 | ConfigCards = []; |
60 | } | 258 | integer n = llGetInventoryNumber(INVENTORY_NOTECARD); |
259 | while (n-- > 0) { | ||
260 | item = llGetInventoryName(INVENTORY_NOTECARD, n); | ||
261 | if (llSubStringIndex(item, ".POSITIONS") != -1) { | ||
262 | ConfigCards += (list) item; | ||
263 | } | ||
264 | } | ||
61 | 265 | ||
62 | on_rez(integer arg) { | 266 | ConfigCardIndex = 0; |
63 | getRefPos(); | 267 | ConfigCards = llListSort(ConfigCards, 1, TRUE); |
64 | getChan(); | 268 | next_card(); |
65 | } | 269 | } |
66 | 270 | ||
67 | link_message(integer from, integer num, string cmd, key pkey) { | 271 | dataserver(key query_id, string data) { |
68 | if (cmd == "PRIMTOUCH"){ | 272 | if (query_id != ConfigQueryId) { |
69 | return; | 273 | return; |
70 | } | 274 | } |
275 | if (data == EOF) { | ||
276 | if (next_card()) { | ||
277 | return; | ||
278 | } | ||
279 | state on; | ||
280 | } | ||
281 | if (llGetSubString(data,0,0) != "/") { // skip comments | ||
282 | integer ix = llSubStringIndex(data, "{"); //split name from positions, remove junk | ||
283 | integer jx = llSubStringIndex(data, "} <"); | ||
284 | if (ix != -1 && jx != -1) { | ||
285 | add_pose(llGetSubString(data, ix+1, jx-1), llGetSubString(data, jx+2, -1)); | ||
286 | } | ||
287 | } | ||
288 | ++ConfigLineIndex; | ||
289 | ConfigQueryId = llGetNotecardLine(ConfigCardName, ConfigLineIndex); //read next line of positions notecard | ||
290 | } | ||
291 | |||
292 | state_exit() { | ||
293 | if (PosCount < 1) { | ||
294 | add_pose("stand", "<-0.7,0.0,0.9> <0.0,0.0,0.0> <0.7,0.0,0.9> <0.0,0.0,-180.0>"); | ||
295 | } | ||
296 | if (PosCount < 2) { | ||
297 | add_pose("default", "<-0.7,0.0,0.7> <0.0,0.0,0.0> <0.7,0.0,0.7> <0.0,0.0,-180.0>"); | ||
298 | } | ||
299 | |||
300 | // do one save to indicate actual amount of available memory | ||
301 | string position = llList2String(Positions1, 0); | ||
302 | Positions1 = llListReplaceList(Positions1, [position],0,0); | ||
303 | |||
304 | if (llGetInventoryType("~props") == INVENTORY_SCRIPT) { | ||
305 | llSetScriptState("~props", TRUE); | ||
306 | llResetOtherScript("~props"); | ||
307 | llSleep(1.0); // give props a chance to run -- doesn't really matter if not enough | ||
308 | } | ||
309 | } | ||
310 | } | ||
71 | 311 | ||
72 | if (num == 1 && cmd == "STOP") { | 312 | |
73 | swap = 0; | 313 | state on { |
314 | state_entry() { | ||
315 | llMessageLinked(LINK_THIS, 2, "OK", (key)""); //msg to menu, in case it's waiting for loading | ||
316 | announce(); | ||
317 | } | ||
318 | |||
319 | link_message(integer from, integer num, string str, key dkey) { | ||
320 | if (str == "PRIMTOUCH" || num < 0) { | ||
74 | return; | 321 | return; |
75 | } | 322 | } |
76 | 323 | ||
77 | if (num) return; | 324 | if (num == 0 && str == "POSEB") { |
325 | string name = (string)dkey; | ||
326 | if (name == "CHECK1") { | ||
327 | Checking = TRUE; | ||
328 | } else if (Checking) { | ||
329 | check_pose((string)dkey); | ||
330 | } else { | ||
331 | llMessageLinked(LINK_THIS, 0, "POSEPOS", (key)get_pose_data((string)dkey)); // to ~pos | ||
332 | } | ||
333 | return; | ||
334 | } | ||
78 | 335 | ||
79 | if (cmd == "POSE") { | 336 | if (num != 1) { |
80 | list parms = llCSV2List((string)pkey); | ||
81 | BallCount = llList2Integer(parms,1); | ||
82 | return; | 337 | return; |
83 | } else if (cmd == "POSEPOS") { | ||
84 | // p = (integer)((string)pkey | ||
85 | getPosNew((string)pkey); | ||
86 | setPos(); | ||
87 | } else if (cmd == "SWAP") { | ||
88 | swap = (integer)((string)pkey) & 1; | ||
89 | llSay(ch+swap,pr1); //msg to ball1/2 | ||
90 | llSay(ch+!swap,pr2); | ||
91 | } else if (cmd == "REPOS") { | ||
92 | getRefPos(); | ||
93 | } else if (llGetSubString(cmd, 0, 0) == "Z") { | ||
94 | // Changed by Tatjana to make it work :) | ||
95 | integer change; | ||
96 | if (llGetSubString(cmd,1,1) == "+") change = (integer)llGetSubString(cmd,2,10); | ||
97 | else change = (integer)llGetSubString(cmd,1,10); | ||
98 | // End Tatjana changing (Penny helped, of course!) | ||
99 | Zoffset += change; | ||
100 | RefPos.z += (float)change/100.; | ||
101 | setPos(); | ||
102 | llOwnerSay("Height Adjustment: change by " + (string) change + "cm, new offset: " + (string)Zoffset + "cm"); | ||
103 | llSetObjectDesc((string)Zoffset); | ||
104 | } else if (cmd == "GETREFPOS") { | ||
105 | llMessageLinked(LINK_THIS,8,(string)RefPos,(string)RefRot); //send reference position to pose | ||
106 | } | 338 | } |
339 | |||
340 | if (str == "OK?") { //question from menu, before loading menu | ||
341 | llMessageLinked(from, 2, "OK", (key)""); //answer to menu | ||
342 | } else if (str == "DUMP") { | ||
343 | dashes(); | ||
344 | llOwnerSay("Copy to .POSITIONS; delete any other *.POSITIONS* cards"); | ||
345 | dashes(); | ||
346 | string name = llGetObjectName(); | ||
347 | llSetObjectName(""); | ||
348 | |||
349 | integer ix; | ||
350 | for (ix = 0; ix < PosCount; ++ix) { | ||
351 | string nameA = llList2String(Poses, ix); | ||
352 | llOwnerSay("{" + nameA + "} " + get_pose_data(nameA)); | ||
353 | } | ||
354 | |||
355 | llSetObjectName(name); | ||
356 | dashes(); | ||
357 | } else if (llSubStringIndex(str, "REORIENT=") == 0) { | ||
358 | // Reorient command (LINKMENU command from .MENUITEMS file) | ||
359 | // str format: REORIENT=OFF=<x,y,z> or REORIENT=ROT=<x,y,z> (in degrees) | ||
360 | list parms = llParseString2List(str, ["="], []); | ||
361 | vector amount = (vector)llList2String(parms, 2); | ||
362 | llWhisper(0, "Adjusting Poses, please wait"); | ||
363 | |||
364 | if (llList2String(parms, 1) == "OFF") { | ||
365 | adjust_all(TRUE, amount); | ||
366 | } else { | ||
367 | adjust_all(FALSE, amount); | ||
368 | } | ||
369 | llMessageLinked(LINK_THIS, 0, "AGAIN", (key)""); | ||
370 | llWhisper(0, "Pose adjustment complete"); | ||
371 | } else { | ||
372 | if (llGetSubString((string)dkey, 0, 0) == "<") { //SAVE | ||
373 | save_pose(str, (string)dkey); | ||
374 | announce(); | ||
375 | } | ||
376 | } | ||
107 | } | 377 | } |
108 | } | 378 | } |