Steam Particle Template

Expired

//// "Steam" PARTICLE TEMPLATE v1 - by Jopsy Pendragon - 4/8/2008
//// You are free to use this script as you please, so long as you include this line:
//** The original 'free' version of this script came from THE PARTICLE LABORATORY. **//
 
// SETUP:  Drop one optional particle texture and this script into a prim.
// Particles should start automatically. (Reset) the script if you insert a
// particle texture later on.  Add one or more CONTROLLER TEMPLATES to any
// prims in the linked object to control when particles turn ON and OFF.
 
// Customize the particle_parameter values below to create your unique
// particle effect and click SAVE.  Values are explained along with their
// min/max and default values further down in this script.
 
string  CONTROLLER_ID = "A"; // See comments at end regarding CONTROLLERS.
integer AUTO_START = TRUE;   // Optionally FALSE only if using CONTROLLERS.
 
list particle_parameters=[]; // stores your custom particle effect, defined below.
list target_parameters=[]; // remembers targets found using TARGET TEMPLATE scripts.
 
default {
    state_entry() {
        particle_parameters = [  // start of particle settings
           // Texture Parameters:
           PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
           PSYS_PART_START_SCALE, <0.05, .05, FALSE>, PSYS_PART_END_SCALE, <1 .0, 1.0, FALSE>,
           PSYS_PART_START_COLOR, <1 ,1,1>,    PSYS_PART_END_COLOR, <1 ,1,1>,
           PSYS_PART_START_ALPHA,  (float)0.5,            PSYS_PART_END_ALPHA, (float)0.1,   
 
           // Production Parameters:
           PSYS_SRC_BURST_PART_COUNT, (integer)1,
           PSYS_SRC_BURST_RATE, (float) 0.03,
           PSYS_PART_MAX_AGE, (float)4.0,
           PSYS_SRC_MAX_AGE,(float) 0.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.0,   PSYS_SRC_BURST_SPEED_MAX, (float)0.0,
           PSYS_SRC_BURST_RADIUS, 0.5,
 
           // Placement Parameters (only for ANGLE & CONE patterns):
           PSYS_SRC_ANGLE_BEGIN, (float) 0.50*PI,    PSYS_SRC_ANGLE_END, (float)0.50*PI,
        // PSYS_SRC_OMEGA, <0,0,0>, 
 
           // After-Effect & Influence Parameters:
           PSYS_SRC_ACCEL, <0.0,0.0, 0.1 >,
        // PSYS_SRC_TARGET_KEY,      llGetLinkKey(llGetLinkNum() + 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
        ];
 
        if ( AUTO_START ) llParticleSystem( particle_parameters );
 
    }
 
    link_message( integer sibling, integer num, string mesg, key target_key ) {
        if ( mesg != CONTROLLER_ID ) { // this message isn't for me.  Bail out.
            return;
        } else if ( num == 0 ) { // Message says to turn particles OFF:
            llParticleSystem( [ ] );
        } else if ( num == 1 ) { // Message says to turn particles ON:
            llParticleSystem( particle_parameters + target_parameters );
        } else if ( num == 2 ) { // Turn on, and remember and use the key sent us as a target:
            target_parameters = [ PSYS_SRC_TARGET_KEY, target_key ];
            llParticleSystem( particle_parameters + target_parameters );
        } else { // bad instruction number
            // do nothing.
        }
    }
 
}
 
//============================= About Parameters =============================
// There are 22-ish NAMED attributes that affect a particle display.
// To customize a display you give each a VALUE.
// For example: PSYS_PART_START_COLOR is a named attribute,
// and <1 .0, 0.5, 0.0> is a color VALUE (orange, in this case).
//
// As long as your 'names' and 'values' are paired up properly, they can
// be in any order!  Any you omit a pair, it reverts to a default value.
 
