07-21-2019, 03:13 PM
Hang Glider Script for Opensim 09 and Bulletsim Physik
The script has been approved under opensim 09. With some changes it should run under other conditions too.
Instruction:
1. create a box with the size 4 x 3 x 0.4m. Change the prim setting from "touch" to "sit on object". The prim must not be phantom!
2. insert a seat animation in this prim.
3. Drop the script inside the prim, reset it, and take seat. The script will make the prime invisible. Use control ALT T to view it. Now try flying the object.
The box is used as physical shape of the glider. So if you use it for other flying objects you have to change the Prims sizes.
Enjoy your flight!
If you dont want to build from scratch, you can get a complete mesh glider with aditional options in the souvenir shop of my sim Isla Bonita.
148.251.8.108:8002/Isla Bonita
Operation instruction:
With cursor forward you start and increase power. You need a minimum speed of 20kmh for takeoff.
Above this speed the "page UP" Button allows to increase hight.
Page down decreases hight.
Use Cursor left and right for steering
Touch cursor down to start the automatic landing sequence.
Please remove your AO completle before start. It will drop a script reset at simborder and you loose control.
The script has been approved under opensim 09. With some changes it should run under other conditions too.
Instruction:
1. create a box with the size 4 x 3 x 0.4m. Change the prim setting from "touch" to "sit on object". The prim must not be phantom!
2. insert a seat animation in this prim.
3. Drop the script inside the prim, reset it, and take seat. The script will make the prime invisible. Use control ALT T to view it. Now try flying the object.
The box is used as physical shape of the glider. So if you use it for other flying objects you have to change the Prims sizes.
Enjoy your flight!
If you dont want to build from scratch, you can get a complete mesh glider with aditional options in the souvenir shop of my sim Isla Bonita.
148.251.8.108:8002/Isla Bonita
Operation instruction:
With cursor forward you start and increase power. You need a minimum speed of 20kmh for takeoff.
Above this speed the "page UP" Button allows to increase hight.
Page down decreases hight.
Use Cursor left and right for steering
Touch cursor down to start the automatic landing sequence.
Please remove your AO completle before start. It will drop a script reset at simborder and you loose control.
Code:
// P315 Release V1 Hang glider Script für Simcrossing in Opensim 09
// by Tron MCP
// Version 1.0 Stand 29.06.2019
// Creative Commons Version
// feel free to use for your builds.
// The Scritp itself has to stay free of costs and fullperm. The header has to be left unchanged.
//==== Globale User Variablen die ohne Multiposer benötigt werden ====
integer debug = FALSE; // Debug Modus
integer racemode = TRUE; // Zeigt Geschwindigkeits Text an
string sitzanimation; // FahrerAnimation
vector sitzposition = <-0.2, -0.0, -0.12>; // Sitzposition
// === FLUGZEUG KONSTANTEN =====
list getriebeliste = [ 0, 35]; // Antriebskraft je Gang
list auftriebsliste = [ 0 , 1]; // Auftrieb je Gang
list lenkgetriebeListe = [0 , 0.4 ]; // Wendigkeit, höhere Werte sind wendiger
list gangListe = ["Leerlauf", "Flugmodus"];
float kurvenkraenkung = 5;
float abfluggeschwindigkeit = 20.0; // Mindestgeschwindigkeit um Auftrieb zu erhalten
vector vel;
float fahrtgeschwindigkeit; // aktuelle Fluggeschwindigkeit
//==== SONSTIGE GLOBAL VARIABLEN ====
float wasserstand;
key kapitan;
integer imflug;
integer gang; // aktuell eingelegter Gang
float antriebskraft;
float steigfaehigkeit;
float lenkansprechverhalten;
integer ganganzahl;
string animation; // aktuell gespielte Animation
integer landeanflug;
//==== E N D G L O B A L V A R I A B L E D E C L A R A T I O N ====
init_engine()
{
imflug = FALSE;
ganganzahl = llGetListLength(getriebeliste);
llSetSitText("Fliegen");
vector gSitTarget_Rot = llRot2Euler( llGetRootRotation() ); // SIT TARGET in Anhängigkeit von RootPrim Rotation
llSitTarget(sitzposition, llEuler2Rot(DEG_TO_RAD * gSitTarget_Rot));
llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]);
llSetLinkAlpha(LINK_THIS, 0.0, ALL_SIDES);
llSetLinkAlpha(LINK_ALL_OTHERS, 1.0, ALL_SIDES);
}
gangschaltung(string schalte)
{
string gangname;
if (schalte == "Flugmodus") { gang = 1;} // in Flugmodus schalten
else { gang = 0;} // in Leerlauf schalten
antriebskraft = llList2Float(getriebeliste, gang);
steigfaehigkeit = llList2Float(auftriebsliste, gang);
lenkansprechverhalten = llList2Float(lenkgetriebeListe, gang);
gangname = llList2String(gangListe , gang);
}
init_followCam()
{
llSetCameraParams([
CAMERA_ACTIVE, 1, // 0=INACTIVE 1=ACTIVE
CAMERA_BEHINDNESS_ANGLE, 2.5, // (0 to 180) DEGREES
CAMERA_BEHINDNESS_LAG, 0.3, // (0 to 3) SECONDS
CAMERA_DISTANCE, 10.0, // ( 0.5 to 10) METERS
CAMERA_PITCH, 12.0, // (-45 to 80) DEGREES
CAMERA_POSITION_LOCKED, FALSE, // (TRUE or FALSE)
CAMERA_POSITION_LAG, 0.0, // (0 to 3) SECONDS
CAMERA_POSITION_THRESHOLD, 0.0, // (0 to 4) METERS
CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)
CAMERA_FOCUS_LAG, 0.0, // (0 to 3) SECONDS
CAMERA_FOCUS_THRESHOLD, 0.0, // (0 to 4) METERS
CAMERA_FOCUS_OFFSET, <-5, 0, 0> // <-10,-10,-10> to <10,10,10> METERS
]);
llForceMouselook(FALSE);
}
set_engine()
{
//Flugzeug PARAMETER
llSetVehicleType(VEHICLE_TYPE_AIRPLANE);
// linear friction
llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, <200, 200, 200> );
// angular friction
llSetVehicleFloatParam( VEHICLE_ANGULAR_FRICTION_TIMESCALE, 2 );
// linear motor
llSetVehicleVectorParam( VEHICLE_LINEAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_TIMESCALE, 2 );
llSetVehicleFloatParam( VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 1.0 );
// agular motor
llSetVehicleVectorParam( VEHICLE_ANGULAR_MOTOR_DIRECTION, <0, 0, 0> );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0 );
llSetVehicleFloatParam( VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.4);
// hover
llSetVehicleFloatParam( VEHICLE_HOVER_HEIGHT, 2 );
llSetVehicleFloatParam( VEHICLE_HOVER_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_HOVER_TIMESCALE, 3 );
llSetVehicleFloatParam( VEHICLE_BUOYANCY, 0.977 );
// linear deflection
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0 );
llSetVehicleFloatParam( VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 5 );
// angular deflection
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.1);
llSetVehicleFloatParam( VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 10);
// vertical attractor
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 1 );
llSetVehicleFloatParam( VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1 );
// banking
llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 1);
llSetVehicleFloatParam( VEHICLE_BANKING_MIX, .5);
llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 0.01);
// default rotation of local frame
llSetVehicleRotationParam( VEHICLE_REFERENCE_FRAME, <0,0,0,1>);
// remove these flags
llRemoveVehicleFlags( VEHICLE_FLAG_NO_DEFLECTION_UP
| VEHICLE_FLAG_HOVER_WATER_ONLY
| VEHICLE_FLAG_LIMIT_ROLL_ONLY
| VEHICLE_FLAG_HOVER_TERRAIN_ONLY
| VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT
| VEHICLE_FLAG_HOVER_UP_ONLY
| VEHICLE_FLAG_LIMIT_MOTOR_UP );
}
default
{
state_entry()
{
vector bootposition = llGetPos();
bootposition.z = llGround( ZERO_VECTOR );
wasserstand = llWater( ZERO_VECTOR );
if( bootposition.z < wasserstand ) { bootposition.z = wasserstand;}
llSetRegionPos(bootposition + <0,0,0.1>);
sitzanimation = llGetInventoryName(INVENTORY_ANIMATION, 0);
init_engine();
state Ground;
}
}
state Ground
{
state_entry()
{
llSetText("",<0,0,0>,1.0);
}
on_rez(integer param) { llResetScript();}
changed(integer change)
{
if ((change & CHANGED_LINK) == CHANGED_LINK)
{
kapitan = llAvatarOnSitTarget();
if (kapitan != NULL_KEY)
{ // wir haben einen Meister
llSetStatus(STATUS_PHYSICS, TRUE);
llSetStatus(STATUS_ROTATE_Y,TRUE);
llSetStatus(STATUS_ROTATE_Z,TRUE);
llSetStatus(STATUS_ROTATE_X,TRUE);
set_engine();
llRequestPermissions(kapitan, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA | PERMISSION_TRACK_CAMERA);
llSay(0,"Flieger grüß mir die Sonne!\n\r steuer mit Pfeil vorwärts/links/rechts , \n\r kontrollier die Höhe mit Bild auf/ab \n\r lande mit Pfeil runter.");
imflug = TRUE; // Teppich fliegt
landeanflug = FALSE;
}
else
{ // Meister hat Teppich verlassen
llSetStatus(STATUS_PHYSICS, FALSE);
imflug = FALSE; // Teppich steht
init_engine();
llStopAnimation( animation ); // entfällt bei Multiposer
llPushObject(kapitan, <3,3,21>, ZERO_VECTOR, FALSE);
llReleaseControls();
llClearCameraParams();
llSetCameraParams([CAMERA_ACTIVE, 0]);
if(racemode) { llSetText("",<0,0,0>,1.0); }
llResetScript();
}
}
if ((change & CHANGED_REGION) == CHANGED_REGION)
{
if(debug) llWhisper(0,"Simgrenze überquert");
wasserstand = llWater( ZERO_VECTOR ); // Wasserstand der neuen sim ermitteln
}
}
run_time_permissions(integer perm)
{
if (perm)
{
gangschaltung("Leerlauf"); // im Leerlauf starten
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE);
init_followCam();
llStopAnimation("sit");
animation = sitzanimation; // aktuelle Animation merken
llStartAnimation(animation);
llSleep(1.5);
}
}
control(key id, integer held, integer change)
{
if(imflug == FALSE) {return;}
vector AngularMotor;
if(racemode) llSetText( (string)fahrtgeschwindigkeit + " kmh",<1,1,1>,1.0);
if(held & CONTROL_UP) // STEIGFLUG gewählt
{
if( fahrtgeschwindigkeit > abfluggeschwindigkeit )
{
landeanflug = FALSE;
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft *0.75, 0, fahrtgeschwindigkeit * steigfaehigkeit>); // STEIGEN
AngularMotor.y = -2.5; // NASE anheben
}
else { llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft,0,0>); }
}
else if(held & CONTROL_DOWN) // SINKFLUG gewählt
{
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft *2, 0, - fahrtgeschwindigkeit * steigfaehigkeit>); // SINKEN
AngularMotor.y = 3.5; // NASE runterdrücken
}
else if (held & CONTROL_FWD) // weiterhin Vorwärts Gas gegeben
{ llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft,0,0>); }
if (~held & change & CONTROL_FWD) // Auf Vorwärtsflug geschalten
{
if (gang < 1)
{
gangschaltung("Flugmodus");
llSetTimerEvent(1.0); // gestartet: nun kontinuierlicher Hoehenverlust und Vortrieb zuschalten
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft/2 ,0,0>);
}
}
else if (held & CONTROL_BACK) // Automatisches Landen gewählt
{
if (!landeanflug) llSay(0,"Landung eingeleitet");
landeanflug = TRUE;
AngularMotor.y = 1; // NASE runterdrücken
}
if (held & CONTROL_ROT_RIGHT) // Steuerung nach RECHTS erfolgt
{
if( fahrtgeschwindigkeit > 3 ) // Einknicken in Kurvenmittelpunkt
{
AngularMotor.x += ( lenkansprechverhalten * kurvenkraenkung ); // ROLLEN rechts
AngularMotor.y = AngularMotor.y - ( lenkansprechverhalten * kurvenkraenkung * 0.5); // NASE anheben
}
AngularMotor.z -= lenkansprechverhalten; // RECHTS DREHEN
}
else if (held & CONTROL_ROT_LEFT) // Steuerung nach LINKS erfolgt
{
if( fahrtgeschwindigkeit > 3 ) // Einknicken in Kurvenmittelpunkt
{
AngularMotor.x -= ( lenkansprechverhalten * kurvenkraenkung ); // ROLLEN links
AngularMotor.y = AngularMotor.y - ( lenkansprechverhalten * kurvenkraenkung * 0.5); // NASE anheben
}
AngularMotor.z += lenkansprechverhalten; // LINKS DREHEN
}
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, AngularMotor);
}
timer()
{
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, < 10 , 0, -8>); // kontinuierlichen Vortrieb von 10 udn Sinken von 8
vel = llGetVel();
fahrtgeschwindigkeit = llVecMag(vel); // Geschwindigkeit ermitteln
vector drachenposition = llGetPos();
float flughoehe = drachenposition.z - llGround( ZERO_VECTOR );
if (flughoehe < 2 ) // automatisch landen
{
llSetTimerEvent(0.0);
llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, < 0,0,0>);
if( drachenposition.z < wasserstand ) { drachenposition.z = wasserstand;}
llSetRegionPos(drachenposition + <0,0,0.1>);
gangschaltung( "Leerlauf");
llSetText("",<0,0,0>,1.0);
}
}
}