• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

XS Pets

Laraxa

Nutzer
Hallo!

ich habe mir mal die Seite von XS Pets angesehen und fande sie sehr interessant. Habe aber ein paar Probleme und hoffe das hier mir vll. jemand helfen kann.
Hat jemand mit dieser Seite schon Erfahrungen machen können oder wäre bereit mir zu helfen?

Link: http://metaverse.mitsi.com/Secondlife/Posts/Breedable-pet-robot/default.htm

Folgende Probleme habe ich:

Texture Server: Er läuft bei mir nicht richtig, er soll 7 prims von der Textur her wechseln, alle 7 prims haben verschiedene Texturen.
Er wechselt allerdings nur 1 Prim und nicht alle 7.

Gibt es hier Scripter die mir helfen könnten oder vll. auch das ein oder andere Script auf meine Bedürfnisse umzuschreiben?

wie z.B. die Status Werte eines Tieres, Nest Informationen etc.

Wäre euch sehr Dankbar wenn ihr mir helft :)

mfg Laraxa
 
Mit dem Texturen Server hat es sich erledigt. Er funktioniert jetzt.

Ist jetzt noch eine Frage offen.....

Kennt sich jemand mit Scripts aus und könnte Scripte abändern?
z.B. das man zusätzliche Status Werte eines Tieres reinbekommt?

Oder wäre sogar jemand bereit mir ein komplettes Breedable System zu scripten?
Würde auch entspechend dafür bezahlen, wenn alles funktioniert.
 
Hallo!

Ich hoffe das mir doch noch jemand helfen könnte bei der Erstellung meiner Zuchttiere. Ich bin nicht in SL, sondern auf einer OpenSim.
Ich habe gleich mehrere anliegen und hoffe das es nicht zuviel aufeinmal ist, aber ich bin keine scripterin und kenne mich da also so gut wie nicht aus.

Schritt 1: Ich möchte entsprechende Status Werte für das Tier haben. Diese Werte sollten zum Tier angezeigt werden und am besten auch auf dem Nest.

1. Besitzer (Wer der Besitzer vom Tier bzw. Nest ist.
2. Female oder Male
3. Alter
4. Hunger
5. Rasse (Welche Fellart das Tier hat)
6. Augen (welche Augenfarbe das Tier hat)
7. Ohren (Welche Art von Ohren das Tier hat) - Bin ich mir nicht sicher ob das mit diesen scripten überhaupt möglich ist.


Ich gebe euch hier eine Liste der scripte die ich besitze. ich weiß nicht wo was geändert werden müsste. habe aber alle Scripte Full Perm in meinem Besitz legal erworben. In diesen Scripten sind auch Werte drin die unbedingt raus müssen wie z.B. Color1, Color2 etc.
Ich möchte mit Texturen Arbeiten und nicht mit Farben, da man mit Texturen einfach mehr Spielraum hat als mit Farben.
Einen Textur Server habe ich soweit schon eingerichtet und Funktioniert auch.

Script Liste:

Tier Scripte:
ager
breeding
movement
eater
brain
information
special
sex

Nest Scripte:
egg (Kommt ins Ei rein)
color-plugin
cryogate (kommt in die Transportbox für den Anfang, danach nie wieder gebrauchbar)
eggcup (kommt in die endstufe der Transport Box rein, danach nie wieder gebrauchbar)

Home Script:
home (Der Punkt an dem sich die Tiere binden)

Futter Scripte:
food
food animation

Server Script:
Texture Server (Kommt in ein seperaten Prim mit der Notcard und entsprechenden Texturen rein)
Texture Plugin (Kommt in das Tier rein, damit es mit dem Server kommunizieren kann und ändert entsprechend die Fell Art des Tieres)

Hier jetzt der Inhalt dieser Scripte:

ager:
Code:
///////////////////////

// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE










integer age;                // age in days
float   cur_scale = 1.0;
list link_scales = [];
list link_positions = [];



integer scanLinkset()
{
    integer link_qty = llGetNumberOfPrims();
    integer link_idx;
    vector link_pos;
    vector link_scale;

    //script made specifically for linksets, not for single prims
    if (link_qty > 1)
    {
        //link numbering in linksets starts with 1
        for (link_idx=1; link_idx <= link_qty; link_idx++)
        {
            link_pos=llList2Vector(llGetLinkPrimitiveParams(link_idx,[PRIM_POSITION]),0);
            link_scale=llList2Vector(llGetLinkPrimitiveParams(link_idx,[PRIM_SIZE]),0);

            link_scales    += [link_scale];
            link_positions += [(link_pos-llGetRootPosition())/llGetRootRotation()];
        }
    }
    else
    {
        llOwnerSay("error: this script doesn't work for non-linked objects");
        return FALSE;
    }


    return TRUE;
}

resizeObject(float scale)
{
    integer link_qty = llGetNumberOfPrims();
    integer link_idx;
    vector new_size;
    vector new_pos;

    if (link_qty > 1)
    {
        //link numbering in linksets starts with 1
        for (link_idx=1; link_idx <= link_qty; link_idx++)
        {
            new_size   = scale * llList2Vector(link_scales, link_idx-1);
            new_pos    = scale * llList2Vector(link_positions, link_idx-1);

            if (link_idx == 1)
            {
                //because we don't really want to move the root prim as it moves the whole object
                llSetLinkPrimitiveParamsFast(link_idx, [PRIM_SIZE, new_size]);
            }
            else
            {
                llSetLinkPrimitiveParamsFast(link_idx, [PRIM_SIZE, new_size, PRIM_POSITION, new_pos]);
            }
        }
    }
}

default
{
    state_entry()
    {
        scanLinkset();
        age = 0;
    }


    timer()
    {
        llMessageLinked(LINK_SET, LINK_MAGE, "1", "");
    }

     // Version 0.44 7-19-2013 Age growth bug in xs_ager, pets were not increasing in size
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_GET_AGE) {
            llMessageLinked(LINK_SET, LINK_PUT_AGE, (string)age, "");
        } else
        if (num == LINK_DAYTIME) {
            llSetTimerEvent(secs_to_grow); // 86400.0
        } else
        if (num == LINK_RESET_SIZE)
        {
            cur_scale = 1.0;
            resizeObject(cur_scale);
            age = 0;
        }
        if (num == LINK_MAGE) {

            integer wasAge = age;         // fix for not growing is size if > 7 days

            age += (integer) str;        // add 1, typically

            // grow to the correct proportion

            llMessageLinked(LINK_SET, LINK_MOVER, "1", ""); // tell mover to rest for 1 seconds

            integer loop = (integer) str;
            
            if (loop > MaxAge)
                loop = MaxAge;

            if (age > MaxAge && wasAge != 0)    // fix for not growing is size if > 7 days
                    return;
            
            
            while (loop--) {        // age growth bug, was --loop
                cur_scale = cur_scale * (GROWTH_AMOUNT + 1.0);     // new size is 110%, 120%, etc of the original size unless we are reborn 
            }
            DEBUG("Growing " + (string) cur_scale);

            resizeObject(cur_scale);
        }
    }
}
 
breeding:
Code:
// tunable for this script
float TIME_TO_WAIT = 86400; // 86400 secs = wait 1 day to get fertile again.





// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE












// globals
integer age;                // age in days, starting at 0
integer looking_for_female;

key father;
key mother;

integer preg_time;

default
{
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_AGE_START) {
            state running;
        }
    }
}

state running
{
    state_entry()
    {
        age = 0;
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_SEX) {
            if (str == "1") {
                state male;
            } else {
                    state female;
            }
        } else
        if (num == LINK_MAGE) {
            age += (integer)str;
        } else
        if (num == LINK_PREGNANCY_TIME) {
            preg_time = (integer)str;
            if (preg_time != 0) {
                state pregnant;
            } else {
                    state female;
            }
        }
    }
}

state male
{
    state_entry()
    {
        looking_for_female = 0;

        mother = NULL_KEY;
        father = NULL_KEY;

        llMessageLinked(LINK_SET, LINK_GET_AGE, "", "");

        if (age >= fDaysToAdult) {
            llSetTimerEvent(SEX_WAIT);    // 3 hours
        }
    }
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_PUT_AGE) {
            age = (integer)str;
            if (age >= fDaysToAdult) {
                llSetTimerEvent(SEX_WAIT);
            }
        } else
        if (num == LINK_MAGE) {

            age += (integer)str;
            if (age >= fDaysToAdult) {
                llSetTimerEvent(SEX_WAIT);    // look ebvery 3 hours for a female
            }
        } else
        if (num == LINK_FEMALE_ELIGIBLE) {
            if (looking_for_female == 1) {
                looking_for_female = 0;
                mother = id;
                father = llGetKey();
                llMessageLinked(LINK_SET, LINK_CALL_MALE, "", mother);
            }
        } else
        if (num == LINK_RQST_BREED) {
            if (mother != NULL_KEY) {
                llMessageLinked(LINK_SET, LINK_CALL_MALE_INFO, "", mother);          // V0.25 fix error by Ferd, was LINK_CALL_MALE, should be LINK_CALL_MALE_INFO
            }
        } else
        if (num == LINK_MALE_INFO) {
            state male;
        }

    }

    timer()
    {
        looking_for_female = 1;
        // look for an eligible female.
        llWhisper(0, llGetObjectName() + " gets a gleam in his eye.");
        llMessageLinked(LINK_SET, LINK_SEEK_FEMALE, "", "");
    }
}

state female
{
    state_entry()
    {
        mother = NULL_KEY;
        father = NULL_KEY;

        if (age == 0) {
            llMessageLinked(LINK_SET, LINK_GET_AGE, "", "");
        }
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_MAGE) {
            age += (integer)str;        // add to age
        } else
        if (num == LINK_MALE_BREED_CALL) {
            // signal I am eligible
            if (age >= fDaysToAdult && father == NULL_KEY) {
                llWhisper(0, llGetObjectName() + " blushes then bobs her head up and down.");
                llMessageLinked(LINK_SET, LINK_SIGNAL_ELIGIBLE, "", "");
            }
        } else
        if (num == LINK_MALE_ON_THE_WAY) {
            // male on the way, timeout in 15 minutes
            llSetTimerEvent(MALE_TIMEOUT);        // 20 minutes
            father = id;        // was on a line by itself, probably a nasty bug
            mother = llGetKey();
            llMessageLinked(LINK_SET, LINK_MOVER, (string) MALE_TIMEOUT, "");        // tell mover to rest for 20 minutes
        } else
        if (num == LINK_PREGNANT) {
            // pregnant
            llSetTimerEvent(0);
            preg_time = 0;
            state pregnant;
        } else
        if (num == LINK_MALE_INFO) {
            llSetTimerEvent(0);
            state female;
        } else
        if (num == LINK_PUT_AGE) {
            age = (integer)str;
        } else
        if (num == LINK_PREGNANCY_TIME) {
            preg_time = (integer)str;
            if (preg_time != 0) {
                state pregnant;
            }
        }

    }

    timer()
    {
        llSetTimerEvent(0);
        // fail
        llMessageLinked(LINK_SET, LINK_BREED_FAIL, "", father);
        state female;
    }
}

state pregnant
{
    state_entry()
    {
        if (preg_time != 0) {
            llSetTimerEvent(fPregnancy - (float)(llGetUnixTime() - preg_time));
        } else {
           llSetTimerEvent(fPregnancy);
        }
    }
    timer()
    {
        // lay egg.
        llSetTimerEvent(0);
        llMessageLinked(LINK_SET, LINK_LAY_EGG, "", "");
        state Wait;
    }

    changed(integer change)
    {
        if (change & CHANGED_REGION_START)
        {
            llSetTimerEvent(fPregnancy);
        }
    }
}



state Wait
{
     state_entry()
    {
        llSetTimerEvent(TIME_TO_WAIT);
    }
    timer()
    {
        llSetTimerEvent(0);
        state female;
    }

    changed(integer change)
    {
        if (change & CHANGED_REGION_START)
        {
            llSetTimerEvent(TIME_TO_WAIT);
        }
    }
}
 
movement:
Code:
// tunables:

// To make the pet not move, such as for a statue or plant, set to FALSE
integer moveable = TRUE;        

// adjustables for moving pets, you can ignore these if moveable = FALSE
float tolerance = 0.15; 
float increment = 0.1;  
float rest_time = 5.0;  





// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    
integer SECRET_NUMBER = 99999;                        
integer ENCRYPT = FALSE;                          


key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

/////////////////////////
string MaleName = "Hase";        
string FemaleName = "Hase";        
string Egg = "Nest";      
string Crate = "Transport Nest";   
string HomeObject = "Home"; 
string EggCup = "Nestbox";      

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;            
integer MaxAge = 7;                     
integer UNITS_OF_FOOD = 168;             
float secs_to_grow = 86400;             
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    
float fPregnancy = 172800.0;            
float MALE_TIMEOUT = 1800.0 ;            
float SEX_WAIT = 10800.0;               
float fDaysToAdult = 7;                
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        
integer MAXIMUM_HUNGER = 30;            


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE










vector home_location;      // coords of the home posr
float roam_distance;       // how far a pet can roam from the post
list food_bowls;           // a list of food bowl coordinates
list food_bowl_keys;       // a list of food bowl UUIDS
list food_bowl_time;       // the last Unix time was saw a food bowl
vector destination;        // where we are moving to
integer sex_dest = 0;      // we are heading toward a female if = 1
integer food_dest = 0;     // we are heading toward food if = 1
integer rest;              // a random amount of time, up to 5 seconds, between steps.
integer age;
float zoffset;
integer sleep_last_check ;
integer sound_flag;
integer sleep_disabled;


face_target(vector lookat) {

    if (! moveable)
        return;

    vector  fwd = llVecNorm(lookat-llGetPos());     // I assume you know the last and current position
    vector lft = llVecNorm(<0,0,1>%fwd);     //cross with <0,0,1> is parallel to ground
    rotation rot = llAxes2Rot(fwd,lft,fwd%lft);
    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WALKL, "");
    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WALKR, "");
    llSetRot(rot);
}

integer sleeping()
{
    vector sun = llGetSunDirection();
    if (!sleep_disabled) {
        if (sun.z < 0) {
            if (sleep_last_check == 0) {
                // close eyes
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_SLEEP, "");
                llMessageLinked(LINK_SET, LINK_SLEEPING, "", "");
            }
            sleep_last_check = 1;
        } else {
                if (sleep_last_check == 1) {
                    // open eyes
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    llMessageLinked(LINK_SET, LINK_UNSLEEPING, "", "");
                }
            sleep_last_check = 0;
        }
        return sleep_last_check;
    } else {
            if (sleep_last_check == 1) {
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                llMessageLinked(LINK_SET, LINK_UNSLEEPING, "", "");
                sleep_last_check = 0;
            }
        return 0;
    }
}

default
{
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_AGE_START) {
            state running;
        }
    }
}

state running
{
    state_entry()
    {

        if (! moveable)
        {
            tolerance = 255.0;
            increment = 0;   // not necessary, but safer        }
            home_location = <0,0,0>;
            roam_distance = 0;
            destination = <0,0,0>;
            age = 0;
            sleep_last_check = 0;
            sound_flag = 1;
        }
    }

        timer()
    {

        if (!sleeping()) {

            llMessageLinked(LINK_SET, LINK_SOUND, "", "");

            vector my_pos = llGetPos();

            if (llVecDist(<destination.x, destination.y, 0>, <my_pos.x, my_pos.y, 0>) <= tolerance || destination == <0,0,0>) {
                // if at food_destination send 900 msg
                if (food_dest > 0) {
                    llMessageLinked(LINK_SET, LINK_FOOD_CONSUME, (string)food_dest, llList2Key(food_bowl_keys, 0));
                }

                if (sex_dest > 0) {
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    llMessageLinked(LINK_SET, LINK_RQST_BREED, "", "");
                }


                // pick a new destination
                sex_dest = 0;
                food_dest = 0;
                destination.x = (llFrand(roam_distance * 2) - roam_distance) + home_location.x;
                destination.y = (llFrand(roam_distance * 2) - roam_distance) + home_location.y;

                destination.z = home_location.z + zoffset;

                rest = (integer)llFrand(rest_time);
                // face it
                face_target(destination);
            }


            // after the above code so we can trigger food consumption and LINK_RQST_BREED
            if (! moveable)
                return;



            if (rest == 0) {

                // llOwnerSay("move");
                // move towards destination
                vector position = llGetPos();
                float dis_x = llFabs(destination.x - position.x);
                float dis_y = llFabs(destination.y - position.y);

                float angle = llAtan2(dis_y, dis_x);

                float inc_x = llCos(angle) * increment;
                float inc_y = llSin(angle) * increment;

                if (inc_x > increment) {
                    llOwnerSay("BUG: X" + (string)inc_x + " > " + (string)increment);
                }
                if (inc_y > increment) {
                    llOwnerSay("BUG: Y" + (string)inc_y + " > " + (string)increment);
                }

                if (destination.x > position.x) {
                    position.x += inc_x;
                } else {
                        position.x -= inc_x;
                }

                if (destination.y > position.y) {
                    position.y += inc_y;
                } else {
                        position.y -= inc_y;
                }

                position.z = home_location.z + zoffset;

                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WALKL, "");
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WALKR, "");
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                llSetPos(position);
            } else {
                rest--;
                // patch to make sure it never goes < 0 or the pet will never move 
                if (rest < 0) {
                    rest = 0;
                }
            }
        }
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_HUNGRY) {
            if (sex_dest == 0) {
                // move to food bowl, then send 900
                if (llGetListLength(food_bowl_keys) > 0) {
                    if (roam_distance == 0 || home_location == <0,0,0>) {
                        llOwnerSay("I'm hungry, but I'm not homed so I can not move! Attempting to use Jedi Mind Powers to teleport food to my belly.");
                        llMessageLinked(LINK_SET, LINK_FOOD_CONSUME, str, llList2Key(food_bowl_keys, 0));
                        llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                        llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
                        llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    } else {
                            // find nearest food bowl
                            integer i;
                        destination = (vector)llList2String(food_bowls, 0);

                        for (i=1;i<llGetListLength(food_bowls);i++) {
                            if (llVecDist(destination, llGetPos()) > llVecDist((vector)llList2String(food_bowls, i), llGetPos())) {
                                destination = (vector)llList2String(food_bowls, i);
                            }
                        }
                        destination.z = home_location.z + zoffset;
                        // set destination,
                        // face it
                        face_target(destination);
                        food_dest = (integer)str;
                        rest = 0;

                    }
                } else {
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
                    llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                    llOwnerSay("I'm hungry, but I can't seem to find any food bowls at present.");
                }
            }
        } else
        if (num == LINK_SET_HOME) {

            list values = llParseString2List(str, ["^"], []);
            home_location = (vector)llList2String(values, 0);
            roam_distance = (float) llList2String(values, 1);    // 0.43
            vector current_loc = llGetPos();

            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");

            food_bowls = [];
            food_bowl_keys = [];
            food_bowl_time = [];

            destination = <0,0,0>;
            food_dest = 0;

            llSetPos(<current_loc.x, current_loc.y, home_location.z + zoffset>);
            llSetTimerEvent(4.0);
        } else
        if (num == LINK_MOVER) {
            if (rest < (integer)str) {
                rest = (integer)str;
            }
        } else
        if (num == LINK_FOODIE_CLR) {
            food_bowls = [];
            food_bowl_keys = [];
            food_bowl_time = [];
        } else
        if (num == LINK_FOODIE) {
            vector food_loc = (vector)str;

            if (llVecDist(home_location, food_loc) <= roam_distance ) {
                if(llListFindList(food_bowls, (list)str) == -1) {
                    integer id_pos = llListFindList(food_bowl_keys, (list)id);
                    if (id_pos == -1) {
                        food_bowls += str;
                        food_bowl_keys += id;
                        food_bowl_time += llGetUnixTime();
                    } else {
                            food_bowls = llListReplaceList(food_bowls, [str], id_pos, id_pos);
                        food_bowl_time  = llListReplaceList(food_bowl_time, [llGetUnixTime()], id_pos, id_pos);
                    }
                }

                integer iter;

                iter = 0;

                while(iter<llGetListLength(food_bowls)) {
                    if (llGetUnixTime() - llList2Integer(food_bowl_time, iter) > 3600) {//3600
                        food_bowls = llDeleteSubList(food_bowls, iter, iter);
                        food_bowl_keys = llDeleteSubList(food_bowl_keys, iter, iter);
                        food_bowl_time = llDeleteSubList(food_bowl_time, iter, iter);
                    } else {
                            iter++;
                    }
                }

                if (llGetListLength(food_bowls) > 0) {
                    llMessageLinked(LINK_SET, LINK_TIMER, "", "");
                }

            }
        } else
        if (num == LINK_FEMALE_LOCATION) {
            destination = (vector)str;
            face_target(destination);
            rest = 0;
            food_dest = 0;
            sex_dest = 1;
            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
            llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
        } else
        if (num == LINK_MAGE) {
            integer heightm;
            age += (integer)str;
            heightm = age;

            if (heightm > MaxAge) {
                heightm = MaxAge;
            }

            float new_scale = (GROWTH_AMOUNT * heightm) + 1.0;

            float legsz = LegLength * new_scale;
            float legso = LegOffset * new_scale;

            zoffset = legsz / 2 + legso;
        } else
        if (num == LINK_SLEEP) {
            sleep_disabled = (integer)str;
        }
    }
}
 
eater:
Code:
// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE



integer hunger_amount;
integer seconds_elapsed_normal;
integer seconds_elapsed_hungry;

default
{
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_AGE_START) {
            state running;
        }
    }
}

state running
{
    state_entry()
    {
        hunger_amount = 0;
        seconds_elapsed_normal = 0;
        seconds_elapsed_hungry = 0;
        llSetTimerEvent(1.0);
    }

    timer()
    {
        integer do_message = 0;

        if (hunger_amount > 0) {
            if (seconds_elapsed_hungry == SECONDS_BETWEEN_FOOD_HUNGRY) {
                do_message = 1;
                seconds_elapsed_hungry = 0;
            } else {
                seconds_elapsed_hungry++;
            }
        }

        if (seconds_elapsed_normal == SECONDS_BETWEEN_FOOD_NORMAL) {
            hunger_amount++;
            seconds_elapsed_normal = 0;
        } else {
                seconds_elapsed_normal++;
        }

        if (do_message == 1) {
            llMessageLinked(LINK_SET, LINK_HUNGRY, (string)hunger_amount, "");
        }
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_FOODMINUS) {
            hunger_amount --;
        } else
        if (num == LINK_HAMOUNT) {
            hunger_amount = (integer)str;
        }
    }
}
 
brain: teil1
Code:
integer SECURE = FALSE;  



// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        




// SECURITY
string  SECRET_PASSWORD = "Hase"; 
integer SECRET_NUMBER = 99999;       
integer ENCRYPT = FALSE;  


key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";


string MaleName = "Hase";   
string FemaleName = "Hase";   
string Egg = "Nest";  
string Crate = "Transport Nest"; 
string HomeObject = "Home"; 
string EggCup = "Nestbox";  


// misc tunables
float GROWTH_AMOUNT = 0.10;    
integer MaxAge = 7;               
integer UNITS_OF_FOOD = 168;           
float secs_to_grow = 86400;            
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    
float fPregnancy = 172800.0;        
float MALE_TIMEOUT = 1800.0 ;     
float SEX_WAIT = 10800.0;     
float fDaysToAdult = 7;      
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;  
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;  
integer MAXIMUM_HUNGER = 30;               




float LegLength = 0.064;    
float LegOffset = 0.052399;  

string  ANI_STAND = "stand";   
string  ANI_WALKL   = "left";    
string  ANI_WALKR   = "right";   
string  ANI_SLEEP  = "sleep";   
string  ANI_WAVE = "wave";  

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

integer LINK_ANIMATE = 1;   
integer DECREASE_FOOD = 100;    
integer LINK_AGE_START = 800;   
integer LINK_TEXTURE = 801;  
integer LINK_BREEDNAME = 802;   
integer LINK_FOOD_CONSUME = 900;  
integer LINK_FOODMINUS = 901;  
integer LINK_HUNGRY = 903; 
integer LINK_HAMOUNT = 904; 
integer LINK_SET_HOME = 910;   
integer LINK_MOVER = 911;   
integer LINK_FOODIE_CLR = 920;  
integer LINK_FOODIE = 921;  
integer LINK_COLOR1 = 930;  
integer LINK_COLOR2 = 931;    
integer LINK_SEX = 932;      
integer LINK_SHINE = 933;  
integer LINK_GLOW = 934;   
integer LINK_GEN = 935;  
integer LINK_RESET_SIZE = 936;  
integer LINK_MAGE = 940;    
integer LINK_DAYTIME = 941;  
integer LINK_GET_AGE = 942;  
integer LINK_PUT_AGE = 943;  
integer LINK_PACKAGE = 950; 
integer LINK_SEEK_FEMALE = 960; 
integer LINK_MALE_BREED_CALL = 961; 
integer LINK_SIGNAL_ELIGIBLE = 962; 
integer LINK_FEMALE_ELIGIBLE = 963;  
integer LINK_CALL_MALE = 964;   
integer LINK_MALE_ON_THE_WAY = 965; 
integer LINK_FEMALE_LOCATION = 966; 
integer LINK_RQST_BREED  = 967; 
integer LINK_CALL_MALE_INFO = 968;
integer LINK_MALE_INFO = 969; 
integer LINK_LAY_EGG = 970;  
integer LINK_BREED_FAIL = 971; 
integer LINK_PREGNANT = 972;  
integer LINK_SOUND_OFF= 974; 
integer LINK_SOUND_ON= 973;
integer LINK_SLEEPING = 990;
integer LINK_UNSLEEPING = 991; 
integer LINK_SOUND = 1001; 
integer LINK_SPECIAL = 1010; 
integer LINK_EFFECTS_ON = 2000; 
integer LINK_PREGNANCY_TIME = 5000; 
integer LINK_SLEEP = 7999; 
integer LINK_TIMER = 8000; 
integer LINK_DIE = 9999; 

string Copyright = " (c)2014 by Ferd Frederix";



DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////



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);
}


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))];
}

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);
}


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);
}

string xtea_encrypt_string( string str )
{
    if (! ENCRYPT)
        return 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;
}

string xtea_decrypt_string( string str ) {
    if (! ENCRYPT)
        return 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+/";


integer setup = FALSE; 
integer random_number;  
integer random_number2;  
integer hunger_amount;  


vector colour1;
vector colour2;
integer sex;
integer shine;
float glow;
integer gen;
integer age;

vector mcolour1;  
vector mcolour2;
integer mshine;
float mglow;
integer mgen;
integer glow_gene;
string special;
integer mglow_gene;

vector home_loc; 
key new_egg_key;  

integer locked;  
integer pregnancy_time;




Color(integer colornum, vector color, integer shine, float glow )
{


    integer nPrims = llGetNumberOfPrims();
    integer i;
    for (i = 1; i <= nPrims; i++)
    {
        list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]);
        string desc = llList2String(param,0);

        if (llToLower(desc) == "color1" && colornum == 1 )
        {
            llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
        }
        else if (llToLower(desc) == "color2" && colornum == 2 )
        {
            llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
        }
    }
}


Shine(integer shine)
{
    integer nPrims = llGetNumberOfPrims();
    integer i;
    for (i = 1; i <= nPrims; i++)
    {
        list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]);
        string desc = llList2String(param,0);

        if (llToLower(desc) == "color1" || llToLower(desc) == "color2"  )
        {
            llSetLinkPrimitiveParamsFast(i, [PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
        }
    }
}

Eye(vector color, integer shine)
{
    integer nPrims = llGetNumberOfPrims();
    integer i;
    for (i = 1; i <= nPrims; i++)
    {
        list param = llGetLinkPrimitiveParams(i,[PRIM_DESC]);
        string desc = llList2String(param,0);

        if (llToLower(desc) == "eye" )
        {
            llSetLinkPrimitiveParamsFast(i, [PRIM_COLOR, ALL_SIDES, color, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE]);
        }
    }
}

integer CheckPerms()
{
    if (YOUR_UUID != "" && llGetOwner() != YOUR_UUID)
        return 1;

    if (llGetOwner() != llGetCreator())
        return 1;

    return 0;
}


default
{
    state_entry()
    {
        if (CheckPerms()) {
            llOwnerSay("Someone not the creator reset the script. That's naughty.");
            state dead;
        }

        if (FALSE)  
        {
            llOwnerSay("Color Test");
            Color(1, <1,0,0>, 0, 0);
            Color(2, <0,1,0>, 0, 0);
            llSleep(2);
            Color(1, <0,0,1>, 0, 0);
            Color(2, <0,0,0>, 0, 0);
            llSleep(1);
            Color(1, <1,1,1>, 0, 0);
            Color(2, <1,1,1>, 0, 0);
        }

        llSetText("", <1,1,1>, 1.0);
        random_number = 0;
        random_number2 = 0;
        hunger_amount = 0;
        locked = 0;

        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
        llListen(ANIMAL_CHANNEL, "", "", "");
    }

    changed(integer change)
 
brain: teil2
Code:
    {

        if (change & CHANGED_ALLOWED_DROP) {
            if (llGetInventoryType(FemaleName) != INVENTORY_NONE  && llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
                llAllowInventoryDrop(FALSE);
            }
        }

        if (change & CHANGED_INVENTORY) {
            if ( CheckPerms() ) {

                integer inventory_count = llGetInventoryNumber(INVENTORY_ALL);
                integer extras = 4;

                if (SECURE)    // set this to TRUE to do extra security checks
                {

                    if (llGetInventoryType("xs_ager") == INVENTORY_NONE || !llGetScriptState("xs_ager")) {
                        llOwnerSay("no xs_ager");
                        state dead;
                    }
                    if (llGetInventoryType("xs_infomatic") == INVENTORY_NONE || !llGetScriptState("xs_infomatic")) {
                        llOwnerSay("no xs_infomatic");
                        state dead;
                    }
                    if (llGetInventoryType("xs_breeding") == INVENTORY_NONE || !llGetScriptState("xs_breeding")) {
                        llOwnerSay("no xs_breeding");
                        state dead;
                    }
                    if (llGetInventoryType("xs_eater") == INVENTORY_NONE || !llGetScriptState("xs_eater")) {
                        llOwnerSay("no xs_eater");
                        state dead;
                    }
                    if (llGetInventoryType("xs_movement") == INVENTORY_NONE || !llGetScriptState("xs_movement")) {
                        llOwnerSay("no xs_movement");
                        state dead;
                    }


                    if (llGetInventoryType("xs_special") == INVENTORY_NONE) {
                        llOwnerSay("no xs_special");
                        extras--;
                    }

                    if (llGetInventoryType(Egg) == INVENTORY_NONE) {
                        extras--;
                    }

                    if (llGetInventoryType(MaleName) == INVENTORY_NONE) {
                        extras--;
                    }

                    if (llGetInventoryType(FemaleName) == INVENTORY_NONE) {
                        extras--;
                    }

                    if (llGetInventoryType(HomeObject) == INVENTORY_NONE) {
                        state dead;
                    }

                    if (8 + extras != inventory_count) {
                        llOwnerSay("Count wrong, was " + (string) (8 + extras) + " should be " + (string) inventory_count);
                        state dead;
                    }
                }
            }
        }
    }

    timer()
    {
         // for OpenSIm to establish an on_rez, the durn thing does not for the onrez even in the egg unless the script goes idle
        if (setup == TRUE)
        {
            llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
            llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^READY^" + (string)llGetKey() + "^XSPET"));
            setup = FALSE;
            return;
        }



        llMessageLinked(LINK_SET, LINK_FOODIE_CLR, "", "");
        // llWhisper(0, "Scanning for food bowls.");
        random_number = (integer)(llFrand(10000.0) + 1);
        llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_LOCATION^" + (string)random_number + "^" + (string)llGetKey()));
        llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
    }

    listen(integer channel, string name, key id, string message)
    {
        if (channel == ANIMAL_CHANNEL) {
            list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);

            DEBUG(llDumpList2String(data,","));
            
            if (llList2String(data, 0) == "XSPET") {
                if (llList2String(data, 1) == "FOOD_LOCATION") {
                    llMessageLinked(LINK_SET, LINK_FOODIE, llList2String(data, 3), id);
                } else
                if (llList2String(data, 1) == "FOOD_CONSUME") {
                    if ((integer) llList2String(data, 2) == random_number2 && (key) llList2String(data, 3) == llGetKey()) {
                        hunger_amount--;
                        llMessageLinked(LINK_SET, LINK_FOODMINUS, "", "");
                        random_number2 = 0;
                        if ((integer) llList2String(data, 4) == 1 && glow_gene < 10) {
                            glow_gene ++;
                        }
                    }
                } else
                if (llList2String(data, 1) == "HOME_LOCATION") {
                    vector n_home_loc = (vector)llList2String(data, 2);
                    float home_dis = (float) llList2String(data, 3);
                    vector my_loc = llGetPos();
                    //                llOwnerSay((string)llVecDist(home_loc, my_loc) + " " + (string)my_loc + (string)home_loc + (string)home_dis + llList2String(data, 2));
                    if (llVecDist(n_home_loc, my_loc) <= home_dis && llFabs(llFabs(n_home_loc.z) - llFabs(my_loc.z)) < 1) {
                        if (llGetOwnerKey(id) == llGetOwner()) {
                            home_loc = n_home_loc;
                            llMessageLinked(LINK_SET, LINK_SET_HOME, (string)n_home_loc + "^" + (string)home_dis, "");
                        }
                    }
                } else
                    if (llList2String(data, 1) == "CONFIG" && (key) llList2String(data, 2) == llGetKey()) {

                    llMessageLinked(LINK_SET, LINK_AGE_START, "", "");
                    colour1  = (vector) llList2String(data, 3);
                    colour2 = (vector) llList2String(data, 4); 


                    sex = (integer) llList2String(data, 5);

                    shine = (integer)llList2String(data, 6);
                    glow = (float) llList2String(data, 7);

                    gen = (integer) llList2String(data, 8);
                    integer mage = (integer) llList2String(data, 9);
                    integer hamount = (integer)llList2String(data, 10);
                    string myname = llList2String(data, 11);
                    glow_gene = (integer) llList2String(data, 12);
                    special = llList2String(data, 13);

                    Color(1,colour1, shine, glow);
                    Color(2,colour2, shine, glow);

                   
                    string msg = (string) colour1 + "^" +
                        (string) colour2 + "^" +
                        (string) sex + "^" +    
                        (string) shine + "^" +
                        (string) glow + "^";

                    
                    llSleep(2); 

                    llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY); 

                    llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));

                    llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
                    llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");
                    llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
                    llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
                    llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
                    llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");
                    llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");

                    if (hamount > 0) {
                        llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
                    }

                    if (name != MaleName && name != FemaleName) {
                        llSetObjectName(myname);
                    }

                    if (sex == 1)
                        llSetObjectDesc(MaleName + "v" + (string)VERSION + Copyright);
                    else
                        llSetObjectDesc(FemaleName + "v" + (string)VERSION + Copyright);

                    llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");
                    llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");

                    llSay(HOME_CHANNEL, "XSPET_PING_HOME");

                    llSetText("", <1,1,1>, 1.0);
                } else
                if (llList2String(data, 1) == "UPDATE_CONFIG" && (key) llList2String(data, 2) == llGetKey()) {
                    colour1  = (vector) llList2String(data, 3);;
                    colour2 = (vector) llList2String(data, 4);

                    sex = (integer) llList2String(data, 5);

                    shine = (integer) llList2String(data, 6);
                    glow = (float) llList2String(data, 7);

                    gen = (integer) llList2String(data, 8);
                    integer mage = (integer) llList2String(data, 9);
                    integer hamount = (integer) llList2String(data, 10);
                    string myname = llList2String(data, 11);
                    glow_gene = (integer) llList2String(data, 12);
                    special = llList2String(data, 13);
                    mcolour1 = (vector) llList2String(data, 14);
                    mcolour2 = (vector) llList2String(data, 15);
                    mshine = (integer) llList2String(data, 16);
                    mglow = (float) llList2String(data, 17);
                    mgen = (integer) llList2String(data, 18);
                    mglow_gene = (integer) llList2String(data, 19);
                    pregnancy_time = (integer) llList2String(data, 20);

                    Color(1,colour1,shine,glow);
                    Color(2,colour2,shine,glow);

                    string msg = (string) colour1 + "^" +
                        (string) colour2 + "^" +
                        (string) sex + "^" +
                        (string) shine + "^" +
                        (string) glow + "^";

                    llMessageLinked(LINK_SET, LINK_AGE_START, "", "");  
                    llSleep(2);  //give opensim time to switch states *sighs *


                    llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY);  

                    llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));

                    llMessageLinked(LINK_SET, LINK_COLOR1, (string)colour1, "");
                    llMessageLinked(LINK_SET, LINK_COLOR2, (string)colour2, "");

                    if (sex == 1) {
                        llMessageLinked(LINK_SET, LINK_SEX, (string)sex, "");
                    } else {
                            llMessageLinked(LINK_SET, LINK_PREGNANCY_TIME, (string)pregnancy_time, "");
                    }

                    llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
                    llMessageLinked(LINK_SET, LINK_GLOW, (string)glow, "");
                    llMessageLinked(LINK_SET, LINK_GEN, (string)gen, "");


                    llMessageLinked(LINK_SET, LINK_MAGE, (string)mage, "");


                    if (hamount > 0) {
                        llMessageLinked(LINK_SET, LINK_HAMOUNT, (string)hamount, "");
                    }

                    if (name != FemaleName && name != MaleName) {
                        llSetObjectName(myname);
                    }

                    if (sex == 1)
                        llSetObjectDesc(MaleName + " version " + (string)VERSION + Copyright);
                    else
                        llSetObjectDesc(FemaleName + " version " + (string)VERSION + Copyright);

                    llMessageLinked(LINK_SET, LINK_SPECIAL, special, "");

                    llMessageLinked(LINK_SET, LINK_DAYTIME, "", "");
                    
                    llSay(HOME_CHANNEL, "XSPET_PING_HOME");

                    llSetText("", <1,1,1>, 1.0);
                } else
                if (llList2String(data, 1) == "CRATE_PONG" && (key) llList2String(data, 2) == llGetKey()) {
                    if ((float) llList2String(data, 3) >= VERSION && locked == 0) {
                        locked = 1;
                        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));
                    }
 
