Difference between revisions of "Av-Sitter To PMAC Converter."
Admindiamond (talk | contribs) (Created page with "== AV-Sitter2 to PMAC conversion script – Introduction == The Covey AV-Sitter2 to PMAC conversion script reads AV-Sitter position cards and converts them to PMAC menus. AV-S...") |
Admindiamond (talk | contribs) (Final edit to the pages publication) |
||
Line 17: | Line 17: | ||
AV-Sitter can have many configurations. Animations are grouped by menu and button names. In each sitter, the Menu Name must match. When matching menu names are found, it drops down to line by line checking, only pairing matching button names. | AV-Sitter can have many configurations. Animations are grouped by menu and button names. In each sitter, the Menu Name must match. When matching menu names are found, it drops down to line by line checking, only pairing matching button names. | ||
− | Also available on GitHub and | + | == The Script == |
+ | Also available on [https://github.com/manwapastorelli/OpenSimLSL/blob/master/Av-SitterToPmacConverter.lsl GitHub], [https://blog.fireandicegrid.net/av-sitter2-to-pmac-conversion-script/ Fire And Ice Grid Blog] and in the [https://fireandicegrid.net Fire And Ice Grid] at the [https://fireandicegrid.net/region_coveystores.html Covey Stores] And [https://fireandicegrid.net/region_welcome.html Welcome Region]. | ||
<syntaxhighlight lang="lsl" line> | <syntaxhighlight lang="lsl" line> |
Revision as of 23:45, 6 June 2020
Contents
AV-Sitter2 to PMAC conversion script – Introduction
The Covey AV-Sitter2 to PMAC conversion script reads AV-Sitter position cards and converts them to PMAC menus. AV-Sitter uses 2 scripts per avatar and another for setting up pose positions. PMAC, written Aine Caoimhe is a single script. AV-Sitter has a few features PMAC does not support and can be used in Second Life.
About PMAC
The Paramour Multi-Animation Controller (PMAC) is a no pose ball script system. Use PMAC in almost any piece of furniture to animate multiple avatars simultaneously. PMAC reads notecards directly and uses significantly fewer resources than AV-Sitter, map or many others.
AV-Sitter2 to PMAC conversion script – Instructions
Add the conversion script to a prim containing an AV-Sitter positions notecard (AVpos). Script status is in local chat and so is a finish notice. New PMAC menu cards are in the item inventory. Next add the PMAC core script, default animation and configuration notecard.
Important – Work on a copy
Please work on a copy, this script does not convert all AV-Sitter features to PMAC
Single Menus
PMAC handles singles differently to AV-Sitter. When a singles menu is used only one sitter is enabled. To try and work around this, the script looks for singles poses with matching button names from each sitter. If found it will turn the two or more matching singles poses into a set of 2 or more that work like Av-Sitter SYNCS (Couples poses). If a name has no match, it is a single menu.entry.
Menu And Button Names
AV-Sitter can have many configurations. Animations are grouped by menu and button names. In each sitter, the Menu Name must match. When matching menu names are found, it drops down to line by line checking, only pairing matching button names.
The Script
Also available on GitHub, Fire And Ice Grid Blog and in the Fire And Ice Grid at the Covey Stores And Welcome Region.
1 integer menuCardNumber = 2; //used at the end when writing the new menu cards
2 string AvPosCardName = "AVpos"; //name of the Av-sitter positions card
3 integer debug = FALSE; //turns this on to see debug output, this generates a LOT of local chat output
4 //if you use the debug option it's suggested you comment them out section by sec
5
6 ConvertRotations()
7 { //AvSitter uses x,y,z rotations, PMAC uses quaternion rotations, so convert them.
8 list tempList = [];
9 integer lineNumber;
10 integer notecardLines = osGetNumberOfNotecardLines(AvPosCardName);
11 for (lineNumber = 0; lineNumber < notecardLines; lineNumber++)
12 { //loops through each line of the notecard
13 string initial = osGetNotecardLine(AvPosCardName, lineNumber);
14 string noTimes = RemoveTimes(initial);
15 integer braceIndex = llSubStringIndex(noTimes, "}");
16 string fixedRotation;
17 if (braceIndex != -1)
18 { //only deal with lines wich contain a } (pos/rot line)
19 fixedRotation = ConvertLineToRotations(noTimes); //convert this line to real rotations
20 }
21 else
22 { //only deal with lines that do not contain a } (pos/rot line)
23 fixedRotation = noTimes;
24 }
25 tempList += fixedRotation; //add the line to the temp list
26 }
27 //write the temp list to a notecard
28 WriteNotecard("FixedRotations", tempList);
29 }
30 WriteNotecard(string name, list contents)
31 { //writes a notecard with the supplied name and contents
32 /*
33 The conversion script relies on the contents of notecards, Ensure the notecards are deleted and saved before continuing.
34 */
35 integer inventoryType;
36 if (llGetInventoryType(name) == INVENTORY_NOTECARD)
37 {
38 llRemoveInventory(name);
39 inventoryType = llGetInventoryType(name);
40 while (inventoryType > -1) //-1 means it doesn't exist
41 { //wait to make sure the removal is complete before going on
42 inventoryType = llGetInventoryType(name);
43 }
44 }
45 osMakeNotecard(name, contents);
46 inventoryType = llGetInventoryType(name);
47 while (inventoryType != INVENTORY_NOTECARD)
48 { //wait for the write to finish before going on
49 inventoryType = llGetInventoryType(name);
50 }
51 }
52 DebugOwnerSayListContents(string name, list toDisplay)
53 { //outputs the contents of a list nicely to local chat for the owner.
54 string output = "Debug:ListContents:" + "\n" + "ListName: " + name;
55 llOwnerSay(output);
56 integer index;
57 for (index = 0; index < llGetListLength(toDisplay); index++)
58 { //loop through every line of the list outputting to local chat
59 llOwnerSay(llList2String(toDisplay, index));
60 }
61 }
62 list ReverseListOrder(list inputList)
63 { //reverses the order of a list.
64 list reverseList;
65 integer index;
66 for (index = llGetListLength(inputList)-1; index >= 0 ; index--)
67 { //loops through the list backwards, adding each line to a new list
68 reverseList += llList2String(inputList, index);
69 }
70 return reverseList;
71 }
72 string ConvertLineToRotations (string inputString)
73 { //takes in the AVpos format and outputs PMAC format
74 string name = "{"+ NameFromPositionsLine(inputString) + "}";
75 vector posVec = (vector)PosFromPositionsLine(inputString);
76 vector rotVec = (vector)RotFromPositionsLine (inputString);
77 rotation rotRot = llEuler2Rot(rotVec * DEG_TO_RAD); //the actual conversion
78 string fixedString = name + (string)posVec + (string)rotRot;
79 return fixedString;
80 }
81 list GetSpecificNotecardCards (string searchString)
82 { //uses a partial name string to return all matching notecards from the items inventory
83 list sitterNotecards;
84 integer numOfNotecards = llGetInventoryNumber(INVENTORY_NOTECARD);
85 integer index;
86 for (index = 0; index < numOfNotecards; index++)
87 { //loops through every notecard in the inventory
88 string notecardName = llGetInventoryName(INVENTORY_NOTECARD, index);
89 string testName = llGetSubString(notecardName, 0, llStringLength(searchString)-1);
90 if (testName == searchString)
91 { //if we find a match add it to the list
92 sitterNotecards += notecardName;
93 }
94 }
95 return sitterNotecards;
96 }
97 string MenuNameFromMenuLine(string inputString)
98 {
99 integer spaceChar = llSubStringIndex(inputString, " ");//find the space character
100 string menuName = llStringTrim(llGetSubString(inputString, spaceChar +1, -1), STRING_TRIM); //remove everythign before the space
101 return menuName;
102 }
103 string NameFromPositionsLine(string inputString)
104 {
105 integer charBracket = llSubStringIndex(inputString, "}"); //find the } character
106 string nValue = llGetSubString(inputString, 1, charBracket-1); //remove curley brackets and position data
107 return nValue;
108 }
109 string PosFromPositionsLine(string inputString)
110 {
111 integer charLess = llSubStringIndex (inputString, "<"); // find the first < character
112 integer charMore = llSubStringIndex (inputString, ">"); // find the first > character
113 string vValue = llGetSubString (inputString, charLess, charMore); // removed everything except the vector
114 return vValue;
115 }
116 string RotFromPositionsLine (string inputString)
117 {
118 integer charMore = llSubStringIndex (inputString, ">"); // find the first > character
119 string rotValue = llGetSubString (inputString, charMore+1, -1); //remove everything except the rotation vector
120 return rotValue;
121 }
122 string RemoveTimes(string inputString)
123 {
124 integer charStart = llSubStringIndex(inputString, "◆");//find the position of the real start of the line and discard all before it
125 string trimed = llGetSubString(inputString, charStart+1, -1); //remove everything before the "◆"
126 return trimed;
127 }
128 string GetPoseName (string inputString)
129 {
130 integer charLine = llSubStringIndex(inputString,"|"); //find the | seperator character
131 string lValue = llGetSubString (inputString, 0, charLine-1); // remove everything after the |
132 return lValue;
133 }
134 string GetAnimName (string inputString)
135 {
136 integer charLine = llSubStringIndex(inputString, "|"); // find the | seperator
137 string lValue = llGetSubString(inputString, charLine+1, -1); //remove everythign before the |
138 return lValue;
139 }
140 string GetSitterNumberFromMenuCardName(string menuCardName)
141 {
142 list elements = llParseStringKeepNulls(menuCardName, "_", ""); //make a list seperated by underscores
143 string sitterNumber = llList2String(elements, 2); //retrieve the sitter number from the list
144 return sitterNumber;
145 }
146 string GetMenuNameFromMenuCardName(string menuCardName)
147 {
148 list elements = llParseStringKeepNulls(menuCardName, "_", "");//make a list seperated by underscores
149 string name = llList2String(elements, 3);//retrieve the name number from the list
150 return name;
151 }
152 string GetButtonNameFromPmacLine(string inputString)
153 {
154 integer barIndex = llSubStringIndex(inputString, "|");// find the | seperator
155 string name = llGetSubString(inputString, 0, barIndex-1); //remove everything after the |
156 return name;
157 }
158 SplitIntoSitters()
159 { //splits the AVpos card down into individual sitters
160 list tempSitterList;
161 integer sitterCount = -1; //start at -1 so that we don't save contents before the first SITTER line
162 integer lineNumber;
163 integer notecardLines = osGetNumberOfNotecardLines("FixedRotations");
164 for (lineNumber = 0; lineNumber < notecardLines; lineNumber++)
165 { //loop through ever line of the AVpos notecard
166 string currentLine1 = osGetNotecardLine("FixedRotations", lineNumber);
167 if (currentLine1 != "")
168 { //ignore blank lines
169 string test = llGetSubString(currentLine1, 0, 3);
170 string test2 = llGetSubString(currentLine1, 0, 0);
171 if (test == "SITT")
172 { //do something for SITTER line found
173 if (sitterCount > -1)
174 { //if we find a new SITTER line write the contents of the temp list to a notecard
175 WriteNotecard("Sitter" + (string)sitterCount, tempSitterList);
176 tempSitterList = [];//clear the list ready to start again
177 }
178 sitterCount++;
179 }
180 else if (test == "MENU" || test == "POSE" || test == "SYNC" || test2 == "{")
181 { //only deal with the menus, poses, syncs and pos/rot lines
182 tempSitterList += currentLine1; //add info to the new list
183 }
184
185 }
186 }
187 //write a notecard containing all needed information for this sitter
188 WriteNotecard("Sitter" + (string)sitterCount, tempSitterList);
189 }
190 list GetSitterSyncsAndMenus(string notecardName)
191 { //loops through the named notecard looking for lines which start with SYNC, MENU or { (pos/rot lines)
192 //adds them to the new list as they are found
193 list sitterSyncsAndMenus;
194 list poseNames;
195 integer lineNumber;
196 for (lineNumber = 0; lineNumber < osGetNumberOfNotecardLines(notecardName); lineNumber++)
197 { //loops through every line of the notecard
198 string currentLine2 = osGetNotecardLine(notecardName, lineNumber);
199 string testPose = llGetSubString(currentLine2, 0, 3);
200 string testAnimData = llGetSubString(currentLine2, 0, 0);
201 string testPoseName;
202 if (testPose == "SYNC")
203 { //for every SYNC line remove the word SYNC and the space, retrieve the pose name from the remainder
204 //and add the pose name to the list of pose names
205 string withoutTitle = llStringTrim(llGetSubString(currentLine2, 5, -1), STRING_TRIM);
206 sitterSyncsAndMenus += withoutTitle;
207 testPoseName = GetPoseName(withoutTitle);
208 poseNames += testPoseName;
209 }
210 else if (testPose == "MENU")
211 { //add ever Menu line to the list
212 sitterSyncsAndMenus += currentLine2;
213 }
214 else if (testAnimData == "{")
215 { //come here for every pos/rot line, check the name and if it matches
216 //add it to the list
217 integer closeBraceIndex = llSubStringIndex(currentLine2, "}");
218 string lineAnimName = llGetSubString(currentLine2, 1, closeBraceIndex-1);
219 if(~llListFindList(poseNames, (list)lineAnimName))
220 { //if the name matches any of the ones added to the pose list earlier, add the line
221 //to the main list.
222 sitterSyncsAndMenus += currentLine2;
223 }
224 }
225 }
226 return sitterSyncsAndMenus;
227 }
228 list GetSitterPOSEs(string notecardName)
229 { //loop through the supplied notecard name saving just pose names and related pos/rot lines
230 list sitterPoses;
231 list poseNames;
232 integer lineNumber;
233 for (lineNumber = 0; lineNumber < osGetNumberOfNotecardLines(notecardName); lineNumber++)
234 { //loops through every line in the notecard
235 string currentLine2 = osGetNotecardLine(notecardName, lineNumber);
236 string testPose = llGetSubString(currentLine2, 0, 3);
237 string testAnimData = llGetSubString(currentLine2, 0, 0);
238 string testPoseName;
239 if (testPose == "POSE")
240 { //checks each pose line, retrieves the name then adds the name to the poses list
241 string withoutTitle = llStringTrim(llGetSubString(currentLine2, 5, -1), STRING_TRIM);
242 sitterPoses += withoutTitle;
243 testPoseName = GetPoseName(withoutTitle);
244 poseNames += testPoseName;
245 }
246 else if (testAnimData == "{")
247 { //checks every pos/rot line, if the name matches one save earlier add it to the list
248 integer closeBraceIndex = llSubStringIndex(currentLine2, "}");
249 string lineAnimName = llGetSubString(currentLine2, 1, closeBraceIndex-1);
250 if(~llListFindList(poseNames, (list)lineAnimName))
251 { //if the lines name matches one in the pose list add the whole line to the main list
252 sitterPoses += currentLine2;
253 }
254 }
255 }
256 return sitterPoses;
257 }
258 FixAndCombineSinglePoses()
259 { //makes new notecards with the sync and poses seperated
260 //along with their related pos/rot information.
261 SeperatePoseNamesAndData();
262 CreateNewSyncSetFromPoses();
263 }
264 SeperatePoseNamesAndData()
265 { //loops through every sitter card making new serpate cards for poses (not syncs) and their related pos/rot
266 list sitterNotecards = GetSpecificNotecardCards("Sitter");
267 integer sitterCardIndex;
268 for(sitterCardIndex = 0; sitterCardIndex < llGetListLength(sitterNotecards); sitterCardIndex++)
269 { //loops through every sitter notecard
270 string cardName = llList2String(sitterNotecards, sitterCardIndex);
271 list sitterPoses = GetSitterPOSEs(cardName);
272 list sitterPosRotData;
273 integer lineIndex;
274 for (lineIndex = llGetListLength(sitterPoses)-1; lineIndex >=0; lineIndex--)
275 { //add all lines with braces to the sitte pos/rot list and remove from sitter poses list
276 string currentLine3 = llList2String(sitterPoses, lineIndex);
277 integer hasBraces = llSubStringIndex(currentLine3, "}");
278 if (hasBraces > -1)
279 { //takes every pos/rot line and adds it to the pos/rot line list
280 if (debug) llOwnerSay("Debug:BracesLine: " + currentLine3);
281 sitterPosRotData += currentLine3;
282 sitterPoses = llDeleteSubList(sitterPoses, lineIndex, lineIndex);
283 }
284 }
285 //write out both cards, reversing the order of the pos/rot card so it matches the order of the menu card.
286 WriteNotecard("Poses " + cardName, sitterPoses);
287 sitterPosRotData = ReverseListOrder(sitterPosRotData);
288 WriteNotecard("DataPoses " + cardName, sitterPosRotData);
289 }
290 }
291 GeneratePoseToSyncCards(list poseCards, list newSyncNames)
292 { //loops through all pose cards line by line, looking for names with the same button names
293 //assumes these are supposed to be paied up and makes new SYNC menus from them.
294 list newSyncPoses;
295 list newSyncData;
296 integer poseCardIndex;
297 for (poseCardIndex = 0; poseCardIndex < llGetListLength(poseCards); poseCardIndex++)
298 { //loops through each card
299 string cardName = "Poses Sitter" + (string)poseCardIndex;
300 integer cardLength = osGetNumberOfNotecardLines(cardName);
301 if(debug) llOwnerSay("Debug:ReadingCard: " + cardName);
302 integer lineIndex;
303 newSyncPoses = [];
304 newSyncData = [];
305 string menu = "MENU Social-A";
306 newSyncPoses += menu;
307 for (lineIndex = 0; lineIndex < cardLength; lineIndex++)
308 { //loops through each line in the given notecard
309 string posesLine = osGetNotecardLine("Poses Sitter" + (string)poseCardIndex, lineIndex);
310 string dataLine = osGetNotecardLine("DataPoses Sitter" + (string)poseCardIndex,lineIndex);
311 string poseName = GetPoseName (posesLine);
312 if (debug) llOwnerSay("Debug:CheckingPoseName: " + poseName);
313 if (~llListFindList(newSyncNames, (list)poseName))
314 { //come here if the current pose name is found in the new sync names list
315 if (debug) llOwnerSay("Debug:Found" + poseName);
316 string newPoseLine = "SYNC " + posesLine;
317 newSyncPoses += newPoseLine;
318 newSyncData += dataLine;
319 }
320 }
321 list combinedList = newSyncPoses + newSyncData;
322 WriteNotecard("PoseToSyncSitter" + (string)poseCardIndex, combinedList);
323 }
324 }
325 CreateNewSyncSetFromPoses()
326 { //loops though every pose card and attempts to find pairs which should be used together.
327 //then makes a list of real single only poses and pairs to treat as syncs, pmac singles
328 //don't allow others to sit, so better to pair them up when possible.
329 list posesCards = GetSpecificNotecardCards("Poses Sitter");
330 integer posesCardIndex;
331 list poseNamesSitter0;
332 list newSyncNames;
333 list newSinglesNames;
334 if (debug) DebugOwnerSayListContents("list of poses cards", posesCards);
335 //loop through all cards checking for duplicate pose names, store them in newSyncNames
336 for (posesCardIndex = 0; posesCardIndex < llGetListLength(posesCards); posesCardIndex++)
337 { //loops through each card, checking against sitter 0
338 integer lineIndex;
339 string notecardName = llList2String(posesCards, posesCardIndex);
340 integer notecardLength = osGetNumberOfNotecardLines(notecardName);
341 for (lineIndex = 0; lineIndex < notecardLength; lineIndex++)
342 {
343 string currnetLine = osGetNotecardLine(notecardName, lineIndex);
344 string poseName = GetPoseName (currnetLine);
345 if (posesCardIndex == 0)
346 {
347 poseNamesSitter0 += poseName;
348 }
349 else
350 {
351 if(~llListFindList(poseNamesSitter0, (list)poseName))
352 { //come here if poseName is found in sitter0
353 if (!(~llListFindList(newSyncNames, (list)poseName)))
354 { //come here only if the pose is not already in the new sync names
355 newSyncNames += poseName;
356 }
357 }
358 else
359 { //come here if the pose is not found in sitter 0
360 if (!(~llListFindList(newSinglesNames, (list)poseName)))
361 { //come here only if the pose is not already in the new sync names
362 newSinglesNames += poseName;
363 }
364 }
365 }
366 }
367 }
368 GenerateNewSinglesCard(newSyncNames);
369 GeneratePoseToSyncCards(posesCards, newSyncNames);
370 CombinePoseToSyncCardsWithSiterCards();
371 }
372 CombinePoseToSyncCardsWithSiterCards()
373 { //takes the new sync cards (made from pair poses) and combines
374 //these new menus with the original sitter cards ready for sync set processing
375 list sitterCards = GetSpecificNotecardCards ("Sitter");
376 integer sitterCardIndex;
377 for (sitterCardIndex = 0; sitterCardIndex < llGetListLength(sitterCards); sitterCardIndex++)
378 {
379 list newSitterCard;
380 string currentLine;
381 string CardName = "Sitter" + (string)sitterCardIndex;
382 newSitterCard += AllLinesWithOrWithoutBraces (CardName, FALSE);
383 CardName = "PoseToSyncSitter" + (string)sitterCardIndex;
384 newSitterCard += AllLinesWithOrWithoutBraces (CardName, FALSE);
385 CardName = "Sitter" + (string)sitterCardIndex;
386 newSitterCard += AllLinesWithOrWithoutBraces (CardName, TRUE);
387 CardName = "Sitter" + (string)sitterCardIndex;
388 newSitterCard += AllLinesWithOrWithoutBraces (CardName, TRUE);
389 if (debug) DebugOwnerSayListContents("New Sitter " + (string)sitterCardIndex + " card", newSitterCard);
390 WriteNotecard("Sitter" + (string)sitterCardIndex, newSitterCard);
391 }
392 }
393 list AllLinesWithOrWithoutBraces(string cardName, integer with)
394 { //loops through the given notecard name, if the "with" integer is TRUE
395 //adds all lines with braces to a list. If the "with" is FALSE all lines
396 //without braces are added to the list.
397 list newList;
398 integer CardLength = osGetNumberOfNotecardLines(cardName);
399 integer lineNumber;
400 //add lines without braces from the sitter card
401 for (lineNumber = 0; lineNumber < CardLength; lineNumber++)
402 { //loops through the whole notecards
403 string currentLine = osGetNotecardLine(cardName, lineNumber);
404 integer hasBraces = llSubStringIndex(currentLine, "{");
405 if(with)
406 { //we want all lines with braces
407 if (hasBraces > -1)
408 {
409 newList += currentLine;
410 }
411 }
412 else
413 { //we want all lines without braces
414 if (hasBraces == -1)
415 {
416 newList += currentLine;
417 }
418 }
419 }
420 return newList;
421 }
422 GenerateNewSinglesCard(list newSyncNames)
423 { //loops through all poses in all the sitter cards, checks to see if they have matching
424 //entries in the newSyncNames list, if they don't ass them to a list of real single
425 //poses and writes the note card when the list is complelete
426 if (debug) llOwnerSay("Debug:GenerateNewSinglesCard: Entered");
427 integer posesSitter0Line;
428 list posesCards = GetSpecificNotecardCards("Poses Sitter");
429 if (debug) DebugOwnerSayListContents("posesCards", posesCards);
430 if (debug) DebugOwnerSayListContents("sync names list", newSyncNames);
431 list newSinglePoses;
432 list newSinglePosesData;
433 integer posesCardIndex;
434 for (posesCardIndex = 0; posesCardIndex < llGetListLength(posesCards); posesCardIndex++)
435 { //loops through each poses card card
436 integer lineIndex;
437 string notecardName = llList2String(posesCards, posesCardIndex);
438 if (debug) llOwnerSay("Debug:CheckingCard: " + notecardName);
439 integer notecardLength = osGetNumberOfNotecardLines(notecardName);
440 for (lineIndex = 0; lineIndex < notecardLength; lineIndex++)
441 { //loops through every line of the current poses card
442 string currentLine4 = osGetNotecardLine(notecardName, lineIndex);
443 string poseName = GetPoseName (currentLine4);
444 if (debug) llOwnerSay("Debug: checking pose name: " + poseName);
445 integer matchFound = FALSE;
446 integer newSyncNamesIndex = 0;
447 //now check this line against every line of new sync names
448 while (!matchFound && newSyncNamesIndex < llGetListLength(newSyncNames))
449 { //loops through the sync poses checking for a match, keeps going until it finishes withou
450 //a result or finds a match
451 string newSyncNamesLine = llList2String(newSyncNames, newSyncNamesIndex);
452 if(debug) llOwnerSay("Debug:Checking:" + currentLine4 + " against " + newSyncNamesLine);
453 if (poseName == newSyncNamesLine)
454 { //come here if a a match has been found, stop the loop
455 if(debug) llOwnerSay("Debug:MatchFound");
456 matchFound = TRUE;
457 }
458 newSyncNamesIndex++;
459 }
460 if (!matchFound)
461 { //loop though the sync cards has ended, no match found, add this item to the singles list
462 //add the data from the same animations and button names to to another list.
463 if (debug) llOwnerSay("Debug: Not Found");
464 string newSinglePosesLine = osGetNotecardLine("Poses Sitter" + (string)posesCardIndex, lineIndex);
465 string newSinglePosesDataLine = osGetNotecardLine("DataPoses Sitter" + (string)posesCardIndex, lineIndex);
466 newSinglePoses += newSinglePosesLine;
467 newSinglePosesData += newSinglePosesDataLine;
468 }
469 }
470 }
471 if (debug)
472 {
473 DebugOwnerSayListContents("newSinglePoses", newSinglePoses);
474 DebugOwnerSayListContents("newSinglePosesData", newSinglePosesData);
475 }
476 //now turn the two new lists above into a menu card for PMAC
477 integer newSinglePosesIndex;
478 list newSinglesMenu; //list to hold the new singles menu
479 for (newSinglePosesIndex = 0; newSinglePosesIndex < llGetListLength(newSinglePoses); newSinglePosesIndex++)
480 { //loops through each of the new singles poses entries, makes the PMAC line and adds to the list ready for writing
481 string lineFromPoses = llList2String(newSinglePoses, newSinglePosesIndex);
482 string lineFromData = llList2String(newSinglePosesData, newSinglePosesIndex);
483 if (debug) llOwnerSay("Debug:LineFromPoses: " + lineFromPoses);
484 if (debug) llOwnerSay("Debug:LineFromPosesData: " + lineFromData);
485 string buttonname = GetPoseName (lineFromPoses);
486 if (debug) llOwnerSay("Debug:ButtonName: " + buttonname);
487 string animName = GetAnimName (lineFromPoses);
488 string position = PosFromPositionsLine(lineFromData);
489 string rot = RotFromPositionsLine (lineFromData); //this is already a rotation just reusing a method.
490 string newEntry = buttonname + "|NO COM|" + animName + "|" + position + "|" + rot;
491 if(debug) llOwnerSay("Debug:AddedToSingleMenu: " + newEntry);
492 newSinglesMenu += newEntry;
493 }
494 if (debug) DebugOwnerSayListContents("new singels menu", newSinglesMenu);
495 //everything added, write the notecard.
496 WriteNotecard(".menu001A Singles", newSinglesMenu);
497 }
498 RemovePosesAndPoseDataFromSitters()
499 {
500 //now the poses have bene converted to syncs or written to their own PMAC menu
501 //remove them from the SITTER cards so they can be processed as just sync's
502 list sitterCards = GetSpecificNotecardCards ("Sitter");
503 integer sitterCardIndex;
504 for (sitterCardIndex = 0; sitterCardIndex < llGetListLength(sitterCards); sitterCardIndex++)
505 { //loop through each sitter card, inside each one remove any pose related lines
506 string cardName = llList2String(sitterCards, sitterCardIndex);
507 list sitterWithNoPoses = GetSitterSyncsAndMenus(cardName);
508 if (debug) DebugOwnerSayListContents("newSitter" + (string)sitterCardIndex, sitterWithNoPoses);
509 WriteNotecard(cardName, sitterWithNoPoses);
510 }
511 }
512 list SitterWithNoEmptyMenus (string cardName)
513 { //loop through the card name provided, create a new list which contains
514 //non of the menus which only make up a menu structure, keep the ones which
515 //contain animation buttons.
516 list newList;
517 integer lineIndex;
518 integer cardLength = osGetNumberOfNotecardLines(cardName);
519 for (lineIndex = 0; lineIndex < cardLength; lineIndex++)
520 { //loops through each line of the notecard
521 string thisLine = osGetNotecardLine(cardName, lineIndex);
522 string testMenu = llGetSubString(thisLine, 0, 3);
523 string testBraces = llGetSubString(thisLine, 0, 0);
524 string testPoseName;
525 if (testMenu == "MENU")
526 { //come here only if the line starts with MENU
527 if (debug) llOwnerSay("Debug: Menu Line Found");
528 string nextLine = osGetNotecardLine(cardName, lineIndex + 1);
529 string nextLineMenuTest = llGetSubString(nextLine, 0, 3);
530 if (nextLineMenuTest != "MENU")
531 { //if the next line is not also MENU add this line
532 newList += thisLine;
533 }
534 }
535 else if (testBraces = "{")
536 { //keep everything which is not a Menu line
537 newList += thisLine;
538 }
539 }
540 return newList;
541 }
542 RemoveEmptyMenusFromSitterCards()
543 { //removes all the menu structure, preseving just the ones which directly deliver animation buttons
544 list sitterCards = GetSpecificNotecardCards ("Sitter");
545 integer sitterCardIndex;
546 for (sitterCardIndex = 0; sitterCardIndex < llGetListLength(sitterCards); sitterCardIndex++)
547 {
548 string cardName = llList2String(sitterCards, sitterCardIndex);
549 list SitterNoEmptyMenus = SitterWithNoEmptyMenus(cardName);
550 if (debug) DebugOwnerSayListContents("newSitter" + (string)sitterCardIndex, SitterNoEmptyMenus);
551 WriteNotecard(cardName, SitterNoEmptyMenus);
552 }
553 }
554 RemoveTempCards()
555 { //loops though the inventory removing any temp notecards created during the conversion
556 list testStrings = ["DataPoses Sitter", "FixedRotations", "Poses Sitter", "PoseToSyncSitter", "Data_Sitter", "Menu_Sitter", "MenuData_Sitter", "Sitter"];
557 list testResults;
558 integer numOfNotecards = llGetInventoryNumber(INVENTORY_NOTECARD);
559 integer notecardIndex;
560 for (notecardIndex = numOfNotecards -1; notecardIndex >=0; notecardIndex--)
561 { //loops through the inventory
562 string notecardName = llGetInventoryName(INVENTORY_NOTECARD, notecardIndex);
563 integer testIndex;
564 for (testIndex = 0; testIndex < llGetListLength(testStrings);testIndex++)
565 { //checks each name against the ones in the list to remove
566 string testString = llList2String(testStrings,testIndex);
567 string testResult = llGetSubString(notecardName, 0, llStringLength(testString)-1);
568 if (testString == testResult)
569 { //when a match is found, remove it.
570 if (debug) llOwnerSay("Debug:RemoveTempCards:Removed: " + notecardName);
571 llRemoveInventory(notecardName);
572 }
573 }
574 }
575 }
576 list GetMenuLinePositions(string sitterCard)
577 { //loops through the sitter card, making list of all line positions containing MENU lines
578 integer sitterCardLength = osGetNumberOfNotecardLines(sitterCard);
579 integer lineIndex;
580 list menuLinePositions;
581 integer dataStartLine;
582 for(lineIndex = 0; lineIndex < sitterCardLength; lineIndex++)
583 { //loops through each line of the sittercard
584 string currentLine = osGetNotecardLine(sitterCard, lineIndex);
585 string menuTest = "MENU";
586 string testResult = llGetSubString(currentLine, 0, llStringLength(menuTest)-1);
587 if (menuTest == testResult)
588 { //add this line number to the list
589 menuLinePositions += lineIndex;
590 }
591 }
592 if (debug) llOwnerSay("Debug:GetMenuLinePositions:List: " + llList2CSV(menuLinePositions));
593 return menuLinePositions;
594 }
595 GenerateMenuCardsForSyncs()
596 { //goes through each sitter card making invidiual menu notecards for every sitter
597 list sitterCards = GetSpecificNotecardCards ("Sitter");
598 integer sitterCardIndex;
599 for (sitterCardIndex = 0; sitterCardIndex < llGetListLength(sitterCards); sitterCardIndex++)
600 { //loops through each sitter card
601 string sitterCardName = llList2String(sitterCards, sitterCardIndex);
602 list menuLinePositions = GetMenuLinePositions(sitterCardName);
603 list newMenuCardLines;
604 integer menuIndex;
605
606 for (menuIndex = 0; menuIndex < llGetListLength(menuLinePositions); menuIndex++)
607 { //loops through each menu entry for this sitter
608 newMenuCardLines = [];
609 integer menuStartLine = llList2Integer(menuLinePositions, menuIndex) +1; //+1 avoids adding the actual menu line which is no longer required
610 integer menuEndLine;
611 if(menuIndex != llGetListLength(menuLinePositions)-1)
612 { //if its not the last entry, the end point is the start of the next menu
613 menuEndLine = llList2Integer(menuLinePositions, menuIndex+1);
614 }
615 else
616 { //if this is the last menu, set the end to the end of the notecard
617 menuEndLine = osGetNumberOfNotecardLines(sitterCardName)-1; //-1 to ensure we stop at the bottom of the card
618 }
619 integer menuLineIndex;
620 for (menuLineIndex = menuStartLine; menuLineIndex < menuEndLine; menuLineIndex++)
621 { //add each line that forms part of this menu to the new menu card
622 newMenuCardLines;
623 string currentLine = osGetNotecardLine(sitterCardName, menuLineIndex);
624 integer isData = llSubStringIndex(currentLine, "}");
625 if (isData == -1)
626 {
627 newMenuCardLines += currentLine;
628 }
629 }
630 string menuName = MenuNameFromMenuLine(osGetNotecardLine(sitterCardName,menuStartLine-1)) ; //-1 to get the actual menu line
631 string newCardName = "Menu_Sitter_" + (string)sitterCardIndex + "_" + menuName;
632 WriteNotecard(newCardName, newMenuCardLines);
633 }
634 }
635 }
636 string FindMatchingDataLine(string buttonName, string sitterNumber)
637 { //loops through the Sitter card for the sitter number provided
638 //looking for the button name provided inside the pos/rot lines
639 //if one is found, return it
640 string dataLine;
641 string sitterCardName = "Sitter" + sitterNumber;
642 integer cardLength = osGetNumberOfNotecardLines(sitterCardName);
643 integer lineIndex = cardLength-1;
644 integer matchFound = FALSE;
645 while (!matchFound && lineIndex >= 0)
646 { //start from the bottom and loop until a match is found, positions are always at the bottom of the card
647 string currentLine = osGetNotecardLine(sitterCardName, lineIndex);
648 integer isPosRot = llSubStringIndex(currentLine, "}");
649 if (isPosRot)
650 { //only look at pos/rot lines
651 string lineName = NameFromPositionsLine(currentLine);
652 if (lineName == buttonName)
653 { //if a match is found add it to the list
654 dataLine = currentLine;
655 matchFound = TRUE;
656 }
657 }
658 lineIndex--;
659 }
660 return dataLine;
661 }
662 GenerateDataCardsForSyncs()
663 { //loops through all the temp menu cards, for each one it loops through every
664 //line and then retrieves the matching pos/rot line in the appropriate sitter card
665 //using this to make a dedicated pos/rot DATA card for the menu being processed.
666 list menuCards = GetSpecificNotecardCards ("Menu_");
667 integer menuCardIndex;
668 list dataLines;
669 for (menuCardIndex = 0; menuCardIndex < llGetListLength(menuCards); menuCardIndex++)
670 {
671 dataLines = []; //clear this to make a new one each time
672 string cardName = llList2String(menuCards, menuCardIndex);
673 string sitterNumber = GetSitterNumberFromMenuCardName(cardName);
674 string menuName = GetMenuNameFromMenuCardName(cardName);
675 integer cardLength = osGetNumberOfNotecardLines(cardName);
676 integer cardLineIndex;
677 for (cardLineIndex = 0; cardLineIndex < cardLength; cardLineIndex++)
678 { //loops through the current menu card line by line
679 string cardLine = osGetNotecardLine(cardName, cardLineIndex);
680 string buttonname = GetPoseName (cardLine);
681 string dataLine = FindMatchingDataLine(buttonname, sitterNumber);
682 dataLines += dataLine;
683 }
684 string newCardName = "Data_Sitter_" + sitterNumber + "_" + menuName ;
685 WriteNotecard(newCardName, dataLines);
686 }
687 }
688 list GetCombinedSitter0MenuData(string menuCardName, string dataCardName)
689 { //takes the supplied names, retrieves the data from both and combines it line by line.
690 //the returned list will make a MenuData temp notecard.
691 list combinedMenuDataCard;
692 integer menuCardLength = osGetNumberOfNotecardLines(menuCardName);
693 integer dataCardLength = osGetNumberOfNotecardLines(dataCardName);
694 integer menuCardLineIndex;
695 integer dataCardLineIndex;
696 for (menuCardLineIndex = 0; menuCardLineIndex < menuCardLength; menuCardLineIndex++)
697 { //loops through each line of the menu card
698 string menuCardLine = osGetNotecardLine(menuCardName, menuCardLineIndex);
699 string menuButtonName = GetPoseName (menuCardLine);
700 string animName = GetAnimName (menuCardLine);
701 integer dataSitter0CardIndex = 0;
702 integer matchFound = FALSE;
703 while (!matchFound && dataSitter0CardIndex < dataCardLength)
704 {
705 string dataCardLine = osGetNotecardLine(dataCardName, dataSitter0CardIndex);
706 string dataButtonName = NameFromPositionsLine(dataCardLine);
707 if (menuButtonName == dataButtonName)
708 {
709 matchFound = TRUE;
710 string dataPos = PosFromPositionsLine(dataCardLine);
711 string dataRot = RotFromPositionsLine (dataCardLine);
712 string toAdd = menuButtonName + "|NO COM|" + animName + "|" + dataPos + "|" + dataRot;
713 combinedMenuDataCard += toAdd;
714 }
715 dataSitter0CardIndex++;
716 }
717 }
718 return combinedMenuDataCard;
719 }
720 CombineSitter0MenuAndDataCards()
721 { //gets a list of all Menu cards and all Data cards then passes them in
722 //pairs to the combine method.
723 list menuSitter0Cards = GetSpecificNotecardCards ("Menu_Sitter_0");
724 list dataDitter0Cards = GetSpecificNotecardCards ("Data_Sitter_0");
725 integer menuSitter0CardIndex;
726 for (menuSitter0CardIndex = 0; menuSitter0CardIndex < llGetListLength(menuSitter0Cards); menuSitter0CardIndex++)
727 {
728 string sitter0MenuCardName = llList2String(menuSitter0Cards, menuSitter0CardIndex);
729 string sitter0DataCardName = llList2String(dataDitter0Cards, menuSitter0CardIndex);
730 string menuName = GetMenuNameFromMenuCardName(sitter0MenuCardName);
731 list combinedSitter0MenuData = GetCombinedSitter0MenuData(sitter0MenuCardName, sitter0DataCardName);
732 WriteNotecard("MenuData_Sitter_0_" + menuName, combinedSitter0MenuData);
733 if (debug) DebugOwnerSayListContents("sitter0MenuData_" + menuName, combinedSitter0MenuData);
734 }
735 }
736 list GetRelatedMenuSitterCards(string menuName)
737 { //finds all temp menu cards related to the supplied name and returns the list
738 list menuSitterCards = GetSpecificNotecardCards ("Menu_Sitter");
739 list relatedMenuCards;
740 integer menuCardIndex;
741 for (menuCardIndex = 0; menuCardIndex < llGetListLength(menuSitterCards); menuCardIndex++)
742 { //start loop at 0 incase there is only 1 entry, but ignore the first first loop as we do not want sitter 0
743 string currentCardName = llList2String(menuSitterCards, menuCardIndex);
744 string currentMenuName = GetMenuNameFromMenuCardName(currentCardName);
745 string sitterNumber = GetSitterNumberFromMenuCardName(currentCardName);
746 if (currentMenuName == menuName && sitterNumber != "0")
747 { //ignore sitter 0 since it is the one we are working from, don't duplicate it.
748 relatedMenuCards += currentCardName;
749 }
750 }
751 return relatedMenuCards;
752 }
753 string GetAnimNameFromRelatedMenuCard(string relatedMenuCardName, string buttonName)
754 { //All card entries can be out of order, so search through every line until a match is found and return the information.
755 string animName = "";
756 integer cardLength = osGetNumberOfNotecardLines(relatedMenuCardName);
757 integer cardIndex = 0;
758 integer matchFound = FALSE;
759 while (!matchFound && cardIndex < cardLength)
760 {
761 string cardLine = osGetNotecardLine(relatedMenuCardName, cardIndex);
762 string poseName = GetPoseName (cardLine);
763 if (poseName == buttonName)
764 {
765 animName = GetAnimName (cardLine);
766 matchFound = TRUE;
767 }
768 cardIndex++;
769 }
770 return animName;
771 }
772 string GetPosRotFromRelatedDataCard(string relatedDataCardName, string buttonName)
773 { //All card entries can be out of order, so search through every line until a match is found and return the information.
774 string posRotData = "";
775 integer cardLength = osGetNumberOfNotecardLines(relatedDataCardName);
776 integer cardIndex = 0;
777 integer matchFound = FALSE;
778 while (!matchFound && cardIndex < cardLength)
779 {
780 string cardLine = osGetNotecardLine(relatedDataCardName, cardIndex);
781 string poseName = NameFromPositionsLine(cardLine);
782 if (poseName == buttonName)
783 {
784 string pos = PosFromPositionsLine(cardLine);
785 string rot = RotFromPositionsLine (cardLine);
786 posRotData = pos + "|" + rot;
787 matchFound = TRUE;
788 }
789 cardIndex++;
790 }
791 return posRotData;
792 }
793
794 CombineMenuDataCardWithRelatedCards(string menuDataCard, string menuName, list relatedMenuCards)
795 { //take every line in the menuData card, find its corresponding line in each related card and combine the information.
796 //then add the combined line to a list, at the end return the list.
797 list pmcaMenuCard;
798 integer cardLength = osGetNumberOfNotecardLines(menuDataCard);
799 integer cardLineIndex;
800 for (cardLineIndex = 0; cardLineIndex < cardLength; cardLineIndex++)
801 {
802 string currentLine = osGetNotecardLine(menuDataCard, cardLineIndex);
803 string buttonName = GetButtonNameFromPmacLine(currentLine);
804 integer relatedCardsIndex;
805 string newLine = currentLine;
806 for (relatedCardsIndex = 0; relatedCardsIndex < llGetListLength(relatedMenuCards); relatedCardsIndex++)
807 {
808 string relatedMenuCardName = llList2String(relatedMenuCards, relatedCardsIndex);
809 string relatedCardSitter = GetSitterNumberFromMenuCardName(relatedMenuCardName);
810 string relatedDataCardName = "Data_Sitter_" + relatedCardSitter + "_" + menuName;
811 string animName = GetAnimNameFromRelatedMenuCard(relatedMenuCardName, buttonName);
812 string posRot = GetPosRotFromRelatedDataCard(relatedDataCardName, buttonName);
813 string extraToAdd = "|" + animName + "|" + posRot;
814 newLine += extraToAdd;
815 }
816 pmcaMenuCard += newLine;
817 }
818 string pmacMenuCardName = ".menu" + "022A " + menuName;
819 WriteNotecard(pmacMenuCardName, pmcaMenuCard);
820 }
821 CombineMenuAndDataCards()
822 { //loop through each of the MenuData cards, find the related cards and pass them one by one to the
823 //combine card method.
824 menuCardNumber = 2;
825 CombineSitter0MenuAndDataCards();
826 list menuDataSitter0Cards = GetSpecificNotecardCards ("MenuData_Sitter_0");
827 integer cardIndex;
828 for (cardIndex = 0; cardIndex < llGetListLength(menuDataSitter0Cards); cardIndex++)
829 {
830 string currentCardName = llList2String(menuDataSitter0Cards, cardIndex);
831 string menuName = GetMenuNameFromMenuCardName(currentCardName);
832 list releatedMenuSitterCards = GetRelatedMenuSitterCards(menuName);
833 if (debug) llOwnerSay("Debug:CombineMenuAndDataCards:ProcessingMenu: " + menuName);
834 if (debug) DebugOwnerSayListContents(menuName + " related cards: ", releatedMenuSitterCards);
835 CombineMenuDataCardWithRelatedCards(currentCardName, menuName, releatedMenuSitterCards);
836 }
837 }
838 default
839 {
840 state_entry()
841 {
842 if (llGetInventoryType("AVpos") != INVENTORY_NOTECARD)
843 {
844 llOwnerSay("AVpos card not found, aborting");
845 }
846 else
847 {
848 llOwnerSay("Conversion Started");
849 ConvertRotations();
850 SplitIntoSitters();
851 llOwnerSay("Sorting singles poses");
852 FixAndCombineSinglePoses();
853 RemovePosesAndPoseDataFromSitters();
854 llOwnerSay("Preparing to convert SYNC's");
855 RemoveEmptyMenusFromSitterCards();
856 llOwnerSay("Creating Temp Menu cards");
857 GenerateMenuCardsForSyncs();
858 llOwnerSay("Creating Temp Position/Rotation cards");
859 GenerateDataCardsForSyncs();
860 llOwnerSay("Creating PMAC menu cards");
861 CombineMenuAndDataCards();
862 llOwnerSay("Clearing up temporary notecards");
863 RemoveTempCards();
864 llOwnerSay("Finished! You should find your new PMAC menu cards inside");
865 }
866
867 }
868 }