Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Particle Script with Sensor

Captain Roo
Registered User
Join date: 1 Feb 2005
Posts: 5
02-03-2007 02:21
Hi i'm trying to modify a particle script and add a sensor into it so that each time the object is rezzed i dont have to re-edit the script to give it the new target key.

This is the particle script i am using.
CODE

// Particle Script 0.4j
// Created by Ama Omega 3-7-2004
// Updated by Jopsy Pendragon 5-11-2004
// For classes/tutorials/tricks, visit the Particle Labratory in Teal
// Values marked with (*) are defaults.

// SECTION ONE: APPEARANCE -- These settings affect how each particle LOOKS.
integer glow = TRUE; // TRUE or FALSE(*)
vector startColor = <1,1,1>; // RGB color, black<0,0,0> to white<1,1,1>(*)
vector endColor = <1,1,1>; //
float startAlpha = 1.0; // 0.0 to 1.0(*), lower = more transparent
float endAlpha = 1.0; //
vector startSize = <0.1,0.1,0>; // <0.04,0.04,0>(min) to <10,10,0>(max>, <1,1,0>(*)
vector endSize = <0.1,0.1,0>; // (Z part of vector is discarded)
string texture = "chain"; // Texture used for particles. Texture must be in prim's inventory.

// SECTION TWO: FLOW -- These settings affect how Many, how Quickly, and for how Long particles are created.
// Note,
integer count = 30; // Number of particles created per burst, 1(*) to 4096
float rate = 0.1; // Delay between bursts of new particles, 0.0 to 60, 0.1(*)
float age = 10.0; // How long each particle lives, 0.1 to 60, 10.0(*)
float life = 0.0; // When to stop creating new particles. never stops if 0.0(*)

// SECTION THREE: PLACEMENT -- Where are new particles created, and what direction are they facing?
float radius = 0.0; // 0.0(default) to 64? Distance from Emitter where new particles are created.
float innerAngle = PI; // "spread", for all ANGLE patterns, 0(default) to PI
float outerAngle = 0.0; // "tilt", for ANGLE patterns, 0(default) to TWO_PI, can use PI_BY_TWO or PI as well.
integer pattern = PSYS_SRC_PATTERN_ANGLE; // Choose one of the following:
// PSYS_SRC_PATTERN_EXPLODE (sends particles in all directions)
// PSYS_SRC_PATTERN_DROP (ignores minSpeed and maxSpeed. Don't bother with count>1 )
// PSYS_SRC_PATTERN_ANGLE_CONE (set innerangle/outerange to make rings/cones of particles)
// PSYS_SRC_PATTERN_ANGLE (set innerangle/outerangle to make flat fanshapes of particles)
vector omega = <0,0,0>; // How much to rotate the emitter around the <X,Y,Z> axises. <0,0,0>(*)
// Warning, there's no way to RESET the emitter direction once you use Omega!!
// You must attach the script to a new prim to clear the effect of omega.

// SECTION FOUR: MOVEMENT -- How do the particles move once they're created?
integer followSource = FALSE; // TRUE or FALSE(*), Particles move as the emitter moves, (TRUE disables radius!)
integer followVel = TRUE; // TRUE or FALSE(*), Particles rotate towards their direction
integer wind = FALSE; // TRUE or FALSE(*), Particles get blown away by wind in the sim
integer bounce = FALSE; // TRUE or FALSE(*), Make particles bounce on Z altitude of emitter
float minSpeed = 0.1; // 0.01 to ? Min speed each particle is spit out at, 1.0(*)
float maxSpeed = 0.1; // 0.01 to ? Max speed each particle is spit out at, 1.0(*)
vector push = <0,0,-0.1>; // Continuous force pushed on particles, use small settings for long lived particles
key target = "(string)object"; // Select a target for particles to arrive at when they die
// can be "self" (emitter), "owner" (you), "" or any prim/persons KEY.

