Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Pull command

Billybob Street
Registered User
Join date: 18 Aug 2004
Posts: 26
03-11-2006 07:22
Hey i need help adding a pull command to this parachute script if someone could do this for me it would be great, thanks
CODE




//all altitudes are in terms of Above Ground Level, AGL, and not absolute z position.
integer chuteHeight = 50; //the altitude (in m) at which the chute deploys
integer reserveHeight = 45; //the reserve chute's hardcoded trigger altitude
integer cutoffHeight = 3; //the altitude at which the
float pushStrength; //the nudge we give to slow the fall of the av wearing the chute
integer warned = FALSE;
float oldAltitude;
float currentAltitude;
float fudgeFactor = 0.3;
float waterTableTolerance = 0.5;//how close we have to be to the water surface to trigger a splash

//the parachute uses two timer intervals, a slow "dormant" interval when the av isn't in
//need of the chute, and a fast "active" interval once the chute realizes its wearer is falling.
float fastInterval = 0.1;
float timerInterval;
float slowInterval = 5.0;
integer splashActive = FALSE;
integer animSet;
string gAnimName = "hover_down"; //the animation to play once the chute deploys
integer version = 11;

splash() //the function that creates splash particles when water landing. Adapted from
//Ama Omega's fine work
{
//particle functions based off Ama Omega's unbeatable one.
integer glow = FALSE;
integer bounce = TRUE;
integer interpColor = TRUE;
integer interpSize = TRUE;
integer wind = FALSE;
integer followSource = FALSE;
integer followVel = FALSE;
integer pattern = PSYS_SRC_PATTERN_ANGLE_CONE;
key target = "";
float age = 3; // Life of each particle
float maxSpeed = 10; // Max speed each particle is spit out at
float minSpeed = 5; // Min speed each particle is spit out at
string texture; // Texture used for particles, default used if blank
float startAlpha = 0.7; // Start alpha (transparency) value
float endAlpha = 0.01; // End alpha (transparency) value
vector startColor = <0.5,0.5,1>; // Start color of particles <R,G,B>
vector endColor = <1,1,1>; // End color of particles <R,G,B> (if interpColor == TRUE)
vector startSize = <1,1,1>; // Start size of particles
vector endSize = <0.1,0.1,0.1>; // End size of particles (if interpSize == TRUE)
vector push = <0,0,-15>; // Force pushed on particles
float rate = .1; // How fast (rate) to emit particles
float radius = 0; // Radius to emit particles for BURST pattern
integer count = 100; // How many particles to emit per BURST
float outerAngle = 0.5; // Outer angle for all ANGLE patterns
float innerAngle = 0.5; // 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;
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;

llParticleSystem([ 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
]);
}

bubbles() //the function to create bubbles AFTER a water landing.
{
//particle functions based off Ama Omega's unbeatable one.
integer glow = FALSE;
integer bounce = FALSE;
integer interpColor = TRUE;
integer interpSize = TRUE;
integer wind = FALSE;
integer followSource = FALSE;
integer followVel = FALSE;
integer pattern = PSYS_SRC_PATTERN_EXPLODE;
key target = "";
float age = 5; // Life of each particle
float maxSpeed = 0.5; // Max speed each particle is spit out at
float minSpeed = 0; // Min speed each particle is spit out at
string texture = "bubble"; // Texture used for particles, default used if blank
float startAlpha = 1; // Start alpha (transparency) value
float endAlpha = 0.01; // End alpha (transparency) value
vector startColor = <1,1,1>; // Start color of particles <R,G,B>
vector endColor = <1,1,1>; // End color of particles <R,G,B> (if interpColor == TRUE)
vector startSize = <0.1,0.1,0.1>; // Start size of particles
vector endSize = <1,1,1>; // End size of particles (if interpSize == TRUE)
vector push = <0,0,0.5>; // Force pushed on particles
float rate = .1; // How fast (rate) to emit particles
float radius = 0.5; // Radius to emit particles for BURST pattern
integer count = 4; // How many particles to emit per BURST
float outerAngle = 0.5; // Outer angle for all ANGLE patterns
float innerAngle = 0.5; // 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;
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;

llParticleSystem([ 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
]);
}