//============================= Texture Parameters =============================
//
// TEXTURE, can be an "Asset UUID" key copied from a texture
//          that you have full permissions to, or the name of
//          a texture in the prim's inventory.
//
// SCALE, (size) 0.0 to 4.0 meters wide, by 0.0 to 4.0 meters tall. (default 1x1)
//          Textures are FLAT, so the 'z' part of the vector is ignored.
//          Values smaller than 0.04x0.04 may not get rendered at all.
//          Tiny particles vanish if the viewer is not near them.
//
// BEGIN_SCALE sets particle start size.
// END_SCALE (end size) is ignored, if the INTERP_SCALE_MASK option is disabled.
//
// COLOR,  from <0.00,0.00,0.00> (black) to <1 .00,1.00,1.00> (white/default)
// ALPHA, 1.0 = 100% visible(default), 0.0 = invisible.  Less than 0.1 might not get seen.
// START_COLOR and START_ALPHA set the color and transparency of newly created particles.
// END_COLOR and END_ALPHA are ignored, if the INTERP_COLOR_MASK option is disabled.
 
//============================= Production Parameters =============================
//
// BURST_PART_COUNT: quantity of particles per burst, 1 to 4096 (default 1),
//
// BURST_RATE: seconds to delay between particle bursts. 0.0 to 30.0 (default 0.1)
//
// PART_MAX_AGE: particle lifespan in seconds, 0.00 to 30.0 (default=10.0)
//               PART_MAX_AGE less than 0.5 might not be visible.
//
// The default total number of particles that can be seen is 4096, if one or more
// emitters try to create more than that, many will not be seen, and it may cause
// viewer lag.  Use as few particles as you can for your effect:
// AGE/RATE * COUNT will tell you approximately how many particles your emitter creates.
//
// SRC_MAX_AGE: emitter auto shut-off timer. 1.0 to 60.0 seconds. 0.0 = never stop. (default)
 
//============================= Placement Parameters =============================
//
// PATTERN:
//      DROP, ignores all other placement settings.
//      EXPLODE, spray particles in all directions
//      ANGLE, sprays a flat "fan" shape defined by ANGLE_BEGIN and END values
//      CONE, sprays "ring" or "cone" shapes defined by ANGLE_BEGIN and END values
//
// RADIUS:  0.0 to 50.0?  distance from emitter to create new particles
//      (RADIUS is disabled with DROP pattern and the FOLLOW_SRC & TARGET_LINEAR options)
//
// SPEED: 0.00 to 50.0?  Sets min/max starting velocities for non-drop patterns. (default: 1.0)
//
// ANGLE_BEGIN & END:  0.00*PI (up) to 1.00*PI (down),  (Only for ANGLE & CONE patterns)
//       (Values work much like the Sphere-prim's DIMPLE attributes.) (defaults: 0.0)
//
// OMEGA:  Sets how much to rotate angle/cone spray direction after
//                every burst. 0.0 to PI?  (default: <0,0,0>)
 
//======================== After-Effects & Influence Parameters ================
//
// ACCEL, x,y,z 0.0 to 50.0?  sets a constant force, (affects all patterns)
//          Causes particles to drift up/down or in a compass direction.
//          Use ACCEL to create the illusion of (anti-)gravity or a directional wind.
//          (ineffective with TARGET_LINEAR option)
//
// TARGET_KEY,  "key", (requires the TARGET option be enabled).
//       "key" can be a variety of many different things:
         // llGetOwner()
         // llGetKey() target self
         // llGetLinkKey(1) target parent prim
         // llGetLinkKey(llGetLinkNum() + 1) target next prim in link set
         //
         // WARNING: New copies of objects get new keys, you can't simply paste
         // a prim's key into your script and expect it to always work.  Visit
         // the Particle Laboratory's section on TARGETS for a variety of ways
         // to dynamically find your target's key. There are different 'best ways'
         // depending on if your target is linked to your emitter or not.
 