brain: teil3
Code:
     } else
                if (llList2String(data, 1) == "CRATE_DIE" && (key) llList2String(data, 2) == llGetKey()) {
                    llDie();
                } else
                if (llList2String(data, 1) == "MALE_BREED_CALL") {
                    llMessageLinked(LINK_SET, LINK_MALE_BREED_CALL, "", "");
                } else
                if (llList2String(data, 1) == "FEMALE_ELIGIBLE" && home_loc == (vector)llList2String(data, 2)) {
                    llMessageLinked(LINK_SET, LINK_FEMALE_ELIGIBLE, "", id);
                } else
                if  (llList2String(data, 1) == "MALE_ON_THE_WAY" && (key) llList2String(data, 2) == llGetKey()) {
                    llMessageLinked(LINK_SET, LINK_MALE_ON_THE_WAY, "", id);
                    llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_LOC^" + (string)id + "^" + (string)llGetPos()));
                } else
                if (llList2String(data, 1) == "FEMALE_LOC" && (key) llList2String(data, 2) == llGetKey())  // missing key cast - Ferd
                {
                    llMessageLinked(LINK_SET, LINK_FEMALE_LOCATION, llList2String(data, 3), "");
                } else
                if (llList2String(data, 1) == "MALE_INFO" && (key) llList2String(data, 2) == llGetKey()){
                    // pregnant
                    mcolour1 = (vector) llList2String(data, 3);
                    mcolour2 = (vector) llList2String(data, 4);

                    mshine = (integer) llList2String(data, 5);
                    mglow = (float) llList2String(data, 6);

                    mgen = (integer) llList2String(data, 7);
                    mglow_gene = (integer) llList2String(data, 8);
                    pregnancy_time = llGetUnixTime();
                    llMessageLinked(LINK_SET, LINK_PREGNANT, "", "");
                } else
                if (llList2String(data, 1) == "BREEDING_FAIL" && (key) llList2String(data, 2) == llGetKey())  // was missing key cast - Ferd
                {
                    llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
                } else
                if (llList2String(data, 1) == "EGG_READY" && id == new_egg_key)
                {
                    llGiveInventory(id, Egg);
                    llGiveInventory(id, MaleName);
                    llGiveInventory(id, FemaleName);

                    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));
                } else
                if (llList2String(data, 1) == "SHINE_GOO" && (key) llList2String(data, 2) == llGetKey()) {   
                    if (shine == 0) {
                        shine = 1;
                        llMessageLinked(LINK_SET, LINK_SHINE, (string)shine, "");
                        llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_DIE"));

                        Shine(shine);

                        if (sex == 1) {
                            llWhisper(0, "Look out ladies, Mr Slick has arrived!");
                        } else {
                                llWhisper(0, "Look out gentlemen! Miss Slick has arrived!");
                        }
                    } else {
                            llWhisper(0, "I'm already shiny!");
                        llSay(ACC_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^SHINE_GOO_FAIL"));
                    }
                } else
                if (llList2String(data, 1) == "DIE" && (key) llList2String(data, 2) == llGetKey()) {  
                    llDie();
                } else
                if (llList2String(data, 1) == "VERSION" && VERSION < (float) llList2String(data, 2) && llGetOwnerKey(id) == llGetOwner()) {
                    llShout(UPDATE_CHANNEL, "VERSION^" + (string)VERSION);
                } else
                if (llList2String(data, 1) == "UPDATE" && (key) llList2String(data, 2) == llGetKey() && llGetOwnerKey(id) == llGetOwner()) {   // missing key cast - Ferd
                    state update;
                }
            }
        }
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_HUNGRY || num == LINK_HAMOUNT) {
            hunger_amount = (integer)str;
            if (hunger_amount > MAXIMUM_HUNGER) { 
                state dead;
            }
        } else
        if (num == LINK_FOOD_CONSUME) {
            random_number2 = (integer)(llFrand(10000.0) + 1);
            llSay(FOOD_CHANNEL, xtea_encrypt_string("XSPET^FOOD_CONSUME^" + (string)id + "^" + (string)random_number2 + "^" + (string)llGetKey()));
        } else
        if (num == LINK_MAGE) {
            age += (integer)str;
        } else
        if (num == LINK_PACKAGE) {
            llWhisper(0, "Looking for a " + Crate + "...");
            llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CRATE_PING^" + (string)VERSION));
        } else
        if (num == LINK_SEEK_FEMALE) {
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_BREED_CALL^" + (string)llGetKey()));
        } else
        if (num == LINK_SIGNAL_ELIGIBLE) {
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FEMALE_ELIGIBLE^" + (string)home_loc));
        } else
        if (num == LINK_CALL_MALE) {
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_ON_THE_WAY^" + (string)id));
        } else
        if (num == LINK_CALL_MALE_INFO) {
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^MALE_INFO^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^" + (string)glow_gene));
            llMessageLinked(LINK_SET, LINK_MALE_INFO, "", "");
        } else
        if (num == LINK_LAY_EGG) {
            // lay an egg
            pregnancy_time = 0;
            llRezObject(Egg, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
        } else
        if (num == LINK_BREED_FAIL) {
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^BREEDING_FAIL^" + (string)id));
            pregnancy_time = 0;
        } else
        if (num == LINK_SLEEPING) {
            Eye(<0,0,0>,shine);  
        } else
        if (num == LINK_UNSLEEPING) {
            Eye(<1,1,1>,shine);  
        } else
        if (num == LINK_DIE) {
            state dead;
        } else
        if (num == LINK_TIMER) {
            llSetTimerEvent(llFrand(60.0) + (FOOD_BOWL_SCAN_INTERVAL - 30.0));
        }
    }

    object_rez(key id)
    {
        new_egg_key = id;
    }

    on_rez(integer param)
    {
        if (param == SECRET_NUMBER) {
            llSetText("Rezzing...", <1,0,0>, 1.0);
            setup = TRUE;   // Opensim issue with on_rez, the UUID is not sent until the script stops processing, so we use a timer
            
            if (llGetOwner() != llGetCreator()) {
                llAllowInventoryDrop(TRUE);
            }

            llListen(ANIMAL_CHANNEL, "", "", "");
            llSetTimerEvent(5.0);
        } else {
            llOwnerSay("I died in your inventory, please use a " +  Crate + " next time.");
            state dead;
        }
    }
}

state dead
{
    state_entry()
    {
        llSetText("Dead", <1,0,0>, 1.0);
        llMessageLinked(LINK_SET,1,"death",""); 

        llRemoveInventory("xs_ager");
        llRemoveInventory("xs_breeding");
        llRemoveInventory("xs_eater");
        llRemoveInventory("xs_infomatic");
        llRemoveInventory("xs_movement");
        if (llGetInventoryType("xs_special") != INVENTORY_NONE) {
            llRemoveInventory("xs_special");
        }
        llListen(ANIMAL_CHANNEL, "", "", "");
    }



    touch_start(integer number)
    {
        llWhisper(0, "I've died. You could re-animate me with a jar of Xtra Strong Mojo. But we don't have any Mojo coded just yet");
        if (llDetectedKey(0) == llGetOwner()) {
            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));

        }
    }

    listen(integer channel, string name, key id, string message) {
        list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
        if (llList2String(data, 0) == "XSPET") {
            if (llList2String(data, 1) == "STRONG_MOJO_DIE" && (key) llList2String(data, 2) == llGetKey()) {
                llDie();
            }
        }
    }
}

// likewise, the updater script is lost to history.   Apparently you set the pet near a prim, that when touched, chats out "UPDATE", which leads you here.
// code remains here in case you want to make an updater. It givbes this pet a new pet and egg, then causes this pet to give brth to the new pet, then causes this pet to die.

state update
{
    state_entry()
    {
        llSetText("Updating.", <1,0,0>, 1.0);
        llRemoveInventory(FemaleName);
        llRemoveInventory(MaleName);
        llRemoveInventory(Egg);
        llAllowInventoryDrop(TRUE);
        llShout(UPDATE_CHANNEL, "UPDATE_READY");
    }

    changed(integer change)
    {
        if (change & CHANGED_ALLOWED_DROP) {
            if (llGetInventoryType(FemaleName) != INVENTORY_NONE  && llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
                llAllowInventoryDrop(FALSE);
                if (sex == 1)
                    llRezObject(MaleName, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
                else
                    llRezObject(FemaleName, llGetPos() + <0.0, 0.0, 0.25>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
            }
        }

    }
    object_rez(key id)
    {
        llListen(BOX_CHANNEL, "", id, "");
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == BOX_CHANNEL) {
            list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
            if (llList2String(data, 0) == "XSPET" && llList2String(data, 1) == "READY") {

                llGiveInventory(id, Egg);
                llGiveInventory(id, FemaleName);
                llGiveInventory(id, MaleName);
                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));
                llDie();
            }
        }
    }
}
 
infomration: teil1
Code:
// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE; 


string  SECRET_PASSWORD = "Hase";  
integer SECRET_NUMBER = 99999; 
integer ENCRYPT = FALSE;   


key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

string MaleName = "Hase";  
string FemaleName = "Hase"; 
string Egg = "Nest";  
string Crate = "Transport Nest";  
string HomeObject = "Home"; 
string EggCup = "Nestbox"; 


float GROWTH_AMOUNT = 0.10;  
integer MaxAge = 7;  
integer UNITS_OF_FOOD = 168; 
float secs_to_grow = 86400;
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;
float fPregnancy = 172800.0;
float MALE_TIMEOUT = 1800.0 ; 
float SEX_WAIT = 10800.0; 
float fDaysToAdult = 7; 
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400; 
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600; 
integer MAXIMUM_HUNGER = 30;            



float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet


string  ANI_STAND = "stand";  
string  ANI_WALKL   = "left"; 
string  ANI_WALKR   = "right";  
string  ANI_SLEEP  = "sleep";  
string  ANI_WAVE = "wave"; 


integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;



integer LINK_ANIMATE = 1; 
integer DECREASE_FOOD = 100; 
integer LINK_AGE_START = 800; 
integer LINK_TEXTURE = 801;
integer LINK_BREEDNAME = 802;
integer LINK_FOOD_CONSUME = 900; 
integer LINK_FOODMINUS = 901; 
integer LINK_HUNGRY = 903; 
integer LINK_HAMOUNT = 904; 
integer LINK_SET_HOME = 910; 
integer LINK_MOVER = 911; 
integer LINK_FOODIE_CLR = 920; 
integer LINK_FOODIE = 921; 
integer LINK_COLOR1 = 930; 
integer LINK_COLOR2 = 931;
integer LINK_SEX = 932; 
integer LINK_SHINE = 933; 
integer LINK_GLOW = 934; 
integer LINK_GEN = 935; 
integer LINK_RESET_SIZE = 936; 
integer LINK_MAGE = 940; 
integer LINK_DAYTIME = 941; 
integer LINK_GET_AGE = 942; 
integer LINK_PUT_AGE = 943;
integer LINK_PACKAGE = 950; 
integer LINK_SEEK_FEMALE = 960; 
integer LINK_MALE_BREED_CALL = 961; 
integer LINK_SIGNAL_ELIGIBLE = 962; 
integer LINK_FEMALE_ELIGIBLE = 963; 
integer LINK_CALL_MALE = 964; 
integer LINK_MALE_ON_THE_WAY = 965; 
integer LINK_FEMALE_LOCATION = 966; 
integer LINK_RQST_BREED  = 967; 
integer LINK_CALL_MALE_INFO = 968;
integer LINK_MALE_INFO = 969; 
integer LINK_LAY_EGG = 970;
integer LINK_BREED_FAIL = 971; 
integer LINK_PREGNANT = 972; 
integer LINK_SOUND_OFF= 974; 
integer LINK_SOUND_ON= 973;
integer LINK_SLEEPING = 990; 
integer LINK_UNSLEEPING = 991;
integer LINK_SOUND = 1001;
integer LINK_SPECIAL = 1010; 
integer LINK_EFFECTS_ON = 2000; 
integer LINK_PREGNANCY_TIME = 5000; 
integer LINK_SLEEP = 7999;  
integer LINK_TIMER = 8000;  
integer LINK_DIE = 9999; 