//this script accepts input from an llDialog script in the same prim that allows for
//configuration of the trigger height, etc. This should be cut and dry.
message(integer sender_num, integer number, string message, key some_key)
{
if(llList2String(llParseString2List(message,[" "],[]),0) == "deployAltitude")
{
//llOwnerSay("Trigger set");
chuteHeight = llList2Integer(llParseString2List(message,[" "],[]),1);
llMessageLinked(LINK_ALL_OTHERS,chuteHeight, "", "");
}
if(llList2String(llParseString2List(message,[" "],[]),0) == "Launch")
{
//llOwnerSay("Trigger set");
integer pushStrength = llList2Integer(llParseString2List(message,[" "],[]),1);
llPushObject(llGetOwner(),<0,0,pushStrength*llGetMass()>,<0,0,0>,FALSE);
llOwnerSay("Launching!");
}
if (llList2String(llParseString2List(message,[" "],[]),0) == "Switch" && llList2String(llParseString2List(message,[" "],[]),1) == "On" )
{
llSetColor(<0.5,0.5,1>,ALL_SIDES); //set the chute backpack's color to grey when
//it is turned off
integer i;
for (i = 2 ; i <= llGetNumberOfPrims() ; i++ )
{
llSetLinkColor(i,<1,1,1>,ALL_SIDES);
}
llSetColor(<0.5,0.5,1>,ALL_SIDES);
state default;
}
if (llList2String(llParseString2List(message,[" "],[]),0) == "Switch" && llList2String(llParseString2List(message,[" "],[]),1) == "Off" )
{
llSetColor(<0.3,0.3,0.3>,ALL_SIDES);
integer i;
for (i = 1 ; i <= llGetNumberOfPrims() ; i++ )
{
llSetLinkColor(i,<0.3,0.3,0.3>,ALL_SIDES);
}
state off;
}
}


default
{
on_rez(integer foo)
{
llSetBuoyancy(0);
version = version + 1;//I increment the version on each rez of the chute for
//ease in debugging and rollback if necessary.
string ownerFullName = llKey2Name(llGetOwner()); //we store the owner's name
llSetObjectName(ownerFullName + "'s SimpleChute v."+(string)version);
llOffsetTexture(0 , 0.35, ALL_SIDES);//"Dormant"
llMessageLinked(LINK_ALL_OTHERS,0,"furl",""); //pack the chute canopy prims upon rez
}

state_entry()
{
llMessageLinked(LINK_ALL_OTHERS,0,"furl","");
llSetTimerEvent(slowInterval);
llSetBuoyancy(0);
llSetText("",<1,1,1>,1);
}

timer()
{
if(llGetAnimation(llGetOwner()) == "Falling Down" && timerInterval != fastInterval)
{
//then we're falling and need to start polling faster
llSetTimerEvent(fastInterval);
timerInterval = fastInterval;
llSetColor(<1,0.3,0.3>,ALL_SIDES);
llOffsetTexture(0 , 0.0, ALL_SIDES);//"Primed"
}
else if(timerInterval != slowInterval && llGetAnimation(llGetOwner()) != "Falling Down")
{
//then we're doing anything other than falling and we
//need to ease up on the server with fewer timer events
timerInterval = slowInterval;
llSetBuoyancy(0);
llSetTimerEvent(slowInterval);
llParticleSystem([]);
llSetColor(<0.5,0.5,1>,ALL_SIDES);
llOffsetTexture(0 , 0.35, ALL_SIDES);//"Dormant"
llMessageLinked(LINK_ALL_OTHERS,0,"furl","");
warned = FALSE;
}
vector position = llGetPos();
currentAltitude = position.z - llGround(<0,0,0>);//we determine AGL
vector velocity = llGetVel();
if( currentAltitude < chuteHeight && currentAltitude > cutoffHeight && llGetAnimation(llGetOwner()) == "Falling Down" && velocity.z < 0)
{
llMessageLinked(LINK_ALL_OTHERS, 1010101, "main", "");
state deployed;
}
//here we trigger the 'reserve' chute if by some "miracle" the main chute didn't deploy. This event should be logically impossible, but hey. ;)
if( currentAltitude < reserveHeight && currentAltitude > cutoffHeight && llGetAnimation(llGetOwner()) == "Falling Down" && velocity.z < 0)
{
llMessageLinked(LINK_ALL_OTHERS, 1010101, "reserve", "");
state deployed;
}
}

link_message(integer sender_num, integer number, string message, key some_key)
{
message(sender_num, number, message, some_key);
}
}