//============================= About Options =============================
//
// Each option may be ON/ENABLED (no leading // )
// or OFF/DISABLED (by putting a // in front of it.)
// Options are combined together in a special way, (using the | symbol).
// This creates one single Parameter for PSYS_PART_FLAGS.
 
//============================= Texture Options =============================
//
// EMISSIVE: identical to "full bright" setting on prims
//
// FOLLOW_VELOCITY: particle texture 'tilts' towards the direction it's moving
//
// INTERP_COLOR: causes particle COLOR and ALPHA(transparency) to change over it's lifespan
//
// INTERP_SCALE: causes particle SCALE(size) to change over it's lifespan
 
//======================== After-Effects & Influences Options ================
//
// BOUNCE:  particles bounce up from the z-altitude of emitter, and cannot fall below it.
//
// WIND: the sim's wind will push particles around
//
// FOLLOW_SRC: makes particles move (but not rotate) if their emitter moves, (disables RADIUS)
//
// TARGET_POS: causes particles to arrive at a some target at end of of their lifespan.
//
// TARGET_LINEAR: forces particles to form into an even line from emitter to target
//                and forces a DROP-like pattern and disables effects of WIND and ACCEL
 
//========================================================================
//======================== USING CONTROL TEMPLATES =======================
//
// Want to control when your particles turn ON and OFF?   You can!
//
// Drop one (or more) of the CONTROL TEMPLATES from the particle laboratory
// into your object containing this script.  That's it!
 
// Your controls should be effective immediately.  (Some controllers can be
// adjusted and tuned, open them and read the USAGE notes to see.)
//
// One control template can control several particle templates in the
// same object.   (keep in mind that each prim can only have ONE
// particle effect active at a time).
//
// The 'particle_effect_name' value must be the same in both the control
// and particle template to work.  You can change that value and have
// a controller for one effect, and a different controller for a different
// effect in the same object.
//
 
//======================================== END ===============================

 

Swarm Script

Expired

// Swarm script
// by Apotheus Silverman
// This script is my implementation of the well-known swarm algorithm
// which can be found in numerous open-source programs.
// Due to the specifics of the SL environment, I have strayed from some
// of the traditional rules slightly. Regardless, the end effect is
// indistiguishable from the original algorithm.
 
// Configurable parameters
 
// Determines whether or not to enable STATUS_SANDBOX.
integer sandbox = FALSE;
 
// Timer length
float timer_length = 0.5;
 
// Die after this many seconds
integer kill_time = 300;
 
// Enables or disables schooling behavior
integer school = TRUE;
 
// Schooling comm channel
integer school_comm_channel = 9284;
 
// Schooling behavior update interval (should be a multiple of timer_length)
float school_update_interval = 2.0;
 
// How much force to apply with each impulse
float force_modifier = 0.7;
 
// How much force to apply when repulsed by another like me
float repulse_force_modifier = 0.86;
 
// How much friction to use on a scale from 0 to 1.
// Note that friction takes effect each timer cycle, so the lower the timer length,
// the more the friction you specify here will take effect, thereby increasing actual
// friction applied.
float friction = 0.45;
 
// How much to modify the rotation strength. Higher numbers produce greater strength
// Note that if the modifier is too small, the object may not rotate at all.
float rotation_strength_modifier = 2.8;
 
// How much to modify rotation damping. Higher numbers produce slower rotation.
float rotation_damping_modifier = 5000000.0;
 
// Does this object "swim" in air or water?
// 2 = air
// 1 = water
// 0 = both
integer flight_mode = 2;
 
// Maximum distance from spawn point
float max_distance = 15.0;
 
// How far away to scan for others like me
float sensor_distance = 30.0;
 
// *** Don't change anything below unless you *really* know what you're doing ***
 
float mass;
vector spawn_location;
float school_timer = 0.0;
vector school_modifier = <0,0,0>;
 
// Update rotation function
do_rotation(vector mypos, vector myvel) {
        llLookAt(mypos + myvel, mass * rotation_strength_modifier, mass * rotation_damping_modifier);
}
 