string Copyright = " (c)2014 by Ferd Frederix";  

DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



string sBreedName;
integer hunger_amount;
vector colour1;
vector colour2;
integer sex;
integer shine;
float glow;
string pregnant;
string sleep;
integer gen;

integer name_listener;
integer menu_listener;

integer age;
integer play_sounds;
string special;
integer menu_expired;
integer sleep_disabled;


string gHEX_STRING = "0123456789abcdef"; 

list sysColorsVector;
list sysColorsName;


string HTML2SysColorBestMatch(vector userColor)
{

   
    float variance = 2.0;
    float test;
    integer index;
   
    integer count = llGetListLength(sysColorsVector);
    integer i;
    for (i=0;i<count;i++)
    {
        test = llVecMag(userColor - llList2Vector(sysColorsVector, i));
        if (test < variance)
        {
            variance = test;
            index = i;
        }
    }
   
    return llList2String(sysColorsName, index);
}


say_details()
{

    string mysex;
    string myshine;
    if (sex == 1) {
        mysex = "Male";
    } else
    if (sex == 2) {
        mysex = "Female";
    } else {
       mysex = "unknown - not configured correctly";
    }

    if (shine == 0) {
        myshine = "None";
    } else
    if (shine == 1) {
        myshine = "Low";
    } else
    if (shine == 2) {
        myshine = "Medium";
    } else
    if (shine == 3) {
        myshine = "High";
    }
    
    if (llStringLength(sBreedName))
        llWhisper(0, "Breed: " + (string)sBreedName);

    llWhisper(0, "Color1: " + HTML2SysColorBestMatch(colour1));
    llWhisper(0, "Color1: " + HTML2SysColorBestMatch(colour2));
    llWhisper(0, "Shine: " + myshine);
    llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
    llWhisper(0, "Special: " + special);
    llWhisper(0, "Sex: " + mysex);
    llWhisper(0, "Age: " + (string)age + " days");
    llWhisper(0, "Generation: " + (string)gen);

    // the API channel is unused at this time.  You can use it for whatever 
    llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + sBreedName + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
}

default
{

    state_entry()
    {
        sysColorsVector =
        [
            <0.941176,0.972549,1.000000>,
            <0.980392,0.921569,0.843137>,
            <0.000000,1.000000,1.000000>,
            <0.498039,1.000000,0.831373>,
            <0.941176,1.000000,1.000000>,
            <0.960784,0.960784,0.862745>,
            <1.000000,0.894118,0.768627>,
            <0.000000,0.000000,0.000000>,
            <1.000000,0.921569,0.803922>,
            <0.000000,0.000000,1.000000>,
            <0.541176,0.168627,0.886275>,
            <0.647059,0.164706,0.164706>,
            <0.870588,0.721569,0.529412>,
            <0.372549,0.619608,0.627451>,
            <0.498039,1.000000,0.000000>,
            <0.823529,0.411765,0.117647>,
            <1.000000,0.498039,0.313725>,
            <0.392157,0.584314,0.929412>,
            <1.000000,0.972549,0.862745>,
            <0.862745,0.078431,0.235294>,
            <0.000000,1.000000,1.000000>,
            <0.000000,0.000000,0.545098>,
            <0.000000,0.545098,0.545098>,
            <0.721569,0.525490,0.043137>,
            <0.662745,0.662745,0.662745>,
            <0.000000,0.392157,0.000000>,
            <0.741176,0.717647,0.419608>,
            <0.545098,0.000000,0.545098>,
            <0.333333,0.419608,0.184314>,
            <1.000000,0.549020,0.000000>,
            <0.600000,0.196078,0.800000>,
            <0.545098,0.000000,0.000000>,
            <0.913725,0.588235,0.478431>,
            <0.560784,0.737255,0.545098>,
            <0.282353,0.239216,0.545098>,
            <0.184314,0.309804,0.309804>,
            <0.000000,0.807843,0.819608>,
            <0.580392,0.000000,0.827451>,
            <1.000000,0.078431,0.576471>,
            <0.000000,0.749020,1.000000>,
            <0.411765,0.411765,0.411765>,
            <0.117647,0.564706,1.000000>,
            <0.698039,0.133333,0.133333>,
            <1.000000,0.980392,0.941176>,
            <0.133333,0.545098,0.133333>,
            <1.000000,0.000000,1.000000>,
            <0.862745,0.862745,0.862745>,
            <0.972549,0.972549,1.000000>,
            <1.000000,0.843137,0.000000>,
            <0.854902,0.647059,0.125490>,
            <0.501961,0.501961,0.501961>,
            <0.000000,0.501961,0.000000>,
            <0.678431,1.000000,0.184314>,
            <0.941176,1.000000,0.941176>,
            <1.000000,0.411765,0.705882>,
            <0.803922,0.360784,0.360784>,
            <0.294118,0.000000,0.509804>,
            <1.000000,1.000000,0.941176>,
            <0.941176,0.901961,0.549020>,
            <0.901961,0.901961,0.980392>,
            <1.000000,0.941176,0.960784>,
            <0.486275,0.988235,0.000000>,
            <1.000000,0.980392,0.803922>,
            <0.678431,0.847059,0.901961>,
            <0.941176,0.501961,0.501961>,
            <0.878431,1.000000,1.000000>,
            <0.980392,0.980392,0.823529>,
            <0.827451,0.827451,0.827451>,
            <0.564706,0.933333,0.564706>,
            <1.000000,0.713725,0.756863>,
            <1.000000,0.627451,0.478431>,
            <0.125490,0.698039,0.666667>,
            <0.529412,0.807843,0.980392>,
            <0.466667,0.533333,0.600000>,
            <0.690196,0.768627,0.870588>,
            <1.000000,1.000000,0.878431>,
            <0.000000,1.000000,0.000000>,
            <0.196078,0.803922,0.196078>,
            <0.980392,0.941176,0.901961>,
            <1.000000,0.000000,1.000000>,
            <0.501961,0.000000,0.000000>,
            <0.400000,0.803922,0.666667>,
            <0.000000,0.000000,0.803922>,
            <0.729412,0.333333,0.827451>,
            <0.576471,0.439216,0.858824>,
            <0.235294,0.701961,0.443137>,
            <0.482353,0.407843,0.933333>,
            <0.000000,0.980392,0.603922>,
            <0.282353,0.819608,0.800000>,
            <0.780392,0.082353,0.521569>,
            <0.098039,0.098039,0.439216>,
            <0.960784,1.000000,0.980392>,
            <1.000000,0.894118,0.882353>,
            <1.000000,0.894118,0.709804>,
            <1.000000,0.870588,0.678431>,
            <0.000000,0.000000,0.501961>,
            <0.992157,0.960784,0.901961>,
            <0.501961,0.501961,0.000000>,
            <0.419608,0.556863,0.137255>,
            <1.000000,0.647059,0.000000>,
            <1.000000,0.270588,0.000000>,
            <0.854902,0.439216,0.839216>,
            <0.933333,0.909804,0.666667>,
            <0.596078,0.984314,0.596078>,
            <0.686275,0.933333,0.933333>,
            <0.858824,0.439216,0.576471>,
            <1.000000,0.937255,0.835294>,
            <1.000000,0.854902,0.725490>,
            <0.803922,0.521569,0.247059>,
            <1.000000,0.752941,0.796078>,
            <0.866667,0.627451,0.866667>,
            <0.690196,0.878431,0.901961>,
            <0.501961,0.000000,0.501961>,
            <1.000000,0.000000,0.000000>,
            <0.737255,0.560784,0.560784>,
            <0.254902,0.411765,0.882353>,
            <0.545098,0.270588,0.074510>,
            <0.980392,0.501961,0.447059>,
            <0.956863,0.643137,0.376471>,
            <0.180392,0.545098,0.341176>,
            <1.000000,0.960784,0.933333>,
            <0.627451,0.321569,0.176471>,
            <0.752941,0.752941,0.752941>,
            <0.529412,0.807843,0.921569>,
            <0.415686,0.352941,0.803922>,
            <0.439216,0.501961,0.564706>,
            <1.000000,0.980392,0.980392>,
            <0.000000,1.000000,0.498039>,
            <0.274510,0.509804,0.705882>,
            <0.823529,0.705882,0.549020>,
            <0.000000,0.501961,0.501961>,
            <0.847059,0.749020,0.847059>,
            <1.000000,0.388235,0.278431>,
            <1.000000,1.000000,1.000000>,
            <0.250980,0.878431,0.815686>,
            <0.933333,0.509804,0.933333>,
            <0.960784,0.870588,0.701961>,
            <1.000000,1.000000,1.000000>,
            <0.960784,0.960784,0.960784>,
            <1.000000,1.000000,0.000000>,
            <0.603922,0.803922,0.196078>
        ];
 
information: teil2
Code:
        sysColorsName =
        [
            "AliceBlue",
            "AntiqueWhite",
            "Aqua",
            "Aquamarine",
            "Azure",
            "Beige",
            "Bisque",
            "Black",
            "BlanchedAlmond",
            "Blue",
            "BlueViolet",
            "Brown",
            "BurlyWood",
            "CadetBlue",
            "Chartreuse",
            "Chocolate",
            "Coral",
            "CornflowerBlue",
            "Cornsilk",
            "Crimson",
            "Cyan",
            "DarkBlue",
            "DarkCyan",
            "DarkGoldenrod",
            "DarkGray",
            "DarkGreen",
            "DarkKhaki",
            "DarkMagenta",
            "DarkOliveGreen",
            "DarkOrange",
            "DarkOrchid",
            "DarkRed",
            "DarkSalmon",
            "DarkSeaGreen",
            "DarkSlateBlue",
            "DarkSlateGray",
            "DarkTurquoise",
            "DarkViolet",
            "DeepPink",
            "DeepSkyBlue",
            "DimGray",
            "DodgerBlue",
            "Firebrick",
            "FloralWhite",
            "ForestGreen",
            "Fuchsia",
            "Gainsboro",
            "GhostWhite",
            "Gold",
            "Goldenrod",
            "Gray",
            "Green",
            "GreenYellow",
            "Honeydew",
            "HotPink",
            "IndianRed",
            "Indigo",
            "Ivory",
            "Khaki",
            "Lavender",
            "LavenderBlush",
            "LawnGreen",
            "LemonChiffon",
            "LightBlue",
            "LightCoral",
            "LightCyan",
            "LightGoldenrodYellow",
            "LightGray",
            "LightGreen",
            "LightPink",
            "LightSalmon",
            "LightSeaGreen",
            "LightSkyBlue",
            "LightSlateGray",
            "LightSteelBlue",
            "LightYellow",
            "Lime",
            "LimeGreen",
            "Linen",
            "Magenta",
            "Maroon",
            "MediumAquamarine",
            "MediumBlue",
            "MediumOrchid",
            "MediumPurple",
            "MediumSeaGreen",
            "MediumSlateBlue",
            "MediumSpringGreen",
            "MediumTurquoise",
            "MediumVioletRed",
            "MidnightBlue",
            "MintCream",
            "MistyRose",
            "Moccasin",
            "NavajoWhite",
            "Navy",
            "OldLace",
            "Olive",
            "OliveDrab",
            "Orange",
            "OrangeRed",
            "Orchid",
            "PaleGoldenrod",
            "PaleGreen",
            "PaleTurquoise",
            "PaleVioletRed",
            "PapayaWhip",
            "PeachPuff",
            "Peru",
            "Pink",
            "Plum",
            "PowderBlue",
            "Purple",
            "Red",
            "RosyBrown",
            "RoyalBlue",
            "SaddleBrown",
            "Salmon",
            "SandyBrown",
            "SeaGreen",
            "SeaShell",
            "Sienna",
            "Silver",
            "SkyBlue",
            "SlateBlue",
            "SlateGray",
            "Snow",
            "SpringGreen",
            "SteelBlue",
            "Tan",
            "Teal",
            "Thistle",
            "Tomato",
            "White",
            "Turquoise",
            "Violet",
            "Wheat",
            "White",
            "WhiteSmoke",
            "Yellow",
            "YellowGreen"
        ];


        if (debug)
        {
            float i;
            float j;
            float k;
            for (i = 0; i <= 1; i+= 0.5)
            {
                for (j = 0; j <= 1; j+= 0.5)
                {
                    for (k = 0; k <= 1; k+= 0.5)
                    {
                        llWhisper(0, (string)<i,j,k> +  ":" + HTML2SysColorBestMatch(<i,j,k>));

                    }
                }
            }
        }
    }
    
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_AGE_START) {    // this starts the aging process
            state running;
        }
    }
}


state running
{
    state_entry()
    {
        hunger_amount = 0;
        age = 0;
        pregnant = "";
        play_sounds = TRUE;
        llListen(API_CHANNEL, "", "", "");
    }

    touch_start(integer total_number)
    {
        string mysex;
        if (sex == 1) {
            mysex = "Male";
        } else
        if (sex == 2) {
            mysex = "Female";
        } else {
            mysex = "unknown - not configured correctly";
        }

        llSetText(llGetObjectName() + "\n" +  mysex + " - Age: " + (string)age + " - Gen: " + (string)gen + "\n" + "Hunger: " + (string)hunger_amount + "/" + (string)MAXIMUM_HUNGER + "\n" + pregnant + sleep, <1,1,1>, 1.0);

        say_details();

        menu_expired = 0;

        if (llDetectedKey(0) == llGetOwner()) {
            integer menu_chan = (integer)llFrand(10000.0) + 100;
            llListenRemove(menu_listener);
            menu_listener = llListen(menu_chan, "", llGetOwner(), "");

            llDialog(llGetOwner(), "What would you like to do?\n\n - Name: Name your pet "
                + "\n - Package: Place your pet"
                + "into a nearby " + Crate
                + "\n - Sound: Toggle Sound On/Off\n"
                + "- Home Object: Get a new home object\n"
                + "- Sleep: Toggle Sleep On/Off",  ["Nothing", "Name", "Package", "Sound", "Home Object", "Sleep"], menu_chan);

            menu_expired = 1;

        }
        llSetTimerEvent(30.0);
    }

    timer()
    {
        llListenRemove(menu_listener);
        llListenRemove(name_listener);
        llSetTimerEvent(0.0);
        llSetText("", <1,1,1>, 1.0);
        if (menu_expired) {
            llWhisper(0, "Menu Expired");
            menu_expired = 0;
        }
    }

    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_BREEDNAME) {
            sBreedName = str;
        } else
        if (num == LINK_HUNGRY || num == LINK_HAMOUNT) {
            hunger_amount = (integer)str;
        } else
        if (num == LINK_FOODMINUS) {
            hunger_amount --;
            //eaten ++;
        } else
        if (num == LINK_COLOR1) {
            colour1 = (vector)str;
        } else
        if (num == LINK_COLOR2) {
            colour2 = (vector)str;
        } else
        if (num == LINK_SEX) {
            sex = (integer)str;
        } else
        if (num == LINK_SHINE) {
            shine = (integer)str;
        } else
        if (num == LINK_GLOW) {
            glow = (float)str;
        } else
        if (num == LINK_GEN) {
            gen = (integer)str;
        } else
        if (num == LINK_MAGE) {
            age += (integer)str;
        } else
        if (num == LINK_PREGNANT) {
            pregnant = "Pregnant";
            llSay(API_CHANNEL, "I'm Pregnant!");
        } else
        if (num == LINK_PREGNANCY_TIME) {
            sex = 2;
            if ((integer)str != 0) {
                pregnant = "Pregnant";
            }
        } else
        if (num == LINK_LAY_EGG) {
            pregnant = "";
        } else
        if (num == LINK_SLEEPING) {
            sleep = "\nSleeping";
        } else
        if (num == LINK_UNSLEEPING) {
            sleep = "";
        } else
        if (num == LINK_SPECIAL) {
            special = str;
        } else
        if (num == LINK_SET_HOME) {
            list data = llParseString2List(str, ["^"], []);
            llSetText("Home Set: " + llList2String(data, 0) + " " + llList2String(data, 1) + "m", <1,1,1>, 1.0);
            llSetTimerEvent(15.0);
        }
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == 0 && id == llGetOwner()) {
            list name_parts = llParseString2List(msg, [","], []);
            if (llToLower(llList2String(name_parts, 0)) == "name") {
                string myname = llStringTrim(llList2String(name_parts, 1), STRING_TRIM);

                integer i;

                for (i=0;i<llStringLength(myname);i++) {
                    if (llGetSubString(myname, i, i) == "^") {
                        llWhisper(0, "Sorry, cannot have a \"^\" in the name.");
                        llListenRemove(name_listener);
                        return;
                    }
                }

                llWhisper(0, "My new name is " + myname);
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_WAVE, "");
                llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
                llSetObjectName(myname);
                llListenRemove(name_listener);
            }
        } else if (channel == API_CHANNEL) {
                list data = llParseString2List(msg, ["^"], []);
            if (llList2String(data, 0) == "XSPet" && (key) llList2String(data, 1) == llGetKey()) {
                llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
            }
        } else if (channel != ANIMAL_CHANNEL) {
                llListenRemove(menu_listener);
            menu_expired = 0;
            if (msg == "Name") {
                llOwnerSay("You have 30 seconds to type a new name: (Format \"name, Charlie\")");
                name_listener = llListen(0, "", llGetOwner(), "");
                llSetTimerEvent(30.0);
            } else
            if (msg == "Package") {
                llMessageLinked(LINK_SET, LINK_PACKAGE, "", "");
            } else
            if (msg == "Sound") {
                if (play_sounds) {
                    llMessageLinked(LINK_SET, LINK_SOUND_OFF, "", "");
                    llWhisper(0, "Turning sound off.");
                } else {
                        llMessageLinked(LINK_SET, LINK_SOUND_ON, "", "");
                    llWhisper(0, "Turning sound on.");
                }
                play_sounds = !play_sounds;
            } else
            if (msg == "Home Object") {
                llGiveInventory(llGetOwner(), HomeObject);
            } else
            if (msg == "Sleep") {
                if (sleep_disabled) {
                    llWhisper(0, "Enabling Sleeping.");
                } else {
                        llWhisper(0, "Disabling Sleeping.");
                }
                sleep_disabled = !sleep_disabled;
                llMessageLinked(LINK_SET, LINK_SLEEP, (string)sleep_disabled, "");
            }
        }
    }
}
 
