xs_eggcup.lsl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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:10
  6. // :ID:987
  7. // :NUM:1425
  8. // :REV:1
  9. // :WORLD:Second Life, Opensim
  10. // :DESCRIPTION:
  11. // Modified Pet Quail
  12. // :CODE:
  13. // Version 0.35 5-22-2012
  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. ///////////////////////////////////////////////
  27. // COPY FROM GLOBAL CONSTANTS FILE LOCATED IN Debug Folder
  28. // INCLUDE THESE IN ALL SCRIPTS //
  29. // XS_pet constants and names
  30. ///// GLOBAL CONSTANTS extracted from original source //////
  31. //
  32. // if you change any of these constants, change it everywhere and in a list in XS_Debug so it can print them
  33. //
  34. // 0.24 is the original Pet Quail
  35. // 0.25 is the modified Pet Quail
  36. // 0.26 is the Robot code, which is generic
  37. float VERSION = 0.25;
  38. string Animal = "Quail"; // was 'Quail', must be the name of your animal
  39. string Egg = "XS Egg"; // was 'XS Egg', must be the name of your egg
  40. string Crate = "Transport Crate"; // was XS-Cryocrate
  41. string HomeObject = "Home Post"; // was "XS Home Object
  42. string sound = "robot_sound";
  43. string SECRET_PASSWORD = "top secret"; // must use one unique to any animal
  44. integer SECRET_NUMBER = 99999; // any number thats a secret
  45. integer MaxAge = 7; // can get prggers in 7 days
  46. integer UNITS_OF_FOOD = 168; // food bowl food
  47. float secs_to_grow = 86400; // grow daily = 86400
  48. // global listeners
  49. integer FOOD_CHANNEL = -999191;
  50. integer ANIMAL_CHANNEL = -999192;
  51. integer EGG_CHANNEL = -999193;
  52. integer HOME_CHANNEL = -999194;
  53. integer BOX_CHANNEL = -999195;
  54. integer ACC_CHANNEL = -999196;
  55. integer UPDATE_CHANNEL = -999197;
  56. integer API_CHANNEL = -999198;
  57. // global prim animation linkmessages on channel 1
  58. // these are the prim animations played for each type of possible animation
  59. string ANI_STAND = "stand"; // default standing animation
  60. string ANI_WALKL = "left"; // triggers Left foot anbd righrt arm walk animation
  61. string ANI_WALKR = "right"; // triggers Right foot and left arm walk animation
  62. string ANI_SLEEP = "sleep"; // Sleeping
  63. string ANI_WAVE = "wave"; // Calling for sex, needs help with food, etc.
  64. // global link messages to control the animal
  65. integer LINK_AGE_START = 800; // when quail is rezzed and secret_number, is sent by brain to breeder, eater and informatic get booted up
  66. integer LINK_FOOD_CONSUME = 900; // from movement to brain when close to food, brain then consumes a random amount up to 10000
  67. integer LINK_FOODMINUS = 901; // xs_brain receives FOOD_CONSUME, decrement hunger (eat)
  68. integer LINK_HUNGRY = 903; // sent by eater (string)hunger_amount, checks each hour
  69. integer LINK_HAMOUNT = 904; // hunger_amount = (integer)str,m updates the hunger amount in scripts
  70. integer LINK_SET_HOME = 910; // loc ^ dist
  71. integer LINK_MOVER = 911; // tell mover to rest for str seconds
  72. integer LINK_FOODIE_CLR = 920; // clear all food_bowl_keys and contents
  73. integer LINK_FOODIE = 921; // send FOOD_LOCATION coordinates to movement
  74. integer LINK_COLOR1 = 930; // colour1
  75. integer LINK_COLOR2 = 931; // colour2
  76. integer LINK_SEX = 932; // sex
  77. integer LINK_SHINE = 933; // shine
  78. integer LINK_GLOW = 934; // glow
  79. integer LINK_GEN = 935; // generation
  80. integer LINK_RESET_SIZE = 936; // reset size to 1
  81. integer LINK_MAGE = 940; // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
  82. integer LINK_DAYTIME = 941; // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
  83. integer LINK_GET_AGE = 942; // get age from xs_ager and sent it on channel 943
  84. integer LINK_PUT_AGE = 943; // print age from xs_ager
  85. integer LINK_PACKAGE = 950; // look for a cryo_crate
  86. integer LINK_SEEK_FEMALE = 960; // MALE_BREED_CALL
  87. integer LINK_MALE_BREED_CALL = 961; // triggered by LINK_SEEK_FEMALE
  88. integer LINK_SIGNAL_ELIGIBLE = 962; // sent by female when hears LINK_MALE_BREED_CALL
  89. integer LINK_FEMALE_ELIGIBLE = 963; // sent when it hears in chat FEMALE_ELIGIBLE
  90. integer LINK_CALL_MALE = 964; // if LINK_FEMALE_ELIGIBLE && looking_for_female
  91. integer LINK_MALE_ON_THE_WAY = 965; // triggered by LINK_CALL_MALE
  92. integer LINK_FEMALE_LOCATION = 966; // female location, sends coordinates of a female
  93. integer LINK_RQST_BREED = 967; // sent when close enough to male/female
  94. integer LINK_CALL_MALE_INFO = 968; // sent by xs_breeding, this line of code was in error in v.24 of xs_breeding
  95. // see line 557 and 636 of xs_brain which make calls and also xs_breeding which receives LINK_MALE_INFO.
  96. integer LINK_MALE_INFO = 969;
  97. integer LINK_LAY_EGG = 970; // llRezObject("XS Egg"
  98. integer LINK_BREED_FAIL = 971; // key = father, failed, timed out
  99. integer LINK_PREGNANT = 972; // chick is preggers
  100. integer LINK_SLEEPING = 990; // close eyes
  101. integer LINK_UNSLEEPING = 991; // open eyes
  102. integer LINK_SOUND = 1001; // plays a sound if enabled
  103. integer LINK_SPECIAL = 1010; // xs_special, is str = "Normal", removes script
  104. integer LINK_PREGNANCY_TIME = 5000; // in seconds as str
  105. integer LINK_SLEEP = 7999; // disable sleep by parameter
  106. integer LINK_TIMER = 8000; // scan for food bowl about every 1800 seconds
  107. integer LINK_DIE = 9999; // death
  108. ///////// end global Link constants ////////
  109. ////////////////////////////////////////////////////////////////////
  110. // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
  111. integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  112. integer xtea_num_rounds = 6;
  113. list xtea_key = [0, 0, 0, 0];
  114. integer hex2int(string hex) {
  115. if(llGetSubString(hex,0,1) == "0x")
  116. return (integer)hex;
  117. if(llGetSubString(hex,0,0) == "x")
  118. return (integer)("0"+hex);
  119. return(integer)("0x"+hex);
  120. }
  121. // Convers any string to a 32 char MD5 string and then to a list of
  122. // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
  123. // 128 bit key is generated for any string passed.
  124. list xtea_key_from_string( string str )
  125. {
  126. str = llMD5String(str,0); // Use Nonce = 0
  127. return [ hex2int(llGetSubString( str, 0, 7)),
  128. hex2int(llGetSubString( str, 8, 15)),
  129. hex2int(llGetSubString( str, 16, 23)),
  130. hex2int(llGetSubString( str, 24, 31))];
  131. }
  132. // Encipher two integers and return the result as a 12-byte string
  133. // containing two base64-encoded integers.
  134. string xtea_encipher( integer v0, integer v1 )
  135. {
  136. integer num_rounds = xtea_num_rounds;
  137. integer sum = 0;
  138. do {
  139. // LSL does not have unsigned integers, so when shifting right we
  140. // have to mask out sign-extension bits.
  141. v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  142. sum += XTEA_DELTA;
  143. v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
  144. } while( num_rounds = ~-num_rounds );
  145. //return only first 6 chars to remove "=="'s and compact encrypted text.
  146. return llGetSubString(llIntegerToBase64(v0),0,5) +
  147. llGetSubString(llIntegerToBase64(v1),0,5);
  148. }
  149. // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  150. // each as one 10-byte base64-encoded string.
  151. string xtea_decipher( integer v0, integer v1 )
  152. {
  153. integer num_rounds = xtea_num_rounds;
  154. integer sum = XTEA_DELTA*xtea_num_rounds;
  155. do {
  156. // LSL does not have unsigned integers, so when shifting right we
  157. // have to mask out sign-extension bits.
  158. v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
  159. sum -= XTEA_DELTA;
  160. v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
  161. } while ( num_rounds = ~-num_rounds );
  162. return llGetSubString(llIntegerToBase64(v0), 0, 4) +
  163. llGetSubString(llIntegerToBase64(v1), 0, 4);
  164. }
  165. // Encrypt a full string using XTEA.
  166. string xtea_encrypt_string( string str )
  167. {
  168. // encode string
  169. str = llStringToBase64(str);
  170. // remove trailing =s so we can do our own 0 padding
  171. integer i = llSubStringIndex( str, "=" );
  172. if ( i != -1 )
  173. str = llDeleteSubString( str, i, -1 );
  174. // we don't want to process padding, so get length before adding it
  175. integer len = llStringLength(str);
  176. // zero pad
  177. str += "AAAAAAAAAA=";
  178. string result;
  179. i = 0;
  180. do {
  181. // encipher 30 (5*6) bits at a time.
  182. result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
  183. i+=10;
  184. } while ( i < len );
  185. return result;
  186. }
  187. // Decrypt a full string using XTEA
  188. string xtea_decrypt_string( string str ) {
  189. integer len = llStringLength(str);
  190. integer i=0;
  191. string result;
  192. //llOwnerSay(str);
  193. do {
  194. integer v0;
  195. integer v1;
  196. v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  197. i+= 6;
  198. v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
  199. i+= 6;
  200. result += xtea_decipher(v0, v1);
  201. } while ( i < len );
  202. // Replace multiple trailing zeroes with a single one
  203. i = llStringLength(result) - 1;
  204. while ( llGetSubString(result, i - 1, i) == "AA" ){
  205. result = llDeleteSubString(result, i, i);
  206. i--;
  207. }
  208. i = llStringLength(result) - 1;
  209. // while (llGetSubString(result, i, i + 1) == "A" ) {
  210. // i--;
  211. // }
  212. result = llGetSubString(result, 0, i+1);
  213. i = llStringLength(result);
  214. integer mod = i%4; //Depending on encoded length diffrent appends are needed
  215. if(mod == 1) result += "A==";
  216. else if(mod == 2 ) result += "==";
  217. else if(mod == 3) result += "=";
  218. return llBase64ToString(result);
  219. }
  220. string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  221. // tunables
  222. integer up_down = FALSE ; // set to TRUE to rez above the egg cup, set to false to rez below the UFO
  223. vector colour1;
  224. vector colour2;
  225. integer gen;
  226. integer shine;
  227. float glow;
  228. key uuid;
  229. integer listener;
  230. integer owner_touch;
  231. string special;
  232. say_details()
  233. {
  234. string myshine;
  235. if (shine == 0) {
  236. myshine = "None";
  237. } else
  238. if (shine == 1) {
  239. myshine = "Low";
  240. } else
  241. if (shine == 2) {
  242. myshine = "Medium";
  243. } else
  244. if (shine == 3) {
  245. myshine = "High";
  246. }
  247. llWhisper(0, "Color: " + (string)colour1);
  248. llWhisper(0, "Color: " + (string)colour2);
  249. llWhisper(0, "Shine: " + myshine);
  250. llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
  251. llWhisper(0, "Special: " + special);
  252. llWhisper(0, "Generation: " + (string)gen);
  253. llSay(API_CHANNEL, "XSQuail^" + (string)llGetKey() + "^"+ (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^XSQuailEnd");
  254. }
  255. set_colours(vector c1, vector c2, integer shine, float glow)
  256. {
  257. llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  258. llSetLinkPrimitiveParams(3, [PRIM_COLOR, ALL_SIDES, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
  259. }
  260. default
  261. {
  262. state_entry()
  263. {
  264. xtea_key = xtea_key_from_string(SECRET_PASSWORD);
  265. uuid = NULL_KEY;
  266. listener = llListen(BOX_CHANNEL, "", "", "");
  267. }
  268. listen(integer channel, string name, key id, string msg)
  269. {
  270. if (llGetOwnerKey(id) != llGetOwner()) {
  271. return;
  272. }
  273. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  274. if (uuid == NULL_KEY) {
  275. if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "CUP_PING") {
  276. uuid = id;
  277. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^CUP_PONG^" + (string)VERSION));
  278. llSetTimerEvent(15.0);
  279. }
  280. } else if (uuid == id) {
  281. if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey()) {
  282. llSetTimerEvent(0.0);
  283. colour1 = (vector)llList2String(data, 2);
  284. colour2 = (vector)llList2String(data, 3);
  285. shine = llList2Integer(data, 4);
  286. glow = llList2Float(data, 5);
  287. gen = llList2Integer(data, 6);
  288. special = llList2String(data, 7);
  289. llListenRemove(listener);
  290. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^CUP_DIE^"));
  291. state full;
  292. } else
  293. if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) != llGetKey()) {
  294. uuid = NULL_KEY;
  295. }
  296. }
  297. }
  298. timer()
  299. {
  300. llSetTimerEvent(0.0);
  301. uuid = NULL_KEY;
  302. }
  303. }
  304. state full
  305. {
  306. state_entry()
  307. {
  308. string my_special = "";
  309. if (special != "Normal") {
  310. my_special = "(" + special + ") ";
  311. }
  312. llSetObjectName("XS Egg Cup: " + my_special + "S:" + (string)shine + " G:" + (string)((integer)(glow * 100)) + "% <" + llGetSubString((string)colour1.x, 0, 3) + "," + llGetSubString((string)colour1.y, 0, 3) + "," + llGetSubString((string)colour1.z, 0, 3) + ">/<" + llGetSubString((string)colour2.x, 0, 3) + "," + llGetSubString((string)colour2.y, 0, 3) + "," + llGetSubString((string)colour2.z, 0, 3) + ">");
  313. set_colours(colour1, colour2, shine, glow);
  314. llListen(API_CHANNEL, "", "", "");
  315. if (special != "Normal") {
  316. llSetText(special, <1,1,1>, 1.0);
  317. }
  318. }
  319. touch_start(integer num)
  320. {
  321. owner_touch = 0;
  322. say_details();
  323. if (llDetectedKey(0) == llGetOwner()) {
  324. owner_touch = 1;
  325. integer chan = (integer)llFrand(10000.0) + 1000;
  326. listener = llListen(chan, "", llGetOwner(), "");
  327. llDialog(llGetOwner(), "Would you like to unpackage me?", ["Yes", "No"], chan);
  328. }
  329. llSetTimerEvent(20.0);
  330. }
  331. timer()
  332. {
  333. //llOwnerSay("Menu timeout.");
  334. if (owner_touch == 1) {
  335. llListenRemove(listener);
  336. }
  337. llSetTimerEvent(0.0);
  338. }
  339. listen(integer channel, string name, key id, string msg)
  340. {
  341. if (channel == API_CHANNEL) {
  342. list data = llParseString2List(msg, ["^"], []);
  343. if (llList2String(data, 0) == "XSQuail" && llList2Key(data, 1) == llGetKey()) {
  344. llSay(API_CHANNEL, "XSQuail^" + (string)llGetKey() + "^"+ (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^XSQuailEnd");
  345. }
  346. } else {
  347. llListenRemove(listener);
  348. if (msg == "Yes") {
  349. state unbox;
  350. }
  351. }
  352. }
  353. }
  354. state unbox
  355. {
  356. state_entry()
  357. {
  358. listener = llListen(BOX_CHANNEL, "", "", "");
  359. if (up_down)
  360. llRezObject(Egg, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  361. else
  362. {
  363. llMessageLinked(LINK_SET,-2000,"",""); // turn on the particle effects
  364. llRezObject(Egg, llGetPos() + <0.0, 0.0,-0.1>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
  365. }
  366. }
  367. object_rez(key id)
  368. {
  369. vector pos = llGetPos();
  370. pos.z += .2;
  371. llSetPos(pos);
  372. }
  373. listen(integer channel, string name, key id, string msg)
  374. {
  375. if (channel == BOX_CHANNEL) {
  376. list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
  377. if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "EGG_READY") {
  378. llGiveInventory(id, Egg );
  379. llGiveInventory(id, Animal);
  380. llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^UNBOX^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)gen + "^" + (string)shine + "^" + (string)glow + "^" + special));
  381. llDie();
  382. }
  383. }
  384. }
  385. }