Guest User

ZHAO-II core - LSL Functions (tkls 5/9/13.4)

a guest
May 9th, 2013
552
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.76 KB | None | 0 0
  1. // ZHAO-II-core - Ziggy Puff, 07/07
  2. /////////////////////////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Chloe1982 Constantine, 05/08/13 - Modified/Updated to use the new LSL Animation functions, timer is
  5. // now used only to detect swimming (timerEventLength)
  6. //
  7. // Ziggy, 07/16/07 - Warning instead of error on 'no animation in inventory', that way SL's built-in
  8. // anims can be used
  9. //
  10. // Ziggy, 07/14/07 - 2 bug fixes. Listens aren't being reset on owner change, and a typo in the
  11. // ground sit animation code
  12. //
  13. // Ziggy, 06/07:
  14. // Reduce script count, since idle scripts take up scheduler time
  15. // Tokenize notecard reader, to simplify notecard setup
  16. // Remove scripted texture changes, to simplify customization by animation sellers
  17.  
  18. // Fennec Wind, January 18th, 2007:
  19. // Changed Walk/Sit/Ground Sit dialogs to show animation name (or partial name if too long)
  20. // and only show buttons for non-blank entries.
  21. // Fixed minor bug in the state_entry, ground sits were not being initialized.
  22. //
  23. //
  24. // Dzonatas Sol, 09/06: Fixed forward walk override (same as previous backward walk fix).
  25. //
  26. // Based on Francis Chung's Franimation Overrider v1.8
  27. //
  28. // This program is free software; you can redistribute it and/or modify
  29. // it under the terms of the GNU General Public License as published by
  30. // the Free Software Foundation; either version 2 of the License, or
  31. // (at your option) any later version.
  32. //
  33. // This program is distributed in the hope that it will be useful,
  34. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  36. // GNU General Public License for more details.
  37. //
  38. // You should have received a copy of the GNU General Public License
  39. // along with this program; if not, write to the Free Software
  40. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  41.  
  42. /////////////////////////////////////////////////////////////////////////////////////////////////////
  43. // Main engine script - receives link messages from any interface script. Handles the core AO work
  44. //
  45. // Interface definition: The following link_message commands are handled by this script. All of
  46. // these are sent in the string field. All other fields are ignored
  47. //
  48. // ZHAO_RESET Reset script
  49. // ZHAO_LOAD|<notecardName> Load specified notecard
  50. // ZHAO_NEXTSTAND Switch to next stand
  51. // ZHAO_STANDTIME|<time> Time between stands. Specified in seconds, expects an integer.
  52. // 0 turns it off
  53. // ZHAO_AOON AO On
  54. // ZHAO_AOOFF AO Off
  55. // ZHAO_SITON Sit On
  56. // ZHAO_SITOFF Sit Off
  57. // ZHAO_RANDOMSTANDS Stands cycle randomly
  58. // ZHAO_SEQUENTIALSTANDS Stands cycle sequentially
  59. // ZHAO_SETTINGS Prints status
  60. // ZHAO_SITS Select a sit
  61. // ZHAO_GROUNDSITS Select a ground sit
  62. // ZHAO_WALKS Select a walk
  63. //
  64. // So, to send a command to the ZHAO-II engine, send a linked message:
  65. //
  66. // llMessageLinked(LINK_SET, 0, "ZHAO_AOON", NULL_KEY);
  67. //
  68. // This script uses a listener on channel -91234. If other scripts are added to the ZHAO, make sure
  69. // they don't use the same channel
  70. /////////////////////////////////////////////////////////////////////////////////////////////////////
  71.  
  72. /////////////////////////////////////////////////////////////////////////////////////////////////////
  73. // New notecard format
  74. //
  75. /////////////////////////////////////////////////////////////////////////////////////////////////////
  76. // Lines starting with a / are treated as comments and ignored. Blank lines are ignored. Valid lines
  77. // look like this:
  78. //
  79. // [ Walking ]SexyWalk1|SexyWalk2|SexyWalk3
  80. //
  81. // The token (in this case, [ Walking ]) identifies the animation to be overridden. The rest is a
  82. // list of animations, separated by the '|' (pipe) character. You can specify multiple animations
  83. // for Stands, Walks, Sits, and GroundSits. Multiple animations on any other line will be ignored.
  84. // You can have up to 12 animations each for Walks, Sits and GroundSits. There is no hard limit
  85. // on the number of stands, but adding too many stands will make the script run out of memory and
  86. // crash, so be careful. You can repeat tokens, so you can split the Stands up across multiple lines.
  87. // Use the [ Standing ] token in each line, and the script will add the animation lists together.
  88. //
  89. // Advanced: Each 'animation name' can be a comma-separated list of animations, which will be played
  90. // together. For example:
  91. //
  92. // [ Walking ]SexyWalk1UpperBody,SexyWalk1LowerBody|SexyWalk2|SexyWalk3
  93. //
  94. // Note the ',' between SexyWalk1UpperBody and SexyWalk1LowerBody - this tells ZHAO-II to treat these
  95. // as a single 'animation' and play them together. The '|' between this 'animation' and SexyWalk2 tells
  96. // ZHAO-II to treat SexyWalk2 and SexyWalk3 as separate walk animations. You can use this to layer
  97. // animations on top of each other.
  98. //
  99. // Do not add any spaces around animation names!!!
  100. //
  101. // The token can be one of the following:
  102. //
  103. // [ Standing ]
  104. // [ Walking ]
  105. // [ Sitting ]
  106. // [ Sitting On Ground ]
  107. // [ Crouching ]
  108. // [ Crouch Walking ]
  109. // [ Landing ]
  110. // [ Standing Up ]
  111. // [ Falling ]
  112. // [ Flying Down ]
  113. // [ Flying Up ]
  114. // [ Flying ]
  115. // [ Flying Slow ]
  116. // [ Hovering ]
  117. // [ Jumping ]
  118. // [ Pre Jumping ]
  119. // [ Running ]
  120. // [ Turning Right ]
  121. // [ Turning Left ]
  122. // [ Floating ]
  123. // [ Swimming Forward ]
  124. // [ Swimming Up ]
  125. // [ Swimming Down ]
  126. //
  127.  
  128.  
  129. // CONSTANTS
  130. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. // Default notecard we read on script_entry
  132. string defaultNoteCard = "Default";
  133.  
  134. // List of all the animation states
  135. list animState = [ "Sitting on Ground", "Sitting", "Striding", "Crouching", "CrouchWalking",
  136. "Soft Landing", "Standing Up", "Falling Down", "Hovering Down", "Hovering Up",
  137. "FlyingSlow", "Flying", "Hovering", "Jumping", "PreJumping", "Running",
  138. "Turning Right", "Turning Left", "Walking", "Landing", "Standing", "Taking Off" ];
  139.  
  140. // Logic change - we now have a list of tokens. The 'overrides' list is the same length as this,
  141. // i.e. it has one entry per token, *not* one entry per animation. Multiple options for a token
  142. // are stored as | separated strings in a single list entry. This was done to save memory, and
  143. // allow a larger number of stands etc. All the xxxIndex variables now refer to the token index,
  144. // since that's how long 'overrides' is.
  145.  
  146. // List of internal tokens. This *must* be in the same sequence as the animState list. Note that
  147. // we combine some tokens after the notecard is read (striding/walking, landing/soft landing), etc.
  148. // The publicized tokens list only contains one entry for each pair, but we'll accept both, and
  149. // combine them later
  150. list tokens = [ "Sitting On Ground", "Sitting", "Striding", "Crouching", "Crouch Walking", // 0-4
  151. "Soft Landing", "Standing Up", "Falling", "Flying Down", "Flying Up", // 5-9
  152. "Flying Slow", "Flying", "Hovering", "Jumping", "Pre Jumping", // 10-14
  153. "Running", "Turning Right", "Turning Left", "Walking", "Landing", // 15-19
  154. "Standing", "Taking Off", "Swimming Down", "Swimming Up", "Swimming Forward", // 20-24
  155. "Floating" ]; // 25
  156.  
  157. // The tokens for which we allow multiple animations
  158. string multiAnimTokenIndexes = ",0,1,18,20,"; // Groundsit, Sitting, Walking, Standing
  159.  
  160. // Index of interesting animations
  161. integer noAnimIndex = -1;
  162. integer sitgroundIndex = 0;
  163. integer sittingIndex = 1;
  164. /*
  165. integer hoverdownIndex = 8;
  166. integer hoverupIndex = 9;
  167. integer flyingslowIndex = 10;
  168. integer flyingIndex = 11;
  169. integer hoverIndex = 12;
  170. */
  171. integer walkingIndex = 18;
  172. integer standingIndex = 20;
  173. /*
  174. integer swimdownIndex = 22;
  175. integer swimupIndex = 23;
  176. integer swimmingIndex = 24;
  177. integer waterTreadIndex = 25;
  178. */
  179.  
  180. // magic string that replaces the following commented out lists
  181. string magicPos = "12111009082524242322";
  182. // number of swimming replacement anims
  183. integer magicSwim = 5;
  184.  
  185. // list of animations that have a different value when underwater
  186. //list underwaterAnim = [ hoverIndex, flyingIndex, flyingslowIndex, hoverupIndex, hoverdownIndex ];
  187.  
  188. // corresponding list of animations that we override the overrider with when underwater
  189. //list underwaterOverride = [ waterTreadIndex, swimmingIndex, swimmingIndex, swimupIndex, swimdownIndex];
  190.  
  191. // How long before flipping stand animations
  192. integer standTimeDefault = 30;
  193.  
  194. // How fast should we poll for whether or not we're under water?
  195. // NOTE, you can change this to whatever value you like, it will just change the delay on how long it takes
  196. // you to start/stop swimming
  197.  
  198. float timerEventLength = 3.0;
  199.  
  200. // Number of timer events that will have to pass to change an anim
  201. integer maxTicks;
  202. // Number of ticks that have passed
  203. integer numTicks = 0;
  204. // Are we underwater?
  205. integer isUnder = FALSE;
  206.  
  207. // Listen channel for pop-up menu
  208. integer listenChannel = -91234;
  209.  
  210. // GLOBALS
  211. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  212.  
  213. integer numStands; // Number of stands - needed for auto cycle
  214. integer randomStands = FALSE; // Whether stands cycle randomly
  215. integer curStandIndex; // Current stand - needed for cycling
  216. string curStandAnim = ""; // Current Stand animation
  217. string curSitAnim = ""; // Current sit animation
  218. string curWalkAnim = ""; // Current walk animation
  219. string curGsitAnim = ""; // Current ground sit animation
  220.  
  221. list overrides = []; // List of animations we override
  222. key notecardLineKey; // notecard reading keys
  223. integer notecardIndex; // current line being read from notecard
  224. integer numOverrides; // # of overrides
  225.  
  226. integer standTime = standTimeDefault; // How long before flipping stand animations
  227.  
  228. integer animOverrideOn = TRUE; // Is the animation override on?
  229. integer gotPermission = FALSE; // Do we have animation permissions?
  230.  
  231. integer listenHandle; // Listen handlers - only used for pop-up menu, then turned off
  232.  
  233. integer haveWalkingAnim = FALSE; // Hack to get it so we face the right way when we walk backwards
  234.  
  235. integer sitOverride = TRUE; // Whether we're overriding sit or not
  236.  
  237. integer listenState = 0; // What pop-up menu we're handling now
  238.  
  239. integer loadInProgress = FALSE; // Are we currently loading a notecard
  240. string notecardName = ""; // The notecard we're currently reading
  241.  
  242. key Owner = NULL_KEY;
  243.  
  244. // String constants to save a few bytes
  245. string EMPTY = "";
  246. string SEPARATOR = "|";
  247. string TRYAGAIN = "\nPlease correct the notecard and try again.";
  248.  
  249. // CODE
  250. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  251.  
  252. // Enable or disable the AO
  253.  
  254. AO_Enable()
  255. {
  256. llSetTimerEvent(timerEventLength);
  257. numTicks = 0;
  258. if (gotPermission)
  259. sendOverrides();
  260. }
  261.  
  262. AO_Disable()
  263. {
  264. llSetTimerEvent(0.0);
  265. if (gotPermission)
  266. llResetAnimationOverride("ALL"); // Clear them all out
  267. }
  268.  
  269. // Send new overrides to the server
  270. sendOverrides()
  271. {
  272. integer n = llGetListLength(animState);
  273. string anim = EMPTY;
  274. string st;
  275. while (n--)
  276. {
  277. st = llList2String(animState, n);
  278. if ((anim = llList2String(overrides, n)) == EMPTY)
  279. llResetAnimationOverride(st);
  280. else if (llSubStringIndex(multiAnimTokenIndexes, "," + (string)n + ",") == -1)
  281. doAnimSet(st, anim);
  282. else
  283. {
  284. if (n == 0)
  285. anim = curGsitAnim;
  286. else if (n == 1)
  287. anim = curSitAnim;
  288. else if (n == 18)
  289. anim = curWalkAnim;
  290. else
  291. anim = curStandAnim;
  292. doAnimSet(st, anim);
  293. }
  294. }
  295. }
  296.  
  297. // Switch to the next stand anim
  298. doNextStand(integer fromUI)
  299. {
  300. if (numStands > 0)
  301. {
  302. if (randomStands)
  303. curStandIndex = llFloor(llFrand(numStands));
  304. else
  305. curStandIndex = (curStandIndex + 1) % numStands;
  306.  
  307. doAnimSet("Standing", curStandAnim = findMultiAnim(20, curStandIndex)); //, 20
  308.  
  309. if (fromUI)
  310. llOwnerSay("Switching to stand '" + curStandAnim + "'.");
  311. }
  312. else if (fromUI)
  313. llOwnerSay("No stand animations configured.");
  314. }
  315.  
  316. // Actually set the animation (if we need to)
  317. doAnimSet(string st, string anim)
  318. {
  319. if (anim == EMPTY)
  320. return;
  321. if (animOverrideOn)
  322. llSetAnimationOverride(st, anim);
  323. }
  324.  
  325. // Displays menu of animation choices
  326. doMultiAnimMenu( integer _animIndex, string _animType, string _currentAnim )
  327. {
  328. // Dialog enhancement - Fennec Wind
  329. // Fix - a no-mod anim with a long name will break this
  330.  
  331. list anims = llParseString2List( llList2String(overrides, _animIndex), [SEPARATOR], [] );
  332. integer numAnims = llGetListLength( anims );
  333. if ( numAnims > 12 ) {
  334. llOwnerSay( "Too many animations, cannot generate menu. " + TRYAGAIN );
  335. return;
  336. }
  337.  
  338. list buttons = [];
  339. integer i;
  340. string animNames = EMPTY;
  341. for ( i=0; i<numAnims; i++ ) {
  342. animNames += "\n" + (string)(i+1) + ". " + llList2String( anims, i );
  343. buttons += [(string)(i+1)];
  344. }
  345. // If no animations were configured, say so and just display an "OK" button
  346. if ( animNames == EMPTY ) {
  347. animNames = "\n\nNo overrides have been configured.";
  348. }
  349. llListenControl(listenHandle, TRUE);
  350. llDialog( Owner, "Select the " + _animType + " animation to use:\n\nCurrently: " + _currentAnim + animNames,
  351. buttons, listenChannel );
  352. }
  353.  
  354. // Returns an animation from the multiAnims
  355. string findMultiAnim( integer _animIndex, integer _multiAnimIndex )
  356. {
  357. list animsList = llParseString2List( llList2String(overrides, _animIndex), [SEPARATOR], [] );
  358. return llList2String( animsList, _multiAnimIndex );
  359. }
  360.  
  361. // Checks for too many animations - can't do menus with > 12 animations
  362. checkMultiAnim( integer _animIndex, string _animName )
  363. {
  364. list animsList = llParseString2List( llList2String(overrides, _animIndex), [SEPARATOR], [] );
  365. if ( llGetListLength(animsList) > 12 )
  366. llOwnerSay( "You have more than 12 " + _animName + " animations. Please correct this." );
  367. }
  368.  
  369. checkAnimInInventory( string _csvAnims )
  370. {
  371. list anims = llCSV2List( _csvAnims );
  372. integer i;
  373. for( i=0; i<llGetListLength(anims); i++ ) {
  374. string animName = llList2String( anims, i );
  375. if ( llGetInventoryType( animName ) != INVENTORY_ANIMATION ) {
  376. // Only a warning, so built-in anims can be used
  377. llOwnerSay( "Warning: Couldn't find animation '" + animName + "' in inventory." );
  378. }
  379. }
  380. }
  381.  
  382. // Print free memory. Separate function to save a few bytes
  383. printFreeMemory()
  384. {
  385. float memory = (float)llGetFreeMemory() * 100.0 / 16384.0;
  386. llOwnerSay( (string)((integer)memory) + "% memory free" );
  387. }
  388.  
  389. doWater(integer drowning)
  390. {
  391. if (isUnder == drowning)
  392. return;
  393. integer n = magicSwim;
  394. integer off = 0;
  395. if (isUnder = drowning)
  396. off = 2 * n;
  397.  
  398. integer p;
  399. integer po;
  400. string anim;
  401. string st;
  402. while (n--)
  403. {
  404. po = p = (integer)llGetSubString(magicPos, n * 2, n * 2 + 1);
  405. if (isUnder)
  406. po = (integer)llGetSubString(magicPos, n * 2 + off, n * 2 + 1 + off);
  407. st = llList2String(animState, p);
  408. if ((anim = llList2String(overrides, po)) == EMPTY)
  409. llResetAnimationOverride(st);
  410. else
  411. doAnimSet(st, anim);
  412. }
  413. }
  414.  
  415. // Load all the animation names from a notecard
  416. loadNoteCard() {
  417.  
  418. if ( llGetInventoryKey(notecardName) == NULL_KEY ) {
  419. llOwnerSay( "Notecard '" + notecardName + "' does not exist, or does not have full permissions." );
  420. loadInProgress = FALSE;
  421. notecardName = EMPTY;
  422. return;
  423. }
  424.  
  425. llOwnerSay( "Loading notecard '" + notecardName + "'..." );
  426.  
  427. // Faster events while processing our notecard
  428. llMinEventDelay( 0 );
  429.  
  430. // Clear out saved override information, since we now allow sparse notecards
  431. overrides = [];
  432. integer i;
  433. for ( i=0; i<numOverrides; i++ )
  434. overrides += [EMPTY];
  435.  
  436. // Clear out multi-anim info as well, since we may end up with fewer options
  437. // that the last time
  438. curStandIndex = 0;
  439. curStandAnim = EMPTY;
  440. curSitAnim = EMPTY;
  441. curWalkAnim = EMPTY;
  442. curGsitAnim = EMPTY;
  443.  
  444. // Start reading the data
  445. notecardIndex = 0;
  446. notecardLineKey = llGetNotecardLine( notecardName, notecardIndex );
  447. }
  448.  
  449. // Stop loading notecard
  450. endNotecardLoad()
  451. {
  452. loadInProgress = FALSE;
  453. notecardName = EMPTY;
  454. }
  455.  
  456. // Initialize listeners, and reset some status variables
  457. initialize() {
  458. Owner = llGetOwner();
  459.  
  460. float tevent = 0.0;
  461. if (animOverrideOn)
  462. tevent = standTime;
  463. llSetTimerEvent(tevent);
  464. numTicks = 0;
  465. maxTicks = llRound(standTime / timerEventLength);
  466.  
  467. gotPermission = FALSE;
  468.  
  469. // Create new listener, and turn it off
  470. if ( listenHandle )
  471. llListenRemove( listenHandle );
  472.  
  473. listenHandle = llListen( listenChannel, EMPTY, Owner, EMPTY );
  474. llListenControl( listenHandle, FALSE );
  475.  
  476. printFreeMemory();
  477. }
  478.  
  479. // STATE
  480. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  481.  
  482. default {
  483. state_entry() {
  484. integer i;
  485.  
  486. Owner = llGetOwner();
  487.  
  488. // Just a precaution, this shouldn't be on after a reset
  489. if ( listenHandle )
  490. llListenRemove( listenHandle );
  491.  
  492. listenHandle = llListen( listenChannel, EMPTY, Owner, EMPTY );
  493.  
  494. if (llGetAttached())
  495. llRequestPermissions(Owner, PERMISSION_OVERRIDE_ANIMATIONS);
  496.  
  497. numOverrides = llGetListLength(tokens);
  498.  
  499. // populate override list with blanks
  500. overrides = [];
  501. for ( i=0; i<numOverrides; i++ ) {
  502. overrides += [ EMPTY ];
  503. }
  504. randomStands = FALSE;
  505. initialize();
  506. notecardName = defaultNoteCard;
  507. loadInProgress = TRUE;
  508. loadNoteCard();
  509. }
  510.  
  511. on_rez( integer _code ) {
  512. initialize();
  513. }
  514.  
  515. attach( key _k ) {
  516. if (_k != NULL_KEY)
  517. llRequestPermissions(Owner, PERMISSION_OVERRIDE_ANIMATIONS);
  518. else if (gotPermission)
  519. llResetAnimationOverride("ALL");
  520. gotPermission = FALSE;
  521. }
  522.  
  523. run_time_permissions( integer _perm ) {
  524. if (_perm & PERMISSION_OVERRIDE_ANIMATIONS)
  525. {
  526. if (animOverrideOn)
  527. sendOverrides();
  528. gotPermission = TRUE;
  529. }
  530. }
  531.  
  532. link_message( integer _sender, integer _num, string _message, key _id) {
  533.  
  534. // Coming from an interface script
  535. if ( _message == "ZHAO_RESET" ) {
  536. llOwnerSay( "Resetting..." );
  537. llResetScript();
  538.  
  539. } else if ( _message == "ZHAO_AOON" ) {
  540. animOverrideOn = TRUE;
  541. llOwnerSay("AO Enabled.");
  542. AO_Enable();
  543.  
  544. } else if ( _message == "ZHAO_AOOFF" ) {
  545. animOverrideOn = FALSE;
  546. llOwnerSay("AO Disabled.");
  547. AO_Disable();
  548.  
  549. } else if ( _message == "ZHAO_SITON" ) {
  550. // Turning on sit override
  551. sitOverride = TRUE;
  552. llOwnerSay("Sit override: On");
  553. doAnimSet("Sitting", curSitAnim);
  554.  
  555. } else if ( _message == "ZHAO_SITOFF" ) {
  556. // Turning off sit override
  557. sitOverride = FALSE;
  558. llOwnerSay("Sit override: Off");
  559. llResetAnimationOverride("Sitting");
  560.  
  561. } else if ( _message == "ZHAO_RANDOMSTANDS" ) {
  562. // Cycling to next stand - sequential or random
  563. randomStands = TRUE;
  564. llOwnerSay( "Stand cycling: Random" );
  565.  
  566. } else if ( _message == "ZHAO_SEQUENTIALSTANDS" ) {
  567. // Cycling to next stand - sequential or random
  568. randomStands = FALSE;
  569. llOwnerSay( "Stand cycling: Sequential" );
  570.  
  571. } else if ( _message == "ZHAO_SETTINGS" ) {
  572. // Print settings
  573. if ( sitOverride == TRUE ) {
  574. llOwnerSay( "Sit override: On" );
  575. } else {
  576. llOwnerSay( "Sit override: Off" );
  577. }
  578. if ( randomStands == TRUE ) {
  579. llOwnerSay( "Stand cycling: Random" );
  580. } else {
  581. llOwnerSay( "Stand cycling: Sequential" );
  582. }
  583. llOwnerSay( "Stand cycle time: " + (string)standTime + " seconds" );
  584.  
  585. } else if ( _message == "ZHAO_NEXTSTAND" ) {
  586. // Cycling to next stand - sequential or random. This is from UI, so we
  587. // want feedback
  588. doNextStand( TRUE );
  589.  
  590. } else if ( llGetSubString(_message, 0, 14) == "ZHAO_STANDTIME|" ) {
  591. // Stand time change
  592. maxTicks = llRound((standTime = (integer)llGetSubString(_message, 15, -1)) / timerEventLength);
  593. llOwnerSay( "Stand cycle time: " + (string)standTime + " seconds" );
  594.  
  595. } else if ( llGetSubString(_message, 0, 9) == "ZHAO_LOAD|" ) {
  596. // Can't load while we're in the middle of a load
  597. if ( loadInProgress == TRUE ) {
  598. llOwnerSay( "Cannot load new notecard, still reading notecard '" + notecardName + "'" );
  599. return;
  600. }
  601.  
  602. // Notecard menu
  603. loadInProgress = TRUE;
  604. notecardName = llGetSubString(_message, 10, -1);
  605. loadNoteCard();
  606.  
  607. } else if ( _message == "ZHAO_SITS" ) {
  608. // Selecting new sit anim
  609.  
  610. // Move these to a common function
  611. doMultiAnimMenu( sittingIndex, "Sitting", curSitAnim );
  612.  
  613. listenState = 1;
  614.  
  615. } else if ( _message == "ZHAO_WALKS" ) {
  616. // Same thing for the walk
  617.  
  618. // Move these to a common function
  619. doMultiAnimMenu( walkingIndex, "Walking", curWalkAnim );
  620.  
  621. listenState = 2;
  622. } else if ( _message == "ZHAO_GROUNDSITS" ) {
  623. // And the ground sit
  624.  
  625. // Move these to a common function
  626. doMultiAnimMenu( sitgroundIndex, "Sitting On Ground", curGsitAnim );
  627.  
  628. listenState = 3;
  629. }
  630. }
  631.  
  632. listen( integer _channel, string _name, key _id, string _message) {
  633. // Turn listen off. We turn it on again if we need to present
  634. // another menu
  635. llListenControl(listenHandle, FALSE);
  636.  
  637. if ( listenState == 1 ) {
  638. doAnimSet("Sitting", curSitAnim = findMultiAnim(1, (integer)_message - 1));
  639. llOwnerSay("New sitting animation: " + curSitAnim);
  640.  
  641. } else if ( listenState == 2 ) {
  642. doAnimSet("Walking", curWalkAnim = findMultiAnim(18, (integer)_message - 1));
  643. llOwnerSay("New walking animation: " + curWalkAnim);
  644.  
  645. } else if ( listenState == 3 ) {
  646. doAnimSet("Sitting on Ground", curGsitAnim = findMultiAnim(0, (integer)_message - 1));
  647. llOwnerSay("New groundsit animation: " + curGsitAnim);
  648. }
  649. }
  650.  
  651. dataserver( key _query_id, string _data )
  652. {
  653. if ( _query_id != notecardLineKey )
  654. return;
  655.  
  656. if ( _data == EOF )
  657. {
  658. // Now the read ends when we hit EOF
  659.  
  660. // End-of-notecard handling...
  661.  
  662. // See how many walks/sits/ground-sits we have
  663. checkMultiAnim(18, "walking");
  664. checkMultiAnim(1, "sitting");
  665.  
  666. // Reset stand, walk, sit and ground-sit anims to first entry
  667. curStandIndex = 0;
  668. numStands = llGetListLength(llParseString2List(llList2String(overrides, 20), (list)SEPARATOR, [])); //FIX
  669.  
  670. curStandAnim = findMultiAnim(20, 0);
  671. curWalkAnim = findMultiAnim(18, 0);
  672. curSitAnim = findMultiAnim(1, 0);
  673.  
  674. endNotecardLoad();
  675. llOwnerSay("LSL Functions/AO loaded. Mem:" + (string)llGetFreeMemory());
  676.  
  677. return;
  678. }
  679.  
  680. // We ignore blank lines and lines which start with a #
  681. if (_data == EMPTY || llGetSubString(_data, 0, 0) == "#")
  682. {
  683. notecardLineKey = llGetNotecardLine(notecardName, ++notecardIndex);
  684. return;
  685. }
  686.  
  687. // Let's get a token
  688. integer p = llSubStringIndex(_data, "[");
  689. string token = EMPTY;
  690. string anims = EMPTY;
  691. if (p != -1)
  692. {
  693. if ((p = llSubStringIndex(_data = llDeleteSubString(_data, 0, p), "]")) != -1)
  694. {
  695. token = llStringTrim(llGetSubString(_data, 0, p - 1), STRING_TRIM);
  696. anims = llStringTrim(llDeleteSubString(_data, 0, p), STRING_TRIM);
  697. if ((p = llListFindList(tokens, [token])) == -1)
  698. {
  699. llOwnerSay("AO:bad data on line " + (string)(notecardIndex+1) + " of " + notecardName + TRYAGAIN); // start from 1
  700. endNotecardLoad();
  701. return;
  702. }
  703. }
  704. }
  705.  
  706. if (anims != EMPTY)
  707. {
  708. // See if this is a token for which we allow multiple animations
  709. if (llSubStringIndex(multiAnimTokenIndexes, "," + (string)p + ",") != -1)
  710. { //FIX
  711. list anims2Add = llParseString2List(anims, (list)SEPARATOR, []); //FIX
  712. // Make sure the anims exist
  713. integer k = llGetListLength(anims2Add);
  714. while (k--)
  715. checkAnimInInventory(llList2String(anims2Add, k));
  716.  
  717. // Join the string and list and put it back into overrides
  718. overrides = llListReplaceList(overrides, (list)(llList2String(overrides, p) + SEPARATOR + llDumpList2String(anims2Add, SEPARATOR)), p, p ); //FIX
  719. }
  720. else
  721. {
  722. // This is an animation for which we only allow one override
  723. if (llSubStringIndex(anims, SEPARATOR) != -1)
  724. {
  725. llOwnerSay("Multiple anims for " + token + " not allowed. " + TRYAGAIN);
  726. endNotecardLoad();
  727. return;
  728. }
  729.  
  730. // Inventory check
  731. checkAnimInInventory(anims);
  732.  
  733. // We're good
  734. overrides = llListReplaceList(overrides, (list)anims, p, p); //FIX
  735. }
  736. }
  737.  
  738. // Wow, after all that, we read one line of the notecard
  739. notecardLineKey = llGetNotecardLine(notecardName, ++notecardIndex);
  740. }
  741.  
  742. timer() {
  743. vector cur = llGetPos();
  744. doWater(cur.z < llWater(ZERO_VECTOR));
  745. if (!(numTicks = (numTicks + 1) % maxTicks))
  746. {
  747. if (llGetAnimation(Owner) == "Standing")
  748. doNextStand(FALSE);
  749. }
  750. }
  751. }
Advertisement
Add Comment
Please, Sign In to add comment