// Collision function
collide(vector loc) {
        vector mypos = llGetPos();
        // Apply repulse force
        vector impulse = llVecNorm(mypos - loc);
        llApplyImpulse(impulse * repulse_force_modifier * mass, FALSE);
        //llSay(0, "collide() - impulse " + (string)impulse + " applied.");
        // Update rotation
        do_rotation(mypos, llGetVel());
}
 
// This function is called whether the sensor senses anything or not
sensor_any() {
        // Die after reaching kill_time
        if (kill_time != 0 && llGetTime() >= kill_time) {
                llDie();
        }
 
        // Get my velocity
        vector myvel = llGetVel();
 
        // Apply friction
        llApplyImpulse(-(myvel * friction * mass), FALSE);
 
        // Schooling behavior
        if (school && llGetTime() - school_timer > school_update_interval) {
                llSay(school_comm_channel, (string)myvel);
                school_timer = llGetTime();
        }
 
        // Get my position
        vector mypos = llGetPos();
 
        // Check for air/water breach
        if (flight_mode == 1) {
                // water
                if (mypos.z >= llWater(mypos) - llVecMag(llGetScale())) {
                        //llSay(0, "collide() called due to air/water breach.");
                        collide();
                }
        } else if (flight_mode == 2) {
                // air
                if (mypos.z <= llWater(mypos) + llVecMag(llGetScale())) {
                        //llSay(0, "collide() called due to air/water breach.");
                        collide();
                }
        }
 
        // Stay near spawn location
        if (llVecDist(mypos, spawn_location) > max_distance) {
                // Compensate for being near sim border
                if (spawn_location.x - mypos.x > 100) {
                        mypos.x += 255;
                }
                //llSay(0, "collide() called due to too much distance from my spawn point. mypos=" + (string)mypos + ", spawn_location = " + (string)spawn_location);
                collide(mypos - llVecNorm(spawn_location - mypos));
        }
 
        // Stay above ground level
        if (mypos.z <= llGround(ZERO_VECTOR)) {
                collide(mypos - llGroundNormal(ZERO_VECTOR));
        }
}
 
default {
        state_entry() {
                llResetTime();
                llSay(0, "Fishy spawned.");
 
                // School
                if (school) {
                        llListen(school_comm_channel, "", NULL_KEY, "");
                }
 
                // Sandbox
                llSetStatus(STATUS_SANDBOX, sandbox);
                llSetStatus(STATUS_BLOCK_GRAB, FALSE);
                spawn_location = llGetPos();
 
                // Initialize physics behavior
                mass = llGetMass();
                llSetBuoyancy(1.0);
                llSetStatus(STATUS_PHYSICS, TRUE);
                llVolumeDetect(TRUE);
 
                // Initialize sensor
                llSensorRepeat(llGetObjectName(), NULL_KEY, ACTIVE|SCRIPTED, sensor_distance, PI, timer_length);
 
        }
 
        collision_start(integer total_number) {
                //llSay(0, "collide() called due to physical object collision.");
                collide(llDetectedPos(0));
        }
 
        no_sensor() {
                sensor_any();
        }
 
        sensor(integer total_number) {
                sensor_any();
 
                // Populate neighbors with the positions of the two nearest neighbors.
                vector mypos = llGetPos();
                list neighbors = [];
                integer i;
 
                for (i = 0; i < total_number; i++) {
                        vector current_pos = llDetectedPos(i);
 
                        if (llGetListLength(neighbors) < 2) {
                                // Add to list
                                neighbors = llListInsertList(neighbors, [current_pos], llGetListLength(neighbors));
                        } else {
                                // Check to see if the current vector is closer than the list
                                // vector which is furthest away.
                                if (llVecDist(mypos, llList2Vector(neighbors, 0)) > llVecDist(mypos, llList2Vector(neighbors, 1))) {
                                        // check against first list item
                                        if (llVecDist(mypos, llList2Vector(neighbors, 0)) > llVecDist(mypos, current_pos)) {
                                                llListInsertList(neighbors, [current_pos], 0);
                                        }
                                } else {
                                        // check against second list item
                                        if (llVecDist(mypos, llList2Vector(neighbors, 1)) > llVecDist(mypos, current_pos)) {
                                                llListInsertList(neighbors, [current_pos], 1);
                                        }
                                }
                        }
                }
 
                // Process movement
 
                // Apply force
                if (llGetListLength(neighbors) == 2) {
                        vector neighbor1 = llList2Vector(neighbors, 0);
                        vector neighbor2 = llList2Vector(neighbors, 1);
                        vector target = neighbor2 + ((neighbor1 - neighbor2) * 0.5);
                        vector impulse = <0,0,0>;
                        if (school) {
                                impulse = llVecNorm(target + school_modifier - mypos);
                        } else {
                                impulse = llVecNorm(target - mypos);
                        }
                        //llSay(0, "setforce " + (string)(impulse * force_modifier * mass));
                        llSetForce(impulse * force_modifier * mass, FALSE);
                }
 
                // Update rotation
                do_rotation(llGetPos(), llGetVel());
        }
 
        listen(integer channel, string name, key id, string message) {
                list myList = llCSV2List(llGetSubString(message, 1, llStringLength(message) - 2));
                if (llGetListLength(myList) == 3) {
                        school_modifier = ;
                        school_timer = llGetTime();
                }
        }
 
        on_rez(integer start_param) {
                llResetScript();
                //        spawn_location = llGetPos();
                //        llResetTime();
        }
}

 

