Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // --------------------------------------------------------
- // SAILING SCRIPT VERSION 1-39 BBK EDITION (modified for Opensim)
- // --------------------------------------------------------
- // BWind Sailing Engine Release 1-39-1
- // (sort of) by Becca Moulliez - RELEASE June 2010 - GNU/GPL
- // with many changes along the way, it seems
- // SAIL + APPARENT WIND
- // refer to boat name for release :
- // BOAT RELEASE-WIND ENGINE VERSION-LATEST UPDATE VERSION
- // i.e : 1-1-1
- // script based upon Kanker Greenacre's Flying Tako
- //------------------------------------------------------
- // Please do not remove this header
- // Permitted Free Uses
- // - allowed to use in your personal boats.
- // - allowed to use in boats you wish to sell or give away in second life.
- // - allowed to modify any part to your particular needs
- // Not Allowed Uses
- // - not allowed to re-package and give away, or sell this script.
- // - not allowed to change a few lines of code then call this your own work
- // - not allowed to take this to another platform or any use other than Second Life sailing without the express
- // permission from Becca Moulliez
- // ======= End Header =========
- //
- // All that being said above, how can we be GNU and restricted to SL at the same time? I don't think that works.
- // So since this is a substantial modification, the GNU fits. GPL for the win.
- //
- // Version 1-38-OS (Opensim) adds the following:
- //
- // 1) Spinnaker (was added somewhere in the journey to Opensim, I didn't do it, honest, I think it was Lotek's change)
- // 2) Spinnaker Pole (with the spinnaker)
- // 3) Fenders, hatch, tackle - for boats equipped with fenders or hatches or tackle that you want to either disappear or
- // appear depending on if you are sailing or not, there's support for this, name the fender prim "fender" and optionally the
- // face on the mesh prim. Likewise for hatch, also if the boom tackle is out, you can make that disappear too.
- //
- // 4) Ocean Engineering/WeatherOS wind setter to BWind (new commands setter/setoff) this takes real life wind
- // via the setter buoys, or any Ocean Engineering setter buoy for that matter, giving you "race mode" but maybe even
- // a little better even when not racing.
- //
- // 5) Windvane follows wind setting (stop using that stupid sim wind) - yes, a new windvane added. There is also a windvane script
- // you need to install in the windvane. The windvane will point into the direction bwind is set to, and will stay pointed at that direction.
- //
- // 6) tweaks for ubODE - mostly around the X-axis which seems determined to nose into the water on turns.
- // 7) disable motor when sails are up. That seemed like a bug.
- //
- // You can adapt this to any boat, if you wish. It would be nicer with mesh
- // sails, but the centres of the prims have to be on the edge to work right, you were warned. See the documentation.
- //
- // Version 1-39-OS (Opensim) adds the following new functions:
- //
- // 1) Implement course hold command. Type "hold" and the boat will follow the
- // current course/heading (in other words, the boat will stay pointed
- // in the direction you are heading, but that will also hold your course).
- // If you touch the wheel (left or right keys) it will disengage. So there is no "unhold" command for that reason.
- // 2) Some support for linked gauges is introduced here too. Specifically AWA is
- // now directly supported as well as a tachometer, the tach is rudimentary because
- // the engine is rudimentary.
- // 3) A number of bugs are fixed here. The most noticeable was the spinnaker appearing on sit, the startup and setup is complicated for
- // less than good reasons. quite a few other bugs in the hud, and other places.
- // 4) not directly part of this script, but spinnaker will shrink when not in use to prevent collisions, and the wake uses 1/2 the particles
- // and 2/3 the life to save on frame rate.
- // 5) Turn the tacking animation support on or off with a single flag. This saves commenting out code or remembering to.
- //
- // ----------------------------------------- START PROGRAMME ---
- ///////////////////////////////////////////////////////////////////////
- // GLOBAL BOAT SETTINGS /////////////////////////////////////////////
- // you don't want to modify these settings unless specifically noted //////
- /////////////////////////////////////////////////////////////////////
- //version settings
- string boatName="Sailboat 50D"; // Rename this according to your needs...
- string versionNumber="1-39-OS"; // Release reference
- //script module flags
- integer CONTROLS_MODULE=1;
- integer SAIL_MODULE=2;
- //environment
- vector wind;
- float windAngle;
- float absWindAngle;
- float seaLevel;
- //reused math variables
- vector eulerRot;
- vector currEuler;
- rotation quatRot;
- rotation currRot;
- //boat variables
- float zRotAngle;
- vector fwdVec;
- vector upVec;
- vector leftVec;
- float compass;
- //heeling variables
- float heelAngle;
- float heelTorque;
- float heelAdd;
- //linear motion variables
- float currSpeed;
- vector groundSpeed=ZERO_VECTOR;
- float spdFactor=0.0;
- float leeway;
- //angular motion variables
- float rotSpeed;
- float rotDelta;
- vector eulerTurnLeft;
- vector eulerTurnRight;
- rotation quatTurnLeft=ZERO_ROTATION;
- rotation quatTurnRight=ZERO_ROTATION;
- //sail variables
- integer sailingAngle;
- integer currBoomAngle=0;
- integer delta;
- integer incr;
- float optBoomAngle;
- float trimFactor;
- //spinnaker variables
- integer spinAngle;
- integer spindelta;
- integer currSpinAngle=0;
- integer SPIN_UP=FALSE;
- integer CurJib;
- integer CurSpin;
- string Tack;
- //performance constants - Standard defaults
- float timerFreq=1.0; //timer frequency, seconds (original paramer 1.5; check this if gets laggy)
- integer sheetAngle=5; //initial sheet angle setting
- float maxWindSpeed=14.0; //used for heeling calculation (better leave this unchanged)
- //miscellaneous settings
- key owner; //boat owner
- key avatar; //avatar sitting at the helm
- integer lock=FALSE;
- integer ownerVersion=FALSE;
- integer SAIL_UP=FALSE;
- integer permSet=FALSE;
- integer HUD_ON=TRUE;
- string idStr;
- integer numTouches=0;
- integer sailing=TRUE;
- float mpsToKts=1.944; //Metres per Second to Knots conversion
- float convert=1.944;
- string units=" Kts.";
- integer showKnots=TRUE; //Yes we show speed in Knots...
- float time;
- float offset;
- float theta;
- integer msgTypeModeChange=40001;
- integer modeBWind=0;
- string helpString;
- string visualAid;
- vector hudcolour=<1,1,1>;
- string currentString;
- integer ADV_HUD=TRUE; //Advanced HUD off by default; set to TRUE to set on...
- integer useSetter=FALSE; // flag to use wind setter buoys
- integer courseHold=FALSE; // flag to indicate course hold is set
- float courseHoldValue; // the course to hold
- integer Tacking=FALSE; // does this boat use the tacking animations? Set to TRUE if so.
- //linked parts - childprims declarations; the rootscript will send commands to childs when running...
- //to work properly relevant prims MUST be renamed following the scheme below
- integer JIB;
- integer SAIL;
- integer BOOM;
- integer HUD;
- integer CREWMAN; //this refers to the Crew Poseball in the cockpit...
- integer POLE; //NEW for Spinnaker
- integer SPINNAKER; //NEW for Spinnaker
- integer FENDERS; //if boat is equipped with fenders
- integer WINDVANE; //support windvane direction
- integer HATCHUPPER;
- integer HATCHLOWER; // for closing and opening the hatch
- integer L33; // boom tackle
- integer AWI1; // apparent wind gauge
- integer TACH; // tachometer
- //general sailing parameters
- float ironsAngle=31; //this is as close as the boat can sail to the wind
- float slowingFactor=0.7; //speed drops by this factor every timerFreq seconds if sailing into the wind
- float leewayTweak=1.50; //scales leeway (0=no leeway)
- float rotTweak=0.8; //scales boat turning rate
- float speedTweak=1.0; //DON'T touch this !!!!!!!!
- //Apparent Wind parameters
- vector tmpwind;
- float truewindDir;
- float truewindSpeed;
- float truewindAngle;
- float appwindSpeed;
- float appwindAngle;
- // Buoy listener/setter globals
- //
- integer windh=-1; //handle for listening to scripted wind
- vector windvec=<0,1,0>; //default to north
- // ------------------------- END GLOBAL BOAT SETTINGS ---
- ///////////////////////////////////////////////////////
- // BWIND DEFAULT PRESET DECLARATION //////////////////
- // modify this section as per 15 Knots Wind Preset //
- ////////////////////////////////////////////////////
- //The boat will sail a 15 Knots East BWind by default... following parameters apply
- float windDir=0; //BWind Wind direction
- string windRose="East "; //BWind Preset declaration for 15 Knots Wind
- string windType="15 Knots"; //BWind Preset declaration for 15 Knots Wind
- //primary parameters
- float windSpeed=7.75; // Don't touch this... 15 Knots Speed
- float maxSpeed=5.5; // Edit this according to your needs... this is the actual Speed with a 15 Knots Wind
- float heelTweak=0.85; // Edit this according to your needs... this is the actual Heel for a 15 Knots Wind
- //Note : you MUST check the 15 Knots BWind Preset below in the Script (line 829); The values set here MUST be the same...
- // --------------------------- END DEFAULT PRESET DECLARATION ---
- ///////////////////////////////////////////////////
- // GLOBAL BOAT EQUATIONS AND FUNCTIONS ///////
- // you don't want to modify these settings //////
- ////////////////////////////////////////////////
- //Following Equations and Functions will affect GLOBAL Boat's behavior -- I strongly recommend you will NOT edit unless you know what you are doing...
- // BWind Basic Boat Behaviour - LSL Angle Calculation
- integer realAngle2LslAngle(integer realAngle) {
- integer lslAngle= (realAngle-90)*-1;
- while(lslAngle>=360) lslAngle-=360;
- while(lslAngle<0) lslAngle+=360;
- return lslAngle;
- }
- // BWind Basic Boat Behaviour - calculate wind angle
- //TRUE WIND - True Wind has been left as a separate routine in case you dont want your boat to support Apparent Wind
- calcTrueWindAngle() {
- currRot=llGetRot();
- currEuler=llRot2Euler(currRot);
- zRotAngle=currEuler.z;//boat heading
- leftVec=llRot2Left(currRot);
- truewindAngle=windDir-zRotAngle;
- while (truewindAngle>PI) truewindAngle-=TWO_PI; //bw -PI and PI
- while (truewindAngle<-PI) truewindAngle+=TWO_PI; //bw -PI and PI
- if ((truewindAngle) < 0) {
- truewindAngle = truewindAngle * -1;
- }
- }
- //APPARENT WIND
- calcAppWindAngle() {
- currRot=llGetRot();
- currEuler=llRot2Euler(currRot);
- zRotAngle=currEuler.z; //boat heading
- leftVec=llRot2Left(currRot);
- windAngle=windDir-zRotAngle;
- while (windAngle>PI) windAngle-=TWO_PI; //bw -PI and PI
- while (windAngle<-PI) windAngle+=TWO_PI; //bw -PI and PI
- vector boatMovement=<currSpeed*llCos(currEuler.z),currSpeed*llSin(currEuler.z),0>;
- tmpwind=wind+boatMovement;
- float spd=llVecMag(llGetVel());
- appwindAngle=llAtan2(windSpeed*llSin(windAngle),(windSpeed*llCos(windAngle)+spd));
- while (appwindAngle>PI) spd=-spd;
- while (appwindAngle<-PI) spd=-spd;
- appwindSpeed=spd*llCos(llFabs(windAngle))-windSpeed*llCos(windAngle);
- if ((appwindSpeed) < 0) {
- appwindSpeed = appwindSpeed * -1;
- }
- if ((appwindSpeed) > 3) {
- appwindSpeed = appwindSpeed -(TWO_PI-1.0);
- }
- // in order for the AWA gauge to work properly it needs to know negative
- // deflection, therefore we don't want to use absolute value (all of this could
- // be simplified with llFabs() but whatever...
- // if ((appwindAngle) < 0) {
- // appwindAngle = appwindAngle * -1;
- // }
- }
- // BWind Basic Boat Behaviour - calculate heel angle based on wind and sail settings
- calcHeelAngle() {
- heelAngle=llAsin(leftVec.z);
- if (SAIL_UP) {
- if (llFabs(windAngle+sailingAngle)>3*DEG_TO_RAD) {
- heelTorque=SAIL_UP*llSin(windAngle)*llCos(heelAngle)*PI_BY_TWO*(windSpeed/maxWindSpeed)*llCos(sailingAngle*DEG_TO_RAD)*heelTweak;
- } else heelTorque=0;
- } else heelTorque=0;
- heelAdd=heelTorque-heelAngle;
- eulerRot=<heelAdd,0,0>;
- quatRot=llEuler2Rot(eulerRot);
- }
- // BWind Basic Boat Behaviour - calculate angle of sail (or jib) based on sheet setting and the wind
- calcBoomDelta() {
- if (sheetAngle<=0) sheetAngle=5; //never let the actual sheetangle be less than 5°
- if (sheetAngle>=79) sheetAngle=79; //never let the actual sheetangle be more than 79°
- sailingAngle=sheetAngle;
- if (sailingAngle>llFabs(windAngle*RAD_TO_DEG)) sailingAngle=llRound(llFabs(windAngle*RAD_TO_DEG));
- if (windAngle<0) sailingAngle*=-1;
- delta=sailingAngle-currBoomAngle;
- currBoomAngle=sailingAngle;
- if (currBoomAngle < 0) Tack="Starb'd";
- if (currBoomAngle > 0) Tack="Port";
- currBoomAngle=sailingAngle;
- llMessageLinked(SAIL,delta,"",NULL_KEY);//tell sail to rotate by delta
- llMessageLinked(JIB,delta,"",NULL_KEY);//tell jib to rotate by delta
- llMessageLinked(BOOM,delta,"",NULL_KEY);//tell boom to rotate by delta
- }
- // BWind Basic Boat Behaviour - calculate boat speed
- calcSpeed() {
- groundSpeed=llGetVel();
- absWindAngle=llFabs(windAngle);
- if (llFabs(absWindAngle*RAD_TO_DEG-llFabs(sailingAngle))<10) trimFactor=0;
- else {
- optBoomAngle=0.5*absWindAngle*RAD_TO_DEG;
- trimFactor=(90.-llFabs(optBoomAngle-llFabs(sailingAngle)))/90.;
- }
- //(old)if (absWindAngle<ironsAngle*DEG_TO_RAD) currSpeed*=slowingFactor;
- if (llFabs(appwindAngle)<ironsAngle*DEG_TO_RAD) currSpeed*=slowingFactor;
- else {
- if (SAIL_UP) {
- //currSpeed=speedTweak*(llCos(windAngle/2.)+0.5)*windSpeed*trimFactor;
- //if (currSpeed>maxSpeed) currSpeed=maxSpeed;
- currSpeed=speedTweak*(llSin(llFabs(windAngle)/2)+llCos(llFabs(windAngle)/2.75) - 0.75)*windSpeed*trimFactor; // mod donated by Eta Carver
- }
- else currSpeed*=0.8;
- }
- }
- // BWind Basic Boat Behaviour - calculate leeway (lateral drift) due to wind
- calcLeeway() {
- leeway=SAIL_UP*-llSin(llFabs(appwindAngle))*llSin(heelAngle)*windSpeed*leewayTweak;
- //BUG found by Balduin Aabye - ty :))
- }
- // BWind Basic Boat Behaviour - calculate turning rate based on current speed
- calcTurnRate() {
- spdFactor=llVecMag(groundSpeed)/(maxSpeed);
- rotSpeed=0.5+(spdFactor)/2.0;
- }
- // String Conversions - automatically detect link nums for each named part - based upon original Tako parts names
- getLinkNums() {
- integer i;
- integer linkcount=llGetNumberOfPrims();
- for (i=1;i<=linkcount;++i) {
- string str=llGetLinkName(i);
- if (str=="jib") JIB=i;
- if (str=="sail") SAIL=i;
- if (str=="boom") BOOM=i;
- if (str=="pole") POLE=i;
- if (str=="spinnaker") SPINNAKER=i;
- if (str=="hud") HUD=i;
- if (str=="crewman") CREWMAN=i;
- if (str=="fenders") FENDERS=i;
- if (str=="windvane") WINDVANE=i;
- if (str=="hatchupper") HATCHUPPER=i;
- if (str=="hatchlower") HATCHLOWER=i;
- if (str=="l33") L33 = i;
- if (str=="awi1") AWI1 = i;
- if (str=="tach") TACH = i;
- }
- }
- fenders(float visible)
- {
- float openshut; // hatch does the opposite
- if (visible > 0)
- {
- openshut = 0.0;
- }
- else
- {
- openshut = 1.0;
- }
- llSetLinkAlpha(FENDERS,visible,ALL_SIDES);
- llSetLinkAlpha(L33,visible,ALL_SIDES);
- llSetLinkAlpha(HATCHUPPER,openshut,ALL_SIDES);
- // llSetLinkPrimitiveParamsFast(HATCHUPPER,[PRIM_PHANTOM,(integer)visible]);
- llSetLinkAlpha(HATCHLOWER,openshut,ALL_SIDES);
- // llSetLinkPrimitiveParamsFast(HATCHLOWER,[PRIM_PHANTOM,(integer)visible]);
- }
- setAWI(float appAngle)
- {
- llMessageLinked(AWI1,22,(string)appAngle,"");
- }
- setTach(float rpm)
- {
- llMessageLinked(TACH,-123202,(string)rpm,"");
- }
- setWindvane(float wDir)
- {
- // given a direction, send it to the windvane, it'll point in that general direction and jiggle around a few degrees
- llMessageLinked(WINDVANE,0,(string)wDir,"");
- }
- // use the WeatherOS/OE buoy
- setWindFromBuoy()
- {
- windh = llListen(-54001,"","","");
- }
- // RAISE ROUTINE - raise sail: start timer
- raiseSail() {
- SAIL_UP=TRUE;
- llOwnerSay("Ready to sail... ");
- llMessageLinked(SAIL,1002,"",NULL_KEY); // raise sail
- llMessageLinked(JIB,1002,"",NULL_KEY); // raise jib
- llMessageLinked(SPINNAKER,1001,"",NULL_KEY); // don't raise spinnaker
- llMessageLinked(BOOM,1002,"",NULL_KEY); // move boom
- llMessageLinked(CREWMAN,1000,"",NULL_KEY); // hide crewman poseball
- fenders(0.0); // hide fenders, shut hatches
- llSetTimerEvent(timerFreq);
- llLoopSound("sailing", 1.0);
- }
- // LOWER ROUTINE - lower sail but leave physics on
- lowerSail() {
- llOwnerSay("Lowering sails... ");
- llMessageLinked(SAIL,1000,"",NULL_KEY);//lower sail w/ reset
- llMessageLinked(JIB,1000,"",NULL_KEY);//lower jib w/ reset
- llMessageLinked(BOOM,1000,"",NULL_KEY);//stop boom w/ reset
- llMessageLinked(POLE,1000,"",NULL_KEY);//stop pole w/ reset
- llMessageLinked(SPINNAKER,1000,"",NULL_KEY); // drop and reset spinnaker
- fenders(1.0); // put the fenders out, open the hatches
- sailingAngle = 0;
- llStopSound();
- llMessageLinked(LINK_ALL_CHILDREN , 0, "stop", NULL_KEY); // stop all children-linked activities
- currBoomAngle=0;
- sheetAngle=5;
- SAIL_UP=FALSE;
- llSetObjectDesc (""); //This sets your boat's description string when lowering... useful when you add a WWC Wind routine
- }
- //SPINNAKER ROUTINE
- HoistSpin(){
- if ((sheetAngle > 50)) {
- llOwnerSay("Hoisting Spinnaker");
- llMessageLinked(SPINNAKER,1002,"",NULL_KEY); //hoist spinnaker
- if (-sailingAngle > 0) llMessageLinked(POLE,1002,"",NULL_KEY);
- if (-sailingAngle < 0) llMessageLinked(POLE,1004,"",NULL_KEY);
- llMessageLinked(JIB,1001,"",NULL_KEY); //lower jib
- SPIN_UP=TRUE;
- CurJib=0;
- }
- if ((sheetAngle < 50)) {
- llOwnerSay("Sheet too close to Hoist Spin");
- }
- }
- DropSpin(){
- llOwnerSay("Dropping Spinnaker");
- llMessageLinked(SPINNAKER,1000,"",NULL_KEY); //drop spinnaker/W reset
- llMessageLinked(POLE,1000,"",NULL_KEY); // hide & reset pole
- llMessageLinked(JIB,1002,"",NULL_KEY); //raise jib
- CurSpin=0;
- CurJib=0;
- currSpinAngle=0;
- spinAngle=0;
- SPIN_UP=FALSE;
- }
- TrimSpinPlus() {
- if (CurSpin < 37) {
- llMessageLinked(SPINNAKER,(delta+3),"",NULL_KEY); //trim spinnaker +
- llMessageLinked(POLE,(delta+3),"",NULL_KEY); // hide pole
- CurSpin=CurSpin+3;
- }
- }
- TrimSpinMinus() {
- if (CurSpin > -37) {
- llMessageLinked(SPINNAKER,(delta-3),"",NULL_KEY); //trim spinnaker -
- llMessageLinked(POLE,(delta-3),"",NULL_KEY); // hide pole
- CurSpin=CurSpin-3;
- }
- }
- // VEHICLE PHYSICS PARAMETERS - set initial vehicle parameters
- // WARNING !!!! - Following physics parameters should NOT be edited unless you REALLY KNOW what you are doing....
- setVehicleParams() {
- //vehicle flags
- llSetLinkPrimitiveParamsFast(LINK_ALL_CHILDREN, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]);
- llSetVehicleType (VEHICLE_TYPE_BOAT);
- llSetVehicleRotationParam(VEHICLE_REFERENCE_FRAME,ZERO_ROTATION); // ZERO_ROTATION = <0.0,0.0,0.0,1.0> you may wish to edit this for fun
- llSetVehicleFlags (VEHICLE_FLAG_NO_DEFLECTION_UP|VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT|VEHICLE_FLAG_LIMIT_MOTOR_UP );
- //linear motion
- llSetVehicleVectorParam (VEHICLE_LINEAR_FRICTION_TIMESCALE,<20.0,2.0,0.5>);;
- llSetVehicleVectorParam (VEHICLE_LINEAR_MOTOR_DIRECTION,ZERO_VECTOR);
- llSetVehicleFloatParam (VEHICLE_LINEAR_MOTOR_TIMESCALE,5.0);
- llSetVehicleFloatParam (VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE,10);
- llSetVehicleFloatParam (VEHICLE_LINEAR_DEFLECTION_EFFICIENCY,0.85);
- llSetVehicleFloatParam (VEHICLE_LINEAR_DEFLECTION_TIMESCALE,1.0);
- //angular motion
- llSetVehicleVectorParam (VEHICLE_ANGULAR_FRICTION_TIMESCALE,<5,0.1,0.1>);
- llSetVehicleVectorParam (VEHICLE_ANGULAR_MOTOR_DIRECTION,ZERO_VECTOR);
- llSetVehicleFloatParam (VEHICLE_ANGULAR_MOTOR_TIMESCALE,0.1);
- llSetVehicleFloatParam (VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE,3);
- llSetVehicleFloatParam (VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY,1.0);
- llSetVehicleFloatParam (VEHICLE_ANGULAR_DEFLECTION_TIMESCALE,1.0);//default 1.0 -- reduce to have more lateral drift (like 0.3 - 0.5)
- //vertical attractor
- llSetVehicleFloatParam (VEHICLE_VERTICAL_ATTRACTION_TIMESCALE,3.0);
- llSetVehicleFloatParam (VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY,0.8);
- //banking
- llSetVehicleFloatParam (VEHICLE_BANKING_EFFICIENCY,0.0);
- llSetVehicleFloatParam (VEHICLE_BANKING_MIX,1.0);
- llSetVehicleFloatParam (VEHICLE_BANKING_TIMESCALE,1.2);
- //vertical control
- llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel);
- llSetVehicleFloatParam (VEHICLE_HOVER_EFFICIENCY,2.0);
- llSetVehicleFloatParam (VEHICLE_HOVER_TIMESCALE,1.0);
- llSetVehicleFloatParam (VEHICLE_BUOYANCY,1.0);
- }
- //MASTMAN AND CREW CAMERA SETUP - set camera position for third person view
- setCamera() {
- llSetCameraEyeOffset(<-11.5,0.0,4.7>); //Here you may set your Sailing Camera EYE Offset
- llSetCameraAtOffset(<3.0,0.0,1.0>); //Here you may set your Sailing Camera actual position
- }
- //REZZING INITIAL POSITION - figure out where to put boat when it is rezzed
- // The boat will float at a 20.100 level... Edit and raise/lower the rootprim to set your waterline... DON'T mod THIS !
- setInitialPosition() {
- vector pos=llGetPos();
- float groundHeight=llGround(ZERO_VECTOR);
- float waterHeight = llWater(ZERO_VECTOR);
- seaLevel=llWater(ZERO_VECTOR);
- upright();
- //if over water, set boat height to sealevel + 0.1m; this is the standard default water level
- if (groundHeight <= waterHeight) {
- pos.z = waterHeight + 0.1; //fixed by Balduin Aabye (originally 0.12)
- while (llVecDist(llGetPos(),pos)>.001) llSetPos(pos);
- }
- }
- //SIT TARGET - REFER TO pose_s SCRIPT FOR MASTMAN AND CREW SET - set sit target for helmsperson
- //this function is now being disabled - there is an external pose script to set this...
- setSitTarget() {
- llSetSitText("Sail !");
- llSetText("",ZERO_VECTOR,1.0);
- }
- //BOAT UPRIGHT POSITION - force boat upright
- upright() {
- currRot=llGetRot();
- currEuler=llRot2Euler(currRot);
- leftVec=llRot2Left(currRot);
- heelAngle=llAsin(leftVec.z);
- eulerRot=<-heelAngle,0,0>;
- quatRot=llEuler2Rot(eulerRot);
- llRotLookAt(quatRot*currRot,0.2,0.2);
- }
- //MOORING FUNCTION - what happens when your boat moors...
- moor() {
- llMessageLinked(LINK_THIS,SAIL_MODULE,"moor",NULL_KEY);
- {
- llSetTimerEvent(timerFreq);
- sailing=TRUE;
- }
- llOwnerSay("Mooring.");
- upright();
- llReleaseControls();
- llSetStatus(STATUS_PHYSICS,TRUE);
- llSetTimerEvent(0);
- currSpeed=0;
- }
- //GENERAL BOAT STARTUP - reset stuff - this resets the script to defaults... you may call this function as needed...
- startup() {
- owner=llGetOwner();
- llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Z | STATUS_ROTATE_Y,TRUE);
- llSetStatus(STATUS_PHYSICS,FALSE);
- llSetStatus(STATUS_PHANTOM,FALSE);
- llSetStatus(STATUS_BLOCK_GRAB,TRUE);
- llSetTimerEvent(0);
- setInitialPosition();
- setVehicleParams();
- setSitTarget();
- getLinkNums();
- llMessageLinked(SAIL,1000,"",NULL_KEY); //reset MAINSAIL
- llMessageLinked(JIB,1000,"",NULL_KEY); //reset JIB
- llMessageLinked(BOOM,1000,"",NULL_KEY); //reset BOOM
- llMessageLinked(CREWMAN,1001,"",NULL_KEY); // show crewman poseball
- llMessageLinked(POLE,1000,"",NULL_KEY); // hide & reset pole
- llMessageLinked(SPINNAKER,1001,"",NULL_KEY); //reset SPINNAKER
- setCamera(); //apply Camera default setting
- currSpeed=0;
- llListen(0,"",owner,""); //listen to boat owner only...
- llOwnerSay("Ready.");
- llMessageLinked(LINK_ALL_CHILDREN , 0, "stop", NULL_KEY);
- }
- updateCourse()
- {
- float compass=zRotAngle*RAD_TO_DEG;
- compass = (450.0 - compass)%360.0;
- //llOwnerSay("Compass "+(string)compass);
- //llOwnerSay("Hold at "+(string)courseHoldValue);
- //llOwnerSay("rotSpeed "+(string)rotSpeed);
- float compDiff = compass - courseHoldValue;
- if (llFabs(compDiff) > 350.00)
- {
- compass = compass + 360.00;
- }
- if (compass > (courseHoldValue+1))
- {
- // need to turn left
- //llOwnerSay("left turn");
- //llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,1.0>);
- llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,rotSpeed/35.0>);
- }
- else
- {
- if (compass < (courseHoldValue-1))
- {
- //llOwnerSay("right turn");
- // need to turn right
- //llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,-1.0>);
- llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,-rotSpeed/35.0>);
- }
- }
- //llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,0.0>);
- }
- // ------------------------------------- END GLOBAL BOAT EQUATIONS AND FUNCTIONS---
- ///////////////////////////////////////////////////
- // HUD SETTINGS //////////////////////////////////
- // you don't want to modify these settings //////
- ////////////////////////////////////////////////
- // UPDATE HUD - Main HUD routine and colour management
- updateHUD() {
- string dataString;
- float compass=PI_BY_TWO-zRotAngle;
- float effcoeff;
- string rgn = llGetRegionName();
- string blank = " ";
- float efficiency;
- string ratio;
- float derivatesheetAngle=sheetAngle;
- //CALCULATE SPINNAKER EFFECTS ON EFFICIENCY
- //Spinnaker tweak weighs 1/3 of global sheet
- if (Tack=="Starb'd") {
- derivatesheetAngle+=(CurSpin/3); //Starboards Spinnaker Tweak
- }
- if (Tack=="Port") {
- derivatesheetAngle-=(CurSpin/3); //Port Spinnaker Tweak
- }
- //ACTUAL EFFICIENCY CALCULATION including spinnaker tweaks
- efficiency = llFabs(appwindAngle)*RAD_TO_DEG/derivatesheetAngle;
- if ((efficiency) < 0) {
- efficiency = efficiency * -1;
- }
- compass=PI_BY_TWO-zRotAngle;
- while (compass<0) compass+=TWO_PI;
- dataString = " "; //clean hud message on startup
- currentString = " "; //clean hud storage on startup
- //HUD COMPASS CONVERSION
- float hudcompass =((integer)(compass*RAD_TO_DEG));
- string huddirection;
- if ((hudcompass) <= 360) {
- huddirection="North";
- }
- if ((hudcompass) <= 315) {
- huddirection="Northwest";
- }
- if ((hudcompass) <= 275) {
- huddirection="West";
- }
- if ((hudcompass) <= 230) {
- huddirection="Southwest";
- }
- if ((hudcompass) <= 185) {
- huddirection="South";
- }
- if ((hudcompass) <= 140) {
- huddirection="SouthEast";
- }
- if ((hudcompass) <= 95) {
- huddirection="East";
- }
- if ((hudcompass) <= 50) {
- huddirection="Northeast";
- }
- if ((hudcompass) <= 5) {
- huddirection="North";
- }
- // STANDARD HUD STRING CONSTRUCTION ROUTINE
- if (ADV_HUD==FALSE) {
- // efficiency positive convert and ratio calculation
- if ((efficiency) < 0) {
- efficiency = efficiency * -1;
- }
- ratio = llGetSubString ((string)efficiency, 0, 3);
- hudcolour=<1,1,1>; //default hudcolour
- dataString+="-> "+huddirection+" "; //add a direction string
- dataString+="( " +(string)((integer)(compass*RAD_TO_DEG))+"° )\n "; //add compass degrees
- dataString+="| "+visualAid+" | Speed "+llGetSubString((string)(llVecMag(groundSpeed*convert)),0,3)+units+"\n"; //add boat speed
- dataString+=(windType)+" "+(windRose)+"BWind\n"; //add BWind wind preset
- //trailing blanks
- dataString+=blank+"\n";
- dataString+=blank+"\n";
- }
- // ADVANCED HUD STRING CONSTRUCTION ROUTINE
- if (ADV_HUD==TRUE) {
- // efficiency positive convert
- if ((efficiency) < 0) {
- efficiency = efficiency * -1;
- }
- hudcolour=<1,1,1>; //default hudcolour
- dataString+="-> "+huddirection+" "; //add a direction string
- dataString+="( " +(string)((integer)(compass*RAD_TO_DEG))+"° )\n "; //add compass degrees
- dataString+="| "+visualAid+" | Speed "+llGetSubString((string)(llVecMag(groundSpeed*convert)),0,3)+units+" - "; //add boat speed
- dataString+=(windType)+" "+(windRose)+"BWind\n"; //add BWind wind preset
- dataString+="True Wind Angle " +(string)((integer)(truewindAngle*RAD_TO_DEG))+"° - "; //add True Wind
- dataString+="App. Wind Angle " +(string)((integer)(llFabs(appwindAngle)*RAD_TO_DEG))+"°\n"; //add Apparent Wind
- if (AWI1 > 0)
- {
- setAWI(appwindAngle*RAD_TO_DEG);
- }
- ratio = llGetSubString ((string)efficiency, 0, 3); //display efficiency conversion
- dataString+="Wind/Sheet ratio " +ratio+ " - Sheet Angle "+((string)(sheetAngle))+"°\n"; //add Efficiency and Sheet Angle
- //trailing blanks
- dataString+=blank+"\n";
- dataString+=blank+"\n";
- }
- //---------- END HUD CONSTRUCTION ROUTINE
- // HUD Colour Manager - This activates the HUD's virtual telltale function and affects ACTUAL BOAT'S SPEED WHILE TRIMMING
- // THIS ROUTINE IS VITAL FOR YOUR BOAT PERFORMANCE... THIS SETS THE BOAT'S SPEED WHEN YOU TRIM SAILS
- // too tight - cyan - this is good as it is...
- if ((efficiency) < 25.0) {
- hudcolour=<0,1,1>;
- // dataString=currentString; //update hud message on activation
- visualAid="<>"; //help symbol for colour visual impaired - immediate feel of TOO TIGHT
- speedTweak=0.3; //MODIFY THIS VALUE ACCORDING TO YOUR NEEDS... TWEAKS BOAT'S SPEED
- }
- // optimal - green - INCREASE THIS (never over 3) for easier apparent wind sailing
- // LOWER THIS (never below 2) for a more demanding trim activity
- if ((efficiency) < 2.5) {
- hudcolour=<0,1,0>;
- // dataString=currentString; //update hud message on activation
- visualAid="="; //help symbol for colour visual impaired - immediate feel of OPTIMAL
- speedTweak=1.0; //MODIFY THIS VALUE ACCORDING TO YOUR NEEDS... TWEAKS BOAT'S SPEED
- //SPINNAKER Boost/De-Boost
- if (SPIN_UP==TRUE) {
- if ((sheetAngle < 65)) {
- speedTweak+=0.3;
- }
- if ((sheetAngle > 65)) {
- speedTweak+=0.0;
- }
- if ((sheetAngle < 50)) {
- speedTweak-=1.0; //original 0.5
- if (speedTweak < 0) speedTweak = 0.00001;
- }
- }
- }
- // off optimal - yellow - here the sheet is too loose, but your boat will still sail quite well
- if ((efficiency) < 1.7) {
- hudcolour=<1,1,0>;
- // dataString=currentString; //update hud message on activation
- visualAid="><"; //help symbol for colour visual impaired - immediate feel of TOO LOOSE
- speedTweak=0.7; //MODIFY THIS VALUE ACCORDING TO YOUR NEEDS... TWEAKS BOAT'S SPEED
- }
- // too loose - red - oh yes this is very bad... the boat will almost stop sailing :)
- if ((efficiency) < 1.2) {
- hudcolour=<1,0,0>;
- // dataString=currentString; //update hud message on activation
- visualAid=">><<"; //help symbol for colour visual impaired - immediate feel of WAY TOO LOOSE
- speedTweak=0.3; //MODIFY THIS VALUE ACCORDING TO YOUR NEEDS... TWEAKS BOAT'S SPEED
- }
- //display hud string - HERE WE START HUD
- llSetText(dataString,(vector)hudcolour,1.0);
- currentString=dataString; //save current HUD message
- //Tacking animation management - HERE YOU CAN DECTIVATE THE TACKING ANIMATION - JUST COMMENT (//) THE FOLLOWING LINES
- // rather than doing that, it's configurable with a runtime flag now... set that up top in the startup.
- if (Tacking)
- {
- if (-sailingAngle > 0) {
- if ((llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) && llGetAgentSize(llGetPermissionsKey()) != ZERO_VECTOR) {
- llStopAnimation("bbk_helmsman");
- llStartAnimation ("bbk_helmstack");
- }
- }
- if (-sailingAngle < 0) {
- if ((llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) && llGetAgentSize(llGetPermissionsKey()) != ZERO_VECTOR) {
- llStopAnimation("bbk_helmstack");
- llStartAnimation ("bbk_helmsman");
- }
- }
- }
- }
- // ---------------------------- END HUD SETTINGS ---
- //////////////////////////////////////////////////////////////////////////////////////////////
- // SCRIPT TRAPPING ROUTINE - state default //////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////
- default {
- //get boat parts status
- state_entry() {
- getLinkNums();
- llSetText("",ZERO_VECTOR,1.0);
- startup();
- llSetStatus(STATUS_BLOCK_GRAB,TRUE);
- }
- //reset boat
- on_rez(integer param) {
- llResetScript();
- }
- //OWNER CHECK AND STATUS
- changed(integer change) {
- avatar=llAvatarOnSitTarget();
- if (change & CHANGED_LINK) {
- if (avatar==NULL_KEY) {
- if (!(llGetAgentInfo(owner) & AGENT_ON_OBJECT)) {
- if (SAIL_UP)
- {
- lowerSail();
- llMessageLinked(SPINNAKER,1000,"",NULL_KEY); //drop spinnaker/W reset
- }
- if (permSet) llReleaseControls();
- permSet=FALSE;
- llMessageLinked(LINK_SET, 70400, "", NULL_KEY);
- llResetScript();
- }
- }
- else {
- if (ownerVersion && avatar!=owner) llWhisper(0,"Only the owner can operate this boat.");
- else if ((llGetAgentInfo(owner) & AGENT_ON_OBJECT)) {
- llMessageLinked(SPINNAKER,1000,"",NULL_KEY); //drop spinnaker/W reset
- llWhisper(0,"Say raise to start sailing, help for sailing commands...");
- llWhisper(0,"BWind System defaults to East Wind, 15 Knots...");
- if (llAvatarOnSitTarget()==owner) llRequestPermissions(owner,PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION | PERMISSION_CONTROL_CAMERA);
- }
- }
- }
- }
- //BOAT CONTROLS SETUP
- run_time_permissions(integer perms) {
- if (perms & (PERMISSION_TAKE_CONTROLS)) {
- llClearCameraParams();
- llSetCameraParams([
- CAMERA_ACTIVE, 1, // 0=INACTIVE 1=ACTIVE
- CAMERA_BEHINDNESS_ANGLE, 15.0, // (0 to 180) DEGREES
- CAMERA_BEHINDNESS_LAG, 1.0, // (0 to 3) SECONDS
- CAMERA_DISTANCE, 6.0, // ( 0.5 to 10) METERS
- CAMERA_PITCH, 20.0, // (-45 to 80) DEGREES
- CAMERA_POSITION_LOCKED, FALSE, // (TRUE or FALSE)
- CAMERA_POSITION_LAG, 0.05, // (0 to 3) SECONDS
- CAMERA_POSITION_THRESHOLD, 30.0, // (0 to 4) METERS
- CAMERA_FOCUS_LOCKED, FALSE, // (TRUE or FALSE)
- CAMERA_FOCUS_LAG, 0.01 , // (0 to 3) SECONDS
- CAMERA_FOCUS_THRESHOLD, 0.01, // (0 to 4) METERS
- CAMERA_FOCUS_OFFSET, <0.0,0.0,0.0> // <-10,-10,-10> to <10,10,10> METERS
- ]);
- llTakeControls(CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT |
- CONTROL_ROT_LEFT | CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP,TRUE,FALSE);
- permSet=TRUE;
- if (permSet) llStartAnimation("bbk_helmsman");
- llMessageLinked(LINK_SET, 70400, "", avatar);
- llMessageLinked(SPINNAKER,1000,"",NULL_KEY); //drop spinnaker/W reset
- }
- }
- // ------------------------ END STATE DEFAULT DECLARATIONS ---
- ////////////////////////////////////////////////////////////////////
- // MAIN BOAT LISTENER /////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////
- // YOU BETTER NEVER EDIT THE FOLLWING LINES UNLESS YOU KNOW WHAT TO DO :)
- listen(integer channel, string name, key id, string msg)
- {
- if (channel==0)
- {
- if (owner==id & llAvatarOnSitTarget()==owner)
- {
- if (llGetAgentInfo(owner) & AGENT_ON_OBJECT)
- {
- if (llGetSubString(msg,0,4)=="sheet")
- {
- incr=(integer)llDeleteSubString(msg,0,4);
- sheetAngle+=incr;
- if (sheetAngle>90) sheetAngle=90;
- }
- //MESSAGE raise - hey we DO want to sail huh?
- else if (msg=="raise")
- {
- llMessageLinked(LINK_ALL_CHILDREN , 0, "start", NULL_KEY);
- sailing=TRUE;
- if (!permSet) llRequestPermissions(owner,PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
- permSet=TRUE;
- llSetStatus(STATUS_PHYSICS,TRUE);
- raiseSail();
- llSetTimerEvent(timerFreq);
- }
- // SPINNAKER HOIST/DROP
- else if (msg=="spin" && SPIN_UP) DropSpin();
- else if (msg=="spin" && !SPIN_UP) HoistSpin();
- //SPINNAKER TRIM
- else if (msg=="spin+") TrimSpinPlus();
- else if (msg=="spin-") TrimSpinMinus();
- //GYBE POLE
- else if (msg=="gybe")
- {
- if (SPIN_UP==TRUE)
- {
- llMessageLinked(SPINNAKER,1004,"",NULL_KEY); //hoist spinnaker
- if (-sailingAngle > 0) llMessageLinked(POLE,1003,"",NULL_KEY);
- if (-sailingAngle < 0) llMessageLinked(POLE,1004,"",NULL_KEY);
- CurSpin=0;
- }
- }
- //MESSAGE lower - okay now we want physics ON but no sailing...
- else if (msg=="lower")
- {
- sailing=FALSE;
- lowerSail();
- }
- else if (msg=="moor")
- {
- llMessageLinked(LINK_ALL_CHILDREN , 0, "stop", NULL_KEY);
- moor();
- llSetTimerEvent(0);
- if (SAIL_UP) lowerSail();
- llResetScript();
- }
- // course hold
- else if (msg=="hold")
- {
- courseHold = TRUE;
- courseHoldValue = zRotAngle*RAD_TO_DEG;
- courseHoldValue = (450.0 - courseHoldValue)%360.0;
- llWhisper(0,"Course Hold enabled:" + (string)courseHoldValue);
- }
- //BOAT ID Setter
- else if (llGetSubString(msg,0,1)=="id")
- {
- if (llGetSubString(msg,3,-1)!="off")
- {
- idStr=llGetSubString(msg,3,-1);
- string tmp=boatName+" #"+idStr;
- llSetObjectName(tmp);
- llWhisper(0,"New Boat ID :"+tmp);
- }
- }
- //START bbk_helmsman ANIMATION
- else if (llGetSubString(msg,0,3)=="anim")
- {
- if (llGetSubString(msg,5,-1)=="off")
- {
- }
- else if (llGetSubString(msg,5,-1)=="on")
- {
- if (permSet) llStartAnimation("bbk_helmsman"); // change thise pose/animation name if needed...
- }
- }
- }
- }
- //-------------------------------- END MAIN BOAT LISTENER ---
- ///////////////////////////////////////////////////////////////
- // BWind Engine - WIND DIRECTION PRESETS /////////////////////
- //////////////////////////////////////////////////////////////
- //wind direction in degrees - North = 0°
- //you don't want to modify the following presets unless you want to add other BWind directions
- // setter on or off, locks out the rest of the settings
- if (msg=="setter")
- {
- llWhisper(0,"BWind using weather buoy");
- useSetter=TRUE;
- lock = TRUE;
- setWindFromBuoy(); // will set all the preset variables based on set wind vector
- }
- if (msg=="setoff")
- {
- llWhisper(0,"BWind setter disengaged");
- llListenRemove(windh); // stop listening, save lag
- useSetter=FALSE; // stop setting variables
- lock = FALSE; // allow the manual BWind setter to work again
- }
- // command set here
- if (lock==FALSE) {
- if (msg=="n") {
- windRose ="North ";
- windDir=(90*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from North");
- }
- if (msg=="nw") {
- windRose ="Northwest ";
- windDir=(135*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from Northwest");
- }
- if (msg=="ne") {
- windRose ="Northeast ";
- windDir=(45*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from Northeast");
- }
- if (msg=="e") {
- windRose ="East ";
- windDir=(0*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from East");
- }
- if (msg=="s") {
- windRose ="South ";
- windDir=(270*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from South");
- }
- if (msg=="sw") {
- windRose ="Southwest ";
- windDir=(225*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from Southwest");
- }
- if (msg=="se") {
- windRose ="Southeast ";
- windDir=(315*DEG_TO_RAD);
- llWhisper(0,"BWind now blowing from Southeast");
- }
- if (msg=="w") {
- windRose ="West ";
- windDir=(180*DEG_TO_RAD);;
- llWhisper(0,"BWind now blowing from West");
- }
- }
- // ----------------------------- END WIND DIRECTION PRESETS ---
- ///////////////////////////////////////////////////////////////
- // BWind Engine - BWIND SPEED PRESETS ////////////////////////
- //////////////////////////////////////////////////////////////
- //this is where you have to mod to set your desired BWIND Wind PRESETS
- // REMEBER THAT THE BOAT SPEED IS SET IN THE TRIM/HUD ROUTINE ABOVE - here you set the max speed only for each wind preset...
- //You may add other wind speeds at will, while I think you have plenty...
- //WWC racing module preset will be added here upon release... (currently under development)
- //8 KNOTS PRESET
- if (msg=="8") {
- //primary parameters - self explanatory
- windSpeed=4.12; //PRECALCULATED WIND SPEED
- maxSpeed=4.0; //YOUR BOAT MAX SPEED FOR THIS WIND PRESET
- heelTweak=0.7; //YOUR BOAT MAX HEEL FOR THIS WIND PRESET
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift; this is useful for multihull boats
- //Preset running... return wind speed status... - THIS BUILDS THE HUD STRING....
- llWhisper(0,"BWind speed set to 8 Knots");
- windType="8 Knots"; // 8 Knots
- }
- // 11 KNOTS PRESET
- if (msg=="11") {
- //primary parameters - see above for explanation (8 Knots Preset)
- windSpeed=5.70;
- maxSpeed=4.5;
- heelTweak=0.8;
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift
- //Preset running... return wind speed status...
- llWhisper(0,"BWind speed set to 11 Knots");
- windType="11 Knots"; // 11 Knots
- }
- // 15 KNOTS PRESET
- // VERY IMPORTANT !!!
- // REMEMBER ! : FOLLOWING VALUES MUST BE THE SAME YOU SET IN DEFAULT WIND SPEED AT LINE 143
- if (msg=="15") {
- //primary parameters - see above for explanation (8 Knots Preset)
- windSpeed=7.75;
- maxSpeed=5.5;
- heelTweak=0.85;
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift
- //Preset running... return wind speed status...
- llWhisper(0,"BWind speed set to 15 Knots");
- windType="15 Knots"; // 15 Knots
- }
- // 18 KNOTS PRESET
- if (msg=="18") {
- //primary parameters - see above for explanation (8 Knots Preset)
- windSpeed=9.30;
- maxSpeed=6.5;
- heelTweak=0.95;
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift
- //Preset running... return wind speed status...
- llWhisper(0,"BWind speed set to 18 Knots");
- windType="18 Knots"; // 18 Knots
- }
- // 21 KNOTS PRESET
- if (msg=="21") {
- //primary parameters - see above for explanation (8 Knots Preset)
- windSpeed=9.5;
- maxSpeed=7.0;
- heelTweak=1.0;
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift
- //Preset running... return wind speed status...
- llWhisper(0,"BWind speed set to 21 Knots");
- windType="21 Knots"; // 21 Knots
- }
- // 25 KNOTS PRESET
- if (msg=="25") {
- //primary parameters - see above for explanation (8 Knots Preset)
- windSpeed=11.3;
- maxSpeed=7.5;
- heelTweak=1.1;
- //Preset Boat Physics
- //llSetVehicleFloatParam (VEHICLE_HOVER_HEIGHT,seaLevel); //Vehicle Lift
- //Preset running... return wind speed status...
- llWhisper(0,"BWind speed set to 25 Knots");
- windType="25 Knots"; // 25 Knots
- }
- // ------------------------------ END WIND SPEED PRESETS ---
- //////////////////////////////////////////////////////////////
- // UTILITIES ////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////
- //Help Message
- //here you may build your own help message, shown when you type 'help' without quotes in chat...
- if (msg=="help") {
- helpString = " ";
- helpString+="SAY IN CHAT...\n";
- helpString+="------------------------------------------------------------------------------------------------\n";
- helpString+="raise - start sailing\n";
- helpString+="lower - lower sails (press arrow keys to move around)\n";
- helpString+="moor - stop sailing\n";
- helpString+="hold - hold current heading\n";
- helpString+="------------------------------------------------------------------------------------------------\n";
- helpString+="n,s,e,w,nw,ne,sw,se,setter,setoff - set BWind direction\n";
- helpString+="8,11,15,18,21,25 - set BWind speed\n";
- helpString+="id nnaa (ex. 12AB) - set boat ID\n";
- helpString+="hud - hud switch (standard/advanced)\n";
- helpString+="spin - hoist/drop Spinnaker (press PgUp & PgDn to trim)\n";
- helpString+="gybe - gybe Spinnaker's pole upon tack\n";
- helpString+="------------------------------------------------------------------------------------------------\n";
- helpString+="HUD colour shows trim settings :\n";
- helpString+="|>><<| red = too loose - |><| yellow = off optimum - \n";
- helpString+="|=| green = optimum - |<>| cyan = too tight\n";
- helpString+="------------------------------------------------------------------------------------------------\n";
- llWhisper(0,helpString);
- }
- // HUD Switch -switch between the two alternative HUD modes : standard and advanced
- else if (msg=="hud" && ADV_HUD) ADV_HUD=FALSE;
- else if (msg=="hud" && !ADV_HUD) ADV_HUD=TRUE;
- }
- if (channel==-54001) // setter buoy, if present, is on this channel
- {
- if (useSetter==TRUE) // don't do anything unless the setter is active
- {
- list lines=llParseString2List(msg,["\n"],[]);
- if (llList2String(lines,0)=="wind") // look for a wind message
- {
- list parse=llParseString2List(llList2String(lines,1),["=",";","/"],[]);
- string var=llList2String(parse,0);
- string val=llList2String(parse,1);
- if (var=="wvel") // take wind velocity as a vector
- {
- wind=(vector)val;
- windSpeed = llVecMag(wind); // m/s for the calculations
- maxSpeed = windSpeed*0.75; // generically, max speed is 3/4 the wind speed
- windSpeed = windSpeed*1.94; // change wind speed to knots
- windDir = ((llAtan2(wind.x,wind.y)* RAD_TO_DEG)+180.0); // true direction
- windType = llGetSubString((string)windSpeed,0,4) + " Knots";
- if (windSpeed > 25.0) // do the heel tweaks based on windspeed
- {
- heelTweak = 1.2;
- }
- else
- {
- if (windSpeed > 21.0)
- {
- heelTweak = 1.1;
- }
- else
- {
- if (windSpeed > 18.0)
- {
- heelTweak = 1.0;
- }
- else
- {
- if (windSpeed > 15.0)
- {
- heelTweak = 0.95;
- }
- else
- {
- if (windSpeed > 11.0)
- {
- heelTweak = 0.85;
- }
- else
- {
- if (windSpeed > 8.0)
- {
- heelTweak = 0.8;
- }
- else
- {
- heelTweak = 0.7;
- }
- }
- }
- }
- }
- }
- if (windDir > 336.0) // now set the compass rose too
- {
- windRose = " North ";
- }
- else
- {
- if (windDir > 290.0)
- {
- windRose = " Northwest ";
- }
- else
- {
- if (windDir > 250.0)
- {
- windRose = " West ";
- }
- else
- {
- if (windDir > 202)
- {
- windRose = " Southwest ";
- }
- else
- {
- if (windDir > 157.0)
- {
- windRose = " South ";
- }
- else
- {
- if (windDir > 112.0)
- {
- windRose = " Southeast ";
- }
- else
- {
- if (windDir > 67.0)
- {
- windRose = " East ";
- }
- else
- {
- if (windDir > 22.0)
- {
- windRose = " Northeast ";
- }
- else
- {
- windRose = " North ";
- }
- }
- }
- }
- }
- }
- }
- }
- windRose = "from " + llGetSubString((string)windDir,0,4) + "º " + windRose;
- // finally the system actually wants the wind direction in radians so convert it back
- // also the whole compass is bass ackwards and offset by 90 degrees being east so
- // the whole damn thing has to rotate and then go to degrees
- windDir = (450.0 - windDir)%360.0;
- //windDir = windDir + 90;
- windDir = windDir*DEG_TO_RAD;
- }
- }
- } }
- }
- // --------------------------------------- END UTILITIES ---
- ///////////////////////////////////////////////////
- // GLOBAL BOAT CONTROLS //////////////////////////
- // you don't want to modify these settings //////
- ////////////////////////////////////////////////
- //Following section maps keyboard keys for boat control... I would NOT edit this section...
- control(key id, integer held, integer change) {
- //turning controls - LEFT AND RIGHT KEYS
- if ( (change & held & CONTROL_LEFT) || (held & CONTROL_LEFT) || (change & held & CONTROL_ROT_LEFT) || (held & CONTROL_ROT_LEFT) ) {
- if (courseHold)
- {
- courseHold = FALSE;
- llWhisper(0,"disengaging course hold...");
- }
- if (sailing == FALSE) llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<rotSpeed/2.0,0.0,rotSpeed>);
- else llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<-rotSpeed,0.0,rotSpeed/1.5>); // left key hold - end
- }
- else if ( (change & held & CONTROL_RIGHT) || (held & CONTROL_RIGHT) || (change & held & CONTROL_ROT_RIGHT) || (held & CONTROL_ROT_RIGHT) ) {
- if (courseHold)
- {
- courseHold = FALSE;
- llWhisper(0,"disengaging course hold...");
- }
- if (sailing == FALSE) llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<-rotSpeed/2.0,0.0,-rotSpeed>);
- else llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<rotSpeed,0.0,-rotSpeed/1.5>); // right key hold - end
- }
- else if ( (change & ~held & CONTROL_LEFT) || (change & ~held & CONTROL_ROT_LEFT) ) {
- llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,0.0>); // left key touched - end
- }
- else if ( (change & ~held & CONTROL_RIGHT) || (change & ~held & CONTROL_ROT_RIGHT) ) {
- llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<0.0,0.0,0.0>); // right key touched - end
- }
- //sail/throttle controls - UP AND DOWN KEYS
- if ( (held & CONTROL_FWD) && (held & CONTROL_UP) ) {
- if (sailing == TRUE) {
- sheetAngle+=7;
- if (sheetAngle>90) sheetAngle=90;
- }
- else
- {
- setTach(5.0);
- llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<5.0,0,0>);
- }
- } // up key hold - end
- else if ( (held & CONTROL_FWD) || (change & held & CONTROL_FWD) ) {
- if (sailing == TRUE) {
- sheetAngle+=2;
- if (sheetAngle>90) sheetAngle=90;
- //llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<5.0,0.0,0.0>);
- } else {
- setTach(5.0);
- llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<5.0,0,0>);
- }
- } // up key touched - end
- else if ( (held & CONTROL_BACK) && (held & CONTROL_UP) ) {
- if (sailing == TRUE) {
- sheetAngle-=7;
- if (sheetAngle<5) sheetAngle=5;
- }
- else
- {
- setTach(0.0);
- }
- } // down key hold - end
- else if ( (held & CONTROL_BACK) || (change & held & CONTROL_BACK) ) {
- if (sailing == TRUE) {
- sheetAngle-=2;
- if (sheetAngle<5) sheetAngle=5;
- //llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<-5.0,0.0,0.0>);
- } else {
- setTach(0.0);
- llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<-5.0,0,0>);
- }
- } // down key touched - end
- //PGUP/PGDN Spinnaker control
- else if (change & held & CONTROL_UP) {
- TrimSpinPlus();
- }
- else if (change & held & CONTROL_DOWN) {
- TrimSpinMinus();
- }
- }
- // ------------------------------------- END GLOBAL BOAT CONTROLS ---
- ///////////////////////////////////////////////////
- // GLOBAL BOAT TIMER /////////////////////////////
- // you don't want to modify these settings //////
- ////////////////////////////////////////////////
- //IMPORTANT !!! THIS IS THE ACTUAL BOAT CYCLE INVOKING ALL SAILING ROUTINES
- //WHATEVER YOU DELETE HERE WILL AFFECT ACTUAL ENGINE BEHAVIOUR
- //HERE YOU MAY ADD YOUR OWN PERSONAL FUNCTIONS IF NEEDED AND YOU KNOW WHAT TO DO...
- link_message(integer from,integer to,string msg,key id) {
- }
- timer() {
- calcTrueWindAngle();
- calcAppWindAngle(); // invoke wind angle calculation routine
- if (SAIL_UP) calcBoomDelta(); // invoke sail trim calculation routine
- calcHeelAngle(); // invoke heel calculation routine
- calcSpeed(); // invoke speed calculation routine
- calcLeeway(); // invoke leeway calculation routine
- calcTurnRate(); // invoke turn rate routine
- if (HUD_ON) updateHUD(); // update hud on cycle
- llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION,<currSpeed,leeway,0>); // boat linear movement
- llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION,<heelTorque,0.0,0.0>); // boat angular movement
- if (courseHold) updateCourse(); // if AP is on, adjust course
- setWindvane(windDir*RAD_TO_DEG);
- }
- // -------------------------------------- END GLOBAL BOAT TIMER ---
- }
- // ------------------------------------- END PROGRAMME -----------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement