xs_cryocrate.lsl 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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-05-18
  7. // :ID:988
  8. // :NUM:1452
  9. // :REV:0.52
  10. // :WORLD:Second Life, OpenSim
  11. // :DESCRIPTION:
  12. // XS Pet xs_cryocrate
  13. // :CODE:
  14. // xs_cryocrate
  15. // 11-24-2012 added LINK_TEXTURE to allow crate to be textured.
  16. // 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
  17. // Tunables
  18. // Quail rezzed eggs up 0.25 meters above the egg cup.
  19. float position = 0.25; // just above the egg cup for XS QUail, not used when MoveUp is TRUE
  20. integer BOX = FALSE; // if TRUE, uses XS Quail prim type of a BOX, if False, uses Name of linked prim to color or texture
  21. integer MoveUp = TRUE; // if set to TRUE, will move the box up when an egg is rezzed and set it on top of the animal, then play an effect
  22. float distance = 0.5; // how far the crate will move up if MoveUp is set to TRUE, the egg is laid this distance below it.
  23. float delay = 3; // numner of seconds for effects to begin and then end. 0 is default for a Quail
  24. // START OF COPIED file 'Global Constants.txt' from the Debug folder. It has to be the same in all files
  25. // If you change this in any script, change it in all of them, please. It works a lot better that way.
  26. // This is code based on Version 0.50 01-30-2014
  27. // For version history, see file revisions.txt
  28. //
  29. // LICENSE
  30. /////////////////////////////////////////////////////////////////////
  31. // This code is licensed as Creative Commons Attribution/NonCommercial/Share Alike
  32. // See http://creativecommons.org/liceses/by-nc-sa/3.0/
  33. // Noncommercial -- You may not use this work for commercial purposes, i.e., you cannot sell this script in any form, including derivatives.
  34. // 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.
  35. // 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.
  36. // You must attribute authorship in the original scripts to Ferd Frederix and Xundra Snowpaw, and leave this notice intact.
  37. // You do not have to give back to the community any changes you make, however, code changes would be greatly appreciated!
  38. //
  39. // Exception: I am allowing this script to be used in an original build and sold with the build.
  40. // 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/
  41. // Note: Xundra Snowpaw's license was 'New BSD' license and adding additional licenses is allowed.
  42. // Based on code from Xundra Snowpaw
  43. // New BSD License: http://www.opensource.org/licenses/bsd-license.php
  44. // Copyright (c) 2010, Xundra Snowpaw
  45. // All rights reserved.
  46. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  47. //* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  48. //* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
  49. // in the documentationand/or other materials provided with the distribution.
  50. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  51. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
  52. // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  54. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  55. // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56. ////////////////////////////////////////////////////////////////////
  57. // DEBUG - lets you see and hear wtf is happening
  58. integer debug = FALSE; // set to TRUE TO hear a lot of chat
  59. // This section has a few tuneable items that MUST be changed for any new pet
  60. // SECURITY
  61. 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.
  62. 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.
  63. 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.
  64. // if you add the UUID for your avatar here, you can change it later
  65. // and other alts or friends can change it too, and all of you can work on these pets.
  66. // If you leave it blank, only the creator of the root prim can work on these pets.
  67. key YOUR_UUID = "";
  68. // PET NAMES - YOU MUST CHANGE THEM HERE AND IN THE ROOT PRIM OF THE OBJECT - THEY MUST MATCH EXACTLY
  69. /////////////////////////
  70. string MaleName = "Troubot"; // Must be the name of your animal
  71. 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.
  72. string Egg = "Nut and Bolt"; // was 'XS Egg', must be the name of your egg
  73. string Crate = "Transport Spaceship"; // was XS-Cryocrate, must be the name of the crate you package pets in
  74. string HomeObject = "Home Flag"; // was "XS Home Object", must be the name of your Home Post indicator
  75. string EggCup = "Toolbox"; // was "XS Egg Cup", must be the name of your egg holder
  76. // any other object names are 'do not cares'.
  77. // NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE
  78. // misc tunables
  79. float GROWTH_AMOUNT = 0.10; // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
  80. 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.
  81. integer UNITS_OF_FOOD = 168; // food bowl food qty, used by food bowl only
  82. float secs_to_grow = 86400; // grow daily = 86400 seconds
  83. float FOOD_BOWL_SCAN_INTERVAL = 1800.0; // look for food every 3 hours
  84. float fPregnancy = 172800.0; // how many seconds to lay an egg = 2 days or 48 hours.
  85. float MALE_TIMEOUT = 900.0 ; // in seconds, female waits this long in one spot for a male to arrive
  86. float SEX_WAIT = 10800.0; // How often they desire sex = 3 hours
  87. float fDaysToAdult = 7; // 7 days to become old enough to breed.
  88. integer SECONDS_BETWEEN_FOOD_NORMAL = 14400; // number of seconds to get hungry = 4 hours
  89. integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600; // number of seconds before hunger count increases = 1 hour
  90. integer MAXIMUM_HUNGER = 30; // They die after a month with no food.
  91. // I control versions by Subversion Source Code Control. But the updater needs a version numbert in world.
  92. // This is the Protocol version. If you change this, then all pets with a lower version will be updated by the updater
  93. float VERSION = 0.50;
  94. // 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
  95. float LegLength = 0.064; // length of pet leg??? - not sure
  96. float LegOffset = 0.052399; // This is added to the Post Z to position the pet
  97. // the following are global constants and do not need to be changed
  98. // Prim animation linkmessages are sent by scripts on Link Message number 1
  99. // The strings are the names of the animations that are recorded.
  100. // 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
  101. // If your pet walks, you need to record these names and save them in the notecard
  102. //
  103. // Example:
  104. // llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
  105. // The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
  106. // The following animations are used in the pet. You can add your own.
  107. string ANI_STAND = "stand"; // default standing animation
  108. string ANI_WALKL = "left"; // triggers Left foot and Right arm walk animation
  109. string ANI_WALKR = "right"; // triggers Right foot and Left arm walk animation
  110. string ANI_SLEEP = "sleep"; // Sleeping
  111. string ANI_WAVE = "wave"; // Calling for sex, needs help with food, etc.
  112. // Channel assignments
  113. // if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
  114. // If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.
  115. integer FOOD_CHANNEL = -999191;
  116. integer ANIMAL_CHANNEL = -999192;
  117. integer EGG_CHANNEL = -999193;
  118. integer HOME_CHANNEL = -999194;
  119. integer BOX_CHANNEL = -999195;
  120. integer ACC_CHANNEL = -999196;
  121. integer UPDATE_CHANNEL = -999197;
  122. integer API_CHANNEL = -999198;
  123. // global link messages to control the animal, never any need to change these.
  124. // They are exposed here so they will be the same everywhere. This uses a bit of RAM, but who cares?
  125. integer LINK_ANIMATE = 1; // messages on num 1 are assumed to be directed at the prim animator.
  126. integer DECREASE_FOOD = 100; // used in the food bowl.
  127. integer LINK_COLOR1_GET = 101; // to xs_egg color plugin.
  128. integer LINK_COLOR2_GET = 102; // to xs_egg color plugin.
  129. integer LINK_COLOR1_PUT = 103; // to xs_egg color plugin.
  130. integer LINK_COLOR2_PUT = 104; // to xs_egg color plugin.
  131. integer LINK_AGE_START = 800; // when pety is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
  132. integer LINK_TEXTURE = 801; // ask for a new texture, or paint a color
  133. integer LINK_BREEDNAME = 802; // the name of the pet texture from the texture server notecard
  134. integer LINK_FOOD_CONSUME = 900; // from movement to brain when close to food, brain then consumes a random amount up to 10000
  135. integer LINK_FOODMINUS = 901; // xs_brain receives FOOD_CONSUME, decrement hunger (eat)
  136. integer LINK_HUNGRY = 903; // sent by eater (string)hunger_amount, checks each hour
  137. integer LINK_HAMOUNT = 904; // hunger_amount = (integer)str,m updates the hunger amount in scripts
  138. integer LINK_SET_HOME = 910; // loc ^ dist
  139. integer LINK_MOVER = 911; // tell mover to rest for str seconds
  140. integer LINK_FOODIE_CLR = 920; // clear all food_bowl_keys and contents
  141. integer LINK_FOODIE = 921; // send FOOD_LOCATION coordinates to movement
  142. integer LINK_COLOR1 = 930; // colour1
  143. integer LINK_COLOR2 = 931; // colour2
  144. integer LINK_SEX = 932; // sex
  145. integer LINK_SHINE = 933; // shine
  146. integer LINK_GLOW = 934; // glow
  147. integer LINK_GEN = 935; // generation
  148. integer LINK_RESET_SIZE = 936; // reset size to 1
  149. integer LINK_MAGE = 940; // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
  150. integer LINK_DAYTIME = 941; // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
  151. integer LINK_GET_AGE = 942; // get age from xs_ager and sent it on channel 943
  152. integer LINK_PUT_AGE = 943; // print age from xs_ager
  153. integer LINK_PACKAGE = 950; // look for a cryo_crate
  154. integer LINK_SEEK_FEMALE = 960; // MALE_BREED_CALL
  155. integer LINK_MALE_BREED_CALL = 961; // triggered by LINK_SEEK_FEMALE
  156. integer LINK_SIGNAL_ELIGIBLE = 962; // sent by female when hears LINK_MALE_BREED_CALL
  157. integer LINK_FEMALE_ELIGIBLE = 963; // sent when it hears in chat FEMALE_ELIGIBLE
  158. integer LINK_CALL_MALE = 964; // if LINK_FEMALE_ELIGIBLE && looking_for_female
  159. integer LINK_MALE_ON_THE_WAY = 965; // triggered by LINK_CALL_MALE
  160. integer LINK_FEMALE_LOCATION = 966; // female location, sends coordinates of a female
  161. integer LINK_RQST_BREED = 967; // sent when close enough to male/female
  162. 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.
  163. integer LINK_MALE_INFO = 969; // Breeding failed, sent info
  164. integer LINK_LAY_EGG = 970; // Rez Object(Egg...
  165. integer LINK_BREED_FAIL = 971; // key = father, failed, timed out
  166. integer LINK_PREGNANT = 972; // chick is preggers
  167. integer LINK_SOUND_OFF= 974; // sound is off
  168. integer LINK_SOUND_ON= 973; // sound is on
  169. integer LINK_SLEEPING = 990; // close eyes
  170. integer LINK_UNSLEEPING = 991; // open eyes
  171. integer LINK_SOUND = 1001; // plays a sound if enabled
  172. integer LINK_SPECIAL = 1010; // xs_special, if str = "Normal", removes script
  173. integer LINK_EFFECTS_ON = 2000; // particle effects in the packger
  174. integer LINK_PREGNANCY_TIME = 5000; // in seconds as str
  175. integer LINK_SLEEP = 7999; // disable sleep by parameter
  176. integer LINK_TIMER = 8000; // scan for food bowl about every 1800 seconds
  177. integer LINK_DIE = 9999; // death
  178. string Copyright = " (c)2014 by Ferd Frederix"; // You cannot change this line, but you can change the code that prints it!
  179. // See License agreements above.
  180. // Attribution is required, as these files are copyrighted.
  181. DEBUG ( string msg){
  182. if (debug) {
  183. llOwnerSay(llGetScriptName() + ":" + msg);
  184. }
  185. }
  186. ///////// end global Link constants ////////
  187. // END OF COPIED CODE
  188. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  189. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  190. integer xtea_num_rounds = 6;
  191. list xtea_key = [0, 0, 0, 0];
  192. integer hex2int(string hex) {
  193. if(llGetSubString(hex,0,1) == "0x")
  194. return (integer)hex;
  195. if(llGetSubString(hex,0,0) == "x")
  196. return (integer)("0"+hex);
  197. return(integer)("0x"+hex);
  198. }
  199. // Convers any string to a 32 char MD5 string and then to a list of
  200. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  201. // 128 bit key is generated for any string passed.
  202. list xtea_key_from_string( string str )
  203. {
  204. str = llMD5String(str,0); // Use Nonce = 0
  205. return [ hex2int(llGetSubString( str, 0, 7)),
  206. hex2int(llGetSubString( str, 8, 15)),
  207. hex2int(llGetSubString( str, 16, 23)),
  208. hex2int(llGetSubString( str, 24, 31))];
  209. }
  210. // Encipher two integers and return the result as a 12-byte string
  211. // containing two base64-encoded integers.
  212. string xtea_encipher( integer v0, integer v1 )
  213. {
  214. integer num_rounds = xtea_num_rounds;
  215. integer sum = 0;
  216. do {
  217. // LSL does not have unsigned integers, so when shifting right we
  218. // have to mask out sign-extension bits.
  219. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  220. sum += XTEA_DELTA;
  221. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  222. } while( num_rounds = ~-num_rounds );
  223. //return only first 6 chars to remove "=="'s and compact encrypted text.
  224. return llGetSubString(llIntegerToBase64(v0),0,5) +
  225. llGetSubString(llIntegerToBase64(v1),0,5);
  226. }
  227. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  228. // each as one 10-byte base64-encoded string.
  229. string xtea_decipher( integer v0, integer v1 )
  230. {
  231. integer num_rounds = xtea_num_rounds;
  232. integer sum = XTEA_DELTA*xtea_num_rounds;
  233. do {
  234. // LSL does not have unsigned integers, so when shifting right we
  235. // have to mask out sign-extension bits.
  236. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  237. sum -= XTEA_DELTA;
  238. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  239. } while ( num_rounds = ~-num_rounds );
  240. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  241. llGetSubString(llIntegerToBase64(v1), 0, 4);
  242. }
  243. // Encrypt a full string using XTEA.
  244. string xtea_encrypt_string( string str )
  245. {
  246. if (! ENCRYPT)
  247. return str;
  248. // encode string
  249. str = llStringToBase64(str);
  250. // remove trailing =s so we can do our own 0 padding
  251. integer i = llSubStringIndex( str, "=" );
  252. if ( i != -1 )
  253. str = llDeleteSubString( str, i, -1 );
  254. // we don't want to process padding, so get length before adding it
  255. integer len = llStringLength(str);
  256. // zero pad
  257. str += "AAAAAAAAAA=";
  258. string result;
  259. i = 0;
  260. do {
  261. // encipher 30 (5*6) bits at a time.
  262. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  263. i+=10;
  264. } while ( i < len );
  265. return result;
  266. }
  267. // Decrypt a full string using XTEA
  268. string xtea_decrypt_string( string str ) {
  269. if (! ENCRYPT)
  270. return str;
  271. integer len = llStringLength(str);
  272. integer i=0;
  273. string result;
  274. //llOwnerSay(str);
  275. do {
  276. integer v0;
  277. integer v1;
  278. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  279. i+= 6;
  280. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  281. i+= 6;
  282. result += xtea_decipher(v0, v1);
  283. } while ( i < len );
  284. // Replace multiple trailing zeroes with a single one
  285. i = llStringLength(result) - 1;
  286. while ( llGetSubString(result, i - 1, i) == "AA" ){
  287. result = llDeleteSubString(result, i, i);
  288. i--;
  289. }
  290. i = llStringLength(result) - 1;
  291. // while (llGetSubString(result, i, i + 1) == "A" ) {
  292. // i--;
  293. // }
  294. result = llGetSubString(result, 0, i+1);
  295. i = llStringLength(result);
  296. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  297. if(mod == 1) result += "A==";
  298. else if(mod == 2 ) result += "==";
  299. else if(mod == 3) result += "=";
  300. return llBase64ToString(result);
  301. }
  302. string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  303. vector colour1; // saved animal coloration 1 breedable param
  304. vector colour2; // saved animal coloration 2 breedable param
  305. integer gen; // saved animal Gen 0 is first born, 1 is babies, etc
  306. integer shine; //saved animal 0 = None, 1 = Low, 2 = Medium, 3 = High shine
  307. float glow; // saved animal food fed glow in percent
  308. key uuid; // Animal UUID from a CRATE_PING
  309. integer listener; // listener ID for menu
  310. integer owner_touch; // flag to prevent a second touch from someone else from cancelling the menu timer
  311. integer sex; // 1 = Male, 2 = Female
  312. integer age; // age in days
  313. integer hunger; // saved animal hunger value
  314. string myname; // saved animal pet name
  315. integer glow_gene; // saved animal glow gene
  316. string special; // saved animal special feature
  317. string colourName1; // new string to hold color name version 0.52
  318. string colourName2;
  319. say_details()
  320. {
  321. string mysex;
  322. string myshine;
  323. if (sex == 1) {
  324. mysex = "Male";
  325. } else
  326. if (sex == 2) {
  327. mysex = "Female";
  328. } else {
  329. mysex = (string)sex;
  330. }
  331. if (shine == 0) {
  332. myshine = "None";
  333. } else
  334. if (shine == 1) {
  335. myshine = "Low";
  336. } else
  337. if (shine == 2) {
  338. myshine = "Medium";
  339. } else
  340. if (shine == 3) {
  341. myshine = "High";
  342. }
  343. llWhisper(0, "Color: " + colourName1);
  344. llWhisper(0, "Color: " + colourName2);
  345. llWhisper(0, "Shine: " + myshine);
  346. llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
  347. llWhisper(0, "Special: " + special);
  348. llWhisper(0, "Sex: " + mysex);
  349. llWhisper(0, "Age: " + (string)age + " days");
  350. llWhisper(0, "Generation: " + (string)gen);
  351. llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
  352. }
  353. set_colours(vector c1, vector c2, integer shine, float glow)
  354. {
  355. string msg = (string) c1 + "^" +
  356. (string) c2 + "^" +
  357. "0^" + // sex is unknown in an egg
  358. (string) shine + "^" +
  359. (string) glow + "^";
  360. llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY); // tell the optional texture plugin
  361. llMessageLinked(LINK_SET,LINK_COLOR1_GET,(string) colour1,""); // V 0.52 send colors to plug in
  362. llMessageLinked(LINK_SET,LINK_COLOR2_GET,(string) colour2,"");
  363. if (BOX)
  364. // sets color 1 on sides 0,1,3,5 and color 2 on sides 2 &4 of a box
  365. llSetPrimitiveParams([PRIM_COLOR, 0, c1, 1.0, PRIM_COLOR, 1, c1, 1.0, PRIM_COLOR, 3, c1, 1.0, PRIM_COLOR, 5, c1, 1.0, PRIM_COLOR, 2, c2, 1.0, PRIM_COLOR, 4, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  366. else
  367. {
  368. integer N = llGetNumberOfPrims();
  369. integer i;
  370. for (i = 1; i <= N; i++)
  371. {
  372. list lDesc = llGetLinkPrimitiveParams(i,[28]); // 28 = PRIM_DESC, but LSLEdit does not support it yet :-(
  373. string desc = llToLower(llList2String(lDesc,0)); // get the string description
  374. if (desc == "color1")
  375. {
  376. llSetLinkPrimitiveParamsFast(i,[PRIM_COLOR, 0, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  377. } else if (desc == "color2")
  378. {
  379. llSetLinkPrimitiveParamsFast(i,[PRIM_COLOR, 0, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  380. }
  381. }
  382. }
  383. }
  384. default
  385. {
  386. state_entry()
  387. {
  388. set_colours(<1,1,1>,<1,1,1>,0,0); // default box color
  389. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  390. uuid = NULL_KEY;
  391. listener = llListen(BOX_CHANNEL, "", "", "");
  392. }
  393. touch_start(integer num)
  394. {
  395. llWhisper(0, "This " + llGetObjectName() + " is version " + (string)VERSION);
  396. }
  397. listen(integer channel, string name, key id, string msg)
  398. {
  399. if (llGetOwnerKey(id) != llGetOwner()) {
  400. return;
  401. }
  402. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  403. if (uuid == NULL_KEY) {
  404. if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "CRATE_PING") {
  405. uuid = id;
  406. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CRATE_PONG^" + (string)id + "^" + (string)VERSION));
  407. llSetTimerEvent(15.0);
  408. }
  409. } else
  410. if (uuid == id) {
  411. if (llList2String(data, 0) == "XSPET" && (key) llList2String(data, 1) == llGetKey()) {
  412. llSetTimerEvent(0.0);
  413. colour1 = (vector)llList2String(data, 2);
  414. colour2 = (vector)llList2String(data, 3);
  415. shine = (integer) llList2String(data, 4);
  416. glow = (float) llList2String(data, 5);
  417. gen = (integer) llList2String(data, 6);
  418. sex = (integer) llList2String(data, 7);
  419. age = (integer) llList2String(data, 8);
  420. hunger = (integer) llList2String(data, 9);
  421. myname = llList2String(data, 10);
  422. glow_gene = (integer) llList2String(data, 11);
  423. special = llList2String(data, 12);
  424. llListenRemove(listener);
  425. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CRATE_DIE^" + (string)id + "^" + (string)VERSION));
  426. state full;
  427. } else {
  428. if (llList2String(data, 0) == "XSPET" && (key) llList2String(data, 1) != llGetKey()) {
  429. uuid = NULL_KEY;
  430. }
  431. }
  432. }
  433. }
  434. timer()
  435. {
  436. llSetTimerEvent(0.0);
  437. uuid = NULL_KEY;
  438. }
  439. }
  440. state full
  441. {
  442. state_entry()
  443. {
  444. llSetObjectName(Crate + ":" + myname);
  445. set_colours(colour1, colour2, shine, glow);
  446. llListen(API_CHANNEL, "", "", "");
  447. }
  448. touch_start(integer num)
  449. {
  450. owner_touch = 0;
  451. say_details();
  452. if (llDetectedKey(0) == llGetOwner()) {
  453. owner_touch = 1;
  454. integer chan = (integer)llFrand(10000.0) + 1000;
  455. listener = llListen(chan, "", llGetOwner(), "");
  456. llDialog(llGetOwner(), "Would you like to unpackage me?", ["Yes", "No"], chan);
  457. }
  458. llSetTimerEvent(20.0);
  459. }
  460. link_message(integer sender_number, integer number, string message, key id)
  461. {
  462. if (number == LINK_COLOR1_PUT)
  463. {
  464. colourName1 = message;
  465. } else if (number == LINK_COLOR2_PUT)
  466. {
  467. colourName2 = message;
  468. }
  469. }
  470. timer()
  471. {
  472. if (owner_touch == 1) {
  473. llListenRemove(listener);
  474. }
  475. llSetTimerEvent(0.0);
  476. }
  477. listen(integer channel, string name, key id, string msg)
  478. {
  479. if (channel == API_CHANNEL) {
  480. list data = llParseString2List(msg, ["^"], []);
  481. if (llList2String(data, 0) == "XSPet" && (key) llList2String(data, 1) == llGetKey()) {
  482. llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
  483. }
  484. } else {
  485. llListenRemove(listener);
  486. if (msg == "Yes") {
  487. state unbox;
  488. }
  489. }
  490. }
  491. }
  492. state unbox
  493. {
  494. state_entry()
  495. {
  496. if (MoveUp) {
  497. vector pos = llGetPos();
  498. pos.z += distance;
  499. llSetPos(pos); // move up a bit
  500. position = - distance; // down below us for ufo
  501. }
  502. // v.25 ufo particles
  503. llMessageLinked(LINK_SET,LINK_EFFECTS_ON,"",""); // V.25 turn on effects
  504. if (sex == 1)
  505. llRezObject(MaleName, llGetPos() + <0.0, 0.0, position>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  506. else
  507. llRezObject(FemaleName, llGetPos() + <0.0, 0.0, position>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  508. }
  509. object_rez(key id)
  510. {
  511. listener = llListen(BOX_CHANNEL, "", id, "");
  512. }
  513. listen(integer channel, string name, key id, string msg)
  514. {
  515. if (channel == BOX_CHANNEL) {
  516. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  517. if (llList2String(data, 0) == "XSPET" && llList2String(data, 1) == "READY") {
  518. llGiveInventory(id, Egg);
  519. llGiveInventory(id, MaleName);
  520. llGiveInventory(id, FemaleName);
  521. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CONFIG^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)sex + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" +(string)age + "^" + (string)hunger + "^" + myname + "^" + (string)glow_gene + "^" + special));
  522. if (delay) {
  523. llSleep(delay); // V.25 give some time for effects to rez
  524. }
  525. llDie();
  526. }
  527. }
  528. }
  529. }