LSL: Particles Listen Template

Basic particle script that listens for commands on a chat channel. Can emit particles for the current link or all links in a linkset.

// particle script
//
// Commands:
// on
// off
// show
// hide
 
// Listen channel
integer CHANNEL = 15171;
 
// Set num_links to 0 to scan the linkset and create particles from each link
// Set it to -1 to only generate particles from the link containing the script
// (aka LINK_THIS)
integer num_links = 0;
 
integer particle_state = 0;
 
integer MEM_LIMIT = 12288;
 
particles(integer link) {
        // The below list may be copied directly from the script generated by
        // Firestorm's Edit Particles script
        llLinkParticleSystem(link, [  // start of particle settings
            // Texture Parameters:
            // PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0), 
            PSYS_SRC_TEXTURE, "ee3d9913-d38e-e2be-7e13-fec4d691723f",
            PSYS_PART_START_SCALE, <1.00, 1.50, 0.00>,
            PSYS_PART_END_SCALE, <3.00, 2.90, 0.00>,
            PSYS_PART_START_COLOR, <0.00, 0.20, 0.10>,
            PSYS_PART_END_COLOR, <0.00, 0.40, 0.10>,
            PSYS_PART_START_ALPHA, 0.1,
            PSYS_PART_END_ALPHA, 0.8,
            PSYS_PART_START_GLOW, 0.0,
            PSYS_PART_END_GLOW, 0.0,
            PSYS_PART_BLEND_FUNC_SOURCE, PSYS_PART_BF_SOURCE_ALPHA,
            PSYS_PART_BLEND_FUNC_DEST, PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA,
 
            // Production Parameters:
            PSYS_SRC_BURST_PART_COUNT, 10,
            PSYS_SRC_BURST_RATE, 0.25,
            PSYS_PART_MAX_AGE, 16,
            PSYS_SRC_MAX_AGE, 0,
 
            // Placement Parameters:
            PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE,
            PSYS_SRC_BURST_RADIUS, 0.8,
            PSYS_SRC_BURST_SPEED_MIN, 0.2,
            PSYS_SRC_BURST_SPEED_MAX, 0.5,
 
            // Placement Parameters (only for ANGLE & CONE patterns):
            PSYS_SRC_ANGLE_BEGIN, -0.5,
            PSYS_SRC_ANGLE_END, 0.5,
            PSYS_SRC_OMEGA, <0.00, 0.00, 0.00>,
 
            // After-Effect & Influence Parameters:
            PSYS_SRC_ACCEL,<0.10, 0.00, 0.01>,
            // PSYS_SRC_TARGET_KEY, llGetKey(),
 
            PSYS_PART_FLAGS,
                0 |
                PSYS_PART_EMISSIVE_MASK |
                PSYS_PART_INTERP_COLOR_MASK |
                PSYS_PART_INTERP_SCALE_MASK
        ]);
}
 
particles_off() {
    particle_state = -1;
    if (num_links >= 0) {
        integer i;
        for(i=0; i <= num_links; ++i) {
            llLinkParticleSystem(i, []);
        }
    } else {
        llLinkParticleSystem(LINK_THIS, []);
    }
}
 
particles_on() {
    particle_state = 1;
    if (num_links >= 0) {
        integer i;
        for(i=0; i <= num_links; ++i) {
            particles(i);
        }
    } else {
        particles(LINK_THIS);
    }
}
 
reset() {
    if (num_links >= 0) {
        num_links = llGetObjectPrimCount(llGetKey());
    }
    particles_off();
}
 
default {
    state_entry() {
        llSetMemoryLimit(MEM_LIMIT);
        reset();
 
        llListen(CHANNEL, "", NULL_KEY, ""); 
        llOwnerSay("Memory: used="+(string)llGetUsedMemory()+" free="+(string)llGetFreeMemory());
    }
 
    listen(integer channel, string name, key id, string message) {
        // Parse command
        string cmd = "";
        string args = "";
        integer idx = llSubStringIndex(message, " ");
        if (idx == -1) {
            cmd = message;
            args = "";
        } else {
            cmd = llGetSubString(message, 0, idx-1);
            args = llDeleteSubString(message, 0, idx);
        }
        cmd = llToLower(cmd);
 
        // Parse a number too?
        integer num = (integer)cmd;
 
        if (cmd == "reset") {
            reset();
        } else if (cmd == "off") {
            particles_off();
        } else if (cmd == "on") {
            particles_on();
        } else if (cmd == "show") {
            if (num_links >= 0) {
                llSetAlpha(1.0, ALL_SIDES);
            }
        } else if (cmd == "hide") {
            if (num_links >= 0) {
                llSetAlpha(0.0, ALL_SIDES);
            }
        }
    }
 
    changed(integer change) {
        if (change & CHANGED_LINK){
            reset();
        }
    }
}