Re: Scripts Library
Posted: Mon Mar 24, 2014 6:54 pm
I wrote this cannon ball script that explodes when it hits land or other prims. But it just sank to the bottom of the water and exploded on the bottom. So I added a test while flying to detect when it crosses the boundary from air to water, calculate the intersection with the water, and put in a water splash particle blue/white explosion in that location! Using Nickola Martynov's cannon script (with a few improvements) I have been firing at my friend's sailing ships. The water explosion makes it easy to predict which way to change the cannon angle (I'm just using the build tools to aim) and when you hit the ship, the explosion turns orange! Too much fun!
Note that the cannot must fire it with the "safety off", or a 1 in the last argument to llRezObject. I also moved the rezzing point of the ball to be 2 meters from the center of the cannon, in the direction it is facing. That keeps it from exploding when it appears. If your cannon is longer than 4 meters, you will have to up that number. Here is the modified cannot script:
Code: Select all
// cannon ball with effects
//
// This cannon ball explodes when it hits land or a prim
// and makes a splash when it passes through water
// NOTE: to prevent it from exploding at the munitions factory (in my hands)
// it has a safety: It won't explode unless it is rezzed with 1 in the last
// parameter of llRezObject()
// Wwittenby Kayaker Magic
// I hereby give this code away without restrictions
// use it for whatever, even put it in products for sale
// all I ask is that you think kindly of me.
//
integer mode=0; //mode for using timer, 0 is flying, 1 is dying
vector last; //where I was last tick
explode() //used when colliding with land or other prims
{
if (llGetStartParameter()==0) return; //check the safety
llSetStatus(STATUS_PHYSICS,FALSE); //stop where you are
llSetLinkPrimitiveParamsFast(LINK_THIS,[
PRIM_ROTATION,ZERO_ROTATION, //rotate to 0 so the particle explosion goes up
PRIM_COLOR, 0, <0,0,0>, 0.0 //become invisible, so they only see particles
]);
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROTATION,ZERO_ROTATION]);
llSetStatus(STATUS_PHANTOM,TRUE);
//rotate to 0 so the particle explosion goes up
llPlaySound("boom",1.0); //explosion sound
llParticleSystem([ //explosion particles
PSYS_PART_FLAGS, PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK|PSYS_PART_WIND_MASK,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE,
PSYS_SRC_BURST_RADIUS, 0.2,
PSYS_SRC_ANGLE_BEGIN, 0.0,
PSYS_SRC_ANGLE_END, 0.4,
PSYS_PART_START_COLOR, <1,0.5,0>, //start orange
PSYS_PART_END_COLOR, <0,0,0>, //fade to black
PSYS_PART_START_ALPHA, 1.0, //start opaque
PSYS_PART_END_ALPHA, 0.0, //fade to transparent
PSYS_PART_START_SCALE, <0.5,0.5,1>, //start small
PSYS_PART_END_SCALE, <4.0,4.0,1>, //end big
PSYS_SRC_TEXTURE,"", //default texture
PSYS_SRC_MAX_AGE, 0.2, //explosion emits for only this long
PSYS_PART_MAX_AGE, 5.0, //each particle lives this long
PSYS_SRC_BURST_RATE, 0.02, //a value of 0 here "starves" other emitters
PSYS_SRC_BURST_PART_COUNT, 20, //how many per burst
PSYS_SRC_ACCEL, <0,0,-4.0>, //make them fall back down
PSYS_SRC_BURST_SPEED_MIN, 6.0, //how fast they jump
PSYS_SRC_BURST_SPEED_MAX, 8.0
]);
llSetTimerEvent(2); //give the particles time to happen
mode=1; //then die
}
default
{
state_entry()
{
llOwnerSay("reset");
llSetStatus(STATUS_PHYSICS,TRUE); //in case you forgot to do this
llSetStatus(STATUS_PHANTOM,FALSE);
llParticleSystem([]); //turn off any old particles
}
on_rez(integer armed)
{
llSetTimerEvent(0); //don't want an old one going off
if (armed>0) //only work when fired with a parameter
{
llSetTimerEvent(0.09); //check often for water
mode=0;
last=llGetPos(); //record the starting position
}
}
timer()
{
if (llGetStartParameter()==0) return; //check the safety
if (mode==0) //still flying, check for water
{
float wat=llWater(ZERO_VECTOR); //how high the water is
vector pos=llGetPos(); //where cannon ball is now
if (last.z>wat && pos.z<=wat) //did I pass through the water surface?
{
llSetStatus(STATUS_PHYSICS,FALSE); //stop where you are
//interpolate your position back to water's surface
pos=last+(pos-last)*(last.z-wat)/(last.z-pos.z);
llSetLinkPrimitiveParamsFast(LINK_THIS,[
PRIM_ROTATION,ZERO_ROTATION, //rotate to 0 so the particle explosion goes up
PRIM_POSITION,pos, //sit on the surface
PRIM_COLOR, 0, <0,0,0>, 0.0 //become invisible, so they only see particles
]);
llSetStatus(STATUS_PHANTOM,TRUE);
llPlaySound("boom",1.0); //splash sound
llParticleSystem([ //explosion particles
PSYS_PART_FLAGS, PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK|PSYS_PART_WIND_MASK|PSYS_PART_EMISSIVE_MASK ,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE,
PSYS_SRC_BURST_RADIUS, 0.2,
PSYS_SRC_ANGLE_BEGIN, 0.0,
PSYS_SRC_ANGLE_END, 0.4,
PSYS_PART_START_COLOR, <0.125,.25,.35>, //start aquamarine
PSYS_PART_END_COLOR, <1,1,1>, //fade to white
PSYS_PART_START_ALPHA, 1.0, //start opaque
PSYS_PART_END_ALPHA, 0.0, //fade to transparent
PSYS_PART_START_SCALE, <0.5,0.5,1>, //start small
PSYS_PART_END_SCALE, <4.0,4.0,1>, //end big
PSYS_SRC_TEXTURE,"", //default texture
PSYS_SRC_MAX_AGE, 0.3, //explosion emits for only this long
PSYS_PART_MAX_AGE, 5.0, //each particle lives this long
PSYS_SRC_BURST_RATE, 0.02, //a value of 0 here "starves" other emitters
PSYS_SRC_BURST_PART_COUNT, 20, //how many per burst
PSYS_SRC_ACCEL, <0,0,-4.0>, //make them fall back down
PSYS_SRC_BURST_SPEED_MIN, 6.0, //how fast they jump
PSYS_SRC_BURST_SPEED_MAX, 8.0
]);
llSetTimerEvent(2); //give the particles and sound time to happen
mode=1; //then die
}
last=pos; //record this position for next test
}
else //mode 1, die when the timer happens now.
{
llDie();
}
}
collision_start(integer num)
{
explode();
}
land_collision_start( vector pos )
{
explode();
}
}
Code: Select all
default
{
touch_start(integer cannon)
{
string floater = llGetInventoryName(INVENTORY_OBJECT, 0);
vector power=<0,0,25>*llGetRot();
llRezObject(floater,llGetPos()+<0,0,2>*llGetRot(),power,llGetRot(),1); //safety off!
}
}