Fire Flies

Expired

//start_unprocessed_text
/*mySetParticles() {
    /|/ Part-1 - APPEARANCE - Settings for how each particle LOOKS
    vector   START_SCALE = <0.1, 0.1, 0.1 >; /|/ <1.0, 1.0, 0.0 >
    vector     END_SCALE = <0.1, 0.1, 0.1 >; /|/ <1.0, 1.0, 0.0 >
    vector   START_COLOR = <1.0, 1.0, 0.0 >; /|/ <1.0, 1.0, 1.0 >
    vector     END_COLOR = <1.0, 1.0, 0.0 >; /|/ <1.0, 1.0, 1.0 >
    float    START_ALPHA = 1.0; /|/ 1.00
    float      END_ALPHA = 1.0; /|/ 1.00
    integer INTERP_COLOR = TRUE; /|/ FALSE
    integer INTERP_SCALE = TRUE; /|/ FALSE
    integer     EMISSIVE = TRUE; /|/ FALSE
    string       TEXTURE = ""; /|/ ""
    /|/ START/END: refers to the birth and death time of each particle.
    /|/ SCALE: particle height/width, from 0.04 to 4.0. (no depth)
    /|/ ALPHA: sets transparency, from invis = 0.0 to opaque = 1.0
    /|/       START_ALPHA is ignored if it is less than END_ALPHA
    /|/ COLOR: vectors , each 0.00 to 1.00
    /|/ INTERP_COLOR: enables/disables END_COLOR and END_ALPHA
    /|/ INTERP_SCALE: enables/disables END_SCALE
    /|/ EMISSIVE: enables/diables particle 'glow'
    /|/ TEXTURE: name of a texture in the emitter-prim's inventory
    /|/          or the asset id key of any texture
 
    /|/ Part-2 - FLOW - These settings affect how Many, how Quickly,
    /|/                  and for how Long particles are present
    float     AGE = 2.00; /|/ 10.00
    float    RATE = 0.5;  /|/ 0.10
    integer COUNT = 1;    /|/ 1
    float    LIFE = 0.0;  /|/ 0.0
    /|/ AGE: How many seconds each particle lives, 0.1 to 60
    /|/ RATE: Seconds between particle bursts, 0.0 to 60
    /|/ COUNT: Number of particles per burst, 1 to 4096
    /|/ LIFE Number of seconds to wait before shutting off 0.1 to 60
    /|/       0.0 never stops
 
    /|/ Part-3 - 3    PLACEMENT -- Where are new particles created, and what
    /|/                     direction  are they facing?
    integer   PATTERN = PSYS_SRC_PATTERN_EXPLODE; /|/ PSYS_SRC_PATTERN_DROP
    float      RADIUS = 1.00; /|/ 0.00
    float ANGLE_BEGIN = 0.10; /|/ 0.00
    float   ANGLE_END = 0.10; /|/ 0.00
    vector      OMEGA = <0.00, 0.00, 1.00 >; /|/ <0.00, 0.00, 0.00 >
    /|/float  INNERANGLE = 0.00; /|/ 0.00
    /|/float  OUTERANGLE = 0.00; /|/ 0.00
    /|/ PATTERN: must be set to one of the following:
    /|/      PSYS_SRC_PATTERN_EXPLODE sends particles in all directions
    /|/      PSYS_SRC_PATTERN_DROP  ignores minSpeed and maxSpeed.
    /|/      PSYS_SRC_PATTERN_ANGLE_CONE use ANGLE settings to make rings/cones
    /|/      PSYS_SRC_PATTERN_ANGLE use innerangle/outerangle to make flat
    /|/      wedges
    /|/ RADIUS: distance between emitter and each new particle,  0.0 to 64?
    /|/ ANGLE_BEGIN: for both ANGLE patterns, 0 to PI(3.14159)
    /|/ ANGLE_END: for both for ANGLE patterns,  0 to PI.
    /|/ OMEGA: How much to rotate the emitter around the  axises
    /|/         after each burst.  Set OMEGA to all 0's to reset/disable it.
    /|/ INNER/OUTER ANGLE:  Depreciated. Old versions of ANGLE_BEGIN/_END.
    /|/    Can still be used to make lop-sided angle displays though.
 
    /|/  Part-4 - MOVEMENT - How do the particles move once they're created?
    integer      FOLLOW_SRC = TRUE; /|/ FALSE
    integer FOLLOW_VELOCITY = TRUE; /|/ FALSE
    integer            WIND = TRUE; /|/ FALSE
    integer          BOUNCE = FALSE; /|/ FALSE
    float         SPEED_MIN = 1.00; /|/ 1.00
    float         SPEED_MAX = 2.20; /|/ 1.00
    vector            ACCEL = <0.00, 0.00, 0.00 >; /|/ <0.00, 0.00, 0.00 >
    integer      TARGET_POS = TRUE; /|/ FALSE
    key              TARGET = llGetKey(); /|/ llGetKey();
    /|/ FOLLOW_SRC: moves particles when emitter moves. It will disable RADIUS!
    /|/ FOLLOW_VELOCITY:  Particles rotate towards their heading
    /|/ WIND: Sim's Wind will push particles
    /|/ BOUNCE: Make particles bounce above the Z altitude of emitter
    /|/ SPEED_MIN: 0.01 to ?, slowest speed of new particles, 1.0(*)
    /|/ SPEED_MAX: 0.01 to ?, fastest speed of new particle, 1.0(*)
    /|/      SPEED_ is ignored for the DROP pattern.
    /|/ ACCEL: a continuous force pushed on particles,
    /|/             use SMALL settings for long lived particles
    /|/ TARGET_POS: If FALSE(*), TARGET value is ignored.
    /|/ TARGET: Select a target for particles to arrive at when they die
    /|/      key TARGET = llGetKey(); /|/ particles return to the emitter
    /|/      key TARGET = llGetOwner(); /|/ particles home in on owner
    /|/      You can have another object llSay(999,llGetKey);
    /|/      and grab the key with this object by using the listen()
    /|/      event handler.
 
    list particle_parameters = [
            PSYS_PART_FLAGS, (
                (        EMISSIVE * PSYS_PART_EMISSIVE_MASK ) |
                (          BOUNCE * PSYS_PART_BOUNCE_MASK ) |
                (    INTERP_COLOR * PSYS_PART_INTERP_COLOR_MASK ) |
                (    INTERP_SCALE * PSYS_PART_INTERP_SCALE_MASK ) |
                (            WIND * PSYS_PART_WIND_MASK ) |
                (      FOLLOW_SRC * PSYS_PART_FOLLOW_SRC_MASK ) |
                ( FOLLOW_VELOCITY * PSYS_PART_FOLLOW_VELOCITY_MASK ) |
                (      TARGET_POS * PSYS_PART_TARGET_POS_MASK ) ),
            PSYS_PART_START_COLOR,     START_COLOR,
            PSYS_PART_END_COLOR,       END_COLOR,
            PSYS_PART_START_ALPHA,     START_ALPHA,
            PSYS_PART_END_ALPHA,       END_ALPHA,
            PSYS_PART_START_SCALE,     START_SCALE,
            PSYS_PART_END_SCALE,       END_SCALE,
            PSYS_SRC_PATTERN,          PATTERN,
            PSYS_SRC_BURST_PART_COUNT, COUNT,
            PSYS_SRC_BURST_RATE,       RATE,
            PSYS_PART_MAX_AGE,         AGE,
            PSYS_SRC_ACCEL,            ACCEL,
            PSYS_SRC_BURST_RADIUS,     RADIUS,
            PSYS_SRC_BURST_SPEED_MIN,  SPEED_MIN,
            PSYS_SRC_BURST_SPEED_MAX,  SPEED_MAX,
            PSYS_SRC_TARGET_KEY,       TARGET,
            PSYS_SRC_ANGLE_BEGIN,      ANGLE_BEGIN,
            PSYS_SRC_ANGLE_END,        ANGLE_END,
            /|/PSYS_SRC_INNERANGLE,       INNERANGLE,
            /|/PSYS_SRC_OUTERANGLE,       OUTERANGLE,
            PSYS_SRC_OMEGA,            OMEGA,
            PSYS_SRC_MAX_AGE,          LIFE,
            PSYS_SRC_TEXTURE,          TEXTURE
        ];
 
    llParticleSystem( particle_parameters ); /|/ Turns on the particle hose!
 
    if ( (AGE/RATE)*COUNT > 4096) {
        llOwnerSay( "Your emitter creates too many particles!"
            + "Please decrease AGE and COUNT and/or increase RATE."
            + "Give a hoot, don't pollute!");
    } else {
        llOwnerSay( "This emitter produces "
                    + (string)((integer)((AGE/RATE)*COUNT))
                    + " concurrent particles." );
    }
}
 
default
{
    state_entry() {
        mySetParticles();
        /|/ llSetTimerEvent(60); /|/ uncomment to set auto-off for 60 seconds
    }
 
    timer() {
        llSetTimerEvent( 0 );  /|/ Turn off the alarm clock
        llParticleSystem( [ ] );  /|/ Turn off the particles
        /|/ updateParticles(); /|/ Or use this to update/change the particle
        /|/ system
    }
 
    touch(integer i) {
        mySetParticles(); /|/ touch to reset/turn on the particles
        /|/ llSetTimerEvent(60); /|/ reset the alarm clock
    }
}*/
//end_unprocessed_text
//nfo_preprocessor_version 0
//program_version Emerald Viewer
//mono
 