state deployed
{
state_entry()
{
llSetTimerEvent(fastInterval);
//animation elements from
//http://secondlife.com/badgeo/wakka.php?wakka=ExampleAnimationBasic
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); // ask the owner for permission to trigger animations
llStopAnimation("falldown");
llStartAnimation(gAnimName); // automatically trigger animation.
}

on_rez(integer param)
{
llResetScript(); // reset the script as soon as it starts (switches to default state)
}

attach(key id)
{
integer perm = llGetPermissions();

if (id != NULL_KEY) // make sure we're actually attached.
{
if (! (perm & PERMISSION_TRIGGER_ANIMATION)) // remember to use bitwise operators!
{
llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); // request permissions from the owner.
}
}
else
{
if (perm & PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation(gAnimName); // stop the animation
}
}
}

timer()
{
vector position = llGetPos();
currentAltitude = position.z - llGround(<0,0,0>);

if( currentAltitude < cutoffHeight )
{//we're within a few m of the ground and can pack the chute
state default;
}

vector speed = llGetVel();
llSetBuoyancy(-speed.z * fudgeFactor);
//setting the buoyancy as a function of downward velocity seems to have a nice damping
//effect most of the time. Sometimes, it rockets you upwards. Not sure why.
if(!warned)
{
llMessageLinked(LINK_ALL_OTHERS,0,"unfurl","");
llOffsetTexture(0 , -0.37, ALL_SIDES);//"Active"
llSetColor(<0,1,0>,ALL_SIDES);
warned = TRUE;
}

if(llFabs((currentAltitude - llFabs((llWater(ZERO_VECTOR) - llGround(ZERO_VECTOR))))) < waterTableTolerance && llWater(ZERO_VECTOR) > llGround(ZERO_VECTOR) && llGetAnimation(llGetOwner()) == "Falling Down")
{
splash();
splashActive = TRUE;
llMessageLinked(LINK_ALL_OTHERS,0,"furl","");
}
else if(splashActive)
{
//llStopAnimation(animation);
splashActive = FALSE;
if(llGetAnimation(llGetOwner()) == "Falling Down")
{
bubbles();
llMessageLinked(LINK_ALL_OTHERS,0,"furl","");
}
}
}

link_message(integer sender_num, integer number, string message, key some_key)
{
message(sender_num, number, message, some_key);
}

state_exit()
{
llStopAnimation(gAnimName);
llOffsetTexture(0 , 0.35, ALL_SIDES);//"Dormant"
llSetColor(<0.5,0.5,1>,ALL_SIDES);
llParticleSystem([]);
}
}

state off
{
link_message(integer sender_num, integer number, string message, key some_key)
{
message(sender_num, number, message, some_key);
}
}
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-11-2006 10:02
Use llTakeControls and have it fire when the user hits page up.

Also, have a look at my flight script (you can get it from the shop 500m over the land in my picks) to see one way of dealing with the "sometimes it rockets you upwards" problem. Gravity is uneven in many parts of second life, and you need to use a feedback loop to adjust impulse or bouyancy to avoid excursions.