xs_brain.lsl 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. // :CATEGORY:XS Pet
  2. // :NAME:XS Pet Robot
  3. // :AUTHOR:Ferd Frederix
  4. // :KEYWORDS: Pet,XS,breed,breedable,companion,Ozimal,Meeroo,Amaretto,critter,Fennux,Pets
  5. // :CREATED:2013-09-06
  6. // :EDITED:2014-01-30 12:24:21
  7. // :ID:988
  8. // :NUM:1463
  9. // :REV:0.50
  10. // :WORLD:Second Life, OpenSim
  11. // :DESCRIPTION:
  12. // XS Pet xs_brain
  13. // :CODE:
  14. // xs_brain
  15. // 8-17-2012 patch changes CONST 28 to PRIM_DESC in several places for otherworld compatibility now that the LSLEditor supports PRIM_DESC
  16. // 3-25-2013 fixed on rez for opensim where pet did not sync with egg
  17. // 4-10-2013 V 0.43 Lots of casting to fix Opensim 0.7.4 failures to parse llList2Float and llList2Integer when there are strings in the list
  18. // 11-16-2013 no rev bump, just a test to make sure the revsions match everywhere
  19. // tunable numbers just for the brain
  20. integer SECURE = FALSE; // Set this to true to check that the script names and counts match exactly.
  21. // This double-checks that pets have the correct scripts in them, but it causes grief to new users.
  22. // START OF COPIED file 'Global Constants.txt' from the Debug folder. It has to be the same in all files
  23. // If you change this in any script, change it in all of them, please. It works a lot better that way.
  24. // This is code based on Version 0.50 01-30-2014
  25. // For version history, see file revisions.txt
  26. //
  27. // LICENSE
  28. /////////////////////////////////////////////////////////////////////
  29. // This code is licensed as Creative Commons Attribution/NonCommercial/Share Alike
  30. // See http://creativecommons.org/liceses/by-nc-sa/3.0/
  31. // Noncommercial -- You may not use this work for commercial purposes, i.e., you cannot sell this script in any form, including derivatives.
  32. // If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.
  33. // This means that you cannot sell this or derivative code by itself, but you may share and use this code in any object or virtual world.
  34. // You must attribute authorship in the original scripts to Ferd Frederix and Xundra Snowpaw, and leave this notice intact.
  35. // You do not have to give back to the community any changes you make, however, code changes would be greatly appreciated!
  36. //
  37. // Exception: I am allowing this script to be used in an original build and sold with the build.
  38. // You are not selling the script, you are selling the build. If you want to sell these scripts, write your own or use the original at http://code.google.com/p/xspets/
  39. // Note: Xundra Snowpaw's license was 'New BSD' license and adding additional licenses is allowed.
  40. // Based on code from Xundra Snowpaw
  41. // New BSD License: http://www.opensource.org/licenses/bsd-license.php
  42. // Copyright (c) 2010, Xundra Snowpaw
  43. // All rights reserved.
  44. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  45. //* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  46. //* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
  47. // in the documentationand/or other materials provided with the distribution.
  48. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  49. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
  50. // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  51. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  52. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  53. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54. ////////////////////////////////////////////////////////////////////
  55. // DEBUG - lets you see and hear wtf is happening
  56. integer debug = FALSE; // set to TRUE TO hear a lot of chat
  57. // This section has a few tuneable items that MUST be changed for any new pet
  58. // SECURITY
  59. string SECRET_PASSWORD = "top secret string"; // must use a password unique to any species of animal, when ENCRYPT= TRUE. Otherwise you will find Pet type A fucking pet type B.
  60. integer SECRET_NUMBER = 99999; // any number thats a secret, not necessary to change usually, this is used when pets are born and eggs are rezzed to establish a comm channel.
  61. integer ENCRYPT = TRUE; // set to TRUE to encrypt all data, Some Opensim worlds prefer FALSE due to parsing bugs, TRUE is the most secure. If FALSE you MUST change the FOOD_CHANNEL and other channels for different pets. or they will literally fuck each other.
  62. // if you add the UUID for your avatar here, you can change it later
  63. // and other alts or friends can change it too, and all of you can work on these pets.
  64. // If you leave it blank, only the creator of the root prim can work on these pets.
  65. key YOUR_UUID = "";
  66. // PET NAMES - YOU MUST CHANGE THEM HERE AND IN THE ROOT PRIM OF THE OBJECT - THEY MUST MATCH EXACTLY
  67. /////////////////////////
  68. string MaleName = "Troubot"; // Must be the name of your animal
  69. string FemaleName = "Troubot"; // The name of the female pet, if a different shape or prim count. Can be the same as the Male for pets like the robot that are unisex.
  70. string Egg = "Nut and Bolt"; // was 'XS Egg', must be the name of your egg
  71. string Crate = "Transport Spaceship"; // was XS-Cryocrate, must be the name of the crate you package pets in
  72. string HomeObject = "Home Flag"; // was "XS Home Object", must be the name of your Home Post indicator
  73. string EggCup = "Toolbox"; // was "XS Egg Cup", must be the name of your egg holder
  74. // any other object names are 'do not cares'.
  75. // NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE
  76. // misc tunables
  77. float GROWTH_AMOUNT = 0.10; // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
  78. integer MaxAge = 7; // stop growing in seven days. 10% growth compounded daily means that your pet will be 194% larger ( 2x, basically) in 7 days.
  79. integer UNITS_OF_FOOD = 168; // food bowl food qty, used by food bowl only
  80. float secs_to_grow = 86400; // grow daily = 86400 seconds
  81. float FOOD_BOWL_SCAN_INTERVAL = 10800.0; // look for food every 3 hours
  82. float fPregnancy = 172800.0; // how many seconds to lay an egg = 2 days or 48 hours.
  83. float MALE_TIMEOUT = 900.0 ; // in seconds, female waits this long in one spot for a male to arrive
  84. float SEX_WAIT = 10800.0; // How often they desire sex = 3 hours
  85. float fDaysToAdult = 7; // 7 days to become old enough to breed.
  86. integer SECONDS_BETWEEN_FOOD_NORMAL = 14400; // number of seconds to get hungry = 4 hours
  87. integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600; // number of seconds before hunger count increases = 1 hour
  88. integer MAXIMUM_HUNGER = 30; // They die after a month with no food.
  89. // I control versions by Subversion Source Code Control. But the updater needs a version numbert in world.
  90. // This is the Protocol version. If you change this, then all pets with a lower version will be updated by the updater
  91. float VERSION = 0.50;
  92. // the leg sizes are safe to leave alone or set to 0 if you use a thin base prim, these are from the original Quail
  93. float LegLength = 0.064; // length of pet leg??? - not sure
  94. float LegOffset = 0.052399; // This is added to the Post Z to position the pet
  95. // the following are global constants and do not need to be changed
  96. // Prim animation linkmessages are sent by scripts on Link Message number 1
  97. // The strings are the names of the animations that are recorded.
  98. // No need to change them unless you want to change names of the animations when you run the prim animator, or you add additional link messages
  99. // If your pet walks, you need to record these names and save them in the notecard
  100. //
  101. // Example:
  102. // llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
  103. // The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
  104. // The following animations are used in the pet. You can add your own.
  105. string ANI_STAND = "stand"; // default standing animation
  106. string ANI_WALKL = "left"; // triggers Left foot and Right arm walk animation
  107. string ANI_WALKR = "right"; // triggers Right foot and Left arm walk animation
  108. string ANI_SLEEP = "sleep"; // Sleeping
  109. string ANI_WAVE = "wave"; // Calling for sex, needs help with food, etc.
  110. // Channel assignments
  111. // if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
  112. // If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.
  113. integer FOOD_CHANNEL = -999191;
  114. integer ANIMAL_CHANNEL = -999192;
  115. integer EGG_CHANNEL = -999193;
  116. integer HOME_CHANNEL = -999194;
  117. integer BOX_CHANNEL = -999195;
  118. integer ACC_CHANNEL = -999196;
  119. integer UPDATE_CHANNEL = -999197;
  120. integer API_CHANNEL = -999198;
  121. // global link messages to control the animal, never any need to change these.
  122. // They are exposed here so they will be the same everywhere. This uses a bit of RAM, but who cares?
  123. integer LINK_ANIMATE = 1; // messages on num 1 are assumed to be directed at the prim animator.
  124. integer DECREASE_FOOD = 100; // used in the food bowl.
  125. integer LINK_AGE_START = 800; // when pety is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
  126. integer LINK_TEXTURE = 801; // ask for a new texture, or paint a color
  127. integer LINK_BREEDNAME = 802; // the name of the pet texture from the texture server notecard
  128. integer LINK_FOOD_CONSUME = 900; // from movement to brain when close to food, brain then consumes a random amount up to 10000
  129. integer LINK_FOODMINUS = 901; // xs_brain receives FOOD_CONSUME, decrement hunger (eat)
  130. integer LINK_HUNGRY = 903; // sent by eater (string)hunger_amount, checks each hour
  131. integer LINK_HAMOUNT = 904; // hunger_amount = (integer)str,m updates the hunger amount in scripts
  132. integer LINK_SET_HOME = 910; // loc ^ dist
  133. integer LINK_MOVER = 911; // tell mover to rest for str seconds
  134. integer LINK_FOODIE_CLR = 920; // clear all food_bowl_keys and contents
  135. integer LINK_FOODIE = 921; // send FOOD_LOCATION coordinates to movement
  136. integer LINK_COLOR1 = 930; // colour1
  137. integer LINK_COLOR2 = 931; // colour2
  138. integer LINK_SEX = 932; // sex
  139. integer LINK_SHINE = 933; // shine
  140. integer LINK_GLOW = 934; // glow
  141. integer LINK_GEN = 935; // generation
  142. integer LINK_RESET_SIZE = 936; // reset size to 1
  143. integer LINK_MAGE = 940; // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
  144. integer LINK_DAYTIME = 941; // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
  145. integer LINK_GET_AGE = 942; // get age from xs_ager and sent it on channel 943
  146. integer LINK_PUT_AGE = 943; // print age from xs_ager
  147. integer LINK_PACKAGE = 950; // look for a cryo_crate
  148. integer LINK_SEEK_FEMALE = 960; // MALE_BREED_CALL
  149. integer LINK_MALE_BREED_CALL = 961; // triggered by LINK_SEEK_FEMALE
  150. integer LINK_SIGNAL_ELIGIBLE = 962; // sent by female when hears LINK_MALE_BREED_CALL
  151. integer LINK_FEMALE_ELIGIBLE = 963; // sent when it hears in chat FEMALE_ELIGIBLE
  152. integer LINK_CALL_MALE = 964; // if LINK_FEMALE_ELIGIBLE && looking_for_female
  153. integer LINK_MALE_ON_THE_WAY = 965; // triggered by LINK_CALL_MALE
  154. integer LINK_FEMALE_LOCATION = 966; // female location, sends coordinates of a female
  155. integer LINK_RQST_BREED = 967; // sent when close enough to male/female
  156. integer LINK_CALL_MALE_INFO = 968; // sent by xs_breeding, this line of code was in error in v.24 of xs_breeding see line 557 and 636 of xs_brain which make calls and also xs_breeding which receives LINK_MALE_INFO.
  157. integer LINK_MALE_INFO = 969; // Breeding failed, sent info
  158. integer LINK_LAY_EGG = 970; // Rez Object(Egg...
  159. integer LINK_BREED_FAIL = 971; // key = father, failed, timed out
  160. integer LINK_PREGNANT = 972; // chick is preggers
  161. integer LINK_SOUND_OFF= 974; // sound is off
  162. integer LINK_SOUND_ON= 973; // sound is on
  163. integer LINK_SLEEPING = 990; // close eyes
  164. integer LINK_UNSLEEPING = 991; // open eyes
  165. integer LINK_SOUND = 1001; // plays a sound if enabled
  166. integer LINK_SPECIAL = 1010; // xs_special, if str = "Normal", removes script
  167. integer LINK_EFFECTS_ON = 2000; // particle effects in the packger
  168. integer LINK_PREGNANCY_TIME = 5000; // in seconds as str
  169. integer LINK_SLEEP = 7999; // disable sleep by parameter
  170. integer LINK_TIMER = 8000; // scan for food bowl about every 1800 seconds
  171. integer LINK_DIE = 9999; // death
  172. string Copyright = " (c)2014 by Ferd Frederix"; // You cannot change this line, but you can change the code that prints it!
  173. // See License agreements above.
  174. // Attribution is required, as these files are copyrighted.
  175. DEBUG ( string msg){
  176. if (debug) {
  177. llOwnerSay(llGetScriptName() + ":" + msg);
  178. }
  179. }
  180. ///////// end global Link constants ////////
  181. // END OF COPIED CODE
  182. // code begins
  183. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  184. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  185. integer xtea_num_rounds = 6;
  186. list xtea_key = [0, 0, 0, 0];
  187. integer hex2int(string hex) {
  188. if(llGetSubString(hex,0,1) == "0x")
  189. return (integer)hex;
  190. if(llGetSubString(hex,0,0) == "x")
  191. return (integer)("0"+hex);
  192. return(integer)("0x"+hex);
  193. }
  194. // Convers any string to a 32 char MD5 string and then to a list of
  195. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  196. // 128 bit key is generated for any string passed.
  197. list xtea_key_from_string( string str )
  198. {
  199. str = llMD5String(str,0); // Use Nonce = 0
  200. return [ hex2int(llGetSubString( str, 0, 7)),
  201. hex2int(llGetSubString( str, 8, 15)),
  202. hex2int(llGetSubString( str, 16, 23)),
  203. hex2int(llGetSubString( str, 24, 31))];
  204. }
  205. // Encipher two integers and return the result as a 12-byte string
  206. // containing two base64-encoded integers.
  207. string xtea_encipher( integer v0, integer v1 )
  208. {
  209. integer num_rounds = xtea_num_rounds;
  210. integer sum = 0;
  211. do {
  212. // LSL does not have unsigned integers, so when shifting right we
  213. // have to mask out sign-extension bits.
  214. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  215. sum += XTEA_DELTA;
  216. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  217. } while( num_rounds = ~-num_rounds );
  218. //return only first 6 chars to remove "=="'s and compact encrypted text.
  219. return llGetSubString(llIntegerToBase64(v0),0,5) +
  220. llGetSubString(llIntegerToBase64(v1),0,5);
  221. }
  222. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  223. // each as one 10-byte base64-encoded string.
  224. string xtea_decipher( integer v0, integer v1 )
  225. {
  226. integer num_rounds = xtea_num_rounds;
  227. integer sum = XTEA_DELTA*xtea_num_rounds;
  228. do {
  229. // LSL does not have unsigned integers, so when shifting right we
  230. // have to mask out sign-extension bits.
  231. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  232. sum -= XTEA_DELTA;
  233. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  234. } while ( num_rounds = ~-num_rounds );
  235. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  236. llGetSubString(llIntegerToBase64(v1), 0, 4);
  237. }
  238. // Encrypt a full string using XTEA.
  239. string xtea_encrypt_string( string str )
  240. {
  241. if (! ENCRYPT)
  242. return str;
  243. // encode string
  244. str = llStringToBase64(str);
  245. // remove trailing =s so we can do our own 0 padding
  246. integer i = llSubStringIndex( str, "=" );
  247. if ( i != -1 )
  248. str = llDeleteSubString( str, i, -1 );
  249. // we don't want to process padding, so get length before adding it
  250. integer len = llStringLength(str);
  251. // zero pad
  252. str += "AAAAAAAAAA=";
  253. string result;
  254. i = 0;
  255. do {
  256. // encipher 30 (5*6) bits at a time.
  257. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  258. i+=10;
  259. } while ( i < len );
  260. return result;
  261. }
  262. // Decrypt a full string using XTEA
  263. string xtea_decrypt_string( string str ) {
  264. if (! ENCRYPT)
  265. return str;
  266. integer len = llStringLength(str);
  267. integer i=0;
  268. string result;
  269. //llOwnerSay(str);
  270. do {
  271. integer v0;
  272. integer v1;
  273. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  274. i+= 6;
  275. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  276. i+= 6;
  277. result += xtea_decipher(v0, v1);
  278. } while ( i < len );
  279. // Replace multiple trailing zeroes with a single one
  280. i = llStringLength(result) - 1;
  281. while ( llGetSubString(result, i - 1, i) == "AA" ){
  282. result = llDeleteSubString(result, i, i);
  283. i--;
  284. }
  285. i = llStringLength(result) - 1;
  286. // while (llGetSubString(result, i, i + 1) == "A" ) {
  287. // i--;
  288. // }
  289. result = llGetSubString(result, 0, i+1);
  290. i = llStringLength(result);
  291. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  292. if(mod == 1) result += "A==";
  293. else if(mod == 2 ) result += "==";
  294. else if(mod == 3) result += "=";
  295. return llBase64ToString(result);
  296. }
  297. string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  298. integer setup = FALSE; // added to cure opensim rezzing issue
  299. integer random_number; // food bowl chatted key
  300. integer random_number2; // food bowl chatted key
  301. integer hunger_amount; // from 0 to 30
  302. // breedeable numbers
  303. vector colour1;
  304. vector colour2;
  305. integer sex;
  306. integer shine;
  307. float glow;
  308. integer gen;
  309. integer age;
  310. // Male
  311. vector mcolour1; // male color for the famel to breed against, and so on
  312. vector mcolour2;
  313. integer mshine;
  314. float mglow;
  315. integer mgen;
  316. integer glow_gene;
  317. string special;
  318. integer mglow_gene;
  319. // globals
  320. vector home_loc; // where the home post is chatted to us
  321. key new_egg_key; // egg key of a laid egg so we can give a egg and animal to it
  322. integer locked; // global flag for crate PING and PONG
  323. integer pregnancy_time;// clock time we have been pregnant
  324. // change the color of any prim named 'color1' or color2'
  325. Color(integer colornum, vector color, integer shine, float glow )
  326. {
  327. integer nPrims = llGetNumberOfPrims();
  328. integer i;
  329. for (i = 1; i <= nPrims; i++)
  330. {
  331. list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]);
  332. string desc = llList2String(param,0);
  333. if (llToLower(desc) == "color1" && colornum == 1 )
  334. {
  335. llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  336. }
  337. else if (llToLower(desc) == "color2" && colornum == 2 )
  338. {
  339. llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  340. }
  341. }
  342. }
  343. // sets all prims to have a PRIM_BUMP_SHINY that have a color1 or a color2 in the description.
  344. Shine(integer shine)
  345. {
  346. integer nPrims = llGetNumberOfPrims();
  347. integer i;
  348. for (i = 1; i <= nPrims; i++)
  349. {
  350. list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]);
  351. string desc = llList2String(param,0);
  352. if (llToLower(desc) == "color1" || llToLower(desc) == "color2" )
  353. {
  354. llSetLinkPrimitiveParamsFast(i, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  355. }
  356. }
  357. }
  358. // sets all prims to have a PRIM_BUMP_SHINY and color that have a eye in the description.
  359. Eye(vector color, integer shine)
  360. {
  361. integer nPrims = llGetNumberOfPrims();
  362. integer i;
  363. for (i = 1; i <= nPrims; i++)
  364. {
  365. list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]); // 28 should be PRIM_DESC but lsleditor is old and does not support this.
  366. string desc = llList2String(param,0);
  367. if (llToLower(desc) == "eye" )
  368. {
  369. llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  370. }
  371. }
  372. }
  373. // allow either a UUID to be entered, or not, and still maintain security
  374. integer CheckPerms()
  375. {
  376. if (YOUR_UUID != "" && llGetOwner() != YOUR_UUID)
  377. return 1;
  378. if (llGetOwner() != llGetCreator())
  379. return 1;
  380. return 0;
  381. }
  382. default
  383. {
  384. state_entry()
  385. {
  386. if (CheckPerms()) {
  387. llOwnerSay("Someone not the creator reset the script. That's naughty.");
  388. state dead;
  389. }
  390. if ((integer) 0) // set to TRUE to play with colors
  391. {
  392. llOwnerSay("Color Test");
  393. Color(1, <1,0,0>, 0, 0);
  394. Color(2, <0,1,0>, 0, 0);
  395. llSleep(2);
  396. Color(1, <0,0,1>, 0, 0);
  397. Color(2, <0,0,0>, 0, 0);
  398. llSleep(1);
  399. Color(1, <1,1,1>, 0, 0);
  400. Color(2, <1,1,1>, 0, 0);
  401. }
  402. llSetText("", <1,1,1>, 1.0);
  403. random_number = 0;
  404. random_number2 = 0;
  405. hunger_amount = 0;
  406. locked = 0;
  407. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  408. llListen(ANIMAL_CHANNEL, "", "", "");
  409. }
  410. changed(integer change)
  411. {
  412. if (change & CHANGED_ALLOWED_DROP) {
  413. if (llGetInventoryType(FemaleName) != INVENTORY_NONE && llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
  414. llAllowInventoryDrop(FALSE);
  415. }
  416. }
  417. if (change & CHANGED_INVENTORY) {
  418. if ( CheckPerms() ) {
  419. integer inventory_count = llGetInventoryNumber(INVENTORY_ALL);
  420. integer extras = 4;
  421. if (SECURE) // set this to TRUE to do extra security checks
  422. {
  423. if (llGetInventoryType("xs_ager") == INVENTORY_NONE || !llGetScriptState("xs_ager")) {
  424. llOwnerSay("no xs_ager");
  425. state dead;
  426. }
  427. if (llGetInventoryType("xs_infomatic") == INVENTORY_NONE || !llGetScriptState("xs_infomatic")) {
  428. llOwnerSay("no xs_infomatic");
  429. state dead;
  430. }
  431. if (llGetInventoryType("xs_breeding") == INVENTORY_NONE || !llGetScriptState("xs_breeding")) {
  432. llOwnerSay("no xs_breeding");
  433. state dead;
  434. }
  435. if (llGetInventoryType("xs_eater") == INVENTORY_NONE || !llGetScriptState("xs_eater")) {
  436. llOwnerSay("no xs_eater");
  437. state dead;
  438. }
  439. if (llGetInventoryType("xs_movement") == INVENTORY_NONE || !llGetScriptState("xs_movement")) {
  440. llOwnerSay("no xs_movement");
  441. state dead;
  442. }
  443. if (llGetInventoryType("xs_special") == INVENTORY_NONE) {
  444. llOwnerSay("no xs_special");
  445. extras--;
  446. }
  447. if (llGetInventoryType(Egg) == INVENTORY_NONE) {
  448. extras--;
  449. }
  450. if (llGetInventoryType(MaleName) == INVENTORY_NONE) {
  451. extras--;
  452. }
  453. if (llGetInventoryType(FemaleName) == INVENTORY_NONE) {
  454. extras--;
  455. }
  456. if (llGetInventoryType(HomeObject) == INVENTORY_NONE) {
  457. state dead;
  458. }
  459. if (8 + extras != inventory_count) {
  460. llOwnerSay("Count wrong, was " + (string) (8 + extras) + " should be " + (string) inventory_count);
  461. state dead;
  462. }
  463. }
  464. }
  465. }
  466. }
  467. timer()
  468. {
  469. // for OpenSIm to establish an on_rez, the durn thing does not for the onrez even in the egg unless the script goes idle
  470. if (setup == TRUE)
  471. {
  472. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
  473. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
  474. setup = FALSE;
  475. return;
  476. }
  477. llMessageLinked(LINK_SET, LINK_FOODIE_CLR, "", "");
  478. // llWhisper(0, "Scanning for food bowls.");
  479. random_number = (integer)(llFrand(10000.0) + 1);
  480. llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_LOCATION^" + (string)random_number + "^" + (string)llGetKey()));
  481. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  482. }
  483. listen(integer channel, string name, key id, string message)
  484. {
  485. if (channel == ANIMAL_CHANNEL) {
  486. list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
  487. DEBUG(llDumpList2String(data,","));
  488. if (llList2String(data, 0) == "XSPET") {
  489. if (llList2String(data, 1) == "FOOD_LOCATION") {
  490. llMessageLinked(LINK_SET, LINK_FOODIE, llList2String(data, 3), id);
  491. } else
  492. if (llList2String(data, 1) == "FOOD_CONSUME") {
  493. if ((integer) llList2String(data, 2) == random_number2 && (key) llList2String(data, 3) == llGetKey()) {
  494. hunger_amount--;
  495. llMessageLinked(LINK_SET, LINK_FOODMINUS, "", "");
  496. random_number2 = 0;
  497. if ((integer) llList2String(data, 4) == 1 && glow_gene < 10) {
  498. glow_gene ++;
  499. }
  500. }
  501. } else
  502. if (llList2String(data, 1) == "HOME_LOCATION") {
  503. vector n_home_loc = (vector)llList2String(data, 2);
  504. float home_dis = (float) llList2String(data, 3);
  505. vector my_loc = llGetPos();
  506. // llOwnerSay((string)llVecDist(home_loc, my_loc) + " " + (string)my_loc + (string)home_loc + (string)home_dis + llList2String(data, 2));
  507. if (llVecDist(n_home_loc, my_loc) <= home_dis && llFabs(llFabs(n_home_loc.z) - llFabs(my_loc.z)) < 1) {
  508. if (llGetOwnerKey(id) == llGetOwner()) {
  509. home_loc = n_home_loc;
  510. llMessageLinked(LINK_SET, LINK_SET_HOME, (string)n_home_loc + "^" + (string)home_dis, "");
  511. }
  512. }
  513. } else
  514. if (llList2String(data, 1) == "CONFIG" && (key) llList2String(data, 2) == llGetKey()) {
  515. llMessageLinked(LINK_SET, LINK_AGE_START, "", ""); // start the pet up!
  516. colour1 = (vector) llList2String(data, 3);
  517. colour2 = (vector) llList2String(data, 4); // 0.43 4-1-2013 Opensim requires the cast
  518. sex = (integer) llList2String(data, 5);
  519. shine = (integer)llList2String(data, 6);
  520. glow = (float) llList2String(data, 7);
  521. gen = (integer) llList2String(data, 8);
  522. integer mage = (integer) llList2String(data, 9);
  523. integer hamount = (integer)llList2String(data, 10);
  524. string myname = llList2String(data, 11);
  525. glow_gene = (integer) llList2String(data, 12);
  526. special = llList2String(data, 13);
  527. Color(1,colour1, shine, glow); // set prims labeled color1 to color 1
  528. Color(2,colour2, shine, glow); // set prims labeled color2 to color 2
  529. // v.36 added texture plugin
  530. string msg = (string) colour1 + "^" +
  531. (string) colour2 + "^" +
  532. (string) sex + "^" + // sex should be a 1 or a 2
  533. (string) shine + "^" +
  534. (string) glow + "^";
  535. llSleep(2); //give opensim time to switch states *sighs *
  536. llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY); // tell the optional texture plugin
  537. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  538. llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
  539. llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");
  540. llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
  541. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  542. llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
  543. llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");
  544. llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");
  545. if (hamount > 0) {
  546. llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
  547. }
  548. if (name != MaleName && name != FemaleName) {
  549. llSetObjectName(myname);
  550. }
  551. if (sex == 1)
  552. llSetObjectDesc(MaleName + "v" + (string)VERSION + Copyright);
  553. else
  554. llSetObjectDesc(FemaleName + "v" + (string)VERSION + Copyright);
  555. llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");
  556. llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");
  557. llSay(HOME_CHANNEL, "XSPET_PING_HOME");
  558. llSetText("", <1,1,1>, 1.0);
  559. } else
  560. if (llList2String(data, 1) == "UPDATE_CONFIG" && (key) llList2String(data, 2) == llGetKey()) {
  561. colour1 = (vector) llList2String(data, 3);;
  562. colour2 = (vector) llList2String(data, 4);
  563. sex = (integer) llList2String(data, 5);
  564. shine = (integer) llList2String(data, 6);
  565. glow = (float) llList2String(data, 7);
  566. gen = (integer) llList2String(data, 8);
  567. integer mage = (integer) llList2String(data, 9);
  568. integer hamount = (integer) llList2String(data, 10);
  569. string myname = llList2String(data, 11);
  570. glow_gene = (integer) llList2String(data, 12);
  571. special = llList2String(data, 13);
  572. mcolour1 = (vector) llList2String(data, 14);
  573. mcolour2 = (vector) llList2String(data, 15);
  574. mshine = (integer) llList2String(data, 16);
  575. mglow = (float) llList2String(data, 17);
  576. mgen = (integer) llList2String(data, 18);
  577. mglow_gene = (integer) llList2String(data, 19);
  578. pregnancy_time = (integer) llList2String(data, 20);
  579. Color(1,colour1,shine,glow);
  580. Color(2,colour2,shine,glow);
  581. // v.36 added txture plugin
  582. string msg = (string) colour1 + "^" +
  583. (string) colour2 + "^" +
  584. (string) sex + "^" +
  585. (string) shine + "^" +
  586. (string) glow + "^";
  587. llMessageLinked(LINK_SET, LINK_AGE_START, "", ""); // start the pet up!
  588. llSleep(2); //give opensim time to switch states *sighs *
  589. llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY); // tell the optional texture plugin
  590. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  591. llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
  592. llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");
  593. if (sex == 1) {
  594. llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
  595. } else {
  596. llMessageLinked(LINK_SET, LINK_PREGNANCY_TIME, (string)pregnancy_time, "");
  597. }
  598. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  599. llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
  600. llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");
  601. llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");
  602. if (hamount > 0) {
  603. llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
  604. }
  605. if (name != FemaleName && name != MaleName) {
  606. llSetObjectName(myname);
  607. }
  608. if (sex == 1)
  609. llSetObjectDesc(MaleName + " version " + (string)VERSION + Copyright);
  610. else
  611. llSetObjectDesc(FemaleName + " version " + (string)VERSION + Copyright);
  612. llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");
  613. llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");
  614. llSay(HOME_CHANNEL, "XSPET_PING_HOME");
  615. llSetText("", <1,1,1>, 1.0);
  616. } else
  617. if (llList2String(data, 1) == "CRATE_PONG" && (key) llList2String(data, 2) == llGetKey()) {
  618. if ((float) llList2String(data, 3) >= VERSION && locked == 0) {
  619. locked = 1;
  620. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^" + (string )colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^" + (string)hunger_amount + "^" + llGetObjectName() + "^" + (string)glow_gene + "^" + special));
  621. }
  622. } else
  623. if (llList2String(data, 1) == "CRATE_DIE" && (key) llList2String(data, 2) == llGetKey()) {
  624. llDie();
  625. } else
  626. if (llList2String(data, 1) == "MALE_BREED_CALL") {
  627. llMessageLinked(LINK_SET, LINK_MALE_BREED_CALL, "", "");
  628. } else
  629. if (llList2String(data, 1) == "FEMALE_ELIGIBLE" && home_loc == (vector)llList2String(data, 2)) {
  630. llMessageLinked(LINK_SET, LINK_FEMALE_ELIGIBLE, "", id);
  631. } else
  632. if (llList2String(data, 1) == "MALE_ON_THE_WAY" && (key) llList2String(data, 2) == llGetKey()) {
  633. llMessageLinked(LINK_SET, LINK_MALE_ON_THE_WAY, "", id);
  634. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_LOC^" + (string)id + "^" + (string)llGetPos()));
  635. } else
  636. if (llList2String(data, 1) == "FEMALE_LOC" && (key) llList2String(data, 2) == llGetKey()) // missing key cast - Ferd
  637. {
  638. llMessageLinked(LINK_SET, LINK_FEMALE_LOCATION, llList2String(data, 3), "");
  639. } else
  640. if (llList2String(data, 1) == "MALE_INFO" && (key) llList2String(data, 2) == llGetKey()){
  641. // pregnant
  642. mcolour1 = (vector) llList2String(data, 3);
  643. mcolour2 = (vector) llList2String(data, 4);
  644. mshine = (integer) llList2String(data, 5);
  645. mglow = (float) llList2String(data, 6);
  646. mgen = (integer) llList2String(data, 7);
  647. mglow_gene = (integer) llList2String(data, 8);
  648. pregnancy_time = llGetUnixTime();
  649. llMessageLinked(LINK_SET, LINK_PREGNANT, "", "");
  650. } else
  651. if (llList2String(data, 1) == "BREEDING_FAIL" && (key) llList2String(data, 2) == llGetKey()) // was missing key cast - Ferd
  652. {
  653. llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
  654. } else
  655. if (llList2String(data, 1) == "EGG_READY" && id == new_egg_key)
  656. {
  657. llGiveInventory(id, Egg);
  658. llGiveInventory(id, MaleName);
  659. llGiveInventory(id, FemaleName);
  660. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^BORN^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)gen + "^" + (string)shine + "^" + (string)glow + "^" + (string)glow_gene + "^" + (string)mcolour1 + "^" + (string)mcolour2 + "^" + (string)mgen + "^" + (string)mshine + "^" + (string)mglow + "^" + (string)mglow_gene));
  661. } else
  662. if (llList2String(data, 1) == "SHINE_GOO" && (key) llList2String(data, 2) == llGetKey()) {
  663. if (shine == 0) {
  664. shine = 1;
  665. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  666. llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_DIE"));
  667. Shine(shine);
  668. if (sex == 1) {
  669. llWhisper(0, "Look out ladies, Mr Slick has arrived!");
  670. } else {
  671. llWhisper(0, "Look out gentlemen! Miss Slick has arrived!");
  672. }
  673. } else {
  674. llWhisper(0, "I'm already shiny!");
  675. llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_FAIL"));
  676. }
  677. } else
  678. if (llList2String(data, 1) == "DIE" && (key) llList2String(data, 2) == llGetKey()) {
  679. llDie();
  680. } else
  681. if (llList2String(data, 1) == "VERSION" && VERSION < (float) llList2String(data, 2) && llGetOwnerKey(id) == llGetOwner()) {
  682. llShout(UPDATE_CHANNEL, "VERSION^" + (string)VERSION);
  683. } else
  684. if (llList2String(data, 1) == "UPDATE" && (key) llList2String(data, 2) == llGetKey() && llGetOwnerKey(id) == llGetOwner()) { // missing key cast - Ferd
  685. state update;
  686. }
  687. }
  688. }
  689. }
  690. link_message(integer sender, integer num, string str, key id)
  691. {
  692. if (num == LINK_HUNGRY || num == LINK_HAMOUNT) {
  693. hunger_amount = (integer)str;
  694. if (hunger_amount > MAXIMUM_HUNGER) { // usually 30, see globals
  695. state dead;
  696. }
  697. } else
  698. if (num == LINK_FOOD_CONSUME) {
  699. random_number2 = (integer)(llFrand(10000.0) + 1);
  700. llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_CONSUME^" + (string)id + "^" + (string)random_number2 + "^" + (string)llGetKey()));
  701. } else
  702. if (num == LINK_MAGE) {
  703. age += (integer)str;
  704. } else
  705. if (num == LINK_PACKAGE) {
  706. llWhisper(0, "Looking for a " + Crate + "...");
  707. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CRATE_PING^" + (string)VERSION));
  708. } else
  709. if (num == LINK_SEEK_FEMALE) {
  710. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_BREED_CALL^" + (string)llGetKey()));
  711. } else
  712. if (num == LINK_SIGNAL_ELIGIBLE) {
  713. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_ELIGIBLE^" + (string)home_loc));
  714. } else
  715. if (num == LINK_CALL_MALE) {
  716. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_ON_THE_WAY^" + (string)id));
  717. } else
  718. if (num == LINK_CALL_MALE_INFO) {
  719. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_INFO^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + (string)glow_gene));
  720. llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
  721. } else
  722. if (num == LINK_LAY_EGG) {
  723. // lay an egg
  724. pregnancy_time = 0;
  725. llRezObject(Egg, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  726. } else
  727. if (num == LINK_BREED_FAIL) {
  728. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^BREEDING_FAIL^" + (string)id));
  729. pregnancy_time = 0;
  730. } else
  731. if (num == LINK_SLEEPING) {
  732. Eye(<0,0,0>,shine); // white eyes
  733. } else
  734. if (num == LINK_UNSLEEPING) {
  735. Eye(<1,1,1>,shine); // blackout the eyes
  736. } else
  737. if (num == LINK_DIE) {
  738. state dead;
  739. } else
  740. if (num == LINK_TIMER) {
  741. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  742. }
  743. }
  744. object_rez(key id)
  745. {
  746. new_egg_key = id;
  747. }
  748. on_rez(integer param)
  749. {
  750. if (param == SECRET_NUMBER) {
  751. llSetText("Rezzing...", <1,0,0>, 1.0);
  752. setup = TRUE; // Opensim issue with on_rez, the UUID is not sent until the script stops processing, so we use a timer
  753. if (llGetOwner() != llGetCreator()) {
  754. llAllowInventoryDrop(TRUE);
  755. }
  756. llListen(ANIMAL_CHANNEL, "", "", "");
  757. llSetTimerEvent(5.0);
  758. } else {
  759. llOwnerSay("I died in your inventory, please use a " + Crate + " next time.");
  760. state dead;
  761. }
  762. }
  763. }
  764. state dead
  765. {
  766. state_entry()
  767. {
  768. llSetText("Dead", <1,0,0>, 1.0);
  769. llMessageLinked(LINK_SET,1,"death",""); // play the death animation v.37
  770. llRemoveInventory("xs_ager");
  771. llRemoveInventory("xs_breeding");
  772. llRemoveInventory("xs_eater");
  773. llRemoveInventory("xs_infomatic");
  774. llRemoveInventory("xs_movement");
  775. if (llGetInventoryType("xs_special") != INVENTORY_NONE) {
  776. llRemoveInventory("xs_special");
  777. }
  778. llListen(ANIMAL_CHANNEL, "", "", "");
  779. }
  780. // no one has Xtra Strong Mojo, script has been lost. It appears that it triggers a box to rez a new pet with the params from this one.
  781. touch_start(integer number)
  782. {
  783. llWhisper(0, "I've died. You could re-animate me with a jar of Xtra Strong Mojo. But we don't have any Mojo coded just yet");
  784. if (llDetectedKey(0) == llGetOwner()) {
  785. llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^STRONG_MOJO^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^" + (string)glow_gene + (string)VERSION));
  786. }
  787. }
  788. listen(integer channel, string name, key id, string message) {
  789. list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
  790. if (llList2String(data, 0) == "XSPET") {
  791. if (llList2String(data, 1) == "STRONG_MOJO_DIE" && (key) llList2String(data, 2) == llGetKey()) {
  792. llDie();
  793. }
  794. }
  795. }
  796. }
  797. // likewise, the updater script is (no longer) lost to history. Apparently you set the pet near a prim, that when touched, chats out "UPDATE", which leads you here.
  798. // code remains here in case you want to make an updater. It givbes this pet a new pet and egg, then causes this pet to give birth to the new pet, then causes this pet to die.
  799. state update
  800. {
  801. state_entry()
  802. {
  803. llSetText("Updating.", <1,0,0>, 1.0);
  804. llRemoveInventory(FemaleName);
  805. llRemoveInventory(MaleName);
  806. llRemoveInventory(Egg);
  807. llAllowInventoryDrop(TRUE);
  808. llShout(UPDATE_CHANNEL, "UPDATE_READY");
  809. }
  810. changed(integer change)
  811. {
  812. if (change & CHANGED_ALLOWED_DROP) {
  813. if (llGetInventoryType(FemaleName) != INVENTORY_NONE && llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
  814. llAllowInventoryDrop(FALSE);
  815. if (sex == 1)
  816. llRezObject(MaleName, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  817. else
  818. llRezObject(FemaleName, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  819. }
  820. }
  821. }
  822. object_rez(key id)
  823. {
  824. llListen(BOX_CHANNEL, "", id, "");
  825. }
  826. listen(integer channel, string name, key id, string msg)
  827. {
  828. if (channel == BOX_CHANNEL) {
  829. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  830. if (llList2String(data, 0) == "XSPET" && llList2String(data, 1) == "READY") {
  831. llGiveInventory(id, Egg);
  832. llGiveInventory(id, FemaleName);
  833. llGiveInventory(id, MaleName);
  834. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^UPDATE_CONFIG^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)sex + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + (string)age + "^" + (string)hunger_amount + "^" + llGetObjectName() + "^" + (string)glow_gene + "^" + special + "^" + (string)mcolour1 + "^" + (string)mcolour2 + "^" + (string)mshine + "^" + (string)mglow + "^" + (string)mgen + "^" + (string)mglow_gene + "^" + (string)pregnancy_time));
  835. llDie();
  836. }
  837. }
  838. }
  839. }