Advertisement
AineCaoimhe

addon PAO LockGuard v1.0

Jul 7th, 2017
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.31 KB | None | 0 0
  1. // LOCKGUARD ADD-ON FOR PMAC 1.0
  2. // by Aine Caoimhe (c. LACM) July 2017
  3. // Provided under Creative Commons Attribution-Non-Commercial-ShareAlike 4.0 International license.
  4. // Please be sure you read and adhere to the terms of this license: https://creativecommons.org/licenses/by-nc-sa/4.0/
  5. //
  6. // Command format for this addon:
  7. // PAO_LOCK{chain_data_pos1::chain_data_pos12...}
  8. // for each position the following is needed:
  9. // child_prim_name=lockguard_link_name and any other valid lg commands
  10. // to do multiples, separate each with "&&"
  11. // if a position has no data, it needs to be given "LOCK_NO_COM" instead
  12. //
  13. // Example #1: for a 2-person pose where the 1st position has 3 chains and the 2nd position has none...
  14. // Pose1|POA_LOCK{Point-1=rightwrist&&Point-3=leftwrist&&Point-8=leftankle::LOCK_NO_COM}|...the rest of the animation line data
  15. // Example #2" the exact same pose, except this time it's position 1 that has no chains and position 2 that has 3
  16. // Pose2|POA_LOCK{LOCK_NO_COM::Point-1=rightwrist&&Point-3=leftwrist&&Point-8=leftankle}|...the rest of the animation line data
  17. //
  18. // Each possible LG attachment point of the PMAC object must be a child prim (cannot be root) and must have a UNIQUE name (it also can't
  19. // be "Primitive" even it it's the only prim with that name)
  20. //
  21. integer warnAboutDupes=FALSE;
  22. // During initialization ths add-on has to check child-prim names and retain a list of any that are unique. When discovering duplicated named prims it will
  23. // ignore them but by setting this TRUE you will be notified that it's doing so which could be useful when creating a new item or during an MLP conversion process.
  24. // Leaving it at the default FALSE will have it ignore them silently.
  25. //
  26. // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  27. // DO NOT CHANGE ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING
  28. // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  29. //
  30. integer lgChannel=-9119; // LG channel per spec.
  31. list targets; //[child prim name, key,....]
  32. list existingLinks; // pairs of data for avatar and which lg points are being used... [avatar key, point1|point2|point3|....]...order doesn't matter
  33. //
  34. // FOR REFERENCE: LG syntax expected by the receiving object )cuff or whatever):
  35. // llWhisper( -9119, "lockguard " + (string)[targetUUID] +" "+ (string)[item to link]+" " + (string)[commands using space separation] );
  36. // only critical commands are the link and unlink....link is followed by the key of the PMAC object attachment point and unlink has no argument
  37. //
  38. addLinks(key who, string dataBlock)
  39. {
  40. //ignore invalid or null keys and datablocks marked as empty
  41. if (who==NULL_KEY) return;
  42. if (!osIsUUID(who)) return;
  43. if (dataBlock=="LOCK_NO_COM") return;
  44. // getting here means we ought to have something we need to draw so now we need to break it by attach points
  45. list pointsData=llParseString2List(dataBlock,["&&"],[]);
  46. integer p=llGetListLength(pointsData);
  47. list targetLinkData=[];
  48. while (--p>=0)
  49. {
  50. list thisPointData=llParseString2List(llList2String(pointsData,p),["="],[]);
  51. string thisPoint=llList2String(thisPointData,0); // the name of the PMAC attachment point prim
  52. integer indexThisPoint=llListFindList(targets,[thisPoint]);
  53. if (indexThisPoint==-1) llOwnerSay("ERROR: told to draw a chain to child prim "+thisPoint+" but it doesn't exist");
  54. else
  55. {
  56. key thisPointKey=llList2Key(targets,indexThisPoint+1);
  57. string attachString=llList2String(thisPointData,1);
  58. integer firstSpace=llSubStringIndex(attachString," ");
  59. if (firstSpace>-1) firstSpace--; // we don't want to bring the space with it too
  60. string attachName=llGetSubString(attachString,0,firstSpace); // this is just the cuff name to store in the user list
  61. targetLinkData=[]+targetLinkData+[attachName];
  62. llWhisper(lgChannel,"lockguard "+(string)who+" "+attachString+" link "+(string)thisPointKey);
  63. }
  64. }
  65. existingLinks=[]+existingLinks+[who,llDumpList2String(targetLinkData,"|")];
  66. }
  67. stripLinks(key who)
  68. {
  69. // remove any links
  70. integer lInd=llListFindList(existingLinks,[who]);
  71. if (lInd>-1)
  72. {
  73. // there are some so parse them to list and remove one by one
  74. list pointsToStrip=llParseString2List(llList2String(existingLinks,lInd+1),["|"],[]);
  75. integer p=llGetListLength(pointsToStrip);
  76. while (--p>=0) { llWhisper(lgChannel,"lockguard "+(string)who+" "+llList2String(pointsToStrip,p)+" unlink"); }
  77. // delete the entry
  78. existingLinks=[]+llDeleteSubList(existingLinks,lInd,lInd+1);
  79. }
  80. }
  81. buildTargetList()
  82. {
  83. list ignore=[];
  84. targets=[];
  85. integer link=llGetNumberOfPrims();
  86. if (link==1)
  87. {
  88. llOwnerSay("LOCKGUARD PMAC addon cannot work with an object that has only 1 prim. Please read the instructions!");
  89. return;
  90. }
  91. while (link>1)
  92. {
  93. string name=llGetLinkName(link);
  94. if (name!="Primitive")
  95. {
  96. if (llListFindList(ignore,[name])>-1)
  97. {
  98. if (warnAboutDupes) llOwnerSay("WARNING! LOCKGUARD for PMAC found another child prim with the name \""+name+"\" and will ignore it too.");
  99. }
  100. if (llListFindList(targets,[name])>-1)
  101. {
  102. if (warnAboutDupes) llOwnerSay("WARNING! LOCKGUARD for PMAC found two child prims with the same name \""+name+"\" and will ignore them. They cannot be called as attachment points");
  103. targets=[]+llDeleteSubList(targets,llListFindList(targets,[name]),llListFindList(targets,[name]));
  104. ignore=[]+ignore+[name];
  105. }
  106. else targets=[]+[name,llGetLinkKey(link)]+targets;
  107. }
  108. link--;
  109. }
  110. }
  111. default
  112. {
  113. state_entry()
  114. {
  115. // we need a quick-access list of attachment points to potentially attach chains to so might as well build it on start-up when there's no appreciable load
  116. buildTargetList();
  117. existingLinks=[];
  118. }
  119. link_message(integer fromLink,integer num, string message, key ID)
  120. {
  121. list parsed=llParseString2List(message,["|"],[]);
  122. // see if this is a main PMAC command that we need to pay attention to
  123. string mainCommand=llList2String(parsed,0);
  124. if (mainCommand=="GLOBAL_SYSTEM_RESET")
  125. {
  126. // release any existingLinks
  127. while (llGetListLength(existingLinks)>0) { stripLinks(llList2Key(existingLinks,0)); }
  128. llResetScript();
  129. }
  130. else if (mainCommand=="GLOBAL_USER_STOOD")
  131. {
  132. // release any existingLinks
  133. stripLinks(llList2Key(parsed,2));
  134. }
  135. else if (mainCommand=="GLOBAL_NEXT_AN")
  136. {
  137. // whether or not there's data for the new animation, we need to remove any old
  138. while (llGetListLength(existingLinks)>0) { stripLinks(llList2Key(existingLinks,0)); }
  139. // find out if the command block has anything for us..
  140. list theseCommands=llParseString2List(llList2String(parsed,1),["{","}"],[]);
  141. integer indexThisBlock=(llListFindList(theseCommands,["PAO_LOCK"]));
  142. if (indexThisBlock==-1) return; // finished if there isn't any new data
  143. // otherwise let's read our block and break it into positions first
  144. list positionData=llParseString2List(llList2String(theseCommands,indexThisBlock+1),["::"],[]);
  145. // pull the users list from the passed data
  146. list users=llParseString2List((string)ID,["|"],[]);
  147. integer u=llGetListLength(users);
  148. // error-check length match
  149. if (llGetListLength(positionData)!=u)
  150. {
  151. llOwnerSay("ERROR! LOCKGUARD add-on encountered a mismatch between number of postions in the card chain data and number of positions in the pose. Can't draw chains");
  152. return;
  153. }
  154. // otherwise send each
  155. llSleep(0.1); // yes, this is a deliberate thread-lock - due to potential asynch sending we need to do a short delay to ensure that any new draw commands arrive *after* the last of the strip ones
  156. while (--u>=0) { addLinks(llList2Key(users,u),llList2String(positionData,u)); }
  157. }
  158. }
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement