How and What do i need to make a Halloween Candy Giver?also particle question

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

i know i keep coming on here asking about stuff, sorry but i dont know how else to learn lol can't aford lessons.

anyway  i have a cauldron and i want  to make  it give candy to people when they touch it.

how would i imput the candy and the script  to work togeather like that? what type of candy script thing would i need?

it seems complicated when i think about how it might operate.

anyone have the time to explain? or help me out a bit?

also, i've been tinkering with a smoke script

but i cant seem to slow down the smoke  with out it spreading  out too much

i tried playing with the numbers :

float maxSpeed = 0.3; // Max speed each particle is spit out at float minSpeed = 0.8; // Min speed each particle is spit out at﻿

Dont ask me why  max speed is lower then min speed i didnt creat this i bought it..and it has full permition.

it looks great but  it spits out way to fast and when i lower the numbers  it doesnt seem to slow down much.. and when i figure out how to slow it down it spreads out too much and starts to look crappy and misty instead of rising smoke puffs

thanks!

```// Particle Script 0.5
// Created by Ama Omega
// 3-26-2004

integer keystate = 0 ;

// Mask Flags - set to TRUE to enable
integer glow = FALSE;            // Make the particles glow
integer bounce = FALSE;          // Make particles bounce on Z plane of object
integer interpColor = TRUE;     // Go from start to end color
integer interpSize = TRUE;      // Go from start to end size
integer wind = TRUE;           // Particles effected by wind
integer followSource = FALSE;    // Particles follow the source
integer followVel = FALSE;       // Particles turn to velocity direction

// Choose a pattern from the following:
// PSYS_SRC_PATTERN_EXPLODE
// PSYS_SRC_PATTERN_DROP
// PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
// PSYS_SRC_PATTERN_ANGLE_CONE
// PSYS_SRC_PATTERN_ANGLE
integer pattern = PSYS_SRC_PATTERN_EXPLODE;

// Select a target for particles to go towards
// "" for no target, "owner" will follow object owner
//    and "self" will target this object
//    or put the key of an object for particles to go to
key target = "";

// Particle paramaters
float age = 2.5;                  // Life of each particle
float maxSpeed = 0.3;            // Max speed each particle is spit out at
float minSpeed = 0.8;            // Min speed each particle is spit out at
string texture = "4f714019-c1cf-6b16-994f-44b217022f1a";                 // Texture used for particles, default used if blank
float startAlpha = 0.8;           // Start alpha (transparency) value
float endAlpha = 0.0;           // End alpha (transparency) value
vector startColor = <0.5,0.5,0.5>;    // Start color of particles <R,G,B>
vector endColor = <0,0,0>;      // End color of particles <R,G,B> (if interpColor == TRUE)
vector startSize = <0.01,0.01,0.0>;     // Start size of particles
vector endSize = <2.0,2.0,0.0>;       // End size of particles (if interpSize == TRUE)
vector push = <.2,0,3>;          // Force pushed on particles

// System paramaters
float rate = 0.1;            // How fast (rate) to emit particles
float radius = 0.0;          // Radius to emit particles for BURST pattern
integer count = 5;        // How many particles to emit per BURST
float outerAngle = 0;    // Outer angle for all ANGLE patterns
float innerAngle = 0.1;    // Inner angle for all ANGLE patterns
vector omega = <0,0,0>;    // Rotation of ANGLE patterns around the source
float life = 0;             // Life in seconds for the system to make particles

integer flags;
list sys;
integer type;
vector tempVector;
rotation tempRot;
string tempString;
integer i;

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 (interpColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK;
if (interpSize) 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_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
];

llParticleSystem(sys);
}

default
{
state_entry()
{
//updateParticles();
keystate = 0 ;
updateParticles() ;
//llParticleSystem([]) ;
}

}```

Share on other sites

As far as having the cauldron give out candy when touched, that's pretty simple.

Just have the candy objects in the inventory of Cauldron.  In the state_entry() or on_rez() event, build a list of the candy objects in the inventory (and possibly in the changed() event, if you want it to update dynamically.)

Then, in the touch_start() event, have it do a llGiveInventory() and give a random entry from the list to the toucher.

Now, as for the particles.....

For smoke, I'd go with a cone pattern, that is wide, to start.  If the min of something is less than the max, it automatically gets set to the max, as I recall.  Might want to adjust those to more correct values.  Then just experiment with other parameters.

Share on other sites

We're glad to see you coming back with questions, Luxz.  It's a good way to learn.

The best way to learn how particles work is to experiment.  Go to the Particle Lab in world and wander around, playing with Jopsy's many displays and tutorials to see what each of the parameters does.  Then spend time in their sandbox, where you can get samples of scripts for many common effects.  I made a collection of those myself a long time ago and I still use some of them as starting points when I want to create a new effect.

Share on other sites

ah, that was very technical

i'm just a beginner when it comes to scripting,

when you mean inventory do you mean ''content'' the objects content where you  normally put scripts?

i found a code ''random item giver'' this may sound like a dumb question but i'm going to ask anyway.. where would i input the name of the items.. or how would i input the folder  or make it so it (the script) knows that there is a folder  full of objects? cause there is no state_entry()﻿ or on_rez()﻿

do  i put it in :  touch_start(integer total_number)﻿ or is that the place where you input how many objects are in the folder?

`//Emmas Seetan //21 September, 16:46  default {     touch_start(integer total_number)     {         float totalobjects = llGetInventoryNumber(INVENTORY_OBJECT); //number of objects         totalobjects = llFrand(totalobjects); //Total objects         llGiveInventory(llDetectedKey(0),llGetInventoryName(INVENTORY_OBJECT, (integer)totalobjects)); //Give any random  object out of the total     } }`

