| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- // :CATEGORY:XS Pet
- // :NAME:XS Pet Xundra Snowpaw Original Quail
- // :AUTHOR:Xundra Snowpaw
- // :CREATED:2013-09-06
- // :EDITED:2013-09-18 15:39:11
- // :ID:989
- // :NUM:1479
- // :REV:1
- // :WORLD:Second Life, Opensim
- // :DESCRIPTION:
- // Original Pet Quail
- // :CODE:
- float VERSION = 0.22;
- integer API_CHANNEL = -999198;
- string SECRET_PASSWORD = "top secret";
- integer SECRET_NUMBER = 99999;
- key YOUR_UUID = "00000000-0000-0000-0000-000000000000";
- integer ANIMAL_CHANNEL = -999192;
- integer EGG_CHANNEL = -999193;
- integer BOX_CHANNEL = -999195;
- string SPECIAL = "Normal";
- //integer TIME_TO_HATCH = 7200;
- // DON'T CHANGE THE FOLLOWING! (Unless you know what you are doing!)
- integer XTEA_DELTA = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
- integer xtea_num_rounds = 6;
- list xtea_key = [0, 0, 0, 0];
-
- integer hex2int(string hex) {
- if(llGetSubString(hex,0,1) == "0x")
- return (integer)hex;
- if(llGetSubString(hex,0,0) == "x")
- return (integer)("0"+hex);
- return(integer)("0x"+hex);
- }
-
-
- // Convers any string to a 32 char MD5 string and then to a list of
- // 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
- // 128 bit key is generated for any string passed.
- list xtea_key_from_string( string str )
- {
- str = llMD5String(str,0); // Use Nonce = 0
- return [ hex2int(llGetSubString( str, 0, 7)),
- hex2int(llGetSubString( str, 8, 15)),
- hex2int(llGetSubString( str, 16, 23)),
- hex2int(llGetSubString( str, 24, 31))];
- }
-
- // Encipher two integers and return the result as a 12-byte string
- // containing two base64-encoded integers.
- string xtea_encipher( integer v0, integer v1 )
- {
- integer num_rounds = xtea_num_rounds;
- integer sum = 0;
- do {
- // LSL does not have unsigned integers, so when shifting right we
- // have to mask out sign-extension bits.
- v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
- sum += XTEA_DELTA;
- v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
-
- } while( num_rounds = ~-num_rounds );
- //return only first 6 chars to remove "=="'s and compact encrypted text.
- return llGetSubString(llIntegerToBase64(v0),0,5) +
- llGetSubString(llIntegerToBase64(v1),0,5);
- }
-
- // Decipher two base64-encoded integers and return the FIRST 30 BITS of
- // each as one 10-byte base64-encoded string.
- string xtea_decipher( integer v0, integer v1 )
- {
- integer num_rounds = xtea_num_rounds;
- integer sum = XTEA_DELTA*xtea_num_rounds;
- do {
- // LSL does not have unsigned integers, so when shifting right we
- // have to mask out sign-extension bits.
- v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
- sum -= XTEA_DELTA;
- v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
- } while ( num_rounds = ~-num_rounds );
-
- return llGetSubString(llIntegerToBase64(v0), 0, 4) +
- llGetSubString(llIntegerToBase64(v1), 0, 4);
- }
-
- // Encrypt a full string using XTEA.
- string xtea_encrypt_string( string str )
- {
- // encode string
- str = llStringToBase64(str);
- // remove trailing =s so we can do our own 0 padding
- integer i = llSubStringIndex( str, "=" );
- if ( i != -1 )
- str = llDeleteSubString( str, i, -1 );
-
- // we don't want to process padding, so get length before adding it
- integer len = llStringLength(str);
-
- // zero pad
- str += "AAAAAAAAAA=";
-
- string result;
- i = 0;
-
- do {
- // encipher 30 (5*6) bits at a time.
- result += xtea_encipher(llBase64ToInteger(llGetSubString(str, i, i + 4) + "A="), llBase64ToInteger(llGetSubString(str, i+5, i + 9) + "A="));
- i+=10;
- } while ( i < len );
-
- return result;
- }
-
- // Decrypt a full string using XTEA
- string xtea_decrypt_string( string str ) {
- integer len = llStringLength(str);
- integer i=0;
- string result;
- //llOwnerSay(str);
- do {
- integer v0;
- integer v1;
-
- v0 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
- i+= 6;
- v1 = llBase64ToInteger(llGetSubString(str, i, i + 5) + "==");
- i+= 6;
-
- result += xtea_decipher(v0, v1);
- } while ( i < len );
-
- // Replace multiple trailing zeroes with a single one
- i = llStringLength(result) - 1;
- while ( llGetSubString(result, i - 1, i) == "AA" ){
- result = llDeleteSubString(result, i, i);
- i--;
- }
- i = llStringLength(result) - 1;
- // while (llGetSubString(result, i, i + 1) == "A" ) {
- // i--;
- // }
- result = llGetSubString(result, 0, i+1);
- i = llStringLength(result);
- integer mod = i%4; //Depending on encoded length diffrent appends are needed
- if(mod == 1) result += "A==";
- else if(mod == 2 ) result += "==";
- else if(mod == 3) result += "=";
-
- return llBase64ToString(result);
- }
-
- string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- vector colour1;
- vector colour2;
- integer sex;
- integer gen;
- integer shine;
- float glow;
- integer api_listener;
- integer locked;
- integer born_hatched;
- integer owner_touch;
- integer menu_listener;
- set_colours(vector c1, vector c2, integer shine, float glow)
- {
- llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
- llSetLinkPrimitiveParams(2, [PRIM_COLOR, ALL_SIDES, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
- }
- say_details()
- {
-
- string myshine;
- if (shine == 0) {
- myshine = "None";
- } else
- if (shine == 1) {
- myshine = "Low";
- } else
- if (shine == 2) {
- myshine = "Medium";
- } else
- if (shine == 3) {
- myshine = "High";
- }
-
- llWhisper(0, "Head/Body Colour: " + (string)colour1);
- llWhisper(0, "Tail/Wing Colour: " + (string)colour2);
- llWhisper(0, "Shine: " + myshine);
- llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
- llWhisper(0, "Special: " + SPECIAL);
- llWhisper(0, "Generation: " + (string)gen);
- llSay(API_CHANNEL, "XSQuail^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + SPECIAL + "^" + (string)gen + "^XSQuailEnd");
- }
- default
- {
- state_entry()
- {
- llSetText("", <1,1,1>, 1.0);
- llSetColor(<1,1,1>, ALL_SIDES);
- llSetLinkColor(2, <1,1,1>, ALL_SIDES);
- llParticleSystem([]);
- xtea_key = xtea_key_from_string(SECRET_PASSWORD);
- }
-
- changed(integer change) {
- if (change & CHANGED_ALLOWED_DROP) {
- if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
- llAllowInventoryDrop(FALSE);
- }
- }
- }
-
- on_rez(integer param)
- {
- llSetText("Rezzing...", <1,0,0>, 1.0);
-
- llSleep(5.0);
-
- if (param == 0) {
- if (llGetOwner() == YOUR_UUID) {
- integer colour = (integer)llFrand(9.0) + 1;
- if (colour == 1) {
- colour1 = <1,0,0>;
- colour2 = <1,0,0>;
- } else
- if (colour == 2) {
- colour1 = <1,0,0>;
- colour2 = <0,1,0>;
- } else
- if (colour == 3) {
- colour1 = <1,0,0>;
- colour2 = <0,0,1>;
- } else
- if (colour == 4) {
- colour1 = <0,1,0>;
- colour2 = <1,0,0>;
- } else
- if (colour == 5) {
- colour1 = <0,1,0>;
- colour2 = <0,1,0>;
- } else
- if (colour == 6) {
- colour1 = <0,1,0>;
- colour2 = <0,0,1>;
- } else
- if (colour == 7) {
- colour1 = <0,0,1>;
- colour2 = <1,0,0>;
- } else
- if (colour == 8) {
- colour1 = <0,0,1>;
- colour2 = <0,1,0>;
- } else
- if (colour == 9) {
- colour1 = <0,0,1>;
- colour2 = <0,0,1>;
- }
-
-
- set_colours(colour1, colour2, shine, glow);
- state rezzed;
- } else {
- llWhisper(0, "Oh no! This egg was broken in your inventory! Please use an egg-cup next time.");
- state dead;
- }
- } else
- if (param == SECRET_NUMBER) {
- menu_listener = llListen(EGG_CHANNEL, "", "", "");
- if (llGetOwner() != YOUR_UUID) {
- llAllowInventoryDrop(TRUE);
- }
- llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^EGG_READY^" + (string)llGetKey() + "^SMILE"));
- llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^EGG_READY^SMILE"));
- }
- }
- listen(integer channel, string sender, key id, string msg) {
- list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
- if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey()) {
- if (llList2String(data, 2) == "UNBOX") {
- colour1 = (vector)llList2String(data, 3);
- colour2 = (vector)llList2String(data, 4);
-
- gen = llList2Integer(data,5);
- shine = llList2Integer(data, 6);
- glow = llList2Float(data, 7);
- SPECIAL = llList2String(data, 8);
-
- llListenRemove(menu_listener);
-
- set_colours(colour1, colour2, shine, glow);
- state rezzed;
- } else
- if (llList2String(data, 2) == "BORN") {
- vector fcolour1 = (vector)llList2String(data, 3);
- vector fcolour2 = (vector)llList2String(data, 4);
-
- integer fgen = llList2Integer(data,5);
- integer fshine = llList2Integer(data, 6);
- float fglow = llList2Float(data, 7);
- integer fglow_gene = llList2Integer(data, 8);
-
- vector mcolour1 = (vector)llList2String(data, 9);
- vector mcolour2 = (vector)llList2String(data, 10);
-
- integer mgen = llList2Integer(data, 11);
- integer mshine = llList2Integer(data, 12);
- float mglow = llList2Float(data, 13);
- integer mglow_gene = llList2Integer(data, 14);
-
- integer mix = (integer)llFrand(2) + 1;
-
- float deviation1 = (llFrand(10) - 5) / 100;
- float deviation2 = (llFrand(10) - 5) / 100;
- if (mix == 1) {
- colour1.x = (fcolour1.x / 2 + mcolour1.x / 2) + deviation1;
- colour1.y = (fcolour1.y / 2 + mcolour1.y / 2) + deviation1;
- colour1.z = (fcolour1.z / 2 + mcolour1.z / 2) + deviation1;
-
- colour2.x = (fcolour2.x / 2 + mcolour2.x / 2) + deviation2;
- colour2.y = (fcolour2.y / 2 + mcolour2.y / 2) + deviation2;
- colour2.z = (fcolour2.z / 2 + mcolour2.z / 2) + deviation2;
- } else {
- colour1.x = (fcolour1.x / 2 + mcolour2.x / 2) + deviation1;
- colour1.y = (fcolour1.y / 2 + mcolour2.y / 2) + deviation1;
- colour1.z = (fcolour1.z / 2 + mcolour2.z / 2) + deviation1;
-
- colour2.x = (fcolour2.x / 2 + mcolour1.x / 2) + deviation2;
- colour2.y = (fcolour2.y / 2 + mcolour1.y / 2) + deviation2;
- colour2.z = (fcolour2.z / 2 + mcolour1.z / 2) + deviation2;
- }
-
- if (colour1.x < 0)
- colour1.x = 0;
-
- if (colour1.x > 1)
- colour1.x = 1;
- if (colour1.y < 0)
- colour1.y = 0;
-
- if (colour1.y > 1)
- colour1.y = 1;
- if (colour1.z < 0)
- colour1.z = 0;
-
- if (colour1.z > 1)
- colour1.z = 1;
- if (colour2.x < 0)
- colour2.x = 0;
-
- if (colour2.x > 1)
- colour2.x = 1;
-
- if (colour2.y < 0)
- colour2.y = 0;
-
- if (colour2.y > 1)
- colour2.y = 1;
- if (colour2.z < 0)
- colour2.z = 0;
-
- if (colour2.z > 1)
- colour2.z = 1;
-
- if (mgen > fgen) {
- gen = mgen + 1;
- } else {
- gen = fgen + 1;
- }
-
- // TODO: shine / glow
- shine = 0;
- if (gen > 2) {
- integer pos = (integer)llFrand(100) + 1;
- if (fshine == mshine && fshine > 0) {
- if (pos < 25) {
- shine = fshine + 1;
- if (shine > 3) {
- shine = 3;
- }
- }
- } else {
- if (pos < 10) {
- // increase shine
- if (mshine > fshine) {
- shine = mshine + 1;
- } else
- if (fshine > mshine) {
- shine = fshine + 1;
- } else {
- shine = 1;
- }
- if (shine > 3) {
- shine = 3;
- }
- }
- }
- }
- glow = 0.0;
-
- if (mglow <= 0.3 && fglow <= 0.3) {
- if (mglow > fglow) {
- glow = mglow - 0.1;
- } else if (fglow > mglow) {
- glow = fglow - 0.1;
- }
- }
-
- if (fglow_gene >= 10 && mglow_gene >= 10) {
- integer poss = (integer)llFrand(100) + 1;
- if (poss < 25) {
- glow = 0.3;
- }
- } else if (fglow_gene >= 10 || mglow_gene >= 10) {
- integer poss = (integer)llFrand(100) + 1;
- if (poss < 10) {
- glow = 0.3;
- }
- }
-
-
-
- llListenRemove(menu_listener);
- born_hatched = 1;
- set_colours(colour1, colour2, shine, glow);
- llSetTimerEvent(1.0);
- }
- }
- }
- timer() {
- if (llGetInventoryType("Quail") != INVENTORY_NONE && llGetInventoryType("XS Egg") != INVENTORY_NONE) {
- state rezzed;
- }
- }
- }
- state rezzed
- {
- on_rez(integer param)
- {
- if (llGetOwner() != YOUR_UUID) {
- llWhisper(0, "Oh no! This egg was broken in your inventory! Please use an egg-cup next time.");
- state dead;
- }
- }
-
- state_entry()
- {
- if (SPECIAL == "Normal") {
- llSetText("", <1,1,1>, 1.0);
- } else {
- llSetText(SPECIAL, <1,1,1>, 1.0);
- }
- api_listener = llListen(API_CHANNEL, "", "", "");
- }
-
- touch_start(integer num)
- {
- owner_touch = 0;
- say_details();
-
- if (llDetectedKey(0) == llGetOwner()) {
- owner_touch = 1;
- integer chan = (integer)llFrand(100000.0) + 1000;
- menu_listener = llListen(chan, "", llGetOwner(), "");
- llDialog(llGetOwner(), "I'm an egg. What would you like to do with me?", ["Hatch", "Package", "Nothing"], chan);
- }
- llSetTimerEvent(30.0);
- }
-
- timer()
- {
- llSetTimerEvent(0);
-
- if (owner_touch == 1) {
- llOwnerSay("Menu timeout.");
- llListenRemove(menu_listener);
- owner_touch = 0;
- }
- }
-
- listen(integer channel, string sender, key id, string msg)
- {
- if (channel == API_CHANNEL) {
- list data = llParseString2List(msg, ["^"], []);
- if (llList2String(data, 0) == "XSQuail" && llList2Key(data, 1) == llGetKey()) {
- say_details();
- }
- } else {
- if (id == llGetOwner()) {
- llSetTimerEvent(0);
- llListenRemove(menu_listener);
-
- if (msg == "Hatch") {
- state hatching;
- } else
- if (msg == "Package") {
- state package;
- }
- }
- }
- }
-
- state_exit() {
- llListenRemove(api_listener);
- }
- }
- state hatching
- {
-
- state_entry()
- {
- llRezObject("Quail", llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
- }
-
- object_rez(key id)
- {
- menu_listener = llListen(EGG_CHANNEL, "", id, "");
- }
-
- listen(integer channel, string sender, key id, string msg)
- {
- list decrypted = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
- if (llList2String(decrypted, 0) == "XSPET" && llList2String(decrypted, 1) == "READY" && llList2String(decrypted, 2) == (string)id) {
- llGiveInventory(id, "Quail");
- llGiveInventory(id, "XS Egg");
-
- sex = (integer)llFrand(2) + 1;
-
- 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));
- llDie();
- }
- }
- }
- state package
- {
- state_entry() {
- llSetTimerEvent(20.0);
- llWhisper(0, "Looking for an egg cup...");
- menu_listener = llListen(EGG_CHANNEL, "", "", "");
- llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CUP_PING^" + (string)VERSION));
- }
- timer()
- {
- llListenRemove(menu_listener);
- llSetTimerEvent(0);
-
- llWhisper(0, "No egg cup found.");
- state rezzed;
- }
-
- listen(integer channel, string sender, key id, string msg)
- {
- list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
- if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey() && llList2String(data, 2) == "CUP_PONG" && llList2Float(data, 3) >= VERSION && locked == 0) {
- llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + SPECIAL));
- locked = 1;
- } else
- if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey() && llList2String(data, 2) == "CUP_DIE") {
- llDie();
- }
- }
- }
- state dead
- {
- state_entry()
- {
- llSetText("Broken egg.", <1,0,0>, 1.0);
- }
- }
|