xs_egg.lsl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. // :CATEGORY:XS Quail
  2. // :NAME:XS Pet Quail Modified
  3. // :AUTHOR:Xundra Snowpaw, Ferd Frederix
  4. // :CREATED:2013-09-06
  5. // :EDITED:2014-01-17 11:32:48
  6. // :ID:987
  7. // :NUM:1424
  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. float VERSION = 0.22;
  27. integer API_CHANNEL = -999198;
  28. string SECRET_PASSWORD = "top secret";
  29. integer SECRET_NUMBER = 99999;
  30. integer ANIMAL_CHANNEL = -999192;
  31. integer EGG_CHANNEL = -999193;
  32. integer BOX_CHANNEL = -999195;
  33. string SPECIAL = "Normal";
  34. //integer TIME_TO_HATCH = 7200;
  35. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  36. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  37. integer xtea_num_rounds = 6;
  38. list xtea_key = [0, 0, 0, 0];
  39. integer hex2int(string hex) {
  40. if(llGetSubString(hex,0,1) == "0x")
  41. return (integer)hex;
  42. if(llGetSubString(hex,0,0) == "x")
  43. return (integer)("0"+hex);
  44. return(integer)("0x"+hex);
  45. }
  46. // Convers any string to a 32 char MD5 string and then to a list of
  47. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  48. // 128 bit key is generated for any string passed.
  49. list xtea_key_from_string( string str )
  50. {
  51. str = llMD5String(str,0); // Use Nonce = 0
  52. return [ hex2int(llGetSubString( str, 0, 7)),
  53. hex2int(llGetSubString( str, 8, 15)),
  54. hex2int(llGetSubString( str, 16, 23)),
  55. hex2int(llGetSubString( str, 24, 31))];
  56. }
  57. // Encipher two integers and return the result as a 12-byte string
  58. // containing two base64-encoded integers.
  59. string xtea_encipher( integer v0, integer v1 )
  60. {
  61. integer num_rounds = xtea_num_rounds;
  62. integer sum = 0;
  63. do {
  64. // LSL does not have unsigned integers, so when shifting right we
  65. // have to mask out sign-extension bits.
  66. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  67. sum += XTEA_DELTA;
  68. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  69. } while( num_rounds = ~-num_rounds );
  70. //return only first 6 chars to remove "=="'s and compact encrypted text.
  71. return llGetSubString(llIntegerToBase64(v0),0,5) +
  72. llGetSubString(llIntegerToBase64(v1),0,5);
  73. }
  74. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  75. // each as one 10-byte base64-encoded string.
  76. string xtea_decipher( integer v0, integer v1 )
  77. {
  78. integer num_rounds = xtea_num_rounds;
  79. integer sum = XTEA_DELTA*xtea_num_rounds;
  80. do {
  81. // LSL does not have unsigned integers, so when shifting right we
  82. // have to mask out sign-extension bits.
  83. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  84. sum -= XTEA_DELTA;
  85. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  86. } while ( num_rounds = ~-num_rounds );
  87. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  88. llGetSubString(llIntegerToBase64(v1), 0, 4);
  89. }
  90. // Encrypt a full string using XTEA.
  91. string xtea_encrypt_string( string str )
  92. {
  93. // encode string
  94. str = llStringToBase64(str);
  95. // remove trailing =s so we can do our own 0 padding
  96. integer i = llSubStringIndex( str, "=" );
  97. if ( i != -1 )
  98. str = llDeleteSubString( str, i, -1 );
  99. // we don't want to process padding, so get length before adding it
  100. integer len = llStringLength(str);
  101. // zero pad
  102. str += "AAAAAAAAAA=";
  103. string result;
  104. i = 0;
  105. do {
  106. // encipher 30 (5*6) bits at a time.
  107. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  108. i+=10;
  109. } while ( i < len );
  110. return result;
  111. }
  112. // Decrypt a full string using XTEA
  113. string xtea_decrypt_string( string str ) {
  114. integer len = llStringLength(str);
  115. integer i=0;
  116. string result;
  117. //llOwnerSay(str);
  118. do {
  119. integer v0;
  120. integer v1;
  121. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  122. i+= 6;
  123. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  124. i+= 6;
  125. result += xtea_decipher(v0, v1);
  126. } while ( i < len );
  127. // Replace multiple trailing zeroes with a single one
  128. i = llStringLength(result) - 1;
  129. while ( llGetSubString(result, i - 1, i) == "AA" ){
  130. result = llDeleteSubString(result, i, i);
  131. i--;
  132. }
  133. i = llStringLength(result) - 1;
  134. // while (llGetSubString(result, i, i + 1) == "A" ) {
  135. // i--;
  136. // }
  137. result = llGetSubString(result, 0, i+1);
  138. i = llStringLength(result);
  139. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  140. if(mod == 1) result += "A==";
  141. else if(mod == 2 ) result += "==";
  142. else if(mod == 3) result += "=";
  143. return llBase64ToString(result);
  144. }
  145. string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  146. vector colour1;
  147. vector colour2;
  148. integer sex;
  149. integer gen;
  150. integer shine;
  151. float glow;
  152. integer api_listener;
  153. integer locked;
  154. integer born_hatched;
  155. integer owner_touch;
  156. integer menu_listener;
  157. set_colours(vector c1, vector c2, integer shine, float glow)
  158. {
  159. llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  160. llSetLinkPrimitiveParams(2, [PRIM_COLOR, ALL_SIDES, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  161. }
  162. say_details()
  163. {
  164. string myshine;
  165. if (shine == 0) {
  166. myshine = "None";
  167. } else
  168. if (shine == 1) {
  169. myshine = "Low";
  170. } else
  171. if (shine == 2) {
  172. myshine = "Medium";
  173. } else
  174. if (shine == 3) {
  175. myshine = "High";
  176. }
  177. llWhisper(0, "Head/Body Colour: " + (string)colour1);
  178. llWhisper(0, "Tail/Wing Colour: " + (string)colour2);
  179. llWhisper(0, "Shine: " + myshine);
  180. llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
  181. llWhisper(0, "Special: " + SPECIAL);
  182. llWhisper(0, "Generation: " + (string)gen);
  183. llSay(API_CHANNEL, "XSQuail^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + SPECIAL + "^" + (string)gen + "^XSQuailEnd");
  184. }
  185. default
  186. {
  187. state_entry()
  188. {
  189. llSetText("", <1,1,1>, 1.0);
  190. llSetColor(<1,1,1>, ALL_SIDES);
  191. llSetLinkColor(2, <1,1,1>, ALL_SIDES);
  192. llParticleSystem([]);
  193. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  194. }
  195. changed(integer change) {
  196. if (change & CHANGED_ALLOWED_DROP) {
  197. if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
  198. llAllowInventoryDrop(FALSE);
  199. }
  200. }
  201. }
  202. on_rez(integer param)
  203. {
  204. llSetText("Rezzing...", <1,0,0>, 1.0);
  205. llSleep(5.0);
  206. if (param == 0) {
  207. if (llGetOwner() == llGetCreator()) {
  208. integer colour = (integer)llFrand(9.0) + 1;
  209. if (colour == 1) {
  210. colour1 = <1,0,0>;
  211. colour2 = <1,0,0>;
  212. } else
  213. if (colour == 2) {
  214. colour1 = <1,0,0>;
  215. colour2 = <0,1,0>;
  216. } else
  217. if (colour == 3) {
  218. colour1 = <1,0,0>;
  219. colour2 = <0,0,1>;
  220. } else
  221. if (colour == 4) {
  222. colour1 = <0,1,0>;
  223. colour2 = <1,0,0>;
  224. } else
  225. if (colour == 5) {
  226. colour1 = <0,1,0>;
  227. colour2 = <0,1,0>;
  228. } else
  229. if (colour == 6) {
  230. colour1 = <0,1,0>;
  231. colour2 = <0,0,1>;
  232. } else
  233. if (colour == 7) {
  234. colour1 = <0,0,1>;
  235. colour2 = <1,0,0>;
  236. } else
  237. if (colour == 8) {
  238. colour1 = <0,0,1>;
  239. colour2 = <0,1,0>;
  240. } else
  241. if (colour == 9) {
  242. colour1 = <0,0,1>;
  243. colour2 = <0,0,1>;
  244. }
  245. set_colours(colour1, colour2, shine, glow);
  246. state rezzed;
  247. } else {
  248. llWhisper(0, "Oh no! This egg was broken in your inventory! Please use an egg-cup next time.");
  249. state dead;
  250. }
  251. } else
  252. if (param == SECRET_NUMBER) {
  253. menu_listener = llListen(EGG_CHANNEL, "", "", "");
  254. if (llGetOwner() != llGetCreator()) {
  255. llAllowInventoryDrop(TRUE);
  256. }
  257. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^EGG_READY^" + (string)llGetKey() + "^SMILE"));
  258. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^EGG_READY^SMILE"));
  259. }
  260. }
  261. listen(integer channel, string sender, key id, string msg) {
  262. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  263. if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey()) {
  264. if (llList2String(data, 2) == "UNBOX") {
  265. colour1 = (vector)llList2String(data, 3);
  266. colour2 = (vector)llList2String(data, 4);
  267. gen = llList2Integer(data,5);
  268. shine = llList2Integer(data, 6);
  269. glow = llList2Float(data, 7);
  270. SPECIAL = llList2String(data, 8);
  271. llListenRemove(menu_listener);
  272. set_colours(colour1, colour2, shine, glow);
  273. state rezzed;
  274. } else
  275. if (llList2String(data, 2) == "BORN") {
  276. vector fcolour1 = (vector)llList2String(data, 3);
  277. vector fcolour2 = (vector)llList2String(data, 4);
  278. integer fgen = llList2Integer(data,5);
  279. integer fshine = llList2Integer(data, 6);
  280. float fglow = llList2Float(data, 7);
  281. integer fglow_gene = llList2Integer(data, 8);
  282. vector mcolour1 = (vector)llList2String(data, 9);
  283. vector mcolour2 = (vector)llList2String(data, 10);
  284. integer mgen = llList2Integer(data, 11);
  285. integer mshine = llList2Integer(data, 12);
  286. float mglow = llList2Float(data, 13);
  287. integer mglow_gene = llList2Integer(data, 14);
  288. integer mix = (integer)llFrand(2) + 1;
  289. float deviation1 = (llFrand(10) - 5) / 100;
  290. float deviation2 = (llFrand(10) - 5) / 100;
  291. if (mix == 1) {
  292. colour1.x = (fcolour1.x / 2 + mcolour1.x / 2) + deviation1;
  293. colour1.y = (fcolour1.y / 2 + mcolour1.y / 2) + deviation1;
  294. colour1.z = (fcolour1.z / 2 + mcolour1.z / 2) + deviation1;
  295. colour2.x = (fcolour2.x / 2 + mcolour2.x / 2) + deviation2;
  296. colour2.y = (fcolour2.y / 2 + mcolour2.y / 2) + deviation2;
  297. colour2.z = (fcolour2.z / 2 + mcolour2.z / 2) + deviation2;
  298. } else {
  299. colour1.x = (fcolour1.x / 2 + mcolour2.x / 2) + deviation1;
  300. colour1.y = (fcolour1.y / 2 + mcolour2.y / 2) + deviation1;
  301. colour1.z = (fcolour1.z / 2 + mcolour2.z / 2) + deviation1;
  302. colour2.x = (fcolour2.x / 2 + mcolour1.x / 2) + deviation2;
  303. colour2.y = (fcolour2.y / 2 + mcolour1.y / 2) + deviation2;
  304. colour2.z = (fcolour2.z / 2 + mcolour1.z / 2) + deviation2;
  305. }
  306. if (colour1.x < 0)
  307. colour1.x = 0;
  308. if (colour1.x > 1)
  309. colour1.x = 1;
  310. if (colour1.y < 0)
  311. colour1.y = 0;
  312. if (colour1.y > 1)
  313. colour1.y = 1;
  314. if (colour1.z < 0)
  315. colour1.z = 0;
  316. if (colour1.z > 1)
  317. colour1.z = 1;
  318. if (colour2.x < 0)
  319. colour2.x = 0;
  320. if (colour2.x > 1)
  321. colour2.x = 1;
  322. if (colour2.y < 0)
  323. colour2.y = 0;
  324. if (colour2.y > 1)
  325. colour2.y = 1;
  326. if (colour2.z < 0)
  327. colour2.z = 0;
  328. if (colour2.z > 1)
  329. colour2.z = 1;
  330. if (mgen > fgen) {
  331. gen = mgen + 1;
  332. } else {
  333. gen = fgen + 1;
  334. }
  335. // TODO: shine / glow
  336. shine = 0;
  337. if (gen > 2) {
  338. integer pos = (integer)llFrand(100) + 1;
  339. if (fshine == mshine && fshine > 0) {
  340. if (pos < 25) {
  341. shine = fshine + 1;
  342. if (shine > 3) {
  343. shine = 3;
  344. }
  345. }
  346. } else {
  347. if (pos < 10) {
  348. // increase shine
  349. if (mshine > fshine) {
  350. shine = mshine + 1;
  351. } else
  352. if (fshine > mshine) {
  353. shine = fshine + 1;
  354. } else {
  355. shine = 1;
  356. }
  357. if (shine > 3) {
  358. shine = 3;
  359. }
  360. }
  361. }
  362. }
  363. glow = 0.0;
  364. if (mglow <= 0.3 && fglow <= 0.3) {
  365. if (mglow > fglow) {
  366. glow = mglow - 0.1;
  367. } else if (fglow > mglow) {
  368. glow = fglow - 0.1;
  369. }
  370. }
  371. if (fglow_gene >= 10 && mglow_gene >= 10) {
  372. integer poss = (integer)llFrand(100) + 1;
  373. if (poss < 25) {
  374. glow = 0.3;
  375. }
  376. } else if (fglow_gene >= 10 || mglow_gene >= 10) {
  377. integer poss = (integer)llFrand(100) + 1;
  378. if (poss < 10) {
  379. glow = 0.3;
  380. }
  381. }
  382. llListenRemove(menu_listener);
  383. born_hatched = 1;
  384. set_colours(colour1, colour2, shine, glow);
  385. llSetTimerEvent(1.0);
  386. }
  387. }
  388. }
  389. timer() {
  390. if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
  391. state rezzed;
  392. }
  393. }
  394. }
  395. state rezzed
  396. {
  397. on_rez(integer param)
  398. {
  399. if (llGetOwner() != llGetCreator()) { // wtf?
  400. llWhisper(0, "Oh no! This egg was broken in your inventory! Please use an egg-cup next time.");
  401. state dead;
  402. }
  403. }
  404. state_entry()
  405. {
  406. if (SPECIAL == "Normal") {
  407. llSetText("", <1,1,1>, 1.0);
  408. } else {
  409. llSetText(SPECIAL, <1,1,1>, 1.0);
  410. }
  411. api_listener = llListen(API_CHANNEL, "", "", "");
  412. }
  413. touch_start(integer num)
  414. {
  415. owner_touch = 0;
  416. say_details();
  417. if (llDetectedKey(0) == llGetOwner()) {
  418. owner_touch = 1;
  419. integer chan = (integer)llFrand(100000.0) + 1000;
  420. menu_listener = llListen(chan, "", llGetOwner(), "");
  421. llDialog(llGetOwner(), "I'm an egg. What would you like to do with me?", ["Hatch", "Package", "Nothing"], chan);
  422. }
  423. llSetTimerEvent(30.0);
  424. }
  425. timer()
  426. {
  427. llSetTimerEvent(0);
  428. if (owner_touch == 1) {
  429. llOwnerSay("Menu timeout.");
  430. llListenRemove(menu_listener);
  431. owner_touch = 0;
  432. }
  433. }
  434. listen(integer channel, string sender, key id, string msg)
  435. {
  436. if (channel == API_CHANNEL) {
  437. list data = llParseString2List(msg, ["^"], []);
  438. if (llList2String(data, 0) == "XSQuail" && llList2Key(data, 1) == llGetKey()) {
  439. say_details();
  440. }
  441. } else {
  442. if (id == llGetOwner()) {
  443. llSetTimerEvent(0);
  444. llListenRemove(menu_listener);
  445. if (msg == "Hatch") {
  446. state hatching;
  447. } else
  448. if (msg == "Package") {
  449. state package;
  450. }
  451. }
  452. }
  453. }
  454. state_exit() {
  455. llListenRemove(api_listener);
  456. }
  457. }
  458. state hatching
  459. {
  460. state_entry()
  461. {
  462. llRezObject("Quail", llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  463. }
  464. object_rez(key id)
  465. {
  466. menu_listener = llListen(EGG_CHANNEL, "", id, "");
  467. }
  468. listen(integer channel, string sender, key id, string msg)
  469. {
  470. list decrypted = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  471. if (llList2String(decrypted, 0) == "XSPET" && llList2String(decrypted, 1) == "READY" && llList2String(decrypted, 2) == (string)id) {
  472. llGiveInventory(id, "Quail");
  473. llGiveInventory(id, "XS Egg");
  474. sex = (integer)llFrand(2) + 1;
  475. llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CONFIG^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)sex + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^0^0^Quail^0^" + SPECIAL));
  476. llDie();
  477. }
  478. }
  479. }
  480. state package
  481. {
  482. state_entry() {
  483. llSetTimerEvent(20.0);
  484. llWhisper(0, "Looking for an egg cup...");
  485. menu_listener = llListen(EGG_CHANNEL, "", "", "");
  486. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CUP_PING^" + (string)VERSION));
  487. }
  488. timer()
  489. {
  490. llListenRemove(menu_listener);
  491. llSetTimerEvent(0);
  492. llWhisper(0, "No egg cup found.");
  493. state rezzed;
  494. }
  495. listen(integer channel, string sender, key id, string msg)
  496. {
  497. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  498. if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey() && llList2String(data, 2) == "CUP_PONG" && llList2Float(data, 3) >= VERSION && locked == 0) {
  499. llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + SPECIAL));
  500. locked = 1;
  501. } else
  502. if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey() && llList2String(data, 2) == "CUP_DIE") {
  503. llDie();
  504. }
  505. }
  506. }
  507. state dead
  508. {
  509. state_entry()
  510. {
  511. llSetText("Broken egg.", <1,0,0>, 1.0);
  512. }
  513. }