special:
Code:
// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE










// The xs_special.lsl script is a script Xundra Snowpaw made to extend pets, and how you use it is up to you.
// Something is defined as a special by the xs_egg script.  The default is "Normal".  You change the special in the xs_egg script to any other string, and it ends up here in this script.
// There is no  'real code' in xs_special to handle specials.  You have to add code.
// The crates and other packaging tools do remember the special string.
// If special string = "Normal", the brain will remove this script.
// If you set the string special = "Normal" in the egg to special = "Abnormal", this code below will be triggered with that string 'Abnormal'.  What that does is up to you.

default
{
    link_message(integer sender, integer num, string str, key id)
    {
        if (num == LINK_SPECIAL) {
            if (str == "Normal") {
                llRemoveInventory("xs_special");
            } else {
                    // add states for specific specials. The string 'str'  is defined in the xs_egg script and it ends up here.
                }
        }
    }
}





// example:  Change in xs_egg:

//    string SPECIAL = "Normal";
// to
//    string SPECIAL = "Alpha";
//and in another egg:
//string SPECIAL = "Beta";

// then add the following code wheere indicated and the pet will know it is an Alpha or a Beta

// add states for specific specials. The string 'str'  is defined in the xs_egg script and it ends up here.
//    if (str == "Alpha")
//    {
//        // okay, its an alpha, what do we do now?
//        // anything ya want.    See "Beta" below
//    }
//    else if (str == "Beta")
//    {
//        // okay, its a  beta, what do we do now?
//        llMessageLinked("LINK_SET,1,"beta","");   // let's make the beta one play the animation named beta
//    }

sex:
Code:
////////////////////////////////////////////////////////////////////

string sexType = "1";            // set to a "2" for female parts


// Code begins //

integer sex =  0 ;               // no sex, 1 = male, 2 = female
integer LINK_SEX = 932;          // sex
//

default
{
    state_entry()
    {
        llSetAlpha(0.0,ALL_SIDES);       // 0 = invisible so we hide this part until we know our sex
    }

    on_rez(integer param)
    {
        llResetScript();
    }

    link_message(integer sender_num, integer num, string message, key id)
    {
        if (num == LINK_SEX )
        {
            if (message == "1")        // Male
            {
                llSetAlpha(1.0,ALL_SIDES);        // 1 = visible for male parts
            }
            else
            {
                llSetAlpha(0.0,ALL_SIDES);       // 0 = invisible
            }
        }
    }

}
 
egg: teil1
Code:
/// tunables:
string SPECIAL = "Normal";    // change this to trigger the xs_special script in the pet.   See xs_special documentation in the pet
vector  Position = <0.0, 0.0, 0.25>; // how far above the egg to rez the pet.
vector  Rot = <0,0,0>;   // the rotation of the pet when rezzed
integer AUTO_HATCH = FALSE;   //If set to TRUE, rthe egg will auto-hatch when laid. Default: FALSE. If FALSE, you have to touch and hatch the egg manually


// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 900.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_COLOR1_GET = 101;       // to xs_egg color plugin.
integer LINK_COLOR2_GET = 102;       // to xs_egg color plugin.
integer LINK_COLOR1_PUT = 103;       // to xs_egg color plugin.
integer LINK_COLOR2_PUT = 104;       // to xs_egg color plugin.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE



// 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 )
{
    if (! ENCRYPT)
        return 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 ) {
    if (! ENCRYPT)
        return 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+/";




// EGG code begins again, see tunables up above

integer unpackaged = FALSE; // Opensim has issues with establishing a on_rez, so we use a timer to fix the bug

// breedable params
vector colour1;
vector colour2;
integer sex;
integer gen;
integer shine;
float glow;

// globals
string colourName1;    // new string to hold color name version 0.52
string colourName2;

integer api_listener;        // holds the API listener id so we can remove it
integer locked;              // only hear 1 PONG from a crate
integer owner_touch;         // flag set when ower has touched the prim
integer menu_listener;        // integer of the listener so we can remove it.

// allow either a UUID to be entered, or not, and still maintain security
integer CheckPerms()
{
    if (YOUR_UUID != "" && llGetOwner() != YOUR_UUID)
        return 1;

    if (llGetOwner() != llGetCreator())
        return 1;

    return 0;
}


set_colours(vector c1, vector c2, integer shine, float glow)
{
    // set the root prim (the egg top), skip the base, and then do the egg bottom half
    // Link order is top Egg half, Base, then bottom of the egg half

    // IN CASE YOU ARE USING THE TEXTURE PLUG IN:
    string msg = (string) c1 + "^" +
        (string) c2 + "^" +
        "0^" +        // sex is unknown in an egg
        (string) shine + "^" +
        (string) glow + "^";

    llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY);        // tell the optional texture plugin to fetch the textures

    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]);
    llMessageLinked(LINK_SET,LINK_COLOR1_GET,(string) colour1,"");    // V 0.52 send colors to plug in
    llMessageLinked(LINK_SET,LINK_COLOR2_GET,(string) colour2,"");

}

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, "Color: " + colourName1);
    llWhisper(0, "Color: " + colourName2);
    llWhisper(0, "Shine: " + myshine);
    llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
    llWhisper(0, "Special: " + SPECIAL);
    llWhisper(0, "Generation: " + (string)gen);
    llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + SPECIAL + "^" + (string)gen + "^XSPetEnd");
}
 
egg teil2
Code:
default
{
    state_entry()
    {
        DEBUG("RESET");
        llSetText("", <1,1,1>, 1.0);         // no white text
        llSetColor(<1,1,1>, ALL_SIDES);      // all white egg
        llSetLinkColor(2, <1,1,1>, ALL_SIDES);  // white egg link 2
        llParticleSystem([]);                // no particles, beats me why, somebody once had an egg that spewed so I am leaving it.
        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
    }

    // the egg accepts inventory from crates and mama
    changed(integer change) {
        if (change & CHANGED_ALLOWED_DROP) {
            if (llGetInventoryType(FemaleName) != INVENTORY_NONE  && llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
                llAllowInventoryDrop(FALSE);
            }
        }
    }

    on_rez(integer param)
    {
        DEBUG("REZZING");
        llSetText("Rezzing...", <1,0,0>, 1.0);     // Rez Rezzing.. text

        // if param = 0, then someone rezzed an egg. It had better be the creator or someone who has put their UUID in the script.
        // all colors start in GEN 0 as primary colors here

        if (param == 0) {
            
            DEBUG("CREATOR REZZED ME");
            if (! CheckPerms() ) {
                integer colour = (integer)llFrand(9.0) + 1;
                if (colour == 1) {
                    colour1 = <1,0,0>;    // red/red
                    colour2 = <1,0,0>;
                } else
                if (colour == 2) {
                    colour1 = <1,0,0>;    // red/blue
                    colour2 = <0,1,0>;
                } else
                if (colour == 3) {
                    colour1 = <1,0,0>;    // red/blue
                    colour2 = <0,0,1>;
                } else
                if (colour == 4) {
                    colour1 = <0,1,0>;  // green/red
                    colour2 = <1,0,0>;
                } else
                if (colour == 5) {
                    colour1 = <0,1,0>;    // blue/blue
                    colour2 = <0,1,0>;
                } else
                if (colour == 6) {
                    colour1 = <0,1,0>; // green/blue
                    colour2 = <0,0,1>;
                } else
                if (colour == 7) {
                    colour1 = <0,0,1>; // blue/red
                    colour2 = <1,0,0>;
                } else
                if (colour == 8) {
                    colour1 = <0,0,1>;    // blue/red
                    colour2 = <0,1,0>;
                } else
                if (colour == 9) {
                    colour1 = <0,0,1>;    // blue/blue
                    colour2 = <0,0,1>;
                }

                set_colours(colour1, colour2, shine, glow);
                
            } else {
                llWhisper(0, "Oh no! This " + Egg + " was broken in your inventory! Please use an " + Egg + " container next time.");
                state dead;
            }
        } else if (param == SECRET_NUMBER) {
            DEBUG("REZZING from an object");
            menu_listener = llListen(EGG_CHANNEL, "", "", "");
            if ( CheckPerms() ) {
                llAllowInventoryDrop(TRUE);
            }
            unpackaged = TRUE;
            llSetTimerEvent(5);
        }
    }

    link_message(integer sender_number, integer number, string message, key id)
    {
        if (number == LINK_COLOR1_PUT)
        {
            colourName1 = message;
        } else if (number == LINK_COLOR2_PUT)
        {
            colourName2 = message;
            state rezzed;
        }
    }

    listen(integer channel, string sender, key id, string msg) {
        list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
        if (llList2String(data, 0) == "XSPET" && (key) llList2String(data, 1) == llGetKey()) {
            if (llList2String(data, 2) == "UNBOX") {
                colour1 = (vector)llList2String(data, 3);
                colour2 = (vector)llList2String(data, 4);

                gen = (integer) llList2String(data,5);
                shine = (integer) llList2String(data, 6);
                glow = (float) llList2String(data, 7);
                SPECIAL = llList2String(data, 8);

                llListenRemove(menu_listener);

                set_colours(colour1, colour2, shine, glow);
            } else
            if (llList2String(data, 2) == "BORN") {
                vector fcolour1 = (vector)llList2String(data, 3);
                vector fcolour2 = (vector)llList2String(data, 4);

                integer fgen = (integer) llList2String(data,5);
                integer fshine = (integer) llList2String(data, 6);
                float fglow = (float) llList2String(data, 7);
                integer fglow_gene = (integer) llList2String(data, 8);

                vector mcolour1 = (vector)llList2String(data, 9);
                vector mcolour2 = (vector)llList2String(data, 10);

                integer mgen = (integer) llList2String(data, 11);
                integer mshine = (integer)llList2String(data, 12);
                float mglow = (float) llList2String(data, 13);
                integer mglow_gene = (integer)llList2String(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);
                set_colours(colour1, colour2, shine, glow);
                llSetTimerEvent(1.0);
            }
        }
    }
    timer() {
        if (unpackaged)
        {
            DEBUG("UNPACKAGED");
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^EGG_READY^" + (string)llGetKey() + "^SMILE"));  // tell Mama she has a baby
            llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^EGG_READY^SMILE"));       // and tell a crate it is okay to poof
            unpackaged = FALSE;
            return;
        }
        
        DEBUG("TIMER EXPIRED");
        
        if (llGetInventoryType(MaleName) != INVENTORY_NONE && llGetInventoryType(FemaleName) != INVENTORY_NONE && llGetInventoryType(Egg) != INVENTORY_NONE) {
            state rezzed;
        }
    }
}

state rezzed
{
    on_rez(integer param)
    {
        DEBUG("STATE REZZED ON_REZ");
        if (CheckPerms()) {
            llWhisper(0, "Oh no! This " + Egg + " was broken in your inventory! Please use an " + Egg + " container next time.");
            state dead;
        }
    }

    state_entry()
    {
        DEBUG("STATE REZZED STATE ENTRY");
        if (SPECIAL == "Normal") {
            llSetText("", <1,1,1>, 1.0);
        } else {
            llSetText(SPECIAL, <1,1,1>, 1.0);
        }
        api_listener = llListen(API_CHANNEL, "", "", "");

        // added auto hatch operator 11-30-2012 fkb
        if (AUTO_HATCH &&  unpackaged)
            state hatching;    }

    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 a " + Egg + ". What would you like to do with me?", ["Hatch", "Package", "Nothing"], chan);
        }
        llSetTimerEvent(30.0);
    }

    timer()
    {
        DEBUG("TIMER EXPIRED");
        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) == MaleName || llList2String(data, 0) == FemaleName)  && (key) llList2String(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()
    {
        DEBUG("STATE HATCHING");
        sex = (integer)llFrand(2) + 1;
        if (sex == 1)
            llRezObject(MaleName, llGetPos() + Position, ZERO_VECTOR, llGetRot() * llEuler2Rot(Rot * DEG_TO_RAD) , SECRET_NUMBER);
        else
            llRezObject(FemaleName, llGetPos() + Position, ZERO_VECTOR, llGetRot() * llEuler2Rot(Rot * DEG_TO_RAD) , SECRET_NUMBER);
    }

    object_rez(key id)
    {
        DEBUG("OBJECT REZZED");
        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, MaleName);
            llGiveInventory(id, FemaleName);
            llGiveInventory(id, Egg);
            string sexname;
            if (sex == 1)
                sexname = MaleName;
            else
                sexname = FemaleName;
            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CONFIG^" + (string)id + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)sex + "^" + (string)shine + "^" + (string)glow + "^" + (string)gen + "^0^0^" + sexname + "^0^" + SPECIAL));
            llDie();
        }
    }
}

