| Scripts/SSLaneIndicator.js | "use strict";
this.name	= "SSLaneIndicator";
this.author	= "wesfire";
this.copyright	= "2020 wesfire";
this.description= "Main script to:-calculate and display curent lane position.-set compass lane nearest spot.";
this.version	= "0.8";
this.licence	= "CC BY-NC-SA 4.0";
//internal properties, should not touch
this.$SSLI_t = [1];//null;//new Array(1); //Smart traders ship list
this.$SSLI_bb =null;//VisualEFFECT FOR COMPASS
this.$SSLI_SmartTraderExists =false;//Spawned smart trader exists
this.$SSLI_spawnCounter;//Spawn Counter(Only 1 'Smart' trader and aproximatly every 10 min)
this.$SSLI_MODE_N=0;//MODE id
this.$SSLI_MFDSETOK=false;//For MFD exist and quick setup with N prime button
//worldscript events
this.startUp = function() {
    this.$SSLI_MODE_N=0;
    this.$SSLI_spawnCounter=0.0;
    this.$SSLI_MFDSETOK=false;  
    player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator",false);
}
//Equipment mode...b key
this.mode = function ()
{
    if(player.ship.equipmentStatus("EQ_ADVANCED_COMPASS") != "EQUIPMENT_OK" ||
            player.ship.equipmentStatus("EQ_SSLI_MFD") != "EQUIPMENT_OK" ){
        player.consoleMessage("..ERROR..",4);
        this.$SSLI_MFDSETOK=false;
        return -1;
    }
    
    this.$SSLI_MODE_N=this.$SSLI_MODE_N+1;
    if(this.$SSLI_MODE_N%5==0){
        player.consoleMessage("SSLI, MODE: Only MFD GUI",4);
        player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator\n\nPress 'N' to acivate MFD GUI. ",false);
    }
    else if(this.$SSLI_MODE_N%5==1){
        player.consoleMessage("SSLI, MODE: Lane-1 WP.  ",4);
        player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator\n\nPress 'N' to acivate MFD GUI and \nset compass to nearest point of\nLane-1\n(WhichPointBeacon-MainPlanet)\nlane axis.",false);
    }
    else if(this.$SSLI_MODE_N%5==2){
        player.consoleMessage("SSLI, MODE: Lane-2 SW.  ",4);
        player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator\n\nPress 'N' to acivate MFD GUI and \nset compass to nearest point of\nLane-2\n(Star-WhichPointBeacon)\nlane axis.",false);
    }
    else if(this.$SSLI_MODE_N%5==3){
        player.consoleMessage("SSLI, MODE: Lane-3 SP.  ",4);
        player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator\n\nPress 'N' to acivate MFD GUI and \nset compass to nearest point of\nLane-3\n(Star-MainPlanet)\nlane axis.",false);
    }
    else if(this.$SSLI_MODE_N%5==4){
        player.consoleMessage("SSLI, MODE: Lane-A (N). ",4);
        player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator\n\nPress 'N' to acivate MFD GUI and \nset compass to nearest point of\nLane-A\n(MainStation & Parallel to Lane-1)\nlane axis.",false);
    }
}
//Equipment primed and activated....
this.activated = function ()
{
    if(player.ship.equipmentStatus("EQ_ADVANCED_COMPASS") != "EQUIPMENT_OK" ||
            player.ship.equipmentStatus("EQ_SSLI_MFD") != "EQUIPMENT_OK" ){
        player.consoleMessage("..ERROR..",4);
        this.$SSLI_MFDSETOK=false;
        return -1;
    }else if(this.$SSLI_MFDSETOK==false){
      
        //this.$SSLI_MFDSETOK=player.ship.setMultiFunctionDisplay(player.ship.multiFunctionDisplays, "SSLaneIndicator");
    }
    //Init MFD vars to display
    this.$p1=this.$p2=this.$p3="\xa0|\xa0";
    this.$p4=this.$p5=this.$p6="\xa0/\xa0";
    this.$p7=this.$p8=this.$p9="\xa0-\xa0";
    this.$p10="\xa0-\xa0";
    player.ship.setMultiFunctionText("SSLaneIndicator" , "StarSystemLaneIndicator",false);
    var $SSLaneIndicator_ppos = player.ship.position;
    var $SSLaneIndicator_mppos = system.mainPlanet.position;
    var $SSLaneIndicator_wpos = new Vector3D([0,0,0]);
    var $SSLaneIndicator_spos = system.sun.position;
    //Calculate lanes edges not from planet-Star centers but from 1.2*radius of planet or Star
    var $SSLaneIndicator_mppos1 = Vector3D.interpolate($SSLaneIndicator_wpos,$SSLaneIndicator_mppos,($SSLaneIndicator_wpos.distanceTo($SSLaneIndicator_mppos)-(system.mainPlanet.radius*1.2))/($SSLaneIndicator_wpos.distanceTo($SSLaneIndicator_mppos)));
    var $SSLaneIndicator_mppos2 = Vector3D.interpolate($SSLaneIndicator_mppos,$SSLaneIndicator_spos,((system.mainPlanet.radius*1.2))/($SSLaneIndicator_mppos.distanceTo($SSLaneIndicator_spos)));
    var $SSLaneIndicator_spos2 = Vector3D.interpolate($SSLaneIndicator_spos,$SSLaneIndicator_mppos2,((system.sun.radius*1.2))/($SSLaneIndicator_spos.distanceTo($SSLaneIndicator_mppos2)));
    var $SSLaneIndicator_spos3 = Vector3D.interpolate($SSLaneIndicator_wpos,$SSLaneIndicator_spos,($SSLaneIndicator_wpos.distanceTo($SSLaneIndicator_spos)-(system.sun.radius*1.2))/($SSLaneIndicator_wpos.distanceTo($SSLaneIndicator_spos)));
//BEACON compass FUNCTIONALITY
    if (this.$SSLI_MODE_N % 5 == 0){//GUI ON COMPASS
        player.consoleMessage("MFD output only ...",4);
        if (this.$SSLI_bb==null)
        {
            //  log(this.name, "null");
        }
        else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
    }
    else if (this.$SSLI_MODE_N % 5 == 1){//Lane-1
        player.consoleMessage("SSLI Spot 1 set ...",4);
        if (this.$SSLI_bb==null)
        {
            //  log(this.name, "null");
        }
        else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
        //PROJECTION player position to lane
        var $SSLaneIndicator_CWP_spot = this.$SSLI_closestPointOnLine ($SSLaneIndicator_wpos,$SSLaneIndicator_mppos1,$SSLaneIndicator_ppos);
        // If direction same(NOT IN BETWEEN)...
        if($SSLaneIndicator_CWP_spot.subtract($SSLaneIndicator_wpos).dot($SSLaneIndicator_CWP_spot.subtract($SSLaneIndicator_mppos1)) > 0)
        {
             //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_wpos)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_mppos1))
             {
                 //$SSLaneIndicator_CWP_spot = $SSLaneIndicator_mppos1;
             }
             else
             {
                 //$SSLaneIndicator_CWP_spot = $SSLaneIndicator_wpos;
             }
        }
        this.$SSLI_bb = system.addVisualEffect("SSLI_EMPTYVE_beacon",$SSLaneIndicator_CWP_spot);
        this.$SSLI_bb.beaconLabel = "Lane-1";
        player.ship.compassTarget = this.$SSLI_bb;//SWITCH COMPASS
    }
    else if (this.$SSLI_MODE_N % 5 == 3){//Lane-3 Star-PLANET
        player.consoleMessage("SSLI Spot 3 set ...",4);
        if (this.$SSLI_bb==null)
        {
            //log(this.name, "null");
        }
        else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
        //PROJECTION player position to lane
        var $SSLaneIndicator_CSP_spot = this.$SSLI_closestPointOnLine ($SSLaneIndicator_spos2,$SSLaneIndicator_mppos2,$SSLaneIndicator_ppos);
        // If direction same(NOT IN BETWEEN)...
        if($SSLaneIndicator_CSP_spot.subtract($SSLaneIndicator_spos2).dot($SSLaneIndicator_CSP_spot.subtract($SSLaneIndicator_mppos2)) > 0)
        {
             //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_spos2)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_mppos2) )
             {
                 //$SSLaneIndicator_CSP_spot = $SSLaneIndicator_mppos2;
             }
             else
             {
                 //$SSLaneIndicator_CSP_spot = $SSLaneIndicator_spos2;
             }
        }
        this.$SSLI_bb = system.addVisualEffect("SSLI_EMPTYVE_beacon",$SSLaneIndicator_CSP_spot);
        this.$SSLI_bb.beaconLabel = "Lane-3-Star-P";
        player.ship.compassTarget = this.$SSLI_bb;//SWITCH COMPASS
    }
    else if (this.$SSLI_MODE_N % 5 == 2){//Lane-2 STAR-WITCHPOINT
        player.consoleMessage("SSLI Spot 2 set ...",4);
        if (this.$SSLI_bb==null)
        {
            //log(this.name, "null");
        }
        else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
        //PROJECTION player position to lane
        var $SSLaneIndicator_CSW_spot = this.$SSLI_closestPointOnLine ($SSLaneIndicator_spos3,$SSLaneIndicator_wpos,$SSLaneIndicator_ppos);
        // If direction same(NOT IN BETWEEN)...
        if($SSLaneIndicator_CSW_spot.subtract($SSLaneIndicator_spos3).dot($SSLaneIndicator_CSW_spot.subtract($SSLaneIndicator_wpos)) > 0)
        {
             //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_spos3)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_wpos))
             {
                 //$SSLaneIndicator_CSW_spot = $SSLaneIndicator_wpos;
             }
             else
             {
                 //$SSLaneIndicator_CSW_spot = $SSLaneIndicator_spos3;
             }
        }
        this.$SSLI_bb = system.addVisualEffect("SSLI_EMPTYVE_beacon",$SSLaneIndicator_CSW_spot);
        this.$SSLI_bb.beaconLabel = "Lane-2-Star-W";
        player.ship.compassTarget = this.$SSLI_bb;//SWITCH COMPASS
    }
    else if (this.$SSLI_MODE_N % 5 == 4){//Lane-A
        player.consoleMessage("SSLI Spot A set ...",4);
        if (this.$SSLI_bb==null)
        {
            //log(this.name, "null");
        }
        else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
        //LANE A edges position
        var $SSLaneIndicator_xyn = new Vector3D([0,0,1]);//xy plane normal
        var $SSLaneIndicator_ACmppos = system.mainPlanet.position;// mainPlanet position vector
        var $SSLaneIndicator_ACmspos = system.mainStation.position;//mainStation position vector
        var $SSLaneIndicator_ACmpms = $SSLaneIndicator_ACmspos.subtract($SSLaneIndicator_ACmppos);// Vector from mainPlanet to mainStation
        var $SSLaneIndicator_ACmpmsproj = $SSLaneIndicator_ACmpms.subtract($SSLaneIndicator_xyn.multiply($SSLaneIndicator_ACmpms.dot($SSLaneIndicator_xyn)));//Projection of vector mainPlanet to mainStation to xy plane
        var $SSLaneIndicator_Awpos=$SSLaneIndicator_ACmpmsproj.direction().multiply(75000.0);// A lane at witchpoint;
        var $SSLaneIndicator_Amppos=$SSLaneIndicator_Awpos.add(new Vector3D([0,0,$SSLaneIndicator_mppos1.z]));// A LANE at main planet;
        //PROJECTION player position to lane
        var $SSLaneIndicator_CAWP_spot = this.$SSLI_closestPointOnLine ($SSLaneIndicator_Awpos,$SSLaneIndicator_Amppos,$SSLaneIndicator_ppos);
        // If direction same(NOT IN BETWEEN)...
        if($SSLaneIndicator_CAWP_spot.subtract($SSLaneIndicator_Awpos).dot($SSLaneIndicator_CAWP_spot.subtract($SSLaneIndicator_Amppos)) > 0)
        {
             //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_Awpos)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_Amppos))
             {
                 $SSLaneIndicator_CAWP_spot = $SSLaneIndicator_Amppos;
             }
             else
             {
                 $SSLaneIndicator_CAWP_spot = $SSLaneIndicator_Awpos;
             }
        }
        this.$SSLI_bb = system.addVisualEffect("SSLI_EMPTYVE_beacon",$SSLaneIndicator_CAWP_spot);
        this.$SSLI_bb.beaconLabel = "Lane-A (N)";
        player.ship.compassTarget = this.$SSLI_bb;//SWITCH COMPASS
    }
//MainPlanet-Witchpoint ,GUI DISPLAY and CONSOLE MESAG
    //Find closest point of lane center 
    var $SSLaneIndicator_pInCMPW = this.$SSLI_closestPointOnLine ($SSLaneIndicator_wpos,$SSLaneIndicator_mppos1,$SSLaneIndicator_ppos);
    if($SSLaneIndicator_pInCMPW.z >0 && $SSLaneIndicator_pInCMPW.z < $SSLaneIndicator_mppos1.z){//witchPoint>Player<MainPlanet LANE-1
        if($SSLaneIndicator_ppos.subtract($SSLaneIndicator_pInCMPW).magnitude()<50000){//Inside WB - MP cylinder
	    player.consoleMessage("In Lane-1 (WitchPoint - Main Planet) ",4);
            this.$p2="@";//return 1;
        }else if($SSLaneIndicator_ppos.subtract($SSLaneIndicator_pInCMPW).magnitude()<100000){
            //Calculate angle between mainStation and playerShip vectors on xy plane
            var $SSLaneIndicator_xyn = new Vector3D([0,0,1]);//xy plane normal
            var $SSLaneIndicator_mspos = system.mainStation.position;//mainStation position vector
            var $SSLaneIndicator_mpms = $SSLaneIndicator_mspos.subtract($SSLaneIndicator_mppos);// Vector from mainPlanet to mainStation
            var $SSLaneIndicator_mpmsproj = $SSLaneIndicator_mpms.subtract($SSLaneIndicator_xyn.multiply($SSLaneIndicator_mpms.dot($SSLaneIndicator_xyn)));//Projection of vector mainPlanet to mainStation to xy plane
            var $SSLaneIndicator_pposproj = $SSLaneIndicator_ppos.subtract($SSLaneIndicator_xyn.multiply($SSLaneIndicator_ppos.dot($SSLaneIndicator_xyn)));//Projection of vector of player to xy plane
            var $SSLaneIndicator_rPMS = $SSLaneIndicator_mpmsproj.angleTo($SSLaneIndicator_pposproj);//ANgle in Radians
            //clockwise or counterclockwise angle
            var $SSLaneIndicator_crossPMS = $SSLaneIndicator_mpmsproj.cross($SSLaneIndicator_pposproj);//Cross product of projections
            var $SSLaneIndicator_cwQ = $SSLaneIndicator_crossPMS.dot($SSLaneIndicator_xyn);//Dot prod of cross and normal. >0 cw, <0 ccw.
            if ($SSLaneIndicator_rPMS<=0.3925 || ($SSLaneIndicator_mpms.x == 0 && $SSLaneIndicator_mpms.y ==0 )){
	        player.consoleMessage("In Lane-A (MainStation & parallel to Lane-1) ",4);
                this.$p10="@";//return 4;
            }
	}else{
           // player.consoleMessage("**NOT** In lane witch-mPlanet Cylinder");
	}
    }else{
        //player.consoleMessage("**OFF** lane witch-mPlanet ");
        //...PICK nearest edge of lane
        if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_wpos)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_mppos1))
        {
            //$SSLaneIndicator_CWP_spot = $SSLaneIndicator_mppos1;
            if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCMPW)<50000){//IF in lane Cylinder
                this.$p1="@";
            }
        }
        else
        {
            //$SSLaneIndicator_CWP_spot = $SSLaneIndicator_wpos;
            if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCMPW)<50000){//IF in lane Cylinder
                this.$p3="@";
            }
        }
    }
//MainPlanet-Star ,GUI DISPLAY and CONSOLE MESAG
    var $SSLaneIndicator_pInCMPS = this.$SSLI_closestPointOnLine ($SSLaneIndicator_spos2,$SSLaneIndicator_mppos2,$SSLaneIndicator_ppos);
    if($SSLaneIndicator_pInCMPS.subtract($SSLaneIndicator_mppos2).dot($SSLaneIndicator_pInCMPS.subtract($SSLaneIndicator_spos2)) <= 0){
        if($SSLaneIndicator_ppos.subtract($SSLaneIndicator_pInCMPS).magnitude()<50000){
	    player.consoleMessage("In Lane 3 (Star - MainPlanet).",4);
            this.$p8="@";//return 3;
        }
        else{
            //player.consoleMessage("**NOT** In lane Star-mPlanet Cylinder");
	}
    }else{
          //  player.consoleMessage("**OFF** lane Star-mPlanet ");
          //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_spos2)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_mppos2) )
             {
                 //$SSLaneIndicator_CSP_spot = $SSLaneIndicator_mppos2;
                 if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCMPS)<50000){//IF in lane Cylinder
                     this.$p7="@";
                 }
             }
             else
             {
                 //$SSLaneIndicator_CSP_spot = $SSLaneIndicator_spos2;
                 if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCMPS)<50000){//IF in lane Cylinder
                     this.$p9="@";
                 }
             }      
    }
//WitchPoint-Star ,GUI DISPLAY and CONSOLE MESAG
    var $SSLaneIndicator_pInCWS = this.$SSLI_closestPointOnLine ($SSLaneIndicator_spos3,$SSLaneIndicator_wpos,$SSLaneIndicator_ppos);
    if($SSLaneIndicator_pInCWS.subtract($SSLaneIndicator_wpos).dot($SSLaneIndicator_pInCWS.subtract($SSLaneIndicator_spos3)) <= 0 ){
        if($SSLaneIndicator_ppos.subtract($SSLaneIndicator_pInCWS).magnitude()<50000){
	    player.consoleMessage("In Lane 2 (Star - Witchpoint).",4);
            this.$p5="@";//return 2;
        }
        else{
            //player.consoleMessage("**NOT** In lane Star-Witchpoint Cylinder");
	}
    }else{
        //player.consoleMessage("**OFF** lane Star-Witchpoint ");
             //...PICK nearest edge of lane
             if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_spos3)>$SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_wpos))
             {
                 //$SSLaneIndicator_CSW_spot = $SSLaneIndicator_wpos;
                 if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCWS)<50000){//IF in lane Cylinder
                     this.$p6="@";
                 }
             }
             else
             {
                 //$SSLaneIndicator_CSW_spot = $SSLaneIndicator_spos3;
                 if ($SSLaneIndicator_ppos.distanceTo($SSLaneIndicator_pInCWS)<50000){//IF in lane Cylinder
                     this.$p4="@";
                 }
             }
    }
//NO_LANE ,GUI DISPLAY and CONSOLE MESAG
    if (this.$p2!="@" && this.$p5!="@" && this.$p8!="@" && this.$p10!="@"){
   
        player.consoleMessage("Not in any Known Lane.",4);
    }
    //MFD OUTPUT
    player.ship.setMultiFunctionText("SSLaneIndicator" , "Star System Lane Indicator"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+this.$p1+"\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+this.$p4+"\xa0\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+this.$p7+"\xa0P\xa0"+this.$p8+"\xa0S\xa0"+this.$p9+"\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+this.$p2+"\xa0"+this.$p5+"\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0W\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+this.$p6+"\xa0"+this.$p3+"\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+
       "\n\xa0\xa0\xa0\xa0\xa0\xa0\xa0Lane-A:"+this.$p10+"\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0"+
       "\n\t@:Position"+"\tP:Planet"+"\t-|/:Lanes"+"\n\tW:Whichpoint beacon"+"\tS:Star"+ "\n",false);
    //MFD OUTPUT END
    return 0;
}
//Compass gui remove target
this.$SSLI_compToNone = function(){
    if (this.$SSLI_bb==null)
        {
            //  log(this.name, "null-und");
        }
    else if(this.$SSLI_bb.isVisualEffect){
            this.$SSLI_bb.remove();
        }
}
//Calculate position p projection to line of points a,b
this.$SSLI_closestPointOnLine  = function( $SSLaneIndicator_a, $SSLaneIndicator_b, $SSLaneIndicator_p ){
    var $SSLaneIndicator_ab = $SSLaneIndicator_b.subtract($SSLaneIndicator_a);
    var $SSLaneIndicator_ap = $SSLaneIndicator_p.subtract($SSLaneIndicator_a);
    var $SSLaneIndicator_result = $SSLaneIndicator_a.add(  $SSLaneIndicator_ab.multiply($SSLaneIndicator_ap.dot($SSLaneIndicator_ab)/($SSLaneIndicator_ab.dot($SSLaneIndicator_ab))));
    return $SSLaneIndicator_result;
}
 |