mySetParticles() {
 
    vector   START_SCALE = <0.1, 0.1, 0.1 >;
    vector     END_SCALE = <0.1, 0.1, 0.1 >;
    vector   START_COLOR = <1.0, 1.0, 0.0 >;
    vector     END_COLOR = <1.0, 1.0, 0.0 >;
    float    START_ALPHA = 1.0;
    float      END_ALPHA = 1.0;
    integer INTERP_COLOR = TRUE;
    integer INTERP_SCALE = TRUE;
    integer     EMISSIVE = TRUE;
    string       TEXTURE = ""; 
 
    float     AGE = 2.00;
    float    RATE = 0.5;
    integer COUNT = 1;
    float    LIFE = 0.0;  
 
    integer   PATTERN = PSYS_SRC_PATTERN_EXPLODE;
    float      RADIUS = 1.00;
    float ANGLE_BEGIN = 0.10;
    float   ANGLE_END = 0.10;
    vector      OMEGA = <0.00, 0.00, 1.00 >; 
 
    integer      FOLLOW_SRC = TRUE;
    integer FOLLOW_VELOCITY = TRUE;
    integer            WIND = TRUE;
    integer          BOUNCE = FALSE;
    float         SPEED_MIN = 1.00;
    float         SPEED_MAX = 2.20;
    vector            ACCEL = <0.00, 0.00, 0.00 >;
    integer      TARGET_POS = TRUE;
    key              TARGET = llGetKey(); 
 
    list particle_parameters = [
            PSYS_PART_FLAGS, (
                (        EMISSIVE * PSYS_PART_EMISSIVE_MASK ) |
                (          BOUNCE * PSYS_PART_BOUNCE_MASK ) |
                (    INTERP_COLOR * PSYS_PART_INTERP_COLOR_MASK ) |
                (    INTERP_SCALE * PSYS_PART_INTERP_SCALE_MASK ) |
                (            WIND * PSYS_PART_WIND_MASK ) |
                (      FOLLOW_SRC * PSYS_PART_FOLLOW_SRC_MASK ) |
                ( FOLLOW_VELOCITY * PSYS_PART_FOLLOW_VELOCITY_MASK ) |
                (      TARGET_POS * PSYS_PART_TARGET_POS_MASK ) ),
            PSYS_PART_START_COLOR,     START_COLOR,
            PSYS_PART_END_COLOR,       END_COLOR,
            PSYS_PART_START_ALPHA,     START_ALPHA,
            PSYS_PART_END_ALPHA,       END_ALPHA,
            PSYS_PART_START_SCALE,     START_SCALE,
            PSYS_PART_END_SCALE,       END_SCALE,
            PSYS_SRC_PATTERN,          PATTERN,
            PSYS_SRC_BURST_PART_COUNT, COUNT,
            PSYS_SRC_BURST_RATE,       RATE,
            PSYS_PART_MAX_AGE,         AGE,
            PSYS_SRC_ACCEL,            ACCEL,
            PSYS_SRC_BURST_RADIUS,     RADIUS,
            PSYS_SRC_BURST_SPEED_MIN,  SPEED_MIN,
            PSYS_SRC_BURST_SPEED_MAX,  SPEED_MAX,
            PSYS_SRC_TARGET_KEY,       TARGET,
            PSYS_SRC_ANGLE_BEGIN,      ANGLE_BEGIN,
            PSYS_SRC_ANGLE_END,        ANGLE_END,
 
            PSYS_SRC_OMEGA,            OMEGA,
            PSYS_SRC_MAX_AGE,          LIFE,
            PSYS_SRC_TEXTURE,          TEXTURE
        ];
 
    llParticleSystem( particle_parameters ); 
 
    if ( (AGE/RATE)*COUNT > 4096) {
        llOwnerSay( "Your emitter creates too many particles!"
            + "Please decrease AGE and COUNT and/or increase RATE."
            + "Give a hoot, don't pollute!");
    } else {
        llOwnerSay( "This emitter produces "
                    + (string)((integer)((AGE/RATE)*COUNT))
                    + " concurrent particles." );
    }
}
 
default
{
    state_entry() {
        mySetParticles();
 
    }
 
    timer() {
        llSetTimerEvent( 0 );
        llParticleSystem( [ ] );  
 
    }
 
    touch(integer i) {
        mySetParticles(); 
 
    }
}