xs_brain.lsl 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. // :CATEGORY:XS Pet
  2. // :NAME:XS Pet Quail Modified
  3. // :AUTHOR:Xundra Snowpaw, Ferd Frederix
  4. // :CREATED:2013-09-06
  5. // :EDITED:2013-09-18 15:39:09
  6. // :ID:987
  7. // :NUM:1416
  8. // :REV:1
  9. // :WORLD:Second Life, Opensim
  10. // :DESCRIPTION:
  11. // Modified Pet Quail
  12. // :CODE:
  13. // Version .24 10-3-2011
  14. // script by Xundra Snowpaw
  15. // mods by Ferd Frederix
  16. //
  17. // New BSD License: http://www.opensource.org/licenses/bsd-license.php
  18. // Copyright (c) 2010, Xundra Snowpaw
  19. // All rights reserved.
  20. //
  21. // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  22. //* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  23. //* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. ////////////////////////////////////////////////////////////////////
  26. ///// GLOBAL LINK CONSTANTS extracted from original source //////
  27. ///
  28. // if you change anything, you change it everywhere and in a list in XS_Debug
  29. ///
  30. integer LINK_AGE_START = 800; // when quail is rezzed and secret_number, is sent by brain to breeder, eater and informatic get booted up
  31. integer LINK_FOOD_CONSUME = 900; // from movement to brain when close to food, brain then consumes a random amount up to 10000
  32. integer LINK_FOODMINUS = 901; // xs_brain receives FOOD_CONSUME, decrement hunger (eat)
  33. integer LINK_HUNGRY = 903; // sent by eater (string)hunger_amount, checks each hour
  34. integer LINK_HAMOUNT = 904; // hunger_amount = (integer)str,m updates the hunger amount in scripts
  35. integer LINK_SET_HOME = 910; // loc ^ dist
  36. integer LINK_MOVER = 911; // tell mover to rest for str seconds
  37. integer LINK_FOODIE_CLR = 920; // clear all food_bowl_keys and contents
  38. integer LINK_FOODIE = 921; // send FOOD_LOCATION coordinates to movement
  39. integer LINK_COLOR1 = 930; // colour1
  40. integer LINK_COLOR2 = 931; // colour2
  41. integer LINK_SEX = 932; // sex
  42. integer LINK_SHINE = 933; // shine
  43. integer LINK_GLOW = 934; // glow
  44. integer LINK_GEN = 935; // generation
  45. integer LINK_MAGE = 940; // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
  46. integer LINK_DAYTIME = 941; // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
  47. integer LINK_GET_AGE = 942; // get age from xs_ager and sent it on channel 943
  48. integer LINK_PUT_AGE = 943; // print age from xs_ager
  49. integer LINK_PACKAGE = 950; // look for a cryo_crate
  50. integer LINK_SEEK_FEMALE = 960; // MALE_BREED_CALL
  51. integer LINK_MALE_BREED_CALL = 961; // triggered by LINK_SEEK_FEMALE
  52. integer LINK_SIGNAL_ELIGIBLE = 962; // sent by female when hears LINK_MALE_BREED_CALL
  53. integer LINK_FEMALE_ELIGIBLE = 963; // sent when it hears in chat FEMALE_ELIGIBLE
  54. integer LINK_CALL_MALE = 964; // if LINK_FEMALE_ELIGIBLE && looking_for_female
  55. integer LINK_MALE_ON_THE_WAY = 965; // triggered by LINK_CALL_MALE
  56. integer LINK_FEMALE_LOCATION = 966; // female location, sends coordinates of a female
  57. integer LINK_RQST_BREED = 967; // sent when close enough to male/female
  58. integer LINK_CALL_MALE_INFO = 968; // ****** BUG ***** read, but never sent by anybody!!!!!
  59. // see line 557 and 636 of xs_brain which make calls and also xs_breeding which receives LUNK_MALE_INFO.
  60. integer LINK_MALE_INFO = 969;
  61. integer LINK_LAY_EGG = 970; // llRezObject("XS Egg"
  62. integer LINK_BREED_FAIL = 971; // key = father, failed, timed out
  63. integer LINK_PREGNANT = 972; // chick is preggers
  64. integer LINK_SLEEPING = 990; // close eyes
  65. integer LINK_UNSLEEPING = 991; // open eyes
  66. integer LINK_SOUND = 1001; // plays a sound if enabled
  67. integer LINK_SPECIAL = 1010; // xs_special, is str = "Normal", removes script
  68. integer LINK_PREGNANCY_TIME = 5000; // in seconds as str
  69. integer LINK_SLEEP = 7999; // disable sleep by parameter
  70. integer LINK_TIMER = 8000; // scan for food bowl about every 1800 seconds
  71. integer LINK_DIE = 9999; // death
  72. ///////// end global Link constants ////////
  73. // END //
  74. float VERSION = 0.22;
  75. string SECRET_PASSWORD = "top secret";
  76. integer SECRET_NUMBER = 99999;
  77. integer FOOD_CHANNEL = -999191;
  78. integer ANIMAL_CHANNEL = -999192;
  79. integer HOME_CHANNEL = -999194;
  80. integer BOX_CHANNEL = -999195;
  81. integer ACC_CHANNEL = -999196;
  82. integer UPDATE_CHANNEL = -999197;
  83. integer EGG_CHANNEL = -999193;
  84. float FOOD_BOWL_SCAN_INTERVAL = 1800.0;
  85. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  86. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  87. integer xtea_num_rounds = 6;
  88. list xtea_key = [0, 0, 0, 0];
  89. integer hex2int(string hex) {
  90. if(llGetSubString(hex,0,1) == "0x")
  91. return (integer)hex;
  92. if(llGetSubString(hex,0,0) == "x")
  93. return (integer)("0"+hex);
  94. return(integer)("0x"+hex);
  95. }
  96. // Convers any string to a 32 char MD5 string and then to a list of
  97. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  98. // 128 bit key is generated for any string passed.
  99. list xtea_key_from_string( string str )
  100. {
  101. str = llMD5String(str,0); // Use Nonce = 0
  102. return [ hex2int(llGetSubString( str, 0, 7)),
  103. hex2int(llGetSubString( str, 8, 15)),
  104. hex2int(llGetSubString( str, 16, 23)),
  105. hex2int(llGetSubString( str, 24, 31))];
  106. }
  107. // Encipher two integers and return the result as a 12-byte string
  108. // containing two base64-encoded integers.
  109. string xtea_encipher( integer v0, integer v1 )
  110. {
  111. integer num_rounds = xtea_num_rounds;
  112. integer sum = 0;
  113. do {
  114. // LSL does not have unsigned integers, so when shifting right we
  115. // have to mask out sign-extension bits.
  116. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  117. sum += XTEA_DELTA;
  118. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  119. } while( num_rounds = ~-num_rounds );
  120. //return only first 6 chars to remove "=="'s and compact encrypted text.
  121. return llGetSubString(llIntegerToBase64(v0),0,5) +
  122. llGetSubString(llIntegerToBase64(v1),0,5);
  123. }
  124. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  125. // each as one 10-byte base64-encoded string.
  126. string xtea_decipher( integer v0, integer v1 )
  127. {
  128. integer num_rounds = xtea_num_rounds;
  129. integer sum = XTEA_DELTA*xtea_num_rounds;
  130. do {
  131. // LSL does not have unsigned integers, so when shifting right we
  132. // have to mask out sign-extension bits.
  133. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  134. sum -= XTEA_DELTA;
  135. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  136. } while ( num_rounds = ~-num_rounds );
  137. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  138. llGetSubString(llIntegerToBase64(v1), 0, 4);
  139. }
  140. // Encrypt a full string using XTEA.
  141. string xtea_encrypt_string( string str )
  142. {
  143. // encode string
  144. str = llStringToBase64(str);
  145. // remove trailing =s so we can do our own 0 padding
  146. integer i = llSubStringIndex( str, "=" );
  147. if ( i != -1 )
  148. str = llDeleteSubString( str, i, -1 );
  149. // we don't want to process padding, so get length before adding it
  150. integer len = llStringLength(str);
  151. // zero pad
  152. str += "AAAAAAAAAA=";
  153. string result;
  154. i = 0;
  155. do {
  156. // encipher 30 (5*6) bits at a time.
  157. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  158. i+=10;
  159. } while ( i < len );
  160. return result;
  161. }
  162. // Decrypt a full string using XTEA
  163. string xtea_decrypt_string( string str ) {
  164. integer len = llStringLength(str);
  165. integer i=0;
  166. string result;
  167. //llOwnerSay(str);
  168. do {
  169. integer v0;
  170. integer v1;
  171. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  172. i+= 6;
  173. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  174. i+= 6;
  175. result += xtea_decipher(v0, v1);
  176. } while ( i < len );
  177. // Replace multiple trailing zeroes with a single one
  178. i = llStringLength(result) - 1;
  179. while ( llGetSubString(result, i - 1, i) == "AA" ){
  180. result = llDeleteSubString(result, i, i);
  181. i--;
  182. }
  183. i = llStringLength(result) - 1;
  184. // while (llGetSubString(result, i, i + 1) == "A" ) {
  185. // i--;
  186. // }
  187. result = llGetSubString(result, 0, i+1);
  188. i = llStringLength(result);
  189. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  190. if(mod == 1) result += "A==";
  191. else if(mod == 2 ) result += "==";
  192. else if(mod == 3) result += "=";
  193. return llBase64ToString(result);
  194. }
  195. integer setup = FALSE; // added to cure opensim rezzing issue
  196. //integer food_left;
  197. integer random_number;
  198. integer random_number2;
  199. //list food_bowl_keys;
  200. //list food_bowl_locations;
  201. integer hunger_amount;
  202. vector colour1;
  203. vector colour2;
  204. integer sex;
  205. integer shine;
  206. float glow;
  207. integer gen;
  208. integer age;
  209. vector mcolour1;
  210. vector mcolour2;
  211. integer mshine;
  212. float mglow;
  213. integer mgen;
  214. vector home_loc;
  215. key new_egg_key;
  216. integer glow_gene;
  217. string special;
  218. integer mglow_gene;
  219. integer locked;
  220. integer pregnancy_time;
  221. default
  222. {
  223. state_entry()
  224. {
  225. if (llGetOwner() != llGetCreator()) {
  226. // someone not the creator reset the script. Thats naughty.
  227. state dead;
  228. }
  229. llSetText("", <1,1,1>, 1.0);
  230. random_number = 0;
  231. random_number2 = 0;
  232. hunger_amount = 0;
  233. locked = 0;
  234. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  235. llListen(ANIMAL_CHANNEL, "", "", "");
  236. }
  237. changed(integer change)
  238. {
  239. if (change & CHANGED_ALLOWED_DROP) {
  240. if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
  241. llAllowInventoryDrop(FALSE);
  242. }
  243. }
  244. if (change & CHANGED_INVENTORY) {
  245. if (llGetOwner() != llGetCreator()) {
  246. integer inventory_count = llGetInventoryNumber(INVENTORY_ALL);
  247. integer extras = 3;
  248. if (llGetInventoryType("xs_ager") == INVENTORY_NONE || !llGetScriptState("xs_ager")) {
  249. state dead;
  250. }
  251. if (llGetInventoryType("xs_infomatic") == INVENTORY_NONE || !llGetScriptState("xs_infomatic")) {
  252. state dead;
  253. }
  254. if (llGetInventoryType("xs_breeding") == INVENTORY_NONE || !llGetScriptState("xs_breeding")) {
  255. state dead;
  256. }
  257. if (llGetInventoryType("xs_eater") == INVENTORY_NONE || !llGetScriptState("xs_eater")) {
  258. state dead;
  259. }
  260. if (llGetInventoryType("xs_movement") == INVENTORY_NONE || !llGetScriptState("xs_movement")) {
  261. state dead;
  262. }
  263. if (llGetInventoryType("bird_sound") == INVENTORY_NONE) {
  264. state dead;
  265. }
  266. if (llGetInventoryType("xs_special") == INVENTORY_NONE) {
  267. extras--;
  268. }
  269. if (llGetInventoryType("XS Egg") == INVENTORY_NONE) {
  270. extras--;
  271. }
  272. if (llGetInventoryType("Quail") == INVENTORY_NONE) {
  273. extras--;
  274. }
  275. if (llGetInventoryType("XS Home Object") == INVENTORY_NONE) {
  276. state dead;
  277. }
  278. if (8 + extras != inventory_count) {
  279. state dead;
  280. }
  281. }
  282. }
  283. }
  284. timer()
  285. {
  286. // for OpenSIm to establish an on_rez, the durn thing does not for the onrez even in the egg unless the script goes idle
  287. if (setup == TRUE)
  288. {
  289. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
  290. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
  291. setup = FALSE;
  292. return;
  293. }
  294. llMessageLinked(LINK_SET, LINK_FOODIE_CLR, "", "");
  295. // llWhisper(0, "Scanning for food bowls.");
  296. random_number = (integer)(llFrand(10000.0) + 1);
  297. llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_LOCATION^" + (string)random_number + "^" + (string)llGetKey()));
  298. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  299. }
  300. listen(integer channel, string name, key id, string message)
  301. {
  302. if (channel == ANIMAL_CHANNEL) {
  303. list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
  304. if (llList2String(data, 0) == "XSPET") {
  305. if (llList2String(data, 1) == "FOOD_LOCATION") {
  306. llMessageLinked(LINK_SET, LINK_FOODIE, llList2String(data, 3), id);
  307. } else
  308. if (llList2String(data, 1) == "FOOD_CONSUME") {
  309. if (llList2Integer(data, 2) == random_number2 && llList2Key(data, 3) == llGetKey()) {
  310. hunger_amount--;
  311. llMessageLinked(LINK_SET, LINK_FOODMINUS, "", "");
  312. random_number2 = 0;
  313. if (llList2Integer(data, 4) == 1 && glow_gene < 10) {
  314. glow_gene ++;
  315. }
  316. }
  317. } else
  318. if (llList2String(data, 1) == "HOME_LOCATION") {
  319. vector n_home_loc = (vector)llList2String(data, 2);
  320. float home_dis = llList2Float(data, 3);
  321. vector my_loc = llGetPos();
  322. // llOwnerSay((string)llVecDist(home_loc, my_loc) + " " + (string)my_loc + (string)home_loc + (string)home_dis + llList2String(data, 2));
  323. if (llVecDist(n_home_loc, my_loc) <= home_dis && llFabs(llFabs(n_home_loc.z) - llFabs(my_loc.z)) < 1) {
  324. if (llGetOwnerKey(id) == llGetOwner()) {
  325. home_loc = n_home_loc;
  326. llMessageLinked(LINK_SET, LINK_SET_HOME, (string)n_home_loc + "^" + (string)home_dis, "");
  327. }
  328. }
  329. } else
  330. if (llList2String(data, 1) == "CONFIG" && llList2Key(data, 2) == llGetKey()) {
  331. colour1 = (vector)llList2String(data, 3);;
  332. colour2 = (vector)llList2String(data, 4);
  333. sex = llList2Integer(data, 5);
  334. shine = llList2Integer(data, 6);
  335. glow = llList2Float(data, 7);
  336. gen = llList2Integer(data, 8);
  337. integer mage = llList2Integer(data, 9);
  338. integer hamount = llList2Integer(data, 10);
  339. string myname = llList2String(data, 11);
  340. glow_gene = llList2Integer(data, 12);
  341. special = llList2String(data, 13);
  342. llSetLinkPrimitiveParams(5, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  343. llSetLinkPrimitiveParams(1, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  344. // llSetLinkColor(8, colour1, ALL_SIDES);
  345. // llSetLinkColor(1, colour1, ALL_SIDES);
  346. llSetLinkPrimitiveParams(7, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  347. llSetLinkPrimitiveParams(4, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  348. llSetLinkPrimitiveParams(9, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  349. // llSetLinkColor(3, colour2, ALL_SIDES);
  350. // llSetLinkColor(2, colour2, ALL_SIDES);
  351. // llSetLinkColor(7, colour2, ALL_SIDES);
  352. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  353. llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
  354. llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");
  355. llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
  356. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  357. llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
  358. llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");
  359. llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");
  360. if (hamount > 0) {
  361. llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
  362. }
  363. if (name != "Quail") {
  364. llSetObjectName(myname);
  365. }
  366. llSetObjectDesc("XS Quail v" + (string)VERSION + " (c) 2010 Xundra Snowpaw");
  367. llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");
  368. llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");
  369. llSay(HOME_CHANNEL, "XSPET_PING_HOME");
  370. llSetText("", <1,1,1>, 1.0);
  371. } else
  372. if (llList2String(data, 1) == "UPDATE_CONFIG" && llList2Key(data, 2) == llGetKey()) {
  373. colour1 = (vector)llList2String(data, 3);;
  374. colour2 = (vector)llList2String(data, 4);
  375. sex = llList2Integer(data, 5);
  376. shine = llList2Integer(data, 6);
  377. glow = llList2Float(data, 7);
  378. gen = llList2Integer(data, 8);
  379. integer mage = llList2Integer(data, 9);
  380. integer hamount = llList2Integer(data, 10);
  381. string myname = llList2String(data, 11);
  382. glow_gene = llList2Integer(data, 12);
  383. special = llList2String(data, 13);
  384. mcolour1 = (vector)llList2String(data, 14);
  385. mcolour2 = (vector)llList2String(data, 15);
  386. mshine = llList2Integer(data, 16);
  387. mglow = llList2Float(data, 17);
  388. mgen = llList2Integer(data, 18);
  389. mglow_gene = llList2Integer(data, 19);
  390. pregnancy_time = llList2Integer(data, 20);
  391. llSetLinkPrimitiveParams(5, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  392. llSetLinkPrimitiveParams(1, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  393. // llSetLinkColor(8, colour1, ALL_SIDES);
  394. // llSetLinkColor(1, colour1, ALL_SIDES);
  395. llSetLinkPrimitiveParams(7, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  396. llSetLinkPrimitiveParams(4, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  397. llSetLinkPrimitiveParams(9, [PRIM_COLOR, ALL_SIDES, colour2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  398. // llSetLinkColor(3, colour2, ALL_SIDES);
  399. // llSetLinkColor(2, colour2, ALL_SIDES);
  400. // llSetLinkColor(7, colour2, ALL_SIDES);
  401. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  402. llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
  403. llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");
  404. if (sex == 1) {
  405. llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
  406. } else {
  407. llMessageLinked(LINK_SET, LINK_PREGNANCY_TIME, (string)pregnancy_time, "");
  408. }
  409. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  410. llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
  411. llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");
  412. llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");
  413. if (hamount > 0) {
  414. llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
  415. }
  416. if (name != "Quail") {
  417. llSetObjectName(myname);
  418. }
  419. llSetObjectDesc("XS Quail v" + (string)VERSION + " (c) 2010 Xundra Snowpaw");
  420. llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");
  421. llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");
  422. llSay(HOME_CHANNEL, "XSPET_PING_HOME");
  423. llSetText("", <1,1,1>, 1.0);
  424. } else
  425. if (llList2String(data, 1) == "CRATE_PONG" && llList2Key(data, 2) == llGetKey()) {
  426. if (llList2Float(data, 3) >= VERSION && locked == 0) {
  427. locked = 1;
  428. 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));
  429. }
  430. } else
  431. if (llList2String(data, 1) == "CRATE_DIE" && llList2Key(data, 2) == llGetKey()) {
  432. llDie();
  433. } else
  434. if (llList2String(data, 1) == "MALE_BREED_CALL") {
  435. llMessageLinked(LINK_SET, LINK_MALE_BREED_CALL, "", "");
  436. } else
  437. if (llList2String(data, 1) == "FEMALE_ELIGIBLE" && home_loc == (vector)llList2String(data, 2)) {
  438. llMessageLinked(LINK_SET, LINK_FEMALE_ELIGIBLE, "", id);
  439. } else
  440. if (llList2String(data, 1) == "MALE_ON_THE_WAY" && llList2Key(data, 2) == llGetKey()) {
  441. llMessageLinked(LINK_SET, LINK_MALE_ON_THE_WAY, "", id);
  442. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_LOC^" + (string)id + "^" + (string)llGetPos()));
  443. } else
  444. if (llList2String(data, 1) == "FEMALE_LOC" && (key) llList2String(data, 2) == llGetKey()) // missing key cast - Ferd
  445. {
  446. llMessageLinked(LINK_SET, LINK_FEMALE_LOCATION, llList2String(data, 3), "");
  447. } else
  448. if (llList2String(data, 1) == "MALE_INFO" && llList2Key(data, 2) == llGetKey()){
  449. // pregnant
  450. mcolour1 = (vector)llList2String(data, 3);
  451. mcolour2 = (vector)llList2String(data, 4);
  452. mshine = llList2Integer(data, 5);
  453. mglow = llList2Float(data, 6);
  454. mgen = llList2Integer(data, 7);
  455. mglow_gene = llList2Integer(data, 8);
  456. pregnancy_time = llGetUnixTime();
  457. llMessageLinked(LINK_SET, LINK_PREGNANT, "", "");
  458. } else
  459. if (llList2String(data, 1) == "BREEDING_FAIL" && (key) llList2String(data, 2) == llGetKey()) // missing key cast - Ferd
  460. {
  461. llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
  462. } else
  463. if (llList2String(data, 1) == "EGG_READY" && id == new_egg_key)
  464. {
  465. llGiveInventory(id, "XS Egg");
  466. llGiveInventory(id, "Quail");
  467. 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));
  468. } else
  469. if (llList2String(data, 1) == "SHINE_GOO" && (key) llList2String(data, 2) == llGetKey()) { // missing key cast - Ferd
  470. if (shine == 0) {
  471. shine = 1;
  472. llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
  473. llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_DIE"));
  474. llSetLinkPrimitiveParams(5, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  475. llSetLinkPrimitiveParams(1, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  476. // llSetLinkColor(8, colour1, ALL_SIDES);
  477. // llSetLinkColor(1, colour1, ALL_SIDES);
  478. llSetLinkPrimitiveParams(7, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  479. llSetLinkPrimitiveParams(4, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  480. llSetLinkPrimitiveParams(9, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  481. if (sex == 1) {
  482. llWhisper(0, "Look out ladies, Mr Slick has arrived!");
  483. } else {
  484. llWhisper(0, "Look out gentlemen! Miss Slick has arrived!");
  485. }
  486. } else {
  487. llWhisper(0, "I'm already shiny!");
  488. llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_FAIL"));
  489. }
  490. } else
  491. if (llList2String(data, 1) == "DIE" && (key) llList2String(data, 2) == llGetKey()) { // missing key cast - Ferd
  492. llDie();
  493. } else
  494. if (llList2String(data, 1) == "VERSION" && VERSION < llList2Float(data, 2) && llGetOwnerKey(id) == llGetOwner()) {
  495. llShout(UPDATE_CHANNEL, "VERSION^" + (string)VERSION);
  496. } else
  497. if (llList2String(data, 1) == "UPDATE" && (key) llList2String(data, 2) == llGetKey() && llGetOwnerKey(id) == llGetOwner()) { // missing key cast - Ferd
  498. state update;
  499. }
  500. }
  501. }
  502. }
  503. link_message(integer sender, integer num, string str, key id)
  504. {
  505. if (num == LINK_HUNGRY || num == LINK_HAMOUNT) {
  506. hunger_amount = (integer)str;
  507. if (hunger_amount > 30) {
  508. state dead;
  509. }
  510. } else
  511. if (num == LINK_FOOD_CONSUME) {
  512. random_number2 = (integer)(llFrand(10000.0) + 1);
  513. llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_CONSUME^" + (string)id + "^" + (string)random_number2 + "^" + (string)llGetKey()));
  514. } else
  515. if (num == LINK_MAGE) {
  516. age += (integer)str;
  517. } else
  518. if (num == LINK_PACKAGE) {
  519. llWhisper(0, "Looking for a cryo-crate...");
  520. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CRATE_PING^" + (string)VERSION));
  521. } else
  522. if (num == LINK_SEEK_FEMALE) {
  523. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_BREED_CALL^" + (string)llGetKey()));
  524. } else
  525. if (num == LINK_SIGNAL_ELIGIBLE) {
  526. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_ELIGIBLE^" + (string)home_loc));
  527. } else
  528. if (num == LINK_CALL_MALE) {
  529. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_ON_THE_WAY^" + (string)id));
  530. } else
  531. if (num == LINK_CALL_MALE_INFO) {
  532. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_INFO^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + (string)glow_gene));
  533. llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
  534. } else
  535. if (num == LINK_LAY_EGG) {
  536. // lay an egg
  537. pregnancy_time = 0;
  538. llRezObject("XS Egg", llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  539. } else
  540. if (num == LINK_BREED_FAIL) {
  541. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^BREEDING_FAIL^" + (string)id));
  542. pregnancy_time = 0;
  543. } else
  544. if (num == LINK_SLEEPING) {
  545. llSetLinkPrimitiveParams(3, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  546. llSetLinkPrimitiveParams(8, [PRIM_COLOR, ALL_SIDES, colour1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
  547. } else
  548. if (num == LINK_UNSLEEPING) {
  549. llSetLinkPrimitiveParams(3, [PRIM_COLOR, ALL_SIDES, <0,0,0>, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, 1, PRIM_BUMP_NONE]);
  550. llSetLinkPrimitiveParams(8, [PRIM_COLOR, ALL_SIDES, <0,0,0>, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, 1, PRIM_BUMP_NONE]);
  551. } else
  552. if (num == LINK_DIE) {
  553. state dead;
  554. } else
  555. if (num == LINK_TIMER) {
  556. llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
  557. }
  558. }
  559. object_rez(key id)
  560. {
  561. new_egg_key = id;
  562. }
  563. on_rez(integer param)
  564. {
  565. if (param == SECRET_NUMBER) {
  566. llSetText("Rezzing...", <1,0,0>, 1.0);
  567. llMessageLinked(LINK_SET, LINK_AGE_START, "", "");
  568. setup = TRUE;
  569. if (llGetOwner() != llGetCreator()) {
  570. llAllowInventoryDrop(TRUE);
  571. }
  572. llSetTimerEvent(5.0);
  573. } else {
  574. llOwnerSay("I died in your inventory, please use a cryo-crate next time.");
  575. state dead;
  576. }
  577. }
  578. }
  579. state dead
  580. {
  581. state_entry()
  582. {
  583. llSetText("Dead", <1,0,0>, 1.0);
  584. llRemoveInventory("xs_ager");
  585. llRemoveInventory("xs_breeding");
  586. llRemoveInventory("xs_eater");
  587. llRemoveInventory("xs_infomatic");
  588. llRemoveInventory("xs_movement");
  589. if (llGetInventoryType("xs_special") != INVENTORY_NONE) {
  590. llRemoveInventory("xs_special");
  591. }
  592. llListen(ANIMAL_CHANNEL, "", "", "");
  593. }
  594. touch_start(integer number)
  595. {
  596. llWhisper(0, "I've died. You could re-animate me with a jar of Xtra Strong Mojo");
  597. if (llDetectedKey(0) == llGetOwner()) {
  598. 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));
  599. }
  600. }
  601. listen(integer channel, string name, key id, string message) {
  602. list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
  603. if (llList2String(data, 0) == "XSPET") {
  604. if (llList2String(data, 1) == "STRONG_MOJO_DIE" && llList2Key(data, 2) == llGetKey()) {
  605. llDie();
  606. }
  607. }
  608. }
  609. }
  610. state update
  611. {
  612. state_entry()
  613. {
  614. llSetText("Updating.", <1,0,0>, 1.0);
  615. llRemoveInventory("Quail");
  616. llRemoveInventory("XS Egg");
  617. llAllowInventoryDrop(TRUE);
  618. llShout(UPDATE_CHANNEL, "UPDATE_READY");
  619. }
  620. changed(integer change)
  621. {
  622. if (change & CHANGED_ALLOWED_DROP) {
  623. if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
  624. llAllowInventoryDrop(FALSE);
  625. llRezObject("Quail", llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  626. }
  627. }
  628. }
  629. object_rez(key id)
  630. {
  631. llListen(BOX_CHANNEL, "", id, "");
  632. }
  633. listen(integer channel, string name, key id, string msg)
  634. {
  635. if (channel == BOX_CHANNEL) {
  636. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  637. if (llList2String(data, 0) == "XSPET" && llList2String(data, 1) == "READY") {
  638. llGiveInventory(id, "XS Egg");
  639. llGiveInventory(id, "Quail");
  640. 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));
  641. llDie();
  642. }
  643. }
  644. }
  645. }