// SECTION FIVE: Ama's "Create Short Particle Settings List"
integer enableoutput = FALSE; // If this is TRUE, clicking on your emitter prim will cause it to speak
// very terse "shorthand" version of your particle settings. You can cut'n'paste
// this abbreviated version into a call to llParticleSystem([ ]); in another script.
// Pros: Takes up far less scripting space, letting you focus on the rest of your code.
// Cons: makes tune your settings afterwards rather awkward

// === Don't muck about below this line unless you're comfortable with the LSL scripting language ====

// Script variables
integer pre = 2; //Adjust the precision of the generated list.
integer flags;
list sys;
integer type;
vector tempVector;
rotation tempRot;
string tempString;
integer i;
string float2String(float in)
{
return llGetSubString((string)in,0,pre - 7);
}

updateParticles()
{
flags = 0;
if (target == "owner") target = llGetOwner();
if (target == "self") target = llGetKey();
if (glow) flags = flags | PSYS_PART_EMISSIVE_MASK;
if (bounce) flags = flags | PSYS_PART_BOUNCE_MASK;
if (startColor != endColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK;
if (startSize != endSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK;
if (wind) flags = flags | PSYS_PART_WIND_MASK;
if (followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK;
if (followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;
if (target != "") flags = flags | PSYS_PART_TARGET_POS_MASK;
sys = [ PSYS_PART_MAX_AGE,age,
PSYS_PART_FLAGS,flags,
PSYS_PART_START_COLOR, startColor,
PSYS_PART_END_COLOR, endColor,
PSYS_PART_START_SCALE,startSize,
PSYS_PART_END_SCALE,endSize,
PSYS_SRC_PATTERN, pattern,
PSYS_SRC_BURST_RATE,rate,
PSYS_SRC_ACCEL, push,
PSYS_SRC_BURST_PART_COUNT,count,
PSYS_SRC_BURST_RADIUS,radius,
PSYS_SRC_BURST_SPEED_MIN,minSpeed,
PSYS_SRC_BURST_SPEED_MAX,maxSpeed,
PSYS_SRC_TARGET_KEY,target,
PSYS_SRC_INNERANGLE,innerAngle,
PSYS_SRC_OUTERANGLE,outerAngle,
PSYS_SRC_OMEGA, omega,
PSYS_SRC_MAX_AGE, life,
PSYS_SRC_TEXTURE, texture,
PSYS_PART_START_ALPHA, startAlpha,
PSYS_PART_END_ALPHA, endAlpha
];
float newrate = rate;
if (newrate == 0.0) newrate=.01;
if ( (age/rate)*count < 4096) llParticleSystem(sys);
else {
llInstantMessage(llGetOwner(),"Your particle system creates too many concurrent particles.");
llInstantMessage(llGetOwner(),"Reduce count or age, or increate rate.");
llParticleSystem( [ ] );
}
}
integer onoff;
default

{
state_entry()
{
touch_start(integer total_number)
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI); // scan for agents/avatars within 10 metres.
}

sensor(integer total_number) // total_number is the number of avatars detected.
{
llSay(0, (string)total_number + " avatars detected" );
// The following 'for' loop runs through all detected avatars and says "Hello Jane Doe",
// where "Jane Doe" is the name of the current detected avatar.
integer i;
for (i = 0; i < total_number; i++)
{
llSay(0, "Hello " + llDetectedName(i));
key object = llDetectedKey(0);
llSay(0, (string)object);
llSay(0, "target is " +(string)object);
}
}

// if nobody is within 10 meters, say so.
no_sensor() {

}
{
onoff=0;
updateParticles();
}

touch_start(integer num)
{
if ( enableoutput == FALSE ) {
if ( onoff ) llResetScript();
onoff++;
llParticleSystem( [ ] );
return;
}
if (1) return; // Comment out this line to enable this function
llWhisper(0,"...Generating List...");
for (i=1;i<42;i+=2)
{
type = llGetListEntryType(sys,i);
if(type == TYPE_FLOAT)
{
tempString = float2String(llList2Float(sys,i));
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_VECTOR)
{
tempVector = llList2Vector(sys,i);
tempString = "<" + float2String(tempVector.x) + ","
+ float2String(tempVector.y) + ","
+ float2String(tempVector.z) + ">";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_ROTATION)
{
tempRot = llList2Rot(sys,i);
tempString = "<" + float2String(tempRot.x) + ","
+ float2String(tempRot.y) + ","
+ float2String(tempRot.z) + ","
+ float2String(tempRot.s) + ">";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_STRING || type == TYPE_KEY)
{
tempString = "\"" + llList2String(sys,i) + "\"";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
}
i = llListFindList(sys,[20,""]);
if (i != -1) sys = llDeleteSubList(sys,i,i+1);
llWhisper(0,"[" + llList2CSV(llList2List(sys,0,22)) + ",");
llWhisper(0,llList2CSV(llList2List(sys,23,-1)) + "]");
}
}

As you will notice the target information is incorrect due to i havemt found a way to combine both scripts yet.

Here is a copy of the sensor script i have been working on

CODE


default
{
touch_start(integer total_number)
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI); // scan for Point_1 Object within 10 metres.
}

sensor(integer total_number) // total_number is the number of objects detected.
{
llSay(0, (string)total_number + " objects detected" );
integer i;
for (i = 0; i < total_number; i++)
{
llSay(0, "Hello " + llDetectedName(i));
key object = llDetectedKey(0);
llSay(0, (string)object);
}
}
no_sensor() {

}
}



Once i can get both scripts combined i will be removing the say command on the sensor.
Would anyone be able to help me combine these scripts or offer any suggestions on a better way to do it.

Thanks
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
02-03-2007 09:17
Not 100% sure what you are really after, but you can set a particle system to a target just by giving its key. Assuming your objects are always called "Point_1" then your existing code needs only to assign the key of teh detetced object to target and then call the particles.

CODE

sensor(integer total_number) // total_number is the number of avatars detected.
{
target = llDetectedKey(0);
updateParticles();
}
Captain Roo
Registered User
Join date: 1 Feb 2005
Posts: 5
02-03-2007 15:26
Hi, Thanks for the quick reply.
I have changed a few things in the script but i cant seem to get it to accept the sensor integer line.
I have changed to kry target.
CODE

key target = "+(string)target)";

and I have the llSensor running at state entry
CODE

default
{
state_entry()
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI);
key target = llDetectedKey(0);
onoff=0;
updateParticles();

But no matter where i put the sensor command i just get a syntax error
CODE

sensor(integer total_number)


Thanks again for any help you can give me.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
02-03-2007 16:31
From: Captain Roo
Hi, Thanks for the quick reply.
I have changed a few things in the script but i cant seem to get it to accept the sensor integer line.
I have changed to kry target.
CODE

key target = "+(string)target)";

and I have the llSensor running at state entry
CODE

default
{
state_entry()
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI);
key target = llDetectedKey(0);
onoff=0;
updateParticles();

But no matter where i put the sensor command i just get a syntax error
CODE

sensor(integer total_number)


Thanks again for any help you can give me.


Your sensor is a single shot sensor and the target doenst need to be initialised like that.

I assume state_entry has a closing brace before the sensor event handler?

CODE

default
{
state_entry()
{
onoff=0;
updateParticles();
}

touch_start(integer total_number)
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI);
onoff=1;
}

sensor(integer total_number) // total_number is the number of avatars detected.
{
target = llDetectedKey(0);
updateParticles();
}
}