state package
{
    state_entry() {
        DEBUG("STATE PACKAGED");
        llSetTimerEvent(20.0);
        llWhisper(0, "Looking for an " + Egg + "  container...");
        menu_listener = llListen(EGG_CHANNEL, "", "", "");
        llSay(BOX_CHANNEL, xtea_encrypt_string("XSPET^" + (string)llGetKey() + "^CUP_PING^" + (string)VERSION));
    }
    timer()
    {
        DEBUG("TIMER EXPIRED");
        llListenRemove(menu_listener);
        llSetTimerEvent(0);

        llWhisper(0, "No " + Egg + " container found.");
        state rezzed;
    }

    listen(integer channel, string sender, key id, string msg)
    {
        list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
        if (llList2String(data, 0) == "XSPET" && (key) llList2String(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);
    }
}
 
color plugin:
Code:
// :CODE:


integer LINK_COLOR1_GET = 101;       // to xs_egg color plugin.
integer LINK_COLOR2_GET = 102;       // to xs_egg color plugin.
integer LINK_COLOR1_PUT = 103;       // to xs_egg color plugin.
integer LINK_COLOR2_PUT = 104;       // to xs_egg color plugin.

// vector values of all known system colors
list sysColorsVector;
// names of all known system colors
list sysColorsName;


string HTML2SysColorBestMatch(vector userColor)
{

    // place holder for the system color to match

    // start with a large variance and narrow down
    float variance = 2.0;
    float test;
    integer index;

    integer count = llGetListLength(sysColorsVector);
    integer i;
    for (i=0;i<count;i++)
    {
        test = llVecMag(userColor - llList2Vector(sysColorsVector, i));
        if (test < variance)
        {
            variance = test;
            index = i;
        }
    }

    return llList2String(sysColorsName, index);
}



default
{
    state_entry()
    {
        sysColorsVector= [<0.941176,0.972549,1.000000>,<0.980392,0.921569,0.843137>,<0.000000,1.000000,1.000000>,<0.498039,1.000000,0.831373>,<0.941176,1.000000,1.000000>,<0.960784,0.960784,0.862745>,<1.000000,0.894118,0.768627>,<0.000000,0.000000,0.000000>,<1.000000,0.921569,0.803922>,<0.000000,0.000000,1.000000>]
            +[<0.541176,0.168627,0.886275>,<0.647059,0.164706,0.164706>,<0.870588,0.721569,0.529412>,<0.372549,0.619608,0.627451>,<0.498039,1.000000,0.000000>,<0.823529,0.411765,0.117647>,<1.000000,0.498039,0.313725>,<0.392157,0.584314,0.929412>,<1.000000,0.972549,0.862745>,<0.862745,0.078431,0.235294>]
            +[<0.000000,1.000000,1.000000>,<0.000000,0.000000,0.545098>,<0.000000,0.545098,0.545098>,<0.721569,0.525490,0.043137>,<0.662745,0.662745,0.662745>,<0.000000,0.392157,0.000000>,<0.741176,0.717647,0.419608>,<0.545098,0.000000,0.545098>,<0.333333,0.419608,0.184314>,<1.000000,0.549020,0.000000>]
            +[<0.600000,0.196078,0.800000>,<0.545098,0.000000,0.000000>,<0.913725,0.588235,0.478431>,<0.560784,0.737255,0.545098>,<0.282353,0.239216,0.545098>,<0.184314,0.309804,0.309804>,<0.000000,0.807843,0.819608>,<0.580392,0.000000,0.827451>,<1.000000,0.078431,0.576471>,<0.000000,0.749020,1.000000>]
            +[<0.411765,0.411765,0.411765>,<0.117647,0.564706,1.000000>,<0.698039,0.133333,0.133333>,<1.000000,0.980392,0.941176>,<0.133333,0.545098,0.133333>,<1.000000,0.000000,1.000000>,<0.862745,0.862745,0.862745>,<0.972549,0.972549,1.000000>,<1.000000,0.843137,0.000000>,<0.854902,0.647059,0.125490>]
            +[<0.501961,0.501961,0.501961>,<0.000000,0.501961,0.000000>,<0.678431,1.000000,0.184314>,<0.941176,1.000000,0.941176>,<1.000000,0.411765,0.705882>,<0.803922,0.360784,0.360784>,<0.294118,0.000000,0.509804>,<1.000000,1.000000,0.941176>,<0.941176,0.901961,0.549020>,<0.901961,0.901961,0.980392>]
            +[<1.000000,0.941176,0.960784>,<0.486275,0.988235,0.000000>,<1.000000,0.980392,0.803922>,<0.678431,0.847059,0.901961>,<0.941176,0.501961,0.501961>,<0.878431,1.000000,1.000000>,<0.980392,0.980392,0.823529>,<0.827451,0.827451,0.827451>,<0.564706,0.933333,0.564706>,<1.000000,0.713725,0.756863>]
            +[<1.000000,0.627451,0.478431>,<0.125490,0.698039,0.666667>,<0.529412,0.807843,0.980392>,<0.466667,0.533333,0.600000>,<0.690196,0.768627,0.870588>,<1.000000,1.000000,0.878431>,<0.000000,1.000000,0.000000>,<0.196078,0.803922,0.196078>,<0.980392,0.941176,0.901961>,<1.000000,0.000000,1.000000>]
            +[<0.501961,0.000000,0.000000>,<0.400000,0.803922,0.666667>,<0.000000,0.000000,0.803922>,<0.729412,0.333333,0.827451>,<0.576471,0.439216,0.858824>,<0.235294,0.701961,0.443137>,<0.482353,0.407843,0.933333>,<0.000000,0.980392,0.603922>,<0.282353,0.819608,0.800000>,<0.780392,0.082353,0.521569>]
            +[<0.098039,0.098039,0.439216>,<0.960784,1.000000,0.980392>,<1.000000,0.894118,0.882353>,<1.000000,0.894118,0.709804>,<1.000000,0.870588,0.678431>,<0.000000,0.000000,0.501961>,<0.992157,0.960784,0.901961>,<0.501961,0.501961,0.000000>,<0.419608,0.556863,0.137255>,<1.000000,0.647059,0.000000>]
            +[<1.000000,0.270588,0.000000>,<0.854902,0.439216,0.839216>,<0.933333,0.909804,0.666667>,<0.596078,0.984314,0.596078>,<0.686275,0.933333,0.933333>,<0.858824,0.439216,0.576471>,<1.000000,0.937255,0.835294>,<1.000000,0.854902,0.725490>,<0.803922,0.521569,0.247059>,<1.000000,0.752941,0.796078>]
            +[<0.866667,0.627451,0.866667>,<0.690196,0.878431,0.901961>,<0.501961,0.000000,0.501961>,<1.000000,0.000000,0.000000>,<0.737255,0.560784,0.560784>,<0.254902,0.411765,0.882353>,<0.545098,0.270588,0.074510>,<0.980392,0.501961,0.447059>,<0.956863,0.643137,0.376471>,<0.180392,0.545098,0.341176>]
            +[<1.000000,0.960784,0.933333>,<0.627451,0.321569,0.176471>,<0.752941,0.752941,0.752941>,<0.529412,0.807843,0.921569>,<0.415686,0.352941,0.803922>,<0.439216,0.501961,0.564706>,<1.000000,0.980392,0.980392>,<0.000000,1.000000,0.498039>,<0.274510,0.509804,0.705882>,<0.823529,0.705882,0.549020>]
            +[<0.000000,0.501961,0.501961>,<0.847059,0.749020,0.847059>,<1.000000,0.388235,0.278431>,<1.000000,1.000000,1.000000>,<0.250980,0.878431,0.815686>,<0.933333,0.509804,0.933333>,<0.960784,0.870588,0.701961>,<1.000000,1.000000,1.000000>,<0.960784,0.960784,0.960784>,<1.000000,1.000000,0.000000>]
            +[<0.603922,0.803922,0.196078>];

        sysColorsName= ["AliceBlue","AntiqueWhite","Aqua","Aquamarine","Azure","Beige","Bisque","Black","BlanchedAlmond","Blue"]
            +["BlueViolet","Brown","BurlyWood","CadetBlue","Chartreuse","Chocolate","Coral","CornflowerBlue","Cornsilk","Crimson"]
            +["Cyan","DarkBlue","DarkCyan","DarkGoldenrod","DarkGray","DarkGreen","DarkKhaki","DarkMagenta","DarkOliveGreen","DarkOrange"]
            +["DarkOrchid","DarkRed","DarkSalmon","DarkSeaGreen","DarkSlateBlue","DarkSlateGray","DarkTurquoise","DarkViolet","DeepPink","DeepSkyBlue"]
            +["DimGray","DodgerBlue","Firebrick","FloralWhite","ForestGreen","Fuchsia","Gainsboro","GhostWhite","Gold","Goldenrod"]
            +["Gray","Green","GreenYellow","Honeydew","HotPink","IndianRed","Indigo","Ivory","Khaki","Lavender"]
            +["LavenderBlush","LawnGreen","LemonChiffon","LightBlue","LightCoral","LightCyan","LightGoldenrodYellow","LightGray","LightGreen","LightPink"]
            +["LightSalmon","LightSeaGreen","LightSkyBlue","LightSlateGray","LightSteelBlue","LightYellow","Lime","LimeGreen","Linen","Magenta"]
            +["Maroon","MediumAquamarine","MediumBlue","MediumOrchid","MediumPurple","MediumSeaGreen","MediumSlateBlue","MediumSpringGreen","MediumTurquoise","MediumVioletRed"]
            +["MidnightBlue","MintCream","MistyRose","Moccasin","NavajoWhite","Navy","OldLace","Olive","OliveDrab","Orange"]
            +["OrangeRed","Orchid","PaleGoldenrod","PaleGreen","PaleTurquoise","PaleVioletRed","PapayaWhip","PeachPuff","Peru","Pink"]
            +["Plum","PowderBlue","Purple","Red","RosyBrown","RoyalBlue","SaddleBrown","Salmon","SandyBrown","SeaGreen"]
            +["SeaShell","Sienna","Silver","SkyBlue","SlateBlue","SlateGray","Snow","SpringGreen","SteelBlue","Tan"]
            +["Teal","Thistle","Tomato","White","Turquoise","Violet","Wheat","White","WhiteSmoke","Yellow"]
            +["YellowGreen"];


    }

    link_message(integer sender_number, integer number, string message, key id)
    {
        if (number == LINK_COLOR1_GET)
        {
            llMessageLinked(LINK_SET,LINK_COLOR1_PUT,HTML2SysColorBestMatch((vector) message),"");
        } else if (number == LINK_COLOR2_GET)
        {
            llMessageLinked(LINK_SET,LINK_COLOR2_PUT,HTML2SysColorBestMatch((vector) message),"");
        }
    }

}
 
cryogate:
Code:
// Tunables

float position = 0.25; 
integer BOX = FALSE;   
integer MoveUp = TRUE;   
float distance = 0.5;  
float delay = 3;   


integer debug = FALSE; 




// SECURITY
string  SECRET_PASSWORD = "Hase";    
integer SECRET_NUMBER = 99999;  
integer ENCRYPT = FALSE;  

key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";


/////////////////////////
string MaleName = "Hase";  
string FemaleName = "Haesin";  
string Egg = "Nest"; 
string Crate = "Transport Nest";  
string HomeObject = "Home";
string EggCup = "Nestbox"; 


// misc tunables
float GROWTH_AMOUNT = 0.10; 
integer MaxAge = 7;  
integer UNITS_OF_FOOD = 168; 
float secs_to_grow = 86400; 
float FOOD_BOWL_SCAN_INTERVAL = 1800.0; 
float fPregnancy = 172800.0; 
float MALE_TIMEOUT = 1800.0 ; 
float SEX_WAIT = 10800.0; 
float fDaysToAdult = 7;
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400; 
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600; 
integer MAXIMUM_HUNGER = 30; 
           

float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet


string  ANI_STAND = "stand"; 
string  ANI_WALKL   = "left"; 
string  ANI_WALKR   = "right";  
string  ANI_SLEEP  = "sleep";  
string  ANI_WAVE = "wave";  


integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;


integer LINK_ANIMATE = 1;   
integer DECREASE_FOOD = 100;  
integer LINK_COLOR1_GET = 101;  
integer LINK_COLOR2_GET = 102;  
integer LINK_COLOR1_PUT = 103;  
integer LINK_COLOR2_PUT = 104;  
integer LINK_AGE_START = 800; 
integer LINK_TEXTURE = 801; 
integer LINK_BREEDNAME = 802;  
integer LINK_FOOD_CONSUME = 900; 
integer LINK_FOODMINUS = 901; 
integer LINK_HUNGRY = 903; 
integer LINK_HAMOUNT = 904;  
integer LINK_SET_HOME = 910; 
integer LINK_MOVER = 911; 
integer LINK_FOODIE_CLR = 920; 
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE











// 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 )
{
    if (! ENCRYPT)
        return 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 ) {
    if (! ENCRYPT)
        return 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;        // saved animal coloration 1 breedable param
vector colour2;        // saved animal coloration 2 breedable param
integer gen;           // saved animal Gen 0 is first born, 1 is babies, etc
integer shine;         //saved animal  0 = None, 1 = Low, 2 = Medium, 3 = High shine
float glow;            // saved animal food fed glow in percent
key uuid;                // Animal UUID from a CRATE_PING
integer listener;        // listener ID for menu
integer owner_touch;    // flag to prevent a second touch from someone else from cancelling the menu timer
integer sex;            // 1 = Male, 2 = Female
integer age;            // age in days
integer hunger;         // saved animal hunger value
string myname;          // saved animal pet name
integer glow_gene;      // saved animal glow gene
string special;         // saved animal special feature

string colourName1;    // new string to hold color name version 0.52
string colourName2;

say_details()
{

    string mysex;
    string myshine;
    if (sex == 1) {
        mysex = "Male";
    } else
    if (sex == 2) {
        mysex = "Female";
    } else {
            mysex = (string)sex;
    }

    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, "Color: " + colourName1);
    llWhisper(0, "Color: " + colourName2);
    llWhisper(0, "Shine: " + myshine);
    llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
    llWhisper(0, "Special: " + special);
    llWhisper(0, "Sex: " + mysex);
    llWhisper(0, "Age: " + (string)age + " days");
    llWhisper(0, "Generation: " + (string)gen);

    llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
}

set_colours(vector c1, vector c2, integer shine, float glow)
{

    string msg = (string) c1 + "^" +
        (string) c2 + "^" +
        "0^" +        // sex is unknown in an egg
        (string) shine + "^" +
        (string) glow + "^";
    llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY);        // tell the optional texture plugin
    llMessageLinked(LINK_SET,LINK_COLOR1_GET,(string) colour1,"");    // V 0.52 send colors to plug in
    llMessageLinked(LINK_SET,LINK_COLOR2_GET,(string) colour2,"");

    if (BOX)
        // sets color 1  on sides 0,1,3,5 and color 2 on sides 2 &4 of a box
        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]);
    else
    {
        integer N = llGetNumberOfPrims();
        integer i;
        for (i = 1; i <= N; i++)
        {
            list  lDesc = llGetLinkPrimitiveParams(i,[28]);    // 28 = PRIM_DESC, but LSLEdit does not support it yet :-(
            string desc = llToLower(llList2String(lDesc,0));    // get the string description

            if (desc == "color1")
            {
                llSetLinkPrimitiveParamsFast(i,[PRIM_COLOR, 0, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
            } else if (desc == "color2")
        {
            llSetLinkPrimitiveParamsFast(i,[PRIM_COLOR, 0, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
        }
        }

    }
}

default
{
    state_entry()
    {
        set_colours(<1,1,1>,<1,1,1>,0,0);       // default box color

        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
        uuid = NULL_KEY;
        listener = llListen(BOX_CHANNEL, "", "", "");
    }
    
    touch_start(integer num)
    {
        llWhisper(0, "This " + llGetObjectName() + " is version " + (string)VERSION);
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (llGetOwnerKey(id) != llGetOwner()) {
            return;
        }

        list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);

        if (uuid == NULL_KEY) {
            if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "CRATE_PING") {
                uuid = id;
                llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CRATE_PONG^" + (string)id + "^" + (string)VERSION));
                llSetTimerEvent(15.0);
            }
        } else
        if (uuid == id) {
            if (llList2String(data, 0) == "XSPET" && (key) llList2String(data, 1) == llGetKey()) {
                llSetTimerEvent(0.0);
                colour1 = (vector)llList2String(data, 2);
                colour2 = (vector)llList2String(data, 3);
                shine = (integer) llList2String(data, 4);
                glow = (float) llList2String(data, 5);
                gen = (integer) llList2String(data, 6);
                sex = (integer) llList2String(data, 7);
                age = (integer) llList2String(data, 8);
                hunger = (integer) llList2String(data, 9);
                myname = llList2String(data, 10);
                glow_gene = (integer) llList2String(data, 11);
                special = llList2String(data, 12);
                llListenRemove(listener);
                llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^CRATE_DIE^" + (string)id + "^" + (string)VERSION));

                state full;
            } else {
                if (llList2String(data, 0) == "XSPET" && (key) llList2String(data, 1) != llGetKey()) {
                    uuid = NULL_KEY;
                }
            }
        }
    }

    timer()
    {
        llSetTimerEvent(0.0);
        uuid = NULL_KEY;
    }
}

state full
{
    state_entry()
    {
        llSetObjectName(Crate + ":" + myname);
        set_colours(colour1, colour2, shine, glow);
        llListen(API_CHANNEL, "", "", "");
    }

    touch_start(integer num)
    {
        owner_touch = 0;
        say_details();

        if (llDetectedKey(0) == llGetOwner()) {
            owner_touch = 1;
            integer chan = (integer)llFrand(10000.0) + 1000;
            listener = llListen(chan, "", llGetOwner(), "");

            llDialog(llGetOwner(), "Would you like to unpackage me?", ["Yes", "No"], chan);
        }
        llSetTimerEvent(20.0);
    }

    link_message(integer sender_number, integer number, string message, key id)
    {
        if (number == LINK_COLOR1_PUT)
        {
            colourName1 = message;
        } else if (number == LINK_COLOR2_PUT)
        {
            colourName2 = message;
        }
    }

    timer()
    {
        if (owner_touch == 1) {
            llListenRemove(listener);
        }
        llSetTimerEvent(0.0);
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == API_CHANNEL) {
            list data = llParseString2List(msg, ["^"], []);
            if (llList2String(data, 0) == "XSPet" && (key) llList2String(data, 1) == llGetKey()) {
                llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^" + (string)sex + "^" + (string)age + "^XSPetEnd");
            }
        } else {
                llListenRemove(listener);
            if (msg == "Yes") {
                state unbox;
            }
        }
    }
}



state unbox
{
    state_entry()
    {

        if (MoveUp) {
            vector pos = llGetPos();
            pos.z +=  distance;
            llSetPos(pos);          // move up a bit
            position = - distance; // down below us for ufo
        }


        // v.25 ufo particles
        llMessageLinked(LINK_SET,LINK_EFFECTS_ON,"","");     // V.25 turn on effects
        if (sex == 1)
            llRezObject(MaleName, llGetPos() + <0.0, 0.0, position>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
        else
            llRezObject(FemaleName, llGetPos() + <0.0, 0.0, position>, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
    }

    object_rez(key id)
    {
        listener = llListen(BOX_CHANNEL, "", id, "");
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == BOX_CHANNEL) {
            list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
            if (llList2String(data, 0) == "XSPET" && llList2String(data, 1) == "READY") {

                llGiveInventory(id, Egg);
                llGiveInventory(id, MaleName);
                llGiveInventory(id, FemaleName);

                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));
                if (delay) {
                    llSleep(delay);   // V.25 give some time for effects to rez
                }

                llDie();
            }
        }
    }
}
 
eggcup:
Code:
// tunables
integer up_down = FALSE ;
vector POS_UP = <0.0, 0.0, 0.25>; 
vector POS_DOWN =  <0.0, 0.0, -0.1>;   


integer debug = FALSE; 


// SECURITY
string  SECRET_PASSWORD = "Hase";
integer SECRET_NUMBER = 99999; 
integer ENCRYPT = FALSE;  

key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";


/////////////////////////
string MaleName = "Hase";    
string FemaleName = "Haesin"; 
string Egg = "Nest";  
string Crate = "Transport Nest"; 
string HomeObject = "Home";
string EggCup = "Nestbox"; 


// misc tunables
float GROWTH_AMOUNT = 0.10;    
integer MaxAge = 7;  
integer UNITS_OF_FOOD = 168; 
float secs_to_grow = 86400;
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;
float fPregnancy = 172800.0;
float MALE_TIMEOUT = 900.0 ; 
float SEX_WAIT = 10800.0; 
float fDaysToAdult = 7; 
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400; 
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;
integer MAXIMUM_HUNGER = 30;  


float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet


string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_COLOR1_GET = 101;       // to xs_egg color plugin.
integer LINK_COLOR2_GET = 102;       // to xs_egg color plugin.
integer LINK_COLOR1_PUT = 103;       // to xs_egg color plugin.
integer LINK_COLOR2_PUT = 104;       // to xs_egg color plugin.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE












// 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 )
{
    if (! ENCRYPT)
        return 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 ) {
    if (! ENCRYPT)
        return 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+/";


// breed params

vector colour1;
vector colour2;
integer gen;
integer shine;
float glow;
string special;

// globals
string colourName1;    // new string to hold color name version 0.52
string colourName2;
key uuid;
integer listener;
integer owner_touch;

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, "Color: " + colourName1);
    llWhisper(0, "Color: " + colourName2);
    llWhisper(0, "Shine: " + myshine);
    llWhisper(0, "Glow: " + (string)((integer)(glow * 100)) + "%");
    llWhisper(0, "Special: " + special);
    llWhisper(0, "Generation: " + (string)gen);

    llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^"+ (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^XSPetEnd");
}

set_colours(vector c1, vector c2, integer shine, float glow)
{
    string msg = (string) c1 + "^" +
        (string) c2 + "^" +
        "0^" +        // sex is unknown in an egg
        (string) shine + "^" +
        (string) glow + "^";

    llMessageLinked(LINK_SET,LINK_TEXTURE,msg,NULL_KEY);        // tell the optional texture plugin

    llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, c2, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
    llSetLinkPrimitiveParams(3, [PRIM_COLOR, ALL_SIDES, c1, 1.0, PRIM_BUMP_SHINY, ALL_SIDES, shine, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, glow]);
    llMessageLinked(LINK_SET,LINK_COLOR1_GET,(string) colour1,"");    // V 0.52 send colors to plug in
    llMessageLinked(LINK_SET,LINK_COLOR2_GET,(string) colour2,"");
}

default
{
    state_entry()
    {
        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
        uuid = NULL_KEY;
        listener = llListen(BOX_CHANNEL, "", "", "");
    }

    touch_start(integer p)
    {
        llSay(0,"This " + EggCup + " is empty. Touch the " + Egg + " to pack it in the " + EggCup);
    }
    
    listen(integer channel, string name, key id, string msg)
    {

        if (llGetOwnerKey(id) != llGetOwner()) {        // must check key of owner, not CheckPerms
            return;
        }

        list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);

        if (uuid == NULL_KEY) {
            if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "CUP_PING") {
                uuid = id;
                llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^CUP_PONG^" + (string)VERSION));
                llSetTimerEvent(15.0);
            }
        } else if (uuid == id) {
                if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) == llGetKey()) {
                    llSetTimerEvent(0.0);
                    colour1 = (vector)llList2String(data, 2);
                    colour2 = (vector)llList2String(data, 3);
                    shine = (integer) llList2String(data, 4);
                    glow = (integer) llList2String(data, 5);
                    gen = (integer) llList2String(data, 6);
                    special = llList2String(data, 7);
                    llListenRemove(listener);
                    llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^CUP_DIE^"));
                    state full;
                } else
            if (llList2String(data, 0) == "XSPET" && llList2Key(data, 1) != llGetKey()) {
                uuid = NULL_KEY;
            }
        }
    }
    timer()
    {
        llSetTimerEvent(0.0);
        uuid = NULL_KEY;
    }
}

state full
{
    state_entry()
    {
        string my_special = "";
        if (special != "Normal") {
            my_special = "(" + special + ") ";
        }
        llSetObjectName(EggCup + ": " + 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) + ">");
        set_colours(colour1, colour2, shine, glow);
        llListen(API_CHANNEL, "", "", "");
        if (special != "Normal") {
            llSetText(special, <1,1,1>, 1.0);
        }
    }

    link_message(integer sender_number, integer number, string message, key id)
    {
        if (number == LINK_COLOR1_PUT)
        {
            colourName1 = message;
        } else if (number == LINK_COLOR2_PUT)
        {
            colourName2 = message;
        }
    }

   
    touch_start(integer num)
    {
        owner_touch = 0;

        say_details();

        if (llDetectedKey(0) == llGetOwner()) {
            owner_touch = 1;
            integer chan = (integer)llFrand(10000.0) + 1000;
            listener = llListen(chan, "", llGetOwner(), "");

            llDialog(llGetOwner(), "Would you like to unpackage me?", ["Yes", "No"], chan);
        }
        llSetTimerEvent(20.0);
    }

    timer()
    {
        //llOwnerSay("Menu timeout.");
        if (owner_touch == 1) {
            llListenRemove(listener);
        }
        llSetTimerEvent(0.0);
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == API_CHANNEL) {
            list data = llParseString2List(msg, ["^"], []);
            if (llList2String(data, 0) == "XSPet" && llList2Key(data, 1) == llGetKey()) {
                llSay(API_CHANNEL, "XSPet^" + (string)llGetKey() + "^"+ (string)colour1 + "^" + (string)colour2 + "^" + (string)shine + "^" + (string)glow + "^" + special + "^" + (string)gen + "^XSPetEnd");
            }
        } else {
                llListenRemove(listener);
            if (msg == "Yes") {
                state unbox;
            }
        }
    }
}

state unbox
{
    state_entry()
    {
        if (up_down)
            llRezObject(Egg, llGetPos() + POS_UP, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);
        else
        {
            vector pos = llGetPos();
            pos.z += - POS_DOWN.z;
            llSetPos(pos);
            llRezObject(Egg, llGetPos() + POS_DOWN, ZERO_VECTOR, ZERO_ROTATION, SECRET_NUMBER);

        }
    }

    object_rez(key id)
    {
        listener = llListen(BOX_CHANNEL, "", id, "");
    }

    listen(integer channel, string name, key id, string msg)
    {
        if (channel == BOX_CHANNEL) {
            list data = llParseString2List(xtea_decrypt_string(msg), ["^"], []);
            if (llList2String(data, 0) == "XSPET" && llList2String(data, 2) == "EGG_READY") {

                llGiveInventory(id, Egg );
                llGiveInventory(id, MaleName);
                llGiveInventory(id, FemaleName);

                llSay(EGG_CHANNEL, xtea_encrypt_string("XSPET^" + (string)id + "^UNBOX^" + (string)colour1 + "^" + (string)colour2 + "^" + (string)gen + "^" + (string)shine + "^" + (string)glow + "^" + special));
                llDie();
            }
        }
    }
}
 
home:
Code:
// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// This  section has a few tuneable items that MUST be changed for any new pet

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE


// 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 )
{
    if (! ENCRYPT)
        return 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 ) {
    if (! ENCRYPT)
        return 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+/";


default
{
    state_entry()
    {
        if (((integer) llGetObjectDesc()) == 0)
        {
            llOwnerSay("Distance set to 10 meters (default)");
            llSetObjectDesc("10");
        }


        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
        llListen(HOME_CHANNEL, "", "", "XSPET_PING_HOME");      // listen for a pet to say XSPET_PING_HOME - Mod by Ferd to listen to HOME_CHANNEL, not -237918

    }

    touch_start(integer total_number)
    {
        if (llDetectedKey(0) == llGetOwner()) {
            vector size = llGetScale();
            vector pos = llGetPos();

            pos.z = pos.z - size.z / 2;

            llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^HOME_LOCATION^" + (string)pos + "^" + llGetObjectDesc()));
        }
        llOwnerSay("Setting Home Location");
    }

    listen(integer channel, string name, key id, string msg)
    {
        vector size = llGetScale();
        vector pos = llGetPos();

        pos.z = pos.z - size.z / 2;

        llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^HOME_LOCATION^" + (string)pos + "^" + llGetObjectDesc()));
    }

    // set a default distance
    on_rez(integer start_param)
    {

        llResetScript();
    }

}
 
food:
Code:
integer FOOD_TYPE = 0;




// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE;        // set to TRUE TO hear a lot of chat


// Dieser Abschnitt hat ein paar abstimmbare Elemente, die für jedes neue Tier geändert werden müssen.

// SECURITY
string  SECRET_PASSWORD = "Hase";    // Passwort für jedes neue Tier ändern
integer SECRET_NUMBER = 99999;                       // Geheimzahl, nicht notwendig in der Regel zu ändern. Wird verwendet, wenn Haustiere neu geboren und Eier werden rezzed einen Kanal einzurichten.
integer ENCRYPT = FALSE;                           // True = Verschlüsselt (Empfehlenswert)

// wenn Sie die UUID für Ihren Avatar hier hinzufügen, können Sie sie später ändern Wenn Sie es leer lassen, kann nur der Ersteller der Rootprim auf diese Tiere zu arbeiten.
key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

// Tier Namen  - Sie müssen hier und im ROOTPRIM übereinstimmen
/////////////////////////
string MaleName = "Hase";        // Muss der Name des Tieres sein
string FemaleName = "Hase";        // Muss der gleiche Name sein wie beim Männlichen.
string Egg = "Nest";      // muss der Name des Ei´s sein
string Crate = "Transport Nest";   // was XS-Cryocrate, must be the name of the crate you package pets in
string HomeObject = "Home"; // was "XS Home Object", must be the name of your Home Post indicator
string EggCup = "Nestbox";      // was "XS Egg Cup", must be the name of your egg holder
// any other object names are 'do not cares'.

// NOTHING NEEDS TO BE CHANGED BELOW, BUT CAN BE CHANGED IF YOU DO IT EVERYWHERE

// misc tunables
float GROWTH_AMOUNT = 0.10;             // 10% size increase each day for MaxAge days = 200% (double size after 7 days)
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.
integer UNITS_OF_FOOD = 168;             // food bowl food qty, used by food bowl only
float secs_to_grow = 86400;              // grow daily = 86400 seconds
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;    // look for food every 3 hours
float fPregnancy = 172800.0;             // how many seconds to lay an egg  = 2 days or 48 hours.
float MALE_TIMEOUT = 1800.0 ;            // in seconds, female waits this long in one spot for a male to arrive
float SEX_WAIT = 10800.0;               // How often they desire sex = 3 hours
float fDaysToAdult = 7;                 // 7 days to become old enough to breed.
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;    // number of seconds to get hungry = 4 hours
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600;        // number of seconds before hunger count increases = 1 hour
integer MAXIMUM_HUNGER = 30;            // They die after a month with no food.


// I control versions by Subversion Source Code Control.  But the updater needs a version numbert in world.  
// This is the Protocol version.  If you change this, then all pets with a lower version will be updated by the updater
float VERSION = 0.50;            



// 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
float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet

// the following are global constants and do not need to be changed
// Prim animation linkmessages are sent by scripts on Link Message number 1
// The strings are the names of the animations that are recorded.
// 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
// If your pet walks, you need to record these names and save them in the notecard
//
// Example:
// llMessageLinked(LINK_SET, LINK_ANIMATE, ANI_STAND, "");
// The above line will play the pre-recorded 'stand up' animation "stand" using the animator script.
// The following animations are used in the pet.  You can add your own.

string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.

// Channel assignments
// if you change any of these constants, change it everywhere and in the list in XS_Debug so it can print them
// If you turn encryption FALSE, you MUST change these between species of pets are they will fuck with each other. Literally.

integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;

// global link messages to control the animal, never any need to change these.
// They are exposed here so they will be the same everywhere.  This uses a bit of RAM, but who cares?

integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE



// 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 )
{
    if (! ENCRYPT)
        return 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 ) {
    if (! ENCRYPT)
        return 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+/";




integer food_left;

// allow either a UUID to be entered, or not, and still maintain security
integer CheckPerms()
{
    if (YOUR_UUID != "" && llGetOwner() != YOUR_UUID)
        return 1;

    if (llGetOwner() != llGetCreator())
        return 1;

    return 0;
}


default
{
    state_entry()
    {
        if ( CheckPerms() ) {
            // someone not the creator reset the script. That's naughty.
            state dead;
        }

        llSetText("", <1,1,1>, 1.0);
        xtea_key = xtea_key_from_string(SECRET_PASSWORD);
        food_left = UNITS_OF_FOOD;
        llListen(FOOD_CHANNEL, "", "", "");
    }

    touch_start(integer total_number)
    {
        llSetTimerEvent(20.0);
        llSetText((string)food_left + " remaining.", <1,1,1>, 1.0);
    }

    timer()
    {
        llSetTimerEvent(0.0);
        llSetText("", <1,1,1>, 1.0);
    }

    listen(integer channel, string name, key id, string message)
    {
        list data = llParseString2List(xtea_decrypt_string(message), ["^"] , []);
        if (llList2String(data, 0) == "XSPET") {
            if (llList2String(data, 1) == "FOOD_LOCATION") {
                integer random_key = (integer) llList2String(data, 2);        // 0.43
                key animal_key = (key) llList2String(data, 3);
                llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FOOD_LOCATION^" + (string)random_key + "^" + (string)llGetPos() + "^" + (string)animal_key));
            }
            if (llList2String(data, 1) == "FOOD_CONSUME") {
                if ((key) llList2String(data, 2) == llGetKey()) {
                    integer random_key = (integer) llList2String(data, 3);
                    key animal_key = (key) llList2String(data, 4);
                    food_left--;
                    llMessageLinked(LINK_SET, DECREASE_FOOD, "1", "");
                    llSay(ANIMAL_CHANNEL, xtea_encrypt_string("XSPET^FOOD_CONSUME^" + (string)random_key + "^" + (string)animal_key + "^" + (string)FOOD_TYPE));
                    if (food_left <= 0) {
                        state empty;
                    }
                }
            }
        }
    }
}

state dead
{
    state_entry()
    {
        llSetText("This " + llGetObjectName() + " has been broken.", <1,0,0>, 1.0);
    }
}

state empty
{
    state_entry()
    {
        llSetObjectName(llGetObjectName() + " (Empty)");
        llSetText("Empty", <1,0,0>, 1.0);
    }
}
 
food animation:
Code:
integer PIE = FALSE; 



// DEBUG - lets you see and hear wtf is happening
integer debug = FALSE; 



// SECURITY
string  SECRET_PASSWORD = "Hase";  
integer SECRET_NUMBER = 99999; 
integer ENCRYPT = FALSE;  

key YOUR_UUID = "77ff4551-831b-4896-b5d1-600504814451";

/////////////////////////
string MaleName = "Hase"; 
string FemaleName = "Hase";
string Egg = "Nest";
string Crate = "Transport Nest"; 
string HomeObject = "Home"; 
string EggCup = "Nestbox";  

// misc tunables
float GROWTH_AMOUNT = 0.10; 
integer MaxAge = 7;  
integer UNITS_OF_FOOD = 168;
float secs_to_grow = 86400;
float FOOD_BOWL_SCAN_INTERVAL = 1800.0;
float fPregnancy = 172800.0; 
float MALE_TIMEOUT = 1800.0 ;
float SEX_WAIT = 10800.0;
float fDaysToAdult = 7; 
integer SECONDS_BETWEEN_FOOD_NORMAL = 14400;
integer SECONDS_BETWEEN_FOOD_HUNGRY = 3600; 
integer MAXIMUM_HUNGER = 30;  





float LegLength = 0.064;      // length of pet leg??? - not sure
float LegOffset = 0.052399;  // This is added to the Post Z to position the pet


string  ANI_STAND = "stand";             // default standing animation
string  ANI_WALKL   = "left";           // triggers Left foot and Right arm walk animation
string  ANI_WALKR   = "right";          // triggers Right foot and Left arm walk animation
string  ANI_SLEEP  = "sleep";           // Sleeping
string  ANI_WAVE = "wave";              // Calling for sex, needs help with food, etc.



integer FOOD_CHANNEL = -996091;
integer ANIMAL_CHANNEL = -996092;
integer EGG_CHANNEL = -996093;
integer HOME_CHANNEL = -996094;
integer BOX_CHANNEL = -996095;
integer ACC_CHANNEL = -996096;
integer UPDATE_CHANNEL = -996097;
integer API_CHANNEL = -996098;



integer LINK_ANIMATE = 1;          // messages on num 1 are assumed to be directed at the prim animator.
integer DECREASE_FOOD = 100;       // used in the food bowl.
integer LINK_AGE_START = 800;      // when pety  is rezzed and secret_number is sent by brain to breeder, eater and infomatic get booted up
integer LINK_TEXTURE = 801;        // ask for a new texture, or paint a color
integer LINK_BREEDNAME = 802;      // the name of the pet texture from the texture server notecard
integer LINK_FOOD_CONSUME = 900;   // from movement to brain when close to food, brain then consumes a random amount up to 10000
integer LINK_FOODMINUS = 901;    // xs_brain  receives FOOD_CONSUME, decrement hunger (eat)
integer LINK_HUNGRY = 903;        // sent by eater (string)hunger_amount, checks each hour
integer LINK_HAMOUNT = 904;       // hunger_amount = (integer)str,m updates the hunger amount in scripts
integer LINK_SET_HOME = 910;      // loc ^ dist
integer LINK_MOVER = 911;         // tell mover to rest for str seconds
integer LINK_FOODIE_CLR = 920;    // clear all food_bowl_keys and contents
integer LINK_FOODIE = 921;        // send FOOD_LOCATION coordinates to movement
integer LINK_COLOR1 = 930;             // colour1
integer LINK_COLOR2 = 931;             // colour2
integer LINK_SEX = 932;                // sex
integer LINK_SHINE = 933;              // shine
integer LINK_GLOW = 934;               // glow
integer LINK_GEN = 935;                // generation
integer LINK_RESET_SIZE = 936;          // reset size to 1
integer LINK_MAGE = 940;                // xs_brain sends, xs_ager consumes, adds str to age, if older than 7 days, will grow the animal
integer LINK_DAYTIME = 941;             // xs_ager consumes, starts a timer of 86,400 seconds in xs_ager
integer LINK_GET_AGE = 942;             // get age from xs_ager and sent it on channel 943
integer LINK_PUT_AGE = 943;             // print age from xs_ager
integer LINK_PACKAGE = 950;             // look for a cryo_crate
integer LINK_SEEK_FEMALE = 960;         // MALE_BREED_CALL
integer LINK_MALE_BREED_CALL = 961;     // triggered by LINK_SEEK_FEMALE
integer LINK_SIGNAL_ELIGIBLE = 962;     // sent by female when hears LINK_MALE_BREED_CALL
integer LINK_FEMALE_ELIGIBLE = 963;     // sent when it hears in chat FEMALE_ELIGIBLE
integer LINK_CALL_MALE = 964;           // if LINK_FEMALE_ELIGIBLE && looking_for_female
integer LINK_MALE_ON_THE_WAY = 965;     // triggered by LINK_CALL_MALE
integer LINK_FEMALE_LOCATION = 966;     // female location, sends coordinates of a female
integer LINK_RQST_BREED  = 967;         // sent when close enough to male/female
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.
integer LINK_MALE_INFO = 969;           // Breeding failed, sent info
integer LINK_LAY_EGG = 970;             // Rez Object(Egg...
integer LINK_BREED_FAIL = 971;          // key = father, failed, timed out
integer LINK_PREGNANT = 972;            // chick is preggers
integer LINK_SOUND_OFF= 974;             // sound is off
integer LINK_SOUND_ON= 973;             // sound is on
integer LINK_SLEEPING = 990;            // close eyes
integer LINK_UNSLEEPING = 991;          // open eyes
integer LINK_SOUND = 1001;              // plays a sound if enabled
integer LINK_SPECIAL = 1010;            // xs_special, if str = "Normal", removes script
integer LINK_EFFECTS_ON = 2000;         // particle effects in the packger
integer LINK_PREGNANCY_TIME = 5000;    // in seconds as str
integer LINK_SLEEP = 7999;              // disable sleep by parameter
integer LINK_TIMER = 8000;              // scan for food bowl about every 1800 seconds
integer LINK_DIE = 9999;                // death

string Copyright = " (c)2014 by Ferd Frederix";    // You cannot change this line, but you can change the code that prints it!
// See License agreements above.
//  Attribution is required, as these files are copyrighted. 


DEBUG ( string msg){
    if (debug) {
        llOwnerSay(llGetScriptName() + ":" + msg);
    }
}



///////// end global Link constants ////////

// END OF COPIED CODE




// globals

integer food_left;
// code

// allow either a UUID to be entered, or not, and still maintain security
integer CheckPerms()
{
    if (YOUR_UUID != "" && llGetOwner() != YOUR_UUID)
        return 1;

    if (llGetOwner() != llGetCreator())
        return 1;

    return 0;
}
default
{
    state_entry()
    {
        food_left = UNITS_OF_FOOD;

        if ( ! CheckPerms() )        // V .30 was backwards, needed the !
        {
            float i = 0 ;
            while (i <= 1.01)
            {
                if (PIE)
                    llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_CYLINDER, PRIM_HOLE_DEFAULT, <0, i, 0>, 0, <0, 0, 0>, <1.0, 1.0, 0.0>, <0,0,0>]);
                else
                    llOffsetTexture(1,1 - i/2,ALL_SIDES);

                llSleep(.5);
                i += .1 ;
            }
            llOffsetTexture(1,1,ALL_SIDES);
        }
    }

    link_message(integer sender, integer number, string str, key id)
    {
        if (number == DECREASE_FOOD) {
            // its a decrease message
            integer amount = (integer)str;

            food_left = food_left - amount;


            if (PIE)
            {
                // do the pie slice thing
                float cut_amount = ((float)food_left / (float)UNITS_OF_FOOD) * 0.95;
                llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_CYLINDER, PRIM_HOLE_DEFAULT, <0, cut_amount, 0>, 0.0, <0, 0, 0>, <1.0, 1.0, 0.0>, <0,0,0>]);
            }
            else
            {
                // do the vertical plasma draining effect

                float offset_amount = 1 - ((float)food_left / (float)UNITS_OF_FOOD) /2;

                llOffsetTexture(1,offset_amount,ALL_SIDES);    // slide the texture
            }
        }
    }
}

