Prim teaching script.lsl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. // :CATEGORY:Blue Whale
  2. // :NAME:BlueWhale
  3. // :AUTHOR:Ferd Frederix
  4. // :CREATED:2013-09-06
  5. // :EDITED:2013-09-18 15:38:49
  6. // :ID:107
  7. // :NUM:144
  8. // :REV:1
  9. // :WORLD:Second Life
  10. // :DESCRIPTION:
  11. // learning script
  12. // :CODE:
  13. // Open source, GPL license.
  14. // Do not remove the header, do not sell this script.
  15. // ______ _ ______ _ _
  16. // | ___| | | | ___| | | (_)
  17. // | |_ ___ _ __ __| | | |_ _ __ ___ __| | ___ _ __ ___ __
  18. // | _/ _ \ '__/ _` | | _| '__/ _ \/ _` |/ _ \ '__| \ \/ /
  19. // | || __/ | | (_| | | | | | | __/ (_| | __/ | | |> <
  20. // \_| \___|_| \__,_| \_| |_| \___|\__,_|\___|_| |_/_/\_\
  21. //
  22. // author Ferd Frederix
  23. // Prim position root script
  24. // Put this script in the root prim. Put the child script in all prims you wish to move.
  25. // touch the script to start recording
  26. // Reset - wipe out all recording.
  27. // Name - name a new recording
  28. // Pause - insert a 1 second pause
  29. // PlayBack - play back the current animation
  30. // RemoveAll - removel all child scripts
  31. // Record - store a new set of child prim positions
  32. //
  33. integer debug = 0;
  34. // notecard reading
  35. integer iIndexLines;
  36. integer i = 0;
  37. integer move = 0; // N movements rea from the notecard
  38. string NOTECARD = "Movement"; // the notecard
  39. key kNoteCardLines; // the key of the notecard
  40. key kGetIndexLines; // the key of the current line
  41. //communications
  42. integer linkchannel = 5001; // for recording purposes
  43. integer dialogchannel ; // dialog boxes
  44. integer playchannel = 50003; // the playback channel
  45. integer nPrims; // total number of prims
  46. integer PrimsCounter = 0; // how many have checked in
  47. integer timercounter = 0; // how many seconds have gone by
  48. integer wantname; // flag indicating we are waiting for a name to be chatted
  49. integer pplcounter =0;
  50. // last heard prim params
  51. vector primpos;
  52. rotation primrot;
  53. // the list of coords
  54. list masterlist;
  55. string curranimation;
  56. list Menu;
  57. integer STRIDE = 6;
  58. integer Runtime; // flag that we are in running mode vs learning mode
  59. string strip( string str)
  60. {
  61. return llStringTrim(str, STRING_TRIM);
  62. }
  63. string Getline(list Input, integer line)
  64. {
  65. return strip(llList2String(Input, line));
  66. }
  67. DumpBack ()
  68. {
  69. integer i;
  70. integer max = llGetListLength(masterlist);
  71. integer flag = 0;
  72. for (i = 0; i < max; i+= STRIDE)
  73. {
  74. string aniname2 = llList2String(masterlist,i);
  75. curranimation = aniname2;
  76. integer primnum2 = llList2Integer(masterlist,i+1);
  77. vector sprimpos2 = llList2Vector(masterlist,i+2);
  78. rotation sprimrot2 = llList2Rot(masterlist,i+3) ;
  79. //if (debug) llOwnerSay("aniname:"+ aniname2 + " num:" +(string) primnum2 + " pos:" + (string) sprimpos2 + " rot:" + (string) sprimrot2);
  80. llOwnerSay("|"+ aniname2 + "|" + (string) primnum2 + "|" + (string) sprimpos2 + "|" + (string) sprimrot2);
  81. flag++;
  82. }
  83. if (! flag)
  84. llOwnerSay("No recording!" );
  85. }
  86. PlayBack (string name)
  87. {
  88. integer i;
  89. integer max = llGetListLength(masterlist);
  90. integer linknum = 0;
  91. for (i = 0; i < max; i+= STRIDE)
  92. {
  93. string aniname2 = llList2String(masterlist,i);
  94. if (aniname2 == name)
  95. {
  96. integer primnum2 = llList2Integer(masterlist,i+1);
  97. vector sprimpos2 = llList2Vector(masterlist,i+2);
  98. rotation sprimrot2 = llList2Rot(masterlist,i+3) ;
  99. string msg = llList2String(masterlist,i+4);
  100. string UUID = llList2String(masterlist,i+5);
  101. if (llStringLength(msg) > 0)
  102. llSay(0,msg);
  103. if (llStringLength(UUID) > 0)
  104. llPlaySound(UUID,1.0);
  105. if (primnum2 < 0)
  106. {
  107. llSleep(.5);
  108. }
  109. else
  110. {
  111. sprimrot2 /= llGetRot(); // Add in the local rot
  112. //if (debug) llOwnerSay("|"+ aniname2 + " num:" +(string) primnum2 + " pos:" + (string) sprimpos2 + " rot:" + (string) sprimrot2);
  113. if (primnum2 !=0)
  114. //llSetLinkPrimitiveParamsFast(primnum2,[PRIM_POSITION,sprimpos2,PRIM_ROTATION,sprimrot2]);
  115. llSetLinkPrimitiveParams(primnum2,[PRIM_POSITION,sprimpos2,PRIM_ROTATION,sprimrot2]);
  116. else
  117. //llSetPrimitiveParams([PRIM_POSITION,sprimpos2,PRIM_ROTATION,sprimrot2]);
  118. llSetPrimitiveParams([PRIM_POSITION,sprimpos2,PRIM_ROTATION,sprimrot2]);
  119. }
  120. //llOwnerSay((string) primnum2);
  121. }
  122. }
  123. }
  124. MakeMenu()
  125. {
  126. list amenu = ["Reset","Record","PlayBack","Name","Dump","RemoveAll","Pause"];
  127. amenu += Menu;
  128. llDialog(llGetOwner(), "Pick a command",amenu,dialogchannel);
  129. }
  130. default
  131. {
  132. state_entry()
  133. {
  134. nPrims = llGetNumberOfPrims();
  135. llOwnerSay(" Total Prims = " + (string) nPrims);
  136. kNoteCardLines = llGetNumberOfNotecardLines(NOTECARD);
  137. kGetIndexLines = llGetNotecardLine(NOTECARD,0);
  138. dialogchannel = (integer) (llFrand(100) +600);
  139. llListen(dialogchannel,"","","");
  140. llMessageLinked(LINK_SET,0,"Reset","");
  141. }
  142. // read notecard on bootup
  143. dataserver(key queryid, string data)
  144. {
  145. if (queryid == kNoteCardLines)
  146. {
  147. iIndexLines = (integer) data;
  148. }
  149. if (queryid == kGetIndexLines)
  150. {
  151. if (data != EOF)
  152. {
  153. //if (debug) llOwnerSay("Line");
  154. queryid = llGetNotecardLine(NOTECARD, i);
  155. list lLine = (llParseString2List(data, ["|"], []));
  156. // if (_debug ) llOwnerSay("Line = " + llDumpList2String(lLine,":"));
  157. string junk = llList2String(lLine,0);
  158. string aniname = llList2String(lLine,1);
  159. integer Num = (integer)Getline(lLine,2);
  160. vector Pos = (vector) Getline(lLine,3);
  161. rotation Rot = (rotation) Getline(lLine,4);
  162. string msg = llList2String(lLine,5);
  163. string UUID = llList2String(lLine,6);
  164. if(Num>=0)
  165. {
  166. if (llStringLength(msg) > 0)
  167. llSay(0,msg);
  168. if (llStringLength(UUID) > 0)
  169. llPlaySound(UUID,1.0);
  170. masterlist += [aniname];
  171. masterlist += [Num];
  172. masterlist += [Pos];
  173. masterlist += [Rot];
  174. masterlist += [msg];
  175. masterlist += [UUID];
  176. Rot /= llGetRot();
  177. llSetLinkPrimitiveParams(Num,[PRIM_POSITION,Pos,PRIM_ROTATION,Rot]);
  178. //llSetLinkPrimitiveParamsFast(Num,[PRIM_POSITION,Pos,PRIM_ROTATION,Rot]);
  179. move++;
  180. }
  181. i++;
  182. integer InitPerCent = (integer) llRound(( (i+1) / (float) iIndexLines) * 100);
  183. llSetText("Initialising... \n" + (string) InitPerCent + "%" , <1,1,1>, 1.0);
  184. if (InitPerCent == 100)
  185. llSetText("" , <1,1,1>, 1.0);
  186. kGetIndexLines = llGetNotecardLine(NOTECARD,i);
  187. }
  188. else
  189. {
  190. llOwnerSay("initialized with " + (string) move + " movements");
  191. llSetText("" , <1,1,1>, 1.0);
  192. llMessageLinked(LINK_THIS, playchannel, "bird", "");
  193. }
  194. }
  195. }
  196. touch_start(integer total_number)
  197. {
  198. if (! Runtime && llDetectedKey(0) == llGetOwner())
  199. {
  200. MakeMenu();
  201. }
  202. }
  203. listen( integer channel, string name, key id, string message )
  204. {
  205. if (channel == dialogchannel)
  206. {
  207. if (message == "Reset")
  208. {
  209. masterlist = [];
  210. MakeMenu();
  211. }
  212. else if (message =="Pause")
  213. {
  214. masterlist += [curranimation];
  215. masterlist += [-1];
  216. masterlist += [<0,0,0>];
  217. masterlist += [<0,0,1>];
  218. masterlist += ["Pause"];
  219. masterlist += [""];
  220. MakeMenu();
  221. }
  222. else if (message == "RemoveAll")
  223. {
  224. llMessageLinked(LINK_SET,0,"Remove","");
  225. Runtime++;
  226. }
  227. else if (message == "Record")
  228. {
  229. PrimsCounter = 0;
  230. timercounter = 0;
  231. llSetTimerEvent(1.0);
  232. llMessageLinked(LINK_SET,0,"Set","");
  233. MakeMenu();
  234. }
  235. else if (message == "Name")
  236. {
  237. llOwnerSay("Type the current animation name on channel /" + (string) dialogchannel);
  238. wantname++;
  239. MakeMenu();
  240. }
  241. else if (message == "PlayBack")
  242. {
  243. PlayBack(curranimation);
  244. MakeMenu();
  245. }
  246. else if (message == "Dump")
  247. {
  248. DumpBack();
  249. MakeMenu();
  250. }
  251. else if (wantname)
  252. {
  253. curranimation = message;
  254. MakeMenu();
  255. Menu += [message];
  256. llOwnerSay("Recording is ready for animation '" + curranimation + "'");
  257. llOwnerSay("Position all child prims, then select the Menu item 'Record'. When finished, click 'PlayBack' to play back the animation, or click 'Name' to record a new animation, or click 'RemoveAll' to finish and shut down all child scripts");
  258. wantname = 0;
  259. PrimsCounter = 0;
  260. llMessageLinked(LINK_SET,0,"All","");
  261. timercounter = 0;
  262. llSetTimerEvent(1.0);
  263. }
  264. else
  265. {
  266. if (debug) llOwnerSay("Possible Animations:" + llDumpList2String(Menu,","));
  267. if (llListFindList(Menu,[message]) > -1)
  268. {
  269. //if (debug) llOwnerSay("Playing back animation " + message);
  270. PlayBack(message);
  271. }
  272. }
  273. }
  274. }
  275. on_rez(integer param)
  276. {
  277. llListen(dialogchannel,"","","");
  278. }
  279. link_message(integer sender_num, integer num, string message, key id)
  280. {
  281. //llOwnerSay((string) sender_num);
  282. if (num == 1) // They sat
  283. {
  284. if (debug) llOwnerSay(message);
  285. if (message == "R1" || message == "L1")
  286. {
  287. pplcounter++;
  288. llMessageLinked(LINK_THIS, playchannel, "stand", "");
  289. llSleep(0.5);
  290. llMessageLinked(LINK_THIS, playchannel, "down", "");
  291. }
  292. if (message == "L0"|| message == "R0")
  293. {
  294. pplcounter--;
  295. }
  296. if (pplcounter < 0)
  297. {
  298. llMessageLinked(LINK_THIS, playchannel, "stand", "");
  299. llSleep(1.0);
  300. llMessageLinked(LINK_THIS, playchannel, "bird", "");
  301. pplcounter = 0;
  302. }
  303. }
  304. else if (num == playchannel)
  305. {
  306. if (debug) llOwnerSay("playback animation " + message);
  307. PlayBack(message);
  308. }
  309. else if (num == linkchannel)
  310. {
  311. PrimsCounter++;
  312. //if(debug) llOwnerSay("link message :" + message);
  313. list my_list = llParseString2List(message,["|"],[""]);
  314. if (debug) llOwnerSay(llDumpList2String(my_list,","));
  315. string sprimpos = llList2String(my_list,0);
  316. string sprimrot = llList2String(my_list,1);
  317. primpos = (vector) sprimpos;
  318. primrot = (rotation) sprimrot;
  319. if (llStringLength(curranimation) > 0)
  320. {
  321. //if (debug) llOwnerSay("Adding ani:"+ curranimation + " num:" +(string) sender_num + " pos:" + (string) primpos + " rot:" + (string) primrot);
  322. masterlist += curranimation;
  323. masterlist += sender_num;
  324. masterlist += primpos;
  325. masterlist += primrot;
  326. masterlist += ""; // sounds
  327. masterlist += "";
  328. integer count = llGetListLength(masterlist) / STRIDE;
  329. //llOwnerSay("Recorded " + (string) count + " coords");
  330. }
  331. }
  332. }
  333. timer()
  334. {
  335. integer left = nPrims - PrimsCounter; // how many left to report in
  336. if (left)
  337. llOwnerSay((string) left + " remaining of " + (string) nPrims);
  338. else
  339. {
  340. llSetTimerEvent(0.0);
  341. llOwnerSay("Ready");
  342. }
  343. if (timercounter++ > 10)
  344. {
  345. timercounter = 0;
  346. PrimsCounter = 0;
  347. llOwnerSay("Giving up");
  348. llSetTimerEvent(0);
  349. }
  350. }
  351. }