Captain Roo
Registered User
Join date: 1 Feb 2005
Posts: 5
02-03-2007 16:44
Because of it being in witht he rest of the particle script.
The full State_entry has alot of if commands before the closing brace.

CODE

default
{
state_entry()
{
llSensor("Point_1", NULL_KEY, PASSIVE, 10, PI);
key target = llDetectedKey(0);
onoff=0;
updateParticles();


if ( enableoutput == FALSE ) {
if ( onoff ) llResetScript();
onoff++;
llParticleSystem( [ ] );
return;
}
if (1) return; // Comment out this line to enable this function
llWhisper(0,"...Generating List...");
for (i=1;i<42;i+=2)
{
type = llGetListEntryType(sys,i);
if(type == TYPE_FLOAT)
{
tempString = float2String(llList2Float(sys,i));
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_VECTOR)
{
tempVector = llList2Vector(sys,i);
tempString = "<" + float2String(tempVector.x) + ","
+ float2String(tempVector.y) + ","
+ float2String(tempVector.z) + ">";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_ROTATION)
{
tempRot = llList2Rot(sys,i);
tempString = "<" + float2String(tempRot.x) + ","
+ float2String(tempRot.y) + ","
+ float2String(tempRot.z) + ","
+ float2String(tempRot.s) + ">";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
else if (type == TYPE_STRING || type == TYPE_KEY)
{
tempString = "\"" + llList2String(sys,i) + "\"";
sys = llDeleteSubList(sys,i,i);
sys = llListInsertList(sys,[tempString],i);
}
}
i = llListFindList(sys,[20,""]);
if (i != -1) sys = llDeleteSubList(sys,i,i+1);
llWhisper(0,"[" + llList2CSV(llList2List(sys,0,22)) + ",");
llWhisper(0,llList2CSV(llList2List(sys,23,-1)) + "]");
}
}


As for it not needing to be initalised like this... its the only way i know how to do it at present.
Jopsy Pendragon
Perpetual Outsider
Join date: 15 Jan 2004
Posts: 1,906
02-03-2007 18:20
Captain-

If it helps any... here's my example for using llSensor to find non-scripted named targets, (also available in The Particle Laboratory, with 3 other examples of setting up targets):

CODE

// Particle Target Demonstration - 1/10/2007 - Jopsy Pendragon
// A sample script from the Particle Laboratory of Teal
// You may copy, mod, sell, spindle, mutilate this script
// as you please.
// If you distribute MODable derivatives of this script please
// include a mention of The Particle Lab of Teal in the
// comments. Thanks! :)

// EMITTER uses Sensor to find a named target

string targetname = "PTarget_123";

default {
state_entry() {
llParticleSystem( [ ] ); // make sure particles are off!
llSensor( targetname, "", PASSIVE, 10.0, TWO_PI );
}

touch_start(integer n) {
llSensor( targetname, "", PASSIVE, 10.0, TWO_PI );
}

sensor(integer number_of_matches) {
llParticleSystem( [ PSYS_SRC_TARGET_KEY, llDetectedKey(0) ,
PSYS_PART_START_SCALE, <.1,.1, 0>,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE,
PSYS_PART_MAX_AGE, 1.75,
PSYS_SRC_OMEGA, <0,0,1>,
PSYS_SRC_ACCEL, <0,0,.15>,
PSYS_SRC_ANGLE_BEGIN, PI_BY_TWO,
PSYS_SRC_ANGLE_END, PI_BY_TWO,
PSYS_PART_FLAGS, (
PSYS_PART_TARGET_POS_MASK
| PSYS_PART_EMISSIVE_MASK ) ] );
}

no_sensor() {
// do nothing
}

on_rez(integer n) { llResetScript(); }
}



_____________________
* The Particle Laboratory * - One of SecondLife's Oldest Learning Resources.
Free particle, control and targetting scripts. Numerous in-depth visual demonstrations, and multiple sandbox areas.
-
Stop by and try out Jopsy's new "Porgan 1800" an advanced steampunk styled 'particle organ' and the new particle texture store!
Captain Roo
Registered User
Join date: 1 Feb 2005
Posts: 5
02-05-2007 03:18
Hi,
Thanks for all the help Newgate Ludd, and Jopsy Pendragon.
I have combined parts of both scripts which seem to be working great.

Thanks again