Rolig Loon﻿﻿ thanks , yeah i was there yesterday browsing and tinkering , but i get scared sometimes changing the numbers  of the coding at times, i geuss i have to make sure the script is copyable before i start to tinker with it just in case i mess up.

Share on other sites

That's a nice, self-contained random giver script.  Take a good look at each function it uses and refer to the LSL wiki to see why it's there.  Basically, whenever anyone touches it, the script

(1) asks how many objects are in its own inventory (Yes, that always means the Contents of the object where the script is located)

(2) Creates a random number between 0 and that total number

(3) Gives whoever touched it (llDetectedKey(0)) the object in inventory (INVENTORY_OBJECT) with that number.

Try it and see.

Never be afraid to experiment.  Keep  working copy of a script that sort of does what you want, and beat the heck out of it till it does exactly what you want.  The worst that can happen (usually) is that the script fails utterly and you have to start over.

• 1
Share on other sites

''and beat the heck out of it till it does exactly what you want.﻿''  LOL thanks  you made me feel a lot better - and thanks for taking a look at the script and helping me understand

Share on other sites

Sorry if I was a bit too technical there, I wasn't sure what level you are at......

The content tab of the Cauldron object is it's "inventory".  You can't put folders in there, just objects, notecards, textures, etc.

The generic script you posted does all of its work in the touch_start() event.  There are other events you can 'catch' when they happen.  Some happen automatically, some happen when certain things occur (like touch_start() is called whenever someone touches the object the script is in.)

So you would drop the various 'candy' objects into the cauldrons' content tab.  Then, when your script calls

`integer num_objects = llGetInventoryNumber(INVENTORY_OBJECT);`

You get the number of 'objects' the cauldron has in it.  You can then use

`string obj_name = llGetInventoryName(INVENTORY_OBJECT, rand_num);`

to get the 'name' of the object.  "rand_num" is an integer between 0 and num_objects-1.   So if num_objects is 5, rand_num could be 0,1,2,3, or 4.  You can use the llFrand() function to generate a random number, as you can see in the generic giver script you posted.

Now you know the object name, you can 'give' it to someone:

`llGiveInventory(to_who, obj_name);`

where "to_who" is the key of the person you want to give it to.  Note, if the object in the Cauldron's content tab is no-copy, then it will give that copy to the person, and remove it from the Cauldron, so the next time there wouldn't be one to give!

Now, a few additions to make the script a little more efficient.  If we don't think the Cauldron's inventory (i.e., the content tab contents) is going to change, we don't need to worry about the changed() event.  So we'll leave that off for now.  We'll add the candy objects, and then reset the object so it starts up fresh on next rez.

Then the script would be something like this:

`integer num_objects;// this is a 'global' variable.  It isn't declared inside an event, function, or state....so it can be accessed from ANY// event, function or state in the script default{// state_entry() is called whenever this state first starts up.    state_entry()    {        num_objects = llGetInventoryNumber(INVENTORY_OBJECT);        // we set this only once this way....    }// on_rez() is called whenever this object rezzes    on_rez(integer rez_param)    {        llResetScript();        // this just insures we go through state_entry() each time        // this object is rezzed.    } // touch_start() is called whenever the object is touched by an avatar    touch_start(integer num_touchers)    {        integer random_num = (integer)llFrand((float)num_objects);        //  This gives us a number from 0 to (num_objects - 1)        string obj_name = llGetInventoryName(INVENTORY_OBJECT, random_num);        //  This gets the name of that object        llGiveInventory(llDetectedKey(0), obj_name);        // This gives that object to the first detected toucher.        llSay(0, "Happy Halloween, " + llDetectedName(0) + "!  Have some candy!");        //  This just says something on the public channel so you know it did it!    }}`

Now, in the above, I did it step-by-step, rather than combining things a bit (like in the example script you posted) and added a few comments on each step so you could see exactly what was being done.

Now, a little explanation on the 'touch_start' events parameter....

Several events populate some information your script can access via a set of functions that all start with "llDetected", and are very useful.  Many of these events handle MULTIPLE people at once.  This is why the parameter for touch_start() and some others I labelled 'num_detected'......you could theoretically have 4 or 5 touches at essentially the same time.  In which case, the number would be passed into the event via that parameter.

That parameter is used in the various "llDetected" functions.  So above, when I called to "llDetectedKey(0)", that gives me the key of the first touch detected in this event.  If 'num_detected' was more than 1, then you really should call the same stuff in a loop over each.....which would look something like this:

`...    touch_start(integer num_detected)    {        integer i;        for(i=0; i < num_detected; i++)        {            integer rand_num = (integer)llFrand((float)num_objects);            string obj_name = llGetInventoryName(INVENTORY_OBJECT,rand_num);            llGiveInventory(llDetectedKey(i), obj_name);            llSay(0, llDetectedName(i) + " got some candy!");        }    }...`

But generally, touches don't accumulate like that except in special cases, and you can just assume you'll only have num_detected is 1.  Sensor() and other events you can't make that assumption though!

Hopefully, this has helped explain how/why these things work.....if you have any questions, feel free to ask!

• 1
Share on other sites

wow thank you thats amazing this really helped me understand and thanks for breaking it up,made it a lot easyer for me

the coding makes more sense now YAY!

Share on other sites

Simplest way? Put a give all items but this script, script in the prim. Name the prim something like "Halloween Candy - Wear Me." It gives them the entire contents of the prim (except that script) in a folder. The folder name tells them what it is, what happened, and what to do with it.

I know you got better answers, but for people who want an easy, free way to do it and aren't scripters, that will work also.