Puppy

The rotation is important, the $z+$ axis must face the front of the puppy and the $x+$ axis must point downward.

The puppy assembly contains a wanderer script modified to trigger some effects as well as broadcast a region message to be picked up by the scoreboard component.

When an avatar touches a rezzed puppy, the script commutes to the die state, and triggers the sound clip called corkpop after which it displays some blood particles and dies.

Additionally, the puppy is set to temporary in order to not pollute the simulator.

All the scripts have to be placed into the yellow surrounding root primitive.

Code

puppy.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
 
// Set this to the centre or origin point from where all
// random points will be picked.
vector _iPos = ZERO_VECTOR;
// Set this to the maximal distance distance in meters  
// from the origin point that the object will travel.
float WANDER_DISTANCE = 10;
 
integer _targetID = 0;
 
vector wasCirclePoint(float radius) {
    float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
    float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
    if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
        return _iPos + <x, y, 0>;
    return wasCirclePoint(radius);
}
 
moveTo(vector position) {
    llTargetRemove(_targetID);
    _targetID = llTarget(position, .8);
    llLookAt(position, .6, .6);
    llMoveToTarget(position, 3);    
}
 
key killer = NULL_KEY;
 
default
{
    state_entry() {
        _iPos = llGetPos();
        llSetStatus(STATUS_PHYSICS|STATUS_BLOCK_GRAB, TRUE);
        llVolumeDetect(TRUE);
        llSetForce(<0,0,9.81> * llGetMass(), 0);
        moveTo(wasCirclePoint(WANDER_DISTANCE));
    }
    touch_start(integer num) {
        killer = llDetectedKey(0);
        state die;
    }
 
    at_target(integer tnum, vector targetpos, vector ourpos) {
        if(tnum != _targetID) return;
        moveTo(wasCirclePoint(WANDER_DISTANCE));
    }
    on_rez(integer param) {
        llSetStatus(STATUS_PHYSICS, FALSE);
        llResetScript();
    }
}
 
state die {
    state_entry() {
        llPlaySound("corkpop", 1);
        llParticleSystem([  // start of particle settings
           // Texture Parameters:
           PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0), 
           PSYS_PART_START_SCALE, <.05, .05, FALSE>, PSYS_PART_END_SCALE, <1, 1, FALSE>, 
           PSYS_PART_START_COLOR, <1,0,0>,    PSYS_PART_END_COLOR, <1,1,1>, 
           PSYS_PART_START_ALPHA,  (float).5,            PSYS_PART_END_ALPHA, (float).1,   
 
           // Production Parameters:
           PSYS_SRC_BURST_PART_COUNT, (integer)1, 
           PSYS_SRC_BURST_RATE, (float) .2,  
           PSYS_PART_MAX_AGE, (float)2.0, 
           PSYS_SRC_MAX_AGE,(float) .0,  
 
           // Placement Parameters:
           PSYS_SRC_PATTERN, (integer)8, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=ANGLE_CONE,
 
           // Placement Parameters (for any non-DROP pattern):
           PSYS_SRC_BURST_SPEED_MIN, (float).0,   PSYS_SRC_BURST_SPEED_MAX, (float).0, 
           PSYS_SRC_BURST_RADIUS, .2,
 
           // Placement Parameters (only for ANGLE & CONE patterns):
           PSYS_SRC_ANGLE_BEGIN, (float) .50*PI,    PSYS_SRC_ANGLE_END, (float).50*PI,  
        // PSYS_SRC_OMEGA, <0,0,0>, 
 
           // After-Effect & Influence Parameters:
           PSYS_SRC_ACCEL, <.0,.0, .1 >,  
        // PSYS_SRC_TARGET_KEY,      llGetLinkKey(llGetLinkNumber() + 1),       
 
           PSYS_PART_FLAGS, (integer)( 0         // Texture Options:     
                                | PSYS_PART_INTERP_COLOR_MASK   
                                | PSYS_PART_INTERP_SCALE_MASK   
                             // | PSYS_PART_EMISSIVE_MASK   
                                | PSYS_PART_FOLLOW_VELOCITY_MASK
                                                  // After-effect & Influence Options:
                                | PSYS_PART_WIND_MASK            
                                | PSYS_PART_BOUNCE_MASK          
                             // | PSYS_PART_FOLLOW_SRC_MASK     
                             // | PSYS_PART_TARGET_POS_MASK     
                             // | PSYS_PART_TARGET_LINEAR_MASK   
                            ) 
            //end of particle settings                     
        ]);
        integer comChannel = ((integer)("0x"+llGetSubString((string)llGetOwner(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        llRegionSay(comChannel, "puppeh_death=" + (string)killer);
        llSetTimerEvent(5);
    }
    timer() {
        llDie();
    }
}