MOTORRAD SCRIPT für BULLET Physik in OPENSIM by Tron
Nachdem sich meine Bikescripte in Opensim verbreiten und ich mehrere positive Rückmeldungen über das angenehm präzise Fahrverhalten erhalten habe,
veröffentliche ich nun dieses Script hier im Forum unter fairen Bedingungen:
Es darf frei in Opensim verbeitet werden, aber nicht gegen Geld verkauft werden. Der Hinweis auf mich als Autor ist zu belassen.
Verkauf und Veröffentlichung in SL ist alleinig mir vorbehalten.
Mögen alle damit Spaß haben die gerne auf ihrer Sim biken wollen.
Das Script ist Fahrtechnisch ausgereift und fertig. Allerdings kann man Features noch hinzufügen.
Etliches ist bereits integriert was ich bei Nachfrage gesondert beschreiben werde.
Hier nun das Basis Script. Diese kommt in ein unsichtbares Root Prim. Die Form des Rootprims ist für die Fahrdynamik sehr wichtig. Früher habe ich bei Autos zu einen abgeschrägten Primwürfel geraten. Das ist aber nicht für ein gutes Motorrad zielführend. Minimum muss der Würfel von allen 4 Seiten abgeschrägt sein damit man sich in die Kurven legen kann. Besser ist ein Eiförmiges Mesh mit entsprechender Physik. Dieses ermöglicht sanftes in die Kurve legen.
Das Fahrzeug selber wird dann mit diesem "PhysikPrim" verlinkt, und zur Fahrzeit phantom.
Einige Features:
FAHREN:
- das Bike hat 5 Vorwärtsgänge, Leerlauf und Rückwärtsgang.
- es gibt Unterstützung für schnelle Schaltvorgänge.
Bremst man bei hoher Geschwindigkeit schaltet das Bike einen Gang herab um besseres Fahrverhalten und höhere Beschleunigung zu erzielen.
- Fahrparameter ändern sich dynamisch in Abhängigkeit von Gang und Fahrtgeschwindigkeit.
Dies gilt für Lenkung, Kurvenneigung, Spurtreue, Driften, Radhaftung sowie Aufsteigen des Vorderrades.
- Es gibt einen Leerlauf in dem das Bike nicht driftet. Auch wird in diesem Modus getankt.
- Im ersten Gang neigt das Bike zum Aufsteigen des Vorderrades wenn man Pfeil Links und Pfeil Rechts gleichzeitig drückt.
- Im ersten Gang driftet das Bike wenn Gasgeben und Lenken zusammen erfolgt. Dann Raucht auch das Hinterrad
FAHRERANIMATIONEN:
- Es wird pro Gang eine eigene Fahrer Animation unterstützt.
BENZINVERBRAUCH:
- Das Bike verbaucht je nach Fahrtgeschwindigkeit unterschiedlich Benzin. Dafür habe ich euch ein Tankstellenscript mit erstellt.
Der Sprittank sollte der Fahrzeuggröße angepasst sein. Für ein normales Motorrad hat sich als "vollertank" 600 bewährt.
Die initiale Tankfüllung nach Scriptreset wird in "benzintank" festgelegt. Es kann ja sein das man frisch gerezzte Bikes erstmal 1/3 voll haben will damit anfangs getankt werden muss.
Aktuell ist das Scritp beim Start auf vollen Tank eingestellt. Probiert aber mal 200 als "benzintank" aus.
PARKEN:
- Es gibt einen Parkmodus auf dem Seitenständer wenn ihr absteigt.
LICHT:
- es gibt Unterstützung für Bremslicht/Rücklicht.
- es gibt Unterstützung für einen Frontscheinwerfer.
- es gibt Unterstützung für einen optionalen Lichtkegel vor dem Fahrzeug zur Strassenbeleuchtung.
- die Einstellung der Paramater wird halbautomatisch unterstützt:
- das Script sucht sich selber die Linknummern heraus wenn ihr die entsprechenden Teile im Mesh folgendermaßen benennt: (auf Gross/Kleinschreibung achten)
"Bremslicht", "Scheinwerfer", "Lichtkegel", "Hinterrad".
Die zugehörigen Faces müsst ihr aber per Hand eintragen:
für Bremslicht in"bremslichtface" damit im Mesh die richtige Fläche leuchtet, und für Scheinwerfer in "frontlichtface".
Vorderrad und Hinterrad Script
In Vorder und Hinterrad kommt jeweils folgendes Radscript. Das Radscript dreht das verlinkte Radmesh direkt. Dazu muss die Achse des Rads passen.
Alternativ kann man hier auch die Achse im Script einstellen. lltargetOmega <x,y,z>
Tankstellen Script:
Das Tankstellenscript dient dem Betanken von mir gescripteter Fahrzeuge.
Das Script kommt in einen transparenten Primwürfel, der Phantom gemacht wird. Dieser soll die Zapfsäule großzügig ummanteln damit ein Klick auf die Zapfsäule das Prim trifft.
Getankt wird indem man auf dem Fahrzeug in Nähe der Zapfsäule sitzt, den LEERLAUF eingelegt hat, und die Zapfsäule anklickt.
Dann muss man warten bis der Tankvorgang abgeschlossen ist. Nun erhält man eine Meldung wieviel getankt wurde.
Die Zapfsäule ist auch für alle anderen modernen Fahrzeuge meiner Entwicklung zu nutzen. Aktuell sind das Autos. Boote werden folgen.
Die Tankstelle funktioniert aktuell nur interaktiv mit meinen Fahrzeugen.
Wenn jemand seine Fahrzeugscripte in das Tanksystem integrieren will, bitte hier posten für Hilfe, oder aus dem Bike Script herauslesen
So, nun wünsche ich viel Spaß, und freue mich auf Rückmeldungen
Tron
Nachdem sich meine Bikescripte in Opensim verbreiten und ich mehrere positive Rückmeldungen über das angenehm präzise Fahrverhalten erhalten habe,
veröffentliche ich nun dieses Script hier im Forum unter fairen Bedingungen:
Es darf frei in Opensim verbeitet werden, aber nicht gegen Geld verkauft werden. Der Hinweis auf mich als Autor ist zu belassen.
Verkauf und Veröffentlichung in SL ist alleinig mir vorbehalten.
Mögen alle damit Spaß haben die gerne auf ihrer Sim biken wollen.
Das Script ist Fahrtechnisch ausgereift und fertig. Allerdings kann man Features noch hinzufügen.
Etliches ist bereits integriert was ich bei Nachfrage gesondert beschreiben werde.
Hier nun das Basis Script. Diese kommt in ein unsichtbares Root Prim. Die Form des Rootprims ist für die Fahrdynamik sehr wichtig. Früher habe ich bei Autos zu einen abgeschrägten Primwürfel geraten. Das ist aber nicht für ein gutes Motorrad zielführend. Minimum muss der Würfel von allen 4 Seiten abgeschrägt sein damit man sich in die Kurven legen kann. Besser ist ein Eiförmiges Mesh mit entsprechender Physik. Dieses ermöglicht sanftes in die Kurve legen.
Das Fahrzeug selber wird dann mit diesem "PhysikPrim" verlinkt, und zur Fahrzeit phantom.
Einige Features:
FAHREN:
- das Bike hat 5 Vorwärtsgänge, Leerlauf und Rückwärtsgang.
- es gibt Unterstützung für schnelle Schaltvorgänge.
Bremst man bei hoher Geschwindigkeit schaltet das Bike einen Gang herab um besseres Fahrverhalten und höhere Beschleunigung zu erzielen.
- Fahrparameter ändern sich dynamisch in Abhängigkeit von Gang und Fahrtgeschwindigkeit.
Dies gilt für Lenkung, Kurvenneigung, Spurtreue, Driften, Radhaftung sowie Aufsteigen des Vorderrades.
- Es gibt einen Leerlauf in dem das Bike nicht driftet. Auch wird in diesem Modus getankt.
- Im ersten Gang neigt das Bike zum Aufsteigen des Vorderrades wenn man Pfeil Links und Pfeil Rechts gleichzeitig drückt.
- Im ersten Gang driftet das Bike wenn Gasgeben und Lenken zusammen erfolgt. Dann Raucht auch das Hinterrad
FAHRERANIMATIONEN:
- Es wird pro Gang eine eigene Fahrer Animation unterstützt.
BENZINVERBRAUCH:
- Das Bike verbaucht je nach Fahrtgeschwindigkeit unterschiedlich Benzin. Dafür habe ich euch ein Tankstellenscript mit erstellt.
Der Sprittank sollte der Fahrzeuggröße angepasst sein. Für ein normales Motorrad hat sich als "vollertank" 600 bewährt.
Die initiale Tankfüllung nach Scriptreset wird in "benzintank" festgelegt. Es kann ja sein das man frisch gerezzte Bikes erstmal 1/3 voll haben will damit anfangs getankt werden muss.
Aktuell ist das Scritp beim Start auf vollen Tank eingestellt. Probiert aber mal 200 als "benzintank" aus.
PARKEN:
- Es gibt einen Parkmodus auf dem Seitenständer wenn ihr absteigt.
LICHT:
- es gibt Unterstützung für Bremslicht/Rücklicht.
- es gibt Unterstützung für einen Frontscheinwerfer.
- es gibt Unterstützung für einen optionalen Lichtkegel vor dem Fahrzeug zur Strassenbeleuchtung.
- die Einstellung der Paramater wird halbautomatisch unterstützt:
- das Script sucht sich selber die Linknummern heraus wenn ihr die entsprechenden Teile im Mesh folgendermaßen benennt: (auf Gross/Kleinschreibung achten)
"Bremslicht", "Scheinwerfer", "Lichtkegel", "Hinterrad".
Die zugehörigen Faces müsst ihr aber per Hand eintragen:
für Bremslicht in"bremslichtface" damit im Mesh die richtige Fläche leuchtet, und für Scheinwerfer in "frontlichtface".
Code:
// P318 Motorrad mit Renngetriebe für Simcrossing in Opensim 09 by Tron V50
// Stand 12.09.2021 V2.0
// unterstützt Hinterraddrift, Gangschaltung mit Leerlauf
// Partikel Textur vorladen auf Fahrzeugprim, damit diese sofort angezeigt wird
//==== FAHRZEUG CHARAKTERISTIKA VARIABLEN: ====
// MOTOR
float bremskraft = 6; // Kraft der Betriebsbremse. Größer bremst stärker
float motorbremse = 1.0; // Motorbremswirkung 1.0 gut, 2.0 weniger Bremswirkung für längerere Auslauf
list getriebeliste = [ -5 , 0.001, 15, 25, 35, 45, 55 ]; // Maximalkraft & Geschwindigkeit des Motors je Gang [ -5 , 0, 15, 25, 35, 55, 70 ];
list beschleunigungsListe = [1.0, 100.0 , 1.0, 3.0, 6.0, 10.0, 15.0]; // Beschleunigungsdauer des Motors bis maximaler Ganggeschwindigkeit. 1 = schnell [1.0, 100.0 , 1.0, 3.0, 6.0, 10.0, 15.0];
list ganganimationListe = ["Bikerfahrer","Bikerfahrer","Bikerfahrer","Bikerfahrer","Bikerfahrer","Bikerfahrer","Bikerfahrer"];
list gangListe = ["Rückwärts","Leerlauf","1. Gang","2. Gang","3. Gang","4. Gang","5. Gang"];
// LENKUNG
float lenkansprechverhalten = 0.32; // 0.32 REAKTIONSZEIT der LENKUNG 0.2 knackig, 0.3 medium, 0,4träge
float lenkberuhgungszeit = 0.8; // 0.50 NACHWIRKZEIT der LENKUNG 0.2++ sehr direkt // 0.5 gut // 1.2 träge
float kurvenkraenkung; // 3 - 6 für Motorrad wird dynamisch zugewiesen
float einknicken = 4;
float lenkradius = 4; // Basiswirkung der Lenkung. größere Werte ermöglichen kleinerer Wendekreise. Wirkung wird dynamisch gesteuert: gut 4
integer racemode = TRUE; // Zeigt Geschwindigkeit und Benzin an, und verbraucht Benzin
vector sitzposition = < -0.690, 0.0, 1.65>; // Sitzposition
// Linknummern des FAHRZEUGS werden automatisch ermittelt anhand LINKNAMEN. Faces manuell eingetragen
integer bremslichtlink; // Bremslicht
integer bremslichtface = ALL_SIDES; // Face des Bremslichtes
integer frontlichtlink; // Frontscheinwerfer
integer frontlichtface = 6; // Face des Frontscheinwerfer manuell eintragen
integer lichtkegellink; // Lichtkegelprims vor dem Bike
integer hinterradlink = 5; // Linknummer des Hinterrades für Rauch
// TANKDIMENSIONIERUNG
float vollertank = 600; // Voller Tank
float benzintank = 600; // Initiale Tankfüllung
integer benzin;
//==== ENDE FAHRZEUG CHARAKTERISTIKA VARIABLEN ====
integer debug = TRUE;
// TANKEN
integer listenhandle; // für Tanken
integer channel = -1000; // Fernbedienungs Kanal für Tankstelle
// GLOBALE VARIABLEN
key biker;
integer bikefahrt;
integer gang; // aktuell eingelegter Gang
float antriebskraft;
integer ganganzahl;
string gangname;
string animation; // aktuell gespielte Animation
vector vel;
float fahrtgeschwindigkeit; // aktuelle Geschwindigkeit
float fahrfaktor; // Hilfsvariable zur Rechenreduktion
integer rechtslenk;
integer linkslenk;
integer bremslicht_ist_an; // aktueller Zustand
// RAUCH
integer rauchpartikelzahl = 1; // Anzahl Partikel pro Ausstoß und Prim
integer raddrift; // aktueller Zustand
list particle_parameters;
//==== 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 ====
// Ermitteln der aktuellen Linknummer anhand des Linknamens
integer getlink(string linkname)
{
integer linknummer = llGetNumberOfPrims();
do
{
if (linkname == llGetLinkName(linknummer)) { return (linknummer);}
linknummer--;
}
while (linknummer > 0);
return (0);
}
rauchpartikel() // Rauchpartikel Vorab initialisieren um in der Fahrschleife Zeit zu sparen
{
particle_parameters =
[
PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0), // erste Textur aus Prim auslesen und nehmen
PSYS_PART_START_SCALE, <3.0000,3.00000,3.00000>,
PSYS_PART_END_SCALE, <7.5,7.5,7.5>,
PSYS_PART_START_COLOR, <0.2 , 0.2 ,0.2 >,
PSYS_PART_END_COLOR, <0.4,0.4,0.4>,
PSYS_PART_START_ALPHA, 0.75,
PSYS_PART_END_ALPHA, 0.0,
PSYS_SRC_BURST_PART_COUNT, rauchpartikelzahl,
PSYS_SRC_BURST_RATE, 0.1, //0.3
PSYS_PART_MAX_AGE, 2.0,
PSYS_SRC_MAX_AGE,(float) 0.0,
PSYS_SRC_PATTERN, 2,
PSYS_SRC_BURST_SPEED_MIN, 1.0,
PSYS_SRC_BURST_SPEED_MAX, 2.05,
PSYS_SRC_BURST_RADIUS, 0.1,
PSYS_SRC_ANGLE_BEGIN, (float) 0.08*PI,
PSYS_SRC_ANGLE_END, (float) 0.08*PI,
PSYS_SRC_ACCEL, <2,0,-.3>,
PSYS_PART_FLAGS, (integer)( 0 | PSYS_PART_INTERP_COLOR_MASK | PSYS_PART_INTERP_SCALE_MASK | PSYS_PART_EMISSIVE_MASK )
];
}
hinterraddrift(integer raddriftenlassen) // Durchdrehendes Hinterrad: Rauch Erzeugung und Fahrwerte ändern: an / aus
{
raddrift = raddriftenlassen;
if (raddrift)
{
llMessageLinked(LINK_SET, 10, "2", NULL_KEY);
llLinkParticleSystem(hinterradlink, particle_parameters );
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY,0.1); // SPURTREUE: starkes seitliches Driften des Hinterrades 0.2
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 40.00); // DRIFTZEIT: starkes Nachdriften des durchdrehenden Hinterrades 10.0
lenkradius = 8;
}
else
{
llMessageLinked(LINK_SET, 10, "1", NULL_KEY);
llLinkParticleSystem(hinterradlink, []);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY,1.0); // SPURTREUE: kein seitliches Driften des Hinterrades 1.0
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 1.0); // DRIFTZEIT: wenig Nachdriften des Hinterrades 1.0
lenkradius = 4;
}
}
bikeausrichten(integer park) // Richtet das Bike in Park und Fahr Positionen aus
{
rotation bikerot = llGetRot();
if (park) llSetRot(<-0.4, bikerot.y, bikerot.z, PI>); // Bike parken (<0.0, -0.20, bikerot.z, PI>);
else llSetRot(<0.0, bikerot.y, bikerot.z, PI>); // Bike fahren
}
frontlicht(integer an) // Schaltet Frontlicht an oder aus
{
// PRIM_POINT_LIGHT, TRUE, primcolor, fIntensity, fRadius, fFalloff ]
if (an)
{
llSetLinkPrimitiveParamsFast(frontlichtlink, [PRIM_GLOW, frontlichtface, 1.0]);
llSetLinkPrimitiveParamsFast(lichtkegellink, [PRIM_POINT_LIGHT, TRUE, <1.0, 1.0, 1.0>, 1.0, 10.0, 0.20, PRIM_GLOW, ALL_SIDES, 0.05]);
llSetLinkPrimitiveParamsFast(bremslichtlink, [PRIM_POINT_LIGHT, FALSE, <1.0, 0.0, 0.0>, 0.0, 0.0, 0.0, PRIM_GLOW, bremslichtface, 0.5]);
}
else
{
llSetLinkPrimitiveParamsFast(frontlichtlink, [PRIM_GLOW, frontlichtface, 0.0]);
llSetLinkPrimitiveParamsFast(lichtkegellink, [PRIM_POINT_LIGHT, FALSE, <0.0, 0.0, 0.0>, 0.0, 0.0, 0.0, PRIM_GLOW, ALL_SIDES, 0.0]);
llSetLinkPrimitiveParamsFast(bremslichtlink, [PRIM_POINT_LIGHT, FALSE, <1.0, 0.0, 0.0>, 0.0, 0.0, 0.0, PRIM_GLOW, bremslichtface, 0.0]);
}
}
bremslicht(integer bremse) // Schaltet Bremslicht an oder aus
{
if (bremse) {llSetLinkPrimitiveParamsFast(bremslichtlink, [PRIM_POINT_LIGHT, TRUE, <1.0, 0.0, 0.0>, 1.0, 2.0, 0.5 , PRIM_GLOW, bremslichtface, 1.0]);}
else {llSetLinkPrimitiveParamsFast(bremslichtlink, [PRIM_POINT_LIGHT, FALSE, <1.0, 0.0, 0.0>, 0.0, 0.0, 0.0, PRIM_GLOW, bremslichtface, 0.5]);}
bremslicht_ist_an = bremse;
}
integer tankanzeige(integer funktion )
{
if (funktion == 1)
{
string kmh = (string)llRound(fahrtgeschwindigkeit * 5);
string rpm = (string)llRound(((fahrtgeschwindigkeit / llList2Float(getriebeliste, gang ))*7000)+600);
if(gang < 2) rpm = "600";
string liter = (string) llRound((benzintank / 50));
if (benzintank < ( vollertank * 0.15))
{
if(benzintank > 0) { llSetText( kmh + " kmh \n Gang: "+ gangname + " rpm: "+ rpm + " \n Benzin: RESERVE " + liter +" Liter",<1,0,0>,1.0); return(TRUE);}
else { benzintank = 0; antriebskraft = 0; llSetText( kmh + " kmh \n Gang: "+ gangname + " rpm: 0 \n Benzin: TANK LEER " ,<1,0,0>,1.0); return(FALSE);}
}
else { llSetText( kmh + " kmh \n Gang: "+ gangname + " rpm: "+ rpm + " \n Benzin: " + liter +" Liter",<1,1,1>,1.0); return(TRUE);}
}
else {llSetText("",<0,0,0>,0.0); return(TRUE);}
}
init_engine() // Vorinitialisierung des Bikes
{
bikefahrt = FALSE;
ganganzahl = llGetListLength(getriebeliste);
llSetSitText("Biker");
llSitTarget(sitzposition, ZERO_ROTATION);
llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]);
// LINKNummern ermitteln anhand Namen der Links
bremslichtlink = getlink("Bremslicht");
frontlichtlink = getlink("Scheinwerfer");
lichtkegellink = getlink("Lichtkegel"); // Lichtkegelprims vor Fahrzeug
hinterradlink = getlink("Hinterrad");
}
gangschaltung(string schalte) // Gangumschaltung
{
string neueanimation;
if (schalte == "Leerlauf") { gang = 1; llMessageLinked(LINK_SET, 10, "0", NULL_KEY); llMessageLinked(LINK_SET, 20, (string)0, NULL_KEY);} // in Leerlauf schalten
else if (schalte == "Rückwärts") { gang = 0; llSleep(0.5); init_fahrercam(-45.0, 6.0); llMessageLinked(LINK_SET, 10, "-1", NULL_KEY); } // Rückwärts Gang einlegen
else if (schalte == "Vorwärts") { gang = 2; llSleep(0.5); init_fahrercam(0.0, 2.5); llMessageLinked(LINK_SET, 10, "1", NULL_KEY);} // in 1. Gang schalten
else if (schalte == "+") { gang += 1;} // in höheren Gang schalten
else { gang -= 1;} // schalte in niedrigeren Gang
antriebskraft = llList2Float(getriebeliste, gang);
float drehmoment = llList2Float(beschleunigungsListe, gang);
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, drehmoment);
neueanimation = llList2String(ganganimationListe, gang);
gangname = llList2String(gangListe , gang);
benzin = tankanzeige(1);
hinterraddrift(FALSE);
if (neueanimation != animation) // Animationswechsel
{
llStopAnimation(animation);
animation = neueanimation;
llStartAnimation(animation);
}
if (gang == 1){ llSetTimerEvent(0.0);} else llSetTimerEvent(1.0);
}
// *** KAMERA EINSTELLEN
init_fahrercam(float angle, float distance)
{
llSetCameraParams(
[
CAMERA_ACTIVE, 1, // 0=INACTIVE 1=ACTIVE
CAMERA_BEHINDNESS_ANGLE, angle, // (0 to 180) DEGREES
CAMERA_BEHINDNESS_LAG, 1.3, // (0 to 3) SECONDS 0.3
CAMERA_DISTANCE, distance, // ( 0.5 to 10) METERS 2.5
CAMERA_PITCH, 12.0, // (-45 to 80) DEGREES
CAMERA_POSITION_LOCKED, FALSE, // (TRUE or FALSE)
CAMERA_POSITION_LAG, 0.25, // (0 to 3) SECONDS 0.05
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, <0, 0, 0> // METERS
]);
llForceMouselook(FALSE);
}
set_engine()
{
llSetVehicleType(VEHICLE_TYPE_CAR);
// default rotation of prim
llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME, <0.00, 0.00, 0.00, 1.00>);
// VEHICLE FLAGS
llSetVehicleFlags( VEHICLE_FLAG_NO_DEFLECTION_UP | VEHICLE_FLAG_HOVER_TERRAIN_ONLY); // Fahrzeug Grundausrichtung bei falschen Mesh Axen
// LINEAR MOTOR ANTRIEB UND SPURTREUE
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); // 1.0 BESCHLEUNIGUNG des MOTORS: Wirkung: Größere Zahl ergibt geringere Beschleunigung. 10 Gut für hohen Gang
llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, motorbremse); // 2.0 MOTORBREMSE: Wirkung: Kleinere Zahl größere Motorbremswirkung
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY,1.0); // 1.0 SPURTREUE: bewirkt starkes seitliches driften des Hinterrades. 0.2 driftet stark für Start mit drehenden rauchenden Reifen, 0.5 leichtes driften. 1 fährt Spurtreu
llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 1.00); // 1.0 DRIFTZEIT nach Lenkstop: Kleine Zahl kurzes Nachdriften [1, .. , 100 ] Griffigkeit der Strasse simulierbar. 1trockener Asphalt, 100 Eis. 10 für Start mit drehenden rauchenden Reifen,
// ANGULAR MOTOR LENKUNG UND NEIGUNG BEI KURVEN
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, lenkansprechverhalten); // REAKTIONSZEIT der LENKUNG
llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, lenkberuhgungszeit); // NACHLENKZEIT bis GERADEAUSLAUF
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 1.00); // 1.0 SPURTREUE wird dynamisch eingestellt
llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 1.00); // 1.00 DRIFTZEIT
// Friction Reibung
llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0,1.0,1.0> ); // ohne sichtbare Auswirkung <1.0,1.0,0.10>
llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <1.0,1.0,1.0> ); // ohne sichtbare Auswirkung <1.0,1.0,1.0>
// Vertical Attraction Vertikale Zugkraft
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 1.0); // ohne sichtbare Auswirkung 5.5
llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1.00); // 1.0 FINAL sonst säuft Nase in Kurven ab // Werte <= 0.4 ZAPPELT Fahrzeug schlecht! SOLL1
// BANKING Nachschieben
llSetVehicleFloatParam( VEHICLE_BANKING_EFFICIENCY, 1.0 );
llSetVehicleFloatParam( VEHICLE_BANKING_TIMESCALE, 0.5 );
llSetVehicleFloatParam( VEHICLE_BANKING_MIX, 1.0 );
llCollisionSound("", 0.0);
}
default
{
state_entry()
{
if(!debug) llSetLinkTexture(LINK_THIS,llGetInventoryName(INVENTORY_TEXTURE, 0), ALL_SIDES); // Partikeltextur auf roortprim vorladen damit sie sofort angezeigt wird
bikeausrichten(TRUE);
init_engine();
rauchpartikel();
llSetText("",<0,0,0>,0.0);
state Fahrbereit;
}
on_rez(integer param) { llResetScript();}
}
state Fahrbereit
{
state_entry() {}
on_rez(integer param) { llResetScript();}
changed(integer change)
{
if ((change & CHANGED_LINK) == CHANGED_LINK)
{
biker = llAvatarOnSitTarget(); // wir haben einen Fahrer
if (biker != NULL_KEY)
{ llRequestPermissions(biker, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA | PERMISSION_TRACK_CAMERA);}
else
{ // Fahrer ist aufgestanden
llMessageLinked(LINK_SET, 10, "0", NULL_KEY); // Räder stoppen
llSetTimerEvent(0.0);
llSetStatus(STATUS_PHYSICS, FALSE);
bikeausrichten(TRUE);
bremslicht(FALSE); // Bremslicht ausschalten
frontlicht(FALSE);
bikefahrt = FALSE;
llStopAnimation(animation);
hinterraddrift(FALSE);
llPushObject(biker, <3,3,21>, ZERO_VECTOR, FALSE);
llReleaseControls();
llClearCameraParams();
llSetCameraParams([CAMERA_ACTIVE, 0]);
benzin = tankanzeige(FALSE);
// llResetScript(); // Hinderlich bei Benzinberechnung. Ansonsten gut
llListenRemove(listenhandle);
state default;
}
}
}
run_time_permissions(integer perm)
{
if (perm)
{
set_engine(); // MOTOR einstellen
listenhandle = llListen(channel,"","","");
bikeausrichten(FALSE);
llSetStatus(STATUS_PHYSICS | STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, TRUE);
frontlicht(TRUE);
bikefahrt = TRUE; // BIKE fährt
animation = "sit";
gangschaltung("Leerlauf"); // im Leerlauf starten und Animation ändern
benzin = tankanzeige(TRUE);
init_fahrercam(0.0, 2.5);
llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE);
llSleep(1.5);
}
}
control(key id, integer tastenzustand, integer tastenaenderung)
{
if(!bikefahrt){return;}
vector AngularMotor;
integer tastefrischgedrueckt = tastenzustand & tastenaenderung;
integer tastelosgelassen = ~tastenzustand & tastenaenderung;
// integer tastegehalten = tastenzustand & ~tastenaenderung;
// integer tastenichtgehalten = ~tastenzustand & ~tastenaenderung;
vel = llGetVel();
fahrtgeschwindigkeit = llVecMag(vel); // Geschwindigkeit
fahrfaktor = fahrtgeschwindigkeit /10; // Hilfsvariable zur Rechenreduktion
// in höheren Gang schalten mit BILD AUF
if(tastefrischgedrueckt & (CONTROL_UP | CONTROL_RIGHT)) { if (gang < (ganganzahl -1)) gangschaltung("+");}
// sonst in niedrigerne Gang schalten mit BILD AB
else if(tastefrischgedrueckt & (CONTROL_DOWN | CONTROL_LEFT)) { if (gang > 0) gangschaltung("-");}
// weiterhin Vorwärts Gas geben
if (tastenzustand & CONTROL_FWD)
{
if (gang < 2) gangschaltung("Vorwärts"); // Auf 1. Gang schalten wenn kein Vorwärtsgang eingelegt war
else { llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft,0,0>);} // Linear Motor Kraft geben
// Sport Gangschaltung aufwärts
// if ((tastefrischgedrueckt & CONTROL_ROT_RIGHT) && (tastefrischgedrueckt & CONTROL_ROT_LEFT)) { if (gang < (ganganzahl -1)) gangschaltung("+"); tastefrischgedrueckt = FALSE; tastenzustand = FALSE; llSleep(0.1); return; }
// Sport Gangschaltung abwärts
if ((tastefrischgedrueckt & CONTROL_BACK)) {if (gang > 2) gangschaltung("-"); tastefrischgedrueckt = FALSE; tastenzustand = FALSE; llSleep(0.1); return; }
}
// sonst Rückwärts schalten (nur wenn kein Gas gegeben wird, und Fahrzeug fast im Stillstand)
else if (tastefrischgedrueckt & CONTROL_BACK) { if ((fahrtgeschwindigkeit < 0.5 ) && (gang > 0)) { gangschaltung("Rückwärts");}}
// weiterhin Rückwärts fahren oder Bremsen
if (tastenzustand & CONTROL_BACK)
{
if (gang > 1)
{
if (!bremslicht_ist_an) bremslicht(TRUE);
if(fahrtgeschwindigkeit > 9) {llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <-bremskraft, 0, 0>);} // stark Bremsen
else llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0, 0, 0>); // sanft Bremsen, Rückwärts fahren verhindern
}
else if (gang == 0) { llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <antriebskraft, 0, 0>);} // Rückwärts fahren
}
// sonst Bremse lösen
else if (tastelosgelassen & CONTROL_BACK){ if (bremslicht_ist_an) bremslicht(FALSE); llMessageLinked(LINK_SET, 20, (string)fahrtgeschwindigkeit, NULL_KEY);}
// Vorderrad Aufsteigen bei Vorwärtsfahrt und links + rechts Pfeiltasten
if ((tastenzustand & CONTROL_ROT_RIGHT) && (tastenzustand & CONTROL_ROT_LEFT))
{
if((gang == 2) || (gang == 3)) // nur im 1. und 2. Gang aufsteigen lassen
{
rechtslenk++; linkslenk++; // eventuell rauchende Reifen erhalten
AngularMotor.y -= ( 2.7 ); // Vorderrad aufsteigen lassen
if(fahrtgeschwindigkeit < 1.0) llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <5.0, 0, 0>); // Vortrieb falls zu langsam für Aufsteigen
}
}
// RECHTS lenken
if (tastenzustand & CONTROL_ROT_RIGHT)
{
if( gang > 1) // Einknicken in Kurvenmittelpunkt bei Vorwärtsfahrt
{
rechtslenk++;
if(fahrtgeschwindigkeit < 1.0) llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <3.0, 0, 0>); // Vortrieb falls zu langsam für Kurvenfahrt
if ((rechtslenk > 30) & (gang == 2) & (fahrtgeschwindigkeit > 4.5)) { if (!raddrift) hinterraddrift(TRUE);} // Hinterrad rotieren lassen
}
AngularMotor.y -= ( 1.15 ); // Nase hoch zur Kompensation des Eintauchens 0.75
AngularMotor.x += ( einknicken + fahrfaktor ); // Seitlich einknicken steigt mit Geschwindigkeit (3-6 gut)
if(gang >0) AngularMotor.z -= ( lenkradius - fahrfaktor ); // Lenkung wird mit steigender Geschwindigkeit wirkungsloser
else if(!gang) AngularMotor.z += 4; // Rueckwärts invers lenken
}
// Nicht mehr rechts lenken
else if (tastelosgelassen & CONTROL_ROT_RIGHT){ rechtslenk = 0; llMessageLinked(LINK_SET, 30, (string)0, NULL_KEY);}
// LINKS Lenken
if (tastenzustand & CONTROL_ROT_LEFT)
{
if( gang > 1) // Einknicken in Kurvenmittelpunkt bei Vorwärtsfahrt
{
linkslenk++;
if(fahrtgeschwindigkeit < 1.0) llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <3.0, 0, 0>); // Vortrieb falls zu langsam für Kurvenfahrt
if ((linkslenk > 30) & (gang == 2) & (fahrtgeschwindigkeit > 4.5)) { if (!raddrift) hinterraddrift(TRUE);} // Hinterrad rotieren lassen
}
AngularMotor.y -= ( 1.15 ); // Nase hoch zur Kompensation des Eintauchens
AngularMotor.x -= ( einknicken + fahrfaktor ); // Seitlich einknicken steigt mit Geschwindigkeit (3-6 gut)
if(gang >0) AngularMotor.z += ( lenkradius - fahrfaktor ); // Lenkung wird mit steigender Geschwindigkeit wirkungsloser
else if(!gang) AngularMotor.z -= 4; // Rueckwärts invers lenken
}
// Nicht mehr links lenken
else if (tastelosgelassen & CONTROL_ROT_LEFT){ linkslenk = 0;}
llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, AngularMotor); // ROTATIONS MOTOR mit Kraft versorgen
if ((!rechtslenk) & (!linkslenk) & raddrift) {hinterraddrift(FALSE);} // rauchende Reifen abschalten
}
timer()
{
vel = llGetVel();
fahrtgeschwindigkeit = llVecMag(vel); // beide Richtugnen haben positive Geschwindigkeit!
float verbrauch = fahrtgeschwindigkeit / 20; // Hilfsvariable zur Rechenreduktion
if(racemode)
{
benzintank -= verbrauch; // Spritverbrauch
benzin = tankanzeige(1);
}
if((gang != 1) & (fahrtgeschwindigkeit < 0.1)) { gangschaltung("Leerlauf"); fahrtgeschwindigkeit = 0.0;} // bei Stand in Leerlauf schalten
llMessageLinked(LINK_SET, 20, (string)fahrtgeschwindigkeit, NULL_KEY);
}
listen(integer channel, string name, key id, string message)
{
string sender = llGetSubString( message, 0, 35 );
if(biker == sender)
{
float tankmenge = ((vollertank - benzintank)/50);
string befehl = llGetSubString( message, 36, llStringLength( message ));
if(befehl == "Tanken")
{
if(gang ==1)
{
llWhisper(0, (string)tankmenge + "Liter Super getankt, das macht dann €:" + (string)(tankmenge *1.57));
benzintank = vollertank;
if(racemode) benzin = tankanzeige(1);
}
else {llWhisper(0, "Bitte zum Tanken den Motor abstellen");}
}
}
}
}
Vorderrad und Hinterrad Script
In Vorder und Hinterrad kommt jeweils folgendes Radscript. Das Radscript dreht das verlinkte Radmesh direkt. Dazu muss die Achse des Rads passen.
Alternativ kann man hier auch die Achse im Script einstellen. lltargetOmega <x,y,z>
Code:
// Radscript Variante by Tron
integer richtung = 0;
float speed;
default
{
state_entry()
{
llTargetOmega(<0,1,0>,PI,0.0);
}
link_message(integer sender_num,integer kanal,string message,key id)
{
if (kanal == 10) { richtung = (integer)(message);}
else if (kanal == 20) { speed = (float)message * 0.20 *PI;}
if ((richtung > 0) & (speed > 0.1)) llTargetOmega(<0,3,0>,speed,0.5);
else if ((richtung < 0) & (speed > 0.1)) llTargetOmega(<0,-3,0>,speed,0.5);
else { speed = 0; llTargetOmega(<0,0,0>,PI,0.0);}
}
}
Tankstellen Script:
Das Tankstellenscript dient dem Betanken von mir gescripteter Fahrzeuge.
Das Script kommt in einen transparenten Primwürfel, der Phantom gemacht wird. Dieser soll die Zapfsäule großzügig ummanteln damit ein Klick auf die Zapfsäule das Prim trifft.
Getankt wird indem man auf dem Fahrzeug in Nähe der Zapfsäule sitzt, den LEERLAUF eingelegt hat, und die Zapfsäule anklickt.
Dann muss man warten bis der Tankvorgang abgeschlossen ist. Nun erhält man eine Meldung wieviel getankt wurde.
Die Zapfsäule ist auch für alle anderen modernen Fahrzeuge meiner Entwicklung zu nutzen. Aktuell sind das Autos. Boote werden folgen.
Die Tankstelle funktioniert aktuell nur interaktiv mit meinen Fahrzeugen.
Wenn jemand seine Fahrzeugscripte in das Tanksystem integrieren will, bitte hier posten für Hilfe, oder aus dem Bike Script herauslesen
Code:
P319 Tankstelle Zapfsäulenscript by Tron V1.0
string ident = "Tanken";
integer channel = -1000; // Fernbedienungs Kanal zur Kommunikation für Fahrzeuge
key user; // ID desjenigen der die Zapfsäule berührt- wird ans Fahrzeug gesendet
integer listenhandle; // für Tanken
default
{
touch_end(integer num_detected)
{
user = llDetectedKey(0);
llSay (0, "Tankvorgang gestartet... bitte warten");
listenhandle = llListen((channel+1),"","","");
llSleep(20.0);
llWhisper(channel,(string) user +ident); // ID desjenigen der die Zapfsäule berührt- wird ans Fahrzeug gesendet
}
listen(integer channel, string name, key id, string message)
{
string sender = llGetSubString( message, 0, 35 );
if(user == sender)
{
string befehl = llGetSubString( message, 36, llStringLength( message ));
{
llSay(0, befehl);
llListenRemove(listenhandle);
}
}
}
}
So, nun wünsche ich viel Spaß, und freue mich auf Rückmeldungen
Tron