The Starter Egg
The starter egg is similar to the ordinary egg script, except it doesn’t need to be birthed, so we can remove some code. We do need to decide how we will choose the starter trait, be it random or set. Often colour based breedables start with primary colours (Red, Green or Blue) however in this tutorial it will just be random.
We will need to make two versions of this script, one for male and one for female. It is possible to let the egg choose a random sex, however that is not popular anymore as sometimes people buy starter kits and get all the same sex, which is a bit unfair.
We start the script with the global variables
integer EGG_CHANNEL = -894339;
string SUPER_SECRET_KEY = "supersecret";
integer SECRET_REZ_NUMBER = 8329329;
vector my_colour_trait;
integer my_sex = 0;
integer dialog_channel;
integer dialog_listener;
Notice how my_sex = 0, this means this script will be for a male starter egg, change it to 1 for a female starter egg.
Next include the XTEA code from Part 1.
Then our default state which will be the main difference between the starter egg and the normal egg.
default {
state_entry() {
xtea_key = xtea_key_from_string(SUPER_SECRET_KEY);
llSetText("Touch to begin", <1,1,1>, 1.0);
}
touch_end(integer detected) {
if (llDetectedKey(0) == llGetOwner()) {
my_colour_trait.x = llFrand(1);
my_colour_trait.y = llFrand(1);
my_colour_trait.z = llFrand(1);
llSetColor(my_color_trait, ALL_SIDES);
state full;
}
}
}
The rest of the script is identical to the normal egg script with one exception - there is no need for a dead state.
state full {
state_entry() {
if (my_sex == 0) {
llSetText("Egg\nColour: " + (string)my_colour_trait + "\nSex: Male\n \nClick to Birth", <0.384, 0.694, 1.000>, 1.0);
} else {
llSetText("Egg\nColour: " + (string)my_colour_trait + "\nSex: Female\n \nClick to Birth", <1.000, 0.710, 1.000>, 1.0);
}
dialog_channel = (integer)llFrand(1000000) - 1000001;
}
touch_start(integer detected) {
if (llDetectedKey(0) == llGetOwner()) {
llListenRemove(dialog_listener);
dialog_listener = llListen(dialog_channel, "", llGetOwner(), "");
llSetTimerEvent(60);
llDialog(llGetOwner(), "Hatch this Egg?", ["YES", "NO"], dialog_channel);
}
}
timer() {
llListenRemove(dialog_listener);
llSetTimerEvent(0);
}
listen(integer channel, string sender, key id, string message) {
llListenRemove(dialog_listener);
llSetTimerEvent(0);
if (message == "YES") {
state birth;
}
}
}
state birth {
state_entry() {
llListen(EGG_CHANNEL, "", "", "");
llSetTimerEvent(60);
llRezObject("Pet", llGetPos(), ZERO_VECTOR, ZERO_ROTATION, SECRET_REZ_NUMBER);
}
listen(integer channel, string sender, key id, string message) {
if (llGetOwnerKey(id) == llGetOwner()) {
list data = llParseString2List(xtea_decrypt_string(message), ["^"], []);
if (llList2String(data, 0) == "PET_READY" && (key)llList2String(data, 1) == id) {
llGiveInventory(id, "Pet");
llGiveInventory(id, "Egg");
llRegionSayTo(id, EGG_CHANNEL, xtea_encrypt_string("PET_DATA^" + (string)my_colour_trait + "^" + (string)my_sex));
llSetTimerEvent(0);
llSleep(2);
llDie();
}
}
}
timer() {
llInstantMessage(llGetOwner(), "Birthing failed. Please try again.");
llSetTimerEvent(0);
state full;
}
}
Putting it together
First create your egg object and your pet object, set their descriptions to 0.1 and put your scripts in them, ensure they are no copy / no mod / transfer ok, then take the egg object and pet object into your inventory. Rezz two more egg objects (these will be your starter eggs, you can colour them pink and blue if you like). Put each version of the starter egg script in the corrosponding egg. Next is the tricky part…
Edit a starter egg and go to it’s contents, drag your pet object and egg object from your inventory into the starter eggs inventory. Next right click the pet object and set to copy. You must do this inside the edit window, not rezzed out on the ground. Do the same for the egg object, then repeat for the other starter egg.
Change the description to 0.1 and your starter eggs are ready! Take them into your inventory so you have backups and rez them out to hatch them!