diff --git a/ButtonHUD.conf b/ButtonHUD.conf index 1866dd3..99ec855 100644 --- a/ButtonHUD.conf +++ b/ButtonHUD.conf @@ -1,4 +1,4 @@ -name: ButtonsHud - Dimencia and Archaegeo v5.4 (Minified) +name: ButtonsHud - Dimencia and Archaegeo v5.42 (Minified) slots: core: class: CoreUnit @@ -187,11 +187,12 @@ handlers: AtmoSpeedAssist = true --export: (Default: true) Whether or not atmospheric speeds should be limited to a maximum of AtmoSpeedLimit ForceAlignment = false --export: (Default: false) Whether velocity vector alignment should be forced when in Altitude Hold minRollVelocity = 150 --export: (Default: 150) Min velocity, in m/s, over which advanced rolling can occur - VertTakeOffEngine = false --export: (Default: false) Set this to true if you have VTOL engines on your construct. Will VTOL on AutoTakeOff. - Nav=Navigator.new(system,core,unit)script={}BrakeToggleStatus=BrakeToggleDefault;BrakeIsOn=false;RetrogradeIsOn=false;ProgradeIsOn=false;Autopilot=false;TurnBurn=false;AltitudeHold=false;BrakeLanding=false;AutoTakeoff=false;Reentry=false;VertTakeOff=false;HoldAltitude=1000;AutopilotAccelerating=false;AutopilotRealigned=false;AutopilotBraking=false;AutopilotCruising=false;AutopilotEndSpeed=0;AutopilotStatus="Aligning"AutopilotPlanetGravity=0;PrevViewLock=1;AutopilotTargetName="None"AutopilotTargetCoords=nil;AutopilotTargetIndex=0;GearExtended=nil;TotalDistanceTravelled=0.0;TotalFlightTime=0;SavedLocations={}VectorToTarget=false;LocationIndex=0;LastMaxBrake=0;LockPitch=nil;LastMaxBrakeInAtmo=0;AntigravTargetAltitude=core.getAltitude()LastStartTime=0;SpaceTarget=false;LeftAmount=0;IntoOrbit=false;OrbitTargetSet=false;OrbitTargetCoords=nil;OrbitTargetOrbit=0;OrbitTargetPlanet=nil;OrbitRetriggerTarget=false;OrbitAchieved=false;local a={"userControlScheme","TargetOrbitRadius","apTickRate","freeLookToggle","turnAssist","SafeR","SafeG","SafeB","warmup","DeadZone","circleRad","MouseXSensitivity","MouseYSensitivity","MaxGameVelocity","showHud","autoRollPreference","InvertMouse","pitchSpeedFactor","yawSpeedFactor","rollSpeedFactor","brakeSpeedFactor","brakeFlatFactor","autoRollFactor","turnAssistFactor","torqueFactor","AutoTakeoffAltitude","TargetHoverHeight","AutopilotInterplanetaryThrottle","hideHudOnToggleWidgets","DampingMultiplier","fuelTankHandlingAtmo","ExternalAGG","ShouldCheckDamage","fuelTankHandlingSpace","fuelTankHandlingRocket","RemoteFreeze","hudTickRate","speedChangeLarge","speedChangeSmall","brightHud","brakeLandingRate","MaxPitch","ReentrySpeed","AtmoSpeedLimit","ReentryAltitude","centerX","centerY","SpaceSpeedLimit","AtmoSpeedAssist","vSpdMeterX","vSpdMeterY","altMeterX","altMeterY","fuelX","fuelY","LandingGearGroundHeight","TrajectoryAlignmentStrength","RemoteHud","YawStallAngle","PitchStallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization","ExtraLongitudeTags","ExtraLateralTags","ExtraVerticalTags","OrbitMapSize","OrbitMapX","OrbitMapY","DisplayOrbit","CalculateBrakeLandingSpeed","ForceAlignment","autoRollRollThreshold","minRollVelocity","VertTakeOffEngine","PvPR","PvPG","PvPB"}local b={"SpaceTarget","BrakeToggleStatus","BrakeIsOn","RetrogradeIsOn","ProgradeIsOn","Autopilot","TurnBurn","AltitudeHold","BrakeLanding","Reentry","AutoTakeoff","HoldAltitude","AutopilotAccelerating","AutopilotBraking","AutopilotCruising","AutopilotRealigned","AutopilotEndSpeed","AutopilotStatus","AutopilotPlanetGravity","PrevViewLock","AutopilotTargetName","AutopilotTargetCoords","AutopilotTargetIndex","TotalDistanceTravelled","TotalFlightTime","SavedLocations","VectorToTarget","LocationIndex","LastMaxBrake","LockPitch","LastMaxBrakeInAtmo","AntigravTargetAltitude","LastStartTime"}local c=system.print;local d=math.floor;local e=string.format;local f=json.decode;local g=json.encode;local h=core.getElementMaxHitPointsById;local j=unit.getAtmosphereDensity;local k=core.getElementHitPointsById;local l=core.getElementTypeById;local m=core.getElementMassById;local n=core.getConstructMass;local o=Nav.control.isRemoteControlled;local p=math.atan;function round(q,r)local s=10^(r or 0)return d(q*s+0.5)/s end;local t=SafeR;local u=SafeB;local v=SafeG;local w=false;local x=0;local y=""local z=0;local A=0;local B=false;local C=0;local D=false;local E=round(ResolutionX/2,0)local F=round(ResolutionY/2,0)local G=false;local H=true;local I=55;local J=false;local K=1;local L=1;local M=false;local N=0;local O=0;local P=0;local Q=0;local R=0;local S=0;local T=0;local U=false;local V=false;local W="empty"local X=1;local Y=5;local Z=5;local a0=false;local a1,a2=0;local a3,a4=0;local a5=false;local a6=false;local a7=nil;local a8=0;local a9=0;local aa=false;local ab=0;local ac=0;local ad=0;local ae=3;local af=0;local ag=""local ah=""local ai=0;local aj=false;local ak=false;local al=false;local am=-1;local an=false;local ao=""local ap=j()>0;local aq=core.getAltitude()local ar=core.getElementIdList()local as=system.getTime()local at=nil;local au=false;local av=[[rgb(]]..d(t+0.5)..","..d(v+0.5)..","..d(u+0.5)..[[)]]local aw=[[rgb(]]..d(t*0.9+0.5)..","..d(v*0.9+0.5)..","..d(u*0.9+0.5)..[[)]]local ax={}local ay=0;local az=0;local aA=""local aB=true;local aC={}local aD=1;local aE=0.001;local aF=ResolutionX;local aG=ResolutionY;local aH=nil;local aI=nil;local aJ=nil;local aK=nil;local aL=false;local aM=false;local aN=0;local aO=nil;local aP={}local aQ={}local aR={}local aS=0;local aT=false;local aU={}local aV={}local aW=d(1/apTickRate)*2;local aX={}local aY={}local aZ={}local a_={}local b0=false;local b1=16;local b2=0;local b3=nil;local b4=""local b5=nil;local b6=nil;local b7=nil;local b8=nil;local b9=nil;local ba=nil;local bb=nil;local bc=nil;local bd=false;local be=false;local bf=autoRollPreference;local bg=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())local bh=vec3(core.getWorldVelocity())local bi=vec3(bh):len()local bj=math.cos(YawStallAngle*constants.deg2rad)local bk=LandingGearGroundHeight;local bl=system.getMouseDeltaX()local bm=system.getMouseDeltaY()local bn=false;local bo=system.getTime()local bp=0;local bq=0;local br=AtmoSpeedLimit;local bs=nil;local bt=0;local bu=0;local bv=0;local bw=0;local bx=false;local by=false;function LoadVariables()if dbHud_1 then local bz=dbHud_1.hasKey;if not useTheseSettings then for bA,bB in pairs(a)do if bz(bB)then local bC=f(dbHud_1.getStringValue(bB))if bC~=nil then c(bB.." "..dbHud_1.getStringValue(bB))_G[bB]=bC;aL=true end end end end;coroutine.yield()for bA,bB in pairs(b)do if bz(bB)then local bC=f(dbHud_1.getStringValue(bB))if bC~=nil then c(bB.." "..dbHud_1.getStringValue(bB))_G[bB]=bC;aL=true end end end;if useTheseSettings then W="Updated user preferences used. Will be saved when you exit seat.\nToggle off useTheseSettings to use saved values"ae=5 elseif aL then W="Loaded Saved Variables (see Lua Chat Tab for list)"else W="No Saved Variables Found - Stand up / leave remote to save settings"end else W="No databank found, install one anywhere and rerun the autoconfigure to save variables"end;local bD=system.getTime()if LastStartTime+180bF then bF=bE end;if ContainerOptimization>0 then bF=bF-bF*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then bF=bF-bF*FuelTankOptimization*0.05 end;return bF end;function ProcessElements()local bG=fuelX~=0 and fuelY~=0;for bA in pairs(ar)do local type=l(ar[bA])if type=="Landing Gear"then M=true end;if type=="Dynamic Core Unit"then local bH=h(ar[bA])if bH>10000 then b1=128 elseif bH>1000 then b1=64 elseif bH>150 then b1=32 end end;aS=aS+h(ar[bA])if bG and(type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank")then local bH=h(ar[bA])local bI=m(ar[bA])local bE=0;local bJ=system.getTime()if type=="Atmospheric Fuel Tank"then local bF=400;local bK=35.03;if bH>10000 then bF=51200;bK=5480 elseif bH>1300 then bF=6400;bK=988.67 elseif bH>150 then bF=1600;bK=182.67 end;bE=bI-bK;if fuelTankHandlingAtmo>0 then bF=bF+bF*fuelTankHandlingAtmo*0.2 end;bF=CalculateFuelVolume(bE,bF)aP[#aP+1]={ar[bA],core.getElementNameById(ar[bA]),bF,bK,bE,bJ}end;if type=="Rocket Fuel Tank"then local bF=320;local bK=173.42;if bH>65000 then bF=40000;bK=25740 elseif bH>6000 then bF=5120;bK=4720 elseif bH>700 then bF=640;bK=886.72 end;bE=bI-bK;if fuelTankHandlingRocket>0 then bF=bF+bF*fuelTankHandlingRocket*0.1 end;bF=CalculateFuelVolume(bE,bF)aR[#aR+1]={ar[bA],core.getElementNameById(ar[bA]),bF,bK,bE,bJ}end;if type=="Space Fuel Tank"then local bF=2400;local bK=182.67;if bH>10000 then bF=76800;bK=5480 elseif bH>1300 then bF=9600;bK=988.67 end;bE=bI-bK;if fuelTankHandlingSpace>0 then bF=bF+bF*fuelTankHandlingSpace*0.2 end;bF=CalculateFuelVolume(bE,bF)aQ[#aQ+1]={ar[bA],core.getElementNameById(ar[bA]),bF,bK,bE,bJ}end end end end;function SetupChecks()if gyro~=nil then at=gyro.getState()==1 end;if userControlScheme~="keyboard"then system.lockView(1)else system.lockView(0)end;if radar_1 then if l(radar_1.getId())=="Space Radar"then a5=true else a6=true end end;local bL=j()if door and(bL>0 or bL==0 and aq<10000)then for _,bB in pairs(door)do bB.toggle()end end;if switch then for _,bB in pairs(switch)do bB.toggle()end end;if forcefield and(bL>0 or bL==0 and aq<10000)then for _,bB in pairs(forcefield)do bB.toggle()end end;if antigrav~=nil and not ExternalAGG then if antigrav.getState()==1 then antigrav.show()end end;if o()==1 and RemoteFreeze then system.freeze(1)else system.freeze(0)end;if M then GearExtended=Nav.control.isAnyLandingGearExtended()==1;if GearExtended then Nav.control.extendLandingGears()else Nav.control.retractLandingGears()end end;local bM=AboveGroundLevel()if bM~=-1 or not ap and vec3(core.getVelocity()):len()<50 then BrakeIsOn=true;if not M then GearExtended=true end else BrakeIsOn=false end;if bk~=nil then Nav.axisCommandManager:setTargetGroundAltitude(bk)if bk==0 and not M then GearExtended=true;BrakeIsOn=true end else bk=Nav:getTargetGroundAltitude()if GearExtended then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if ap and bM~=-1 then bb=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]end;userControlScheme=string.lower(userControlScheme)WasInAtmo=ap end;function ConvertResolutionX(bB)if ResolutionX==1920 then return bB else return round(ResolutionX*bB/1920,0)end end;function ConvertResolutionY(bB)if ResolutionY==1080 then return bB else return round(ResolutionY*bB/1080,0)end end;function RefreshLastMaxBrake(bN,bO)if bN==nil then bN=core.g()end;bN=round(bN,5)local bP=j()if bO~=nil and bO or(aO==nil or aO~=bN)then local bh=core.getVelocity()local bQ=vec3(bh):len()local bR=f(unit.getData()).maxBrake;if bR~=nil and bR>0 and ap then bR=bR/utils.clamp(bQ/100,0.1,1)bR=bR/bP;if bP>0.10 then if LastMaxBrakeInAtmo then LastMaxBrakeInAtmo=(LastMaxBrakeInAtmo+bR)/2 else LastMaxBrakeInAtmo=bR end end end;if bR~=nil and bR>0 then LastMaxBrake=bR end;aO=bN end end;function MakeButton(bS,bT,bU,bV,bW,bX,bY,bZ,b_)local c0={enableName=bS,disableName=bT,width=bU,height=bV,x=bW,y=bX,toggleVar=bY,toggleFunction=bZ,drawCondition=b_,hovered=false}table.insert(aC,c0)return c0 end;function UpdateAtlasLocationsList()AtlasOrdered={}for bA,bB in pairs(b3[0])do table.insert(AtlasOrdered,{name=bB.name,index=bA})end;local function c1(c2,c3)return c2.name=0 and cd or 2*math.pi+cd;cb=math.pi/2-math.acos(c9.z/af)end;return setmetatable({latitude=math.deg(cb),longitude=math.deg(cc),altitude=ca,bodyId=c6.bodyId,systemId=c6.planetarySystemId},MapPosition)end;function zeroConvertToWorldCoordinates(ce)local q=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local cf='::pos{'..q..','..q..','..q..','..q..','..q..'}'local cg,ch,cb,cc,ca=string.match(ce,cf)if cg=="0"and ch=="0"then return vec3(tonumber(cb),tonumber(cc),tonumber(ca))end;cc=math.rad(cc)cb=math.rad(cb)local planet=b3[tonumber(cg)][tonumber(ch)]local ci=math.cos(cb)local cj=vec3(ci*math.cos(cc),ci*math.sin(cc),math.sin(cb))return planet.center+(planet.radius+ca)*cj end;function AddNewLocationByWaypoint(ck,planet,ce)if dbHud_1 then local cl={}local position=zeroConvertToWorldCoordinates(ce)if planet.name=="Space"then cl={position=position,name=ck,atmosphere=false,planetname=planet.name,gravity=planet.gravity}else local bL=false;if planet.hasAtmosphere then bL=true else bL=false end;cl={position=position,name=ck,atmosphere=bL,planetname=planet.name,gravity=planet.gravity}end;SavedLocations[#SavedLocations+1]=cl;table.insert(b3[0],cl)UpdateAtlasLocationsList()else W="Databank must be installed to save locations"end end;function AddNewLocation()if dbHud_1 then local position=vec3(core.getConstructWorldPos())local cm=planet.name..". "..#SavedLocations;if radar_1 then local cn,_=radar_1.getData():match('"constructId":"([0-9]*)","distance":([%d%.]*)')if cn~=nil and cn~=""then cm=cm.." "..radar_1.getConstructName(cn)end end;local cl={}local bL=false;if planet.hasAtmosphere then bL=true end;cl={position=position,name=cm,atmosphere=bL,planetname=planet.name,gravity=planet.gravity,safe=true}SavedLocations[#SavedLocations+1]=cl;table.insert(b3[0],cl)UpdateAtlasLocationsList()W="Location saved as "..cm else W="Databank must be installed to save locations"end end;function UpdatePosition(co)local cp=-1;local cl;for bA,bB in pairs(SavedLocations)do if bB.name and bB.name==CustomTarget.name then cp=bA;break end end;if cp~=-1 then local cq;if co~=nil then cl={position=SavedLocations[cp].position,name=co,atmosphere=SavedLocations[cp].atmosphere,planetname=SavedLocations[cp].planetname,gravity=SavedLocations[cp].gravity}else cl={position=vec3(core.getConstructWorldPos()),name=SavedLocations[cp].name,atmosphere=j(),planetname=planet.name,gravity=unit.getClosestPlanetInfluence(),safe=true}end;SavedLocations[cp]=cl;cp=-1;for bA,bB in pairs(b3[0])do if bB.name and bB.name==CustomTarget.name then cp=bA end end;if cp>-1 then b3[0][cp]=cl end;UpdateAtlasLocationsList()W=CustomTarget.name.." position updated"AutopilotTargetIndex=0;UpdateAutopilotTarget()else W="Name Not Found"end end;function ClearCurrentPosition()local cp=-1;for bA,bB in pairs(b3[0])do if bB.name and bB.name==CustomTarget.name then cp=bA end end;if cp>-1 then table.remove(b3[0],cp)end;cp=-1;for bA,bB in pairs(SavedLocations)do if bB.name and bB.name==CustomTarget.name then W=bB.name.." saved location cleared"cp=bA;break end end;if cp~=-1 then table.remove(SavedLocations,cp)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(cr)cr[#cr+1]=e([[]],DeadZone)end;function ToggleRadarPanel()if radarPanelID~=nil and ai==0 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;if perisPanelID~=nil then system.destroyWidgetPanel(perisPanelID)perisPanelID=nil end else if ai==1 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;_autoconf.displayCategoryPanel(radar,radar_size,L_TEXT("ui_lua_widget_periscope", "Periscope"),"periscope")perisPanelID=_autoconf.panels[_autoconf.panels_size]end;placeRadar=true;if radarPanelID==nil and placeRadar then _autoconf.displayCategoryPanel(radar,radar_size,L_TEXT("ui_lua_widget_radar", "Radar"),"radar")radarPanelID=_autoconf.panels[_autoconf.panels_size]placeRadar=false end;ai=0 end end;function ToggleWidgets()if aB then unit.show()core.show()if atmofueltank_size>0 then _autoconf.displayCategoryPanel(atmofueltank,atmofueltank_size,L_TEXT("ui_lua_widget_atmofuel", "Atmo Fuel"),"fuel_container")fuelPanelID=_autoconf.panels[_autoconf.panels_size]end;if spacefueltank_size>0 then _autoconf.displayCategoryPanel(spacefueltank,spacefueltank_size,L_TEXT("ui_lua_widget_spacefuel", "Space Fuel"),"fuel_container")spacefuelPanelID=_autoconf.panels[_autoconf.panels_size]end;if rocketfueltank_size>0 then _autoconf.displayCategoryPanel(rocketfueltank,rocketfueltank_size,L_TEXT("ui_lua_widget_rocketfuel", "Rocket Fuel"),"fuel_container")rocketfuelPanelID=_autoconf.panels[_autoconf.panels_size]end;aB=false else unit.hide()core.hide()if fuelPanelID~=nil then system.destroyWidgetPanel(fuelPanelID)fuelPanelID=nil end;if spacefuelPanelID~=nil then system.destroyWidgetPanel(spacefuelPanelID)spacefuelPanelID=nil end;if rocketfuelPanelID~=nil then system.destroyWidgetPanel(rocketfuelPanelID)rocketfuelPanelID=nil end;aB=true end end;function SetupInterplanetaryPanel()panelInterplanetary=system.createWidgetPanel("Interplanetary Helper")interplanetaryHeader=system.createWidget(panelInterplanetary,"value")interplanetaryHeaderText=system.createData('{"label": "Target Planet", "value": "N/A", "unit":""}')system.addDataToWidget(interplanetaryHeaderText,interplanetaryHeader)widgetDistance=system.createWidget(panelInterplanetary,"value")widgetDistanceText=system.createData('{"label": "distance", "value": "N/A", "unit":""}')system.addDataToWidget(widgetDistanceText,widgetDistance)widgetTravelTime=system.createWidget(panelInterplanetary,"value")widgetTravelTimeText=system.createData('{"label": "Travel Time", "value": "N/A", "unit":""}')system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)widgetMaxMass=system.createWidget(panelInterplanetary,"value")widgetMaxMassText=system.createData('{"label": "Maximum Mass", "value": "N/A", "unit":""}')system.addDataToWidget(widgetMaxMassText,widgetMaxMass)widgetCurBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetCurBrakeDistanceText=system.createData('{"label": "Cur Brake distance", "value": "N/A", "unit":""}')if not ap then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;widgetCurBrakeTime=system.createWidget(panelInterplanetary,"value")widgetCurBrakeTimeText=system.createData('{"label": "Cur Brake Time", "value": "N/A", "unit":""}')if not ap then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;widgetMaxBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeDistanceText=system.createData('{"label": "Max Brake distance", "value": "N/A", "unit":""}')if not ap then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;widgetMaxBrakeTime=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeTimeText=system.createData('{"label": "Max Brake Time", "value": "N/A", "unit":""}')if not ap then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;widgetTrajectoryAltitude=system.createWidget(panelInterplanetary,"value")widgetTrajectoryAltitudeText=system.createData('{"label": "Projected Altitude", "value": "N/A", "unit":""}')if not ap then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end;widgetTargetOrbit=system.createWidget(panelInterplanetary,"value")widgetTargetOrbitText=system.createData('{"label": "Target Altitude", "value": "N/A", "unit":""}')system.addDataToWidget(widgetTargetOrbitText,widgetTargetOrbit)end;function Contains(cs,ct,bW,bX,bU,bV)if cs>bW and csbX and ct0 then IntoOrbit=true;OrbitAchieved=false;CancelIntoOrbit=false;bx=false;bv=nil;bw=nil;if OrbitTargetPlanet==nil then OrbitTargetPlanet=planet end else W="Unable to engage orbiting, not near planet"end end end;function ToggleLockPitch()if LockPitch==nil then local cu=vec3(core.getConstructWorldOrientationForward())local cv=vec3(core.getConstructWorldOrientationRight())local cw=vec3(core.getWorldVertical())local cx=getPitch(cw,cu,cv)LockPitch=cx;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()local bD=system.getTime()if bD-bq<1.5 then if planet.hasAtmosphere then HoldAltitude=planet.spaceEngineMinAltitude-50;bq=-1;if AltitudeHold then return end end else bq=bD end;AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;U=false;BrakeLanding=false;Reentry=false;bf=true;LockPitch=nil;if hoverDetectGround()==-1 or not ap or antigrav and antigrav.getState()==1 then AutoTakeoff=false;if bq>-1 then HoldAltitude=aq end;if not ak and Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;if bq>-1 then HoldAltitude=aq+AutoTakeoffAltitude end;GearExtended=false;Nav.control.retractLandingGears()BrakeIsOn=true;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end;if ak then HoldAltitude=100000 end else bf=autoRollPreference;AutoTakeoff=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;VectorToTarget=false end end;function ToggleFollowMode()if o()==1 then U=not U;if U then Autopilot=false;RetrogradeIsOn=false;ProgradeIsOn=false;AltitudeHold=false;Reentry=false;BrakeLanding=false;AutoTakeoff=false;OldGearExtended=GearExtended;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)else BrakeIsOn=true;bf=autoRollPreference;GearExtended=OldGearExtended;if GearExtended then Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end end else W="Follow Mode only works with Remote controller"U=false end end;function ToggleAutopilot()TargetSet=false;if AutopilotTargetIndex>0 and not Autopilot and not VectorToTarget and not ak then UpdateAutopilotTarget()local cy=zeroConvertToMapPosition(a7,AutopilotTargetCoords)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)if CustomTarget~=nil then LockPitch=nil;SpaceTarget=CustomTarget.planetname=="Space"if SpaceTarget then if j()~=0 then ak=true;ToggleAltitudeHold()else Autopilot=true end elseif planet.name==CustomTarget.planetname then StrongBrakes=true;if j()>0 then if not AltitudeHold then if not VectorToTarget then ToggleVectorToTarget(SpaceTarget)end else if not VectorToTarget then ToggleVectorToTarget(SpaceTarget)end end else if aq>100000 or aq==0 then Autopilot=true else aj=true;ProgradeIsOn=true;if AltitudeHold then ToggleAltitudeHold()end end end else RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then ak=true;ToggleAltitudeHold()else Autopilot=true end end elseif j()==0 then Autopilot=true;RetrogradeIsOn=false;ProgradeIsOn=false;AutopilotRealigned=false;U=false;AltitudeHold=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;G=false;LockPitch=nil;WaypointSet=false else ak=true;ToggleAltitudeHold()end else ak=false;Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;G=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false;HoldAltitude=aq;TargetSet=false end end;function ProgradeToggle()ProgradeIsOn=not ProgradeIsOn;RetrogradeIsOn=false;Autopilot=false;AltitudeHold=false;U=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function RetrogradeToggle()RetrogradeIsOn=not RetrogradeIsOn;ProgradeIsOn=false;Autopilot=false;AltitudeHold=false;U=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function BrakeToggle()BrakeIsOn=not BrakeIsOn;if BrakeLanding then BrakeLanding=false;bf=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;VertTakeOff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;LockPitch=nil;bf=autoRollPreference;aj=false;al=false;ab=0 end end;function CheckDamage(cr)local cz=0;aA=""local cA=aS;local cB=0;local cC=0;local cD=0;local cE=0;local cF=""for bA in pairs(ar)do local bH=0;local cG=0;cG=h(ar[bA])bH=k(ar[bA])cB=cB+bH;if bH0 and ax[11]==ar[bA]then for cI in pairs(ax)do core.deleteSticker(ax[cI])end;ax={}end end;cz=d(cB/cA*100)if cz<100 then cr[#cr+1]=[[]]cE=d(cz*2.55)cF=e("rgb(%d,%d,%d)",255-cE,cE,0)if cz<100 then cr[#cr+1]=e([[Elemental Integrity: %i %%]],cF,cz)if cD>0 then cr[#cr+1]=e([[Disabled Modules: %i Damaged Modules: %i]],cF,cD,cC)elseif cC>0 then cr[#cr+1]=e([[Damaged Modules: %i]],cF,cC)end end;cr[#cr+1]=[[<\g>]]end end;function DrawCursorLine(cr)local cJ=d(utils.clamp(af/(aF/4)*255,0,255))cr[#cr+1]=e("",ac,ad,d(t+0.5)+cJ,d(v+0.5)-cJ,d(u+0.5)-cJ)end;function getPitch(cK,cL,c3)local cM=cK:cross(c3):normalize_inplace()local cx=math.acos(utils.clamp(cM:dot(-cL),-1,1))*constants.rad2deg;if cM:cross(-cL):dot(c3)<0 then cx=-cx end;return cx end;local function cN(cO,cP,cQ)cP=cP:project_on_plane(cO)cQ=cQ:project_on_plane(cO)return p(cP:cross(cQ):dot(cO),cP:dot(cQ))end;function clearAll()if an then an=false;AutopilotAccelerating=false;AutopilotBraking=false;AutopilotCruising=false;Autopilot=false;AutopilotRealigned=false;AutopilotStatus="Aligning"RetrogradeIsOn=false;ProgradeIsOn=false;AltitudeHold=false;Reentry=false;BrakeLanding=false;BrakeIsOn=false;AutoTakeoff=false;VertTakeOff=false;U=false;G=false;aj=false;ak=false;J=false;bf=autoRollPreference;VectorToTarget=false;TurnBurn=false;at=false;LockPitch=nil else an=true end end;function wipeSaveVariables()if not dbHud_1 then W="No Databank Found, unable to wipe. \nYou must have a Databank attached to ship prior to running the HUD autoconfigure"ae=5 else if aM then for bA,bB in pairs(a)do dbHud_1.setStringValue(bB,g(nil))end;for bA,bB in pairs(b)do if bB~="SavedLocations"then dbHud_1.setStringValue(bB,g(nil))end end;W="Databank wiped. New variables will save after re-enter seat and exit"ae=5;aM=false;aL=false;aa=true else W="Press ALT-7 again to confirm wipe of ALL data"aM=true end end end;function CheckButtons()for _,bB in pairs(aC)do if bB.hovered then if not bB.drawCondition or bB.drawCondition()then bB.toggleFunction()end;bB.hovered=false end end end;function SetButtonContains()local bW=ac+aF/2;local bX=ad+aG/2;for _,bB in pairs(aC)do bB.hovered=Contains(bW,bX,bB.x,bB.y,bB.width,bB.height)end end;function DrawButton(cr,cR,hover,bW,bX,cS,cT,cU,cV,cW,cX)if type(cW)=="function"then cW=cW()end;if type(cX)=="function"then cX=cX()end;cr[#cr+1]=e(""if cR then cr[#cr+1]=e("%s",cW)else cr[#cr+1]=e("%s",cX)end end;function DrawButtons(cr)local cY="rgb(50,50,50)'"local cZ="rgb(210,200,200)"local c_=DrawButton;for _,bB in pairs(aC)do local bT=bB.disableName;local bS=bB.enableName;if type(bT)=="function"then bT=bT()end;if type(bS)=="function"then bS=bS()end;if not bB.drawCondition or bB.drawCondition()then c_(cr,bB.toggleVar(),bB.hovered,bB.x,bB.y,bB.width,bB.height,cZ,cY,bT,bS)end end end;function DrawTank(cr,b0,bW,d0,d1,d2,d3,d4)local d5=1;local d6=2;local d7=3;local d8=4;local d9=5;local da=6;local db=""local dc=0;local dd=fuelY;local de=fuelY+10;if o()==1 and not RemoteHud then dd=dd-50;de=de-50 end;cr[#cr+1]=[[]]if d1=="ATMO"then db="atmofueltank"elseif d1=="SPACE"then db="spacefueltank"else db="rocketfueltank"end;dc=_G[db.."_size"]if#d2>0 then for i=1,#d2 do local cm=string.sub(d2[i][d6],1,12)local df=0;for cI=1,dc do if d2[i][d6]==f(unit[db.."_"..cI].getData()).name then df=cI;break end end;if b0 or d3[i]==nil or d4[i]==nil then local dg=0;local dh=0;local di=0;local dj=0;local bJ=system.getTime()if df~=0 then d4[i]=f(unit[db.."_"..df].getData()).percentage;d3[i]=f(unit[db.."_"..df].getData()).timeLeft;if d3[i]=="n/a"then d3[i]=0 end else di=m(d2[i][d5])-d2[i][d8]dg=d2[i][d7]d4[i]=d(0.5+di*100/dg)dh=d2[i][d9]dj=d2[i][da]if dh<=di then d3[i]=0 else d3[i]=d(0.5+di/((dh-di)/(bJ-dj)))end;d2[i][d9]=di;d2[i][da]=bJ end end;if cm==d0 then cm=e("%s %d",d1,i)end;if df==0 then cm=cm.." *"end;local dk;if d3[i]==0 then dk="n/a"else dk=FormatTimeString(d3[i])end;if d4[i]~=nil then local cE=d(d4[i]*2.55)local cF=e("rgb(%d,%d,%d)",255-cE,cE,0)local dl=""if dk~="n/a"and d3[i]<120 or d4[i]<5 then if b0 then dl=[[class="red"]]end end;cr[#cr+1]=e([[ + VertTakeOffEngine = false --export: (Default: false) Set this to true if you have VTOL engines on your construct. Changes Auto Takeoff to Vertical Takeoff. + VertTakeOffMode = "Orbit" --export: (Default: "Orbit") Set to: "AGG" = turn on AGG when above 1km and near AGG activation height, "Orbit" = go directly to orbit based off of TargetOrbitRadius. Must keep quotes. Any case is fine. + Nav=Navigator.new(system,core,unit)script={}BrakeToggleStatus=BrakeToggleDefault;BrakeIsOn=false;RetrogradeIsOn=false;ProgradeIsOn=false;Autopilot=false;TurnBurn=false;AltitudeHold=false;BrakeLanding=false;AutoTakeoff=false;Reentry=false;VertTakeOff=false;HoldAltitude=1000;AutopilotAccelerating=false;AutopilotRealigned=false;AutopilotBraking=false;AutopilotCruising=false;AutopilotEndSpeed=0;AutopilotStatus="Aligning"AutopilotPlanetGravity=0;PrevViewLock=1;AutopilotTargetName="None"AutopilotTargetCoords=nil;AutopilotTargetIndex=0;GearExtended=nil;TotalDistanceTravelled=0.0;TotalFlightTime=0;SavedLocations={}VectorToTarget=false;LocationIndex=0;LastMaxBrake=0;LockPitch=nil;LastMaxBrakeInAtmo=0;AntigravTargetAltitude=core.getAltitude()LastStartTime=0;SpaceTarget=false;LeftAmount=0;IntoOrbit=false;local a={"userControlScheme","TargetOrbitRadius","apTickRate","freeLookToggle","turnAssist","SafeR","SafeG","SafeB","warmup","DeadZone","circleRad","MouseXSensitivity","MouseYSensitivity","MaxGameVelocity","showHud","autoRollPreference","InvertMouse","pitchSpeedFactor","yawSpeedFactor","rollSpeedFactor","brakeSpeedFactor","brakeFlatFactor","autoRollFactor","turnAssistFactor","torqueFactor","AutoTakeoffAltitude","TargetHoverHeight","AutopilotInterplanetaryThrottle","hideHudOnToggleWidgets","DampingMultiplier","fuelTankHandlingAtmo","ExternalAGG","ShouldCheckDamage","fuelTankHandlingSpace","fuelTankHandlingRocket","RemoteFreeze","hudTickRate","speedChangeLarge","speedChangeSmall","brightHud","brakeLandingRate","MaxPitch","ReentrySpeed","AtmoSpeedLimit","ReentryAltitude","centerX","centerY","SpaceSpeedLimit","AtmoSpeedAssist","vSpdMeterX","vSpdMeterY","altMeterX","altMeterY","fuelX","fuelY","LandingGearGroundHeight","TrajectoryAlignmentStrength","RemoteHud","YawStallAngle","PitchStallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization","ExtraLongitudeTags","ExtraLateralTags","ExtraVerticalTags","OrbitMapSize","OrbitMapX","OrbitMapY","DisplayOrbit","CalculateBrakeLandingSpeed","ForceAlignment","autoRollRollThreshold","minRollVelocity","VertTakeOffEngine","VertTakeOffMode","PvPR","PvPG","PvPB"}local b={"SpaceTarget","BrakeToggleStatus","BrakeIsOn","RetrogradeIsOn","ProgradeIsOn","Autopilot","TurnBurn","AltitudeHold","BrakeLanding","Reentry","AutoTakeoff","HoldAltitude","AutopilotAccelerating","AutopilotBraking","AutopilotCruising","AutopilotRealigned","AutopilotEndSpeed","AutopilotStatus","AutopilotPlanetGravity","PrevViewLock","AutopilotTargetName","AutopilotTargetCoords","AutopilotTargetIndex","TotalDistanceTravelled","TotalFlightTime","SavedLocations","VectorToTarget","LocationIndex","LastMaxBrake","LockPitch","LastMaxBrakeInAtmo","AntigravTargetAltitude","LastStartTime"}local c=system.print;local d=math.floor;local e=string.format;local f=json.decode;local g=json.encode;local h=core.getElementMaxHitPointsById;local j=unit.getAtmosphereDensity;local k=core.getElementHitPointsById;local l=core.getElementTypeById;local m=core.getElementMassById;local n=core.getConstructMass;local o=Nav.control.isRemoteControlled;local p=math.atan;function round(q,r)local s=10^(r or 0)return d(q*s+0.5)/s end;local t=SafeR;local u=SafeB;local v=SafeG;local w=false;local x=0;local y=""local z=0;local A=0;local B=false;local C=0;local D=false;local E=round(ResolutionX/2,0)local F=round(ResolutionY/2,0)local G=false;local H=true;local I=55;local J=false;local K=1;local L=1;local M=false;local N=0;local O=0;local P=0;local Q=0;local R=0;local S=0;local T=0;local U=false;local V=false;local W="empty"local X=5;local Y=5;local Z=false;local a0,a1=0;local a2,a3=0;local a4=nil;local a5=0;local a6=0;local a7=false;local a8=0;local a9=0;local aa=0;local ab=3;local ac=0;local ad=""local ae=""local af=0;local ag=false;local ah=false;local ai=false;local aj=-1;local ak=false;local al=""local am=j()>0;local an=core.getAltitude()local ao=core.getElementIdList()local ap=system.getTime()local aq=nil;local ar=false;local as=[[rgb(]]..d(t+0.5)..","..d(v+0.5)..","..d(u+0.5)..[[)]]local at=[[rgb(]]..d(t*0.9+0.5)..","..d(v*0.9+0.5)..","..d(u*0.9+0.5)..[[)]]local au={}local av=0;local aw=0;local ax=""local ay=true;local az={}local aA=1;local aB=0.001;local aC=ResolutionX;local aD=ResolutionY;local aE=nil;local aF=nil;local aG=nil;local aH=nil;local aI=false;local aJ=false;local aK=0;local aL=nil;local aM={}local aN={}local aO={}local aP=0;local aQ=false;local aR={}local aS={}local aT=d(1/apTickRate)*2;local aU={}local aV={}local aW={}local aX={}local aY=false;local aZ=16;local a_=0;local b0=nil;local b1=""local b2=nil;local b3=nil;local b4=nil;local b5=nil;local b6=nil;local b7=nil;local b8=nil;local b9=nil;local ba=false;local bb=false;local bc=autoRollPreference;local bd=vec3(core.getWorldVelocity())local be=vec3(bd):len()local bf=LandingGearGroundHeight;local bg=system.getMouseDeltaX()local bh=system.getMouseDeltaY()local bi=false;local bj=system.getTime()local bk=0;local bl=0;local bm=AtmoSpeedLimit;local bn=0;local bo=nil;local bp=0;local bq=0;local br=false;local bs=false;local bt=false;local bu=false;local bv=0;local bw=nil;local bx=false;local by=false;local bz=false;function LoadVariables()if dbHud_1 then local bA=dbHud_1.hasKey;if not useTheseSettings then for bB,bC in pairs(a)do if bA(bC)then local bD=f(dbHud_1.getStringValue(bC))if bD~=nil then c(bC.." "..dbHud_1.getStringValue(bC))_G[bC]=bD;aI=true end end end end;coroutine.yield()for bB,bC in pairs(b)do if bA(bC)then local bD=f(dbHud_1.getStringValue(bC))if bD~=nil then c(bC.." "..dbHud_1.getStringValue(bC))_G[bC]=bD;aI=true end end end;if useTheseSettings then W="Updated user preferences used. Will be saved when you exit seat.\nToggle off useTheseSettings to use saved values"ab=5 elseif aI then W="Loaded Saved Variables (see Lua Chat Tab for list)"else W="No Saved Variables Found - Stand up / leave remote to save settings"end else W="No databank found, install one anywhere and rerun the autoconfigure to save variables"end;local bE=system.getTime()if LastStartTime+180bG then bG=bF end;if ContainerOptimization>0 then bG=bG-bG*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then bG=bG-bG*FuelTankOptimization*0.05 end;return bG end;function ProcessElements()local bH=fuelX~=0 and fuelY~=0;for bB in pairs(ao)do local type=l(ao[bB])if string.match(type,'^.*Space Engine$')then if string.match(tostring(core.getElementTagsById(ao[bB])),'^.*vertical.*$')then local bI=core.getElementRotationById(ao[bB])if bI[4]<0 then if utils.round(-bI[4],0.1)==0.5 then by=true;system.print("Space Engine Up detected")end else if utils.round(bI[4],0.1)==0.5 then bz=true;system.print("Space Engine Down detected")end end end end;if type=="Landing Gear"then M=true end;if type=="Dynamic Core Unit"then local bJ=h(ao[bB])if bJ>10000 then aZ=128 elseif bJ>1000 then aZ=64 elseif bJ>150 then aZ=32 end end;aP=aP+h(ao[bB])if bH and(type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank")then local bJ=h(ao[bB])local bK=m(ao[bB])local bF=0;local bL=system.getTime()if type=="Atmospheric Fuel Tank"then local bG=400;local bM=35.03;if bJ>10000 then bG=51200;bM=5480 elseif bJ>1300 then bG=6400;bM=988.67 elseif bJ>150 then bG=1600;bM=182.67 end;bF=bK-bM;if fuelTankHandlingAtmo>0 then bG=bG+bG*fuelTankHandlingAtmo*0.2 end;bG=CalculateFuelVolume(bF,bG)aM[#aM+1]={ao[bB],core.getElementNameById(ao[bB]),bG,bM,bF,bL}end;if type=="Rocket Fuel Tank"then local bG=320;local bM=173.42;if bJ>65000 then bG=40000;bM=25740 elseif bJ>6000 then bG=5120;bM=4720 elseif bJ>700 then bG=640;bM=886.72 end;bF=bK-bM;if fuelTankHandlingRocket>0 then bG=bG+bG*fuelTankHandlingRocket*0.1 end;bG=CalculateFuelVolume(bF,bG)aO[#aO+1]={ao[bB],core.getElementNameById(ao[bB]),bG,bM,bF,bL}end;if type=="Space Fuel Tank"then local bG=2400;local bM=182.67;if bJ>10000 then bG=76800;bM=5480 elseif bJ>1300 then bG=9600;bM=988.67 end;bF=bK-bM;if fuelTankHandlingSpace>0 then bG=bG+bG*fuelTankHandlingSpace*0.2 end;bG=CalculateFuelVolume(bF,bG)aN[#aN+1]={ao[bB],core.getElementNameById(ao[bB]),bG,bM,bF,bL}end end end end;function SetupChecks()if gyro~=nil then aq=gyro.getState()==1 end;if userControlScheme~="keyboard"then system.lockView(1)else system.lockView(0)end;if radar_1 then if l(radar_1.getId())=="Space Radar"then hasSpaceRadar=true else hasAtmoRadar=true end end;local bN=j()if door and(bN>0 or bN==0 and an<10000)then for _,bC in pairs(door)do bC.toggle()end end;if switch then for _,bC in pairs(switch)do bC.toggle()end end;if forcefield and(bN>0 or bN==0 and an<10000)then for _,bC in pairs(forcefield)do bC.toggle()end end;if antigrav~=nil and not ExternalAGG then if antigrav.getState()==1 then antigrav.show()end end;if o()==1 and RemoteFreeze then system.freeze(1)else system.freeze(0)end;if M then GearExtended=Nav.control.isAnyLandingGearExtended()==1;if GearExtended then Nav.control.extendLandingGears()else Nav.control.retractLandingGears()end end;local bO=AboveGroundLevel()if bO~=-1 or not am and vec3(core.getVelocity()):len()<50 then BrakeIsOn=true;if not M then GearExtended=true end else BrakeIsOn=false end;if bf~=nil then Nav.axisCommandManager:setTargetGroundAltitude(bf)if bf==0 and not M then GearExtended=true;BrakeIsOn=true end else bf=Nav:getTargetGroundAltitude()if GearExtended then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if am and bO~=-1 then b8=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]end;userControlScheme=string.lower(userControlScheme)WasInAtmo=am end;function ConvertResolutionX(bC)if ResolutionX==1920 then return bC else return round(ResolutionX*bC/1920,0)end end;function ConvertResolutionY(bC)if ResolutionY==1080 then return bC else return round(ResolutionY*bC/1080,0)end end;function RefreshLastMaxBrake(bP,bQ)if bP==nil then bP=core.g()end;bP=round(bP,5)local bR=j()if bQ~=nil and bQ or(aL==nil or aL~=bP)then local bd=core.getVelocity()local bS=vec3(bd):len()local bT=f(unit.getData()).maxBrake;if bT~=nil and bT>0 and am then bT=bT/utils.clamp(bS/100,0.1,1)bT=bT/bR;if bR>0.10 then if LastMaxBrakeInAtmo then LastMaxBrakeInAtmo=(LastMaxBrakeInAtmo+bT)/2 else LastMaxBrakeInAtmo=bT end end end;if bT~=nil and bT>0 then LastMaxBrake=bT end;aL=bP end end;function MakeButton(bU,bV,bW,bX,bY,bZ,b_,c0,c1)local c2={enableName=bU,disableName=bV,width=bW,height=bX,x=bY,y=bZ,toggleVar=b_,toggleFunction=c0,drawCondition=c1,hovered=false}table.insert(az,c2)return c2 end;function UpdateAtlasLocationsList()AtlasOrdered={}for bB,bC in pairs(b0[0])do table.insert(AtlasOrdered,{name=bC.name,index=bB})end;local function c3(c4,c5)return c4.name=0 and cf or 2*math.pi+cf;cd=math.pi/2-math.acos(cb.z/ac)end;return setmetatable({latitude=math.deg(cd),longitude=math.deg(ce),altitude=cc,bodyId=c8.bodyId,systemId=c8.planetarySystemId},MapPosition)end;function zeroConvertToWorldCoordinates(cg)local q=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local ch='::pos{'..q..','..q..','..q..','..q..','..q..'}'local ci,cj,cd,ce,cc=string.match(cg,ch)if ci=="0"and cj=="0"then return vec3(tonumber(cd),tonumber(ce),tonumber(cc))end;ce=math.rad(ce)cd=math.rad(cd)local planet=b0[tonumber(ci)][tonumber(cj)]local ck=math.cos(cd)local cl=vec3(ck*math.cos(ce),ck*math.sin(ce),math.sin(cd))return planet.center+(planet.radius+cc)*cl end;function AddNewLocationByWaypoint(cm,planet,cg)if dbHud_1 then local cn={}local position=zeroConvertToWorldCoordinates(cg)if planet.name=="Space"then cn={position=position,name=cm,atmosphere=false,planetname=planet.name,gravity=planet.gravity}else local bN=false;if planet.hasAtmosphere then bN=true else bN=false end;cn={position=position,name=cm,atmosphere=bN,planetname=planet.name,gravity=planet.gravity}end;SavedLocations[#SavedLocations+1]=cn;table.insert(b0[0],cn)UpdateAtlasLocationsList()else W="Databank must be installed to save locations"end end;function AddNewLocation()if dbHud_1 then local position=vec3(core.getConstructWorldPos())local co=planet.name..". "..#SavedLocations;if radar_1 then local cp,_=radar_1.getData():match('"constructId":"([0-9]*)","distance":([%d%.]*)')if cp~=nil and cp~=""then co=co.." "..radar_1.getConstructName(cp)end end;local cn={}local bN=false;if planet.hasAtmosphere then bN=true end;cn={position=position,name=co,atmosphere=bN,planetname=planet.name,gravity=planet.gravity,safe=true}SavedLocations[#SavedLocations+1]=cn;table.insert(b0[0],cn)UpdateAtlasLocationsList()W="Location saved as "..co else W="Databank must be installed to save locations"end end;function UpdatePosition(cq)local cr=-1;local cn;for bB,bC in pairs(SavedLocations)do if bC.name and bC.name==CustomTarget.name then cr=bB;break end end;if cr~=-1 then local cs;if cq~=nil then cn={position=SavedLocations[cr].position,name=cq,atmosphere=SavedLocations[cr].atmosphere,planetname=SavedLocations[cr].planetname,gravity=SavedLocations[cr].gravity}else cn={position=vec3(core.getConstructWorldPos()),name=SavedLocations[cr].name,atmosphere=j(),planetname=planet.name,gravity=unit.getClosestPlanetInfluence(),safe=true}end;SavedLocations[cr]=cn;cr=-1;for bB,bC in pairs(b0[0])do if bC.name and bC.name==CustomTarget.name then cr=bB end end;if cr>-1 then b0[0][cr]=cn end;UpdateAtlasLocationsList()W=CustomTarget.name.." position updated"AutopilotTargetIndex=0;UpdateAutopilotTarget()else W="Name Not Found"end end;function ClearCurrentPosition()local cr=-1;for bB,bC in pairs(b0[0])do if bC.name and bC.name==CustomTarget.name then cr=bB end end;if cr>-1 then table.remove(b0[0],cr)end;cr=-1;for bB,bC in pairs(SavedLocations)do if bC.name and bC.name==CustomTarget.name then W=bC.name.." saved location cleared"cr=bB;break end end;if cr~=-1 then table.remove(SavedLocations,cr)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(ct)ct[#ct+1]=e([[]],DeadZone)end;function ToggleRadarPanel()if radarPanelID~=nil and af==0 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;if perisPanelID~=nil then system.destroyWidgetPanel(perisPanelID)perisPanelID=nil end else if af==1 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;_autoconf.displayCategoryPanel(radar,radar_size,L_TEXT("ui_lua_widget_periscope", "Periscope"),"periscope")perisPanelID=_autoconf.panels[_autoconf.panels_size]end;placeRadar=true;if radarPanelID==nil and placeRadar then _autoconf.displayCategoryPanel(radar,radar_size,L_TEXT("ui_lua_widget_radar", "Radar"),"radar")radarPanelID=_autoconf.panels[_autoconf.panels_size]placeRadar=false end;af=0 end end;function ToggleWidgets()if ay then unit.show()core.show()if atmofueltank_size>0 then _autoconf.displayCategoryPanel(atmofueltank,atmofueltank_size,L_TEXT("ui_lua_widget_atmofuel", "Atmo Fuel"),"fuel_container")fuelPanelID=_autoconf.panels[_autoconf.panels_size]end;if spacefueltank_size>0 then _autoconf.displayCategoryPanel(spacefueltank,spacefueltank_size,L_TEXT("ui_lua_widget_spacefuel", "Space Fuel"),"fuel_container")spacefuelPanelID=_autoconf.panels[_autoconf.panels_size]end;if rocketfueltank_size>0 then _autoconf.displayCategoryPanel(rocketfueltank,rocketfueltank_size,L_TEXT("ui_lua_widget_rocketfuel", "Rocket Fuel"),"fuel_container")rocketfuelPanelID=_autoconf.panels[_autoconf.panels_size]end;ay=false else unit.hide()core.hide()if fuelPanelID~=nil then system.destroyWidgetPanel(fuelPanelID)fuelPanelID=nil end;if spacefuelPanelID~=nil then system.destroyWidgetPanel(spacefuelPanelID)spacefuelPanelID=nil end;if rocketfuelPanelID~=nil then system.destroyWidgetPanel(rocketfuelPanelID)rocketfuelPanelID=nil end;ay=true end end;function SetupInterplanetaryPanel()panelInterplanetary=system.createWidgetPanel("Interplanetary Helper")interplanetaryHeader=system.createWidget(panelInterplanetary,"value")interplanetaryHeaderText=system.createData('{"label": "Target Planet", "value": "N/A", "unit":""}')system.addDataToWidget(interplanetaryHeaderText,interplanetaryHeader)widgetDistance=system.createWidget(panelInterplanetary,"value")widgetDistanceText=system.createData('{"label": "distance", "value": "N/A", "unit":""}')system.addDataToWidget(widgetDistanceText,widgetDistance)widgetTravelTime=system.createWidget(panelInterplanetary,"value")widgetTravelTimeText=system.createData('{"label": "Travel Time", "value": "N/A", "unit":""}')system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)widgetMaxMass=system.createWidget(panelInterplanetary,"value")widgetMaxMassText=system.createData('{"label": "Maximum Mass", "value": "N/A", "unit":""}')system.addDataToWidget(widgetMaxMassText,widgetMaxMass)widgetCurBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetCurBrakeDistanceText=system.createData('{"label": "Cur Brake distance", "value": "N/A", "unit":""}')if not am then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;widgetCurBrakeTime=system.createWidget(panelInterplanetary,"value")widgetCurBrakeTimeText=system.createData('{"label": "Cur Brake Time", "value": "N/A", "unit":""}')if not am then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;widgetMaxBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeDistanceText=system.createData('{"label": "Max Brake distance", "value": "N/A", "unit":""}')if not am then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;widgetMaxBrakeTime=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeTimeText=system.createData('{"label": "Max Brake Time", "value": "N/A", "unit":""}')if not am then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;widgetTrajectoryAltitude=system.createWidget(panelInterplanetary,"value")widgetTrajectoryAltitudeText=system.createData('{"label": "Projected Altitude", "value": "N/A", "unit":""}')if not am then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end;widgetTargetOrbit=system.createWidget(panelInterplanetary,"value")widgetTargetOrbitText=system.createData('{"label": "Target Altitude", "value": "N/A", "unit":""}')system.addDataToWidget(widgetTargetOrbitText,widgetTargetOrbit)end;function Contains(cu,cv,bY,bZ,bW,bX)if cu>bY and cubZ and cv0 then IntoOrbit=true;bx=false;CancelIntoOrbit=false;br=false;bp=nil;bq=nil;if bw==nil then bw=planet end else W="Unable to engage orbiting, not near planet"end end end;function ToggleLockPitch()if LockPitch==nil then local cw=vec3(core.getConstructWorldOrientationForward())local cx=vec3(core.getConstructWorldOrientationRight())local cy=vec3(core.getWorldVertical())local cz=getPitch(cy,cw,cx)LockPitch=cz;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()local bE=system.getTime()if bE-bl<1.5 then if planet.hasAtmosphere then HoldAltitude=planet.spaceEngineMinAltitude-50;bl=-1;if AltitudeHold then return end end else bl=bE end;AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;U=false;BrakeLanding=false;Reentry=false;bc=true;LockPitch=nil;if hoverDetectGround()==-1 or not am then AutoTakeoff=false;if bl>-1 then HoldAltitude=an end;if not ah and Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;if bl>-1 then HoldAltitude=an+AutoTakeoffAltitude end;GearExtended=false;Nav.control.retractLandingGears()BrakeIsOn=true;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end;if ah then HoldAltitude=100000 end else bc=autoRollPreference;AutoTakeoff=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;VectorToTarget=false end end;function ToggleFollowMode()if o()==1 then U=not U;if U then Autopilot=false;RetrogradeIsOn=false;ProgradeIsOn=false;AltitudeHold=false;Reentry=false;BrakeLanding=false;AutoTakeoff=false;OldGearExtended=GearExtended;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)else BrakeIsOn=true;bc=autoRollPreference;GearExtended=OldGearExtended;if GearExtended then Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end end else W="Follow Mode only works with Remote controller"U=false end end;function ToggleAutopilot()TargetSet=false;if AutopilotTargetIndex>0 and not Autopilot and not VectorToTarget and not ah then UpdateAutopilotTarget()local cA=zeroConvertToMapPosition(a4,AutopilotTargetCoords)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)if CustomTarget~=nil then LockPitch=nil;SpaceTarget=CustomTarget.planetname=="Space"if SpaceTarget then if j()~=0 then ah=true;ToggleAltitudeHold()else Autopilot=true end elseif planet.name==CustomTarget.planetname then StrongBrakes=true;if j()>0 then bx=false;if not VectorToTarget then ToggleVectorToTarget(SpaceTarget)end else if an>100000 or an==0 then bx=false;Autopilot=true else ag=true;ProgradeIsOn=true;if AltitudeHold then ToggleAltitudeHold()end end end else RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then ah=true;ToggleAltitudeHold()else Autopilot=true end end elseif j()==0 then local cB=unit.getClosestPlanetInfluence()>0;if CustomTarget==nil and(a4.name==planet.name and cB)then ToggleIntoOrbit()else Autopilot=true;RetrogradeIsOn=false;ProgradeIsOn=false;AutopilotRealigned=false;U=false;AltitudeHold=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;G=false;LockPitch=nil;WaypointSet=false end else ah=true;ToggleAltitudeHold()end else ah=false;Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;G=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false;HoldAltitude=an;TargetSet=false end end;function ProgradeToggle()ProgradeIsOn=not ProgradeIsOn;RetrogradeIsOn=false;Autopilot=false;AltitudeHold=false;U=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function RetrogradeToggle()RetrogradeIsOn=not RetrogradeIsOn;ProgradeIsOn=false;Autopilot=false;AltitudeHold=false;U=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function BrakeToggle()BrakeIsOn=not BrakeIsOn;if BrakeLanding then BrakeLanding=false;bc=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;VertTakeOff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;IntoOrbit=false;LockPitch=nil;bc=autoRollPreference;ag=false;ai=false;a8=0 end end;function CheckDamage(ct)local cC=0;ax=""local cD=aP;local cE=0;local cF=0;local cG=0;local cH=0;local cI=""for bB in pairs(ao)do local bJ=0;local cJ=0;cJ=h(ao[bB])bJ=k(ao[bB])cE=cE+bJ;if bJ0 and au[11]==ao[bB]then for cL in pairs(au)do core.deleteSticker(au[cL])end;au={}end end;cC=d(cE/cD*100)if cC<100 then ct[#ct+1]=[[]]cH=d(cC*2.55)cI=e("rgb(%d,%d,%d)",255-cH,cH,0)if cC<100 then ct[#ct+1]=e([[Elemental Integrity: %i %%]],cI,cC)if cG>0 then ct[#ct+1]=e([[Disabled Modules: %i Damaged Modules: %i]],cI,cG,cF)elseif cF>0 then ct[#ct+1]=e([[Damaged Modules: %i]],cI,cF)end end;ct[#ct+1]=[[<\g>]]end end;function DrawCursorLine(ct)local cM=d(utils.clamp(ac/(aC/4)*255,0,255))ct[#ct+1]=e("",a9,aa,d(t+0.5)+cM,d(v+0.5)-cM,d(u+0.5)-cM)end;function getPitch(cN,cO,c5)local cP=cN:cross(c5):normalize_inplace()local cz=math.acos(utils.clamp(cP:dot(-cO),-1,1))*constants.rad2deg;if cP:cross(-cO):dot(c5)<0 then cz=-cz end;return cz end;local function cQ(cR,cS,cT)cS=cS:project_on_plane(cR)cT=cT:project_on_plane(cR)return p(cS:cross(cT):dot(cR),cS:dot(cT))end;function clearAll()if ak then ak=false;AutopilotAccelerating=false;AutopilotBraking=false;AutopilotCruising=false;Autopilot=false;AutopilotRealigned=false;AutopilotStatus="Aligning"RetrogradeIsOn=false;ProgradeIsOn=false;AltitudeHold=false;Reentry=false;BrakeLanding=false;BrakeIsOn=false;AutoTakeoff=false;VertTakeOff=false;U=false;G=false;ag=false;ah=false;J=false;bc=autoRollPreference;VectorToTarget=false;TurnBurn=false;aq=false;LockPitch=nil else ak=true end end;function wipeSaveVariables()if not dbHud_1 then W="No Databank Found, unable to wipe. \nYou must have a Databank attached to ship prior to running the HUD autoconfigure"ab=5 else if aJ then for bB,bC in pairs(a)do dbHud_1.setStringValue(bC,g(nil))end;for bB,bC in pairs(b)do if bC~="SavedLocations"then dbHud_1.setStringValue(bC,g(nil))end end;W="Databank wiped. New variables will save after re-enter seat and exit"ab=5;aJ=false;aI=false;a7=true else W="Press ALT-7 again to confirm wipe of ALL data"aJ=true end end end;function CheckButtons()for _,bC in pairs(az)do if bC.hovered then if not bC.drawCondition or bC.drawCondition()then bC.toggleFunction()end;bC.hovered=false end end end;function SetButtonContains()local bY=a9+aC/2;local bZ=aa+aD/2;for _,bC in pairs(az)do bC.hovered=Contains(bY,bZ,bC.x,bC.y,bC.width,bC.height)end end;function DrawButton(ct,cU,hover,bY,bZ,cV,cW,cX,cY,cZ,c_)if type(cZ)=="function"then cZ=cZ()end;if type(c_)=="function"then c_=c_()end;ct[#ct+1]=e(""if cU then ct[#ct+1]=e("%s",cZ)else ct[#ct+1]=e("%s",c_)end end;function DrawButtons(ct)local d0="rgb(50,50,50)'"local d1="rgb(210,200,200)"local d2=DrawButton;for _,bC in pairs(az)do local bV=bC.disableName;local bU=bC.enableName;if type(bV)=="function"then bV=bV()end;if type(bU)=="function"then bU=bU()end;if not bC.drawCondition or bC.drawCondition()then d2(ct,bC.toggleVar(),bC.hovered,bC.x,bC.y,bC.width,bC.height,d1,d0,bV,bU)end end end;function DrawTank(ct,aY,bY,d3,d4,d5,d6,d7)local d8=1;local d9=2;local da=3;local db=4;local dc=5;local dd=6;local de=""local df=0;local dg=fuelY;local dh=fuelY+10;if o()==1 and not RemoteHud then dg=dg-50;dh=dh-50 end;ct[#ct+1]=[[]]if d4=="ATMO"then de="atmofueltank"elseif d4=="SPACE"then de="spacefueltank"else de="rocketfueltank"end;df=_G[de.."_size"]if#d5>0 then for i=1,#d5 do local co=string.sub(d5[i][d9],1,12)local di=0;for cL=1,df do if d5[i][d9]==f(unit[de.."_"..cL].getData()).name then di=cL;break end end;if aY or d6[i]==nil or d7[i]==nil then local dj=0;local dk=0;local dl=0;local dm=0;local bL=system.getTime()if di~=0 then d7[i]=f(unit[de.."_"..di].getData()).percentage;d6[i]=f(unit[de.."_"..di].getData()).timeLeft;if d6[i]=="n/a"then d6[i]=0 end else dl=m(d5[i][d8])-d5[i][db]dj=d5[i][da]d7[i]=d(0.5+dl*100/dj)dk=d5[i][dc]dm=d5[i][dd]if dk<=dl then d6[i]=0 else d6[i]=d(0.5+dl/((dk-dl)/(bL-dm)))end;d5[i][dc]=dl;d5[i][dd]=bL end end;if co==d3 then co=e("%s %d",d4,i)end;if di==0 then co=co.." *"end;local dn;if d6[i]==0 then dn="n/a"else dn=FormatTimeString(d6[i])end;if d7[i]~=nil then local cH=d(d7[i]*2.55)local cI=e("rgb(%d,%d,%d)",255-cH,cH,0)local dp=""if dn~="n/a"and d6[i]<120 or d7[i]<5 then if aY then dp=[[class="red"]]end end;ct[#ct+1]=e([[ %s %d%% %s - ]],bW,dd,dl,cm,bW,de,cF,d4[i],dk)dd=dd+30;de=de+30 end end end;cr[#cr+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(bh)bh=vec3(bh)local cx=-math.deg(math.atan(bh.y,bh.z))+180;cx=cx-90;if cx<0 then cx=360+cx end;if cx>180 then cx=-180+cx-180 end;return-cx end;function getRelativeYaw(bh)bh=vec3(bh)local dm=math.deg(math.atan(bh.y,bh.x))-90;if dm<-180 then dm=360+dm end;return dm end;function AlignToWorldVector(dn,dp,dq)if not ap or not bn or am~=-1 or bi0 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,dC.height,dC.x-200-30,dC.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)dz=60;dA=300;local bW=10;local bX=aG/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",dA,dz,bW,bX,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",dA,dz,bW+dA+20,bX,function()return AltitudeHold end,ToggleAltitudeHold)bX=bX+dz+20;MakeButton("Engage Autoland","Disable Autoland",dA,dz,bW,bX,function()return AutoLanding end,ToggleAutoLanding)if VertTakeOffEngine then MakeButton("Engage Vertical Takeoff","Disable Vertical Takeoff",dA,dz,bW+dA+20,bX,function()return VertTakeOff end,ToggleAutoTakeoff)else MakeButton("Engage Auto Takeoff","Disable Auto Takeoff",dA,dz,bW+dA+20,bX,function()return AutoTakeoff end,ToggleAutoTakeoff)end;bX=bX+dz+20;MakeButton("Show Orbit Display","Hide Orbit Display",dA,dz,bW,bX,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then W="Orbit Display Enabled"else W="Orbit Display Disabled"end end)MakeButton("Engage Orbiting","Cancel Orbiting",dA,dz,bW+dA+20,bX,function()return IntoOrbit end,ToggleIntoOrbit,function()return j()==0 and unit.getClosestPlanetInfluence()>0 end)bX=bX+dz+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",dA,dz,bW,bX,function()return Reentry end,function()aj=true;ProgradeToggle()end,function()return aq>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",dA,dz,bW+dA+20,bX,function()return Reentry end,BeginReentry,function()return aq>ReentryAltitude end)bX=bX+dz+20;MakeButton("Engage Follow Mode","Disable Follow Mode",dA,dz,bW,bX,function()return U end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",dA,dz,bW+dA+20,bX,function()return aT end,function()aT=not aT;if aT then W="Repair Arrows Enabled"else W="Repair Arrows Diabled"end end,function()return o()==1 end)bX=bX+dz+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",dA,dz,bW,bX,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bX=bX+dz+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,dA*2,dz,bW,bX,function()return false end,function()if userControlScheme=="keyboard"then userControlScheme="mouse"elseif userControlScheme=="mouse"then userControlScheme="virtual joystick"else userControlScheme="keyboard"end end)end;function GetFlightStyle()local dD=Nav.axisCommandManager:getAxisCommandType(0)local dE="TRAVEL"if dD==1 then dE="CRUISE"end;if Autopilot then dE="AUTOPILOT"end;return dE end;function UpdateHud(cr)local ca=aq;local bh=core.getVelocity()local bQ=vec3(bh):len()local cw=vec3(core.getWorldVertical())local cu=vec3(core.getConstructWorldOrientationForward())local cv=vec3(core.getConstructWorldOrientationRight())local dF=vec3(core.getConstructWorldOrientationUp())local dG=getRoll(cw,cu,cv)local dH=dG/180*math.pi;local dI=math.cos(dH)local dJ=math.sin(dH)local cx=getPitch(cw,cu,cv*dI+dF*dJ)local dK=dG;local dL=cx;local dM=j()local dN=d(unit.getThrottle())local dO=bQ*3.6;local dP=unit.getAxisCommandValue(0)local dQ=ConvertResolutionX(1770)local dR=ConvertResolutionY(310)if AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then dP=z;dN=z*100 end;local dE=GetFlightStyle()local dS="ROLL"local dT=unit.getClosestPlanetInfluence()>0;if dN==nil then dN=0 end;if not dT then if bQ>5 then cx=getRelativePitch(bh)dG=getRelativeYaw(bh)else cx=0;dG=0 end;dS="YAW"end;if x>50000 and not ap then local dU;if x>200000 then dU=round(x/200000,2).." su"else dU=round(x/1000,1).." km"end;cr[#cr+1]=e([[PvP Boundary: %s]],dQ,dR,dU)end;cr[#cr+1]=ah;cr[#cr+1]=aA;cr[#cr+1]=ag;if b2%aW==0 then b0=true end;if fuelX~=0 and fuelY~=0 then DrawTank(cr,b0,fuelX,"Atmospheric ","ATMO",aP,aZ,a_)DrawTank(cr,b0,fuelX+100,"Space fuel t","SPACE",aQ,aX,aY)DrawTank(cr,b0,fuelX+200,"Rocket fuel ","ROCKET",aR,aU,aV)end;if b0 then b0=false;b2=0 end;b2=b2+1;DrawVerticalSpeed(cr,ca)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if dT then DrawRollLines(cr,centerX,centerY,dK,dS,dT)DrawArtificialHorizon(cr,dL,dK,centerX,centerY,dT,d(getRelativeYaw(bh)),bQ)else DrawRollLines(cr,centerX,centerY,dG,dS,dT)DrawArtificialHorizon(cr,cx,dG,centerX,centerY,dT,d(dG),bQ)end;DrawAltitudeDisplay(cr,ca,dT)DrawPrograde(cr,bh,bQ,centerX,centerY)end end;DrawThrottle(cr,dE,dN,dP)DrawSpeed(cr,dO)DrawWarnings(cr)DisplayOrbitScreen(cr)if screen_2 then local ce=vec3(core.getConstructWorldPos())local bW=960+ce.x/b5;local bX=450+ce.y/b6;screen_2.moveContent(b7,(bW-80)/19.2,(bX-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(cr)if not w then t=PvPR;v=PvPG;u=PvPB else t=SafeR;v=SafeG;u=SafeB end;av=[[rgb(]]..d(t+0.5)..","..d(v+0.5)..","..d(u+0.5)..[[)]]aw=[[rgb(]]..d(t*0.9+0.5)..","..d(v*0.9+0.5)..","..d(u*0.9+0.5)..[[)]]local dV=av;local dW=aw;local dX=av;local dY=aw;if IsInFreeLook()and not brightHud then dV=[[rgb(]]..d(t*0.4+0.5)..","..d(v*0.4+0.5)..","..d(u*0.3+0.5)..[[)]]dW=[[rgb(]]..d(t*0.3+0.5)..","..d(v*0.3+0.5)..","..d(u*0.2+0.5)..[[)]]end;cr[#cr+1]=e([[ + ]],bY,dg,dp,co,bY,dh,cI,d7[i],dn)dg=dg+30;dh=dh+30 end end end;ct[#ct+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(bd)bd=vec3(bd)local cz=-math.deg(math.atan(bd.y,bd.z))+180;cz=cz-90;if cz<0 then cz=360+cz end;if cz>180 then cz=-180+cz-180 end;return-cz end;function getRelativeYaw(bd)bd=vec3(bd)local dq=math.deg(math.atan(bd.y,bd.x))-90;if dq<-180 then dq=360+dq end;return dq end;function AlignToWorldVector(dr,ds,dt)if not am or not bi or aj~=-1 or be0 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,dF.height,dF.x-200-30,dF.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)dC=60;dD=300;local bY=10;local bZ=aD/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",dD,dC,bY,bZ,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",dD,dC,bY+dD+20,bZ,function()return AltitudeHold end,ToggleAltitudeHold)bZ=bZ+dC+20;MakeButton("Engage Autoland","Disable Autoland",dD,dC,bY,bZ,function()return AutoLanding end,ToggleAutoLanding)local dG,dH,dI;if VertTakeOffEngine then dG="Engage Vertical Takeoff"dH="Disable Vertical Takeoff"dI=VertTakeOff else dG="Engage Auto Takeoff"dH="Disable Auto Takeoff"dI=AutoTakeoff end;MakeButton(dG,dH,dD,dC,bY+dD+20,bZ,function()return dI end,ToggleAutoTakeoff)bZ=bZ+dC+20;MakeButton("Show Orbit Display","Hide Orbit Display",dD,dC,bY,bZ,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then W="Orbit Display Enabled"else W="Orbit Display Disabled"end end)MakeButton("Engage Orbiting","Cancel Orbiting",dD,dC,bY+dD+20,bZ,function()return IntoOrbit end,ToggleIntoOrbit,function()return j()==0 and unit.getClosestPlanetInfluence()>0 end)bZ=bZ+dC+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",dD,dC,bY,bZ,function()return Reentry end,function()ag=true;ProgradeToggle()end,function()return an>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",dD,dC,bY+dD+20,bZ,function()return Reentry end,BeginReentry,function()return an>ReentryAltitude end)bZ=bZ+dC+20;MakeButton("Engage Follow Mode","Disable Follow Mode",dD,dC,bY,bZ,function()return U end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",dD,dC,bY+dD+20,bZ,function()return aQ end,function()aQ=not aQ;if aQ then W="Repair Arrows Enabled"else W="Repair Arrows Diabled"end end,function()return o()==1 end)bZ=bZ+dC+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",dD,dC,bY,bZ,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bZ=bZ+dC+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,dD*2,dC,bY,bZ,function()return false end,function()if userControlScheme=="keyboard"then userControlScheme="mouse"elseif userControlScheme=="mouse"then userControlScheme="virtual joystick"else userControlScheme="keyboard"end end)end;function GetFlightStyle()local dJ=Nav.axisCommandManager:getAxisCommandType(0)local dK="TRAVEL"if dJ==1 then dK="CRUISE"end;if Autopilot then dK="AUTOPILOT"end;return dK end;function UpdateHud(ct)local cc=an;local bd=core.getVelocity()local bS=vec3(bd):len()local cy=vec3(core.getWorldVertical())local cw=vec3(core.getConstructWorldOrientationForward())local cx=vec3(core.getConstructWorldOrientationRight())local dL=vec3(core.getConstructWorldOrientationUp())local dM=getRoll(cy,cw,cx)local dN=dM/180*math.pi;local dO=math.cos(dN)local dP=math.sin(dN)local cz=getPitch(cy,cw,cx*dO+dL*dP)local dQ=dM;local dR=cz;local dS=j()local dT=d(unit.getThrottle())local dU=bS*3.6;local dV=unit.getAxisCommandValue(0)local dW=ConvertResolutionX(1770)local dX=ConvertResolutionY(310)if AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then dV=z;dT=z*100 end;local dK=GetFlightStyle()local dY="ROLL"local cB=unit.getClosestPlanetInfluence()>0;if dT==nil then dT=0 end;if not cB then if bS>5 then cz=getRelativePitch(bd)dM=getRelativeYaw(bd)else cz=0;dM=0 end;dY="YAW"end;if x>50000 and not am then local dZ;if x>200000 then dZ=round(x/200000,2).." su"else dZ=round(x/1000,1).." km"end;ct[#ct+1]=e([[PvP Boundary: %s]],dW,dX,dZ)end;ct[#ct+1]=ae;ct[#ct+1]=ax;ct[#ct+1]=ad;if a_%aT==0 then aY=true end;if fuelX~=0 and fuelY~=0 then DrawTank(ct,aY,fuelX,"Atmospheric ","ATMO",aM,aW,aX)DrawTank(ct,aY,fuelX+100,"Space fuel t","SPACE",aN,aU,aV)DrawTank(ct,aY,fuelX+200,"Rocket fuel ","ROCKET",aO,aR,aS)end;if aY then aY=false;a_=0 end;a_=a_+1;DrawVerticalSpeed(ct,cc)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if cB then DrawRollLines(ct,centerX,centerY,dQ,dY,cB)DrawArtificialHorizon(ct,dR,dQ,centerX,centerY,cB,d(getRelativeYaw(bd)),bS)else DrawRollLines(ct,centerX,centerY,dM,dY,cB)DrawArtificialHorizon(ct,cz,dM,centerX,centerY,cB,d(dM),bS)end;DrawAltitudeDisplay(ct,cc,cB)DrawPrograde(ct,bd,bS,centerX,centerY)end end;DrawThrottle(ct,dK,dT,dV)DrawSpeed(ct,dU)DrawWarnings(ct)DisplayOrbitScreen(ct)if screen_2 then local cg=vec3(core.getConstructWorldPos())local bY=960+cg.x/b2;local bZ=450+cg.y/b3;screen_2.moveContent(b4,(bY-80)/19.2,(bZ-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(ct)if not w then t=PvPR;v=PvPG;u=PvPB else t=SafeR;v=SafeG;u=SafeB end;as=[[rgb(]]..d(t+0.5)..","..d(v+0.5)..","..d(u+0.5)..[[)]]at=[[rgb(]]..d(t*0.9+0.5)..","..d(v*0.9+0.5)..","..d(u*0.9+0.5)..[[)]]local d_=as;local e0=at;local e1=as;local e2=at;if IsInFreeLook()and not brightHud then d_=[[rgb(]]..d(t*0.4+0.5)..","..d(v*0.4+0.5)..","..d(u*0.3+0.5)..[[)]]e0=[[rgb(]]..d(t*0.3+0.5)..","..d(v*0.3+0.5)..","..d(u*0.2+0.5)..[[)]]end;ct[#ct+1]=e([[ ",ResolutionX,ResolutionY)cr[#cr+1]=b4;cr[#cr+1]=ip;cr[#cr+1]=""bd=true;cr[#cr+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(cr,"")system.setScreen(content)elseif be then local ip=table.concat(cr,"")cr={}cr[#cr+1]=e("",ResolutionX,ResolutionY)cr[#cr+1]=b4;cr[#cr+1]=ip;cr[#cr+1]=""end;if not bd then cr[#cr+1]=e([[]],E,F,ac,ad)end else CheckButtons()end else if not V and o()==0 then CheckButtons()if af>DeadZone then DrawCursorLine(cr)end else SetButtonContains()DrawButtons(cr)end;cr[#cr+1]=e([[]],E,F,ac,ad)end;cr[#cr+1]=[[]]content=table.concat(cr,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end elseif im=="apTick"then bg=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())ap=j()>0;local bD=system.getTime()local iq=bD-bo;bo=bD;local cu=vec3(core.getConstructWorldOrientationForward())local cv=vec3(core.getConstructWorldOrientationRight())local ir=vec3(core.getConstructWorldOrientationUp())local cw=vec3(core.getWorldVertical())local is=vec3(core.getConstructWorldPos())local it=core.getVelocity()local dG=getRoll(cw,cu,cv)local dH=dG/180*math.pi;local dI=math.cos(dH)local dJ=math.sin(dH)local cx=getPitch(cw,cu,cv)local iu=getPitch(cw,cu,cv*dI+ir*dJ)local iv=-math.deg(cN(ir,bh,cu))local iw=math.deg(cN(cv,bh,cu))bn=ap and iv<-YawStallAngle or iv>YawStallAngle or iw<-PitchStallAngle or iw>PitchStallAngle;bl=system.getMouseDeltaX()bm=system.getMouseDeltaY()if InvertMouse and not V then bm=-bm end;P=0;T=0;O=0;bh=vec3(core.getWorldVelocity())bi=vec3(bh):len()sys=b9[0]planet=sys:closestBody(core.getConstructWorldPos())kepPlanet=bc(planet)orbit=kepPlanet:orbitalParameters(core.getConstructWorldPos(),bh)am=hoverDetectGround()local bN=planet:getGravity(core.getConstructWorldPos()):len()*n()bp=0;bb=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]w,x,y,_=safeZone(is)if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then ac=screen_1.getMouseX()*ResolutionX;ad=screen_1.getMouseY()*ResolutionY elseif system.isViewLocked()==0 then if o()==1 and V then if not bd then ac=ac+bl;ad=ad+bm end else ac=0;ad=0 end else ac=ac+bl;ad=ad+bm;af=math.sqrt(ac*ac+ad*ad)if not V and o()==0 then if userControlScheme=="virtual joystick"then if ac>0 and ac>DeadZone then P=P-(ac-DeadZone)*MouseXSensitivity elseif ac<0 and ac0 and ad>DeadZone then O=O-(ad-DeadZone)*MouseYSensitivity elseif ad<0 and ad8334;if bi>SpaceSpeedLimit/3.6 and not ap and not Autopilot and not ix then W="Space Speed Engine Shutoff reached"if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0 end;if not ix and LastIsWarping then if not BrakeIsOn then BrakeToggle()end;if Autopilot then ToggleAutopilot()end end;LastIsWarping=ix;if ap and j()>0.09 then if bi>br/3.6 and not AtmoSpeedAssist and not au then BrakeIsOn=true;au=true elseif not AtmoSpeedAssist and au then if bi
85)and bi>=br/3.6-1 then BrakeIsOn=false;ProgradeIsOn=false;J=true;aj=false;al=true;Autopilot=false;BeginReentry()else if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,math.floor(br))z=0 end elseif bi>I then AlignToWorldVector(vec3(bh),0.01)end end;if RetrogradeIsOn then if ap then RetrogradeIsOn=false elseif bi>I then AlignToWorldVector(-vec3(bh))end end;if not ProgradeIsOn and aj then if j()==0 then J=true;BeginReentry()aj=false;al=true else aj=false;ToggleAutopilot()end end;local ed=vec3(core.getWorldVertical())*-1;local eb=bh.x*ed.x+bh.y*ed.y+bh.z*ed.z;if al and(aqHoldAltitude-200)and bi*3.6>br-100 and math.abs(eb)<20 and j()>=0.1 and(CustomTarget.position-is):len()>2000+aq then ToggleAutopilot()al=false end;if Autopilot and j()==0 and not aj then local iz=AutopilotTargetCoords;local iA=false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then AutopilotRealigned=true;local iB=(CustomTarget.position-a7.center):normalize()local iC=iB:project_on_plane((a7.center-is):normalize()):normalize()local iD=a7.center+iC*(a7.radius+AutopilotTargetOrbit)local iE=CustomTarget.position+(CustomTarget.position-a7.center):normalize()*(AutopilotTargetOrbit-a7:getAltitude(CustomTarget.position))if not TargetSet then if(is-iD):len()<(is-iE):len()then iz=iD;AutopilotTargetCoords=iz else iz=CustomTarget.position+(CustomTarget.position-a7.center):normalize()*(AutopilotTargetOrbit-a7:getAltitude(CustomTarget.position))AutopilotTargetCoords=iz end;local cy=zeroConvertToMapPosition(a7,AutopilotTargetCoords)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)iA=true;TargetSet=true end;AutopilotPlanetGravity=0 elseif CustomTarget~=nil and CustomTarget.planetname=="Space"then AutopilotPlanetGravity=0;iA=true;TargetSet=true;AutopilotRealigned=true;iz=CustomTarget.position+(is-CustomTarget.position)*AutopilotTargetOrbit elseif CustomTarget==nil then AutopilotPlanetGravity=0;if not TargetSet then local iB=(is+bh*100000-a7.center):normalize()local iC=iB:project_on_plane((a7.center-is):normalize()):normalize()if iC:len()<1 then iB=(is+vec3(core.getConstructWorldOrientationForward())*100000-a7.center):normalize()iC=iB:project_on_plane((a7.center-is):normalize()):normalize()end;iz=a7.center+iC*(a7.radius+AutopilotTargetOrbit)AutopilotTargetCoords=iz;TargetSet=true;iA=true;AutopilotRealigned=true;local cy=zeroConvertToMapPosition(a7,AutopilotTargetCoords)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)end end;AutopilotDistance=(vec3(iz)-vec3(core.getConstructWorldPos())):len()local fa,fb,fc=b9:getPlanetarySystem(0):castIntersections(is,bh:normalize(),function(fd)if fd.noAtmosphericDensityAltitude>0 then return fd.radius+fd.noAtmosphericDensityAltitude else return fd.radius+fd.surfaceMaxAltitude*1.5 end end)local fe=fb;if fc~=nil and fb~=nil then fe=math.min(fc,fb)end;if fe~=nil and fe300 and AutopilotAccelerating then local ds=vec3(iz)-vec3(core.getConstructWorldPos())local iG=utils.clamp(math.deg(cN(ir,bh:normalize(),ds:normalize()))*bi/500,-90,90)local iH=utils.clamp(math.deg(cN(cv,bh:normalize(),ds:normalize()))*bi/500,-90,90)if math.abs(iG)<20 and math.abs(iH)<20 then iG=iG*2;iH=iH*2 end;if math.abs(iG)<2 and math.abs(iH)<2 then iG=iG*2;iH=iH*2 end;local iv=-math.deg(cN(ir,cu,bh:normalize()))local iw=-math.deg(cN(cv,cu,bh:normalize()))if apPitchPID==nil then apPitchPID=pid.new(2*0.01,0,2*0.1)end;apPitchPID:inject(iH-iw)local iI=utils.clamp(apPitchPID:get(),-1,1)O=O+iI;if apYawPID==nil then apYawPID=pid.new(2*0.01,0,2*0.1)end;apYawPID:inject(iG-iv)local iJ=utils.clamp(apYawPID:get(),-1,1)P=P+iJ;iA=true;if math.abs(iG)>2 or math.abs(iH)>2 then AutopilotStatus="Adjusting Trajectory"else AutopilotStatus="Accelerating"end end;if iF=MaxGameVelocity or fC==0 and G then AutopilotAccelerating=false;AutopilotStatus="Cruising"AutopilotCruising=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0 end;if AutopilotDistance<=a1 then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;G=false end elseif AutopilotBraking then if AutopilotStatus~="Orbiting to Target"then BrakeIsOn=true;S=1 end;if TurnBurn then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,100)z=1 end;local _,iK=bc(a7):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)local ds,iL,iM;if CustomTarget~=nil then ds=CustomTarget.position-is;iL=planet:getAltitude(CustomTarget.position)iM=math.sqrt(ds:len()^2-(aq-iL)^2)end;if CustomTarget~=nil and CustomTarget.planetname=="Space"and bi<50 then W="Autopilot complete, arrived at space location"AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"elseif CustomTarget~=nil and CustomTarget.planetname~="Space"and bi<=iK and(orbit.apoapsis==nil or orbit.periapsis==nil or orbit.apoapsis.altitude<=0 or orbit.periapsis.altitude<=0)then W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;G=false;ProgradeIsOn=true;aj=true;local cy=zeroConvertToMapPosition(a7,AutopilotTargetCoords)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)elseif orbit.periapsis~=nil and orbit.periapsis.altitude>0 and orbit.eccentricity<1 then AutopilotStatus="Circularizing"local _,iK=bc(a7):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)if bi<=iK then if CustomTarget~=nil then if bh:normalize():dot(ds:normalize())>0.4 then AutopilotStatus="Orbiting to Target"if not WaypointSet then BrakeIsOn=false;local cy=zeroConvertToMapPosition(a7,CustomTarget.position)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)WaypointSet=true end else W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;G=false;ProgradeIsOn=true;aj=true;BrakeIsOn=false;local cy=zeroConvertToMapPosition(a7,CustomTarget.position)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)WaypointSet=false end else BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"W="Autopilot completed, orbit established"S=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;G=false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then ProgradeIsOn=true;aj=true end end end end elseif AutopilotCruising then if AutopilotDistance<=a1 then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true end;local fC=unit.getThrottle()if AtmoSpeedAssist then fC=z end;if fC>0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if iy then if not AutopilotRealigned and CustomTarget==nil or not AutopilotRealigned and CustomTarget~=nil and CustomTarget.planetname~="Space"then if not aj then AutopilotTargetCoords=vec3(a7.center)+(AutopilotTargetOrbit+a7.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()end;AutopilotRealigned=true elseif iy then AutopilotAccelerating=true;AutopilotStatus="Accelerating"if not G then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,AutopilotInterplanetaryThrottle)z=round(AutopilotInterplanetaryThrottle,2)G=true;BrakeIsOn=false end end end end elseif Autopilot and(CustomTarget~=nil and CustomTarget.planetname~="Space"and j()>0)then W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"S=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;G=false;ProgradeIsOn=true;aj=true;local cy=zeroConvertToMapPosition(a7,CustomTarget.position)cy="::pos{"..cy.systemId..","..cy.bodyId..","..cy.latitude..","..cy.longitude..","..cy.altitude.."}"system.setWaypoint(cy)end;if U then bf=true;local iH=0;local ce=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local iN=ce-vec3(core.getConstructWorldPos())local iO=vec3(iN):project_on(vec3(core.getConstructWorldOrientationForward())):len()local iP=vec3(iN):project_on(vec3(core.getConstructWorldOrientationRight())):len()local af=math.sqrt(iO*iO+iP*iP)AlignToWorldVector(iN:normalize())local iQ=40;local iR=afiT then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(iH-cx)local iI=pitchPID:get()O=iI end end;if VertTakeOff then Autopilot=false;AltitudeHold=false;if VertTargetPlanet==nil then VertTargetPlanet=planet end;local iU=-vec3(core.getWorldVertical()):dot(vec3(core.getWorldVelocity()))local iV=nil;if j()>0.08 then iV=0;bf=true;BrakeIsOn=false;ab=ab+1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,1)elseif j()<0.08 and j()>0 then ab=0;Nav.axisCommandManager:activateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,0)iV=36;if iU<10 then BrakeIsOn=true;S=1 else BrakeIsOn=false end;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,3500)else if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,0)if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;z=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical,0)BrakeIsOn=true;S=1;W="Takeoff completed. Parking."ToggleAutoTakeoff()end;if iV~=nil then if vTpitchPID==nil then vTpitchPID=pid.new(2*0.01,0,2*0.1)end;local iW=utils.clamp(iV-iu,-PitchStallAngle*0.85,PitchStallAngle*0.85)vTpitchPID:inject(iW)local iX=utils.clamp(vTpitchPID:get(),-1,1)O=iX end end;if IntoOrbit then local iU=-vec3(core.getWorldVertical()):dot(vec3(core.getWorldVelocity()))local iY,iK=bc(OrbitTargetPlanet):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-OrbitTargetPlanet.center):len()-OrbitTargetPlanet.radius)local iZ=getRoll(cw,cu,cv)if not OrbitTargetSet then if OrbitTargetPlanet.hasAtmosphere then OrbitTargetOrbit=math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1)+OrbitTargetPlanet.noAtmosphericDensityAltitude)else OrbitTargetOrbit=math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1)+OrbitTargetPlanet.surfaceMaxAltitude)end;OrbitTargetSet=true end;if orbit.periapsis~=nil and orbit.eccentricity<1 and aq>OrbitTargetOrbit and aq0 then if orbit.apoapsis~=nil then if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;if orbit.periapsis.altitude>OrbitTargetOrbit*0.9 and orbit.periapsis.altitudeorbit.periapsis.altitude and orbit.apoapsis.altitude<=orbit.periapsis.altitude*1.35 then BrakeIsOn=false;z=0;bt=0;bu=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical,0)OrbitAchieved=true;if iu>2 or iu<-2 then bv=0 else W="Orbit established"bs=nil;by=false;OrbitTargetSet=false;OrbitTargetPlanet=nil;bf=autoRollPreference;ToggleIntoOrbit()end else bs="Adjusting Orbit"by=true;if orbit.periapsis.altitudeorbit.periapsis.altitude*1.25 then if bi+10>iK then if iU>15 then bv=-80;bt=0.5;BrakeIsOn=false elseif iU<-15 then bv=80;bt=0.5;BrakeIsOn=false else bt=0;BrakeIsOn=true end elseif bi-10orbit.periapsis.altitude*1.25 then bt=0;BrakeIsOn=true elseif orbit.periapsis.altitude0 and iu<=bv+3 and iu>=bv-3 then z=bt;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,bt)elseif not OrbitAchieved then z=0.05;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0.05)end else if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()end;local i_=iY%50;local j0=0;if i_>0 then j0=iY-i_+50 else j0=iY end;BrakeIsOn=false;bu=j0*2.5;if not bx then local j1=false;local j2=false;if aq=bv-1 then j1=true else j1=false end;if iZ<=bw+1 and iZ>=bw-1 then j2=true else j2=false end;if j1 and j2 then bv=nil;bw=nil;bx=true end else if aq=OrbitTargetOrbit*0.8 and aq=OrbitTargetOrbit*1.01 and aqOrbitTargetOrbit*1.5 then bv=-80;bs="Reentering orbital corridor"end end;Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,bu)end;if bv~=nil then if OrbitPitchPID==nil then OrbitPitchPID=pid.new(2*0.01,0,2*0.1)end;local j3=bv-iu;OrbitPitchPID:inject(j3)local j4=utils.clamp(OrbitPitchPID:get(),-0.5,0.5)O=j4 end;if bw~=nil then if iu<85 then local j5=math.max(autoRollFactor,0.01)/4;if OrbitRollPID==nil then OrbitRollPID=pid.new(j5*0.01,0,j5*0.1)end;local j6=bw-iZ;OrbitRollPID:inject(j6)local j7=utils.clamp(OrbitRollPID:get(),-0.5,0.5)T=j7 end end elseif CancelIntoOrbit then BrakeIsOn=true;S=1;W="Orbitting cancelled, parking"OrbitTargetSet=false;OrbitTargetPlanet=nil;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;z=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical,0)CancelIntoOrbit=false end;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local dT=unit.getClosestPlanetInfluence()>0;local j8=HoldAltitude-aq;local j9=500+bi;local ja=1;if AutoTakeoff then ja=utils.clamp(bi/100,0.1,1)end;local iH=(utils.smoothstep(j8,-j9,j9)-0.5)*2*MaxPitch*ja;if not Reentry and not aj and not VectorToTarget and cu:dot(bh:normalize())<0.99 then iH=(utils.smoothstep(j8,-j9*utils.clamp(20-19*j()*10,1,20),j9*utils.clamp(20-19*j()*10,1,20))-0.5)*2*MaxPitch*utils.clamp(2-j()*10,1,2)*ja end;if not AltitudeHold then iH=0 end;if LockPitch~=nil then if dT then iH=LockPitch else LockPitch=nil end end;bf=true;local jb=O;if Reentry then local ReentrySpeed=math.floor(br)local jc,jd=ba.computeDistanceAndTime(bi,ReentrySpeed/3.6,n(),0,0,LastMaxBrake-planet.gravity*9.8*n())local je=aq-(planet.noAtmosphericDensityAltitude+5000)if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and aq>planet.noAtmosphericDensityAltitude+5000 and bi<=ReentrySpeed/3.6 and bi>ReentrySpeed/3.6-10 and math.abs(bh:normalize():dot(cu))>0.9 then Nav.control.cancelCurrentControlMasterMode()z=0 elseif Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle and(jc>-1 and je<=jc or aq<=planet.noAtmosphericDensityAltitude+5000)then BrakeIsOn=true else BrakeIsOn=false end;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=ReentrySpeed then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,ReentrySpeed)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if not J then iH=-80;if j()>0.02 then W="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;iH=0;bf=autoRollPreference end elseif planet.noAtmosphericDensityAltitude>0 and aq>planet.noAtmosphericDensityAltitude+5000 then bf=true elseif aq<=planet.noAtmosphericDensityAltitude+5000 then if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,ReentrySpeed)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==br then J=false;Reentry=false;bf=true end end end;if bi>I and not ak and not VectorToTarget and not BrakeLanding and ForceAlignment then AlignToWorldVector(vec3(bh))end;if(VectorToTarget or ak)and AutopilotTargetIndex>0 and j()>0.01 then local ds;if CustomTarget~=nil then ds=CustomTarget.position-vec3(core.getConstructWorldPos())else ds=a7.center-is end;local ir=vec3(core.getConstructWorldOrientationUp())local iG=math.deg(cN(cw:normalize(),bh,ds))*2;local jf=math.rad(math.abs(dG))if bi>minRollVelocity and j()>0.01 then local jg=utils.clamp(90-iH*2,-90,90)bp=utils.clamp(iG*2,-jg,jg)local jh=iG;iG=utils.clamp(utils.clamp(iG,-YawStallAngle*0.85,YawStallAngle*0.85)*math.cos(jf)+4*(iu-iH)*math.sin(math.rad(dG)),-YawStallAngle*0.85,YawStallAngle*0.85)iH=utils.clamp(utils.clamp(iH*math.cos(jf),-PitchStallAngle*0.85,PitchStallAngle*0.85)+math.abs(utils.clamp(math.abs(jh)*math.sin(jf),-PitchStallAngle*0.85,PitchStallAngle*0.85)),-PitchStallAngle*0.85,PitchStallAngle*0.85)else bp=0;iG=utils.clamp(iG,-YawStallAngle*0.85,YawStallAngle*0.85)end;local ji=iv-iG;if not bn and bi>minRollVelocity and j()>0.01 then if yawPID==nil then yawPID=pid.new(2*0.01,0,2*0.1)end;yawPID:inject(ji)local iJ=utils.clamp(yawPID:get(),-1,1)P=P+iJ elseif ap and am>-1 or bi0.01 then if(iv<-YawStallAngle or iv>YawStallAngle)and j()>0.01 then AlignToWorldVector(bh)end;if(iw<-PitchStallAngle or iw>PitchStallAngle)and j()>0.01 then iH=utils.clamp(iu-iw,iu-PitchStallAngle*0.85,iu+PitchStallAngle*0.85)end end;if CustomTarget~=nil and not ak then local iL=planet:getAltitude(CustomTarget.position)local je=math.sqrt(ds:len()^2-(aq-iL)^2)local jj=LastMaxBrakeInAtmo;if jj then jj=jj*utils.clamp(bi/100,0.1,1)*j()else jj=LastMaxBrake end;if j()<0.01 then jj=LastMaxBrake else end;local eb=bh.x*ed.x+bh.y*ed.y+bh.z*ed.z;local jk=bh:len()-math.abs(eb)local jl=vec3(core.getWorldAirFrictionAcceleration())local jm=math.sqrt(jl:len()-jl:project_on(ed):len())*n()if bi>100 then a1,a2=ba.computeDistanceAndTime(bi,100,n(),0,0,jj+jm)local jn,jo=ba.computeDistanceAndTime(100,0,n(),0,0,jj/2)a1=a1+jn else a1,a2=ba.computeDistanceAndTime(bi,0,n(),0,0,jj/2)end;StrongBrakes=true;if not ak and je<=a1+bi*iq/2 and(bh:project_on_plane(cw):normalize():dot(ds:project_on_plane(cw):normalize())>0.99 or VectorStatus=="Finalizing Approach")then VectorStatus="Finalizing Approach"if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0;if AltitudeHold then ToggleAltitudeHold()VectorToTarget=true end;BrakeIsOn=true elseif not AutoTakeoff then BrakeIsOn=false end;if VectorStatus=="Finalizing Approach"and(jk<0.1 or je<0.1 or LastDistanceToTarget~=nil and LastDistanceToTarget0.01 and am==-1 and bi>minRollVelocity and VectorStatus~="Finalizing Approach"then AlignToWorldVector(bh)iH=utils.clamp(iu-iw,iu-PitchStallAngle*0.85,iu+PitchStallAngle*0.85)end;O=jb;local fL=-1;local iT=0.1;if BrakeLanding then iH=0;local eb=bh.x*ed.x+bh.y*ed.y+bh.z*ed.z;local jp=false;local jq=30;if bb~=nil and bb>0 then local jm=0;local dM=utils.clamp(j(),0.4,2)local jj=LastMaxBrakeInAtmo*utils.clamp(bi/100,0.1,1)*dM;local jr=bb*dM+jj+jm-bN;local js=jj+jm-bN;local jt=jj/2+jm-bN;local ju=bi-math.sqrt(math.abs(jt/2)*20/(0.5*n()))*utils.sign(jt)if ju<0 then ju=0 end;local jv;if bi>100 then local jw,_=ba.computeDistanceAndTime(bi,100,n(),0,0,jj)local jx,_=ba.computeDistanceAndTime(100,0,n(),0,0,math.sqrt(jj))jv=jw+jx else jv=ba.computeDistanceAndTime(bi,0,n(),0,0,math.sqrt(jj))end;if jv<20 then BrakeIsOn=false else local jy=0;if ju>100 then local jz,_=ba.computeDistanceAndTime(ju,100,n(),0,0,jr)local jA,_=ba.computeDistanceAndTime(100,0,n(),0,0,bb*dM+math.sqrt(jj)+jm-bN)jy=jz+jA else jy,_=ba.computeDistanceAndTime(ju,0,n(),0,0,bb*dM+math.sqrt(jj)+jm-bN)end;jy=(jy+15+bi*iq)*1.1;local jB=CustomTarget~=nil and planet:getAltitude(CustomTarget.position)>0 and CustomTarget.safe;if jB then local iL=planet:getAltitude(CustomTarget.position)local jC=aq-iL-100;local ds=CustomTarget.position-vec3(core.getConstructWorldPos())local iM=math.sqrt(ds:len()^2-(aq-iL)^2)if iM>100 then jB=false elseif jC<=jy or jy==-1 then BrakeIsOn=true;jp=true else BrakeIsOn=false;jp=true end end;if not jB and CalculateBrakeLandingSpeed then if jy>=jq then BrakeIsOn=true else BrakeIsOn=false end;jp=true end end end;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)fL=am;if fL>-1 then bf=autoRollPreference;if bi<1 or bh:normalize():dot(cw)<0 then BrakeLanding=false;AltitudeHold=false;GearExtended=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)ab=0;BrakeIsOn=true else BrakeIsOn=true end elseif StrongBrakes and bh:normalize():dot(-ed)<0.999 then BrakeIsOn=true elseif eb<-brakeLandingRate and not jp then BrakeIsOn=true elseif not jp then BrakeIsOn=false end end;if AutoTakeoff or ak then local fa,fc,fb=b9:getPlanetarySystem(0):castIntersections(is,(AutopilotTargetCoords-is):normalize(),function(fd)return fd.radius+fd.noAtmosphericDensityAltitude end)if math.abs(iH)<15 and aq/HoldAltitude>0.75 then AutoTakeoff=false;if not ak then if Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end elseif ak and bi-1;local jE=cx;if(VectorToTarget or ak)and not jD and bi>minRollVelocity and j()>0.01 then local jf=math.rad(math.abs(dG))jE=cx*math.abs(math.cos(jf))+iw*math.sin(jf)end;local jF=utils.clamp(iH-jE,-PitchStallAngle*0.85,PitchStallAngle*0.85)if j()<0.01 and VectorToTarget then jF=utils.clamp(iH-jE,-85,MaxPitch)elseif j()<0.01 then jF=utils.clamp(iH-jE,-MaxPitch,MaxPitch)end;if math.abs(dG)<5 or VectorToTarget or BrakeLanding or jD or AltitudeHold then if pitchPID==nil then pitchPID=pid.new(5*0.01,0,5*0.1)end;pitchPID:inject(jF)local iI=pitchPID:get()O=O+iI end end;X=orbit.eccentricity;if antigrav and not ExternalAGG and aq<200000 then if AntigravTargetAltitude==nil or AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;if desiredBaseAltitude~=AntigravTargetAltitude then desiredBaseAltitude=AntigravTargetAltitude;antigrav.setBaseAltitude(desiredBaseAltitude)end end;if AchieveOrbit then local jG=1000;if planet.name~="Space"then if planet.hasAtmosphere then jG=math.floor(planet.radius*(TargetOrbitRadius-1)+planet.noAtmosphericDensityAltitude)else jG=math.floor(planet.radius*(TargetOrbitRadius-1)+planet.surfaceMaxAltitude)end else jG=1000 end;local _,iK=bc(planet):escapeAndOrbitalSpeed((is-planet.center):len()-planet.radius)bf=true;local jH;if OrbitToTarget and CustomTarget~=nil then jH=(target.position-is):normalize():project_on_plane(cw):normalize()else jH=cu:project_on_plane(cw):normalize()end;jH=jH*iK;jH=(jH+-cw*(aq-jG)):normalize()*iK end end end;function script.onFlush()if antigrav and not ExternalAGG then if antigrav.getState()==0 and antigrav.getBaseAltitude()~=AntigravTargetAltitude then antigrav.setBaseAltitude(AntigravTargetAltitude)end end;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle and D then z=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)D=false elseif Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and not D then z=0;D=true end;pitchSpeedFactor=math.max(pitchSpeedFactor,0.01)yawSpeedFactor=math.max(yawSpeedFactor,0.01)rollSpeedFactor=math.max(rollSpeedFactor,0.01)torqueFactor=math.max(torqueFactor,0.01)brakeSpeedFactor=math.max(brakeSpeedFactor,0.01)brakeFlatFactor=math.max(brakeFlatFactor,0.01)autoRollFactor=math.max(autoRollFactor,0.01)turnAssistFactor=math.max(turnAssistFactor,0.01)local jI=utils.clamp(N+O+system.getControlDeviceForwardInput(),-1,1)local jJ=utils.clamp(Q+T+system.getControlDeviceYawInput(),-1,1)local jK=utils.clamp(R+P-system.getControlDeviceLeftRightInput(),-1,1)local jL=S;local jM=vec3(core.getWorldVertical())if jM==nil or jM:len()==0 then jM=(planet.center-vec3(core.getConstructWorldPos())):normalize()end;local jN=vec3(core.getConstructWorldOrientationUp())local jO=vec3(core.getConstructWorldOrientationForward())local jP=vec3(core.getConstructWorldOrientationRight())local jQ=vec3(core.getWorldVelocity())local jR=vec3(core.getWorldVelocity()):normalize()local jS=getRoll(jM,jO,jP)local jT=math.abs(jS)local jU=utils.sign(jS)local j=j()local jV=vec3(core.getWorldAngularVelocity())local jW=jI*pitchSpeedFactor*jP+jJ*rollSpeedFactor*jO+jK*yawSpeedFactor*jN;if jM:len()>0.01 and(j>0.0 or ProgradeIsOn or Reentry or aj or AltitudeHold)then local dG=getRoll(jM,jO,jP)local dH=dG/180*math.pi;local dI=math.cos(dH)local dJ=math.sin(dH)local iu=getPitch(jM,jO,jP*dI+jN*dJ)if bf==true and math.abs(bp-jS)>autoRollRollThreshold and jJ==0 and math.abs(iu)<85 then local jX=bp;local j5=autoRollFactor;if j==0 then j5=j5/4;bp=0;jX=0 end;if rollPID==nil then rollPID=pid.new(j5*0.01,0,j5*0.1)end;rollPID:inject(jX-jS)local jY=rollPID:get()jW=jW+jY*jO end end;if jM:len()>0.01 and j>0.0 then local jZ=20.0;if turnAssist==true and jT>jZ and jI==0 and jK==0 then local j_=turnAssistFactor*0.1;local k0=turnAssistFactor*0.025;local k1=(jT-jZ)/(180-jZ)*180;local k2=0;if k1<90 then k2=k1/90 elseif k1<180 then k2=(180-k1)/90 end;k2=k2*k2;local k3=-jU*k0*(1.0-k2)local k4=j_*k2;jW=jW+k4*jP+k3*jN end end;local k5=1;local k6=0;local k7=1;if system.getMouseWheel()>0 then if AltIsOn then if j>0 or Reentry then br=utils.clamp(br+speedChangeLarge,0,AtmoSpeedLimit)elseif Autopilot then MaxGameVelocity=utils.clamp(MaxGameVelocity+speedChangeLarge/3.6*100,0,8333.00)end;H=false else z=round(utils.clamp(z+speedChangeLarge/100,-1,1),2)end elseif system.getMouseWheel()<0 then if AltIsOn then if j>0 or Reentry then br=utils.clamp(br-speedChangeLarge,0,AtmoSpeedLimit)elseif Autopilot then MaxGameVelocity=utils.clamp(MaxGameVelocity-speedChangeLarge/3.6*100,0,8333.00)end;H=false else z=round(utils.clamp(z-speedChangeLarge/100,-1,1),2)end end;A=0;local eb=-jM:dot(jQ)if ap and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then if throttlePID==nil then throttlePID=pid.new(0.5,0,1)end;throttlePID:inject(br/3.6-jQ:dot(jO))local k8=throttlePID:get()C=utils.clamp(k8,-1,1)if C0.005 then B=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,utils.clamp(C,0.01,1))else B=false;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)end;if brakePID==nil then brakePID=pid.new(1*0.01,0,1*0.1)end;brakePID:inject(jQ:len()-br/3.6)local k9=utils.clamp(brakePID:get(),0,1)if j>0 and eb<-80 or j>0.005 then A=k9 end;if A>0 then if B and C==0.01 then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)end else C=utils.clamp(C,0.01,1)end;local ka=''local kb=vec3()local kc=composeAxisAccelerationFromTargetSpeedV(axisCommandId.vertical,ab*1000)Nav:setEngineForceCommand("vertical airfoil , vertical ground ",kc,k6)local kd='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then kd=kd..ExtraLongitudeTags end;local ke=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)local kf=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kd,axisCommandId.longitudinal)local kg=composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral,LeftAmount*1000)ka=ka..' , '.."lateral airfoil , lateral ground "kb=kb+kg;if kb:len()>constants.epsilon then Nav:setEngineForceCommand(ka,kb,k6,'','','',k7)end;Nav:setEngineForceCommand(kd,kf,k5)local kh='thrust analog vertical fueled 'local ki='thrust analog lateral fueled 'if ExtraLateralTags~="none"then ki=ki..ExtraLateralTags end;if ExtraVerticalTags~="none"then kh=kh..ExtraVerticalTags end;if ab~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(kh,kc,k5)else Nav:setEngineForceCommand(kh,vec3(),k5)end;if LeftAmount~=0 then Nav:setEngineForceCommand(ki,kg,k5)else Nav:setEngineForceCommand(ki,vec3(),k5)end;if jL==0 then jL=A end;local kj=-jL*(brakeSpeedFactor*jQ+brakeFlatFactor*jR)Nav:setEngineForceCommand('brake',kj)else if AtmoSpeedAssist then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)end;local kj=-jL*(brakeSpeedFactor*jQ+brakeFlatFactor*jR)Nav:setEngineForceCommand('brake',kj)local ka=''local kb=vec3()local kk=false;local kd='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then kd=kd..ExtraLongitudeTags end;local ke=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if ke==axisCommandType.byThrottle then local kf=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kd,axisCommandId.longitudinal)Nav:setEngineForceCommand(kd,kf,k5)elseif ke==axisCommandType.byTargetSpeed then local kf=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)ka=ka..' , '..kd;kb=kb+kf;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then kk=true end end;local ki='thrust analog lateral 'if ExtraLateralTags~="none"then ki=ki..ExtraLateralTags end;local kl=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if kl==axisCommandType.byThrottle then local km=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ki,axisCommandId.lateral)Nav:setEngineForceCommand(ki,km,k5)elseif kl==axisCommandType.byTargetSpeed then local kg=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)ka=ka..' , '..ki;kb=kb+kg end;local kh='thrust analog vertical 'if ExtraVerticalTags~="none"then kh=kh..ExtraVerticalTags end;local kn=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if kn==axisCommandType.byThrottle then local kc=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kh,axisCommandId.vertical)if ab~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(kh,kc,k5,'airfoil','ground','',k7)else Nav:setEngineForceCommand(kh,vec3(),k5)Nav:setEngineForceCommand('airfoil vertical',kc,k5,'airfoil','','',k7)Nav:setEngineForceCommand('ground vertical',kc,k5,'ground','','',k7)end elseif kn==axisCommandType.byTargetSpeed then if ab<0 then Nav:setEngineForceCommand('hover',vec3(),k5)end;local ko=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)ka=ka..' , '..kh;kb=kb+ko end;local g5=unit.getAxisCommandValue(0)if kb:len()>constants.epsilon then if S~=0 or kk or math.abs(jR:dot(jO))<0.8 or bh:len()>g5/3.6 then ka=ka..', brake'end;Nav:setEngineForceCommand(ka,kb,k6,'','','',k7)end end;local kp=torqueFactor*(jW-jV)local kq=vec3(core.getWorldAirFrictionAngularAcceleration())kp=kp-kq;Nav:setEngineTorqueCommand('torque',kp,k5,'airfoil','','',k7)Nav:setBoosterCommand('rocket_engine')if a0 and not VanillaRockets then local bQ=vec3(core.getVelocity()):len()local kr=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local ks=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bQ*3.6>ks*(1-kr)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bQ*3.6=g5*(1-kr)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bQ=g5*(1-kr)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bQ0 or aqHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+Z;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+Z end else AntigravTargetAltitude=desiredBaseAltitude+100 end elseif AltitudeHold then HoldAltitude=HoldAltitude+Y else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)end elseif kt=="groundaltitudedown"then OldButtonMod=Y;OldAntiMod=Z;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-Z;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-Z;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end else AntigravTargetAltitude=desiredBaseAltitude end elseif AltitudeHold then HoldAltitude=HoldAltitude-Y else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)end elseif kt=="option1"then IncrementAutopilotTargetIndex()H=false elseif kt=="option2"then DecrementAutopilotTargetIndex()H=false elseif kt=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;H=false;ToggleWidgets()elseif kt=="option4"then ToggleAutopilot()H=false elseif kt=="option5"then ToggleLockPitch()H=false elseif kt=="option6"then ToggleAltitudeHold()H=false elseif kt=="option7"then wipeSaveVariables()H=false elseif kt=="option8"then ToggleFollowMode()H=false elseif kt=="option9"then if gyro~=nil then gyro.toggle()at=gyro.getState()==1 end;H=false elseif kt=="lshift"then if system.isViewLocked()==1 then V=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then V=true;be=false;bd=false end elseif kt=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif kt=="lalt"then AltIsOn=true;if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif kt=="booster"then if VanillaRockets then Nav:toggleBoosters()elseif not a0 then if not IsRocketOn then Nav:toggleBoosters()IsRocketOn=true end;a0=true else if IsRocketOn then Nav:toggleBoosters()IsRocketOn=false end;a0=false end elseif kt=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()z=0 elseif kt=="speedup"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z+speedChangeLarge/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)end else IncrementAutopilotTargetIndex()end elseif kt=="speeddown"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z-speedChangeLarge/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)end else DecrementAutopilotTargetIndex()end elseif kt=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(kt)if kt=="forward"then N=0 elseif kt=="backward"then N=0 elseif kt=="left"then Q=0 elseif kt=="right"then Q=0 elseif kt=="yawright"then R=0 elseif kt=="yawleft"then R=0 elseif kt=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)LeftAmount=0 elseif kt=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)LeftAmount=0 elseif kt=="up"then ab=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif kt=="down"then ab=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif kt=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then Z=OldAntiMod end;if AltitudeHold then Y=OldButtonMod end;H=false elseif kt=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then Z=OldAntiMod end;if AltitudeHold then Y=OldButtonMod end;H=false elseif kt=="lshift"then if system.isViewLocked()==1 then V=false;ac=0;ad=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then V=false;be=false;bd=false end elseif kt=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif kt=="lalt"then if o()==0 and freeLookToggle then if H then if system.isViewLocked()==1 then system.lockView(0)else system.lockView(1)end else H=true end elseif o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(0)end;AltIsOn=false end end;function script.onActionLoop(kt)if kt=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+Z;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+Z end;Z=Z*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude+100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude+Y;Y=Y*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)end elseif kt=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-Z;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-Z;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end;Z=Z*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude-100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude-Y;Y=Y*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)end elseif kt=="speedup"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z+speedChangeSmall/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end end elseif kt=="speeddown"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z-speedChangeSmall/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end end;function script.onInputText(dx)local i;local ku="/commands /setname /G /agg /addlocation /copydatabank"local kv,kw=nil,nil;local kx="Command List:\n/commands \n/setname - Updates current selected saved position name\n/G VariableName newValue - Updates global variable to new value\n".."/G dump - shows all updatable variables with /G\n/agg - Manually set agg target height\n".."/addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572} - adds a saved location by waypoint, not as accurate as making one at location\n".."/copydatabank - copies dbHud databank to a blank databank"i=string.find(dx," ")kv=dx;if i~=nil then kv=string.sub(dx,0,i-1)kw=string.sub(dx,i+1)elseif not string.find(ku,kv)then for g1 in string.gmatch(kx,"([^\n]+)")do c(g1)end;return end;if kv=="/setname"then if kw==nil or kw==""then W="Usage: /setname Newname"return end;if AutopilotTargetIndex>0 and CustomTarget~=nil then UpdatePosition(kw)else W="Select a saved target to rename first"end elseif kv=="/addlocation"then if kw==nil or kw==""or string.find(kw,"::")==nil then W="Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}"return end;i=string.find(kw,"::")local ck=string.sub(kw,1,i-2)local ce=string.sub(kw,i)local q=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local cf='::pos{'..q..','..q..','..q..','..q..','..q..'}'local cg,ch,cb,cc,ca=string.match(ce,cf)local planet=b3[tonumber(cg)][tonumber(ch)]AddNewLocationByWaypoint(ck,planet,ce)W="Added "..ck.." to saved locations,\nplanet "..planet.name.." at "..ce;ae=5 elseif kv=="/agg"then if kw==nil or kw==""then W="Usage: /agg targetheight"return end;kw=tonumber(kw)if kw<1000 then kw=1000 end;AntigravTargetAltitude=kw;W="AGG Target Height set to "..kw elseif kv=="/G"then if kw==nil or kw==""then W="Usage: /G VariableName variablevalue\n/G dump - shows all variables"return end;if kw=="dump"then for bA,bB in pairs(a)do if type(_G[bB])=="boolean"then if _G[bB]==true then c(bB.." true")else c(bB.." false")end elseif _G[bB]==nil then c(bB.." nil")else c(bB.." ".._G[bB])end end;return end;i=string.find(kw," ")local ky=string.sub(kw,0,i-1)local kz=string.sub(kw,i+1)for bA,bB in pairs(a)do if bB==ky then W="Variable "..ky.." changed to "..kz;local kA=type(_G[bB])if kA=="number"then kz=tonumber(kz)elseif kA=="boolean"then if string.lower(kz)=="true"then kz=true else kz=false end end;_G[bB]=kz;return end end;W="No such global variable: "..ky elseif kv=="/copydatabank"then if dbHud_2 then SaveDataBank(true)else W="Databank required to copy databank"end end end;script.onStart() + transform="rotate(-90,]]..bY..[[,]]..bZ..[[)"/>]]ct[#ct+1]=f6 end end end end;function DrawWarnings(ct)ct[#ct+1]=e([[DU Hud Version: %.3f]],ConvertResolutionX(1900),ConvertResolutionY(1070),VERSION_NUMBER)ct[#ct+1]=[[]]if unit.isMouseControlActivated()==1 then ct[#ct+1]=e([[ + Warning: Invalid Control Scheme Detected]],ConvertResolutionX(960),ConvertResolutionY(550))ct[#ct+1]=e([[ + Keyboard Scheme must be selected]],ConvertResolutionX(960),ConvertResolutionY(600))ct[#ct+1]=e([[ + Set your preferred scheme in Lua Parameters instead]],ConvertResolutionX(960),ConvertResolutionY(650))end;local f7=ConvertResolutionX(960)local f8=ConvertResolutionY(860)local f9=ConvertResolutionY(880)local fa=ConvertResolutionY(900)local fb=ConvertResolutionY(960)local fc=ConvertResolutionY(200)local fd=ConvertResolutionY(150)local fe=ConvertResolutionY(960)if o()==1 and not RemoteHud then f8=ConvertResolutionY(135)f9=ConvertResolutionY(155)fa=ConvertResolutionY(175)fc=ConvertResolutionY(115)fd=ConvertResolutionY(95)end;if BrakeIsOn then ct[#ct+1]=e([[Brake Engaged]],f7,f8)elseif A>0 then ct[#ct+1]=e([[Auto-Brake Engaged]],f7,f8,A)end;if am and bi and hoverDetectGround()==-1 then ct[#ct+1]=e([[** STALL WARNING **]],f7,fc+50)end;if aq then ct[#ct+1]=e([[Gyro Enabled]],f7,fe)end;if GearExtended then if M then ct[#ct+1]=e([[Gear Extended]],f7,f9)else ct[#ct+1]=e([[Landed (G: Takeoff)]],f7,f9)end;local dy,dz=getDistanceDisplayString(Nav:getTargetGroundAltitude())ct[#ct+1]=e([[Hover Height: %s]],f7,fa,dy..dz)end;if Z then ct[#ct+1]=e([[ROCKET BOOST ENABLED]],f7,fb+20)end;if antigrav and not ExternalAGG and antigrav.getState()==1 and AntigravTargetAltitude~=nil then if math.abs(an-antigrav.getBaseAltitude())<501 then ct[#ct+1]=e([[AGG On - Target Altitude: %d Singluarity Altitude: %d]],f7,fc+20,d(AntigravTargetAltitude),d(antigrav.getBaseAltitude()))else ct[#ct+1]=e([[AGG On - Target Altitude: %d Singluarity Altitude: %d]],f7,fc+20,d(AntigravTargetAltitude),d(antigrav.getBaseAltitude()))end elseif Autopilot and AutopilotTargetName~="None"then ct[#ct+1]=e([[Autopilot %s]],f7,fc+20,AutopilotStatus)elseif LockPitch~=nil then ct[#ct+1]=e([[LockedPitch: %d]],f7,fc+20,d(LockPitch))elseif U then ct[#ct+1]=e([[Follow Mode Engaged]],f7,fc+20)elseif Reentry then ct[#ct+1]=e([[Re-entry in Progress]],f7,fc+20)end;local ff,fg,fh=b6:getPlanetarySystem(0):castIntersections(vec3(core.getConstructWorldPos()),bd:normalize(),function(fi)if fi.noAtmosphericDensityAltitude>0 then return fi.radius+fi.noAtmosphericDensityAltitude else return fi.radius+fi.surfaceMaxAltitude*1.5 end end)local fj=fg;if fh~=nil and fg~=nil then fj=math.min(fh,fg)end;if AltitudeHold then if AutoTakeoff and not IntoOrbit then local dy,dz=getDistanceDisplayString(HoldAltitude)ct[#ct+1]=e([[Ascent to %s]],f7,fc,dy..dz)if BrakeIsOn then ct[#ct+1]=e([[Throttle Up and Disengage Brake For Takeoff]],f7,fc+50)end else local dy,dz=getDistanceDisplayString2(HoldAltitude)ct[#ct+1]=e([[Altitude Hold: %s]],f7,fc,dy..dz)end end;if VertTakeOff and(antigrav~=nil and antigrav)then if j()>0.1 then ct[#ct+1]=e([[Beginning ascent]],f7,fc)elseif j()<0.09 and j()>0.05 then ct[#ct+1]=e([[Aligning trajectory]],f7,fc)elseif j()<0.05 then ct[#ct+1]=e([[Leaving atmosphere]],f7,fc)end end;if IntoOrbit then if bo~=nil then ct[#ct+1]=e([[%s]],f7,fc,bo)end end;if BrakeLanding then if StrongBrakes then ct[#ct+1]=e([[Brake-Landing]],f7,fc)else ct[#ct+1]=e([[Coast-Landing]],f7,fc)end end;if ProgradeIsOn then ct[#ct+1]=e([[Prograde Alignment]],f7,fc)end;if RetrogradeIsOn then ct[#ct+1]=e([[Retrograde Alignment]],f7,fc)end;if TurnBurn then ct[#ct+1]=e([[Turn & Burn Braking]],f7,fd)elseif fj~=nil and j()==0 then local dy,dz=getDistanceDisplayString(fj)local travelTime=b7.computeTravelTime(be,0,fj)local fk="Collision"if ff.noAtmosphericDensityAltitude>0 then fk="Atmosphere"end;ct[#ct+1]=e([[%s %s In %s (%s)]],f7,fd,ff.name,fk,FormatTimeString(travelTime),dy..dz)end;if VectorToTarget and not IntoOrbit then ct[#ct+1]=e([[%s]],f7,fc+30,VectorStatus)end;ct[#ct+1]=""end;function DisplayOrbitScreen(ct)if orbit~=nil and j()<0.2 and planet~=nil and orbit.apoapsis~=nil and orbit.periapsis~=nil and orbit.period~=nil and orbit.apoapsis.speed>5 and DisplayOrbit then local fl=OrbitMapX;local fm=OrbitMapY;local fn=OrbitMapSize;local fo=4;fm=fm+fo;local fp=15;local bY=fl+fn+fl/2+fo;local bZ=fm+fn/2+5+fo;local fq,fr,fs,ft;fq=fn/4;ft=0;ct[#ct+1]=[[]]ct[#ct+1]=e('',fn+fl*2,fn+fm,fo,fo)if orbit.periapsis~=nil and orbit.apoapsis~=nil then fs=(orbit.apoapsis.altitude+orbit.periapsis.altitude+planet.radius*2)/(fq*2)fr=(planet.radius+orbit.periapsis.altitude+(orbit.apoapsis.altitude-orbit.periapsis.altitude)/2)/fs*(1-orbit.eccentricity)ft=fq-orbit.periapsis.altitude/fs-planet.radius/fs;local fu=""if orbit.periapsis.altitude<=0 then fu='redout'end;ct[#ct+1]=e([[]],fu,fl+fn/2+ft+fo,fm+fn/2+fo,fq,fr)ct[#ct+1]=e('',fl+fn/2+fo,fm+fn/2+fo,planet.radius/fs)end;if orbit.apoapsis~=nil and orbit.apoapsis.speed1 then ct[#ct+1]=e([[]],bY-35,bZ-5,fl+fn/2+fq+ft,bZ-5)ct[#ct+1]=e([[Apoapsis]],bY,bZ)bZ=bZ+fp;local dy,dz=getDistanceDisplayString(orbit.apoapsis.altitude)ct[#ct+1]=e([[%s]],bY,bZ,dy..dz)bZ=bZ+fp;ct[#ct+1]=e([[%s]],bY,bZ,FormatTimeString(orbit.timeToApoapsis))bZ=bZ+fp;ct[#ct+1]=e([[%s]],bY,bZ,getSpeedDisplayString(orbit.apoapsis.speed))end;bZ=fm+fn/2+5+fo;bY=fl-fl/2+10+fo;if orbit.periapsis~=nil and orbit.periapsis.speed1 then ct[#ct+1]=e([[]],bY+35,bZ-5,fl+fn/2-fq+ft,bZ-5)ct[#ct+1]=e([[Periapsis]],bY,bZ)bZ=bZ+fp;local dy,dz=getDistanceDisplayString(orbit.periapsis.altitude)ct[#ct+1]=e([[%s]],bY,bZ,dy..dz)bZ=bZ+fp;ct[#ct+1]=e([[%s]],bY,bZ,FormatTimeString(orbit.timeToPeriapsis))bZ=bZ+fp;ct[#ct+1]=e([[%s]],bY,bZ,getSpeedDisplayString(orbit.periapsis.speed))end;ct[#ct+1]=e([[%s]],fl+fn/2+fo,20+fo,planet.name)if orbit.period~=nil and orbit.periapsis~=nil and orbit.apoapsis~=nil and orbit.apoapsis.speed>1 then local fv=orbit.timeToApoapsis/orbit.period*2*math.pi;local fw=fq*math.cos(fv)local fx=fr*math.sin(fv)ct[#ct+1]=e('',fl+fn/2+fw+ft+fo,fm+fn/2+fx+fo)end;ct[#ct+1]=[[]]end end;function getDistanceDisplayString(ac)local fy=ac>100000;local bD,dz=""if fy then bD,dz=round(ac/1000/200,1),"SU"elseif ac<1000 then bD,dz=round(ac,1),"m"else bD,dz=round(ac/1000,1),"Km"end;return bD,dz end;function getDistanceDisplayString2(ac)local fy=ac>100000;local bD,dz=""if fy then bD,dz=round(ac/1000/200,2)," SU"elseif ac<1000 then bD,dz=round(ac,2)," M"else bD,dz=round(ac/1000,2)," KM"end;return bD,dz end;function getSpeedDisplayString(bS)return d(round(bS*3.6,0)+0.5).." km/h"end;function FormatTimeString(fz)local fA=0;local fB=0;local fC=0;if fz<60 then fz=d(fz)elseif fz<3600 then fA=d(fz/60)fz=d(fz%60)elseif fz<86400 then fB=d(fz/3600)fA=d(fz%3600/60)else fC=d(fz/86400)fB=d(fz%86400/3600)end;if fC>0 then return fC.."d "..fB.."h "elseif fB>0 then return fB.."h "..fA.."m "elseif fA>0 then return fA.."m "..fz.."s"elseif fz>0 then return fz.."s"else return"0s"end end;function getMagnitudeInDirection(dr,fD)dr=vec3(dr)fD=vec3(fD):normalize()local bD=dr*fD;return bD.x+bD.y+bD.z end;function UpdateAutopilotTarget()if AutopilotTargetIndex==0 then AutopilotTargetName="None"a4=nil;CustomTarget=nil;return true end;local fE=AtlasOrdered[AutopilotTargetIndex].index;local fF=b0[0][fE]if fF.center then AutopilotTargetName=fF.name;a4=b6[0][fE]if CustomTarget~=nil then if j()==0 then if system.updateData(widgetMaxBrakeTimeText,widgetMaxBrakeTime)~=1 then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;if system.updateData(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)~=1 then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;if system.updateData(widgetCurBrakeTimeText,widgetCurBrakeTime)~=1 then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;if system.updateData(widgetCurBrakeDistanceText,widgetCurBrakeDistance)~=1 then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;if system.updateData(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)~=1 then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end end;if system.updateData(widgetMaxMassText,widgetMaxMass)~=1 then system.addDataToWidget(widgetMaxMassText,widgetMaxMass)end;if system.updateData(widgetTravelTimeText,widgetTravelTime)~=1 then system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)end;if system.updateData(widgetTargetOrbitText,widgetTargetOrbit)~=1 then system.addDataToWidget(widgetTargetOrbitText,widgetTargetOrbit)end end;CustomTarget=nil else CustomTarget=fF;for _,bC in pairs(b6[0])do if bC.name==CustomTarget.planetname then a4=bC;AutopilotTargetName=CustomTarget.name;break end end;if system.updateData(widgetMaxMassText,widgetMaxMass)~=1 then system.addDataToWidget(widgetMaxMassText,widgetMaxMass)end;if system.updateData(widgetTravelTimeText,widgetTravelTime)~=1 then system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)end end;if CustomTarget==nil then AutopilotTargetCoords=vec3(a4.center)else AutopilotTargetCoords=CustomTarget.position end;if a4.planetname~="Space"then if a4.hasAtmosphere then AutopilotTargetOrbit=math.floor(a4.radius*(TargetOrbitRadius-1)+a4.noAtmosphericDensityAltitude)else AutopilotTargetOrbit=math.floor(a4.radius*(TargetOrbitRadius-1)+a4.surfaceMaxAltitude)end else AutopilotTargetOrbit=1000 end;if CustomTarget~=nil and CustomTarget.planetname=="Space"then AutopilotEndSpeed=0 else _,AutopilotEndSpeed=b9(a4):escapeAndOrbitalSpeed(AutopilotTargetOrbit)end;AutopilotPlanetGravity=0;AutopilotAccelerating=false;AutopilotBraking=false;AutopilotCruising=false;Autopilot=false;AutopilotRealigned=false;AutopilotStatus="Aligning"return true end;function IncrementAutopilotTargetIndex()AutopilotTargetIndex=AutopilotTargetIndex+1;if AutopilotTargetIndex>#AtlasOrdered then AutopilotTargetIndex=0 end;if AutopilotTargetIndex==0 then UpdateAutopilotTarget()else local fE=AtlasOrdered[AutopilotTargetIndex].index;local fF=b0[0][fE]if fF.name=="Space"then IncrementAutopilotTargetIndex()else UpdateAutopilotTarget()end end end;function DecrementAutopilotTargetIndex()AutopilotTargetIndex=AutopilotTargetIndex-1;if AutopilotTargetIndex<0 then AutopilotTargetIndex=#AtlasOrdered end;if AutopilotTargetIndex==0 then UpdateAutopilotTarget()else local fE=AtlasOrdered[AutopilotTargetIndex].index;local fF=b0[0][fE]if fF.name=="Space"then DecrementAutopilotTargetIndex()else UpdateAutopilotTarget()end end end;function GetAutopilotMaxMass()local fG=LastMaxBrakeInAtmo/a4:getGravity(a4.center+vec3(0,0,1)*a4.radius):len()return fG end;function GetAutopilotTravelTime()if not Autopilot then if CustomTarget==nil or CustomTarget.planetname~=planet.name then AutopilotDistance=(a4.center-vec3(core.getConstructWorldPos())):len()else AutopilotDistance=(CustomTarget.position-vec3(core.getConstructWorldPos())):len()end end;local bd=core.getWorldVelocity()local bS=vec3(bd):len()local fH=unit.getThrottle()/100;if AtmoSpeedAssist then fH=z end;local fI,fJ=b7.computeDistanceAndTime(vec3(bd):len(),MaxGameVelocity,n(),Nav:maxForceForward()*fH,warmup,0)local a0,a1;if not TurnBurn then a0,a1=GetAutopilotBrakeDistanceAndTime(MaxGameVelocity)else a0,a1=GetAutopilotTBBrakeDistanceAndTime(MaxGameVelocity)end;local _,fK;if not TurnBurn and bS>0 then _,fK=GetAutopilotBrakeDistanceAndTime(bS)else _,fK=GetAutopilotTBBrakeDistanceAndTime(bS)end;local fL=0;local fM=0;if AutopilotCruising or not Autopilot and bS>5 then fM=b7.computeTravelTime(bS,0,AutopilotDistance)elseif a0+fI0 then return b7.computeDistanceAndTime(bS,AutopilotEndSpeed,n(),0,0,LastMaxBrakeInAtmo-AutopilotPlanetGravity*n())else return 0,0 end end end;function GetAutopilotTBBrakeDistanceAndTime(bS)RefreshLastMaxBrake()return b7.computeDistanceAndTime(bS,AutopilotEndSpeed,n(),Nav:maxForceForward(),warmup,LastMaxBrake-AutopilotPlanetGravity*n())end;function hoverDetectGround()local fO=-1;local fP=-1;if vBooster then fO=vBooster.distance()end;if hover then fP=hover.distance()end;if fO~=-1 and fP~=-1 then if fOProfileTimeMax then ProfileTimeMax=fV end;if fV0 then local g4=g1:find('identifiedConstructs":%[%]')if g4==nil and perisPanelID==nil then af=1;ToggleRadarPanel()end;if g4~=nil and perisPanelID~=nil then ToggleRadarPanel()end;if radarPanelID==nil then ToggleRadarPanel()end;ad=e([[Radar: %i contacts]],g2,g3,#g0)local g5={}for bB,bC in pairs(g0)do if radar_1.hasMatchingTransponder(bC)==1 then table.insert(g5,bC)end end;if#g5>0 then local bZ=ConvertResolutionY(15)local bY=ConvertResolutionX(1370)ad=e([[%sFriendlies In Range]],ad,bY,bZ)for bB,bC in pairs(g5)do bZ=bZ+20;ad=e([[%s%s]],ad,bY,bZ,radar_1.getConstructName(bC))end end else local g6;g6=g1:find('worksInEnvironment":false')if g6 then ad=e([[ + Radar: Jammed]],g2,g3)else ad=e([[ + Radar: No Contacts]],g2,g3)end;if radarPanelID~=nil then af=0;ToggleRadarPanel()end end end end;function DisplayMessage(ct,dy)if dy~="empty"then ct[#ct+1]=[[]]for g7 in string.gmatch(dy,"([^\n]+)")do ct[#ct+1]=e([[%s]],g7)end;ct[#ct+1]=[[]]end;if ab~=0 then unit.setTimer("msgTick",ab)ab=0 end end;function updateDistance()local bL=system.getTime()local bd=vec3(core.getWorldVelocity())local dU=vec3(bd):len()local g8=bL-ap;if dU>1.38889 then dU=dU/1000;local g9=dU*(bL-ap)TotalDistanceTravelled=TotalDistanceTravelled+g9;a5=a5+g9 end;a6=a6+g8;TotalFlightTime=TotalFlightTime+g8;ap=bL end;function composeAxisAccelerationFromTargetSpeedV(ga,gb)local gc=vec3()local gd=vec3()if ga==axisCommandId.longitudinal then gc=vec3(core.getConstructOrientationForward())gd=vec3(core.getConstructWorldOrientationForward())elseif ga==axisCommandId.vertical then gc=vec3(core.getConstructOrientationUp())gd=vec3(core.getConstructWorldOrientationUp())elseif ga==axisCommandId.lateral then gc=vec3(core.getConstructOrientationRight())gd=vec3(core.getConstructWorldOrientationRight())else return vec3()end;local ge=vec3(core.getWorldGravity())local gf=ge:dot(gd)local gg=vec3(core.getWorldAirFrictionAcceleration())local gh=gg:dot(gd)local gi=vec3(core.getVelocity())local gj=gi:dot(gc)local gk=gb*constants.kph2m;if targetSpeedPID2==nil then targetSpeedPID2=pid.new(10,0,10.0)end;targetSpeedPID2:inject(gk-gj)local gl=targetSpeedPID2:get()local gm=(gl-gh-gf)*gd;return gm end;function composeAxisAccelerationFromTargetSpeed(ga,gb)local gc=vec3()local gd=vec3()if ga==axisCommandId.longitudinal then gc=vec3(core.getConstructOrientationForward())gd=vec3(core.getConstructWorldOrientationForward())elseif ga==axisCommandId.vertical then gc=vec3(core.getConstructOrientationUp())gd=vec3(core.getConstructWorldOrientationUp())elseif ga==axisCommandId.lateral then gc=vec3(core.getConstructOrientationRight())gd=vec3(core.getConstructWorldOrientationRight())else return vec3()end;local ge=vec3(core.getWorldGravity())local gf=ge:dot(gd)local gg=vec3(core.getWorldAirFrictionAcceleration())local gh=gg:dot(gd)local gi=vec3(core.getVelocity())local gj=gi:dot(gc)local gk=gb*constants.kph2m;if targetSpeedPID==nil then targetSpeedPID=pid.new(10,0,10.0)end;targetSpeedPID:inject(gk-gj)local gl=targetSpeedPID:get()local gm=(gl-gh-gf)*gd;return gm end;function Atlas()return{[0]={[0]={GM=0,bodyId=0,center={x=0,y=0,z=0},name='Space',planetarySystemId=0,radius=0,hasAtmosphere=false,gravity=0,noAtmosphericDensityAltitude=0,surfaceMaxAltitude=0},[2]={name="Alioth",description="Alioth is the planet selected by the arkship for landfall; it is a typical goldilocks planet where humanity may rebuild in the coming decades. The arkship geological survey reports mountainous regions alongside deep seas and lush forests. This is where it all starts.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9401,atmosphericEngineMaxAltitude=5580,biosphere="Forest",classification="Mesoplanet",bodyId=2,GM=157470826617,gravity=1.0082568597356114,fullAtmosphericDensityMaxAltitude=-10,habitability="High",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=6272,numSatellites=2,positionFromSun=2,center={x=-8,y=-8,z=-126303},radius=126067.8984375,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=3410,surfaceArea=199718780928,surfaceAverageAltitude=200,surfaceMaxAltitude=1100,surfaceMinAltitude=-330,systemZone="High",territories=259472,type="Planet",waterLevel=0,planetarySystemId=0},[21]={name="Alioth Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=21,GM=2118960000,gravity=0.24006116402380084,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=457933,y=-1509011,z=115524},radius=30000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=0,surfaceArea=11309733888,surfaceAverageAltitude=140,surfaceMaxAltitude=200,surfaceMinAltitude=10,systemZone=nil,territories=14522,type="",waterLevel=nil,planetarySystemId=0},[22]={name="Alioth Moon 4",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=22,GM=2165833514,gravity=0.2427018259886451,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=-1692694,y=729681,z=-411464},radius=30330,safeAreaEdgeAltitude=500000,size="L",spaceEngineMinAltitude=0,surfaceArea=11559916544,surfaceAverageAltitude=-15,surfaceMaxAltitude=-5,surfaceMinAltitude=-50,systemZone=nil,territories=14522,type="",waterLevel=nil,planetarySystemId=0},[5]={name="Feli",description="Feli is easily identified by its massive and deep crater. Outside of the crater, the arkship geological survey reports a fairly bland and uniform planet, it also cannot explain the existence of the crater. Feli is particular for having an extremely small atmosphere, allowing life to develop in the deeper areas of its crater but limiting it drastically on the actual surface.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.5488,atmosphericEngineMaxAltitude=66725,biosphere="Barren",classification="Mesoplanet",bodyId=5,GM=16951680000,gravity=0.4801223280476017,fullAtmosphericDensityMaxAltitude=30,habitability="Low",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=78500,numSatellites=1,positionFromSun=5,center={x=-43534464,y=22565536,z=-48934464},radius=41800,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=42800,surfaceArea=21956466688,surfaceAverageAltitude=18300,surfaceMaxAltitude=18500,surfaceMinAltitude=46,systemZone="Low",territories=27002,type="Planet",waterLevel=nil,planetarySystemId=0},[50]={name="Feli Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=50,GM=499917600,gravity=0.11202853997062348,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=-43902841.78,y=22261034.7,z=-48862386},radius=14000,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=0,surfaceArea=2463008768,surfaceAverageAltitude=800,surfaceMaxAltitude=900,surfaceMinAltitude=0,systemZone=nil,territories=3002,type="",waterLevel=nil,planetarySystemId=0},[120]={name="Ion",description="Ion is nothing more than an oversized ice cube frozen through and through. It is a largely inhospitable planet due to its extremely low temperatures. The arkship geological survey reports extremely rough mountainous terrain with little habitable land.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9522,atmosphericEngineMaxAltitude=10480,biosphere="Ice",classification="Hypopsychroplanet",bodyId=120,GM=7135606629,gravity=0.36009174603570127,fullAtmosphericDensityMaxAltitude=-30,habitability="Average",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=17700,numSatellites=2,positionFromSun=12,center={x=2865536.7,y=-99034464,z=-934462.02},radius=44950,safeAreaEdgeAltitude=500000,size="XS",spaceEngineMinAltitude=6410,surfaceArea=25390383104,surfaceAverageAltitude=500,surfaceMaxAltitude=1300,surfaceMinAltitude=250,systemZone="Average",territories=32672,type="Planet",waterLevel=nil,planetarySystemId=0},[121]={name="Ion Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=121,GM=106830900,gravity=0.08802242599860607,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=2472916.8,y=-99133747,z=-1133582.8},radius=11000,safeAreaEdgeAltitude=500000,size="XS",spaceEngineMinAltitude=0,surfaceArea=1520530944,surfaceAverageAltitude=100,surfaceMaxAltitude=200,surfaceMinAltitude=3,systemZone=nil,territories=1922,type="",waterLevel=nil,planetarySystemId=0},[122]={name="Ion Moon 2",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=122,GM=176580000,gravity=0.12003058201190042,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=2995424.5,y=-99275010,z=-1378480.7},radius=15000,safeAreaEdgeAltitude=500000,size="XS",spaceEngineMinAltitude=0,surfaceArea=2827433472,surfaceAverageAltitude=-1900,surfaceMaxAltitude=-1400,surfaceMinAltitude=-2100,systemZone=nil,territories=3632,type="",waterLevel=nil,planetarySystemId=0},[9]={name="Jago",description="Jago is a water planet. The large majority of the planet's surface is covered by large oceans dotted by small areas of landmass across the planet. The arkship geological survey reports deep seas across the majority of the planet with sub 15 percent coverage of solid ground.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9835,atmosphericEngineMaxAltitude=9695,biosphere="Water",classification="Mesoplanet",bodyId=9,GM=18606274330,gravity=0.5041284298678057,fullAtmosphericDensityMaxAltitude=-90,habitability="Very High",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=10900,numSatellites=0,positionFromSun=9,center={x=-94134462,y=12765534,z=-3634464},radius=61590,safeAreaEdgeAltitude=500000,size="XL",spaceEngineMinAltitude=5900,surfaceArea=47668367360,surfaceAverageAltitude=0,surfaceMaxAltitude=1200,surfaceMinAltitude=-500,systemZone="Very High",territories=60752,type="Planet",waterLevel=0,planetarySystemId=0},[100]={name="Lacobus",description="Lacobus is an ice planet that also features large bodies of water. The arkship geological survey reports deep oceans alongside a frozen and rough mountainous environment. Lacobus seems to feature regional geothermal activity allowing for the presence of water on the surface.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.7571,atmosphericEngineMaxAltitude=11120,biosphere="Ice",classification="Psychroplanet",bodyId=100,GM=13975172474,gravity=0.45611622622739767,fullAtmosphericDensityMaxAltitude=-20,habitability="Average",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=12510,numSatellites=3,positionFromSun=10,center={x=98865536,y=-13534464,z=-934461.99},radius=55650,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=6790,surfaceArea=38917074944,surfaceAverageAltitude=800,surfaceMaxAltitude=1660,surfaceMinAltitude=250,systemZone="Average",territories=50432,type="Planet",waterLevel=0,planetarySystemId=0},[102]={name="Lacobus Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=102,GM=444981600,gravity=0.14403669598391783,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=99180968,y=-13783862,z=-926156.4},radius=18000,safeAreaEdgeAltitude=500000,size="XL",spaceEngineMinAltitude=0,surfaceArea=4071504128,surfaceAverageAltitude=150,surfaceMaxAltitude=300,surfaceMinAltitude=10,systemZone=nil,territories=5072,type="",waterLevel=nil,planetarySystemId=0},[103]={name="Lacobus Moon 2",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=103,GM=211503600,gravity=0.11202853997062348,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=99250052,y=-13629215,z=-1059341.4},radius=14000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=0,surfaceArea=2463008768,surfaceAverageAltitude=-1380,surfaceMaxAltitude=-1280,surfaceMinAltitude=-1880,systemZone=nil,territories=3002,type="",waterLevel=nil,planetarySystemId=0},[101]={name="Lacobus Moon 3",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=101,GM=264870000,gravity=0.12003058201190042,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=98905288.17,y=-13950921.1,z=-647589.53},radius=15000,safeAreaEdgeAltitude=500000,size="L",spaceEngineMinAltitude=0,surfaceArea=2827433472,surfaceAverageAltitude=500,surfaceMaxAltitude=820,surfaceMinAltitude=3,systemZone=nil,territories=3632,type="",waterLevel=nil,planetarySystemId=0},[1]={name="Madis",description="Madis is a barren wasteland of a rock; it sits closest to the sun and temperatures reach extreme highs during the day. The arkship geological survey reports long rocky valleys intermittently separated by small ravines.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.8629,atmosphericEngineMaxAltitude=7165,biosphere="Barren",classification="hyperthermoplanet",bodyId=1,GM=6930729684,gravity=0.36009174603570127,fullAtmosphericDensityMaxAltitude=220,habitability="Low",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=8050,numSatellites=3,positionFromSun=1,center={x=17465536,y=22665536,z=-34464},radius=44300,safeAreaEdgeAltitude=500000,size="XS",spaceEngineMinAltitude=4480,surfaceArea=24661377024,surfaceAverageAltitude=750,surfaceMaxAltitude=850,surfaceMinAltitude=670,systemZone="Low",territories=30722,type="Planet",waterLevel=nil,planetarySystemId=0},[10]={name="Madis Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=10,GM=78480000,gravity=0.08002039003323584,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=17448118.224,y=22966846.286,z=143078.82},radius=10000,safeAreaEdgeAltitude=500000,size="XL",spaceEngineMinAltitude=0,surfaceArea=1256637056,surfaceAverageAltitude=210,surfaceMaxAltitude=420,surfaceMinAltitude=0,systemZone=nil,territories=1472,type="",waterLevel=nil,planetarySystemId=0},[11]={name="Madis Moon 2",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=11,GM=237402000,gravity=0.09602446196397631,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=17194626,y=22243633.88,z=-214962.81},radius=12000,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=0,surfaceArea=1809557376,surfaceAverageAltitude=-700,surfaceMaxAltitude=300,surfaceMinAltitude=-2900,systemZone=nil,territories=1922,type="",waterLevel=nil,planetarySystemId=0},[12]={name="Madis Moon 3",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=12,GM=265046609,gravity=0.12003058201190042,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=17520614,y=22184730,z=-309989.99},radius=15000,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=0,surfaceArea=2827433472,surfaceAverageAltitude=700,surfaceMaxAltitude=1100,surfaceMinAltitude=0,systemZone=nil,territories=3632,type="",waterLevel=nil,planetarySystemId=0},[26]={name="Sanctuary",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9666,atmosphericEngineMaxAltitude=6935,biosphere="",classification="",bodyId=26,GM=68234043600,gravity=1.0000000427743831,fullAtmosphericDensityMaxAltitude=-30,habitability="",hasAtmosphere=true,isSanctuary=true,noAtmosphericDensityAltitude=7800,numSatellites=0,positionFromSun=0,center={x=-1404835,y=562655,z=-285074},radius=83400,safeAreaEdgeAltitude=0,size="L",spaceEngineMinAltitude=4230,surfaceArea=87406149632,surfaceAverageAltitude=80,surfaceMaxAltitude=500,surfaceMinAltitude=-60,systemZone=nil,territories=111632,type="",waterLevel=0,planetarySystemId=0},[6]={name="Sicari",description="Sicari is a typical desert planet; it has survived for millenniums and will continue to endure. While not the most habitable of environments it remains a relatively untouched and livable planet of the Alioth sector. The arkship geological survey reports large flatlands alongside steep plateaus.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.897,atmosphericEngineMaxAltitude=7725,biosphere="Desert",classification="Mesoplanet",bodyId=6,GM=10502547741,gravity=0.4081039739797361,fullAtmosphericDensityMaxAltitude=-625,habitability="Average",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=8770,numSatellites=0,positionFromSun=6,center={x=52765536,y=27165538,z=52065535},radius=51100,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=4480,surfaceArea=32813432832,surfaceAverageAltitude=130,surfaceMaxAltitude=220,surfaceMinAltitude=50,systemZone="Average",territories=41072,type="Planet",waterLevel=nil,planetarySystemId=0},[7]={name="Sinnen",description="Sinnen is a an empty and rocky hell. With no atmosphere to speak of it is one of the least hospitable planets in the sector. The arkship geological survey reports mostly flatlands alongside deep ravines which look to have once been riverbeds. This planet simply looks to have dried up and died, likely from solar winds.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9226,atmosphericEngineMaxAltitude=10335,biosphere="Desert",classification="Mesoplanet",bodyId=7,GM=13033380591,gravity=0.4401121421448438,fullAtmosphericDensityMaxAltitude=-120,habitability="Average",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=11620,numSatellites=1,positionFromSun=7,center={x=58665538,y=29665535,z=58165535},radius=54950,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=6270,surfaceArea=37944188928,surfaceAverageAltitude=317,surfaceMaxAltitude=360,surfaceMinAltitude=23,systemZone="Average",territories=48002,type="Planet",waterLevel=nil,planetarySystemId=0},[70]={name="Sinnen Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=70,GM=396912600,gravity=0.1360346539426409,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=58969616,y=29797945,z=57969449},radius=17000,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=0,surfaceArea=3631681280,surfaceAverageAltitude=-2050,surfaceMaxAltitude=-1950,surfaceMinAltitude=-2150,systemZone=nil,territories=4322,type="",waterLevel=nil,planetarySystemId=0},[110]={name="Symeon",description="Symeon is an ice planet mysteriously split at the equator by a band of solid desert. Exactly how this phenomenon is possible is unclear but some sort of weather anomaly may be responsible. The arkship geological survey reports a fairly diverse mix of flat-lands alongside mountainous formations.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.9559,atmosphericEngineMaxAltitude=6920,biosphere="Ice, Desert",classification="Hybrid",bodyId=110,GM=9204742375,gravity=0.3920998898971822,fullAtmosphericDensityMaxAltitude=-30,habitability="High",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=7800,numSatellites=0,positionFromSun=11,center={x=14165536,y=-85634465,z=-934464.3},radius=49050,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=4230,surfaceArea=30233462784,surfaceAverageAltitude=39,surfaceMaxAltitude=450,surfaceMinAltitude=126,systemZone="High",territories=38882,type="Planet",waterLevel=nil,planetarySystemId=0},[4]={name="Talemai",description="Talemai is a planet in the final stages of an Ice Age. It seems likely that the planet was thrown into tumult by a cataclysmic volcanic event which resulted in its current state. The arkship geological survey reports large mountainous regions across the entire planet.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.8776,atmosphericEngineMaxAltitude=9685,biosphere="Barren",classification="Psychroplanet",bodyId=4,GM=14893847582,gravity=0.4641182439650478,fullAtmosphericDensityMaxAltitude=-78,habitability="Average",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=10890,numSatellites=3,positionFromSun=4,center={x=-13234464,y=55765536,z=465536},radius=57500,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=5890,surfaceArea=41547563008,surfaceAverageAltitude=580,surfaceMaxAltitude=610,surfaceMinAltitude=520,systemZone="Average",territories=52922,type="Planet",waterLevel=nil,planetarySystemId=0},[42]={name="Talemai Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=42,GM=264870000,gravity=0.12003058201190042,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=-13058408,y=55781856,z=740177.76},radius=15000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=0,surfaceArea=2827433472,surfaceAverageAltitude=720,surfaceMaxAltitude=850,surfaceMinAltitude=0,systemZone=nil,territories=3632,type="",waterLevel=nil,planetarySystemId=0},[40]={name="Talemai Moon 2",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=40,GM=141264000,gravity=0.09602446196397631,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=-13503090,y=55594325,z=769838.64},radius=12000,safeAreaEdgeAltitude=500000,size="S",spaceEngineMinAltitude=0,surfaceArea=1809557376,surfaceAverageAltitude=250,surfaceMaxAltitude=450,surfaceMinAltitude=0,systemZone=nil,territories=1922,type="",waterLevel=nil,planetarySystemId=0},[41]={name="Talemai Moon 3",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=41,GM=106830900,gravity=0.08802242599860607,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=-12800515,y=55700259,z=325207.84},radius=11000,safeAreaEdgeAltitude=500000,size="XS",spaceEngineMinAltitude=0,surfaceArea=1520530944,surfaceAverageAltitude=190,surfaceMaxAltitude=400,surfaceMinAltitude=0,systemZone=nil,territories=1922,type="",waterLevel=nil,planetarySystemId=0},[8]={name="Teoma",description="[REDACTED] The arkship geological survey [REDACTED]. This planet should not be here.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.7834,atmosphericEngineMaxAltitude=5580,biosphere="Forest",classification="Mesoplanet",bodyId=8,GM=18477723600,gravity=0.48812434578525177,fullAtmosphericDensityMaxAltitude=15,habitability="High",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=6280,numSatellites=0,positionFromSun=8,center={x=80865538,y=54665536,z=-934463.94},radius=62000,safeAreaEdgeAltitude=500000,size="L",spaceEngineMinAltitude=3420,surfaceArea=48305131520,surfaceAverageAltitude=700,surfaceMaxAltitude=1100,surfaceMinAltitude=-200,systemZone="High",territories=60752,type="Planet",waterLevel=0,planetarySystemId=0},[3]={name="Thades",description="Thades is a scorched desert planet. Perhaps it was once teaming with life but now all that remains is ash and dust. The arkship geological survey reports a rocky mountainous planet bisected by a massive unnatural ravine; something happened to this planet.",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0.03552,atmosphericEngineMaxAltitude=32180,biosphere="Desert",classification="Thermoplanet",bodyId=3,GM=11776905000,gravity=0.49612641213015557,fullAtmosphericDensityMaxAltitude=150,habitability="Low",hasAtmosphere=true,isSanctuary=false,noAtmosphericDensityAltitude=32800,numSatellites=2,positionFromSun=3,center={x=29165536,y=10865536,z=65536},radius=49000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=21400,surfaceArea=30171856896,surfaceAverageAltitude=13640,surfaceMaxAltitude=13690,surfaceMinAltitude=370,systemZone="Low",territories=38882,type="Planet",waterLevel=nil,planetarySystemId=0},[30]={name="Thades Moon 1",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=30,GM=211564034,gravity=0.11202853997062348,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=29214402,y=10907080.695,z=433858.2},radius=14000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=0,surfaceArea=2463008768,surfaceAverageAltitude=60,surfaceMaxAltitude=300,surfaceMinAltitude=0,systemZone=nil,territories=3002,type="",waterLevel=nil,planetarySystemId=0},[31]={name="Thades Moon 2",description="",antiGravMinAltitude=1000,atmosphericDensityAboveSurface=0,atmosphericEngineMaxAltitude=0,biosphere="",classification="",bodyId=31,GM=264870000,gravity=0.12003058201190042,fullAtmosphericDensityMaxAltitude=0,habitability="",hasAtmosphere=false,isSanctuary=false,noAtmosphericDensityAltitude=0,numSatellites=0,positionFromSun=0,center={x=29404193,y=10432768,z=19554.131},radius=15000,safeAreaEdgeAltitude=500000,size="M",spaceEngineMinAltitude=0,surfaceArea=2827433472,surfaceAverageAltitude=70,surfaceMaxAltitude=350,surfaceMinAltitude=0,systemZone=nil,territories=3632,type="",waterLevel=nil,planetarySystemId=0}}}end;function SetupAtlas()b0=Atlas()for bB,bC in pairs(b0[0])do if aE==nil or bC.center.xaF then aF=bC.center.x end;if aG==nil or bC.center.yaH then aH=bC.center.y end end;b1=""local gn=1.1*(aF-aE)/1920;local go=1.4*(aH-aG)/1080;for bB,bC in pairs(b0[0])do local bY=960+bC.center.x/gn;local bZ=540+bC.center.y/go;b1=b1 ..''if not string.match(bC.name,"Moon")and not string.match(bC.name,"Sanctuary")and not string.match(bC.name,"Space")then b1=b1 ..""..bC.name..""end end;local cg=vec3(core.getConstructWorldPos())local bY=960+cg.x/gn;local bZ=540+cg.y/go;b1=b1 ..''b1=b1 .."You Are Here"b1=b1 ..[[]]b2=gn;b3=go;if screen_2 then screen_2.setHTML(''..b1)local cg=vec3(core.getConstructWorldPos())local bY=960+cg.x/gn;local bZ=540+cg.y/go;b1=''b1=b1 .."You Are Here"b4=screen_2.addContent((bY-80)/19.20,(bZ-80)/10.80,b1)end end;function PlanetRef()local function gp(gq)return type(gq)=='number'end;local function gr(gq)return type(tonumber(gq))=='number'end;local function gs(gt)return type(gt)=='table'end;local function gu(gv)return type(gv)=='string'end;local function gw(bC)return gs(bC)and gp(bC.x and bC.y and bC.z)end;local function gx(gy)return gs(gy)and gp(gy.latitude and gy.longitude and gy.altitude and gy.bodyId and gy.systemId)end;local gz=math.pi/180;local gA=180/math.pi;local epsilon=1e-10;local q=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local ch='::pos{'..q..','..q..','..q..','..q..','..q..'}'local utils=require('cpml.utils')local vec3=require('cpml.vec3')local gB=utils.clamp;local function float_eq(c6,c7)if c6==0 then return math.abs(c7)<1e-09 end;if c7==0 then return math.abs(c6)<1e-09 end;return math.abs(c6-c7)=0 then local hp=math.sqrt(ho)local fg=hn+hp;local fh=hn-hp;if fh>0 then return fi,fg,fh elseif fg>0 then return fi,fg,nil end end end;return nil,nil,nil end;function gS:closestBody(hq)assert(type(hq)=='table','Invalid coordinates.')local hr,fi;local hs=vec3(hq)for _,ht in pairs(self)do local hu=(ht.center-hs):len2()if(not fi or hu=0 and cf or 2*math.pi+cf;cd=math.pi/2-math.acos(cb.z/ac)end;return setmetatable({latitude=cd,longitude=ce,altitude=cc,bodyId=self.bodyId,systemId=self.planetarySystemId},MapPosition)end;function gH:convertToWorldCoordinates(gR)local hv=gu(gR)and gQ(gR)or gR;if hv.bodyId==0 then return vec3(hv.latitude,hv.longitude,hv.altitude)end;assert(gx(hv),'Argument 1 (mapPosition) is not an instance of "MapPosition".')assert(hv.systemId==self.planetarySystemId,'Argument 1 (mapPosition) has a different planetary system ID.')assert(hv.bodyId==self.bodyId,'Argument 1 (mapPosition) has a different planetary body ID.')local ck=math.cos(hv.latitude)return self.center+(self.radius+hv.altitude)*vec3(ck*math.cos(hv.longitude),ck*math.sin(hv.longitude),math.sin(hv.latitude))end;function gH:getAltitude(c9)return(vec3(c9)-self.center):len()-self.radius end;function gH:getDistance(c9)return(vec3(c9)-self.center):len()end;function gH:getGravity(c9)local hw=self.center-vec3(c9)local hx=hw:len2()return self.GM/hx*hw/math.sqrt(hx)end;return setmetatable(b5,{__call=function(_,...)return g_(...)end})end;function Keplers()local vec3=require('cpml.vec3')local PlanetRef=PlanetRef()local function gu(gv)return type(gv)=='string'end;local function gs(gt)return type(gt)=='table'end;local function float_eq(c6,c7)if c6==0 then return math.abs(c7)<1e-09 end;if c7==0 then return math.abs(c6)<1e-09 end;return math.abs(c6-c7)0 then hO=hN;hP=hO+hI/2 end;if hP>hI then hP=hP-hI end end;return{periapsis={position=hF,speed=hH/hD,circularOrbitSpeed=math.sqrt(hA/hD),altitude=hD-self.body.radius},apoapsis=hG and{position=hG,speed=hH/hE,circularOrbitSpeed=math.sqrt(hA/hE),altitude=hE-self.body.radius},currentVelocity=bC,currentPosition=cg,eccentricity=hC,period=hI,eccentricAnomaly=hK,meanAnomaly=hM,timeToPeriapsis=hO,timeToApoapsis=hP}end;local function hQ(hR)local ht=PlanetRef.BodyParameters(hR.planetarySystemId,hR.bodyId,hR.radius,hR.center,hR.GM)return setmetatable({body=ht},Kepler)end;return setmetatable(Kepler,{__call=function(_,...)return hQ(...)end})end;function Kinematics()local b7={}local hS=30000000/3600;local hT=hS*hS;local hU=100;local function hV(bC)return 1/math.sqrt(1-bC*bC/hT)end;function b7.computeAccelerationTime(hW,hX,hY)local hZ=hS*math.asin(hW/hS)return(hS*math.asin(hY/hS)-hZ)/hX end;function b7.computeDistanceAndTime(hW,hY,h_,i0,i1,i2)i1=i1 or 0;i2=i2 or 0;local i3=hW<=hY;local i4=i0*(i3 and 1 or-1)/h_;local i5=-i2/h_;local i6=i4+i5;if i3 and i6<=0 or not i3 and i6>=0 then return-1,-1 end;local i7,i8=0,0;if i4~=0 and i1>0 then local hZ=math.asin(hW/hS)local i9=math.pi*(i4/2+i5)local ia=i4*i1;local ib=hS*math.pi;local bC=function(gt)local cV=(i9*gt-ia*math.sin(math.pi*gt/2/i1)+ib*hZ)/ib;local ic=math.tan(cV)return hS*ic/math.sqrt(ic*ic+1)end;local id=i3 and function(gv)return gv>=hY end or function(gv)return gv<=hY end;i8=2*i1;if id(bC(i8))then local ie=0;while math.abs(i8-ie)>0.5 do local gt=(i8+ie)/2;if id(bC(gt))then i8=gt else ie=gt end end end;local ig=hW;local ih=i8/hU;for ii=1,hU do local bS=bC(ii*ih)i7=i7+(bS+ig)*ih/2;ig=bS end;if i8<2*i1 then return i7,i8 end;hW=ig end;local hZ=hS*math.asin(hW/hS)local bE=(hS*math.asin(hY/hS)-hZ)/i6;local ij=hT*math.cos(hZ/hS)/i6;local ac=ij-hT*math.cos((i6*bE+hZ)/hS)/i6;return ac+i7,bE+i8 end;function b7.computeTravelTime(hW,hX,ac)if ac==0 then return 0 end;if hX>0 then local hZ=hS*math.asin(hW/hS)local ij=hT*math.cos(hZ/hS)/hX;return(hS*math.acos(hX*(ij-ac)/hT)-hZ)/hX end;if hW==0 then return-1 end;assert(hW>0,'Acceleration and initial speed are both zero.')return ac/hW end;function b7.lorentz(bC)return hV(bC)end;return b7 end;function safeZone(ik)local gN=500000;local il,im,io=math.huge;local ip=false;local iq=vec3({13771471,7435803,-128971})local ir=18000000;il=vec3(ik):dist(iq)if il0 or bN==0 and an<10000)then for _,bC in pairs(door)do bC.toggle()end end;if switch then for _,bC in pairs(switch)do bC.toggle()end end;if forcefield and(bN>0 or bN==0 and an<10000)then for _,bC in pairs(forcefield)do bC.toggle()end end;SaveDataBank()if button then button.activate()end end;local function it(ee,iu)if iu==nil then iu=false end;if Nav.axisCommandManager:getAxisCommandType(0)~=axisCommandType.byThrottle and not iu then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,ee)end;local function iv(ee,iu)if iu==nil then iu=false end;if Nav.axisCommandManager:getAxisCommandType(0)~=axisCommandType.byTargetSpeed and not iu then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,ee)end;function script.onTick(iw)if iw=="tenthSecond"then if j()>0 and not WasInAtmo then if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and AtmoSpeedAssist and(AltitudeHold or Reentry)then z=1;Nav.control.cancelCurrentControlMasterMode()D=false end end;if AutopilotTargetName~="None"then if panelInterplanetary==nil then SetupInterplanetaryPanel()end;if AutopilotTargetName~=nil then local ix=CustomTarget~=nil;planetMaxMass=GetAutopilotMaxMass()system.updateData(interplanetaryHeaderText,'{"label": "Target", "value": "'..AutopilotTargetName..'", "unit":""}')travelTime=GetAutopilotTravelTime()if ix and not Autopilot then ac=(vec3(core.getConstructWorldPos())-CustomTarget.position):len()else ac=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()end;if not TurnBurn then a0,a1=GetAutopilotBrakeDistanceAndTime(be)a2,a3=GetAutopilotBrakeDistanceAndTime(MaxGameVelocity)else a0,a1=GetAutopilotTBBrakeDistanceAndTime(be)a2,a3=GetAutopilotTBBrakeDistanceAndTime(MaxGameVelocity)end;local dy,dz=getDistanceDisplayString(ac)system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..dy..'", "unit":"'..dz..'"}')system.updateData(widgetTravelTimeText,'{"label": "Travel Time", "value": "'..FormatTimeString(travelTime)..'", "unit":""}')dy,dz=getDistanceDisplayString(a0)system.updateData(widgetCurBrakeDistanceText,'{"label": "Cur Brake distance", "value": "'..dy..'", "unit":"'..dz..'"}')system.updateData(widgetCurBrakeTimeText,'{"label": "Cur Brake Time", "value": "'..FormatTimeString(a1)..'", "unit":""}')dy,dz=getDistanceDisplayString(a2)system.updateData(widgetMaxBrakeDistanceText,'{"label": "Max Brake distance", "value": "'..dy..'", "unit":"'..dz..'"}')system.updateData(widgetMaxBrakeTimeText,'{"label": "Max Brake Time", "value": "'..FormatTimeString(a3)..'", "unit":""}')system.updateData(widgetMaxMassText,'{"label": "Maximum Mass", "value": "'..e("%.2f",planetMaxMass/1000)..'", "unit":" Tons"}')dy,dz=getDistanceDisplayString(AutopilotTargetOrbit)system.updateData(widgetTargetOrbitText,'{"label": "Target Orbit", "value": "'..e("%.2f",dy)..'", "unit":"'..dz..'"}')if j()>0 and not WasInAtmo then system.removeDataFromWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)system.removeDataFromWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)system.removeDataFromWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)system.removeDataFromWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)system.removeDataFromWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)WasInAtmo=true end;if j()==0 and WasInAtmo then if system.updateData(widgetMaxBrakeTimeText,widgetMaxBrakeTime)==1 then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;if system.updateData(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)==1 then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;if system.updateData(widgetCurBrakeTimeText,widgetCurBrakeTime)==1 then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;if system.updateData(widgetCurBrakeDistanceText,widgetCurBrakeDistance)==1 then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;if system.updateData(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)==1 then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end;WasInAtmo=false end end else HideInterplanetaryPanel()end;if warpdrive~=nil then if f(warpdrive.getData()).destination~="Unknown"and f(warpdrive.getData()).distance>400000 then warpdrive.show()showWarpWidget=true else warpdrive.hide()showWarpWidget=false end end elseif iw=="oneSecond"then ak=false;RefreshLastMaxBrake(nil,true)updateDistance()updateRadar()updateWeapons()local ct={}local dK=GetFlightStyle()DrawOdometer(ct,a5,TotalDistanceTravelled,dK,a6)if ShouldCheckDamage then CheckDamage(ct)end;ae=table.concat(ct,"")collectgarbage("collect")elseif iw=="fiveSecond"then al=dbHud_1.getStringValue("SPBAutopilotTargetName")if al~=nil and al~=""and al~="SatNavNotChanged"then local bD=json.decode(dbHud_1.getStringValue("SavedLocations"))if bD~=nil then _G["SavedLocations"]=bD;local cr=-1;local cn;for bB,bC in pairs(SavedLocations)do if bC.name and bC.name=="SatNav Location"then cr=bB;break end end;if cr~=-1 then cn=SavedLocations[cr]cr=-1;for bB,bC in pairs(b0[0])do if bC.name and bC.name=="SatNav Location"then cr=bB;break end end;if cr>-1 then b0[0][cr]=cn end;UpdateAtlasLocationsList()W=cn.name.." position updated"end end;for i=1,#AtlasOrdered do if AtlasOrdered[i].name==al then AutopilotTargetIndex=i;system.print("Index = "..AutopilotTargetIndex.." "..AtlasOrdered[i].name)UpdateAutopilotTarget()dbHud_1.setStringValue("SPBAutopilotTargetName","SatNavNotChanged")break end end end elseif iw=="msgTick"then local ct={}DisplayMessage(ct,"empty")W="empty"unit.stopTimer("msgTick")ab=3 elseif iw=="animateTick"then bb=true;ba=false;a9=0;aa=0;unit.stopTimer("animateTick")elseif iw=="hudTick"then local ct={}HUDPrologue(ct)if showHud then UpdateHud(ct)else DisplayOrbitScreen(ct)DrawWarnings(ct)end;HUDEpilogue(ct)ct[#ct+1]=e([[]],ResolutionX,ResolutionY)if W~="empty"then DisplayMessage(ct,W)end;if o()==0 and userControlScheme=="virtual joystick"then DrawDeadZone(ct)end;if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then SetButtonContains()DrawButtons(ct)if screen_1.getMouseState()==1 then CheckButtons()end;ct[#ct+1]=e([[]],E,F,a9,aa)elseif system.isViewLocked()==0 then if o()==1 and V then SetButtonContains()DrawButtons(ct)if not ba and not bb then local iy=table.concat(ct,"")ct={}ct[#ct+1]=e("",ResolutionX,ResolutionY)ct[#ct+1]=b1;ct[#ct+1]=iy;ct[#ct+1]=""ba=true;ct[#ct+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(ct,"")system.setScreen(content)elseif bb then local iy=table.concat(ct,"")ct={}ct[#ct+1]=e("",ResolutionX,ResolutionY)ct[#ct+1]=b1;ct[#ct+1]=iy;ct[#ct+1]=""end;if not ba then ct[#ct+1]=e([[]],E,F,a9,aa)end else CheckButtons()end else if not V and o()==0 then CheckButtons()if ac>DeadZone then DrawCursorLine(ct)end else SetButtonContains()DrawButtons(ct)end;ct[#ct+1]=e([[]],E,F,a9,aa)end;ct[#ct+1]=[[]]content=table.concat(ct,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end elseif iw=="apTick"then rateOfChange=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())am=j()>0;local bE=system.getTime()local iz=bE-bj;bj=bE;local cw=vec3(core.getConstructWorldOrientationForward())local cx=vec3(core.getConstructWorldOrientationRight())local iA=vec3(core.getConstructWorldOrientationUp())local cy=vec3(core.getWorldVertical())local iB=vec3(core.getConstructWorldPos())local dM=getRoll(cy,cw,cx)local dN=dM/180*math.pi;local dO=math.cos(dN)local dP=math.sin(dN)local cz=getPitch(cy,cw,cx)local iC=getPitch(cy,cw,cx*dO+iA*dP)local iD=-math.deg(cQ(iA,bd,cw))local iE=math.deg(cQ(cx,bd,cw))bi=am and iD<-YawStallAngle or iD>YawStallAngle or iE<-PitchStallAngle or iE>PitchStallAngle;bg=system.getMouseDeltaX()bh=system.getMouseDeltaY()if InvertMouse and not V then bh=-bh end;P=0;T=0;O=0;bd=vec3(core.getWorldVelocity())be=vec3(bd):len()sys=b6[0]planet=sys:closestBody(core.getConstructWorldPos())kepPlanet=b9(planet)orbit=kepPlanet:orbitalParameters(core.getConstructWorldPos(),bd)aj=hoverDetectGround()local bP=planet:getGravity(core.getConstructWorldPos()):len()*n()bk=0;b8=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]w,x,y,_=safeZone(iB)if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then a9=screen_1.getMouseX()*ResolutionX;aa=screen_1.getMouseY()*ResolutionY elseif system.isViewLocked()==0 then if o()==1 and V then if not ba then a9=a9+bg;aa=aa+bh end else a9=0;aa=0 end else a9=a9+bg;aa=aa+bh;ac=math.sqrt(a9*a9+aa*aa)if not V and o()==0 then if userControlScheme=="virtual joystick"then if a9>0 and a9>DeadZone then P=P-(a9-DeadZone)*MouseXSensitivity elseif a9<0 and a90 and aa>DeadZone then O=O-(aa-DeadZone)*MouseYSensitivity elseif aa<0 and aa8334;if be>SpaceSpeedLimit/3.6 and not am and not Autopilot and not iF then W="Space Speed Engine Shutoff reached"if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)z=0 end;if not iF and LastIsWarping then if not BrakeIsOn then BrakeToggle()end;if Autopilot then ToggleAutopilot()end end;LastIsWarping=iF;if am and j()>0.09 then if be>bm/3.6 and not AtmoSpeedAssist and not ar then BrakeIsOn=true;ar=true elseif not AtmoSpeedAssist and ar then if be85)and be>=bm/3.6-1 then BrakeIsOn=false;ProgradeIsOn=false;J=true;ag=false;ai=true;Autopilot=false;BeginReentry()else iv(math.floor(bm))z=0 end elseif be>I then AlignToWorldVector(vec3(bd),0.01)end end;if RetrogradeIsOn then if am then RetrogradeIsOn=false elseif be>I then AlignToWorldVector(-vec3(bd))end end;if not ProgradeIsOn and ag then if j()==0 then J=true;BeginReentry()ag=false;ai=true else ag=false;ToggleAutopilot()end end;local ei=vec3(core.getWorldVertical())*-1;local eg=bd.x*ei.x+bd.y*ei.y+bd.z*ei.z;if ai and(anHoldAltitude-200)and be*3.6>bm-100 and math.abs(eg)<20 and j()>=0.1 and(CustomTarget.position-iB):len()>2000+an then ToggleAutopilot()ai=false end;if VertTakeOff then bc=true;VertTakeOffMode=string.lower(VertTakeOffMode)if VertTakeOffMode=="agg"and not ExternalAGG and antigrav~=nil then antigrav.activate()antigrav.show()if an0 then BrakeIsOn=true;a8=0 elseif eg<-5 then BrakeIsOn=true;a8=15 elseif an>=antigrav.getBaseAltitude()then BrakeIsOn=true;a8=0;VertTakeOff=false;W="Singularity engaged"end elseif VertTakeOffMode=="orbit"then if eg<-30 then W="Unable to take off. Landing."a8=0;bc=autoRollPreference;VertTakeOff=false;BrakeLanding=true elseif j()>0.08 then bn=0;BrakeIsOn=false;a8=20 elseif j()<0.08 and j()>0 then BrakeIsOn=false;if bz then bn=0;a8=20 else a8=0;bn=36;iv(3500)end else bc=autoRollPreference;IntoOrbit=true;bx=false;CancelIntoOrbit=false;br=false;bp=nil;bq=nil;if bw==nil then bw=planet end;VertTakeOff=false end else W="Incorrect settings for ship configuration. Takeoff aborted."bc=autoRollPreference;VertTakeOff=false;BrakeLanding=true end;if bn~=nil then if vTpitchPID==nil then vTpitchPID=pid.new(2*0.01,0,2*0.1)end;local iH=utils.clamp(bn-iC,-PitchStallAngle*0.85,PitchStallAngle*0.85)vTpitchPID:inject(iH)local iI=utils.clamp(vTpitchPID:get(),-1,1)O=iI end end;if IntoOrbit then if AutoTakeoff or VectorToTarget then if VectorToTarget then if bw==nil then bw=a4 end;bt=VectorToTarget end;if bw==nil then bw=planet end;AltitudeHold=false;Autopilot=false;VectorToTarget=false;br=true end;local iJ,iK=b9(bw):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-bw.center):len()-bw.radius)local iL=dM;if not bu then if bw.hasAtmosphere then bv=math.floor(bw.radius*(TargetOrbitRadius-1)+bw.noAtmosphericDensityAltitude)else bv=math.floor(bw.radius*(TargetOrbitRadius-1)+bw.surfaceMaxAltitude)end;if bt or AutoTakeoff then bv=AutoTakeoffAltitude;AutoTakeoff=false end;bu=true end;if HoldAltitude>bv then bv=HoldAltitude end;if orbit.periapsis~=nil and orbit.eccentricity<1 and an>bv and an0 then local function iM(ee,iN)bp=iN;if iC<=iN+3 and iC>=iN-3 then z=ee;it(ee)else z=0.05;it(0.05)end end;if orbit.apoapsis~=nil then if orbit.periapsis.altitude>bv*0.9 and orbit.periapsis.altitudeorbit.periapsis.altitude and orbit.apoapsis.altitude<=orbit.periapsis.altitude*1.35 then BrakeIsOn=false;z=0;it(0)bx=true;if iC>2 or iC<-2 then bp=0 else bo=nil;bs=false;bu=false;bw=nil;bc=autoRollPreference;W="Orbit established"if bt then VectorToTarget=bt end;bt=false;CancelIntoOrbit=false;IntoOrbit=false;br=false;bp=nil;bq=nil;bw=nil end else bo="Adjusting Orbit"bs=true;if orbit.periapsis.altitudeorbit.periapsis.altitude*1.25 then if be+10>iK then if eg>15 then iM(0.5,-80)BrakeIsOn=false elseif eg<-15 then iM(0.5,80)BrakeIsOn=false else it(0)BrakeIsOn=true end elseif be-10orbit.periapsis.altitude*1.25 then it(0)BrakeIsOn=true elseif orbit.periapsis.altitude0 then iP=iP-iQ+50 end;BrakeIsOn=false;if not br then local iR=false;local iS=false;if an=bp-1 then iR=true else iR=false end;if iL<=bq+1 and iL>=bq-1 then iS=true else iS=false end;if iR and iS then bp=nil;bq=nil;br=true end else if an=bv*0.8 and an100 then iP=iP*0.75;bp=-50 else bp=utils.map(an,bv*0.6,bv,35,0)end elseif an>=bv*1.01 and anbv*1.5 then bo="Reentering orbital corridor"if eg<-100 then bp=45;iP=iP*1.25 else bp=-80;iP=iP*0.75 end end end;iv(math.floor(iP))end;if bp~=nil then if OrbitPitchPID==nil then OrbitPitchPID=pid.new(2*0.01,0,2*0.1)end;local iT=bp-iC;OrbitPitchPID:inject(iT)local iU=utils.clamp(OrbitPitchPID:get(),-0.5,0.5)O=iU end;if bq~=nil then if iC<85 then local iV=math.max(autoRollFactor,0.01)/4;if OrbitRollPID==nil then OrbitRollPID=pid.new(iV*0.01,0,iV*0.1)end;local iW=bq-iL;OrbitRollPID:inject(iW)local iX=utils.clamp(OrbitRollPID:get(),-0.5,0.5)T=iX end end elseif CancelIntoOrbit then bu=false;bx=false;bw=nil;it(0)CancelIntoOrbit=false end;if Autopilot and j()==0 and not ag then local iY,iZ=AutopilotTargetCoords,false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then AutopilotRealigned=true;if not TargetSet then local i_=(CustomTarget.position-a4.center):normalize()local j0=i_:project_on_plane((a4.center-iB):normalize()):normalize()local j1=a4.center+j0*(a4.radius+AutopilotTargetOrbit)local j2=CustomTarget.position+(CustomTarget.position-a4.center):normalize()*(AutopilotTargetOrbit-a4:getAltitude(CustomTarget.position))if(iB-j1):len()<(iB-j2):len()then iY=j1;AutopilotTargetCoords=iY else iY=CustomTarget.position+(CustomTarget.position-a4.center):normalize()*(AutopilotTargetOrbit-a4:getAltitude(CustomTarget.position))AutopilotTargetCoords=iY end;local cA=zeroConvertToMapPosition(a4,AutopilotTargetCoords)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)iZ=true;TargetSet=true end;AutopilotPlanetGravity=0 elseif CustomTarget~=nil and CustomTarget.planetname=="Space"then AutopilotPlanetGravity=0;iZ=true;TargetSet=true;AutopilotRealigned=true;iY=CustomTarget.position+(iB-CustomTarget.position)*AutopilotTargetOrbit elseif CustomTarget==nil then AutopilotPlanetGravity=0;if not TargetSet then local i_=(iB+bd*100000-a4.center):normalize()local j0=i_:project_on_plane((a4.center-iB):normalize()):normalize()if j0:len()<1 then i_=(iB+vec3(core.getConstructWorldOrientationForward())*100000-a4.center):normalize()j0=i_:project_on_plane((a4.center-iB):normalize()):normalize()end;iY=a4.center+j0*(a4.radius+AutopilotTargetOrbit)AutopilotTargetCoords=iY;TargetSet=true;iZ=true;AutopilotRealigned=true;local cA=zeroConvertToMapPosition(a4,AutopilotTargetCoords)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)end end;AutopilotDistance=(vec3(iY)-vec3(core.getConstructWorldPos())):len()local ff,fg,fh=b6:getPlanetarySystem(0):castIntersections(iB,bd:normalize(),function(fi)if fi.noAtmosphericDensityAltitude>0 then return fi.radius+fi.noAtmosphericDensityAltitude else return fi.radius+fi.surfaceMaxAltitude*1.5 end end)local fj=fg;if fh~=nil and fg~=nil then fj=math.min(fh,fg)end;if fj~=nil and fj300 and AutopilotAccelerating then local dv=vec3(iY)-vec3(core.getConstructWorldPos())local j4=utils.clamp(math.deg(cQ(iA,bd:normalize(),dv:normalize()))*be/500,-90,90)local j5=utils.clamp(math.deg(cQ(cx,bd:normalize(),dv:normalize()))*be/500,-90,90)if math.abs(j4)<20 and math.abs(j5)<20 then j4=j4*2;j5=j5*2 end;if math.abs(j4)<2 and math.abs(j5)<2 then j4=j4*2;j5=j5*2 end;local iD=-math.deg(cQ(iA,cw,bd:normalize()))local iE=-math.deg(cQ(cx,cw,bd:normalize()))if apPitchPID==nil then apPitchPID=pid.new(2*0.01,0,2*0.1)end;apPitchPID:inject(j5-iE)local j6=utils.clamp(apPitchPID:get(),-1,1)O=O+j6;if apYawPID==nil then apYawPID=pid.new(2*0.01,0,2*0.1)end;apYawPID:inject(j4-iD)local j7=utils.clamp(apYawPID:get(),-1,1)P=P+j7;iZ=true;if math.abs(j4)>2 or math.abs(j5)>2 then AutopilotStatus="Adjusting Trajectory"else AutopilotStatus="Accelerating"end end;if j3=MaxGameVelocity or fH==0 and G then AutopilotAccelerating=false;AutopilotStatus="Cruising"AutopilotCruising=true;it(0)z=0 end;if AutopilotDistance<=a0 then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true;it(0)z=0;G=false end elseif AutopilotBraking then if AutopilotStatus~="Orbiting to Target"then BrakeIsOn=true;S=1 end;if TurnBurn then it(100,true)z=1 end;local _,iK=b9(a4):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)local dv;if CustomTarget~=nil then dv=CustomTarget.position-iB end;if CustomTarget~=nil and CustomTarget.planetname=="Space"and be<50 then W="Autopilot complete, arrived at space location"AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"elseif CustomTarget~=nil and CustomTarget.planetname~="Space"and be<=iK and(orbit.apoapsis==nil or orbit.periapsis==nil or orbit.apoapsis.altitude<=0 or orbit.periapsis.altitude<=0)then W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"it(0)z=0;G=false;ProgradeIsOn=true;ag=true;local cA=zeroConvertToMapPosition(a4,AutopilotTargetCoords)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)elseif orbit.periapsis~=nil and orbit.periapsis.altitude>0 and orbit.eccentricity<1 then AutopilotStatus="Circularizing"local _,iK=b9(a4):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)if be<=iK then if CustomTarget~=nil then if bd:normalize():dot(dv:normalize())>0.4 then AutopilotStatus="Orbiting to Target"if not WaypointSet then BrakeIsOn=false;local cA=zeroConvertToMapPosition(a4,CustomTarget.position)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)WaypointSet=true end else W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"it(0)z=0;G=false;ProgradeIsOn=true;ag=true;BrakeIsOn=false;local cA=zeroConvertToMapPosition(a4,CustomTarget.position)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)WaypointSet=false end else BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"W="Autopilot completed, orbit established"S=0;z=0;G=false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then ProgradeIsOn=true;ag=true end end end end elseif AutopilotCruising then if AutopilotDistance<=a0 then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true end;local fH=unit.getThrottle()if AtmoSpeedAssist then fH=z end;if fH>0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if iG then if not AutopilotRealigned and CustomTarget==nil or not AutopilotRealigned and CustomTarget~=nil and CustomTarget.planetname~="Space"then if not ag then AutopilotTargetCoords=vec3(a4.center)+(AutopilotTargetOrbit+a4.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()end;AutopilotRealigned=true elseif iG then AutopilotAccelerating=true;AutopilotStatus="Accelerating"if not G then it(AutopilotInterplanetaryThrottle,true)z=round(AutopilotInterplanetaryThrottle,2)G=true;BrakeIsOn=false end end end end elseif Autopilot and(CustomTarget~=nil and CustomTarget.planetname~="Space"and j()>0)then W="Autopilot complete, proceeding with reentry"AutopilotTargetCoords=CustomTarget.position;BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;TargetSet=false;AutopilotStatus="Aligning"S=0;it(0)z=0;G=false;ProgradeIsOn=true;ag=true;local cA=zeroConvertToMapPosition(a4,CustomTarget.position)cA="::pos{"..cA.systemId..","..cA.bodyId..","..cA.latitude..","..cA.longitude..","..cA.altitude.."}"system.setWaypoint(cA)end;if U then bc=true;local j5=0;local cg=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local j8=cg-vec3(core.getConstructWorldPos())local j9=vec3(j8):project_on(vec3(core.getConstructWorldOrientationForward())):len()local ja=vec3(j8):project_on(vec3(core.getConstructWorldOrientationRight())):len()local ac=math.sqrt(j9*j9+ja*ja)AlignToWorldVector(j8:normalize())local jb=40;local jc=acje then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(j5-cz)local j6=pitchPID:get()O=j6 end end;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local cB=unit.getClosestPlanetInfluence()>0;local jf=HoldAltitude-an;local jg=500+be;local jh=1;if AutoTakeoff then jh=utils.clamp(be/100,0.1,1)end;local j5=(utils.smoothstep(jf,-jg,jg)-0.5)*2*MaxPitch*jh;if j()==0 and(a4~=nil and a4.name==planet.name)and not VectorToTarget and not Reentry and not BrakeLanding and LockPitch==nil and anplanet.noAtmosphericDensityAltitude+5000 and be<=ReentrySpeed/3.6 and be>ReentrySpeed/3.6-10 and math.abs(bd:normalize():dot(cw))>0.9 then Nav.control.cancelCurrentControlMasterMode()z=0 elseif Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle and(jj>-1 and jl<=jj or an<=planet.noAtmosphericDensityAltitude+5000)then BrakeIsOn=true else BrakeIsOn=false end;iv(ReentrySpeed,true)if not J then j5=-80;if j()>0.02 then W="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;j5=0;bc=autoRollPreference end elseif planet.noAtmosphericDensityAltitude>0 and an>planet.noAtmosphericDensityAltitude+5000 then bc=true elseif an<=planet.noAtmosphericDensityAltitude+5000 then iv(ReentrySpeed)if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==bm then J=false;Reentry=false;bc=true end end end;if be>I and not ah and not VectorToTarget and not BrakeLanding and ForceAlignment then AlignToWorldVector(vec3(bd))end;if(VectorToTarget or ah)and AutopilotTargetIndex>0 and j()>0.01 then local dv;if CustomTarget~=nil then dv=CustomTarget.position-vec3(core.getConstructWorldPos())else dv=a4.center-iB end;local j4=math.deg(cQ(cy:normalize(),bd,dv))*2;local jm=math.rad(math.abs(dM))if be>minRollVelocity and j()>0.01 then local jn=utils.clamp(90-j5*2,-90,90)bk=utils.clamp(j4*2,-jn,jn)local jo=j4;j4=utils.clamp(utils.clamp(j4,-YawStallAngle*0.85,YawStallAngle*0.85)*math.cos(jm)+4*(iC-j5)*math.sin(math.rad(dM)),-YawStallAngle*0.85,YawStallAngle*0.85)j5=utils.clamp(utils.clamp(j5*math.cos(jm),-PitchStallAngle*0.85,PitchStallAngle*0.85)+math.abs(utils.clamp(math.abs(jo)*math.sin(jm),-PitchStallAngle*0.85,PitchStallAngle*0.85)),-PitchStallAngle*0.85,PitchStallAngle*0.85)else bk=0;j4=utils.clamp(j4,-YawStallAngle*0.85,YawStallAngle*0.85)end;local jp=iD-j4;if not bi and be>minRollVelocity and j()>0.01 then if yawPID==nil then yawPID=pid.new(2*0.01,0,2*0.1)end;yawPID:inject(jp)local j7=utils.clamp(yawPID:get(),-1,1)P=P+j7 elseif am and aj>-1 or be0.01 then if(iD<-YawStallAngle or iD>YawStallAngle)and j()>0.01 then AlignToWorldVector(bd)end;if(iE<-PitchStallAngle or iE>PitchStallAngle)and j()>0.01 then j5=utils.clamp(iC-iE,iC-PitchStallAngle*0.85,iC+PitchStallAngle*0.85)end end;if CustomTarget~=nil and not ah then local jq=planet:getAltitude(CustomTarget.position)local jl=math.sqrt(dv:len()^2-(an-jq)^2)local jr=LastMaxBrakeInAtmo;if jr then jr=jr*utils.clamp(be/100,0.1,1)*j()else jr=LastMaxBrake end;if j()<0.01 then jr=LastMaxBrake end;local js=bd:len()-math.abs(eg)local jt=vec3(core.getWorldAirFrictionAcceleration())local ju=math.sqrt(jt:len()-jt:project_on(ei):len())*n()if be>100 then a0,a1=b7.computeDistanceAndTime(be,100,n(),0,0,jr+ju)local jv,jw=b7.computeDistanceAndTime(100,0,n(),0,0,jr/2)a0=a0+jv else a0,a1=b7.computeDistanceAndTime(be,0,n(),0,0,jr/2)end;StrongBrakes=true;if not ah and not Reentry and jl<=a0+be*iz/2 and(bd:project_on_plane(cy):normalize():dot(dv:project_on_plane(cy):normalize())>0.99 or VectorStatus=="Finalizing Approach")then VectorStatus="Finalizing Approach"it(0)z=0;if AltitudeHold then ToggleAltitudeHold()VectorToTarget=true end;BrakeIsOn=true elseif not AutoTakeoff then BrakeIsOn=false end;if VectorStatus=="Finalizing Approach"and(js<0.1 or jl<0.1 or LastDistanceToTarget~=nil and LastDistanceToTarget0 and j()==0 and a4.name==planet.name then if not bx then Autopilot=false;ah=false;AltitudeHold=false;IntoOrbit=true;bu=false;bw=a4 else local dv;if CustomTarget~=nil then dv=CustomTarget.position-vec3(core.getConstructWorldPos())else dv=a4.center-iB end;local jq=planet:getAltitude(CustomTarget.position)local jl=math.sqrt(dv:len()^2-(an-jq)^2)local jr=LastMaxBrakeInAtmo;jr=LastMaxBrake;a0,a1=b7.computeDistanceAndTime(be,0,n(),0,0,jr/2)StrongBrakes=true;if not ah and jl<=a0+be*iz/2 and(bd:project_on_plane(cy):normalize():dot(dv:project_on_plane(cy):normalize())>0.99 or VectorStatus=="Finalizing Approach")then if planet.hasAtmosphere then BrakeIsOn=false;ProgradeIsOn=false;J=true;ag=false;ai=true;Autopilot=false;VectorToTarget=false;BeginReentry()end end;LastDistanceToTarget=jl end end;if bi and j()>0.01 and aj==-1 and be>minRollVelocity and VectorStatus~="Finalizing Approach"then AlignToWorldVector(bd)j5=utils.clamp(iC-iE,iC-PitchStallAngle*0.85,iC+PitchStallAngle*0.85)end;O=ji;local fQ=-1;if BrakeLanding then j5=0;local jx=false;local jy=30;if b8~=nil and b8>0 then local ju=0;local dS=utils.clamp(j(),0.4,2)local jr=LastMaxBrakeInAtmo*utils.clamp(be/100,0.1,1)*dS;local jz=b8*dS+jr+ju-bP;local jA=jr/2+ju-bP;local jB=be-math.sqrt(math.abs(jA/2)*20/(0.5*n()))*utils.sign(jA)if jB<0 then jB=0 end;local jC;if be>100 then local jD,_=b7.computeDistanceAndTime(be,100,n(),0,0,jr)local jE,_=b7.computeDistanceAndTime(100,0,n(),0,0,math.sqrt(jr))jC=jD+jE else jC=b7.computeDistanceAndTime(be,0,n(),0,0,math.sqrt(jr))end;if jC<20 then BrakeIsOn=false else local jF=0;if jB>100 then local jG,_=b7.computeDistanceAndTime(jB,100,n(),0,0,jz)local jH,_=b7.computeDistanceAndTime(100,0,n(),0,0,b8*dS+math.sqrt(jr)+ju-bP)jF=jG+jH else jF,_=b7.computeDistanceAndTime(jB,0,n(),0,0,b8*dS+math.sqrt(jr)+ju-bP)end;jF=(jF+15+be*iz)*1.1;local jI=CustomTarget~=nil and planet:getAltitude(CustomTarget.position)>0 and CustomTarget.safe;if jI then local jq=planet:getAltitude(CustomTarget.position)local jJ=an-jq-100;local dv=CustomTarget.position-vec3(core.getConstructWorldPos())local jK=math.sqrt(dv:len()^2-(an-jq)^2)if jK>100 then jI=false elseif jJ<=jF or jF==-1 then BrakeIsOn=true;jx=true else BrakeIsOn=false;jx=true end end;if not jI and CalculateBrakeLandingSpeed then if jF>=jy then BrakeIsOn=true else BrakeIsOn=false end;jx=true end end end;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)fQ=aj;if fQ>-1 then bc=autoRollPreference;if be<1 or bd:normalize():dot(cy)<0 then BrakeLanding=false;AltitudeHold=false;GearExtended=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)a8=0;BrakeIsOn=true else BrakeIsOn=true end elseif StrongBrakes and bd:normalize():dot(-ei)<0.999 then BrakeIsOn=true elseif eg<-brakeLandingRate and not jx then BrakeIsOn=true elseif not jx then BrakeIsOn=false end end;if AutoTakeoff or ah then local ff,fh,fg=b6:getPlanetarySystem(0):castIntersections(iB,(AutopilotTargetCoords-iB):normalize(),function(fi)return fi.radius+fi.noAtmosphericDensityAltitude end)if antigrav and antigrav.getState()==1 then if an>=HoldAltitude-50 then AutoTakeoff=false;BrakeIsOn=true;it(0)z=0 else HoldAltitude=antigrav.getBaseAltitude()end elseif math.abs(j5)<15 and an/HoldAltitude>0.75 then AutoTakeoff=false;if not ah then if Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end elseif ah and be-1;local jM=cz;if(VectorToTarget or ah)and not jL and be>minRollVelocity and j()>0.01 then local jm=math.rad(math.abs(dM))jM=cz*math.abs(math.cos(jm))+iE*math.sin(jm)end;local jN=utils.clamp(j5-jM,-PitchStallAngle*0.85,PitchStallAngle*0.85)if j()<0.01 and VectorToTarget then jN=utils.clamp(j5-jM,-85,MaxPitch)elseif j()<0.01 then jN=utils.clamp(j5-jM,-MaxPitch,MaxPitch)end;if math.abs(dM)<5 or VectorToTarget or BrakeLanding or jL or AltitudeHold then if pitchPID==nil then pitchPID=pid.new(5*0.01,0,5*0.1)end;pitchPID:inject(jN)local j6=pitchPID:get()O=O+j6 end end;if antigrav~=nil and(antigrav and not ExternalAGG and an<200000)then if AntigravTargetAltitude==nil or AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;if desiredBaseAltitude~=AntigravTargetAltitude then desiredBaseAltitude=AntigravTargetAltitude;antigrav.setBaseAltitude(desiredBaseAltitude)end end end end;function script.onFlush()if antigrav~=nil and(antigrav and not ExternalAGG)then if antigrav.getState()==0 and antigrav.getBaseAltitude()~=AntigravTargetAltitude then antigrav.setBaseAltitude(AntigravTargetAltitude)end end;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle and D then z=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)D=false elseif Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed and not D then z=0;D=true end;pitchSpeedFactor=math.max(pitchSpeedFactor,0.01)yawSpeedFactor=math.max(yawSpeedFactor,0.01)rollSpeedFactor=math.max(rollSpeedFactor,0.01)torqueFactor=math.max(torqueFactor,0.01)brakeSpeedFactor=math.max(brakeSpeedFactor,0.01)brakeFlatFactor=math.max(brakeFlatFactor,0.01)autoRollFactor=math.max(autoRollFactor,0.01)turnAssistFactor=math.max(turnAssistFactor,0.01)local jO=utils.clamp(N+O+system.getControlDeviceForwardInput(),-1,1)local jP=utils.clamp(Q+T+system.getControlDeviceYawInput(),-1,1)local jQ=utils.clamp(R+P-system.getControlDeviceLeftRightInput(),-1,1)local jR=S;local jS=vec3(core.getWorldVertical())if jS==nil or jS:len()==0 then jS=(planet.center-vec3(core.getConstructWorldPos())):normalize()end;local jT=vec3(core.getConstructWorldOrientationUp())local jU=vec3(core.getConstructWorldOrientationForward())local jV=vec3(core.getConstructWorldOrientationRight())local jW=vec3(core.getWorldVelocity())local jX=vec3(core.getWorldVelocity()):normalize()local jY=getRoll(jS,jU,jV)local jZ=math.abs(jY)local j_=utils.sign(jY)local j=j()local k0=vec3(core.getWorldAngularVelocity())local k1=jO*pitchSpeedFactor*jV+jP*rollSpeedFactor*jU+jQ*yawSpeedFactor*jT;if jS:len()>0.01 and(j>0.0 or ProgradeIsOn or Reentry or ag or AltitudeHold)then local dM=getRoll(jS,jU,jV)local dN=dM/180*math.pi;local dO=math.cos(dN)local dP=math.sin(dN)local iC=getPitch(jS,jU,jV*dO+jT*dP)if bc==true and math.abs(bk-jY)>autoRollRollThreshold and jP==0 and math.abs(iC)<85 then local k2=bk;local iV=autoRollFactor;if j==0 then iV=iV/4;bk=0;k2=0 end;if rollPID==nil then rollPID=pid.new(iV*0.01,0,iV*0.1)end;rollPID:inject(k2-jY)local k3=rollPID:get()k1=k1+k3*jU end end;if jS:len()>0.01 and j>0.0 then local k4=20.0;if turnAssist==true and jZ>k4 and jO==0 and jQ==0 then local k5=turnAssistFactor*0.1;local k6=turnAssistFactor*0.025;local k7=(jZ-k4)/(180-k4)*180;local k8=0;if k7<90 then k8=k7/90 elseif k7<180 then k8=(180-k7)/90 end;k8=k8*k8;local k9=-j_*k6*(1.0-k8)local ka=k5*k8;k1=k1+ka*jV+k9*jT end end;local kb=1;local kc=0;local kd=1;if system.getMouseWheel()>0 then if AltIsOn then if j>0 or Reentry then bm=utils.clamp(bm+speedChangeLarge,0,AtmoSpeedLimit)elseif Autopilot then MaxGameVelocity=utils.clamp(MaxGameVelocity+speedChangeLarge/3.6*100,0,8333.00)end;H=false else z=round(utils.clamp(z+speedChangeLarge/100,-1,1),2)end elseif system.getMouseWheel()<0 then if AltIsOn then if j>0 or Reentry then bm=utils.clamp(bm-speedChangeLarge,0,AtmoSpeedLimit)elseif Autopilot then MaxGameVelocity=utils.clamp(MaxGameVelocity-speedChangeLarge/3.6*100,0,8333.00)end;H=false else z=round(utils.clamp(z-speedChangeLarge/100,-1,1),2)end end;A=0;local eg=-jS:dot(jW)if am and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then if throttlePID==nil then throttlePID=pid.new(0.5,0,1)end;throttlePID:inject(bm/3.6-jW:dot(jU))local ke=throttlePID:get()C=utils.clamp(ke,-1,1)if C0.005 then B=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,utils.clamp(C,0.01,1))else B=false;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)end;if brakePID==nil then brakePID=pid.new(1*0.01,0,1*0.1)end;brakePID:inject(jW:len()-bm/3.6)local kf=utils.clamp(brakePID:get(),0,1)if j>0 and eg<-80 or j>0.005 then A=kf end;if A>0 then if B and C==0.01 then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)end else C=utils.clamp(C,0.01,1)end;local kg=''local kh=vec3()local ki=composeAxisAccelerationFromTargetSpeedV(axisCommandId.vertical,a8*1000)Nav:setEngineForceCommand("vertical airfoil , vertical ground ",ki,kc)local kj='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then kj=kj..ExtraLongitudeTags end;local kk=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)local kl=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kj,axisCommandId.longitudinal)local km=composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral,LeftAmount*1000)kg=kg..' , '.."lateral airfoil , lateral ground "kh=kh+km;if kh:len()>constants.epsilon then Nav:setEngineForceCommand(kg,kh,kc,'','','',kd)end;Nav:setEngineForceCommand(kj,kl,kb)local kn='thrust analog vertical fueled 'local ko='thrust analog lateral fueled 'if ExtraLateralTags~="none"then ko=ko..ExtraLateralTags end;if ExtraVerticalTags~="none"then kn=kn..ExtraVerticalTags end;if a8~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(kn,ki,kb)else Nav:setEngineForceCommand(kn,vec3(),kb)end;if LeftAmount~=0 then Nav:setEngineForceCommand(ko,km,kb)else Nav:setEngineForceCommand(ko,vec3(),kb)end;if jR==0 then jR=A end;local kp=-jR*(brakeSpeedFactor*jW+brakeFlatFactor*jX)Nav:setEngineForceCommand('brake',kp)else if AtmoSpeedAssist then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,z)end;local kp=-jR*(brakeSpeedFactor*jW+brakeFlatFactor*jX)Nav:setEngineForceCommand('brake',kp)local kg=''local kh=vec3()local kq=false;local kj='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then kj=kj..ExtraLongitudeTags end;local kk=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if kk==axisCommandType.byThrottle then local kl=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kj,axisCommandId.longitudinal)Nav:setEngineForceCommand(kj,kl,kb)elseif kk==axisCommandType.byTargetSpeed then local kl=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)kg=kg..' , '..kj;kh=kh+kl;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then kq=true end end;local ko='thrust analog lateral 'if ExtraLateralTags~="none"then ko=ko..ExtraLateralTags end;local kr=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if kr==axisCommandType.byThrottle then local ks=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ko,axisCommandId.lateral)Nav:setEngineForceCommand(ko,ks,kb)elseif kr==axisCommandType.byTargetSpeed then local km=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)kg=kg..' , '..ko;kh=kh+km end;local kn='thrust analog vertical 'if ExtraVerticalTags~="none"then kn=kn..ExtraVerticalTags end;local kt=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if kt==axisCommandType.byThrottle then local ki=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(kn,axisCommandId.vertical)if a8~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(kn,ki,kb,'airfoil','ground','',kd)else Nav:setEngineForceCommand(kn,vec3(),kb)Nav:setEngineForceCommand('airfoil vertical',ki,kb,'airfoil','','',kd)Nav:setEngineForceCommand('ground vertical',ki,kb,'ground','','',kd)end elseif kt==axisCommandType.byTargetSpeed then if a8<0 then Nav:setEngineForceCommand('hover',vec3(),kb)end;local ku=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)kg=kg..' , '..kn;kh=kh+ku end;local gb=unit.getAxisCommandValue(0)if kh:len()>constants.epsilon then if S~=0 or kq or math.abs(jX:dot(jU))<0.8 or bd:len()>gb/3.6 then kg=kg..', brake'end;Nav:setEngineForceCommand(kg,kh,kc,'','','',kd)end end;local kv=torqueFactor*(k1-k0)local kw=vec3(core.getWorldAirFrictionAngularAcceleration())kv=kv-kw;Nav:setEngineTorqueCommand('torque',kv,kb,'airfoil','','',kd)Nav:setBoosterCommand('rocket_engine')if Z and not VanillaRockets then local bS=vec3(core.getVelocity()):len()local kx=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local ky=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bS*3.6>ky*(1-kx)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bS*3.6=gb*(1-kx)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bS=gb*(1-kx)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bS0 or anHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+Y;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+Y end else AntigravTargetAltitude=desiredBaseAltitude+100 end elseif AltitudeHold then HoldAltitude=HoldAltitude+X else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)end elseif kz=="groundaltitudedown"then OldButtonMod=X;OldAntiMod=Y;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-Y;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-Y;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end else AntigravTargetAltitude=desiredBaseAltitude end elseif AltitudeHold then HoldAltitude=HoldAltitude-X else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)end elseif kz=="option1"then if not Autopilot then IncrementAutopilotTargetIndex()H=false end elseif kz=="option2"then if not Autopilot then DecrementAutopilotTargetIndex()H=false end elseif kz=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;H=false;ToggleWidgets()elseif kz=="option4"then ToggleAutopilot()H=false elseif kz=="option5"then ToggleLockPitch()H=false elseif kz=="option6"then ToggleAltitudeHold()H=false elseif kz=="option7"then wipeSaveVariables()H=false elseif kz=="option8"then ToggleFollowMode()H=false elseif kz=="option9"then if gyro~=nil then gyro.toggle()aq=gyro.getState()==1 end;H=false elseif kz=="lshift"then if system.isViewLocked()==1 then V=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then V=true;bb=false;ba=false end elseif kz=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif kz=="lalt"then AltIsOn=true;if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif kz=="booster"then if VanillaRockets then Nav:toggleBoosters()elseif not Z then if not IsRocketOn then Nav:toggleBoosters()IsRocketOn=true end;Z=true else if IsRocketOn then Nav:toggleBoosters()IsRocketOn=false end;Z=false end elseif kz=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()z=0 elseif kz=="speedup"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z+speedChangeLarge/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)end else IncrementAutopilotTargetIndex()end elseif kz=="speeddown"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z-speedChangeLarge/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)end else DecrementAutopilotTargetIndex()end elseif kz=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(kz)if kz=="forward"then N=0 elseif kz=="backward"then N=0 elseif kz=="left"then Q=0 elseif kz=="right"then Q=0 elseif kz=="yawright"then R=0 elseif kz=="yawleft"then R=0 elseif kz=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)LeftAmount=0 elseif kz=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)LeftAmount=0 elseif kz=="up"then a8=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif kz=="down"then a8=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif kz=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then Y=OldAntiMod end;if AltitudeHold then X=OldButtonMod end;H=false elseif kz=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then Y=OldAntiMod end;if AltitudeHold then X=OldButtonMod end;H=false elseif kz=="lshift"then if system.isViewLocked()==1 then V=false;a9=0;aa=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then V=false;bb=false;ba=false end elseif kz=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif kz=="lalt"then if o()==0 and freeLookToggle then if H then if system.isViewLocked()==1 then system.lockView(0)else system.lockView(1)end else H=true end elseif o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(0)end;AltIsOn=false end end;function script.onActionLoop(kz)if kz=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+Y;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+Y end;Y=Y*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude+100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude+X;X=X*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)end elseif kz=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-Y;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-Y;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end;Y=Y*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude-100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude-X;X=X*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)end elseif kz=="speedup"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z+speedChangeSmall/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end end elseif kz=="speeddown"then if not V then if AtmoSpeedAssist and not AltIsOn then z=utils.clamp(z-speedChangeSmall/100,-1,1)else Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end end;function script.onInputText(dA)local i;local kA="/commands /setname /G /agg /addlocation /copydatabank"local kB,kC=nil,nil;local kD="Command List:\n/commands \n/setname - Updates current selected saved position name\n/G VariableName newValue - Updates global variable to new value\n".."/G dump - shows all updatable variables with /G\n/agg - Manually set agg target height\n".."/addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572} - adds a saved location by waypoint, not as accurate as making one at location\n".."/copydatabank - copies dbHud databank to a blank databank"i=string.find(dA," ")kB=dA;if i~=nil then kB=string.sub(dA,0,i-1)kC=string.sub(dA,i+1)elseif not string.find(kA,kB)then for g7 in string.gmatch(kD,"([^\n]+)")do c(g7)end;return end;if kB=="/setname"then if kC==nil or kC==""then W="Usage: /setname Newname"return end;if AutopilotTargetIndex>0 and CustomTarget~=nil then UpdatePosition(kC)else W="Select a saved target to rename first"end elseif kB=="/addlocation"then if kC==nil or kC==""or string.find(kC,"::")==nil then W="Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}"return end;i=string.find(kC,"::")local cm=string.sub(kC,1,i-2)local cg=string.sub(kC,i)local q=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local ch='::pos{'..q..','..q..','..q..','..q..','..q..'}'local ci,cj,cd,ce,cc=string.match(cg,ch)local planet=b0[tonumber(ci)][tonumber(cj)]AddNewLocationByWaypoint(cm,planet,cg)W="Added "..cm.." to saved locations,\nplanet "..planet.name.." at "..cg;ab=5 elseif kB=="/agg"then if kC==nil or kC==""then W="Usage: /agg targetheight"return end;kC=tonumber(kC)if kC<1000 then kC=1000 end;AntigravTargetAltitude=kC;W="AGG Target Height set to "..kC elseif kB=="/G"then if kC==nil or kC==""then W="Usage: /G VariableName variablevalue\n/G dump - shows all variables"return end;if kC=="dump"then for bB,bC in pairs(a)do if type(_G[bC])=="boolean"then if _G[bC]==true then c(bC.." true")else c(bC.." false")end elseif _G[bC]==nil then c(bC.." nil")else c(bC.." ".._G[bC])end end;return end;i=string.find(kC," ")local kE=string.sub(kC,0,i-1)local kF=string.sub(kC,i+1)for bB,bC in pairs(a)do if bC==kE then W="Variable "..kE.." changed to "..kF;local kG=type(_G[bC])if kG=="number"then kF=tonumber(kF)elseif kG=="boolean"then if string.lower(kF)=="true"then kF=true else kF=false end end;_G[bC]=kF;return end end;W="No such global variable: "..kE elseif kB=="/copydatabank"then if dbHud_2 then SaveDataBank(true)else W="Databank required to copy databank"end end end;script.onStart() -- error handling code added by wrap.lua diff --git a/ChangeLog.md b/ChangeLog.md index c19d300..6ed8427 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,34 @@ ## ChangeLog - Most recent changes at the top +Fixed script unloading when away from control unit. Note: We are now at our script limit even minimized. We are trying to clean up to give more room, +but this might be the limit of everything in the hud meaning new features would remove old features or we might have to get creative on some things. + +Version 5.42 - VTO to Orbit or AGG Height, ATO to AGG, and Same Planet Orbital Hops. +- Vertical Takeoff v3 - (`VertTakeOffEngine` must be set to True for the below to work) + - When `VertTakeOffMode` is set to *"AGG"*, it will now activate AGG and vertically fly up just above AGG Singularity height and stay in the air until the Singularity is at your height, then the engines are turned off and the brakes are engaged. *Not available if you use ExternalAGG.* + - When `VertTakeOffMode` is set to *"Orbit"*, it will vertically fly up and out of atmosphere. If there is not enough force to lift you out, Brake Landing is triggered. If you reach space, it will fly you forward using space engines to the distance set by `TargetOrbitRadius` and then cut off engines and you will be in orbit. +- Auto Takeoff changes + - When Altitude Hold is set above atmospheric height (alt-spacebar) and is in space, orbiting will engaged once out of atmosphere. Your ship will orbit at the altitude hold height. **Set this with care, too low and you risk burning up or will yo-yo trying to achieve orbit** + - If Agg is turned on first (alt-g default) then autotakeoff (alt-6 default) will take you up to current singularity altitude, turn off engines, and engage brake. +- Autopilot changes + - While in space, activating autopilot when your target is the same nearby planet (not a custom waypoint), you will begin orbiting to height determined by `TargetOrbitRadius`. + - On ground, if a custom target is selected and Altitude Hold is raised (alt-spacebar) above atmo height, autopilot will take off and orbit at the configred height. Once orbited, autopilot will reengage and reenter you close to your target. Recommended minimum distance for this feature is a waypoint at least 0.5SU away. **Set this with care, too low and you risk burning up or will yo-yo trying to achieve orbit** + - Target locked when Autopilot is engaged (in space). Disengaging Autopilot allows you to select a new target. +- Script cleanup + - Cleaned up repetative functions and removed unused variables. + + +Version 5.41 +- Vertical Engines Detection developed + - Currently for changing how Vertical Takeoff works, but can be extended in the future. You still need to enable VertTakeOffEngine to activate. +- Vertical Takeoff v2 + - Now has three options set by VertTakeOffMode: "Orbit" to engage orbiting, and "AGG" to engage the AGG at AGG minimum height (1km or AGG Base Alt, whichever is higher), + or higher if set (Not available when ExternalAGG set to true) + - Protection against mispelling or wrong option in VertTakeOffMode. Does not enable if the option is wrong + - Using Vertical Engine Detection, now makes use of vertical engines in space if equiped. If not, will pitch 35 deg up and will move forward. **Will not activate Vertical Takeoff.** + - Saftey Net added to Vertical Takeoff. If you don't reach out of atmo and begin falling, BrakeLanding is enabled for a smooth fall back to ground + - If you cancel Vertical Takeoff mid sequence, BrakeLanding is enabled + Version 5.4 - Updates via ShadowMage, many thanks!: Initial Pass on Vertical Takeoff diff --git a/src/ButtonHUD.lua b/src/ButtonHUD.lua index b006ad4..11ffda9 100644 --- a/src/ButtonHUD.lua +++ b/src/ButtonHUD.lua @@ -91,7 +91,8 @@ autoRollRollThreshold = 0 --export: (Default: 0) The minimum amount of roll befo AtmoSpeedAssist = true --export: (Default: true) Whether or not atmospheric speeds should be limited to a maximum of AtmoSpeedLimit ForceAlignment = false --export: (Default: false) Whether velocity vector alignment should be forced when in Altitude Hold minRollVelocity = 150 --export: (Default: 150) Min velocity, in m/s, over which advanced rolling can occur -VertTakeOffEngine = false --export: (Default: false) Set this to true if you have VTOL engines on your construct. Will VTOL on AutoTakeOff. +VertTakeOffEngine = false --export: (Default: false) Set this to true if you have VTOL engines on your construct. Changes Auto Takeoff to Vertical Takeoff. +VertTakeOffMode = "Orbit" --export: (Default: "Orbit") Set to: "AGG" = turn on AGG when above 1km and near AGG activation height, "Orbit" = go directly to orbit based off of TargetOrbitRadius. Must keep quotes. Any case is fine. -- Auto Variable declarations that store status of ship. Must be global because they get saved/read to Databank due to using _G assignment BrakeToggleStatus = BrakeToggleDefault @@ -131,12 +132,7 @@ LastStartTime = 0 SpaceTarget = false LeftAmount = 0 IntoOrbit = false -OrbitTargetSet = false -OrbitTargetCoords = nil -OrbitTargetOrbit = 0 -OrbitTargetPlanet = nil -OrbitRetriggerTarget = false -OrbitAchieved = false + -- VARIABLES TO BE SAVED GO HERE, SAVEABLE are Edit LUA Parameter settable, AUTO are ship status saves that occur over get up and sit down. local saveableVariables = {"userControlScheme", "TargetOrbitRadius", "apTickRate", "freeLookToggle", "turnAssist", @@ -152,7 +148,7 @@ local saveableVariables = {"userControlScheme", "TargetOrbitRadius", "apTickRate "vSpdMeterX", "vSpdMeterY", "altMeterX", "altMeterY", "fuelX","fuelY", "LandingGearGroundHeight", "TrajectoryAlignmentStrength", "RemoteHud", "YawStallAngle", "PitchStallAngle", "ResolutionX", "ResolutionY", "UseSatNav", "FuelTankOptimization", "ContainerOptimization", "ExtraLongitudeTags", "ExtraLateralTags", "ExtraVerticalTags", "OrbitMapSize", "OrbitMapX", "OrbitMapY", "DisplayOrbit", "CalculateBrakeLandingSpeed", - "ForceAlignment", "autoRollRollThreshold", "minRollVelocity", "VertTakeOffEngine", "PvPR", "PvPG", "PvPB"} + "ForceAlignment", "autoRollRollThreshold", "minRollVelocity", "VertTakeOffEngine","VertTakeOffMode", "PvPR", "PvPG", "PvPB"} local autoVariables = {"SpaceTarget","BrakeToggleStatus", "BrakeIsOn", "RetrogradeIsOn", "ProgradeIsOn", "Autopilot", "TurnBurn", "AltitudeHold", "BrakeLanding", @@ -215,14 +211,14 @@ local rollInput2 = 0 local followMode = false local holdingCtrl = false local msgText = "empty" -local lastEccentricity = 1 +--local lastEccentricity = 1 local holdAltitudeButtonModifier = 5 local antiGravButtonModifier = 5 local isBoosting = false -- Dodgin's Don't Die Rocket Govenor local brakeDistance, brakeTime = 0 local maxBrakeDistance, maxBrakeTime = 0 -local hasSpaceRadar = false -local hasAtmoRadar = false +--local hasSpaceRadar = false +--local hasAtmoRadar = false local autopilotTargetPlanet = nil local totalDistanceTrip = 0 local flightTime = 0 @@ -296,10 +292,10 @@ local Kep = nil local Animating = false local Animated = false local autoRoll = autoRollPreference -local rateOfChange = vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize()) +--local rateOfChange = vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize()) local velocity = vec3(core.getWorldVelocity()) local velMag = vec3(velocity):len() -local minimumRateOfChange = math.cos(YawStallAngle*constants.deg2rad) +--local minimumRateOfChange = math.cos(YawStallAngle*constants.deg2rad) local targetGroundAltitude = LandingGearGroundHeight -- So it can tell if one loaded or not local deltaX = system.getMouseDeltaX() local deltaY = system.getMouseDeltaY() @@ -308,14 +304,21 @@ local lastApTickTime = system.getTime() local targetRoll = 0 local ahDoubleClick = 0 local adjustedAtmoSpeedLimit = AtmoSpeedLimit +local VtPitch = 0 local orbitMsg = nil -local orbitThrottle = 0 -local orbitCruiseSpeed = 0 local orbitPitch = 0 local orbitRoll = 0 local orbitAligned = false local orbitalRecover = false - +local orbitalVectorToTarget = false +local OrbitTargetSet = false +local OrbitTargetOrbit = 0 +local OrbitTargetPlanet = nil +local OrbitAchieved = false +-- local AtmoEngineVertUp = false +-- local AtmoEngineVertDn = false +local SpaceEngineVertUp = false +local SpaceEngineVertDn = false -- BEGIN FUNCTION DEFINITIONS function LoadVariables() @@ -405,6 +408,38 @@ function ProcessElements() local checkTanks = (fuelX ~= 0 and fuelY ~= 0) for k in pairs(elementsID) do local type = eleType(elementsID[k]) + if string.match(type, '^.*Space Engine$') then + if string.match(tostring(core.getElementTagsById(elementsID[k])), '^.*vertical.*$') then + local enrot = core.getElementRotationById(elementsID[k]) + if enrot[4] < 0 then + if utils.round(-enrot[4],0.1) == 0.5 then + SpaceEngineVertUp = true + system.print("Space Engine Up detected") + end + else + if utils.round(enrot[4],0.1) == 0.5 then + SpaceEngineVertDn = true + system.print("Space Engine Down detected") + end + end + end + end + -- if string.match(type, '^.*Atmospheric Engine$') then + -- if string.match(tostring(core.getElementTagsById(elementsID[k])), '^.*vertical.*$') then + -- local enrot = core.getElementRotationById(elementsID[k]) + -- if enrot[4] < 0 then + -- if utils.round(-enrot[4],0.1) == 0.5 then + -- AtmoEngineVertUp = true + -- system.print("Atmo Engine Up detected") + -- end + -- else + -- if utils.round(enrot[4],0.1) == 0.5 then + -- AtmoEngineVertDn = true + -- system.print("Atmo Engine Down detected") + -- end + -- end + -- end + -- end if (type == "Landing Gear") then hasGear = true end @@ -1039,12 +1074,20 @@ function ToggleAutoTakeoff() ToggleAltitudeHold() end elseif VertTakeOff then + BrakeLanding = true VertTakeOff = false AltitudeHold = false else if VertTakeOffEngine then + VertTakeOffMode = string.lower(VertTakeOffMode) + if VertTakeOffMode ~= "orbit" and VertTakeOffMode ~= "agg" then + msgText = "Incorrect VertTakeOffMode setting. Takeoff aborted." + VertTakeOff = false + BrakeLanding = true + else VertTakeOff = true AltitudeHold = false + end else if not AltitudeHold then ToggleAltitudeHold() @@ -1052,10 +1095,13 @@ function ToggleAutoTakeoff() AutoTakeoff = true HoldAltitude = coreAltitude + AutoTakeoffAltitude end - GearExtended = false - Nav.control.retractLandingGears() - Nav.axisCommandManager:setTargetGroundAltitude(500) -- Hard set this for takeoff, you wouldn't use takeoff from a hangar - BrakeIsOn = true + if VertTakeOff or AutoTakeoff then + OrbitAchieved = false + GearExtended = false + Nav.control.retractLandingGears() + Nav.axisCommandManager:setTargetGroundAltitude(500) -- Hard set this for takeoff, you wouldn't use takeoff from a hangar + BrakeIsOn = true + end end end @@ -1126,7 +1172,7 @@ function ToggleAltitudeHold() Reentry = false autoRoll = true LockPitch = nil - if (hoverDetectGround() == -1) or not inAtmo or (antigrav and antigrav.getState() == 1) then -- Never autotakeoff in space + if (hoverDetectGround() == -1) or not inAtmo then -- Never autotakeoff in space AutoTakeoff = false if ahDoubleClick > -1 then HoldAltitude = coreAltitude end if not spaceLaunch and Nav.axisCommandManager:getAxisCommandType(0) == 0 and not AtmoSpeedAssist then @@ -1218,20 +1264,22 @@ function ToggleAutopilot() --end -- Going to need to add all those conditions here. Let's start with the easiest. if atmosphere() > 0 then - if not AltitudeHold then + -- if not AltitudeHold then -- Autotakeoff gets engaged inside the toggle if conditions are met - if not VectorToTarget then - ToggleVectorToTarget(SpaceTarget) - end - else + -- if not VectorToTarget then + -- ToggleVectorToTarget(SpaceTarget) + -- end + -- else -- Vector to target + OrbitAchieved = false if not VectorToTarget then ToggleVectorToTarget(SpaceTarget) end - end -- TBH... this is the only thing we need to do, make sure Alt Hold is on. + --end -- TBH... this is the only thing we need to do, make sure Alt Hold is on. else if coreAltitude > 100000 or coreAltitude == 0 then --spaceLaunch = true + OrbitAchieved = false Autopilot = true else spaceLand = true @@ -1250,6 +1298,10 @@ function ToggleAutopilot() end end elseif atmosphere() == 0 then -- Planetary autopilot + local nearPlanet = unit.getClosestPlanetInfluence() > 0 + if CustomTarget == nil and (autopilotTargetPlanet.name == planet.name and nearPlanet) then + ToggleIntoOrbit() -- this works much better here + else Autopilot = true RetrogradeIsOn = false ProgradeIsOn = false @@ -1262,6 +1314,7 @@ function ToggleAutopilot() apThrottleSet = false LockPitch = nil WaypointSet = false + end else spaceLaunch = true ToggleAltitudeHold() @@ -1325,6 +1378,7 @@ function BrakeToggle() BrakeLanding = false AutoLanding = false AltitudeHold = false -- And stop alt hold + IntoOrbit = false LockPitch = nil autoRoll = autoRollPreference spaceLand = false @@ -1923,17 +1977,20 @@ function SetupButtons() MakeButton("Engage Autoland", "Disable Autoland", buttonWidth, buttonHeight, x, y, function() return AutoLanding end, ToggleAutoLanding) - if VertTakeOffEngine then - MakeButton("Engage Vertical Takeoff", "Disable Vertical Takeoff", buttonWidth, buttonHeight, x + buttonWidth + 20, y, - function() - return VertTakeOff - end, ToggleAutoTakeoff) + local engageMsg, dengageMsg, tOSwitch + if VertTakeOffEngine then + engageMsg = "Engage Vertical Takeoff" + dengageMsg = "Disable Vertical Takeoff" + tOSwitch = VertTakeOff else - MakeButton("Engage Auto Takeoff", "Disable Auto Takeoff", buttonWidth, buttonHeight, x + buttonWidth + 20, y, + engageMsg = "Engage Auto Takeoff" + dengageMsg = "Disable Auto Takeoff" + tOSwitch = AutoTakeoff + end + MakeButton(engageMsg, dengageMsg, buttonWidth, buttonHeight, x + buttonWidth + 20, y, function() - return AutoTakeoff + return tOSwitch end, ToggleAutoTakeoff) - end y = y + buttonHeight + 20 MakeButton("Show Orbit Display", "Hide Orbit Display", buttonWidth, buttonHeight, x, y, function() @@ -2872,7 +2929,7 @@ function DrawWarnings(newContent) atmoDistance = math.min(nearSide,farSide) end if AltitudeHold then - if AutoTakeoff then + if AutoTakeoff and not IntoOrbit then local displayText, displayUnit = getDistanceDisplayString(HoldAltitude) newContent[#newContent + 1] = stringf([[Ascent to %s]], warningX, apY, displayText.. displayUnit) @@ -2887,7 +2944,7 @@ function DrawWarnings(newContent) warningX, apY, displayText.. displayUnit) end end - if VertTakeOff then + if VertTakeOff and (antigrav ~= nil and antigrav) then if atmosphere() > 0.1 then newContent[#newContent + 1] = stringf([[Beginning ascent]], warningX, apY) @@ -2896,7 +2953,7 @@ function DrawWarnings(newContent) warningX, apY) elseif atmosphere() < 0.05 then newContent[#newContent + 1] = stringf([[Leaving atmosphere]], - warningX, apY, VertTargetPlanet.name) + warningX, apY) end end if IntoOrbit then @@ -2932,7 +2989,7 @@ function DrawWarnings(newContent) warningX, turnBurnY,intersectBody.name,displayCollisionType, FormatTimeString(travelTime), displayText.. displayUnit) end - if VectorToTarget then + if VectorToTarget and not IntoOrbit then newContent[#newContent + 1] = stringf([[%s]], warningX, apY+30, VectorStatus) end @@ -5484,7 +5541,7 @@ function safeZone(WorldPos) -- Thanks to @SeM for the base code, modified to wor -- Start of actual HUD Script. Written by Dimencia and Archaegeo. Optimization and Automation of scripting by ChronosWS Linked sources where appropriate, most have been modified. function script.onStart() - VERSION_NUMBER = 5.4 + VERSION_NUMBER = 5.42 SetupComplete = false beginSetup = coroutine.create(function() Nav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, @@ -5588,6 +5645,25 @@ function script.onStop() end +local function cmdThrottle(value, dontSwitch) + if dontSwitch == nil then + dontSwitch = false + end + if Nav.axisCommandManager:getAxisCommandType(0) ~= axisCommandType.byThrottle and not dontSwitch then + Nav.control.cancelCurrentControlMasterMode() + end + Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, value) +end +local function cmdCruise(value, dontSwitch) + if dontSwitch == nil then + dontSwitch = false + end + if Nav.axisCommandManager:getAxisCommandType(0) ~= axisCommandType.byTargetSpeed and not dontSwitch then + Nav.control.cancelCurrentControlMasterMode() + end + Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, value) +end + function script.onTick(timerId) if timerId == "tenthSecond" then if atmosphere() > 0 and not WasInAtmo then @@ -5859,8 +5935,7 @@ function script.onTick(timerId) local worldV = vec3(core.getWorldVertical()) local worldPos = vec3(core.getConstructWorldPos()) - - local localVel = core.getVelocity() + --local localVel = core.getVelocity() --local currentYaw = getRelativeYaw(localVel) --local currentPitch = getRelativePitch(localVel) local roll = getRoll(worldV, constrF, constrR) @@ -6017,10 +6092,7 @@ function script.onTick(timerId) --autoRoll = autoRollPreference BeginReentry() else - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then - Nav.control.cancelCurrentControlMasterMode() - end -- Force cruise to 0 so it brakes for us and prepares for next step - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, math.floor(adjustedAtmoSpeedLimit)) -- Trouble drawing if it's not an int + cmdCruise(math.floor(adjustedAtmoSpeedLimit)) -- Trouble drawing if it's not an int PlayerThrottle = 0 end elseif velMag > minAutopilotSpeed then @@ -6052,6 +6124,284 @@ function script.onTick(timerId) ToggleAutopilot() finalLand = false end + + if VertTakeOff then + autoRoll = true + VertTakeOffMode = string.lower(VertTakeOffMode) + if VertTakeOffMode == "agg" and not ExternalAGG and antigrav ~= nil then + antigrav.activate() + antigrav.show() + if coreAltitude < (antigrav.getBaseAltitude() - 100) then + VtPitch = 0 + upAmount = 15 + BrakeIsOn = false + elseif vSpd > 0 then + BrakeIsOn = true + upAmount = 0 + elseif vSpd < -5 then + BrakeIsOn = true + upAmount = 15 + elseif coreAltitude >= antigrav.getBaseAltitude() then + BrakeIsOn = true + upAmount = 0 + VertTakeOff = false + msgText = "Singularity engaged" + end + elseif VertTakeOffMode == "orbit" then + if vSpd < -30 then -- saftey net + msgText = "Unable to take off. Landing." + upAmount = 0 + autoRoll = autoRollPreference + VertTakeOff = false + BrakeLanding = true + elseif atmosphere() > 0.08 then + VtPitch = 0 + BrakeIsOn = false + upAmount = 20 + elseif atmosphere() < 0.08 and atmosphere() > 0 then + BrakeIsOn = false + if SpaceEngineVertDn then + VtPitch = 0 + upAmount = 20 + else + upAmount = 0 + VtPitch = 36 + cmdCruise(3500) + end + else + autoRoll = autoRollPreference + IntoOrbit = true + OrbitAchieved = false + CancelIntoOrbit = false + orbitAligned = false + orbitPitch = nil + orbitRoll = nil + if OrbitTargetPlanet == nil then + OrbitTargetPlanet = planet + end + VertTakeOff = false + end + else -- stops them from doing bad things and check your settings + msgText = "Incorrect settings for ship configuration. Takeoff aborted." + autoRoll = autoRollPreference + VertTakeOff = false + BrakeLanding = true + end + if VtPitch ~= nil then + if (vTpitchPID == nil) then + vTpitchPID = pid.new(2 * 0.01, 0, 2 * 0.1) + end + local vTpitchDiff = utils.clamp(VtPitch-adjustedPitch, -PitchStallAngle*0.85, PitchStallAngle*0.85) + vTpitchPID:inject(vTpitchDiff) + local vTPitchInput = utils.clamp(vTpitchPID:get(),-1,1) + pitchInput2 = vTPitchInput + end + end + + if IntoOrbit then + if AutoTakeoff or VectorToTarget then + if VectorToTarget then + if OrbitTargetPlanet == nil then + OrbitTargetPlanet = autopilotTargetPlanet + end + orbitalVectorToTarget = VectorToTarget --storing for later. VectorToTarget interferes. + end + if OrbitTargetPlanet == nil then + OrbitTargetPlanet = planet + end + AltitudeHold = false + Autopilot = false + VectorToTarget = false + orbitAligned = true + end + local escapeVel, endSpeed = Kep(OrbitTargetPlanet):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-OrbitTargetPlanet.center):len()-OrbitTargetPlanet.radius) + local orbitalRoll = roll + if not OrbitTargetSet then + if OrbitTargetPlanet.hasAtmosphere then + OrbitTargetOrbit = math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1) + OrbitTargetPlanet.noAtmosphericDensityAltitude) + else + OrbitTargetOrbit = math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1) + OrbitTargetPlanet.surfaceMaxAltitude) + end + if orbitalVectorToTarget or AutoTakeoff then + OrbitTargetOrbit = AutoTakeoffAltitude + AutoTakeoff = false -- turn these off, we've taken over. + end + OrbitTargetSet = true + end + if HoldAltitude > OrbitTargetOrbit then OrbitTargetOrbit = HoldAltitude end + -- Getting as close to orbit distance as comfortably possible + if orbit.periapsis ~= nil and orbit.eccentricity < 1 and coreAltitude > OrbitTargetOrbit and coreAltitude < OrbitTargetOrbit*1.3 and orbit.periapsis.altitude > 0 then + local function orbitThrottle(value, orbitalpitch) + orbitPitch = orbitalpitch + if adjustedPitch <= orbitalpitch+3 and adjustedPitch >= orbitalpitch-3 then + PlayerThrottle=value + cmdThrottle(value) + else + PlayerThrottle = 0.05 + cmdThrottle(0.05) + end + end + if orbit.apoapsis ~= nil then + if orbit.periapsis.altitude > OrbitTargetOrbit*0.9 and orbit.periapsis.altitude < OrbitTargetOrbit*1.2 and orbit.apoapsis.altitude > orbit.periapsis.altitude and orbit.apoapsis.altitude <= orbit.periapsis.altitude*1.35 then -- conditions for a near perfect orbit + BrakeIsOn = false + PlayerThrottle = 0 + cmdThrottle(0) + OrbitAchieved = true + if adjustedPitch > 2 or adjustedPitch < -2 then + orbitPitch = 0 + else + orbitMsg = nil + orbitalRecover = false + OrbitTargetSet = false + OrbitTargetPlanet = nil + autoRoll = autoRollPreference + msgText = "Orbit established" + if orbitalVectorToTarget then + VectorToTarget = orbitalVectorToTarget -- turn it back on. + end + orbitalVectorToTarget = false + CancelIntoOrbit = false + IntoOrbit = false + orbitAligned = false + orbitPitch = nil + orbitRoll = nil + OrbitTargetPlanet = nil + + end + else + orbitMsg = "Adjusting Orbit" + orbitalRecover = true + if orbit.periapsis.altitude < OrbitTargetOrbit then + if orbit.apoapsis.altitude > orbit.periapsis.altitude*1.25 then + if velMag+10 > endSpeed then + if vSpd > 15 then + orbitThrottle(0.5,-80) + BrakeIsOn = false + elseif vSpd < -15 then + orbitThrottle(0.5,80) + BrakeIsOn = false + else + cmdThrottle(0) + BrakeIsOn = true + end + elseif velMag-10 < endSpeed then + orbitThrottle(0.5,80) + BrakeIsOn = false + else + cmdThrottle(0) + BrakeIsOn = true + end + else + orbitThrottle(0.5,80) + BrakeIsOn = false + end + else + if orbit.apoapsis.altitude > orbit.periapsis.altitude*1.25 then + cmdThrottle(0) + BrakeIsOn = true + elseif orbit.periapsis.altitude < OrbitTargetOrbit*1.2 then + orbitThrottle(0.5,-80) + BrakeIsOn = false + end + end + end + end + else + local orbitalMultiplier = 2.75 + local pcs = math.abs(utils.round(escapeVel*orbitalMultiplier)) + local mod = pcs%50 + if mod > 0 then pcs = (pcs - mod) + 50 end + BrakeIsOn = false + if not orbitAligned then + local pitchAligned = false + local rollAligned = false + if coreAltitude < OrbitTargetOrbit then + orbitMsg = "Aligning to orbital path" + else + -- TODO: Target a point in space at the proper distance and point there. + orbitMsg = "Aligning to orbital point" + end + orbitPitch = 0 + orbitRoll = 0 + if adjustedPitch <= orbitPitch+1 and adjustedPitch >= orbitPitch-1 then + pitchAligned = true + else + pitchAligned = false + end + if orbitalRoll <= orbitRoll+1 and orbitalRoll >= orbitRoll-1 then + rollAligned = true + else + rollAligned = false + end + if pitchAligned and rollAligned then + orbitPitch = nil + orbitRoll = nil + orbitAligned = true + end + else + if coreAltitude < OrbitTargetOrbit*0.8 then + orbitMsg = "Escaping planet gravity" + orbitPitch = 35 + elseif coreAltitude >= OrbitTargetOrbit*0.8 and coreAltitude < OrbitTargetOrbit*1.01 then + orbitMsg = "Approaching orbital corridor" + if vSpd > 100 then + pcs = pcs*0.75 + orbitPitch = -50 + else + orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*0.6, OrbitTargetOrbit, 35, 0) + end + elseif coreAltitude >= OrbitTargetOrbit*1.01 and coreAltitude < OrbitTargetOrbit*1.5 then + orbitMsg = "Approaching orbital corridor" + if vSpd < 0 or orbitalRecover then + orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*1.5, OrbitTargetOrbit*1.01, -30, 0) -- Going down? pitch up. + else + orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*0.99, OrbitTargetOrbit*1.5, 0, 30) -- Going up? pitch down. + end + elseif coreAltitude > OrbitTargetOrbit*1.5 then + orbitMsg = "Reentering orbital corridor" + if vSpd < -100 then + orbitPitch = 45 + pcs = pcs*1.25 + else + orbitPitch = -80 + pcs = pcs*0.75 + end + end + end + cmdCruise(math.floor(pcs)) + end + if orbitPitch ~= nil then + if (OrbitPitchPID == nil) then + OrbitPitchPID = pid.new(2 * 0.01, 0, 2 * 0.1) + end + local orbitPitchDiff = orbitPitch - adjustedPitch + OrbitPitchPID:inject(orbitPitchDiff) + local orbitPitchInput = utils.clamp(OrbitPitchPID:get(),-0.5,0.5) + pitchInput2 = orbitPitchInput + end + if orbitRoll ~= nil then + if adjustedPitch < 85 then + local rollFactor = math.max(autoRollFactor, 0.01)/4 + if (OrbitRollPID == nil) then + OrbitRollPID = pid.new(rollFactor * 0.01, 0, rollFactor * 0.1) + end + local orbitalRollDiff = orbitRoll - orbitalRoll + OrbitRollPID:inject(orbitalRollDiff) + local orbitRollInput = utils.clamp(OrbitRollPID:get(),-0.5,0.5) + rollInput2 = orbitRollInput + end + end + elseif CancelIntoOrbit then + -- BrakeIsOn = true + -- brakeInput = 1 + -- msgText = "Orbitting cancelled, parking" + OrbitTargetSet = false + OrbitAchieved = false + OrbitTargetPlanet = nil + cmdThrottle(0) + CancelIntoOrbit = false + end + if Autopilot and atmosphere() == 0 and not spaceLand then -- Planetary autopilot engaged, we are out of atmo, and it has a target -- Do it. @@ -6060,25 +6410,21 @@ function script.onTick(timerId) -- Maybe instead of pointing at our vector, we point at our vector + how far off our velocity vector is -- This is gonna be hard to get the negatives right. -- If we're still in orbit, don't do anything, that velocity will suck - local targetCoords = AutopilotTargetCoords + local targetCoords, skipAlign = AutopilotTargetCoords, false -- This isn't right. Maybe, just take the smallest distance vector between the normal one, and the wrongSide calculated one --local wrongSide = (CustomTarget.position-worldPos):len() > (autopilotTargetPlanet.center-worldPos):len() - local skipAlign = false - if CustomTarget ~= nil and CustomTarget.planetname ~= "Space" then AutopilotRealigned = true -- Don't realign, point straight at the target. Or rather, at AutopilotTargetOrbit above it - - -- It's on the wrong side of the planet. - -- So, get the 3d direction between our target and planet center. Note that, this is basically a vector defining gravity at our target, too... - local initialDirection = (CustomTarget.position - autopilotTargetPlanet.center):normalize() -- Should be pointing up - local finalDirection = initialDirection:project_on_plane((autopilotTargetPlanet.center-worldPos):normalize()):normalize() - - -- And... actually that's all that I need. If forward is really gone, this should give us a point on the edge of the planet - local wrongSideCoords = autopilotTargetPlanet.center + finalDirection*(autopilotTargetPlanet.radius + AutopilotTargetOrbit) - -- This used to be calculated based on our direction instead of gravity, which helped us approach not directly overtop it - -- But that caused bad things to happen for nearside/farside detection sometimes - local rightSideCoords = CustomTarget.position + (CustomTarget.position - autopilotTargetPlanet.center):normalize() * (AutopilotTargetOrbit - autopilotTargetPlanet:getAltitude(CustomTarget.position)) if not TargetSet then + -- It's on the wrong side of the planet. + -- So, get the 3d direction between our target and planet center. Note that, this is basically a vector defining gravity at our target, too... + local initialDirection = (CustomTarget.position - autopilotTargetPlanet.center):normalize() -- Should be pointing up + local finalDirection = initialDirection:project_on_plane((autopilotTargetPlanet.center-worldPos):normalize()):normalize() + -- And... actually that's all that I need. If forward is really gone, this should give us a point on the edge of the planet + local wrongSideCoords = autopilotTargetPlanet.center + finalDirection*(autopilotTargetPlanet.radius + AutopilotTargetOrbit) + -- This used to be calculated based on our direction instead of gravity, which helped us approach not directly overtop it + -- But that caused bad things to happen for nearside/farside detection sometimes + local rightSideCoords = CustomTarget.position + (CustomTarget.position - autopilotTargetPlanet.center):normalize() * (AutopilotTargetOrbit - autopilotTargetPlanet:getAltitude(CustomTarget.position)) --system.print("WrongSide is " .. (worldPos-wrongSideCoords):len() .. ", rightSide is " .. (worldPos-rightSideCoords):len()) if (worldPos-wrongSideCoords):len() < (worldPos-rightSideCoords):len() then --system.print("Taking WrongSide") @@ -6096,13 +6442,22 @@ function script.onTick(timerId) end --AutopilotPlanetGravity = autopilotTargetPlanet.gravity*9.8 -- Since we're aiming straight at it, we have to assume gravity? AutopilotPlanetGravity = 0 + -- if autopilotTargetPlanet.name == planet.name then + -- if not OrbitAchieved then + -- IntoOrbit = true + -- OrbitTargetSet = false + -- OrbitTargetPlanet = autopilotTargetPlanet + -- else + -- AutopilotCruising = true + -- end + -- end elseif CustomTarget ~= nil and CustomTarget.planetname == "Space" then AutopilotPlanetGravity = 0 skipAlign = true TargetSet = true AutopilotRealigned = true targetCoords = CustomTarget.position + (worldPos - CustomTarget.position)*AutopilotTargetOrbit - elseif CustomTarget == nil then + elseif CustomTarget == nil then -- and not autopilotTargetPlanet.name == planet.name then AutopilotPlanetGravity = 0 if not TargetSet then @@ -6238,7 +6593,7 @@ function script.onTick(timerId) --elseif not apThrottleSet then if not apThrottleSet then BrakeIsOn = false - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, AutopilotInterplanetaryThrottle) + cmdThrottle(AutopilotInterplanetaryThrottle) PlayerThrottle = round(AutopilotInterplanetaryThrottle,2) apThrottleSet = true end @@ -6248,7 +6603,7 @@ function script.onTick(timerId) AutopilotAccelerating = false AutopilotStatus = "Cruising" AutopilotCruising = true - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 --apThrottleSet = false -- We already did it, if they cancelled let them throttle up again end @@ -6258,7 +6613,7 @@ function script.onTick(timerId) AutopilotAccelerating = false AutopilotStatus = "Braking" AutopilotBraking = true - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 apThrottleSet = false end @@ -6268,7 +6623,7 @@ function script.onTick(timerId) brakeInput = 1 end if TurnBurn then - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 100) -- This stays 100 to not mess up our calculations + cmdThrottle(100,true) -- This stays 100 to not mess up our calculations PlayerThrottle = 1 end -- Check if an orbit has been established and cut brakes and disable autopilot if so @@ -6278,11 +6633,11 @@ function script.onTick(timerId) local _, endSpeed = Kep(autopilotTargetPlanet):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius) - local targetVec, targetAltitude, horizontalDistance + local targetVec--, targetAltitude, --horizontalDistance if CustomTarget ~= nil then targetVec = CustomTarget.position - worldPos - targetAltitude = planet:getAltitude(CustomTarget.position) - horizontalDistance = math.sqrt(targetVec:len()^2-(coreAltitude-targetAltitude)^2) + --targetAltitude = planet:getAltitude(CustomTarget.position) + --horizontalDistance = math.sqrt(targetVec:len()^2-(coreAltitude-targetAltitude)^2) --system.print(horizontalDistance .. "m, or " .. velocity:normalize():dot(targetVec:normalize())) end if (CustomTarget ~=nil and CustomTarget.planetname == "Space" and velMag < 50) then @@ -6302,7 +6657,7 @@ function script.onTick(timerId) TargetSet = false AutopilotStatus = "Aligning" -- Disable autopilot and reset --brakeInput = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 apThrottleSet = false ProgradeIsOn = true @@ -6312,12 +6667,9 @@ function script.onTick(timerId) system.setWaypoint(waypoint) elseif orbit.periapsis ~= nil and orbit.periapsis.altitude > 0 and orbit.eccentricity < 1 then AutopilotStatus = "Circularizing" - -- Calculate the appropriate speed for the altitude we are from the target planet. These speeds would be lower further out so, shouldn't trigger early local _, endSpeed = Kep(autopilotTargetPlanet):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius) - --if (orbit.eccentricity > lastEccentricity and orbit.eccentricity < 0.5) or if velMag <= endSpeed then --or(orbit.apoapsis.altitude < AutopilotTargetOrbit and orbit.periapsis.altitude < AutopilotTargetOrbit) then if CustomTarget ~= nil then - if velocity:normalize():dot(targetVec:normalize()) > 0.4 then -- Triggers when we get close to passing it AutopilotStatus = "Orbiting to Target" --brakeInput = 0 @@ -6330,7 +6682,7 @@ function script.onTick(timerId) system.setWaypoint(waypoint) WaypointSet = true end - else + else msgText = "Autopilot complete, proceeding with reentry" --BrakeIsOn = false -- Leave brakes on to be safe while we align prograde AutopilotTargetCoords = CustomTarget.position -- For setting the waypoint @@ -6339,7 +6691,7 @@ function script.onTick(timerId) TargetSet = false AutopilotStatus = "Aligning" -- Disable autopilot and reset --brakeInput = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 apThrottleSet = false ProgradeIsOn = true @@ -6359,7 +6711,6 @@ function script.onTick(timerId) -- TODO: This is being added to newContent *after* we already drew the screen, so it'll never get displayed msgText = "Autopilot completed, orbit established" brakeInput = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) PlayerThrottle = 0 apThrottleSet = false if CustomTarget ~= nil and CustomTarget.planetname ~= "Space" then @@ -6401,8 +6752,9 @@ function script.onTick(timerId) AutopilotStatus = "Accelerating" -- Set throttle to max if not apThrottleSet then - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, - AutopilotInterplanetaryThrottle) + cmdThrottle(AutopilotInterplanetaryThrottle, true) + -- Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, + -- AutopilotInterplanetaryThrottle) PlayerThrottle = round(AutopilotInterplanetaryThrottle,2) apThrottleSet = true BrakeIsOn = false @@ -6421,7 +6773,7 @@ function script.onTick(timerId) TargetSet = false AutopilotStatus = "Aligning" -- Disable autopilot and reset brakeInput = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 apThrottleSet = false ProgradeIsOn = true @@ -6481,244 +6833,6 @@ function script.onTick(timerId) end end - if VertTakeOff then - Autopilot = false -- make sure to shut this off for now. - AltitudeHold = false -- Doesn't work for vtol. Shut this off for now. - if VertTargetPlanet == nil then -- Set it once so it doesn't change. Helps when leaving the influence of a planet. - VertTargetPlanet = planet - end - local upVel = -vec3(core.getWorldVertical()):dot(vec3(core.getWorldVelocity())) - local tPitch = nil - if atmosphere() > 0.08 then -- Go straight up - tPitch = 0 - autoRoll = true - BrakeIsOn = false - upAmount = upAmount + 1 -- Only way to make the engines react. - Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization() - Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1) - elseif atmosphere() < 0.08 and atmosphere() > 0 then -- stop , pitch up, and start moving away from planet. - upAmount = 0 - Nav.axisCommandManager:activateGroundEngineAltitudeStabilization() - Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 0) - tPitch = 36 - if upVel < 10 then - BrakeIsOn = true - brakeInput = 1 - else - BrakeIsOn = false - end - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then - Nav.control.cancelCurrentControlMasterMode() - end - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, 3500) -- Space Engines don't turn on when using throttle while in atmo. - -- Cruise solves this. Also, makes orbits easy. - else -- Out of planet atmo, get to orbit - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then - Nav.control.cancelCurrentControlMasterMode() - end - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, 0) - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed then - Nav.control.cancelCurrentControlMasterMode() - end - PlayerThrottle = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) - Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical, 0) - BrakeIsOn = true - brakeInput = 1 - msgText = "Takeoff completed. Parking." - ToggleAutoTakeoff() - end - if tPitch ~= nil then - if (vTpitchPID == nil) then - vTpitchPID = pid.new(2 * 0.01, 0, 2 * 0.1) - end - local vTpitchDiff = utils.clamp(tPitch-adjustedPitch, -PitchStallAngle*0.85, PitchStallAngle*0.85) - vTpitchPID:inject(vTpitchDiff) - local vTPitchInput = utils.clamp(vTpitchPID:get(),-1,1) - pitchInput2 = vTPitchInput - end - end - - if IntoOrbit then - local upVel = -vec3(core.getWorldVertical()):dot(vec3(core.getWorldVelocity())) - local escapeVel, endSpeed = Kep(OrbitTargetPlanet):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-OrbitTargetPlanet.center):len()-OrbitTargetPlanet.radius) - local orbitalRoll = getRoll(worldV, constrF, constrR) - if not OrbitTargetSet then - if OrbitTargetPlanet.hasAtmosphere then - OrbitTargetOrbit = math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1) + OrbitTargetPlanet.noAtmosphericDensityAltitude) - else - OrbitTargetOrbit = math.floor(OrbitTargetPlanet.radius*(TargetOrbitRadius-1) + OrbitTargetPlanet.surfaceMaxAltitude) - end - OrbitTargetSet = true - end - -- Getting as close to orbit distance as comfortably possible - if orbit.periapsis ~= nil and orbit.eccentricity < 1 and coreAltitude > OrbitTargetOrbit and coreAltitude < OrbitTargetOrbit*1.3 and orbit.periapsis.altitude > 0 then - if orbit.apoapsis ~= nil then - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed then - Nav.control.cancelCurrentControlMasterMode() - end - if orbit.periapsis.altitude > OrbitTargetOrbit*0.9 and orbit.periapsis.altitude < OrbitTargetOrbit*1.2 and orbit.apoapsis.altitude > orbit.periapsis.altitude and orbit.apoapsis.altitude <= orbit.periapsis.altitude*1.35 then -- conditions for a near perfect orbit - BrakeIsOn = false - PlayerThrottle = 0 - orbitThrottle = 0 - orbitCruiseSpeed = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) - Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical, 0) - OrbitAchieved = true - if adjustedPitch > 2 or adjustedPitch < -2 then - orbitPitch = 0 - else - msgText = "Orbit established" - orbitMsg = nil - orbitalRecover = false - OrbitTargetSet = false - OrbitTargetPlanet = nil - autoRoll = autoRollPreference - ToggleIntoOrbit() -- turn off sequence - end - else - orbitMsg = "Adjusting Orbit" - orbitalRecover = true - if orbit.periapsis.altitude < OrbitTargetOrbit then - if orbit.apoapsis.altitude > orbit.periapsis.altitude*1.25 then - if velMag+10 > endSpeed then - if upVel > 15 then - orbitPitch = -80 - orbitThrottle = 0.5 - BrakeIsOn = false - elseif upVel < -15 then - orbitPitch = 80 - orbitThrottle = 0.5 - BrakeIsOn = false - else - orbitThrottle = 0 - BrakeIsOn = true - end - elseif velMag-10 < endSpeed then - orbitPitch = 80 - orbitThrottle = 0.5 - BrakeIsOn = false - else - orbitThrottle = 0 - BrakeIsOn = true - end - else - orbitPitch = 80 - orbitThrottle = 0.5 - BrakeIsOn = false - end - else - if orbit.apoapsis.altitude > orbit.periapsis.altitude*1.25 then - orbitThrottle = 0 - BrakeIsOn = true - elseif orbit.periapsis.altitude < OrbitTargetOrbit*1.2 then - orbitPitch = -80 - orbitThrottle = 0.5 - BrakeIsOn = false - end - end - end - end - if orbitThrottle > 0 and adjustedPitch <= orbitPitch+3 and adjustedPitch >= orbitPitch-3 then - PlayerThrottle = orbitThrottle - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, orbitThrottle) - elseif not OrbitAchieved then - PlayerThrottle = 0.05 -- Keep the engines warm - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0.05) - end - else - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then - Nav.control.cancelCurrentControlMasterMode() - end - local mod = escapeVel%50 - local pcs = 0 - if mod > 0 then pcs = escapeVel - mod + 50 else pcs = escapeVel end - BrakeIsOn = false - orbitCruiseSpeed = pcs*2.5 - if not orbitAligned then - local pitchAligned = false - local rollAligned = false - if coreAltitude < OrbitTargetOrbit then - orbitMsg = "Aligning to orbital path" - else - -- TODO: Target a point in space at the proper distance and point there. - orbitMsg = "Aligning to orbital point" - end - orbitPitch = 0 - orbitRoll = 0 - if adjustedPitch <= orbitPitch+1 and adjustedPitch >= orbitPitch-1 then - pitchAligned = true - else - pitchAligned = false - end - if orbitalRoll <= orbitRoll+1 and orbitalRoll >= orbitRoll-1 then - rollAligned = true - else - rollAligned = false - end - if pitchAligned and rollAligned then - orbitPitch = nil - orbitRoll = nil - orbitAligned = true - end - else - if coreAltitude < OrbitTargetOrbit*0.8 then - orbitMsg = "Escaping planet gravity" - orbitPitch = 35 - elseif coreAltitude >= OrbitTargetOrbit*0.8 and coreAltitude < OrbitTargetOrbit*1.01 then - orbitMsg = "Approaching orbital corridor" - orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*0.6, OrbitTargetOrbit, 35, 0) - elseif coreAltitude >= OrbitTargetOrbit*1.01 and coreAltitude < OrbitTargetOrbit*1.5 then - orbitMsg = "Approaching orbital corridor" - if upVel < 0 or orbitalRecover then - orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*1.5, OrbitTargetOrbit*1.01, -30, 0) -- Going down? pitch up. - else - orbitPitch = utils.map(coreAltitude, OrbitTargetOrbit*0.99, OrbitTargetOrbit*1.5, 0, 30) -- Going up? pitch down. - end - elseif coreAltitude > OrbitTargetOrbit*1.5 then - orbitPitch = -80 - orbitMsg = "Reentering orbital corridor" - end - end - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, orbitCruiseSpeed) - end - if orbitPitch ~= nil then - if (OrbitPitchPID == nil) then - OrbitPitchPID = pid.new(2 * 0.01, 0, 2 * 0.1) - end - local orbitPitchDiff = orbitPitch - adjustedPitch - OrbitPitchPID:inject(orbitPitchDiff) - local orbitPitchInput = utils.clamp(OrbitPitchPID:get(),-0.5,0.5) - pitchInput2 = orbitPitchInput - end - if orbitRoll ~= nil then - if adjustedPitch < 85 then - local rollFactor = math.max(autoRollFactor, 0.01)/4 - if (OrbitRollPID == nil) then - OrbitRollPID = pid.new(rollFactor * 0.01, 0, rollFactor * 0.1) - end - local orbitalRollDiff = orbitRoll - orbitalRoll - OrbitRollPID:inject(orbitalRollDiff) - local orbitRollInput = utils.clamp(OrbitRollPID:get(),-0.5,0.5) - rollInput2 = orbitRollInput - end - end - elseif CancelIntoOrbit then - BrakeIsOn = true - brakeInput = 1 - msgText = "Orbitting cancelled, parking" - OrbitTargetSet = false - OrbitTargetPlanet = nil - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed then - Nav.control.cancelCurrentControlMasterMode() - end - PlayerThrottle = 0 - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) - Nav.axisCommandManager:setThrottleCommand(axisCommandId.vertical, 0) - CancelIntoOrbit = false - end - - if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch ~= nil then -- HoldAltitude is the alt we want to hold at local nearPlanet = unit.getClosestPlanetInfluence() > 0 @@ -6732,6 +6846,17 @@ function script.onTick(timerId) if AutoTakeoff then velMultiplier = utils.clamp(velMag/100,0.1,1) end local targetPitch = (utils.smoothstep(altDiff, -minmax, minmax) - 0.5) * 2 * MaxPitch * velMultiplier + if atmosphere() == 0 and (autopilotTargetPlanet ~= nil and autopilotTargetPlanet.name == planet.name) and not VectorToTarget and not Reentry and not BrakeLanding and LockPitch == nil and coreAltitude < HoldAltitude then + if not OrbitAchieved then + --Autopilot = true + spaceLaunch = false + AltitudeHold = false + IntoOrbit = true + OrbitTargetSet = false + OrbitTargetPlanet = autopilotTargetPlanet + end + end + -- atmosphere() == 0 and --system.print(constrF:dot(velocity:normalize())) if not Reentry and not spaceLand and not VectorToTarget and constrF:dot(velocity:normalize()) < 0.99 then @@ -6749,7 +6874,7 @@ function script.onTick(timerId) targetPitch = 0 end if LockPitch ~= nil then - if nearPlanet then + if nearPlanet and not IntoOrbit then targetPitch = LockPitch else LockPitch = nil @@ -6783,11 +6908,12 @@ function script.onTick(timerId) BrakeIsOn = false end - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) ~= ReentrySpeed then -- This thing is dumb. - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, ReentrySpeed) - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical, 0) - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral, 0) - end + -- if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) ~= ReentrySpeed then -- This thing is dumb. + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, ReentrySpeed) + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical, 0) + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral, 0) + -- end + cmdCruise(ReentrySpeed, true) -- I agree, this is dumb. if not reentryMode then targetPitch = -80 if atmosphere() > 0.02 then @@ -6805,12 +6931,13 @@ function script.onTick(timerId) --end autoRoll = true -- It shouldn't actually do it, except while aligning elseif coreAltitude <= planet.noAtmosphericDensityAltitude + 5000 then - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then -- Cancel throttle - Nav.control.cancelCurrentControlMasterMode() - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, ReentrySpeed) - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical, 0) - Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral, 0) - end -- Then we have to wait a tick for it to take our new speed. + -- if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then -- Cancel throttle + -- Nav.control.cancelCurrentControlMasterMode() + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal, ReentrySpeed) + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical, 0) + -- Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral, 0) + -- end + cmdCruise(ReentrySpeed)-- Then we have to wait a tick for it to take our new speed. if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed and Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == adjustedAtmoSpeedLimit then --targetPitch = -MaxPitch -- It will handle pitching for us after this. reentryMode = false @@ -6825,7 +6952,6 @@ function script.onTick(timerId) -- local targetPitch = utils.clamp(altDiff,-20,20) -- Clamp to reasonable values -- Align it prograde but keep whatever pitch inputs they gave us before, and ignore pitch input from alignment. -- So, you know, just yaw. - if velMag > minAutopilotSpeed and not spaceLaunch and not VectorToTarget and not BrakeLanding and ForceAlignment then -- When do we even need this, just alt hold? lol AlignToWorldVector(vec3(velocity)) end @@ -6841,7 +6967,7 @@ function script.onTick(timerId) -- then PID the yaw to that value, with a max value of StallAngle -- Of course, only works if speed is high enough - local constrUp = vec3(core.getConstructWorldOrientationUp()) + --local constrUp = vec3(core.getConstructWorldOrientationUp()) --local vectorInYawDirection = targetVec:project_on_plane(worldV):normalize() --local flatForward = velocity:normalize():project_on_plane(worldV):normalize() -- Possibly necessary after 3d to 2d conversion -- :angle_to uses only .x and .y, literal 2d @@ -6903,8 +7029,7 @@ function script.onTick(timerId) targetPitch = utils.clamp(adjustedPitch-currentPitch,adjustedPitch - PitchStallAngle*0.85, adjustedPitch + PitchStallAngle*0.85) -- Just try to get within un-stalling range to not bounce too much end end - - + if CustomTarget ~= nil and not spaceLaunch then --local distanceToTarget = targetVec:project_on(velocity):len() -- Probably not strictly accurate with curvature but it should work -- Well, maybe not. Really we have a triangle. Of course. @@ -6923,10 +7048,8 @@ function script.onTick(timerId) end if atmosphere() < 0.01 then curBrake = LastMaxBrake -- Assume space brakes - else - end - local vSpd = (velocity.x * up.x) + (velocity.y * up.y) + (velocity.z * up.z) + --local vSpd = (velocity.x * up.x) + (velocity.y * up.y) + (velocity.z * up.z) local hSpd = velocity:len() - math.abs(vSpd) local airFrictionVec = vec3(core.getWorldAirFrictionAcceleration()) local airFriction = math.sqrt(airFrictionVec:len() - airFrictionVec:project_on(up):len()) * constructMass() @@ -6947,15 +7070,14 @@ function script.onTick(timerId) StrongBrakes = true -- We don't care about this or glide landing anymore and idk where all it gets used -- Fudge it with the distance we'll travel in a tick - or half that and the next tick accounts for the other? idk - if not spaceLaunch and distanceToTarget <= brakeDistance + (velMag*deltaTick)/2 and (velocity:project_on_plane(worldV):normalize():dot(targetVec:project_on_plane(worldV):normalize()) > 0.99 or VectorStatus == "Finalizing Approach") then + if not spaceLaunch and not Reentry and distanceToTarget <= brakeDistance + (velMag*deltaTick)/2 and (velocity:project_on_plane(worldV):normalize():dot(targetVec:project_on_plane(worldV):normalize()) > 0.99 or VectorStatus == "Finalizing Approach") then VectorStatus = "Finalizing Approach" - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byTargetSpeed then - Nav.control.cancelCurrentControlMasterMode() - end - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) -- Kill throttle in case they weren't in cruise + cmdThrottle(0) -- Kill throttle in case they weren't in cruise PlayerThrottle = 0 if AltitudeHold then - ToggleAltitudeHold() -- Don't need this anymore + -- if not OrbitAchieved then + ToggleAltitudeHold() -- Don't need this anymore + -- end VectorToTarget = true -- But keep this on end BrakeIsOn = true @@ -6964,11 +7086,50 @@ function script.onTick(timerId) end if VectorStatus == "Finalizing Approach" and (hSpd < 0.1 or distanceToTarget < 0.1 or (LastDistanceToTarget ~= nil and LastDistanceToTarget < distanceToTarget)) then BrakeLanding = true + VectorToTarget = false VectorStatus = "Proceeding to Waypoint" end LastDistanceToTarget = distanceToTarget end + elseif (VectorToTarget or spaceLaunch) and not Reentry and AutopilotTargetIndex > 0 and atmosphere() == 0 and autopilotTargetPlanet.name == planet.name then + if not OrbitAchieved then -- right now this is based solely on if you get out of atmo. It will take AutoTakeOffAltitude and use that height, so if you put it above 7k on alioth, you orbit. + -- eventually I want to make it so I calculate the minimum distance and set a trajectory, and go a few km above amto == 0 and ride the orbit expressway. + -- but only if the distance to get complete orbit is short enough. wouldn't make sense to orbit and overshoot your target... + Autopilot = false + spaceLaunch = false + AltitudeHold = false + IntoOrbit = true + OrbitTargetSet = false + OrbitTargetPlanet = autopilotTargetPlanet + else + local targetVec + if CustomTarget ~= nil then + targetVec = CustomTarget.position - vec3(core.getConstructWorldPos()) + else + targetVec = autopilotTargetPlanet.center - worldPos + end + local targetAltitude = planet:getAltitude(CustomTarget.position) + local distanceToTarget = math.sqrt(targetVec:len()^2-(coreAltitude-targetAltitude)^2) + local curBrake = LastMaxBrakeInAtmo + curBrake = LastMaxBrake + --local hSpd = velocity:len() - math.abs(vSpd) + brakeDistance, brakeTime = Kinematic.computeDistanceAndTime(velMag, 0, constructMass(), 0, 0, curBrake/2) + StrongBrakes = true + if not spaceLaunch and distanceToTarget <= brakeDistance + (velMag*deltaTick)/2 and (velocity:project_on_plane(worldV):normalize():dot(targetVec:project_on_plane(worldV):normalize()) > 0.99 or VectorStatus == "Finalizing Approach") then + if planet.hasAtmosphere then + BrakeIsOn = false + ProgradeIsOn = false + reentryMode = true + spaceLand = false + finalLand = true + Autopilot = false + VectorToTarget = false + BeginReentry() + end + end + LastDistanceToTarget = distanceToTarget + end end if stalling and atmosphere() > 0.01 and hovGndDet == -1 and velMag > minRollVelocity and VectorStatus ~= "Finalizing Approach" then @@ -6979,11 +7140,11 @@ function script.onTick(timerId) pitchInput2 = oldInput local groundDistance = -1 - local autoPitchThreshold = 0.1 + --local autoPitchThreshold = 0.1 if BrakeLanding then targetPitch = 0 - local vSpd = (velocity.x * up.x) + (velocity.y * up.y) + (velocity.z * up.z) + --local vSpd = (velocity.x * up.x) + (velocity.y * up.y) + (velocity.z * up.z) local skipLandingRate = false local distanceToStop = 30 if maxKinematicUp ~= nil and maxKinematicUp > 0 then @@ -7001,7 +7162,7 @@ function script.onTick(timerId) local atmos = utils.clamp(atmosphere(),0.4,2) -- Assume at least 40% atmo when they land, to keep things fast in low atmo local curBrake = LastMaxBrakeInAtmo * utils.clamp(velMag/100,0.1,1) * atmos local totalNewtons = maxKinematicUp * atmos + curBrake + airFriction - gravity -- Ignore air friction for leeway, KinematicUp and Brake are already in newtons - local brakeNewtons = curBrake + airFriction - gravity + --local brakeNewtons = curBrake + airFriction - gravity local weakBreakNewtons = curBrake/2 + airFriction - gravity -- Compute the travel time from current speed, with brake acceleration, for 20m @@ -7111,7 +7272,16 @@ function script.onTick(timerId) if AutoTakeoff or spaceLaunch then local intersectBody, nearSide, farSide = galaxyReference:getPlanetarySystem(0):castIntersections(worldPos, (AutopilotTargetCoords-worldPos):normalize(), function(body) return (body.radius+body.noAtmosphericDensityAltitude) end) - if math.abs(targetPitch) < 15 and (coreAltitude/HoldAltitude) > 0.75 then + if antigrav and antigrav.getState() == 1 then + if coreAltitude >= (HoldAltitude-50) then + AutoTakeoff = false + BrakeIsOn = true + cmdThrottle(0) + PlayerThrottle = 0 + else + HoldAltitude = antigrav.getBaseAltitude() + end + elseif math.abs(targetPitch) < 15 and (coreAltitude/HoldAltitude) > 0.75 then AutoTakeoff = false -- No longer in ascent if not spaceLaunch then if Nav.axisCommandManager:getAxisCommandType(0) == 0 and not AtmoSpeedAssist then @@ -7122,16 +7292,10 @@ function script.onTick(timerId) spaceLaunch = false AltitudeHold = false AutoTakeoff = false - if Nav.axisCommandManager:getAxisCommandType(0) == 1 then - Nav.control.cancelCurrentControlMasterMode() - end - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 elseif spaceLaunch then - if Nav.axisCommandManager:getAxisCommandType(0) ~= 0 then - Nav.control.cancelCurrentControlMasterMode() - end - Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + cmdThrottle(0) PlayerThrottle = 0 BrakeIsOn = true end --coreAltitude > 75000 @@ -7182,9 +7346,9 @@ function script.onTick(timerId) pitchInput2 = pitchInput2 + autoPitchInput end end - lastEccentricity = orbit.eccentricity + --lastEccentricity = orbit.eccentricity - if antigrav and not ExternalAGG and coreAltitude < 200000 then + if antigrav ~= nil and (antigrav and not ExternalAGG and coreAltitude < 200000) then if AntigravTargetAltitude == nil or AntigravTargetAltitude < 1000 then AntigravTargetAltitude = 1000 end if desiredBaseAltitude ~= AntigravTargetAltitude then desiredBaseAltitude = AntigravTargetAltitude @@ -7192,50 +7356,50 @@ function script.onTick(timerId) end end - if AchieveOrbit then -- Try to achieve an orbit. This should only be on when in space. - local orbitAltitude = 1000 - if planet.name ~= "Space" then - if planet.hasAtmosphere then - orbitAltitude = math.floor(planet.radius*(TargetOrbitRadius-1) + planet.noAtmosphericDensityAltitude) - else - orbitAltitude = math.floor(planet.radius*(TargetOrbitRadius-1) + planet.surfaceMaxAltitude) - end - else - orbitAltitude = 1000 - end - - local _, endSpeed = Kep(planet):escapeAndOrbitalSpeed((worldPos-planet.center):len()-planet.radius) - - autoRoll = true - - -- Using the AutopilotTargetOrbit we would calculate for our current nearest planet - -- Figure out a target vector that our velocity should be at - that is, perpendicular to gravity, and toward CustomTarget if not nil - -- Otherwise ship forward if not orbiting to target - local targetVelocityVector - if OrbitToTarget and CustomTarget ~= nil then - -- So we need a vector pointing from our position to the target - -- And project it on a plane defined by worldV, easy - -- Not sure if we need the first normalize or not, might as well - targetVelocityVector = (target.position-worldPos):normalize():project_on_plane(worldV):normalize() - else - targetVelocityVector = constrF:project_on_plane(worldV):normalize() - end - - -- Adjust the vector to account for being above or below target altitude - targetVelocityVector = targetVelocityVector * endSpeed -- Scale based on target speed, and we'll use an un-normalized velocity vector to compare - targetVelocityVector = (targetVelocityVector + -worldV*(coreAltitude - orbitAltitude)):normalize()*endSpeed -- Make sure velocity stays capped - - -- So, this is exactly what we want our velocity vector to look like - - - -- Soo... nothing I do with this is going to really get it to stabilize at an altitude, which is the problem - -- To do that, we really need to get vspeed to 0 - end + -- if AchieveOrbit then -- Try to achieve an orbit. This should only be on when in space. + -- local orbitAltitude = 1000 + -- if planet.name ~= "Space" then + -- if planet.hasAtmosphere then + -- orbitAltitude = math.floor(planet.radius*(TargetOrbitRadius-1) + planet.noAtmosphericDensityAltitude) + -- else + -- orbitAltitude = math.floor(planet.radius*(TargetOrbitRadius-1) + planet.surfaceMaxAltitude) + -- end + -- else + -- orbitAltitude = 1000 + -- end + + -- local _, endSpeed = Kep(planet):escapeAndOrbitalSpeed((worldPos-planet.center):len()-planet.radius) + + -- autoRoll = true + + -- -- Using the AutopilotTargetOrbit we would calculate for our current nearest planet + -- -- Figure out a target vector that our velocity should be at - that is, perpendicular to gravity, and toward CustomTarget if not nil + -- -- Otherwise ship forward if not orbiting to target + -- local targetVelocityVector + -- if OrbitToTarget and CustomTarget ~= nil then + -- -- So we need a vector pointing from our position to the target + -- -- And project it on a plane defined by worldV, easy + -- -- Not sure if we need the first normalize or not, might as well + -- targetVelocityVector = (target.position-worldPos):normalize():project_on_plane(worldV):normalize() + -- else + -- targetVelocityVector = constrF:project_on_plane(worldV):normalize() + -- end + + -- -- Adjust the vector to account for being above or below target altitude + -- targetVelocityVector = targetVelocityVector * endSpeed -- Scale based on target speed, and we'll use an un-normalized velocity vector to compare + -- targetVelocityVector = (targetVelocityVector + -worldV*(coreAltitude - orbitAltitude)):normalize()*endSpeed -- Make sure velocity stays capped + + -- -- So, this is exactly what we want our velocity vector to look like + + + -- -- Soo... nothing I do with this is going to really get it to stabilize at an altitude, which is the problem + -- -- To do that, we really need to get vspeed to 0 + -- end end end function script.onFlush() - if antigrav and not ExternalAGG then + if antigrav ~= nil and (antigrav and not ExternalAGG) then if antigrav.getState() == 0 and antigrav.getBaseAltitude() ~= AntigravTargetAltitude then antigrav.setBaseAltitude(AntigravTargetAltitude) end @@ -7773,11 +7937,15 @@ function script.onActionStart(action) Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0) end elseif action == "option1" then - IncrementAutopilotTargetIndex() - toggleView = false + if not Autopilot then -- added to prevent crash when index == 0 + IncrementAutopilotTargetIndex() + toggleView = false + end elseif action == "option2" then - DecrementAutopilotTargetIndex() - toggleView = false + if not Autopilot then -- added to prevent crash when index == 0 + DecrementAutopilotTargetIndex() + toggleView = false + end elseif action == "option3" then if hideHudOnToggleWidgets then if showHud then