// Simple airplane script example
// THIS script IS PUBLIC DOMAIN! Do not delete the credits at the top of this script!
// Nov 25, 2003 - created by Andrew Linden and posted in the Second Life scripting forum
// Jan 05, 2004 - Cubey Terra - minor changes: customized controls, added enable/disable physics events
// Feel free to copy, modify, and use this script.
// Always give credit to Andrew Linden and all people who modify it in a readme or in the object description.
// assumes that the root primitive is oriented such that its
// local x-axis points toward the nose of the plane, and its
// local z-axis points toward the top
// control flags that we set later
integer gAngularControls = 0;
integer gLinearControls = 0;
// we keep track of angular history for more responsive turns
integer gOldAngularLevel = 0;
// the linear motor uses an accumulator model rather than keeping track
// of the linear control level history
vector gLinearMotor = <0, 0, 0>;
default
{
state_entry()
{
llSetSitText("Fly");
llCollisionSound("", 0.0);
// the sit and camera placement is very shape dependent
// so modify these to suit your vehicle
llSitTarget(<0.6, 0.0, 0.20>, ZERO_ROTATION);
llSetCameraEyeOffset(<-10.0, 0.0, 2.0> );
llSetCameraAtOffset(<3.0, 0.0, 1.0> );
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
// weak angular deflection
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.1);
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 1.0);
// strong linear deflection
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.2);
// somewhat responsive linear motor
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 20);
// somewhat responsive angular motor, but with 3 second decay timescale
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.5);
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 3);
// very weak friction
//llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1000.0, 1000.0, 1000.0> ); // CUBEY - original line
llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, <200, 20, 20> ); // CUBEY - increased friction
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <1000.0, 1000.0, 1000.0> );
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.65); // almost wobbly - CUBEY - increased from .25 to improve stability
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1.5); // mediocre response
llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.4); // medium strength
llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.1); // very responsive
llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.95); // more banking when moving
// hover can be better than sliding along the ground during takeoff and landing
// but it only works over the terrain (not objects)
//llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, 3.0);
//llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.5);
//llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 2.0);
//llSetVehicleFlags(VEHICLE_FLAG_HOVER_UP_ONLY);
// non-zero buoyancy helps the airplane stay up
// set to zero if you don't want this crutch
llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0.2);
// define these here for convenience later
// CUBEY - modified these as per Shadow's prefs
gAngularControls = CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_BACK | CONTROL_FWD;
gLinearControls = CONTROL_UP | CONTROL_DOWN;
llSetStatus(STATUS_PHYSICS, FALSE); //CUBEY - ensure that physics are disabled when plane is rezzed so it doesn't fly off
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
key agent = llAvatarOnSitTarget();
if (agent)
{
if (agent != llGetOwner())
{
// only the owner can use this vehicle
llSay(0, "You aren't the owner -- only the owner can fly this plane.");
llUnSit(agent);
llPushObject(agent, <0,0,10>, ZERO_VECTOR, FALSE);
}
else
{
// clear linear motor on successful sit
gLinearMotor = <0, 0, 0>;
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);
//llSetStatus(STATUS_PHYSICS, TRUE);
llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, 1000.0);
llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 1000.0);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
}
}
else
{
// stop the motors
gLinearMotor = <0, 0, 0>;
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, gLinearMotor);
// use friction to stop the vehicle rather than pinning it in place
//llSetStatus(STATUS_PHYSICS, FALSE);
llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, 1.0);
llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 1.0);
// driver is getting up
llReleaseControls();
llStopAnimation("sit");
llSetStatus(STATUS_PHYSICS, FALSE); //CUBEY - turn off physics to make sure the parked plane can't be moved
}
}
}
run_time_permissions(integer perm)
{
if (perm)
{
llStartAnimation("sit");
llTakeControls(gAngularControls | gLinearControls, TRUE, FALSE);
llSetStatus(STATUS_PHYSICS, TRUE); //CUBEY - enable physics when avatar sits
}
}
control(key id, integer level, integer edge)
{
// only change linear motor if one of the linear controls are pressed
vector motor;
integer motor_changed = level & gLinearControls;
if (motor_changed)
{
if(level & CONTROL_UP) //CUBEY
{
if (gLinearMotor.x < 0)
{
gLinearMotor.x = 0;
}
else if (gLinearMotor.x < 30)
{
gLinearMotor.x += 5;
}
motor_changed = TRUE;
}
if(level & CONTROL_DOWN) //CUBEY
{
if (gLinearMotor.x > 0)
{
gLinearMotor.x = 0;
}
else if (gLinearMotor.x > -30)
{
gLinearMotor.x -= 5;
};
motor_changed = TRUE;
}
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);
}
// only change angular motor if the angular levels have changed
motor_changed = (edge & gOldAngularLevel) + (level & gAngularControls);
if (motor_changed)
{
motor = <0,0,0>;
if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
{
// add roll component ==> triggers banking behavior
motor.x += 10;
}
if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
{
motor.x -= 10;
}
if(level & (CONTROL_BACK)) // CUBEY
{
// add pitch component ==> causes vehicle lift nose (in local frame)
motor.y -= 8;
}
if(level & (CONTROL_FWD)) // CUBEY
{
motor.y += 8;
}
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, motor);
}
// store the angular level history for the next control callback
gOldAngularLevel = level & gAngularControls;
}
}
没有评论:
发表评论