Server Textur:
Code:
string UUID = "a21f0bda-653c-4e62-9601-ce100886752f";
integer debug = TRUE;  // set to 1 or TRUE for debuging information to the owner
integer LSLEDIT = TRUE;   // set to TRUE if debugging in LSLEditor as it does not support the HTTP headers we need.
                          // Type  "POST" in the [method] field and click [http_response]
                          // You should get a response based on "teststring" below        
float testBreed = 0.01;
 // 1/13/2, 1/2 the number of textures.
//for testing to fake out HTTP traffic for a breed value of whatever this string is.
// 0.0 is the first, 1.0 is the last
float testIncrement = 0.076923077;
// 1/13 , the number of test textures

integer testCounter = 0;    // just for testing in LSLEditor.
//////////////////////////////////////////////////////////
//                     INTERNALS                        //
//////////////////////////////////////////////////////////

key notecardQueryId;
string notecardName = "Breeds";        // the notecard
integer notecardLine; // script-wise, the first notecard line is line 0, the second line is line 1, etc.

list textureDB;       // texture storage
integer nTextures;    // how many we find
integer nServed;        // how many we served
integer nPrims ;        // how many prims there must be
integer nBreeds;        // how man breeds
list lNames;            // a list of names
list lBreedNames;       // a list of breed names read from the notecard
key gtextureUUID;       // The UUID of the detected texture
string gtextureName;    // the name of the detected texture
key URLReq = NULL_KEY;
string url;            // sop we can release HTTP-In keys
key urlRequestId;


getNoteCard()
{
    notecardLine = 0;
    notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
}


request_url()
{
    DEBUG("get URL");
    llReleaseURL(url);
    url = "";
 
    urlRequestId = llRequestURL();
}

getImage(integer breedNum)
{

    DEBUG("Seeking Number " + (string) breedNum );

    integer i;
    integer j = llGetListLength(textureDB);
    for (i = 0; i < j; i += 3)      
    {
        integer myBreedParam =  llList2Integer(textureDB,i);   
        string humanName = llList2String(textureDB,i+1);
        key UUID = llList2Key(textureDB,i+2);

        gtextureName = humanName;
        gtextureUUID = UUID;

        if (myBreedParam >= breedNum )
        {
             DEBUG("saving " +  humanName + " " + (string) myBreedParam);
            return;
        }

    }
    
    return;
}

list ListUnique( list lAll ) {
    integer i;
    list lFiltered = llList2List(lAll, 0, 0);
    integer iAll = llGetListLength( lAll );
    for (i = 1; i < iAll; ++i) {
        if ( llListFindList(lFiltered, llList2List(lAll, i, i) ) == -1 ) {
            lFiltered += llList2List(lAll, i, i);
        }
    }
    return lFiltered;
}
list parsePostData(string message)
{
    list postData = [];         
    list parsedMessage = llParseString2List(message,["&"],[]);    
    integer len = ~llGetListLength(parsedMessage);

    while(++len) {
        string currentField = llList2String(parsedMessage, len); 

        integer split = llSubStringIndex(currentField,"=");     
        if(split == -1) { 
            postData += [llUnescapeURL(currentField),""];
        } else {
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];
        }
    }
    
    return postData ;
}


getTextures()
{
    textureDB = [];
    lNames = [];

    integer j = llGetInventoryNumber(INVENTORY_TEXTURE);
    integer i;

    for (i = 0; i < j ; i++)
    {
        string textureName = llGetInventoryName(INVENTORY_TEXTURE,i);
        list splits = llParseString2List(textureName,[" "],[]);
       
        string humanName = llList2String(splits,0);
        integer breedParam = (integer) llList2String(splits,1);
        key UUID = llGetInventoryKey(textureName);

        textureDB += breedParam;
        textureDB += humanName;        
        textureDB += UUID;
        lNames += humanName;
    }
    
    nTextures = llGetListLength(textureDB)/3;      
    lNames = ListUnique(lNames);
    nPrims = llGetListLength(lNames);
    if (nPrims == 0) {
        llOwnerSay("No Textures!");
        nPrims = 1; // prevent divide by zero errors.
    }
    
    DEBUG("Number of colorable prims = " + (string) nPrims);

    nBreeds = nTextures / nPrims;

    textureDB = llListSort(textureDB,3,1);  

    DEBUG("Number of textures = " + (string) nTextures);
    DEBUG("Number of breeds = " + (string) nBreeds);

    llSetText("Textures Loaded",<0,1,0>,1.0);

    request_url();
}


string getTexture(string body)
{
    DEBUG("Parsing " + body);
    list incomingMessage = parsePostData(body);

     // fake out a http header
    if (LSLEDIT)
        incomingMessage = llParseString2List(body,["="],[]);

                
    DEBUG("Params: " + llDumpList2String(incomingMessage,"\n"));
    
    if (llList2String(incomingMessage,0) == "breed")
    {
        float myBreed = (float) llList2String(incomingMessage,1);        
        DEBUG("myBreed = " + (string) myBreed);
        if (myBreed > 1)
            myBreed = 1;
        
        integer myBreedNum = llFloor((myBreed * (nBreeds)));
        DEBUG("myBreedNum = " + (string) myBreedNum);
        
        string Name = llList2String(lBreedNames,myBreedNum);

        string response = Name + "|";        // frst param is the notecard line
        
        DEBUG("Scanning for Breed named: " + Name + " for value = " + (string) myBreed);

        llSetText("Served:" + (string) nServed + "\nLast Breed:"+ (string) Name ,<1,1,1>,1.0);
        
        integer i;        
        for (i = 0; i < nPrims; i++)
        {
            string breedName = llList2String(lNames,i);

            getImage(myBreedNum);
            response += gtextureName + "|";
            response += (string) gtextureUUID + "|";
        }

        // LSLEDIT DIAGNOSTOCS 
        if (LSLEDIT)
        {
            DEBUG("test # "+(string) testCounter);
            DEBUG("Name "+ Name);
            DEBUG("S.b. "+ llList2String(lBreedNames,testCounter));
            
            if ( Name == llList2String(lBreedNames,testCounter))
            {
                DEBUG("test Passed************");
            } else {
                DEBUG("test Failed************");
            }
            
        }
        return "texture|" + response;
    }
    return "texture|blank|blank|" + (string) TEXTURE_BLANK;   // no name, no prim type, no texture
}

key Request(string URL)
{
    llSetText("Registering",<1,1,1>,1.0);
    string url = "http://gridurl.appspot.com/reg?service=" + UUID + "&url=" + llEscapeURL(URL) + "/";
    return  llHTTPRequest( url, [HTTP_METHOD, "GET"], "");
}
  

throw_exception(string inputString)
{
    key owner = llGetOwner();
    llInstantMessage(owner, inputString);
    llSleep(60);        // so we do not flood owner with IM's
    llResetScript();
}




DEBUG(string msg)
{
    if (debug)
        llSay(0,llGetScriptName() + " : " + msg);
}


default
{
    state_entry()
    {
        getNoteCard();
        llSetText("Initializing",<1,1,1>,1.0);
    }
    on_rez(integer param)
    {
        llResetScript();
    }

    
    http_request(key id, string method, string body)
    {
        DEBUG("Response:" + body);
        if (method == URL_REQUEST_GRANTED)
        {
            DEBUG(body);
            url = body;    // save body response so we can release it.
            URLReq = Request(body);
        }
        else if(method == URL_REQUEST_DENIED)
        {
            llOwnerSay("ERROR: URL REQUEST was DENIED "+body);
            llSetText("ERROR: URL REQUEST was DENIED",<1,0,0>,1.0);
            llSleep(5);
            llResetScript();
        }
        else if(id == URLReq)
        {
            if (body == "OK")
            {
                llSetText("OK",<1,0,0>,1.0);
            }
            else
            {
                llSetText("Unable to register",<0,0,1>,1.0);
            }
        }
        else if(method == "POST")
        {
                    
            nServed++;
            string resp;
            if (LSLEDIT) {
                resp = getTexture("breed=" + (string) testBreed);
                testBreed += testIncrement;    // 1/13
                testCounter++;
            }
            else
                resp = getTexture(llGetHTTPHeader(id, "x-query-string"));
            DEBUG("Response:" + resp);
            llHTTPResponse(id, 200, resp);
             

        }
        else
        {
            llSetText("Not Implemented",<1,0,0>,1.0);
            llHTTPResponse(id, 501, "Not Implemented "+method);
        }
    }
    http_response(key request_id, integer status, list metadata, string body)
    {
        if(URLReq == request_id)
        {
            URLReq = NULL_KEY;       
            if(status == 200)
            {
                llSetText("Ok",<1,1,1>,1.0);
            }
            else
            {
                llSetText("Request failed",<1,0,0>,1.0);
                llOwnerSay("Request failed status="+(string)status+" "+body);
                llSleep(10);
                request_url();
            }
        }
    }

     dataserver(key query_id, string data)
    {
        if (query_id == notecardQueryId)
        {
            if (data == EOF) {
                llSetText("Done reading notecard.\n" + (string) llGetListLength(lBreedNames)  + " breeds saved.",<1,1,1>,1.0);
                DEBUG("Notecard contained: " + llDumpList2String(lBreedNames,","));
                getTextures();
            }
            else
            {

                list stuff = llParseString2List(data,[" "],[]);
                string comment = llList2String(stuff,0);
                if (comment != "//") {
                    lBreedNames += data;
                    DEBUG( "Reading Breed name =" + data );
                }
                // bump line number for reporting purposes and in preparation for reading next line
                ++notecardLine;
                notecardQueryId = llGetNotecardLine(notecardName, notecardLine);
            }
        }
    }

    changed (integer what)
    {
        if (what & CHANGED_INVENTORY)
        {
            getNoteCard();
        }

         if (what & (CHANGED_REGION_START ))
        {
            llReleaseURL(url);
            llResetScript();
        }

    }
}
 

Users who are viewing this thread

Zurück
Oben Unten