// Chick'n'Egg v006-002-040 // a Second Life-form by RaddDadd Upshaw //Rezzed egg (G1) should contain // 1. this script, running // 2. a copy (G2) of the egg, // containing this script, running list Prim_Positions = [ < 0.000, 0.000, 0.000 >, // Root Egg < 0.000, 0.000, 0.020 >, // Body < 0.000, -0.010, 0.020 >, // Tail < 0.000, -0.015, 0.031 >, // Neck < 0.000, 0.003, 0.041 >, // Head < 0.018, 0.014, 0.044 >, // RtEye <-0.019, 0.009, 0.046 >, // LtEye < 0.000, 0.028, 0.026 >, // Beak < 0.000, 0.000, 0.000 >, // Root Chk < 0.000, 0.000, 0.049 >, // Body < 0.000, -0.056, 0.089 >, // Tail < 0.000, 0.040, 0.082 >, // Neck < 0.000, 0.057, 0.092 >, // Head < 0.018, 0.068, 0.095 >, // RtEye <-0.019, 0.064, 0.097 >, // LtEye < 0.000, 0.083, 0.077 >, // Beak < 0.000, 0.000, 0.000 >, // Root Hen < 0.000, 0.000, 0.243 >, // Body < 0.000, -0.280, 0.444 >, // Tail < 0.000, 0.200, 0.408 >, // Neck < 0.000, 0.287, 0.460 >, // Head < 0.035, 0.338, 0.475 >, // RtEye <-0.029, 0.318, 0.484 >, // LtEye < 0.000, 0.413, 0.384 >, // Beak < 0.000, 0.000, 0.000 >, // Root Rest < 0.000, 0.000, 0.056 >, // Body < 0.000, -0.339, 0.075 >, // Tail < 0.000, 0.143, 0.150 >, // Neck < 0.000, 0.256, 0.154 >, // Head < 0.036, 0.292, 0.145 >, // RtEye <-0.032, 0.284, 0.159 >, // LtEye < 0.000, 0.320, 0.024 > // Beak ]; list Prim_Sizes = [ < 0.010, 0.060, 0.060 >, // Root Chk < 0.100, 0.100, 0.100 >, // Body < 0.010, 0.060, 0.060 >, // Tail < 0.020, 0.020, 0.028 >, // Neck < 0.050, 0.050, 0.050 >, // Head < 0.020, 0.020, 0.020 >, // RtEye < 0.020, 0.020, 0.020 >, // LtEye < 0.040, 0.040, 0.040 >, // Beak < 0.050, 0.300, 0.300 >, // Root Hen < 0.300, 0.500, 0.400 >, // Body < 0.010, 0.300, 0.300 >, // Tail < 0.050, 0.050, 0.141 >, // Neck < 0.154, 0.100, 0.227 >, // Head < 0.050, 0.050, 0.050 >, // RtEye < 0.050, 0.050, 0.050 >, // LtEye < 0.100, 0.050, 0.200 > // Beak ]; list Prim_Rots = [ < 0.00, 0.00, 0.00 >, // Root Standing < 0.00, 0.00, 0.00 >, // Body < 33.55, 0.00, 90.00 >, // Tail < 310.00, 0.00, 90.00 >, // Neck < 257.00, 0.00, 90.00 >, // Head < 0.00, 0.00, 0.00 >, // RtEye < 0.00, 0.00, 0.00 >, // LtEye < 242.65, 0.00, 90.00 >, // Beak < 0.00, 0.00, 0.00 >, // Root Resting < 0.00, 0.00, 0.00 >, // Body < 112.50, 0.00, 90.00 >, // Tail < 280.00, 0.00, 90.00 >, // Neck < 228.00, 0.00, 90.00 >, // Head < 0.00, 0.00, 0.00 >, // RtEye < 0.00, 0.00, 0.00 >, // LtEye < 217.00, 0.00, 90.00 > // Beak ]; list Stage_Age = [ //morphing durations should be exact multiples of total prims times heartbeat // Dur # Age State Peck & Morph (Birdbrain only) 32.0, // 0 embryonic EggTimer 64.0, // 1 hatching Birdbrain Y Y 32.0, // 2 young Y 64.0, // 3 maturing Y Y 64.0, // 4 adult Y 32.0, // 5 settling No Y 32.0, // 6 laying Laying 32.0, // 7 rising Birdbrain Y Y 128.0, // 8 old Y 32.0, // 9 expiring No Y 64.0 //10 fading Fadeout ]; list Stage_Name = [ "embryonic", "hatching", "young", "maturing", "adult", "settling", "laying", "rising", "old", "expiring", "fading" ]; list Patterns = [ //at least 3 textures are required or script fails "b1b96368-ce26-8eda-aac6-5efad53aa51b", //Floor Tile 3 (beige) "b00fd16f-1b5a-8667-bf61-90d960b8112a", //Denim "0444bf21-f77e-7f63-89e9-b839ec66bc15", //Blue Plasma "61255acc-b70a-51b5-a2eb-3eb96e327dd1", //Burlap "c6c1ee60-72b5-4cf9-a75f-aaad4192ddf9", //Light Moss "2d56afdf-9541-70b1-0342-820cd826d635", //Leopard "c7f1beb3-4c5f-f70e-6d96-7668ff8aea0a", //Granite "18cfbfd6-ad39-11d5-9d21-00d0b7c730a8", //American Flag "a9a32bf2-7085-98f2-ab25-ac5c6854bd19", //Zebra Skin "e98661c3-8c05-30c5-06ad-897e933b4c45", //Tie-Dye "47ecfbee-2a28-92a8-4359-1c767040657d", //Pinktoile "75c0ae9b-bd5a-12f7-bfce-311271475122", //Bricks "530c88fe-647c-e127-b716-0c6001479cdf", //Peeling Paint "f39ca3bf-0058-9cd6-2a56-dd198a992fc0", //Blue-White Gingham "953a7e95-8cdb-c0f7-d251-996564a7dc67", //Plaid 1 "1a661817-070d-5f9c-2f00-4d6f0c3e7573", //Plaid 2 "47204770-1b0a-192f-9d46-48bd8afe0a42", //Wallpaper - Black and Green floral "b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d", //Smoke "e00b6ea4-7a3b-b6fc-e8b7-107e2be6e301", //Plywood "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903" //Default Transparent ]; //Timing and Stages of Growth float Heartbeat = 0.5; integer AgeDuration; string AgeName; integer AgeStage; float countBeats; integer TotalPrims; integer countPrims; //Peck integer Tilted; integer Pecking; float henPeck; integer countPecks; //Pivot float MaxPivot = 30; //Wander vector posOrigin; float tooClose = 0.75; float tooFarAway = 10.0; float maxMove = 0.25; float maxMove2Owner = 0.1; float Corral = 3.5; vector posCurr; //Morphing integer Morphing = FALSE; float frameMorph; float stepMorph; //Size integer orig_size_offset; integer dest_size_offset; vector orig_size; vector dest_size; vector new_size; //Rotation vector orig_rot; vector dest_rot; vector new_rot; //Position integer orig_pos_offset; integer dest_pos_offset; vector orig_pos; vector dest_pos; vector new_pos; //Color & Transparency vector orig_Leather = < 0.0, 0.0, 0.0 >;// #1 Root, #6 & #7 Eyes, & #8 Beak vector orig_Feather = < 0.5, 0.5, 0.0 >;// all the rest vector orig_Color; vector dest_Leather; vector dest_Feather; vector dest_Color; vector new_Color; float viz; //Texture string tex_Leather; string tex_Feather; vector tex_repeat; vector tex_offset; float tex_rot; //Interactive string BirthTime; string BirthPlace; integer textViz = FALSE; vector textColor = < 1.0, 1.0, 0.0 >; float textAlpha = 1.0; integer OwnerEar; integer Sign( float inp ){ if( inp < 0 ){ return - 1; } else if ( inp > 0 ){ return 1; } else return 0; } float Limit( float Unlimited, float UpperLimit ){ if( llFabs( Unlimited ) > UpperLimit ) Unlimited = UpperLimit * Sign( Unlimited ); return Unlimited; } Initialize(){ BirthTime = llGetTimestamp(); BirthPlace = llGetRegionName() + " " + (string) llGetPos(); //TotalPrims = 8; //for testing TotalPrims = llGetNumberOfPrims(); AgeStage = -1; Tilted = 1; Pecking = FALSE; henPeck = -45; orig_size_offset = 0; dest_size_offset = TotalPrims; posOrigin = llGetPos(); orig_size = llList2Vector( llGetPrimitiveParams( [PRIM_SIZE] ), 0 ) / 2; posOrigin.z -= orig_size.z / 2; orig_size = < 0, 0, 0 >; orig_pos = < 0, 0, 0 >; dest_size = < 0, 0, 0 >; dest_pos = < 0, 0, 0 >; dest_Leather = < llFrand( 0.75 ), llFrand( 0.75 ), llFrand( 0.75 ) >; dest_Feather = < llFrand( 0.75 ) + 0.25, llFrand( 0.75 ) + 0.25, llFrand( 0.75 ) + 0.25 >; integer tex1 = (integer) llFrand( llGetListLength( Patterns ) - .001 ); tex_Feather = llList2String( Patterns, tex1 ); integer tex2; do tex2 = (integer) llFrand( llGetListLength( Patterns ) - 1 ); while ( tex2 == tex1 ); tex_Leather = llList2String( Patterns, tex2 ); float TexRepX = llFrand( llFrand( llFrand( 100 ))); float TexRepY; if( llFrand( 2 ) > 1 ){ // 1/2 the time, x & y repeats are equal TexRepY = TexRepX; } else { TexRepY = llFrand( llFrand( llFrand( 100 ))); } tex_repeat = < TexRepX, TexRepY, 0 >; tex_offset = < llFrand( 2 ) - 1, llFrand( 2 ) - 1, 0 >; tex_rot = DEG_TO_RAD * llFrand( 360 ); } NewStage(){ if( textViz ) SelfReport(); AgeStage ++; countBeats = 0; AgeName = llList2String( Stage_Name, AgeStage ); AgeDuration = llList2Integer( Stage_Age, AgeStage ); } SelfReport() { string msg; textViz = !textViz; if( textViz ){ msg = "Gen #" + (string) ( llGetStartParameter() + 1 ) + ", currently " + AgeName + "\nLaid " + llGetSubString( BirthTime, 0, 9 ) + " " + llGetSubString( BirthTime, 11, 15 ) + " at " + BirthPlace + "\n \nmindfulwebworks.com/\nsecond-life/\nchick'n'egg.html\n\n\n\n\n\n\n\n\n\n\n "; } else { msg = ""; } llSetText( msg, textColor, textAlpha ); } Peck(){ rotation rotPeck = llEuler2Rot( < henPeck * Tilted, 0.0, 0.0 > ); llSetRot( rotPeck * llGetRot() ); Tilted = -Tilted; } Pivot(){ llSetRot( llEuler2Rot( < 0.0, 0.0, llFrand( MaxPivot ) - MaxPivot/2 > ) * llGetRot() ); } Wander(){ vector targCorral; posCurr = llGetPos(); vector rootsize = llList2Vector( llGetPrimitiveParams( [PRIM_SIZE] ), 0 ); //get distance to Center float farAway = llVecDist( posOrigin, posCurr ); //if outside the corral OR not at intended height if(( farAway > Corral ) || (( posCurr.z ) != ( posOrigin.z + ( rootsize.z / 2 )))) { targCorral = posOrigin - posCurr; targCorral.z += rootsize.z / 2; targCorral.x = Limit( targCorral.x, maxMove ); targCorral.y = Limit( targCorral.y, maxMove ); targCorral.z = Limit( targCorral.z, maxMove ); } vector targOwner; list detailOwner = llGetObjectDetails( llGetOwner(), [ OBJECT_POS ]); //only if owner is in sim integer detOwnLen = llGetListLength( detailOwner ); if( detOwnLen > 0 ){ //get owner's position vector posOwner = llList2Vector( detailOwner, 0 ); //get XY distance between farAway = llSqrt( llPow( posCurr.x - posOwner.x, 2 ) + llPow( posCurr.y - posOwner.y, 2)); //don't bother about owner if too far away if( farAway < tooFarAway ){ //target owner targOwner = posOwner - posCurr; //veer toward owner integer whichway = 1; if( farAway < tooClose ) whichway = -1; targOwner.x = Limit( targOwner.x, maxMove2Owner ) * whichway; targOwner.y = Limit( targOwner.y, maxMove2Owner ) * whichway; targOwner.z = 0; } } //combine corral seek & owner veer + random vector targRandom = < llFrand( maxMove * 2 ) - maxMove, llFrand( maxMove * 2 ) - maxMove, 0 >; vector vecMove = targCorral + targOwner + targRandom; // llOwnerSay("targCorral = " + (string) targCorral // +"\ntargOwner = " + (string) targOwner // +"\ntargRandom = " + (string) targRandom ); //govern move vecMove.x = Limit( vecMove.x, maxMove ); vecMove.y = Limit( vecMove.y, maxMove ); Pivot(); llSetPos( posCurr + vecMove ); Pivot(); } SetMorphOffsets(){ if( AgeName == "hatching" ){ // Egg to Chick orig_pos_offset = 0; //orig pos is egg dest_pos_offset = TotalPrims; //dest pos is chick } else if ( AgeName == "maturing" ){// Chick to Hen (sizes change) orig_pos_offset = TotalPrims; //orig pos is chick dest_pos_offset = 2 * TotalPrims; //dest pos is hen } else if ( ( AgeName == "settling" // Settle to Nest || AgeName == "expiring" ) ){ // OR Settle at last orig_pos_offset = 2 * TotalPrims; //orig pos is hen in stage 6 or 10 dest_pos_offset = 3 * TotalPrims; //dest pos is rest in stage 6 or 10 } else if ( AgeName == "rising" ){ // Rise from Nest orig_pos_offset = 3 * TotalPrims; //orig pos is rest dest_pos_offset = 2 * TotalPrims; //dest pos is hen } frameMorph = 1/(AgeDuration/Heartbeat/TotalPrims); } Morph(){ list MorphList = []; if( countPrims == 0 ){ stepMorph = 1-(( countBeats / AgeDuration ) + frameMorph); } if( AgeName == "maturing" ){ string txtur; if(( countPrims > 0 ) && ( countPrims < 5 )){ // FEATHER: #2 Body, #3-5, Tail, Neck, & Head dest_Color = dest_Feather; orig_Color = orig_Feather; txtur = tex_Feather; } else { // LEATHER: #1 Root, #6 & #7 Eyes, & #8 Beak dest_Color = dest_Leather; orig_Color = orig_Leather; txtur = tex_Leather; } new_Color = ( dest_Color - orig_Color ) * stepMorph; new_Color = dest_Color - new_Color; vector incr_tex_repeat = < ( 100 - tex_repeat.x ) *stepMorph + tex_repeat.x, ( 100 - tex_repeat.y ) *stepMorph + tex_repeat.y, 0 >; // tex_offset = < llFrand( 2 ) - 1, llFrand( 2 ) - 1, 0 >; // tex_rot = DEG_TO_RAD * llFrand( 360 ); MorphList = [ PRIM_COLOR, ALL_SIDES, new_Color, 1.0, PRIM_TEXTURE, ALL_SIDES, txtur, incr_tex_repeat, tex_offset, tex_rot ]; dest_size = llList2Vector( Prim_Sizes, countPrims + dest_size_offset ); orig_size = llList2Vector( Prim_Sizes, countPrims + orig_size_offset ); new_size = ( dest_size - orig_size ) * stepMorph; new_size = dest_size - new_size; //adjust root position relative to current position with size change if ( countPrims == 0 ){ new_pos = llGetPos(); new_pos.z += ( dest_size.z - orig_size.z ) * frameMorph / 2; MorphList = llListInsertList( MorphList, [ PRIM_SIZE, new_size, PRIM_COLOR, ALL_SIDES, new_Color, 1.0, PRIM_POSITION, new_pos ], llGetListLength( MorphList ) ); } } if( countPrims > 0 ){ //child positions relative to root dest_pos = llList2Vector( Prim_Positions, countPrims + dest_pos_offset ); orig_pos = llList2Vector( Prim_Positions, countPrims + orig_pos_offset ); new_pos = ( dest_pos - orig_pos ) * stepMorph; new_pos = dest_pos - new_pos; MorphList = llListInsertList( MorphList, [ PRIM_POSITION, new_pos ], llGetListLength( MorphList ) ); //sizes if( AgeName == "maturing" ){ MorphList = llListInsertList( MorphList, [ PRIM_SIZE, new_size], llGetListLength( MorphList ) ); } //rotations if(( AgeName == "settling" ) || ( AgeName == "expiring" ) || ( AgeName == "rising" ) ){ dest_rot = llList2Vector( Prim_Rots, countPrims + TotalPrims * ( AgeName != "rising" )); if( dest_rot != < 0, 0, 0 > ){ orig_rot = llList2Vector( Prim_Rots, countPrims + TotalPrims * ( AgeName == "rising" )); new_rot = ( dest_rot - orig_rot ) * stepMorph; new_rot = dest_rot - new_rot; vector new_radians = ( new_rot * DEG_TO_RAD ); rotation modrot = llEuler2Rot( new_radians ) / llGetRot(); MorphList = llListInsertList( MorphList, [ PRIM_ROTATION, modrot ], llGetListLength( MorphList ) ); } } } if( ( AgeName == "maturing" ) || ( countPrims > 0 ) ){ llSetLinkPrimitiveParams( countPrims + 1, MorphList ); } countPrims++; if( countPrims == TotalPrims ) countPrims = 0; } default{ touch_start( integer HowMany ){ integer i = 0; for(; i < HowMany; i++ ){ if( llDetectedKey( i ) == llGetOwner() ){ Initialize(); llSensor( "Henyard", NULL_KEY, PASSIVE, tooFarAway, PI ); } } } on_rez(integer Gen){ Initialize(); llSensor( "Henyard", NULL_KEY, PASSIVE, tooFarAway, PI ); } sensor(integer total_number){ posOrigin = llDetectedPos( 0 ); vector primsize = llList2Vector( llGetPrimitiveParams( [PRIM_SIZE] ), 0 ); posOrigin.z += primsize.z / 2; state EggTimer; } no_sensor(){ state EggTimer; } } state EggTimer{ state_entry(){ NewStage(); llSetTimerEvent(AgeDuration); } timer() { state Birdbrain; } touch_start(integer HowMany) { SelfReport(); } } state Birdbrain{ state_entry() { NewStage(); //stage will be hatching or rising Morphing = TRUE; SetMorphOffsets(); countPecks = 0; Pecking = TRUE; llSetTimerEvent( Heartbeat ); OwnerEar = llListen( 42, "", llGetOwner(), "" ); } listen( integer channel, string name, key id, string message ){ message = llStringTrim( message, STRING_TRIM ); list msgs = llParseString2List( message, [" "], [] ); string msg = llList2String( msgs, 0 ); if( msg == "hen" ){ llSetTimerEvent( 0.0 ); integer msg_ndx = 1; for (; msg_ndx < llGetListLength( msgs ); msg_ndx++ ){ msg = llList2String( msgs, msg_ndx ); integer spins = 6; integer doSpin = TRUE; integer spinLR = 60; if(( msg == "cw" ) || ( msg == "fw" )) spinLR = -spinLR; vector vec_spin = < 0.0, 0.0, 0.0 >; float rad_spin = spinLR * DEG_TO_RAD; if(( msg == "cw" ) || ( msg == "ccw" )){ vec_spin.z = rad_spin; } else if(( msg == "fw" ) || ( msg == "bw" )){ vec_spin.x = rad_spin; } else doSpin = FALSE; if( doSpin ){ if( Tilted < 0 ) Peck(); for (; spins > 0; spins-- ) llSetRot( llEuler2Rot( vec_spin ) * llGetRot() ); } } llSetTimerEvent( Heartbeat ); } } timer() { if( Pecking ) { if ( countPecks > 0 ){ countPecks -= 1; } else { // If pose is not normal, stand up (sometimes poop?), wait 1.0s // If pose is normal, randomly pivot, peck, or wander, wait 0.5s if( Tilted < 0 ){ Peck(); countPecks = 2; } else { float rndBehavior = llFrand( 4.0 ); if( rndBehavior <= 1.0 ){ Pivot(); } else if ( rndBehavior <= 2.0 ){ Peck(); } else Wander(); countPecks = 1; } } } if( Morphing ) Morph(); countBeats += Heartbeat; if( countBeats == AgeDuration ){ NewStage(); if( AgeName == "fading" ){ state FadeOut; } else if( AgeName == "laying" ){ if( Tilted < 0 ) Peck(); state Laying; } else if( ( AgeName == "settling" ) || ( AgeName == "expiring" )){ if ( Tilted < 0 ) Peck(); Pecking = FALSE; Morphing = TRUE; } else { Pecking = TRUE; if ( AgeName == "maturing" ){ Morphing = TRUE; } else { Morphing = FALSE; } } if( Morphing )SetMorphOffsets(); } } touch_start(integer HowMany) { SelfReport(); } } state Laying { state_entry() { vector EggDiff = ( llList2Vector( Prim_Sizes, TotalPrims ) - llList2Vector( Prim_Sizes, 0 ) ); vector EggPos = llGetPos(); EggPos = EggPos - < 0, 0, EggDiff.z / 2.0 >; llRezAtRoot( llGetObjectName(), EggPos, < 0, 0, 0 >, llGetRot(), llGetStartParameter() + 1 ); llSetTimerEvent( AgeDuration ); } object_rez(key id) { llGiveInventory( id, llGetObjectName()); //give egg to egg } timer() { state Birdbrain; } touch_start(integer HowMany) { SelfReport(); } } state FadeOut { state_entry() { countPrims = 0; countBeats = Heartbeat * TotalPrims; llSetTimerEvent( Heartbeat ); } timer() { if( countPrims == 0 ) viz = 1 - ( countBeats / AgeDuration ); if(( countPrims > 0 ) && ( countPrims < 5 )){ dest_Color = dest_Feather; } else { dest_Color = dest_Leather; } new_Color = viz * dest_Color; llSetLinkPrimitiveParams( countPrims + 1, [ PRIM_COLOR, ALL_SIDES, new_Color, viz ]); countPrims++; if( countPrims == TotalPrims ){ countPrims = 0; countBeats += Heartbeat * TotalPrims; if( countBeats >= AgeDuration ) llDie(); } } touch_start(integer HowMany) { SelfReport(); } }