virtual-talk.de
Hang Glider Script for Opensim - Druckversion

+- virtual-talk.de (http://virtual-talk.de)
+-- Forum: English Part (http://virtual-talk.de/forumdisplay.php?fid=46)
+--- Forum: Scripting (http://virtual-talk.de/forumdisplay.php?fid=49)
+--- Thema: Hang Glider Script for Opensim (/showthread.php?tid=1516)



Hang Glider Script for Opensim - Tron Mcp - 21.07.2019

Hang Glider Script for Opensim 09 and Bulletsim Physik


[attachment=9481]


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);
       }
   }
}