diff --git a/ButtonHUD.conf b/ButtonHUD.conf index 5b00d32..f1592a9 100644 --- a/ButtonHUD.conf +++ b/ButtonHUD.conf @@ -1,4 +1,4 @@ -name: ButtonsHud - Dimencia and Archaegeo v5.11 (Minified) +name: ButtonsHud - Dimencia and Archaegeo v5.222 (Minified) slots: core: class: CoreUnit @@ -180,10 +180,11 @@ handlers: ShouldCheckDamage = true --export: (Default: true) Whether or not damage checks are performed. Disabled for performance on very large ships CalculateBrakeLandingSpeed = false --export: (Default: false) Whether BrakeLanding speed at non-waypoints should be calculated or use the brakeLandingRate user setting. Only set to true for ships with low mass to lift capability. autoRollRollThreshold = 1.0 --export: (Default: 1.0) The minimum amount of roll before autoRoll kicks in and stabilizes (if active) - 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;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;local a={"userControlScheme","TargetOrbitRadius","apTickRate","freeLookToggle","turnAssist","PrimaryR","PrimaryG","PrimaryB","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","vSpdMeterX","vSpdMeterY","altMeterX","altMeterY","fuelX","fuelY","LandingGearGroundHeight","TrajectoryAlignmentStrength","RemoteHud","StallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization","ExtraLongitudeTags","ExtraLateralTags","ExtraVerticalTags","OrbitMapSize","OrbitMapX","OrbitMapY","DisplayOrbit","CalculateBrakeLandingSpeed"}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;function round(p,q)local r=10^(q or 0)return d(p*r+0.5)/r end;local s=round(ResolutionX/2,0)local t=round(ResolutionY/2,0)local u=false;local v=true;local w=55;local x=false;local y=1;local z=1;local A=false;local B=0;local C=0;local D=0;local E=0;local F=0;local G=0;local H=0;local I=false;local J=false;local K="empty"local L=1;local M=5;local N=5;local O=false;local P,Q=0;local R,S=0;local T=false;local U=false;local V=nil;local W=0;local X=0;local Y=false;local Z=0;local a0=0;local a1=0;local a2=3;local a3=0;local a4=""local a5=""local a6=0;local a7=false;local a8=false;local a9=false;local aa=-1;local ab=false;local ac=""local ad=j()>0;local ae=core.getAltitude()local af=core.getElementIdList()local ag=system.getTime()local ah=nil;local ai=false;local aj=[[rgb(]]..d(PrimaryR+0.5)..","..d(PrimaryG+0.5)..","..d(PrimaryB+0.5)..[[)]]local ak=[[rgb(]]..d(PrimaryR*0.9+0.5)..","..d(PrimaryG*0.9+0.5)..","..d(PrimaryB*0.9+0.5)..[[)]]local al={}local am=0;local an=0;local ao=""local ap=true;local aq={}local ar=1;local as=0.001;local at=ResolutionX;local au=ResolutionY;local av=nil;local aw=nil;local ax=nil;local ay=nil;local az=false;local aA=false;local aB=0;local aC=nil;local aD={}local aE={}local aF={}local aG=0;local aH=false;local aI={}local aJ={}local aK=d(1/apTickRate)*2;local aL={}local aM={}local aN={}local aO={}local aP=false;local aQ=16;local aR=0;local aS=nil;local aT=""local aU=nil;local aV=nil;local aW=nil;local aX=nil;local aY=nil;local aZ=nil;local a_=nil;local b0=nil;local b1=false;local b2=false;local b3=autoRollPreference;local b4=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())local b5=vec3(core.getWorldVelocity())local b6=vec3(b5):len()local b7=math.cos(StallAngle*constants.deg2rad)local b8=LandingGearGroundHeight;local b9=system.getMouseDeltaX()local ba=system.getMouseDeltaY()local bb=false;local bc=system.getTime()local bd=0;local be=0;function LoadVariables()if dbHud_1 then local bf=dbHud_1.hasKey;if not useTheseSettings then for bg,bh in pairs(a)do if bf(bh)then local bi=f(dbHud_1.getStringValue(bh))if bi~=nil then c(bh.." "..dbHud_1.getStringValue(bh))_G[bh]=bi;az=true end end end end;coroutine.yield()for bg,bh in pairs(b)do if bf(bh)then local bi=f(dbHud_1.getStringValue(bh))if bi~=nil then c(bh.." "..dbHud_1.getStringValue(bh))_G[bh]=bi;az=true end end end;if useTheseSettings then K="Updated user preferences used. Will be saved when you exit seat.\nToggle off useTheseSettings to use saved values"a2=5 elseif az then K="Loaded Saved Variables (see Lua Chat Tab for list)"else K="No Saved Variables Found - Stand up / leave remote to save settings"end else K="No databank found, install one anywhere and rerun the autoconfigure to save variables"end;local bj=system.getTime()if LastStartTime+180bl then bl=bk end;if ContainerOptimization>0 then bl=bl-bl*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then bl=bl-bl*FuelTankOptimization*0.05 end;return bl end;function ProcessElements()local bm=fuelX~=0 and fuelY~=0;for bg in pairs(af)do local type=l(af[bg])c(type)if type=="Landing Gear"then c("HERE1")A=true end;if type=="Dynamic Core Unit"then local bn=h(af[bg])if bn>10000 then aQ=128 elseif bn>1000 then aQ=64 elseif bn>150 then aQ=32 end end;aG=aG+h(af[bg])if bm and(type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank")then local bn=h(af[bg])local bo=m(af[bg])local bk=0;local bp=system.getTime()if type=="Atmospheric Fuel Tank"then local bl=400;local bq=35.03;if bn>10000 then bl=51200;bq=5480 elseif bn>1300 then bl=6400;bq=988.67 elseif bn>150 then bl=1600;bq=182.67 end;bk=bo-bq;if fuelTankHandlingAtmo>0 then bl=bl+bl*fuelTankHandlingAtmo*0.2 end;bl=CalculateFuelVolume(bk,bl)aD[#aD+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end;if type=="Rocket Fuel Tank"then local bl=320;local bq=173.42;if bn>65000 then bl=40000;bq=25740 elseif bn>6000 then bl=5120;bq=4720 elseif bn>700 then bl=640;bq=886.72 end;bk=bo-bq;if fuelTankHandlingRocket>0 then bl=bl+bl*fuelTankHandlingRocket*0.1 end;bl=CalculateFuelVolume(bk,bl)aF[#aF+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end;if type=="Space Fuel Tank"then local bl=2400;local bq=182.67;if bn>10000 then bl=76800;bq=5480 elseif bn>1300 then bl=9600;bq=988.67 end;bk=bo-bq;if fuelTankHandlingSpace>0 then bl=bl+bl*fuelTankHandlingSpace*0.2 end;bl=CalculateFuelVolume(bk,bl)aE[#aE+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end end end end;function SetupChecks()if gyro~=nil then ah=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 T=true else U=true end end;local br=j()if door and(br>0 or br==0 and ae<10000)then for _,bh in pairs(door)do bh.toggle()end end;if switch then for _,bh in pairs(switch)do bh.toggle()end end;if forcefield and(br>0 or br==0 and ae<10000)then for _,bh in pairs(forcefield)do bh.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 A then c("HERE2")GearExtended=Nav.control.isAnyLandingGearExtended()==1;if GearExtended then Nav.control.extendLandingGears()else Nav.control.retractLandingGears()end end;local bs=AboveGroundLevel()if bs~=-1 or not ad and vec3(core.getVelocity()):len()<50 then BrakeIsOn=true;if not A then GearExtended=true end else BrakeIsOn=false end;if b8~=nil then Nav.axisCommandManager:setTargetGroundAltitude(b8)if b8==0 and not A then GearExtended=true;BrakeIsOn=true end else b8=Nav:getTargetGroundAltitude()if GearExtended then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if ad and bs~=-1 then a_=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]end;userControlScheme=string.lower(userControlScheme)WasInAtmo=ad end;function ConvertResolutionX(bh)if ResolutionX==1920 then return bh else return round(ResolutionX*bh/1920,0)end end;function ConvertResolutionY(bh)if ResolutionY==1080 then return bh else return round(ResolutionY*bh/1080,0)end end;function RefreshLastMaxBrake(bt,bu)if bt==nil then bt=core.g()end;bt=round(bt,5)local bv=j()if bu~=nil and bu or(aC==nil or aC~=bt)then local b5=core.getVelocity()local bw=vec3(b5):len()local bx=f(unit.getData()).maxBrake;if bx~=nil and bx>0 and ad then bx=bx/utils.clamp(bw/100,0.1,1)bx=bx/bv;if bv>0.10 then if LastMaxBrakeInAtmo then LastMaxBrakeInAtmo=(LastMaxBrakeInAtmo+bx)/2 else LastMaxBrakeInAtmo=bx end end end;if bx~=nil and bx>0 then LastMaxBrake=bx end;aC=bt end end;function MakeButton(by,bz,bA,bB,bC,bD,bE,bF,bG)local bH={enableName=by,disableName=bz,width=bA,height=bB,x=bC,y=bD,toggleVar=bE,toggleFunction=bF,drawCondition=bG,hovered=false}table.insert(aq,bH)return bH end;function UpdateAtlasLocationsList()AtlasOrdered={}for bg,bh in pairs(aS[0])do table.insert(AtlasOrdered,{name=bh.name,index=bg})end;local function bI(bJ,bK)return bJ.name=0 and bU or 2*math.pi+bU;bS=math.pi/2-math.acos(bQ.z/a3)end;return setmetatable({latitude=math.deg(bS),longitude=math.deg(bT),altitude=bR,bodyId=bN.bodyId,systemId=bN.planetarySystemId},MapPosition)end;function zeroConvertToWorldCoordinates(bV)local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local bW='::pos{'..p..','..p..','..p..','..p..','..p..'}'local bX,bY,bS,bT,bR=string.match(bV,bW)if bX=="0"and bY=="0"then return vec3(tonumber(bS),tonumber(bT),tonumber(bR))end;bT=math.rad(bT)bS=math.rad(bS)local planet=aS[tonumber(bX)][tonumber(bY)]local bZ=math.cos(bS)local b_=vec3(bZ*math.cos(bT),bZ*math.sin(bT),math.sin(bS))return planet.center+(planet.radius+bR)*b_ end;function AddNewLocationByWaypoint(c0,planet,bV)if dbHud_1 then local c1={}local position=zeroConvertToWorldCoordinates(bV)if planet.name=="Space"then c1={position=position,name=c0,atmosphere=false,planetname=planet.name,gravity=planet.gravity}else local br=false;if planet.hasAtmosphere then br=true else br=false end;c1={position=position,name=c0,atmosphere=br,planetname=planet.name,gravity=planet.gravity}end;SavedLocations[#SavedLocations+1]=c1;table.insert(aS[0],c1)UpdateAtlasLocationsList()else K="Databank must be installed to save locations"end end;function AddNewLocation()if dbHud_1 then local position=vec3(core.getConstructWorldPos())local c2=planet.name..". "..#SavedLocations;if radar_1 then local c3,_=radar_1.getData():match('"constructId":"([0-9]*)","distance":([%d%.]*)')if c3~=nil and c3~=""then c2=c2 .." "..radar_1.getConstructName(c3)end end;local c1={}local br=false;if planet.hasAtmosphere then br=true end;c1={position=position,name=c2,atmosphere=br,planetname=planet.name,gravity=planet.gravity}SavedLocations[#SavedLocations+1]=c1;table.insert(aS[0],c1)UpdateAtlasLocationsList()K="Location saved as "..c2 else K="Databank must be installed to save locations"end end;function UpdatePosition(c4)local c5=-1;local c1;for bg,bh in pairs(SavedLocations)do if bh.name and bh.name==CustomTarget.name then c5=bg;break end end;if c5~=-1 then local c6;if c4~=nil then c1={position=SavedLocations[c5].position,name=c4,atmosphere=SavedLocations[c5].atmosphere,planetname=SavedLocations[c5].planetname,gravity=SavedLocations[c5].gravity}else c1={position=vec3(core.getConstructWorldPos()),name=SavedLocations[c5].name,atmosphere=j(),planetname=planet.name,gravity=unit.getClosestPlanetInfluence()}end;SavedLocations[c5]=c1;c5=-1;for bg,bh in pairs(aS[0])do if bh.name and bh.name==CustomTarget.name then c5=bg end end;if c5>-1 then aS[0][c5]=c1 end;UpdateAtlasLocationsList()K=CustomTarget.name.." position updated"AutopilotTargetIndex=0;UpdateAutopilotTarget()else K="Name Not Found"end end;function ClearCurrentPosition()local c5=-1;for bg,bh in pairs(aS[0])do if bh.name and bh.name==CustomTarget.name then c5=bg end end;if c5>-1 then table.remove(aS[0],c5)end;c5=-1;for bg,bh in pairs(SavedLocations)do if bh.name and bh.name==CustomTarget.name then K=bh.name.." saved location cleared"c5=bg;break end end;if c5~=-1 then table.remove(SavedLocations,c5)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(c7)c7[#c7+1]=e([[]],DeadZone)end;function ToggleRadarPanel()if radarPanelID~=nil and a6==0 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;if perisPanelID~=nil then system.destroyWidgetPanel(perisPanelID)perisPanelID=nil end else if a6==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;a6=0 end end;function ToggleWidgets()if ap 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;ap=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;ap=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 ad then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;widgetCurBrakeTime=system.createWidget(panelInterplanetary,"value")widgetCurBrakeTimeText=system.createData('{"label": "Cur Brake Time", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;widgetMaxBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeDistanceText=system.createData('{"label": "Max Brake distance", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;widgetMaxBrakeTime=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeTimeText=system.createData('{"label": "Max Brake Time", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;widgetTrajectoryAltitude=system.createWidget(panelInterplanetary,"value")widgetTrajectoryAltitudeText=system.createData('{"label": "Projected Altitude", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end;widgetTargetOrbit=system.createWidget(panelInterplanetary,"value")widgetTargetOrbitText=system.createData('{"label": "Target Altitude", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetTargetOrbitText,widgetTargetOrbit)end end;function Contains(c8,c9,bC,bD,bA,bB)if c8>bC and c8bD and c9w then K="WARNING: Insufficient Brakes - Attempting coast landing, beware obstacles"end;AltitudeHold=false;AutoTakeoff=false;LockPitch=nil;BrakeLanding=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)end end;function ToggleAutoTakeoff()if AutoTakeoff then AutoTakeoff=false;if AltitudeHold then ToggleAltitudeHold()end else if not AltitudeHold then ToggleAltitudeHold()end;AutoTakeoff=true;HoldAltitude=ae+AutoTakeoffAltitude;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(500)BrakeIsOn=true end end;function ToggleLockPitch()if LockPitch==nil then local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local cc=vec3(core.getWorldVertical())local cd=getPitch(cc,ca,cb)LockPitch=cd;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()local bj=system.getTime()if bj-be<1.5 then if planet.hasAtmosphere then HoldAltitude=planet.spaceEngineMinAltitude-50;be=-1;if AltitudeHold then return end end else be=bj end;AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;I=false;BrakeLanding=false;Reentry=false;b3=true;LockPitch=nil;if not GearExtended and not BrakeIsOn or not ad or antigrav and antigrav.getState()==1 then AutoTakeoff=false;if be>-1 then HoldAltitude=ae end;if not a8 and Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;if be>-1 then HoldAltitude=ae+AutoTakeoffAltitude end;GearExtended=false;Nav.control.retractLandingGears()BrakeIsOn=true;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end;if a8 then HoldAltitude=100000 end else b3=autoRollPreference;AutoTakeoff=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;VectorToTarget=false end end;function ToggleFollowMode()if o()==1 then I=not I;if I 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;b3=autoRollPreference;GearExtended=OldGearExtended;if GearExtended then Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end end else K="Follow Mode only works with Remote controller"I=false end end;function ToggleAutopilot()if AutopilotTargetIndex>0 and not Autopilot and not VectorToTarget and not a8 then local ce=zeroConvertToMapPosition(V,AutopilotTargetCoords)ce="::pos{"..ce.systemId..","..ce.bodyId..","..ce.latitude..","..ce.longitude..","..ce.altitude.."}"system.setWaypoint(ce)if CustomTarget~=nil then LockPitch=nil;SpaceTarget=CustomTarget.planetname=="Space"if SpaceTarget then if j()~=0 then a8=true;ToggleAltitudeHold()else Autopilot=true end elseif planet.name==CustomTarget.planetname then StrongBrakes=planet.gravity*9.80665*n()w then K="Insufficient Brake Force\nCoast landing will be inaccurate"end;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 ae>100000 or ae==0 then Autopilot=true else a7=true end end else RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then a8=true;ToggleAltitudeHold()else Autopilot=true end end elseif j()==0 then Autopilot=true;RetrogradeIsOn=false;ProgradeIsOn=false;AutopilotRealigned=false;I=false;AltitudeHold=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;u=false;LockPitch=nil else a8=true;ToggleAltitudeHold()end else a8=false;Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;u=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false;HoldAltitude=ae end end;function ProgradeToggle()ProgradeIsOn=not ProgradeIsOn;RetrogradeIsOn=false;Autopilot=false;AltitudeHold=false;I=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function RetrogradeToggle()RetrogradeIsOn=not RetrogradeIsOn;ProgradeIsOn=false;Autopilot=false;AltitudeHold=false;I=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function BrakeToggle()BrakeIsOn=not BrakeIsOn;if BrakeLanding then BrakeLanding=false;b3=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;LockPitch=nil;b3=autoRollPreference end end;function CheckDamage(c7)local cf=0;ao=""local cg=aG;local ch=0;local ci=0;local cj=0;local ck=0;local cl=""for bg in pairs(af)do local bn=0;local cm=0;cm=h(af[bg])bn=k(af[bg])ch=ch+bn;if bn0 and al[11]==af[bg]then for co in pairs(al)do core.deleteSticker(al[co])end;al={}end end;cf=d(ch/cg*100)if cf<100 then c7[#c7+1]=[[]]ck=d(cf*2.55)cl=e("rgb(%d,%d,%d)",255-ck,ck,0)if cf<100 then c7[#c7+1]=e([[Elemental Integrity: %i %%]],cl,cf)if cj>0 then c7[#c7+1]=e([[Disabled Modules: %i Damaged Modules: %i]],cl,cj,ci)elseif ci>0 then c7[#c7+1]=e([[Damaged Modules: %i]],cl,ci)end end;c7[#c7+1]=[[<\g>]]end end;function DrawCursorLine(c7)local cp=d(utils.clamp(a3/(at/4)*255,0,255))c7[#c7+1]=e("",a0,a1,d(PrimaryR+0.5)+cp,d(PrimaryG+0.5)-cp,d(PrimaryB+0.5)-cp)end;function getPitch(cq,cr,bK)local cs=cq:cross(bK):normalize_inplace()local cd=math.acos(utils.clamp(cs:dot(-cr),-1,1))*constants.rad2deg;if cs:cross(-cr):dot(bK)<0 then cd=-cd end;return cd end;local ct=math.atan;local function cu(cv,cw,cx)return ct(cw:cross(cx):dot(cv),cw:dot(cx))end;function clearAll()if ab then ab=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;I=false;u=false;a7=false;a8=false;x=false;b3=autoRollPreference;VectorToTarget=false;TurnBurn=false;ah=false;LockPitch=nil else ab=true end end;function wipeSaveVariables()if not dbHud_1 then K="No Databank Found, unable to wipe. \nYou must have a Databank attached to ship prior to running the HUD autoconfigure"a2=5 else if aA then for bg,bh in pairs(a)do dbHud_1.setStringValue(bh,g(nil))end;for bg,bh in pairs(b)do if bh~="SavedLocations"then dbHud_1.setStringValue(bh,g(nil))end end;K="Databank wiped. New variables will save after re-enter seat and exit"a2=5;aA=false;az=false;Y=true else K="Press ALT-7 again to confirm wipe of ALL data"aA=true end end end;function CheckButtons()for _,bh in pairs(aq)do if bh.hovered then if not bh.drawCondition or bh.drawCondition()then bh.toggleFunction()end;bh.hovered=false end end end;function SetButtonContains()local bC=a0+at/2;local bD=a1+au/2;for _,bh in pairs(aq)do bh.hovered=Contains(bC,bD,bh.x,bh.y,bh.width,bh.height)end end;function DrawButton(c7,cy,hover,bC,bD,cz,cA,cB,cC,cD,cE)if type(cD)=="function"then cD=cD()end;if type(cE)=="function"then cE=cE()end;c7[#c7+1]=e(""if cy then c7[#c7+1]=e("%s",cD)else c7[#c7+1]=e("%s",cE)end end;function DrawButtons(c7)local cF="rgb(50,50,50)'"local cG="rgb(210,200,200)"local cH=DrawButton;for _,bh in pairs(aq)do local bz=bh.disableName;local by=bh.enableName;if type(bz)=="function"then bz=bz()end;if type(by)=="function"then by=by()end;if not bh.drawCondition or bh.drawCondition()then cH(c7,bh.toggleVar(),bh.hovered,bh.x,bh.y,bh.width,bh.height,cG,cF,bz,by)end end end;function DrawTank(c7,aP,bC,cI,cJ,cK,cL,cM)local cN=1;local cO=2;local cP=3;local cQ=4;local cR=5;local cS=6;local cT=""local cU=0;local cV=fuelY;local cW=fuelY+10;if o()==1 and not RemoteHud then cV=cV-50;cW=cW-50 end;c7[#c7+1]=[[]]if cJ=="ATMO"then cT="atmofueltank"elseif cJ=="SPACE"then cT="spacefueltank"else cT="rocketfueltank"end;cU=_G[cT.."_size"]if#cK>0 then for i=1,#cK do local c2=string.sub(cK[i][cO],1,12)local cX=0;for co=1,cU do if cK[i][cO]==f(unit[cT.."_"..co].getData()).name then cX=co;break end end;if aP or cL[i]==nil or cM[i]==nil then local cY=0;local cZ=0;local c_=0;local d0=0;local bp=system.getTime()if cX~=0 then cM[i]=f(unit[cT.."_"..cX].getData()).percentage;cL[i]=f(unit[cT.."_"..cX].getData()).timeLeft;if cL[i]=="n/a"then cL[i]=0 end else c_=m(cK[i][cN])-cK[i][cQ]cY=cK[i][cP]cM[i]=d(0.5+c_*100/cY)cZ=cK[i][cR]d0=cK[i][cS]if cZ<=c_ then cL[i]=0 else cL[i]=d(0.5+c_/((cZ-c_)/(bp-d0)))end;cK[i][cR]=c_;cK[i][cS]=bp end end;if c2==cI then c2=e("%s %d",cJ,i)end;if cX==0 then c2=c2 .." *"end;local d1;if cL[i]==0 then d1="n/a"else d1=FormatTimeString(cL[i])end;if cM[i]~=nil then local ck=d(cM[i]*2.55)local cl=e("rgb(%d,%d,%d)",255-ck,ck,0)local d2=""if d1~="n/a"and cL[i]<120 or cM[i]<5 then if aP then d2=[[class="red"]]end end;c7[#c7+1]=e([[ + AtmoSpeedAssist = true --export: (Default: true) Whether or not atmospheric speeds should be limited to a maximum of AtmoSpeedLimit + 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;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;PlayerThrottle=0;brakeInput2=0;ThrottleLimited=false;calculatedThrottle=0;local a={"userControlScheme","TargetOrbitRadius","apTickRate","freeLookToggle","turnAssist","PrimaryR","PrimaryG","PrimaryB","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","StallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization","ExtraLongitudeTags","ExtraLateralTags","ExtraVerticalTags","OrbitMapSize","OrbitMapX","OrbitMapY","DisplayOrbit","CalculateBrakeLandingSpeed"}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;function round(p,q)local r=10^(q or 0)return d(p*r+0.5)/r end;local s=round(ResolutionX/2,0)local t=round(ResolutionY/2,0)local u=false;local v=true;local w=55;local x=false;local y=1;local z=1;local A=false;local B=0;local C=0;local D=0;local E=0;local F=0;local G=0;local H=0;local I=false;local J=false;local K="empty"local L=1;local M=5;local N=5;local O=false;local P,Q=0;local R,S=0;local T=false;local U=false;local V=nil;local W=0;local X=0;local Y=false;local Z=0;local a0=0;local a1=0;local a2=3;local a3=0;local a4=""local a5=""local a6=0;local a7=false;local a8=false;local a9=false;local aa=-1;local ab=false;local ac=""local ad=j()>0;local ae=core.getAltitude()local af=core.getElementIdList()local ag=system.getTime()local ah=nil;local ai=false;local aj=[[rgb(]]..d(PrimaryR+0.5)..","..d(PrimaryG+0.5)..","..d(PrimaryB+0.5)..[[)]]local ak=[[rgb(]]..d(PrimaryR*0.9+0.5)..","..d(PrimaryG*0.9+0.5)..","..d(PrimaryB*0.9+0.5)..[[)]]local al={}local am=0;local an=0;local ao=""local ap=true;local aq={}local ar=1;local as=0.001;local at=ResolutionX;local au=ResolutionY;local av=nil;local aw=nil;local ax=nil;local ay=nil;local az=false;local aA=false;local aB=0;local aC=nil;local aD={}local aE={}local aF={}local aG=0;local aH=false;local aI={}local aJ={}local aK=d(1/apTickRate)*2;local aL={}local aM={}local aN={}local aO={}local aP=false;local aQ=16;local aR=0;local aS=nil;local aT=""local aU=nil;local aV=nil;local aW=nil;local aX=nil;local aY=nil;local aZ=nil;local a_=nil;local b0=nil;local b1=false;local b2=false;local b3=autoRollPreference;local b4=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())local b5=vec3(core.getWorldVelocity())local b6=vec3(b5):len()local b7=math.cos(StallAngle*constants.deg2rad)local b8=LandingGearGroundHeight;local b9=system.getMouseDeltaX()local ba=system.getMouseDeltaY()local bb=false;local bc=system.getTime()local bd=0;local be=0;function LoadVariables()if dbHud_1 then local bf=dbHud_1.hasKey;if not useTheseSettings then for bg,bh in pairs(a)do if bf(bh)then local bi=f(dbHud_1.getStringValue(bh))if bi~=nil then c(bh.." "..dbHud_1.getStringValue(bh))_G[bh]=bi;az=true end end end end;coroutine.yield()for bg,bh in pairs(b)do if bf(bh)then local bi=f(dbHud_1.getStringValue(bh))if bi~=nil then c(bh.." "..dbHud_1.getStringValue(bh))_G[bh]=bi;az=true end end end;if useTheseSettings then K="Updated user preferences used. Will be saved when you exit seat.\nToggle off useTheseSettings to use saved values"a2=5 elseif az then K="Loaded Saved Variables (see Lua Chat Tab for list)"else K="No Saved Variables Found - Stand up / leave remote to save settings"end else K="No databank found, install one anywhere and rerun the autoconfigure to save variables"end;local bj=system.getTime()if LastStartTime+180bl then bl=bk end;if ContainerOptimization>0 then bl=bl-bl*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then bl=bl-bl*FuelTankOptimization*0.05 end;return bl end;function ProcessElements()local bm=fuelX~=0 and fuelY~=0;for bg in pairs(af)do local type=l(af[bg])if type=="Landing Gear"then A=true end;if type=="Dynamic Core Unit"then local bn=h(af[bg])if bn>10000 then aQ=128 elseif bn>1000 then aQ=64 elseif bn>150 then aQ=32 end end;aG=aG+h(af[bg])if bm and(type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank")then local bn=h(af[bg])local bo=m(af[bg])local bk=0;local bp=system.getTime()if type=="Atmospheric Fuel Tank"then local bl=400;local bq=35.03;if bn>10000 then bl=51200;bq=5480 elseif bn>1300 then bl=6400;bq=988.67 elseif bn>150 then bl=1600;bq=182.67 end;bk=bo-bq;if fuelTankHandlingAtmo>0 then bl=bl+bl*fuelTankHandlingAtmo*0.2 end;bl=CalculateFuelVolume(bk,bl)aD[#aD+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end;if type=="Rocket Fuel Tank"then local bl=320;local bq=173.42;if bn>65000 then bl=40000;bq=25740 elseif bn>6000 then bl=5120;bq=4720 elseif bn>700 then bl=640;bq=886.72 end;bk=bo-bq;if fuelTankHandlingRocket>0 then bl=bl+bl*fuelTankHandlingRocket*0.1 end;bl=CalculateFuelVolume(bk,bl)aF[#aF+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end;if type=="Space Fuel Tank"then local bl=2400;local bq=182.67;if bn>10000 then bl=76800;bq=5480 elseif bn>1300 then bl=9600;bq=988.67 end;bk=bo-bq;if fuelTankHandlingSpace>0 then bl=bl+bl*fuelTankHandlingSpace*0.2 end;bl=CalculateFuelVolume(bk,bl)aE[#aE+1]={af[bg],core.getElementNameById(af[bg]),bl,bq,bk,bp}end end end end;function SetupChecks()if gyro~=nil then ah=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 T=true else U=true end end;local br=j()if door and(br>0 or br==0 and ae<10000)then for _,bh in pairs(door)do bh.toggle()end end;if switch then for _,bh in pairs(switch)do bh.toggle()end end;if forcefield and(br>0 or br==0 and ae<10000)then for _,bh in pairs(forcefield)do bh.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 A then GearExtended=Nav.control.isAnyLandingGearExtended()==1;if GearExtended then Nav.control.extendLandingGears()else Nav.control.retractLandingGears()end end;local bs=AboveGroundLevel()if bs~=-1 or not ad and vec3(core.getVelocity()):len()<50 then BrakeIsOn=true;if not A then GearExtended=true end else BrakeIsOn=false end;if b8~=nil then Nav.axisCommandManager:setTargetGroundAltitude(b8)if b8==0 and not A then GearExtended=true;BrakeIsOn=true end else b8=Nav:getTargetGroundAltitude()if GearExtended then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if ad and bs~=-1 then a_=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]end;userControlScheme=string.lower(userControlScheme)WasInAtmo=ad end;function ConvertResolutionX(bh)if ResolutionX==1920 then return bh else return round(ResolutionX*bh/1920,0)end end;function ConvertResolutionY(bh)if ResolutionY==1080 then return bh else return round(ResolutionY*bh/1080,0)end end;function RefreshLastMaxBrake(bt,bu)if bt==nil then bt=core.g()end;bt=round(bt,5)local bv=j()if bu~=nil and bu or(aC==nil or aC~=bt)then local b5=core.getVelocity()local bw=vec3(b5):len()local bx=f(unit.getData()).maxBrake;if bx~=nil and bx>0 and ad then bx=bx/utils.clamp(bw/100,0.1,1)bx=bx/bv;if bv>0.10 then if LastMaxBrakeInAtmo then LastMaxBrakeInAtmo=(LastMaxBrakeInAtmo+bx)/2 else LastMaxBrakeInAtmo=bx end end end;if bx~=nil and bx>0 then LastMaxBrake=bx end;aC=bt end end;function MakeButton(by,bz,bA,bB,bC,bD,bE,bF,bG)local bH={enableName=by,disableName=bz,width=bA,height=bB,x=bC,y=bD,toggleVar=bE,toggleFunction=bF,drawCondition=bG,hovered=false}table.insert(aq,bH)return bH end;function UpdateAtlasLocationsList()AtlasOrdered={}for bg,bh in pairs(aS[0])do table.insert(AtlasOrdered,{name=bh.name,index=bg})end;local function bI(bJ,bK)return bJ.name=0 and bU or 2*math.pi+bU;bS=math.pi/2-math.acos(bQ.z/a3)end;return setmetatable({latitude=math.deg(bS),longitude=math.deg(bT),altitude=bR,bodyId=bN.bodyId,systemId=bN.planetarySystemId},MapPosition)end;function zeroConvertToWorldCoordinates(bV)local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local bW='::pos{'..p..','..p..','..p..','..p..','..p..'}'local bX,bY,bS,bT,bR=string.match(bV,bW)if bX=="0"and bY=="0"then return vec3(tonumber(bS),tonumber(bT),tonumber(bR))end;bT=math.rad(bT)bS=math.rad(bS)local planet=aS[tonumber(bX)][tonumber(bY)]local bZ=math.cos(bS)local b_=vec3(bZ*math.cos(bT),bZ*math.sin(bT),math.sin(bS))return planet.center+(planet.radius+bR)*b_ end;function AddNewLocationByWaypoint(c0,planet,bV)if dbHud_1 then local c1={}local position=zeroConvertToWorldCoordinates(bV)if planet.name=="Space"then c1={position=position,name=c0,atmosphere=false,planetname=planet.name,gravity=planet.gravity}else local br=false;if planet.hasAtmosphere then br=true else br=false end;c1={position=position,name=c0,atmosphere=br,planetname=planet.name,gravity=planet.gravity}end;SavedLocations[#SavedLocations+1]=c1;table.insert(aS[0],c1)UpdateAtlasLocationsList()else K="Databank must be installed to save locations"end end;function AddNewLocation()if dbHud_1 then local position=vec3(core.getConstructWorldPos())local c2=planet.name..". "..#SavedLocations;if radar_1 then local c3,_=radar_1.getData():match('"constructId":"([0-9]*)","distance":([%d%.]*)')if c3~=nil and c3~=""then c2=c2 .." "..radar_1.getConstructName(c3)end end;local c1={}local br=false;if planet.hasAtmosphere then br=true end;c1={position=position,name=c2,atmosphere=br,planetname=planet.name,gravity=planet.gravity,safe=true}SavedLocations[#SavedLocations+1]=c1;table.insert(aS[0],c1)UpdateAtlasLocationsList()K="Location saved as "..c2 else K="Databank must be installed to save locations"end end;function UpdatePosition(c4)local c5=-1;local c1;for bg,bh in pairs(SavedLocations)do if bh.name and bh.name==CustomTarget.name then c5=bg;break end end;if c5~=-1 then local c6;if c4~=nil then c1={position=SavedLocations[c5].position,name=c4,atmosphere=SavedLocations[c5].atmosphere,planetname=SavedLocations[c5].planetname,gravity=SavedLocations[c5].gravity}else c1={position=vec3(core.getConstructWorldPos()),name=SavedLocations[c5].name,atmosphere=j(),planetname=planet.name,gravity=unit.getClosestPlanetInfluence(),safe=true}end;SavedLocations[c5]=c1;c5=-1;for bg,bh in pairs(aS[0])do if bh.name and bh.name==CustomTarget.name then c5=bg end end;if c5>-1 then aS[0][c5]=c1 end;UpdateAtlasLocationsList()K=CustomTarget.name.." position updated"AutopilotTargetIndex=0;UpdateAutopilotTarget()else K="Name Not Found"end end;function ClearCurrentPosition()local c5=-1;for bg,bh in pairs(aS[0])do if bh.name and bh.name==CustomTarget.name then c5=bg end end;if c5>-1 then table.remove(aS[0],c5)end;c5=-1;for bg,bh in pairs(SavedLocations)do if bh.name and bh.name==CustomTarget.name then K=bh.name.." saved location cleared"c5=bg;break end end;if c5~=-1 then table.remove(SavedLocations,c5)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(c7)c7[#c7+1]=e([[]],DeadZone)end;function ToggleRadarPanel()if radarPanelID~=nil and a6==0 then system.destroyWidgetPanel(radarPanelID)radarPanelID=nil;if perisPanelID~=nil then system.destroyWidgetPanel(perisPanelID)perisPanelID=nil end else if a6==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;a6=0 end end;function ToggleWidgets()if ap 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;ap=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;ap=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 ad then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;widgetCurBrakeTime=system.createWidget(panelInterplanetary,"value")widgetCurBrakeTimeText=system.createData('{"label": "Cur Brake Time", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;widgetMaxBrakeDistance=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeDistanceText=system.createData('{"label": "Max Brake distance", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;widgetMaxBrakeTime=system.createWidget(panelInterplanetary,"value")widgetMaxBrakeTimeText=system.createData('{"label": "Max Brake Time", "value": "N/A", "unit":""}')if not ad then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;widgetTrajectoryAltitude=system.createWidget(panelInterplanetary,"value")widgetTrajectoryAltitudeText=system.createData('{"label": "Projected Altitude", "value": "N/A", "unit":""}')if not ad 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(c8,c9,bC,bD,bA,bB)if c8>bC and c8bD and c9w then K="WARNING: Insufficient Brakes - Attempting coast landing, beware obstacles"end;AltitudeHold=false;AutoTakeoff=false;LockPitch=nil;BrakeLanding=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0 end end;function ToggleAutoTakeoff()if AutoTakeoff then AutoTakeoff=false;if AltitudeHold then ToggleAltitudeHold()end else if not AltitudeHold then ToggleAltitudeHold()end;AutoTakeoff=true;HoldAltitude=ae+AutoTakeoffAltitude;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(500)BrakeIsOn=true end end;function ToggleLockPitch()if LockPitch==nil then local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local cc=vec3(core.getWorldVertical())local cd=getPitch(cc,ca,cb)LockPitch=cd;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()local bj=system.getTime()if bj-be<1.5 then if planet.hasAtmosphere then HoldAltitude=planet.spaceEngineMinAltitude-50;be=-1;if AltitudeHold then return end end else be=bj end;AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;I=false;BrakeLanding=false;Reentry=false;b3=true;LockPitch=nil;if not GearExtended and not BrakeIsOn or not ad or antigrav and antigrav.getState()==1 then AutoTakeoff=false;if be>-1 then HoldAltitude=ae end;if not a8 and Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;if be>-1 then HoldAltitude=ae+AutoTakeoffAltitude end;GearExtended=false;Nav.control.retractLandingGears()BrakeIsOn=true;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end;if a8 then HoldAltitude=100000 end else b3=autoRollPreference;AutoTakeoff=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;VectorToTarget=false end end;function ToggleFollowMode()if o()==1 then I=not I;if I 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;b3=autoRollPreference;GearExtended=OldGearExtended;if GearExtended then Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end end else K="Follow Mode only works with Remote controller"I=false end end;function ToggleAutopilot()if AutopilotTargetIndex>0 and not Autopilot and not VectorToTarget and not a8 then local ce=zeroConvertToMapPosition(V,AutopilotTargetCoords)ce="::pos{"..ce.systemId..","..ce.bodyId..","..ce.latitude..","..ce.longitude..","..ce.altitude.."}"system.setWaypoint(ce)if CustomTarget~=nil then LockPitch=nil;SpaceTarget=CustomTarget.planetname=="Space"if SpaceTarget then if j()~=0 then a8=true;ToggleAltitudeHold()else Autopilot=true end elseif planet.name==CustomTarget.planetname then StrongBrakes=planet.gravity*9.80665*n()w then K="Insufficient Brake Force\nCoast landing will be inaccurate"end;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 ae>100000 or ae==0 then Autopilot=true else a7=true end end else RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then a8=true;ToggleAltitudeHold()else Autopilot=true end end elseif j()==0 then Autopilot=true;RetrogradeIsOn=false;ProgradeIsOn=false;AutopilotRealigned=false;I=false;AltitudeHold=false;BrakeLanding=false;Reentry=false;AutoTakeoff=false;u=false;LockPitch=nil else a8=true;ToggleAltitudeHold()end else a8=false;Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;u=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false;HoldAltitude=ae end end;function ProgradeToggle()ProgradeIsOn=not ProgradeIsOn;RetrogradeIsOn=false;Autopilot=false;AltitudeHold=false;I=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function RetrogradeToggle()RetrogradeIsOn=not RetrogradeIsOn;ProgradeIsOn=false;Autopilot=false;AltitudeHold=false;I=false;BrakeLanding=false;LockPitch=nil;Reentry=false;AutoTakeoff=false end;function BrakeToggle()BrakeIsOn=not BrakeIsOn;if BrakeLanding then BrakeLanding=false;b3=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;LockPitch=nil;b3=autoRollPreference end end;function CheckDamage(c7)local cf=0;ao=""local cg=aG;local ch=0;local ci=0;local cj=0;local ck=0;local cl=""for bg in pairs(af)do local bn=0;local cm=0;cm=h(af[bg])bn=k(af[bg])ch=ch+bn;if bn0 and al[11]==af[bg]then for co in pairs(al)do core.deleteSticker(al[co])end;al={}end end;cf=d(ch/cg*100)if cf<100 then c7[#c7+1]=[[]]ck=d(cf*2.55)cl=e("rgb(%d,%d,%d)",255-ck,ck,0)if cf<100 then c7[#c7+1]=e([[Elemental Integrity: %i %%]],cl,cf)if cj>0 then c7[#c7+1]=e([[Disabled Modules: %i Damaged Modules: %i]],cl,cj,ci)elseif ci>0 then c7[#c7+1]=e([[Damaged Modules: %i]],cl,ci)end end;c7[#c7+1]=[[<\g>]]end end;function DrawCursorLine(c7)local cp=d(utils.clamp(a3/(at/4)*255,0,255))c7[#c7+1]=e("",a0,a1,d(PrimaryR+0.5)+cp,d(PrimaryG+0.5)-cp,d(PrimaryB+0.5)-cp)end;function getPitch(cq,cr,bK)local cs=cq:cross(bK):normalize_inplace()local cd=math.acos(utils.clamp(cs:dot(-cr),-1,1))*constants.rad2deg;if cs:cross(-cr):dot(bK)<0 then cd=-cd end;return cd end;local ct=math.atan;local function cu(cv,cw,cx)return ct(cw:cross(cx):dot(cv),cw:dot(cx))end;function clearAll()if ab then ab=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;I=false;u=false;a7=false;a8=false;x=false;b3=autoRollPreference;VectorToTarget=false;TurnBurn=false;ah=false;LockPitch=nil else ab=true end end;function wipeSaveVariables()if not dbHud_1 then K="No Databank Found, unable to wipe. \nYou must have a Databank attached to ship prior to running the HUD autoconfigure"a2=5 else if aA then for bg,bh in pairs(a)do dbHud_1.setStringValue(bh,g(nil))end;for bg,bh in pairs(b)do if bh~="SavedLocations"then dbHud_1.setStringValue(bh,g(nil))end end;K="Databank wiped. New variables will save after re-enter seat and exit"a2=5;aA=false;az=false;Y=true else K="Press ALT-7 again to confirm wipe of ALL data"aA=true end end end;function CheckButtons()for _,bh in pairs(aq)do if bh.hovered then if not bh.drawCondition or bh.drawCondition()then bh.toggleFunction()end;bh.hovered=false end end end;function SetButtonContains()local bC=a0+at/2;local bD=a1+au/2;for _,bh in pairs(aq)do bh.hovered=Contains(bC,bD,bh.x,bh.y,bh.width,bh.height)end end;function DrawButton(c7,cy,hover,bC,bD,cz,cA,cB,cC,cD,cE)if type(cD)=="function"then cD=cD()end;if type(cE)=="function"then cE=cE()end;c7[#c7+1]=e(""if cy then c7[#c7+1]=e("%s",cD)else c7[#c7+1]=e("%s",cE)end end;function DrawButtons(c7)local cF="rgb(50,50,50)'"local cG="rgb(210,200,200)"local cH=DrawButton;for _,bh in pairs(aq)do local bz=bh.disableName;local by=bh.enableName;if type(bz)=="function"then bz=bz()end;if type(by)=="function"then by=by()end;if not bh.drawCondition or bh.drawCondition()then cH(c7,bh.toggleVar(),bh.hovered,bh.x,bh.y,bh.width,bh.height,cG,cF,bz,by)end end end;function DrawTank(c7,aP,bC,cI,cJ,cK,cL,cM)local cN=1;local cO=2;local cP=3;local cQ=4;local cR=5;local cS=6;local cT=""local cU=0;local cV=fuelY;local cW=fuelY+10;if o()==1 and not RemoteHud then cV=cV-50;cW=cW-50 end;c7[#c7+1]=[[]]if cJ=="ATMO"then cT="atmofueltank"elseif cJ=="SPACE"then cT="spacefueltank"else cT="rocketfueltank"end;cU=_G[cT.."_size"]if#cK>0 then for i=1,#cK do local c2=string.sub(cK[i][cO],1,12)local cX=0;for co=1,cU do if cK[i][cO]==f(unit[cT.."_"..co].getData()).name then cX=co;break end end;if aP or cL[i]==nil or cM[i]==nil then local cY=0;local cZ=0;local c_=0;local d0=0;local bp=system.getTime()if cX~=0 then cM[i]=f(unit[cT.."_"..cX].getData()).percentage;cL[i]=f(unit[cT.."_"..cX].getData()).timeLeft;if cL[i]=="n/a"then cL[i]=0 end else c_=m(cK[i][cN])-cK[i][cQ]cY=cK[i][cP]cM[i]=d(0.5+c_*100/cY)cZ=cK[i][cR]d0=cK[i][cS]if cZ<=c_ then cL[i]=0 else cL[i]=d(0.5+c_/((cZ-c_)/(bp-d0)))end;cK[i][cR]=c_;cK[i][cS]=bp end end;if c2==cI then c2=e("%s %d",cJ,i)end;if cX==0 then c2=c2 .." *"end;local d1;if cL[i]==0 then d1="n/a"else d1=FormatTimeString(cL[i])end;if cM[i]~=nil then local ck=d(cM[i]*2.55)local cl=e("rgb(%d,%d,%d)",255-ck,ck,0)local d2=""if d1~="n/a"and cL[i]<120 or cM[i]<5 then if aP then d2=[[class="red"]]end end;c7[#c7+1]=e([[ %s %d%% %s - ]],bC,cV,d2,c2,bC,cW,cl,cM[i],d1)cV=cV+30;cW=cW+30 end end end;c7[#c7+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(b5)b5=vec3(b5)local cd=-math.deg(math.atan(b5.y,b5.z))+180;cd=cd-90;if cd<0 then cd=360+cd end;if cd>180 then cd=-180+cd-180 end;return-cd end;function getRelativeYaw(b5)b5=vec3(b5)local d3=math.deg(math.atan(b5.y,b5.x))-90;if d3<-180 then d3=360+d3 end;return d3 end;function AlignToWorldVector(d4,d5,d6)if not ad or not bb or aa~=-1 or b60 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,dg.height,dg.x-200-30,dg.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)dd=60;de=300;local bC=10;local bD=au/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",de,dd,bC,bD,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",de,dd,bC+de+20,bD,function()return AltitudeHold end,ToggleAltitudeHold)bD=bD+dd+20;MakeButton("Engage Autoland","Disable Autoland",de,dd,bC,bD,function()return AutoLanding end,ToggleAutoLanding)MakeButton("Engage Auto Takeoff","Disable Auto Takeoff",de,dd,bC+de+20,bD,function()return AutoTakeoff end,ToggleAutoTakeoff)bD=bD+dd+20;MakeButton("Show Orbit Display","Hide Orbit Display",de,dd,bC,bD,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then K="Orbit Display Enabled"else K="Orbit Display Disabled"end end)bD=bD+dd+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",de,dd,bC,bD,function()return Reentry end,function()x=true;BeginReentry()end,function()return ae>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",de,dd,bC+de+20,bD,function()return Reentry end,BeginReentry,function()return ae>ReentryAltitude end)bD=bD+dd+20;MakeButton("Engage Follow Mode","Disable Follow Mode",de,dd,bC,bD,function()return I end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",de,dd,bC+de+20,bD,function()return aH end,function()aH=not aH;if aH then K="Repair Arrows Enabled"else K="Repair Arrows Diabled"end end,function()return o()==1 end)bD=bD+dd+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",de,dd,bC,bD,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bD=bD+dd+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,de*2,dd,bC,bD,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 dh=Nav.axisCommandManager:getAxisCommandType(0)local di="TRAVEL"if dh==1 then di="CRUISE"end;if Autopilot then di="AUTOPILOT"end;return di end;function UpdateHud(c7)local bR=ae;local b5=core.getVelocity()local bw=vec3(b5):len()local cc=vec3(core.getWorldVertical())local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local dj=vec3(core.getConstructWorldOrientationUp())local dk=getRoll(cc,ca,cb)local dl=dk/180*math.pi;local dm=math.cos(dl)local dn=math.sin(dl)local cd=getPitch(cc,ca,cb*dm+dj*dn)local dp=dk;local dq=cd;local dr=j()local ds=d(unit.getThrottle())local dt=bw*3.6;local du=unit.getAxisCommandValue(0)local di=GetFlightStyle()local dv="ROLL"local dw=unit.getClosestPlanetInfluence()>0;if ds==nil then ds=0 end;if not dw then if bw>5 then cd=getRelativePitch(b5)dk=getRelativeYaw(b5)else cd=0;dk=0 end;dv="YAW"end;c7[#c7+1]=a5;c7[#c7+1]=ao;c7[#c7+1]=a4;if aR%aK==0 then aP=true end;if fuelX~=0 and fuelY~=0 then DrawTank(c7,aP,fuelX,"Atmospheric ","ATMO",aD,aN,aO)DrawTank(c7,aP,fuelX+100,"Space fuel t","SPACE",aE,aL,aM)DrawTank(c7,aP,fuelX+200,"Rocket fuel ","ROCKET",aF,aI,aJ)end;if aP then aP=false;aR=0 end;aR=aR+1;DrawVerticalSpeed(c7,bR)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if dw then DrawRollLines(c7,centerX,centerY,dp,dv,dw)DrawArtificialHorizon(c7,dq,dp,centerX,centerY,dw,d(getRelativeYaw(b5)),bw)else DrawRollLines(c7,centerX,centerY,dk,dv,dw)DrawArtificialHorizon(c7,cd,dk,centerX,centerY,dw,d(dk),bw)end;DrawAltitudeDisplay(c7,bR,dw)DrawPrograde(c7,b5,bw,centerX,centerY)end end;DrawThrottle(c7,di,ds,du)DrawSpeed(c7,dt)DrawWarnings(c7)DisplayOrbitScreen(c7)if screen_2 then local bV=vec3(core.getConstructWorldPos())local bC=960+bV.x/aU;local bD=450+bV.y/aV;screen_2.moveContent(aW,(bC-80)/19.2,(bD-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(c7)local dx=aj;local dy=ak;local dz=aj;local dA=ak;if IsInFreeLook()and not brightHud then dx=[[rgb(]]..d(PrimaryR*0.4+0.5)..","..d(PrimaryG*0.4+0.5)..","..d(PrimaryB*0.3+0.5)..[[)]]dy=[[rgb(]]..d(PrimaryR*0.3+0.5)..","..d(PrimaryG*0.3+0.5)..","..d(PrimaryB*0.2+0.5)..[[)]]end;c7[#c7+1]=e([[ + ]],bC,cV,d2,c2,bC,cW,cl,cM[i],d1)cV=cV+30;cW=cW+30 end end end;c7[#c7+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(b5)b5=vec3(b5)local cd=-math.deg(math.atan(b5.y,b5.z))+180;cd=cd-90;if cd<0 then cd=360+cd end;if cd>180 then cd=-180+cd-180 end;return-cd end;function getRelativeYaw(b5)b5=vec3(b5)local d3=math.deg(math.atan(b5.y,b5.x))-90;if d3<-180 then d3=360+d3 end;return d3 end;function AlignToWorldVector(d4,d5,d6)if not ad or not bb or aa~=-1 or b60 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,dg.height,dg.x-200-30,dg.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)dd=60;de=300;local bC=10;local bD=au/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",de,dd,bC,bD,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",de,dd,bC+de+20,bD,function()return AltitudeHold end,ToggleAltitudeHold)bD=bD+dd+20;MakeButton("Engage Autoland","Disable Autoland",de,dd,bC,bD,function()return AutoLanding end,ToggleAutoLanding)MakeButton("Engage Auto Takeoff","Disable Auto Takeoff",de,dd,bC+de+20,bD,function()return AutoTakeoff end,ToggleAutoTakeoff)bD=bD+dd+20;MakeButton("Show Orbit Display","Hide Orbit Display",de,dd,bC,bD,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then K="Orbit Display Enabled"else K="Orbit Display Disabled"end end)bD=bD+dd+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",de,dd,bC,bD,function()return Reentry end,function()x=true;BeginReentry()end,function()return ae>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",de,dd,bC+de+20,bD,function()return Reentry end,BeginReentry,function()return ae>ReentryAltitude end)bD=bD+dd+20;MakeButton("Engage Follow Mode","Disable Follow Mode",de,dd,bC,bD,function()return I end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",de,dd,bC+de+20,bD,function()return aH end,function()aH=not aH;if aH then K="Repair Arrows Enabled"else K="Repair Arrows Diabled"end end,function()return o()==1 end)bD=bD+dd+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",de,dd,bC,bD,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bD=bD+dd+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,de*2,dd,bC,bD,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 dh=Nav.axisCommandManager:getAxisCommandType(0)local di="TRAVEL"if dh==1 then di="CRUISE"end;if Autopilot then di="AUTOPILOT"end;return di end;function UpdateHud(c7)local bR=ae;local b5=core.getVelocity()local bw=vec3(b5):len()local cc=vec3(core.getWorldVertical())local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local dj=vec3(core.getConstructWorldOrientationUp())local dk=getRoll(cc,ca,cb)local dl=dk/180*math.pi;local dm=math.cos(dl)local dn=math.sin(dl)local cd=getPitch(cc,ca,cb*dm+dj*dn)local dp=dk;local dq=cd;local dr=j()local ds=d(unit.getThrottle())local dt=bw*3.6;local du=unit.getAxisCommandValue(0)if ad and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then du=PlayerThrottle;ds=PlayerThrottle*100 end;local di=GetFlightStyle()local dv="ROLL"local dw=unit.getClosestPlanetInfluence()>0;if ds==nil then ds=0 end;if not dw then if bw>5 then cd=getRelativePitch(b5)dk=getRelativeYaw(b5)else cd=0;dk=0 end;dv="YAW"end;c7[#c7+1]=a5;c7[#c7+1]=ao;c7[#c7+1]=a4;if aR%aK==0 then aP=true end;if fuelX~=0 and fuelY~=0 then DrawTank(c7,aP,fuelX,"Atmospheric ","ATMO",aD,aN,aO)DrawTank(c7,aP,fuelX+100,"Space fuel t","SPACE",aE,aL,aM)DrawTank(c7,aP,fuelX+200,"Rocket fuel ","ROCKET",aF,aI,aJ)end;if aP then aP=false;aR=0 end;aR=aR+1;DrawVerticalSpeed(c7,bR)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if dw then DrawRollLines(c7,centerX,centerY,dp,dv,dw)DrawArtificialHorizon(c7,dq,dp,centerX,centerY,dw,d(getRelativeYaw(b5)),bw)else DrawRollLines(c7,centerX,centerY,dk,dv,dw)DrawArtificialHorizon(c7,cd,dk,centerX,centerY,dw,d(dk),bw)end;DrawAltitudeDisplay(c7,bR,dw)DrawPrograde(c7,b5,bw,centerX,centerY)end end;DrawThrottle(c7,di,ds,du)DrawSpeed(c7,dt)DrawWarnings(c7)DisplayOrbitScreen(c7)if screen_2 then local bV=vec3(core.getConstructWorldPos())local bC=960+bV.x/aU;local bD=450+bV.y/aV;screen_2.moveContent(aW,(bC-80)/19.2,(bD-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(c7)local dx=aj;local dy=ak;local dz=aj;local dA=ak;if IsInFreeLook()and not brightHud then dx=[[rgb(]]..d(PrimaryR*0.4+0.5)..","..d(PrimaryG*0.4+0.5)..","..d(PrimaryB*0.3+0.5)..[[)]]dy=[[rgb(]]..d(PrimaryR*0.3+0.5)..","..d(PrimaryG*0.3+0.5)..","..d(PrimaryB*0.2+0.5)..[[)]]end;c7[#c7+1]=e([[ ",ResolutionX,ResolutionY)c7[#c7+1]=aT;c7[#c7+1]=hD;c7[#c7+1]=""b1=true;c7[#c7+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(c7,"")system.setScreen(content)elseif b2 then local hD=table.concat(c7,"")c7={}c7[#c7+1]=e("",ResolutionX,ResolutionY)c7[#c7+1]=aT;c7[#c7+1]=hD;c7[#c7+1]=""end;if not b1 then c7[#c7+1]=e([[]],s,t,a0,a1)end else CheckButtons()end else if not J and o()==0 then CheckButtons()if a3>DeadZone then DrawCursorLine(c7)end else SetButtonContains()DrawButtons(c7)end;c7[#c7+1]=e([[]],s,t,a0,a1)end;c7[#c7+1]=[[]]content=table.concat(c7,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end elseif hB=="apTick"then b4=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())ad=j()>0;local bj=system.getTime()local hE=bj-bc;bc=bj;local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local hF=vec3(core.getConstructWorldOrientationUp())local cc=vec3(core.getWorldVertical())local hG=core.getVelocity()local dk=getRoll(cc,ca,cb)local dl=dk/180*math.pi;local dm=math.cos(dl)local dn=math.sin(dl)local cd=getPitch(cc,ca,cb)local hH=getPitch(cc,ca,cb*dm+hF*dn)local hI=-math.deg(cu(hF,b5,ca))local hJ=math.deg(cu(cb,b5,ca))bb=ad and hI<-StallAngle or hI>StallAngle or hJ<-StallAngle or hJ>StallAngle;local hK=50;b9=system.getMouseDeltaX()ba=system.getMouseDeltaY()if InvertMouse and not J then ba=-ba end;D=0;H=0;C=0;b5=vec3(core.getWorldVelocity())b6=vec3(b5):len()sys=aY[0]planet=sys:closestBody(core.getConstructWorldPos())kepPlanet=b0(planet)orbit=kepPlanet:orbitalParameters(core.getConstructWorldPos(),b5)aa=hoverDetectGround()local bt=planet:getGravity(core.getConstructWorldPos()):len()*n()bd=0;a_=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then a0=screen_1.getMouseX()*ResolutionX;a1=screen_1.getMouseY()*ResolutionY elseif system.isViewLocked()==0 then if o()==1 and J then if not b1 then a0=a0+b9;a1=a1+ba end else a0=0;a1=0 end else a0=a0+b9;a1=a1+ba;a3=math.sqrt(a0*a0+a1*a1)if not J and o()==0 then if userControlScheme=="virtual joystick"then if a0>0 and a0>DeadZone then D=D-(a0-DeadZone)*MouseXSensitivity elseif a0<0 and a00 and a1>DeadZone then C=C-(a1-DeadZone)*MouseYSensitivity elseif a1<0 and a18334;if b6>SpaceSpeedLimit/3.6 and not ad and not Autopilot and not hL then K="Space Speed Engine Shutoff reached"if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)end;if not hL and LastIsWarping then if not BrakeIsOn then BrakeToggle()end;if Autopilot then ToggleAutopilot()end end;LastIsWarping=hL;if ad and j()>0.09 then if b6>AtmoSpeedLimit/3.6 then if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.control.cancelCurrentControlMasterMode()end end end;if BrakeIsOn then G=1 else G=0 end;ae=core.getAltitude()if ae==0 then ae=(vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius end;if ProgradeIsOn then if b6>w then local hM=AlignToWorldVector(vec3(b5),0.01)if a7 then b3=true;if b6w then AlignToWorldVector(-vec3(b5))end end;if not ProgradeIsOn and a7 then if j()==0 then x=true;BeginReentry()a7=false;a9=true else a7=false;ToggleAutopilot()end end;if a9 and aeReentrySpeed-100 then ToggleAutopilot()a9=false end;if Autopilot and j()==0 and not a7 then local P,Q;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(b6)else P,Q=GetAutopilotTBBrakeDistanceAndTime(b6)end;P=P;Q=Q;local hN=AutopilotTargetCoords;local hO=false;AutopilotDistance=(vec3(hN)-vec3(core.getConstructWorldPos())):len()local hP=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()local db,dc=getDistanceDisplayString(hP)system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..db..'", "unit":"'..dc..'"}')local hQ=true;local hR=(V.center-(vec3(core.getConstructWorldPos())+vec3(b5):normalize()*AutopilotDistance)):len()-V.radius;db,dc=getDistanceDisplayString(hR)system.updateData(widgetTrajectoryAltitudeText,'{"label": "Projected Altitude", "value": "'..db..'", "unit":"'..dc..'"}')if orbit.apoapsis==nil and b6>300 and AutopilotAccelerating then local d8=vec3(hN)-vec3(core.getConstructWorldPos())local hS=utils.clamp(math.deg(cu(hF,b5:normalize(),d8:normalize()))*b6/500,-90,90)local hT=utils.clamp(math.deg(cu(cb,b5:normalize(),d8:normalize()))*b6/500,-90,90)if math.abs(hS)<5 and math.abs(hT)<5 then hS=hS*2;hT=hT*2 end;if math.abs(hS)<2 and math.abs(hT)<2 then hS=hS*2;hT=hT*2 end;local hI=-math.deg(cu(hF,ca,b5:normalize()))local hJ=-math.deg(cu(cb,ca,b5:normalize()))if apPitchPID==nil then apPitchPID=pid.new(2*0.01,0,2*0.1)end;apPitchPID:inject(hT-hJ)local hU=utils.clamp(apPitchPID:get(),-1,1)C=C+hU;if apYawPID==nil then apYawPID=pid.new(2*0.01,0,2*0.1)end;apYawPID:inject(hS-hI)local hV=utils.clamp(apYawPID:get(),-1,1)D=D+hV;hO=true end;if hR=MaxGameVelocity or unit.getThrottle()==0 and u then AutopilotAccelerating=false;AutopilotStatus="Cruising"AutopilotCruising=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)u=false end;if AutopilotDistance<=P then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)u=false end elseif AutopilotBraking then BrakeIsOn=true;G=1;if TurnBurn then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,100)end;if CustomTarget~=nil and CustomTarget.planetname=="Space"and b6<50 then K="Autopilot complete, arrived at space location"AutopilotBraking=false;Autopilot=false;AutopilotStatus="Aligning"elseif(CustomTarget==nil or CustomTarget~=nil and CustomTarget.planetname~="Space")and orbit.periapsis~=nil and orbit.eccentricity<1 then AutopilotStatus="Circularizing"local _,hW=b0(V):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)if b6<=hW then BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;AutopilotStatus="Aligning"K="Autopilot completed, orbit established"G=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)u=false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then ProgradeIsOn=true;a7=true end end end elseif AutopilotCruising then if AutopilotDistance<=P then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true end;if unit.getThrottle()>0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if hQ then if not AutopilotRealigned and CustomTarget==nil or not AutopilotRealigned and CustomTarget~=nil and CustomTarget.planetname~="Space"then if not a7 then AutopilotTargetCoords=vec3(V.center)+(AutopilotTargetOrbit+V.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()end;AutopilotRealigned=true elseif hQ then AutopilotAccelerating=true;AutopilotStatus="Accelerating"if not u then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,AutopilotInterplanetaryThrottle)u=true;BrakeIsOn=false end end end end end;if I then b3=true;local hT=0;local bV=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local hX=bV-vec3(core.getConstructWorldPos())local hY=vec3(hX):project_on(vec3(core.getConstructWorldOrientationForward())):len()local hZ=vec3(hX):project_on(vec3(core.getConstructWorldOrientationRight())):len()local a3=math.sqrt(hY*hY+hZ*hZ)AlignToWorldVector(hX:normalize())local h_=40;local i0=a3i3 then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(hT-cd)local hU=pitchPID:get()C=hU end end;local dQ=vec3(core.getWorldVertical())*-1;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local dw=unit.getClosestPlanetInfluence()>0;local i4=HoldAltitude-ae;local i5=500+b6;local hT=(utils.smoothstep(i4,-i5,i5)-0.5)*2*MaxPitch*utils.clamp(b6/100,0.1,1)if not AltitudeHold then hT=0 end;if LockPitch~=nil then if dw then hT=LockPitch else LockPitch=nil end end;b3=true;if Reentry then local i6=ReentrySpeed;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=i6 then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,i6)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if not x then hT=-80;if j()>0.02 then K="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;hT=0;b3=autoRollPreference end elseif Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==ReentrySpeed then x=false;Reentry=false;b3=autoRollPreference end end;local i7=C;if b6>w and not a8 and not VectorToTarget and not BrakeLanding then AlignToWorldVector(vec3(b5))end;if VectorToTarget and CustomTarget~=nil and AutopilotTargetIndex>0 then local d8=CustomTarget.position-vec3(core.getConstructWorldPos())local hF=vec3(core.getConstructWorldOrientationUp())local hS=math.deg(cu(cc,b5:normalize(),d8:normalize()))*2;local i8=math.rad(math.abs(dk))if b6>hK then bd=utils.clamp(hS/2,-90,90)local i9=hS;hS=utils.clamp(hI-hS,hI-StallAngle*0.85,hI+StallAngle*0.85)*math.cos(i8)+utils.clamp(hT-hH,-StallAngle*0.85,StallAngle*0.85)*math.sin(math.rad(dk))hT=utils.clamp(hT*math.cos(i8),-StallAngle*0.85,StallAngle*0.85)+utils.clamp(math.abs(i9),-StallAngle*0.85,StallAngle*0.85)*math.sin(i8)end;local ia=hS;if not bb and b6>hK then if yawPID==nil then yawPID=pid.new(2*0.01,0,2*0.1)end;yawPID:inject(ia)local hV=utils.clamp(yawPID:get(),-1,1)D=D+hV elseif aa>-1 or b6100 then P,Q=aZ.computeDistanceAndTime(b6,100,n(),0,0,id+ih)local ii,ij=aZ.computeDistanceAndTime(100,0,n(),0,0,id/2)P=P+ii else P,Q=aZ.computeDistanceAndTime(b6,0,n(),0,0,id/2)end;StrongBrakes=true;if ic<=P+b6*hE/2 then VectorStatus="Finalizing Approach"if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)if AltitudeHold then ToggleAltitudeHold()VectorToTarget=true end;BrakeIsOn=true;if ie<1 or ic<1 then BrakeLanding=true;VectorToTarget=false end elseif not AutoTakeoff then BrakeIsOn=false end end;C=i7;local fg=-1;local i3=0.1;if BrakeLanding then hT=0;local dO=b5.x*dQ.x+b5.y*dQ.y+b5.z*dQ.z;local ik=false;local il=30;if a_~=nil and a_>0 then local ih=0;local dr=utils.clamp(j(),0.4,2)local id=LastMaxBrakeInAtmo*utils.clamp(b6/100,0.1,1)*dr;local im=a_*dr+id+ih-bt;local io=id+ih-bt;local ip=id/2+ih-bt;local iq=b6-math.sqrt(math.abs(ip/2)*20/(0.5*n()))*utils.sign(ip)if iq<0 then iq=0 end;local ir;if b6>100 then local is,_=aZ.computeDistanceAndTime(b6,100,n(),0,0,id)local it,_=aZ.computeDistanceAndTime(100,0,n(),0,0,math.sqrt(id))ir=is+it else ir=aZ.computeDistanceAndTime(b6,0,n(),0,0,math.sqrt(id))end;if ir<20 then BrakeIsOn=false else local iu=0;if iq>100 then local iv,_=aZ.computeDistanceAndTime(iq,100,n(),0,0,im)local iw,_=aZ.computeDistanceAndTime(100,0,n(),0,0,a_*dr+math.sqrt(id)+ih-bt)iu=iv+iw else iu,_=aZ.computeDistanceAndTime(iq,0,n(),0,0,a_*dr+math.sqrt(id)+ih-bt)end;iu=(iu+15+b6*hE)*1.1;local ix=CustomTarget~=nil and planet:getAltitude(CustomTarget.position)>0;if ix then local ib=planet:getAltitude(CustomTarget.position)local iy=ae-ib-100;local d8=CustomTarget.position-vec3(core.getConstructWorldPos())local iz=math.sqrt(d8:len()^2-(ae-ib)^2)if iz>100 then ix=false elseif iy<=iu or iu==-1 then BrakeIsOn=true;ik=true else BrakeIsOn=false;ik=true end end;if not ix and CalculateBrakeLandingSpeed then if iu>=il then BrakeIsOn=true else BrakeIsOn=false end;ik=true end end end;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)fg=aa;if fg>-1 then b3=autoRollPreference;if b6<1 or b5:normalize():dot(cc)<0 then BrakeLanding=false;AltitudeHold=false;GearExtended=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)Z=0;BrakeIsOn=true else BrakeIsOn=true end elseif StrongBrakes and b5:normalize():dot(-dQ)<0.999 then BrakeIsOn=true elseif dO<-brakeLandingRate and not ik then BrakeIsOn=true elseif not ik then BrakeIsOn=false end end;if AutoTakeoff or a8 then if hT<15 and ae/HoldAltitude>0.75 then AutoTakeoff=false;if not a8 then if Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end elseif a8 and b675000 then if Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=1500 then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,1500)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end end end;local iA=hoverDetectGround()>-1;local iB=cd;if VectorToTarget and not iA and b6>hK then local i8=math.rad(math.abs(dk))iB=cd*math.cos(i8)+hJ*math.sin(i8)end;local iC=utils.clamp(hT-iB,-StallAngle*0.85,StallAngle*0.85)if math.abs(iC)>i3 and(not bb and(math.abs(dk)<5 or VectorToTarget)or BrakeLanding or iA)then if pitchPID==nil then pitchPID=pid.new(8*0.01,0,8*0.1)end;pitchPID:inject(iC)local hU=pitchPID:get()C=C+hU end end;L=orbit.eccentricity;if antigrav and not ExternalAGG and ae<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 and not ExternalAGG then if antigrav.getState()==0 and antigrav.getBaseAltitude()~=AntigravTargetAltitude then antigrav.setBaseAltitude(AntigravTargetAltitude)end 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 iD=utils.clamp(B+C+system.getControlDeviceForwardInput(),-1,1)local iE=utils.clamp(E+H+system.getControlDeviceYawInput(),-1,1)local iF=utils.clamp(F+D-system.getControlDeviceLeftRightInput(),-1,1)local iG=G;local iH=vec3(core.getWorldVertical())local iI=vec3(core.getConstructWorldOrientationUp())local iJ=vec3(core.getConstructWorldOrientationForward())local iK=vec3(core.getConstructWorldOrientationRight())local iL=vec3(core.getWorldVelocity())local iM=vec3(core.getWorldVelocity()):normalize()local iN=getRoll(iH,iJ,iK)local iO=math.abs(iN)local iP=utils.sign(iN)local j=j()local iQ=vec3(core.getWorldAngularVelocity())local iR=iD*pitchSpeedFactor*iK+iE*rollSpeedFactor*iJ+iF*yawSpeedFactor*iI;if iH:len()>0.01 and j>0.0 or ProgradeIsOn then if b3==true and math.abs(bd-iN)>autoRollRollThreshold and iE==0 then local iS=bd;local iT=autoRollFactor;if rollPID==nil then rollPID=pid.new(iT*0.01,0,iT*0.1)end;rollPID:inject(iS-iN)local iU=rollPID:get()iR=iR+iU*iJ end end;if iH:len()>0.01 and j>0.0 then local iV=20.0;if turnAssist==true and iO>iV and iD==0 and iF==0 then local iW=turnAssistFactor*0.1;local iX=turnAssistFactor*0.025;local iY=(iO-iV)/(180-iV)*180;local iZ=0;if iY<90 then iZ=iY/90 elseif iY<180 then iZ=(180-iY)/90 end;iZ=iZ*iZ;local i_=-iP*iX*(1.0-iZ)local j0=iW*iZ;iR=iR+j0*iK+i_*iI end end;local j1=1;local j2=0;local j3=1;local j4=torqueFactor*(iR-iQ)local j5=vec3(core.getWorldAirFrictionAngularAcceleration())j4=j4-j5;Nav:setEngineTorqueCommand('torque',j4,j1,'airfoil','','',j3)local j6=-iG*(brakeSpeedFactor*iL+brakeFlatFactor*iM)Nav:setEngineForceCommand('brake',j6)local j7=''local j8=vec3()local j9=false;local ja='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then ja=ja..ExtraLongitudeTags end;local jb=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if jb==axisCommandType.byThrottle then local jc=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ja,axisCommandId.longitudinal)Nav:setEngineForceCommand(ja,jc,j1)elseif jb==axisCommandType.byTargetSpeed then local jc=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)j7=j7 ..' , '..ja;j8=j8+jc;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then j9=true end end;local jd='thrust analog lateral 'if ExtraLateralTags~="none"then jd=jd..ExtraLateralTags end;local je=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if je==axisCommandType.byThrottle then local jf=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jd,axisCommandId.lateral)Nav:setEngineForceCommand(jd,jf,j1)elseif je==axisCommandType.byTargetSpeed then local jg=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)j7=j7 ..' , '..jd;j8=j8+jg end;local jh='thrust analog vertical 'if ExtraVerticalTags~="none"then jh=jh..ExtraVerticalTags end;local ji=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if ji==axisCommandType.byThrottle then local jj=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jh,axisCommandId.vertical)if Z~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(jh,jj,j1,'airfoil','ground','',j3)else Nav:setEngineForceCommand(jh,vec3(),j1)Nav:setEngineForceCommand('airfoil vertical',jj,j1,'airfoil','','',j3)Nav:setEngineForceCommand('ground vertical',jj,j1,'ground','','',j3)end elseif ji==axisCommandType.byTargetSpeed then if Z==0 then Nav:setEngineForceCommand('hover',vec3(),j1)end;local jk=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)j7=j7 ..' , '..jh;j8=j8+jk end;if j8:len()>constants.epsilon then if G~=0 or j9 or math.abs(iM:dot(iJ))<0.95 then j7=j7 ..', brake'end;Nav:setEngineForceCommand(j7,j8,j2,'','','',j3)end;Nav:setBoosterCommand('rocket_engine')if O and not VanillaRockets then local bw=vec3(core.getVelocity()):len()local jl=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local jm=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bw*3.6>jm*(1-jl)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw*3.6=i2*(1-jl)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw=i2*(1-jl)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw0 or aew then K="WARNING: Insufficient Brakes - Attempting landing anyway"end;Reentry=false;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=true;b3=true;GearExtended=false else BrakeIsOn=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end;if A and not BrakeLanding then Nav.control.extendLandingGears()end else if A then Nav.control.retractLandingGears()end;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end elseif jo=="light"then if Nav.control.isAnyHeadlightSwitchedOn()==1 then Nav.control.switchOffHeadlights()else Nav.control.switchOnHeadlights()end elseif jo=="forward"then B=B-1 elseif jo=="backward"then B=B+1 elseif jo=="left"then E=E-1 elseif jo=="right"then E=E+1 elseif jo=="yawright"then F=F-1 elseif jo=="yawleft"then F=F+1 elseif jo=="straferight"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,1.0)elseif jo=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,-1.0)elseif jo=="up"then Z=Z+1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,1.0)elseif jo=="down"then Z=Z-1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,-1.0)elseif jo=="groundaltitudeup"then OldButtonMod=M;OldAntiMod=N;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+N;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+N end else AntigravTargetAltitude=desiredBaseAltitude+100 end elseif AltitudeHold then HoldAltitude=HoldAltitude+M else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)end elseif jo=="groundaltitudedown"then OldButtonMod=M;OldAntiMod=N;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end else AntigravTargetAltitude=desiredBaseAltitude end elseif AltitudeHold then HoldAltitude=HoldAltitude-M else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)end elseif jo=="option1"then IncrementAutopilotTargetIndex()v=false elseif jo=="option2"then DecrementAutopilotTargetIndex()v=false elseif jo=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;v=false;ToggleWidgets()elseif jo=="option4"then ToggleAutopilot()v=false elseif jo=="option5"then ToggleLockPitch()v=false elseif jo=="option6"then ToggleAltitudeHold()v=false elseif jo=="option7"then wipeSaveVariables()v=false elseif jo=="option8"then ToggleFollowMode()v=false elseif jo=="option9"then if gyro~=nil then gyro.toggle()ah=gyro.getState()==1 end;v=false elseif jo=="lshift"then if system.isViewLocked()==1 then J=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then J=true;b2=false;b1=false end elseif jo=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif jo=="lalt"then if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif jo=="booster"then if VanillaRockets then Nav:toggleBoosters()elseif not O then if not IsRocketOn then Nav:toggleBoosters()IsRocketOn=true end;O=true else if IsRocketOn then Nav:toggleBoosters()IsRocketOn=false end;O=false end elseif jo=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()elseif jo=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)else IncrementAutopilotTargetIndex()end elseif jo=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)else DecrementAutopilotTargetIndex()end elseif jo=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(jo)if jo=="forward"then B=0 elseif jo=="backward"then B=0 elseif jo=="left"then E=0 elseif jo=="right"then E=0 elseif jo=="yawright"then F=0 elseif jo=="yawleft"then F=0 elseif jo=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)elseif jo=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)elseif jo=="up"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif jo=="down"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif jo=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif jo=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif jo=="lshift"then if system.isViewLocked()==1 then J=false;a0=0;a1=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then J=false;b2=false;b1=false end elseif jo=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif jo=="lalt"then if o()==0 and freeLookToggle then if v then if system.isViewLocked()==1 then system.lockView(0)else system.lockView(1)end else v=true end elseif o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(0)end end end;function script.onActionLoop(jo)if jo=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+N;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+N end;N=N*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude+100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude+M;M=M*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)end elseif jo=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end;N=N*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude-100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude-M;M=M*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)end elseif jo=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end elseif jo=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end;function script.onInputText(jp)local i;local jq="/commands /setname /G /agg /addlocation /copydatabank"local jr,js=nil,nil;local jt="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(jp," ")jr=jp;if i~=nil then jr=string.sub(jp,0,i-1)js=string.sub(jp,i+1)elseif not string.find(jq,jr)then for fy in string.gmatch(jt,"([^\n]+)")do c(fy)end;return end;if jr=="/setname"then if js==nil or js==""then K="Usage: /setname Newname"return end;if AutopilotTargetIndex>0 and CustomTarget~=nil then UpdatePosition(js)else K="Select a saved target to rename first"end elseif jr=="/addlocation"then if js==nil or js==""or string.find(js,"::")==nil then K="Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}"return end;i=string.find(js,"::")local c0=string.sub(js,1,i-2)local bV=string.sub(js,i)local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local bW='::pos{'..p..','..p..','..p..','..p..','..p..'}'local bX,bY,bS,bT,bR=string.match(bV,bW)local planet=aS[tonumber(bX)][tonumber(bY)]AddNewLocationByWaypoint(c0,planet,bV)K="Added "..c0 .." to saved locations,\nplanet "..planet.name.." at "..bV;a2=5 elseif jr=="/agg"then if js==nil or js==""then K="Usage: /agg targetheight"return end;js=tonumber(js)if js<1000 then js=1000 end;AntigravTargetAltitude=js;K="AGG Target Height set to "..js elseif jr=="/G"then if js==nil or js==""then K="Usage: /G VariableName variablevalue\n/G dump - shows all variables"return end;if js=="dump"then for bg,bh in pairs(a)do if type(_G[bh])=="boolean"then if _G[bh]==true then c(bh.." true")else c(bh.." false")end elseif _G[bh]==nil then c(bh.." nil")else c(bh.." ".._G[bh])end end;return end;i=string.find(js," ")local ju=string.sub(js,0,i-1)local jv=string.sub(js,i+1)for bg,bh in pairs(a)do if bh==ju then K="Variable "..ju.." changed to "..jv;local jw=type(_G[bh])if jw=="number"then jv=tonumber(jv)elseif jw=="boolean"then if string.lower(jv)=="true"then jv=true else jv=false end end;_G[bh]=jv;return end end;K="No such global variable: "..ju elseif jr=="/copydatabank"then if dbHud_2 then SaveDataBank(true)else K="Databank required to copy databank"end end end;script.onStart() + Radar: No Contacts]],ft,fu)end;if radarPanelID~=nil then a6=0;ToggleRadarPanel()end end end end;function DisplayMessage(c7,db)if db~="empty"then c7[#c7+1]=[[]]for fy in string.gmatch(db,"([^\n]+)")do c7[#c7+1]=e([[%s]],fy)end;c7[#c7+1]=[[]]end;if a2~=0 then unit.setTimer("msgTick",a2)a2=0 end end;function updateDistance()local bp=system.getTime()local b5=vec3(core.getWorldVelocity())local dt=vec3(b5):len()local fz=bp-ag;if dt>1.38889 then dt=dt/1000;local fA=dt*(bp-ag)TotalDistanceTravelled=TotalDistanceTravelled+fA;W=W+fA end;X=X+fz;TotalFlightTime=TotalFlightTime+fz;ag=bp end;function composeAxisAccelerationFromTargetSpeed(fB,fC)local fD=vec3()local fE=vec3()if fB==axisCommandId.longitudinal then fD=vec3(core.getConstructOrientationForward())fE=vec3(core.getConstructWorldOrientationForward())elseif fB==axisCommandId.vertical then fD=vec3(core.getConstructOrientationUp())fE=vec3(core.getConstructWorldOrientationUp())elseif fB==axisCommandId.lateral then fD=vec3(core.getConstructOrientationRight())fE=vec3(core.getConstructWorldOrientationRight())else return vec3()end;local fF=vec3(core.getWorldGravity())local fG=fF:dot(fE)local fH=vec3(core.getWorldAirFrictionAcceleration())local fI=fH:dot(fE)local fJ=vec3(core.getVelocity())local fK=fJ:dot(fD)local fL=fC*constants.kph2m;if targetSpeedPID==nil then targetSpeedPID=pid.new(1,0,10.0)end;targetSpeedPID:inject(fL-fK)local fM=targetSpeedPID:get()local fN=(fM-fI-fG)*fE;return fN 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},[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()aS=Atlas()for bg,bh in pairs(aS[0])do if av==nil or bh.center.xaw then aw=bh.center.x end;if ax==nil or bh.center.yay then ay=bh.center.y end end;aT=""local fO=1.1*(aw-av)/1920;local fP=1.4*(ay-ax)/1080;for bg,bh in pairs(aS[0])do local bC=960+bh.center.x/fO;local bD=540+bh.center.y/fP;aT=aT..''if not string.match(bh.name,"Moon")and not string.match(bh.name,"Sanctuary")and not string.match(bh.name,"Space")then aT=aT..""..bh.name..""end end;local bV=vec3(core.getConstructWorldPos())local bC=960+bV.x/fO;local bD=540+bV.y/fP;aT=aT..''aT=aT.."You Are Here"aT=aT..[[]]aU=fO;aV=fP;if screen_2 then screen_2.setHTML(''..aT)local bV=vec3(core.getConstructWorldPos())local bC=960+bV.x/fO;local bD=540+bV.y/fP;aT=''aT=aT.."You Are Here"aW=screen_2.addContent((bC-80)/19.20,(bD-80)/10.80,aT)end end;function PlanetRef()local function fQ(fR)return type(fR)=='number'end;local function fS(fR)return type(tonumber(fR))=='number'end;local function fT(fU)return type(fU)=='table'end;local function fV(fW)return type(fW)=='string'end;local function fX(bh)return fT(bh)and fQ(bh.x and bh.y and bh.z)end;local function fY(fZ)return fT(fZ)and fQ(fZ.latitude and fZ.longitude and fZ.altitude and fZ.bodyId and fZ.systemId)end;local f_=math.pi/180;local g0=180/math.pi;local epsilon=1e-10;local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local bW='::pos{'..p..','..p..','..p..','..p..','..p..'}'local utils=require('cpml.utils')local vec3=require('cpml.vec3')local g1=utils.clamp;local function float_eq(bL,bM)if bL==0 then return math.abs(bM)<1e-09 end;if bM==0 then return math.abs(bL)<1e-09 end;return math.abs(bL-bM)=0 then local gR=math.sqrt(gQ)local gS=gP+gR;local gT=gP-gR;if gT>0 then return gG,gS,gT elseif gS>0 then return gG,gS,nil end end end;return nil,nil,nil end;function gi:closestBody(gU)assert(type(gU)=='table','Invalid coordinates.')local gV,gG;local gW=vec3(gU)for _,gX in pairs(self)do local gY=(gX.center-gW):len2()if(not gG or gY=0 and bU or 2*math.pi+bU;bS=math.pi/2-math.acos(bQ.z/a3)end;return setmetatable({latitude=bS,longitude=bT,altitude=bR,bodyId=self.bodyId,systemId=self.planetarySystemId},MapPosition)end;function g7:convertToWorldCoordinates(gh)local gZ=fV(gh)and gg(gh)or gh;if gZ.bodyId==0 then return vec3(gZ.latitude,gZ.longitude,gZ.altitude)end;assert(fY(gZ),'Argument 1 (mapPosition) is not an instance of "MapPosition".')assert(gZ.systemId==self.planetarySystemId,'Argument 1 (mapPosition) has a different planetary system ID.')assert(gZ.bodyId==self.bodyId,'Argument 1 (mapPosition) has a different planetary body ID.')local bZ=math.cos(gZ.latitude)return self.center+(self.radius+gZ.altitude)*vec3(bZ*math.cos(gZ.longitude),bZ*math.sin(gZ.longitude),math.sin(gZ.latitude))end;function g7:getAltitude(bO)return(vec3(bO)-self.center):len()-self.radius end;function g7:getDistance(bO)return(vec3(bO)-self.center):len()end;function g7:getGravity(bO)local g_=self.center-vec3(bO)local h0=g_:len2()return self.GM/h0*g_/math.sqrt(h0)end;return setmetatable(aX,{__call=function(_,...)return gq(...)end})end;function Keplers()local vec3=require('cpml.vec3')local PlanetRef=PlanetRef()local function fV(fW)return type(fW)=='string'end;local function fT(fU)return type(fU)=='table'end;local function float_eq(bL,bM)if bL==0 then return math.abs(bM)<1e-09 end;if bM==0 then return math.abs(bL)<1e-09 end;return math.abs(bL-bM)0 then hh=hg;hi=hh+hb/2 end;if hi>hb then hi=hi-hb end end;return{periapsis={position=h8,speed=ha/h6,circularOrbitSpeed=math.sqrt(h3/h6),altitude=h6-self.body.radius},apoapsis=h9 and{position=h9,speed=ha/h7,circularOrbitSpeed=math.sqrt(h3/h7),altitude=h7-self.body.radius},currentVelocity=bh,currentPosition=bV,eccentricity=h5,period=hb,eccentricAnomaly=hd,meanAnomaly=hf,timeToPeriapsis=hh,timeToApoapsis=hi}end;local function hj(hk)local gX=PlanetRef.BodyParameters(hk.planetarySystemId,hk.bodyId,hk.radius,hk.center,hk.GM)return setmetatable({body=gX},Kepler)end;return setmetatable(Kepler,{__call=function(_,...)return hj(...)end})end;function Kinematics()local aZ={}local hl=30000000/3600;local hm=hl*hl;local hn=100;local function ho(bh)return 1/math.sqrt(1-bh*bh/hm)end;function aZ.computeAccelerationTime(hp,hq,hr)local hs=hl*math.asin(hp/hl)return(hl*math.asin(hr/hl)-hs)/hq end;function aZ.computeDistanceAndTime(hp,hr,ht,hu,hv,hw)hv=hv or 0;hw=hw or 0;local hx=hp<=hr;local hy=hu*(hx and 1 or-1)/ht;local hz=-hw/ht;local hA=hy+hz;if hx and hA<=0 or not hx and hA>=0 then return-1,-1 end;local hB,hC=0,0;if hy~=0 and hv>0 then local hs=math.asin(hp/hl)local hD=math.pi*(hy/2+hz)local hE=hy*hv;local hF=hl*math.pi;local bh=function(fU)local cz=(hD*fU-hE*math.sin(math.pi*fU/2/hv)+hF*hs)/hF;local hG=math.tan(cz)return hl*hG/math.sqrt(hG*hG+1)end;local hH=hx and function(fW)return fW>=hr end or function(fW)return fW<=hr end;hC=2*hv;if hH(bh(hC))then local hI=0;while math.abs(hC-hI)>0.5 do local fU=(hC+hI)/2;if hH(bh(fU))then hC=fU else hI=fU end end end;local hJ=hp;local hK=hC/hn;for hL=1,hn do local bw=bh(hL*hK)hB=hB+(bw+hJ)*hK/2;hJ=bw end;if hC<2*hv then return hB,hC end;hp=hJ end;local hs=hl*math.asin(hp/hl)local bj=(hl*math.asin(hr/hl)-hs)/hA;local hM=hm*math.cos(hs/hl)/hA;local a3=hM-hm*math.cos((hA*bj+hs)/hl)/hA;return a3+hB,bj+hC end;function aZ.computeTravelTime(hp,hq,a3)if a3==0 then return 0 end;if hq>0 then local hs=hl*math.asin(hp/hl)local hM=hm*math.cos(hs/hl)/hq;return(hl*math.acos(hq*(hM-a3)/hm)-hs)/hq end;assert(hp>0,'Acceleration and initial speed are both zero.')return a3/hp end;function aZ.lorentz(bh)return ho(bh)end;return aZ end;function script.onStart()VERSION_NUMBER=5.222;SetupComplete=false;beginSetup=coroutine.create(function()Nav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal,{1000,5000,10000,20000,30000})LoadVariables()coroutine.yield()ProcessElements()coroutine.yield()SetupChecks()SetupButtons()coroutine.yield()SetupAtlas()aX=PlanetRef()aY=aX(Atlas())aZ=Kinematics()b0=Keplers()AddLocationsToAtlas()UpdateAtlasLocationsList()UpdateAutopilotTarget()coroutine.yield()unit.hide()system.showScreen(1)collectgarbage("collect")coroutine.yield()unit.setTimer("apTick",apTickRate)unit.setTimer("hudTick",hudTickRate)unit.setTimer("oneSecond",1)unit.setTimer("tenthSecond",1/10)if UseSatNav then unit.setTimer("fiveSecond",5)end end)end;function SaveDataBank(hN)if dbHud_1 then if not Y then for bg,bh in pairs(b)do dbHud_1.setStringValue(bh,g(_G[bh]))if hN and dbHud_2 then dbHud_2.setStringValue(bh,g(_G[bh]))end end;for bg,bh in pairs(a)do dbHud_1.setStringValue(bh,g(_G[bh]))if hN and dbHud_2 then dbHud_2.setStringValue(bh,g(_G[bh]))end end;c("Saved Variables to Datacore")if hN and dbHud_2 then K="Databank copied. Remove copy when ready."end end end end;function script.onStop()_autoconf.hideCategoryPanels()if antigrav~=nil and not ExternalAGG then antigrav.hide()end;if warpdrive~=nil then warpdrive.hide()end;core.hide()Nav.control.switchOffHeadlights()local br=j()if door and(br>0 or br==0 and ae<10000)then for _,bh in pairs(door)do bh.toggle()end end;if switch then for _,bh in pairs(switch)do bh.toggle()end end;if forcefield and(br>0 or br==0 and ae<10000)then for _,bh in pairs(forcefield)do bh.toggle()end end;SaveDataBank()if button then button.activate()end end;function script.onTick(hO)if hO=="tenthSecond"then if AutopilotTargetName~="None"then if panelInterplanetary==nil then SetupInterplanetaryPanel()end;if AutopilotTargetName~=nil then local hP=CustomTarget~=nil;planetMaxMass=GetAutopilotMaxMass()system.updateData(interplanetaryHeaderText,'{"label": "Target", "value": "'..AutopilotTargetName..'", "unit":""}')travelTime=GetAutopilotTravelTime()if hP then a3=(vec3(core.getConstructWorldPos())-CustomTarget.position):len()else a3=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()end;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(b6)R,S=GetAutopilotBrakeDistanceAndTime(MaxGameVelocity)else P,Q=GetAutopilotTBBrakeDistanceAndTime(b6)R,S=GetAutopilotTBBrakeDistanceAndTime(MaxGameVelocity)end;local db,dc=getDistanceDisplayString(a3)system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..db..'", "unit":"'..dc..'"}')system.updateData(widgetTravelTimeText,'{"label": "Travel Time", "value": "'..FormatTimeString(travelTime)..'", "unit":""}')db,dc=getDistanceDisplayString(P)system.updateData(widgetCurBrakeDistanceText,'{"label": "Cur Brake distance", "value": "'..db..'", "unit":"'..dc..'"}')system.updateData(widgetCurBrakeTimeText,'{"label": "Cur Brake Time", "value": "'..FormatTimeString(Q)..'", "unit":""}')db,dc=getDistanceDisplayString(R)system.updateData(widgetMaxBrakeDistanceText,'{"label": "Max Brake distance", "value": "'..db..'", "unit":"'..dc..'"}')system.updateData(widgetMaxBrakeTimeText,'{"label": "Max Brake Time", "value": "'..FormatTimeString(S)..'", "unit":""}')system.updateData(widgetMaxMassText,'{"label": "Maximum Mass", "value": "'..e("%.2f",planetMaxMass/1000)..'", "unit":" Tons"}')db,dc=getDistanceDisplayString(AutopilotTargetOrbit)system.updateData(widgetTargetOrbitText,'{"label": "Target Orbit", "value": "'..e("%.2f",db)..'", "unit":"'..dc..'"}')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;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then PlayerThrottle=unit.getAxisCommandValue(0)elseif AtmoSpeedAssist then PlayerThrottle=1;Nav.control.cancelCurrentControlMasterMode()end 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;if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,PlayerThrottle)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 hO=="oneSecond"then ab=false;RefreshLastMaxBrake(nil,true)updateDistance()updateRadar()updateWeapons()local c7={}local di=GetFlightStyle()DrawOdometer(c7,W,TotalDistanceTravelled,di,X)if ShouldCheckDamage then CheckDamage(c7)end;a5=table.concat(c7,"")collectgarbage("collect")elseif hO=="fiveSecond"then ac=dbHud_1.getStringValue("SPBAutopilotTargetName")if ac~=nil and ac~=""and ac~="SatNavNotChanged"then local bi=json.decode(dbHud_1.getStringValue("SavedLocations"))if bi~=nil then _G["SavedLocations"]=bi;local c5=-1;local c1;for bg,bh in pairs(SavedLocations)do if bh.name and bh.name=="SatNav Location"then c5=bg;break end end;if c5~=-1 then c1=SavedLocations[c5]c5=-1;for bg,bh in pairs(aS[0])do if bh.name and bh.name=="SatNav Location"then c5=bg;break end end;if c5>-1 then aS[0][c5]=c1 end;UpdateAtlasLocationsList()K=c1.name.." position updated"end end;for i=1,#AtlasOrdered do if AtlasOrdered[i].name==ac then AutopilotTargetIndex=i;system.print("Index = "..AutopilotTargetIndex.." "..AtlasOrdered[i].name)UpdateAutopilotTarget()dbHud_1.setStringValue("SPBAutopilotTargetName","SatNavNotChanged")break end end end elseif hO=="msgTick"then local c7={}DisplayMessage(c7,"empty")K="empty"unit.stopTimer("msgTick")a2=3 elseif hO=="animateTick"then b2=true;b1=false;a0=0;a1=0;unit.stopTimer("animateTick")elseif hO=="hudTick"then local c7={}HUDPrologue(c7)if showHud then UpdateHud(c7)else DisplayOrbitScreen(c7)DrawWarnings(c7)end;HUDEpilogue(c7)c7[#c7+1]=e([[]],ResolutionX,ResolutionY)if K~="empty"then DisplayMessage(c7,K)end;if o()==0 and userControlScheme=="virtual joystick"then DrawDeadZone(c7)end;if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then SetButtonContains()DrawButtons(c7)if screen_1.getMouseState()==1 then CheckButtons()end;c7[#c7+1]=e([[]],s,t,a0,a1)elseif system.isViewLocked()==0 then if o()==1 and J then SetButtonContains()DrawButtons(c7)if not b1 and not b2 then local hQ=table.concat(c7,"")c7={}c7[#c7+1]=e("",ResolutionX,ResolutionY)c7[#c7+1]=aT;c7[#c7+1]=hQ;c7[#c7+1]=""b1=true;c7[#c7+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(c7,"")system.setScreen(content)elseif b2 then local hQ=table.concat(c7,"")c7={}c7[#c7+1]=e("",ResolutionX,ResolutionY)c7[#c7+1]=aT;c7[#c7+1]=hQ;c7[#c7+1]=""end;if not b1 then c7[#c7+1]=e([[]],s,t,a0,a1)end else CheckButtons()end else if not J and o()==0 then CheckButtons()if a3>DeadZone then DrawCursorLine(c7)end else SetButtonContains()DrawButtons(c7)end;c7[#c7+1]=e([[]],s,t,a0,a1)end;c7[#c7+1]=[[]]content=table.concat(c7,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end elseif hO=="apTick"then b4=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())ad=j()>0;local bj=system.getTime()local hR=bj-bc;bc=bj;local ca=vec3(core.getConstructWorldOrientationForward())local cb=vec3(core.getConstructWorldOrientationRight())local hS=vec3(core.getConstructWorldOrientationUp())local cc=vec3(core.getWorldVertical())local hT=core.getVelocity()local dk=getRoll(cc,ca,cb)local dl=dk/180*math.pi;local dm=math.cos(dl)local dn=math.sin(dl)local cd=getPitch(cc,ca,cb)local hU=getPitch(cc,ca,cb*dm+hS*dn)local hV=-math.deg(cu(hS,b5,ca))local hW=math.deg(cu(cb,b5,ca))bb=ad and hV<-StallAngle or hV>StallAngle or hW<-StallAngle or hW>StallAngle;local hX=100;b9=system.getMouseDeltaX()ba=system.getMouseDeltaY()if InvertMouse and not J then ba=-ba end;D=0;H=0;C=0;b5=vec3(core.getWorldVelocity())b6=vec3(b5):len()sys=aY[0]planet=sys:closestBody(core.getConstructWorldPos())kepPlanet=b0(planet)orbit=kepPlanet:orbitalParameters(core.getConstructWorldPos(),b5)aa=hoverDetectGround()local bt=planet:getGravity(core.getConstructWorldPos()):len()*n()bd=0;a_=core.getMaxKinematicsParametersAlongAxis("ground",core.getConstructOrientationUp())[1]if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then a0=screen_1.getMouseX()*ResolutionX;a1=screen_1.getMouseY()*ResolutionY elseif system.isViewLocked()==0 then if o()==1 and J then if not b1 then a0=a0+b9;a1=a1+ba end else a0=0;a1=0 end else a0=a0+b9;a1=a1+ba;a3=math.sqrt(a0*a0+a1*a1)if not J and o()==0 then if userControlScheme=="virtual joystick"then if a0>0 and a0>DeadZone then D=D-(a0-DeadZone)*MouseXSensitivity elseif a0<0 and a00 and a1>DeadZone then C=C-(a1-DeadZone)*MouseYSensitivity elseif a1<0 and a18334;if b6>SpaceSpeedLimit/3.6 and not ad and not Autopilot and not hY then K="Space Speed Engine Shutoff reached"if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0 end;if not hY and LastIsWarping then if not BrakeIsOn then BrakeToggle()end;if Autopilot then ToggleAutopilot()end end;LastIsWarping=hY;if ad and j()>0.09 then if b6>AtmoSpeedLimit/3.6 and not AtmoSpeedAssist and not ai then BrakeIsOn=true;ai=true elseif not AtmoSpeedAssist and ai then if b6w then local hZ=AlignToWorldVector(vec3(b5),0.01)if a7 then b3=true;if b6w then AlignToWorldVector(-vec3(b5))end end;if not ProgradeIsOn and a7 then if j()==0 then x=true;BeginReentry()a7=false;a9=true else a7=false;ToggleAutopilot()end end;if a9 and aeReentrySpeed-100 then ToggleAutopilot()a9=false end;if Autopilot and j()==0 and not a7 then local P,Q;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(b6)else P,Q=GetAutopilotTBBrakeDistanceAndTime(b6)end;P=P;Q=Q;local h_=AutopilotTargetCoords;local i0=false;AutopilotDistance=(vec3(h_)-vec3(core.getConstructWorldPos())):len()local i1=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()local db,dc=getDistanceDisplayString(i1)system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..db..'", "unit":"'..dc..'"}')local i2=true;local i3=(V.center-(vec3(core.getConstructWorldPos())+vec3(b5):normalize()*AutopilotDistance)):len()-V.radius;db,dc=getDistanceDisplayString(i3)system.updateData(widgetTrajectoryAltitudeText,'{"label": "Projected Altitude", "value": "'..db..'", "unit":"'..dc..'"}')if orbit.apoapsis==nil and b6>300 and AutopilotAccelerating then local d8=vec3(h_)-vec3(core.getConstructWorldPos())local i4=utils.clamp(math.deg(cu(hS,b5:normalize(),d8:normalize()))*b6/500,-90,90)local i5=utils.clamp(math.deg(cu(cb,b5:normalize(),d8:normalize()))*b6/500,-90,90)if math.abs(i4)<5 and math.abs(i5)<5 then i4=i4*2;i5=i5*2 end;if math.abs(i4)<2 and math.abs(i5)<2 then i4=i4*2;i5=i5*2 end;local hV=-math.deg(cu(hS,ca,b5:normalize()))local hW=-math.deg(cu(cb,ca,b5:normalize()))if apPitchPID==nil then apPitchPID=pid.new(2*0.01,0,2*0.1)end;apPitchPID:inject(i5-hW)local i6=utils.clamp(apPitchPID:get(),-1,1)C=C+i6;if apYawPID==nil then apYawPID=pid.new(2*0.01,0,2*0.1)end;apYawPID:inject(i4-hV)local i7=utils.clamp(apYawPID:get(),-1,1)D=D+i7;i0=true end;if i3=MaxGameVelocity or unit.getThrottle()==0 and u then AutopilotAccelerating=false;AutopilotStatus="Cruising"AutopilotCruising=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0;u=false end;if AutopilotDistance<=P then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0;u=false end elseif AutopilotBraking then BrakeIsOn=true;G=1;if TurnBurn then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,100)end;if CustomTarget~=nil and CustomTarget.planetname=="Space"and b6<50 then K="Autopilot complete, arrived at space location"AutopilotBraking=false;Autopilot=false;AutopilotStatus="Aligning"elseif(CustomTarget==nil or CustomTarget~=nil and CustomTarget.planetname~="Space")and orbit.periapsis~=nil and orbit.eccentricity<1 then AutopilotStatus="Circularizing"local _,i8=b0(V):escapeAndOrbitalSpeed((vec3(core.getConstructWorldPos())-planet.center):len()-planet.radius)if b6<=i8 then BrakeIsOn=false;AutopilotBraking=false;Autopilot=false;AutopilotStatus="Aligning"K="Autopilot completed, orbit established"G=0;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0;u=false;if CustomTarget~=nil and CustomTarget.planetname~="Space"then ProgradeIsOn=true;a7=true end end end elseif AutopilotCruising then if AutopilotDistance<=P then AutopilotAccelerating=false;AutopilotStatus="Braking"AutopilotBraking=true end;if unit.getThrottle()>0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if i2 then if not AutopilotRealigned and CustomTarget==nil or not AutopilotRealigned and CustomTarget~=nil and CustomTarget.planetname~="Space"then if not a7 then AutopilotTargetCoords=vec3(V.center)+(AutopilotTargetOrbit+V.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()end;AutopilotRealigned=true elseif i2 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"if not u then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,AutopilotInterplanetaryThrottle)u=true;BrakeIsOn=false end end end end end;if I then b3=true;local i5=0;local bV=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local i9=bV-vec3(core.getConstructWorldPos())local ia=vec3(i9):project_on(vec3(core.getConstructWorldOrientationForward())):len()local ib=vec3(i9):project_on(vec3(core.getConstructWorldOrientationRight())):len()local a3=math.sqrt(ia*ia+ib*ib)AlignToWorldVector(i9:normalize())local ic=40;local id=a3ig then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(i5-cd)local i6=pitchPID:get()C=i6 end end;local dQ=vec3(core.getWorldVertical())*-1;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local dw=unit.getClosestPlanetInfluence()>0;local ih=HoldAltitude-ae;local ii=500+b6;local i5=(utils.smoothstep(ih,-ii,ii)-0.5)*2*MaxPitch*utils.clamp(b6/100,0.1,1)if not AltitudeHold then i5=0 end;if LockPitch~=nil then if dw then i5=LockPitch else LockPitch=nil end end;b3=true;if Reentry then local ij=ReentrySpeed;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=ij then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,ij)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if not x then i5=-80;if j()>0.02 then K="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;i5=0;b3=autoRollPreference end elseif Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==ReentrySpeed then x=false;Reentry=false;b3=autoRollPreference end end;local ik=C;if b6>w and not a8 and not VectorToTarget and not BrakeLanding then AlignToWorldVector(vec3(b5))end;if VectorToTarget and CustomTarget~=nil and AutopilotTargetIndex>0 then local d8=CustomTarget.position-vec3(core.getConstructWorldPos())local hS=vec3(core.getConstructWorldOrientationUp())local i4=math.deg(cu(cc,b5:normalize(),d8:normalize()))*2;local il=math.rad(math.abs(dk))if b6>hX then bd=utils.clamp(i4,-90,90)local im=i4;i4=utils.clamp(hV-i4,hV-StallAngle*0.85,hV+StallAngle*0.85)*math.cos(il)+utils.clamp(i5-hU,-StallAngle*0.85,StallAngle*0.85)*math.sin(math.rad(dk))i5=utils.clamp(i5*math.cos(il),-StallAngle*0.85,StallAngle*0.85)+utils.clamp(math.abs(im),-StallAngle*0.85,StallAngle*0.85)*math.sin(il)end;local io=i4;if not bb and b6>hX then if yawPID==nil then yawPID=pid.new(2*0.01,0,2*0.1)end;yawPID:inject(io)local i7=utils.clamp(yawPID:get(),-1,1)D=D+i7 elseif aa>-1 or b6100 then P,Q=aZ.computeDistanceAndTime(b6,100,n(),0,0,ir+iu)local iv,iw=aZ.computeDistanceAndTime(100,0,n(),0,0,ir/2)P=P+iv else P,Q=aZ.computeDistanceAndTime(b6,0,n(),0,0,ir/2)end;StrongBrakes=true;if iq<=P+b6*hR/2 then VectorStatus="Finalizing Approach"if Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byTargetSpeed then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)PlayerThrottle=0;if AltitudeHold then ToggleAltitudeHold()VectorToTarget=true end;BrakeIsOn=true elseif not AutoTakeoff then BrakeIsOn=false end;if VectorStatus=="Finalizing Approach"and(is<0.1 or iq<0.1 or LastDistanceToTarget~=nil and LastDistanceToTarget0 then local iu=0;local dr=utils.clamp(j(),0.4,2)local ir=LastMaxBrakeInAtmo*utils.clamp(b6/100,0.1,1)*dr;local iz=a_*dr+ir+iu-bt;local iA=ir+iu-bt;local iB=ir/2+iu-bt;local iC=b6-math.sqrt(math.abs(iB/2)*20/(0.5*n()))*utils.sign(iB)if iC<0 then iC=0 end;local iD;if b6>100 then local iE,_=aZ.computeDistanceAndTime(b6,100,n(),0,0,ir)local iF,_=aZ.computeDistanceAndTime(100,0,n(),0,0,math.sqrt(ir))iD=iE+iF else iD=aZ.computeDistanceAndTime(b6,0,n(),0,0,math.sqrt(ir))end;if iD<20 then BrakeIsOn=false else local iG=0;if iC>100 then local iH,_=aZ.computeDistanceAndTime(iC,100,n(),0,0,iz)local iI,_=aZ.computeDistanceAndTime(100,0,n(),0,0,a_*dr+math.sqrt(ir)+iu-bt)iG=iH+iI else iG,_=aZ.computeDistanceAndTime(iC,0,n(),0,0,a_*dr+math.sqrt(ir)+iu-bt)end;iG=(iG+15+b6*hR)*1.1;local iJ=CustomTarget~=nil and planet:getAltitude(CustomTarget.position)>0 and CustomTarget.safe;if iJ then local ip=planet:getAltitude(CustomTarget.position)local iK=ae-ip-100;local d8=CustomTarget.position-vec3(core.getConstructWorldPos())local iL=math.sqrt(d8:len()^2-(ae-ip)^2)if iL>100 then iJ=false elseif iK<=iG or iG==-1 then BrakeIsOn=true;ix=true else BrakeIsOn=false;ix=true end end;if not iJ and CalculateBrakeLandingSpeed then if iG>=iy then BrakeIsOn=true else BrakeIsOn=false end;ix=true end end end;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)fg=aa;if fg>-1 then b3=autoRollPreference;if b6<1 or b5:normalize():dot(cc)<0 then BrakeLanding=false;AltitudeHold=false;GearExtended=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)Z=0;BrakeIsOn=true else BrakeIsOn=true end elseif StrongBrakes and b5:normalize():dot(-dQ)<0.999 then BrakeIsOn=true elseif dO<-brakeLandingRate and not ix then BrakeIsOn=true elseif not ix then BrakeIsOn=false end end;if AutoTakeoff or a8 then if i5<15 and ae/HoldAltitude>0.75 then AutoTakeoff=false;if not a8 then if Nav.axisCommandManager:getAxisCommandType(0)==0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode()end elseif a8 and b675000 then if Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=1500 then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,1500)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end end end;local iM=hoverDetectGround()>-1;local iN=cd;if VectorToTarget and not iM and b6>hX then local il=math.rad(math.abs(dk))iN=cd*math.cos(il)+hW*math.sin(il)end;local iO=utils.clamp(i5-iN,-StallAngle*0.85,StallAngle*0.85)if math.abs(iO)>ig and(not bb and(math.abs(dk)<5 or VectorToTarget)or BrakeLanding or iM)then if pitchPID==nil then pitchPID=pid.new(8*0.01,0,8*0.1)end;pitchPID:inject(iO)local i6=pitchPID:get()C=C+i6 end end;L=orbit.eccentricity;if antigrav and not ExternalAGG and ae<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 and not ExternalAGG then if antigrav.getState()==0 and antigrav.getBaseAltitude()~=AntigravTargetAltitude then antigrav.setBaseAltitude(AntigravTargetAltitude)end 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 iP=utils.clamp(B+C+system.getControlDeviceForwardInput(),-1,1)local iQ=utils.clamp(E+H+system.getControlDeviceYawInput(),-1,1)local iR=utils.clamp(F+D-system.getControlDeviceLeftRightInput(),-1,1)local iS=G;local iT=vec3(core.getWorldVertical())local iU=vec3(core.getConstructWorldOrientationUp())local iV=vec3(core.getConstructWorldOrientationForward())local iW=vec3(core.getConstructWorldOrientationRight())local iX=vec3(core.getWorldVelocity())local iY=vec3(core.getWorldVelocity()):normalize()local iZ=getRoll(iT,iV,iW)local i_=math.abs(iZ)local j0=utils.sign(iZ)local j=j()local j1=vec3(core.getWorldAngularVelocity())local j2=iP*pitchSpeedFactor*iW+iQ*rollSpeedFactor*iV+iR*yawSpeedFactor*iU;if iT:len()>0.01 and j>0.0 or ProgradeIsOn then if b3==true and math.abs(bd-iZ)>autoRollRollThreshold and iQ==0 then local j3=bd;local j4=autoRollFactor;if rollPID==nil then rollPID=pid.new(j4*0.01,0,j4*0.1)end;rollPID:inject(j3-iZ)local j5=rollPID:get()j2=j2+j5*iV end end;if iT:len()>0.01 and j>0.0 then local j6=20.0;if turnAssist==true and i_>j6 and iP==0 and iR==0 then local j7=turnAssistFactor*0.1;local j8=turnAssistFactor*0.025;local j9=(i_-j6)/(180-j6)*180;local ja=0;if j9<90 then ja=j9/90 elseif j9<180 then ja=(180-j9)/90 end;ja=ja*ja;local jb=-j0*j8*(1.0-ja)local jc=j7*ja;j2=j2+jc*iW+jb*iU end end;local jd=1;local je=0;local jf=1;if system.getMouseWheel()>0 then PlayerThrottle=utils.clamp(PlayerThrottle+speedChangeLarge/100,-1,1)elseif system.getMouseWheel()<0 then PlayerThrottle=utils.clamp(PlayerThrottle-speedChangeLarge/100,-1,1)end;brakeInput2=0;local dO=-iT:dot(iX)if ad and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0)==axisCommandType.byThrottle then if throttlePID==nil then throttlePID=pid.new(0.5,0,1)end;throttlePID:inject(AtmoSpeedLimit/3.6-iX:dot(iV))local jg=throttlePID:get()calculatedThrottle=utils.clamp(jg,-1,1)if calculatedThrottle0.1 or j>0 and dO<-5)then ThrottleLimited=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,utils.clamp(calculatedThrottle,0.01,1))else ThrottleLimited=false;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,PlayerThrottle)end;if brakePID==nil then brakePID=pid.new(1*0.01,0,1*0.1)end;brakePID:inject(iX:len()-AtmoSpeedLimit/3.6)local jh=utils.clamp(brakePID:get(),0,1)if j>0 and dO<-5 or j>0.1 then brakeInput2=jh end;if brakeInput2>0 then if ThrottleLimited and calculatedThrottle==0.01 then Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)end else calculatedThrottle=utils.clamp(calculatedThrottle,0.01,1)end;local ji=''local jj=vec3()local jk='thrust analog vertical 'local jl='thrust analog lateral 'if ExtraLateralTags~="none"then jl=jl..ExtraLateralTags end;if ExtraVerticalTags~="none"then jk=jk..ExtraVerticalTags end;local jm=composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical,Z*1000)ji=ji..' , '..jk;jj=jj+jm;local jn='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then jn=jn..ExtraLongitudeTags end;local jo=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)local jp=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jn,axisCommandId.longitudinal)local jq=composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral,0)ji=ji..' , '..jl;jj=jj+jq;if jj:len()>constants.epsilon then Nav:setEngineForceCommand(ji,jj,je,'','','',jf)end;Nav:setEngineForceCommand(jn,jp,jd)if iS==0 then iS=brakeInput2 end;local jr=-iS*(brakeSpeedFactor*iX+brakeFlatFactor*iY)Nav:setEngineForceCommand('brake',jr)else local jr=-iS*(brakeSpeedFactor*iX+brakeFlatFactor*iY)Nav:setEngineForceCommand('brake',jr)local ji=''local jj=vec3()local js=false;local jn='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then jn=jn..ExtraLongitudeTags end;local jo=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if jo==axisCommandType.byThrottle then local jp=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jn,axisCommandId.longitudinal)Nav:setEngineForceCommand(jn,jp,jd)elseif jo==axisCommandType.byTargetSpeed then local jp=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)ji=ji..' , '..jn;jj=jj+jp;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then js=true end end;local jl='thrust analog lateral 'if ExtraLateralTags~="none"then jl=jl..ExtraLateralTags end;local jt=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if jt==axisCommandType.byThrottle then local ju=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jl,axisCommandId.lateral)Nav:setEngineForceCommand(jl,ju,jd)elseif jt==axisCommandType.byTargetSpeed then local jq=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)ji=ji..' , '..jl;jj=jj+jq end;local jk='thrust analog vertical 'if ExtraVerticalTags~="none"then jk=jk..ExtraVerticalTags end;local jv=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if jv==axisCommandType.byThrottle then local jm=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(jk,axisCommandId.vertical)if Z~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(jk,jm,jd,'airfoil','ground','',jf)else Nav:setEngineForceCommand(jk,vec3(),jd)Nav:setEngineForceCommand('airfoil vertical',jm,jd,'airfoil','','',jf)Nav:setEngineForceCommand('ground vertical',jm,jd,'ground','','',jf)end elseif jv==axisCommandType.byTargetSpeed then if Z<0 then Nav:setEngineForceCommand('hover',vec3(),jd)end;local jw=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)ji=ji..' , '..jk;jj=jj+jw end;local fC=unit.getAxisCommandValue(0)if jj:len()>constants.epsilon then if G~=0 or js or math.abs(iY:dot(iV))<0.8 or b5:len()>fC/3.6 then ji=ji..', brake'end;Nav:setEngineForceCommand(ji,jj,je,'','','',jf)end end;local jx=torqueFactor*(j2-j1)local jy=vec3(core.getWorldAirFrictionAngularAcceleration())jx=jx-jy;Nav:setEngineTorqueCommand('torque',jx,jd,'airfoil','','',jf)Nav:setBoosterCommand('rocket_engine')if O and not VanillaRockets then local bw=vec3(core.getVelocity()):len()local jz=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local jA=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bw*3.6>jA*(1-jz)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw*3.6=fC*(1-jz)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw=fC*(1-jz)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bw0 or aew then K="WARNING: Insufficient Brakes - Attempting landing anyway"end;Reentry=false;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=true;b3=true;GearExtended=false else BrakeIsOn=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end;if A and not BrakeLanding then Nav.control.extendLandingGears()end else if A then Nav.control.retractLandingGears()end;Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end elseif jC=="light"then if Nav.control.isAnyHeadlightSwitchedOn()==1 then Nav.control.switchOffHeadlights()else Nav.control.switchOnHeadlights()end elseif jC=="forward"then B=B-1 elseif jC=="backward"then B=B+1 elseif jC=="left"then E=E-1 elseif jC=="right"then E=E+1 elseif jC=="yawright"then F=F-1 elseif jC=="yawleft"then F=F+1 elseif jC=="straferight"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,1.0)elseif jC=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,-1.0)elseif jC=="up"then Z=Z+1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,1.0)elseif jC=="down"then Z=Z-1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,-1.0)elseif jC=="groundaltitudeup"then OldButtonMod=M;OldAntiMod=N;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+N;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+N end else AntigravTargetAltitude=desiredBaseAltitude+100 end elseif AltitudeHold then HoldAltitude=HoldAltitude+M else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)end elseif jC=="groundaltitudedown"then OldButtonMod=M;OldAntiMod=N;if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end else AntigravTargetAltitude=desiredBaseAltitude end elseif AltitudeHold then HoldAltitude=HoldAltitude-M else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)end elseif jC=="option1"then IncrementAutopilotTargetIndex()v=false elseif jC=="option2"then DecrementAutopilotTargetIndex()v=false elseif jC=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;v=false;ToggleWidgets()elseif jC=="option4"then ToggleAutopilot()v=false elseif jC=="option5"then ToggleLockPitch()v=false elseif jC=="option6"then ToggleAltitudeHold()v=false elseif jC=="option7"then wipeSaveVariables()v=false elseif jC=="option8"then ToggleFollowMode()v=false elseif jC=="option9"then if gyro~=nil then gyro.toggle()ah=gyro.getState()==1 end;v=false elseif jC=="lshift"then if system.isViewLocked()==1 then J=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then J=true;b2=false;b1=false end elseif jC=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif jC=="lalt"then if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif jC=="booster"then if VanillaRockets then Nav:toggleBoosters()elseif not O then if not IsRocketOn then Nav:toggleBoosters()IsRocketOn=true end;O=true else if IsRocketOn then Nav:toggleBoosters()IsRocketOn=false end;O=false end elseif jC=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()PlayerThrottle=0 elseif jC=="speedup"then if not J then if AtmoSpeedAssist then PlayerThrottle=utils.clamp(PlayerThrottle+speedChangeLarge/100,-1,1)end;Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)else IncrementAutopilotTargetIndex()end elseif jC=="speeddown"then if not J then if AtmoSpeedAssist then PlayerThrottle=utils.clamp(PlayerThrottle-speedChangeLarge/100,-1,1)end;Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)else DecrementAutopilotTargetIndex()end elseif jC=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(jC)if jC=="forward"then B=0 elseif jC=="backward"then B=0 elseif jC=="left"then E=0 elseif jC=="right"then E=0 elseif jC=="yawright"then F=0 elseif jC=="yawleft"then F=0 elseif jC=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)elseif jC=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)elseif jC=="up"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif jC=="down"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif jC=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif jC=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif jC=="lshift"then if system.isViewLocked()==1 then J=false;a0=0;a1=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then J=false;b2=false;b1=false end elseif jC=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif jC=="lalt"then if o()==0 and freeLookToggle then if v then if system.isViewLocked()==1 then system.lockView(0)else system.lockView(1)end else v=true end elseif o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(0)end end end;function script.onActionLoop(jC)if jC=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude+N;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude+N end;N=N*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude+100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude+M;M=M*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)end elseif jC=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then if AntigravTargetAltitude~=nil then if AltitudeHold and AntigravTargetAltitudeHoldAltitude-10 then AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end;HoldAltitude=AntigravTargetAltitude else AntigravTargetAltitude=AntigravTargetAltitude-N;if AntigravTargetAltitude<1000 then AntigravTargetAltitude=1000 end end;N=N*1.05;BrakeIsOn=false else AntigravTargetAltitude=desiredBaseAltitude-100;BrakeIsOn=false end elseif AltitudeHold then HoldAltitude=HoldAltitude-M;M=M*1.05 else Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)end elseif jC=="speedup"then if not J then if AtmoSpeedAssist then PlayerThrottle=utils.clamp(PlayerThrottle+speedChangeSmall/100,-1,1)end;Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end elseif jC=="speeddown"then if not J then if AtmoSpeedAssist then PlayerThrottle=utils.clamp(PlayerThrottle-speedChangeSmall/100,-1,1)end;Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end;function script.onInputText(jD)local i;local jE="/commands /setname /G /agg /addlocation /copydatabank"local jF,jG=nil,nil;local jH="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(jD," ")jF=jD;if i~=nil then jF=string.sub(jD,0,i-1)jG=string.sub(jD,i+1)elseif not string.find(jE,jF)then for fy in string.gmatch(jH,"([^\n]+)")do c(fy)end;return end;if jF=="/setname"then if jG==nil or jG==""then K="Usage: /setname Newname"return end;if AutopilotTargetIndex>0 and CustomTarget~=nil then UpdatePosition(jG)else K="Select a saved target to rename first"end elseif jF=="/addlocation"then if jG==nil or jG==""or string.find(jG,"::")==nil then K="Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}"return end;i=string.find(jG,"::")local c0=string.sub(jG,1,i-2)local bV=string.sub(jG,i)local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local bW='::pos{'..p..','..p..','..p..','..p..','..p..'}'local bX,bY,bS,bT,bR=string.match(bV,bW)local planet=aS[tonumber(bX)][tonumber(bY)]AddNewLocationByWaypoint(c0,planet,bV)K="Added "..c0 .." to saved locations,\nplanet "..planet.name.." at "..bV;a2=5 elseif jF=="/agg"then if jG==nil or jG==""then K="Usage: /agg targetheight"return end;jG=tonumber(jG)if jG<1000 then jG=1000 end;AntigravTargetAltitude=jG;K="AGG Target Height set to "..jG elseif jF=="/G"then if jG==nil or jG==""then K="Usage: /G VariableName variablevalue\n/G dump - shows all variables"return end;if jG=="dump"then for bg,bh in pairs(a)do if type(_G[bh])=="boolean"then if _G[bh]==true then c(bh.." true")else c(bh.." false")end elseif _G[bh]==nil then c(bh.." nil")else c(bh.." ".._G[bh])end end;return end;i=string.find(jG," ")local jI=string.sub(jG,0,i-1)local jJ=string.sub(jG,i+1)for bg,bh in pairs(a)do if bh==jI then K="Variable "..jI.." changed to "..jJ;local jK=type(_G[bh])if jK=="number"then jJ=tonumber(jJ)elseif jK=="boolean"then if string.lower(jJ)=="true"then jJ=true else jJ=false end end;_G[bh]=jJ;return end end;K="No such global variable: "..jI elseif jF=="/copydatabank"then if dbHud_2 then SaveDataBank(true)else K="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 2a422e0..f9df157 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,35 @@ ## ChangeLog - Most recent changes at the top +Version 5.223 - Major flight changes including new "Cruise control" mode when using autopilot, read changelog since 5.11 +- Adjusted Waypoints to really land immediately if you pass the location or distance starts getting higher +- IMPORANT: For any waypoint to be most accurate and use faster brake landing, go to the waypoint and use the Update Position button. + +Version 5.222 +- Increased minimum roll speed to 100m/s from 50/ms +- Increased roll power to help converge on ships with no tailfins + +Version 5.221 +- Allowed new waypoints entered from the ship to be considered safe for Extreme Landing + +Version 5.22 +- Fixed issue causing Cruise to be unable to apply brakes +- Adjusted Cruise mode to brake less aggressively when the velocity angle is far from ship front +- Adjusted Cruise to brake more aggressively when total speed is too high - Beware testing glide reentry +- If AtmoSpeedAssist is enabled, swaps to throttled mode when entering atmosphere from cruise mode +- Adjusted Waypoints to land immediately if you pass the location or distance starts getting higher +- Waypoints will no longer perform Extreme Brake Landings at positions entered on the map - you must land at location and Update Position for these + Your old waypoints must be updated in this way for them to work with Extreme Landings + +Version 5.21 +- Removed throttle limiting when atmosphere levels are below 10% for easier atmo escapes, and brake limiting when atmo levels are below 1% + Note that throttle and brakes will still limit if your vspeed becomes less than -20m/s, to help with entries, and always when atmo is above 10% +- Fixed bug causing no throttle control when in space + +Version 5.2 +- Replaced Cruise with AtmoSpeedAssist (parameter to enable/disable), a throttled flight overhaul. +Adjusts throttle to limit speed to AtmoSpeedLimit, brakes when necessary (such as reentry) without limiting throttle, and applies all wings to center the velocity vector like Cruise does. Unlike cruise, it will not cause you to brake just because you are facing the wrong direction - only if your total speed is too high for atmo +This also means that when AtmoSpeedAssist is on, all Atmo Flight Modes no longer put you in Cruise +And consequently and accidentally, the player's throttle is now remembered and re-set when swapping back to Throttle mode from Cruise (in atmo) + Version 5.11 - Improved orbits and waypoints - waypoints may feather brakes again diff --git a/src/ButtonHUD.lua b/src/ButtonHUD.lua index 0e5666a..1c34139 100644 --- a/src/ButtonHUD.lua +++ b/src/ButtonHUD.lua @@ -84,6 +84,7 @@ hudTickRate = 0.0666667 -- export: (Default: 0.0666667) Set the tick rate for yo ShouldCheckDamage = true --export: (Default: true) Whether or not damage checks are performed. Disabled for performance on very large ships CalculateBrakeLandingSpeed = false --export: (Default: false) Whether BrakeLanding speed at non-waypoints should be calculated or use the brakeLandingRate user setting. Only set to true for ships with low mass to lift capability. autoRollRollThreshold = 1.0 --export: (Default: 1.0) The minimum amount of roll before autoRoll kicks in and stabilizes (if active) +AtmoSpeedAssist = true --export: (Default: true) Whether or not atmospheric speeds should be limited to a maximum of AtmoSpeedLimit -- 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 @@ -120,6 +121,10 @@ LastMaxBrakeInAtmo = 0 AntigravTargetAltitude = core.getAltitude() LastStartTime = 0 SpaceTarget = false +PlayerThrottle = 0 +brakeInput2 = 0 +ThrottleLimited = false +calculatedThrottle = 0 -- 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", @@ -131,7 +136,7 @@ local saveableVariables = {"userControlScheme", "TargetOrbitRadius", "apTickRate "hideHudOnToggleWidgets", "DampingMultiplier", "fuelTankHandlingAtmo", "ExternalAGG", "ShouldCheckDamage", "fuelTankHandlingSpace", "fuelTankHandlingRocket", "RemoteFreeze", "hudTickRate", "speedChangeLarge", "speedChangeSmall", "brightHud", "brakeLandingRate", "MaxPitch", - "ReentrySpeed", "AtmoSpeedLimit", "ReentryAltitude", "centerX", "centerY", "SpaceSpeedLimit", + "ReentrySpeed", "AtmoSpeedLimit", "ReentryAltitude", "centerX", "centerY", "SpaceSpeedLimit", "AtmoSpeedAssist", "vSpdMeterX", "vSpdMeterY", "altMeterX", "altMeterY", "fuelX","fuelY", "LandingGearGroundHeight", "TrajectoryAlignmentStrength", "RemoteHud", "StallAngle", "ResolutionX", "ResolutionY", "UseSatNav", "FuelTankOptimization", "ContainerOptimization", "ExtraLongitudeTags", "ExtraLateralTags", "ExtraVerticalTags", "OrbitMapSize", "OrbitMapX", "OrbitMapY", "DisplayOrbit", "CalculateBrakeLandingSpeed"} @@ -367,9 +372,7 @@ function ProcessElements() local checkTanks = (fuelX ~= 0 and fuelY ~= 0) for k in pairs(elementsID) do local type = eleType(elementsID[k]) - sprint(type) if (type == "Landing Gear") then - sprint("HERE1") hasGear = true end if (type == "Dynamic Core Unit") then @@ -497,7 +500,6 @@ function SetupChecks() system.freeze(0) end if hasGear then - sprint("HERE2") GearExtended = (Nav.control.isAnyLandingGearExtended() == 1) if GearExtended then Nav.control.extendLandingGears() @@ -743,7 +745,8 @@ function AddNewLocation() -- Don't call this unless they have a databank or it's name = name, atmosphere = atmo, planetname = planet.name, - gravity = planet.gravity + gravity = planet.gravity, + safe = true -- This indicates we can extreme land here, because this was a real positional waypoint } SavedLocations[#SavedLocations + 1] = newLocation -- Nearest planet, gravity also important - if it's 0, we don't autopilot to the target planet, the target isn't near a planet. @@ -781,7 +784,8 @@ function UpdatePosition(newName) name = SavedLocations[index].name, atmosphere = atmosphere(), planetname = planet.name, - gravity = unit.getClosestPlanetInfluence() + gravity = unit.getClosestPlanetInfluence(), + safe = true } end SavedLocations[index] = newLocation @@ -946,9 +950,9 @@ function SetupInterplanetaryPanel() -- Interplanetary helper widgetTargetOrbit = system.createWidget(panelInterplanetary, "value") widgetTargetOrbitText = system.createData('{"label": "Target Altitude", "value": "N/A", "unit":""}') - if not inAtmo then + --if not inAtmo then system.addDataToWidget(widgetTargetOrbitText, widgetTargetOrbit) - end + --end end function Contains(mousex, mousey, x, y, width, height) @@ -990,6 +994,7 @@ function ToggleAutoLanding() LockPitch = nil BrakeLanding = true Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 end end @@ -1054,7 +1059,7 @@ function ToggleAltitudeHold() if (not GearExtended and not BrakeIsOn) or not inAtmo or (antigrav and antigrav.getState() == 1) then -- Never autotakeoff in space AutoTakeoff = false if ahDoubleClick > -1 then HoldAltitude = coreAltitude end - if not spaceLaunch and Nav.axisCommandManager:getAxisCommandType(0) == 0 then + if not spaceLaunch and Nav.axisCommandManager:getAxisCommandType(0) == 0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode() end else @@ -1929,6 +1934,11 @@ function UpdateHud(newContent) local throt = mfloor(unit.getThrottle()) local spd = speed * 3.6 local flightValue = unit.getAxisCommandValue(0) + if inAtmo and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then + flightValue = PlayerThrottle + throt = PlayerThrottle*100 + end + local flightStyle = GetFlightStyle() local bottomText = "ROLL" local nearPlanet = unit.getClosestPlanetInfluence() > 0 @@ -2164,7 +2174,7 @@ function DrawOdometer(newContent, totalDistanceTrip, TotalDistanceTravelled, fli end function DrawThrottle(newContent, flightStyle, throt, flightValue) - + throt = math.floor(throt+0.5) -- Hard-round it to an int local y1 = throtPosY+10 local y2 = throtPosY+20 if isRemote() == 1 and not RemoteHud then @@ -2192,10 +2202,31 @@ function DrawThrottle(newContent, flightStyle, throt, flightValue) end newContent[#newContent + 1] = stringf([[ - %s - %d %s + %s + %d %s ]], throtPosX+10, y1, label, throtPosX+10, y2, value, unit) + + if inAtmo and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle and ThrottleLimited then + -- Display a marker for where the AP throttle is putting it, calculatedThrottle + + throt = math.floor(calculatedThrottle*100+0.5) + local throtclass = "red" + if throt < 0 then + throtclass = "red" -- TODO + end + newContent[#newContent + 1] = stringf([[ + + + ]], throtclass, (1 - math.abs(throt)), + throtPosX-10, throtPosY+50, throtPosX-15, throtPosY+53, throtPosX-15, throtPosY+47) + newContent[#newContent + 1] = stringf([[ + + %s + %d %s + + ]], throtPosX+10, y1+40, "LIMIT", throtPosX+10, y2+40, throt, "%") + end end @@ -2650,6 +2681,8 @@ function DrawWarnings(newContent) end if BrakeIsOn then newContent[#newContent + 1] = stringf([[Brake Engaged]], warningX, brakeY) + elseif brakeInput2 > 0 then + newContent[#newContent + 1] = stringf([[Auto-Brake Engaged]], warningX, brakeY, brakeInput2) end if inAtmo and stalling and hoverDetectGround() == -1 then newContent[#newContent + 1] = stringf([[** STALL WARNING **]], warningX, apY+50) @@ -2941,13 +2974,13 @@ function UpdateAutopilotTarget() system.addDataToWidget(widgetCurBrakeDistanceText, widgetCurBrakeDistance) end if system.updateData(widgetTrajectoryAltitudeText, widgetTrajectoryAltitude) ~= 1 then system.addDataToWidget(widgetTrajectoryAltitudeText, widgetTrajectoryAltitude) end - if system.updateData(widgetTargetOrbitText, widgetTargetOrbit) ~= 1 then - system.addDataToWidget(widgetTargetOrbitText, widgetTargetOrbit) 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 @@ -3286,6 +3319,52 @@ function updateDistance() lastTravelTime = curTime end +function composeAxisAccelerationFromTargetSpeed(commandAxis, targetSpeed) + + local axisCRefDirection = vec3() + local axisWorldDirection = vec3() + + if (commandAxis == axisCommandId.longitudinal) then + axisCRefDirection = vec3(core.getConstructOrientationForward()) + axisWorldDirection = vec3(core.getConstructWorldOrientationForward()) + elseif (commandAxis == axisCommandId.vertical) then + axisCRefDirection = vec3(core.getConstructOrientationUp()) + axisWorldDirection = vec3(core.getConstructWorldOrientationUp()) + elseif (commandAxis == axisCommandId.lateral) then + axisCRefDirection = vec3(core.getConstructOrientationRight()) + axisWorldDirection = vec3(core.getConstructWorldOrientationRight()) + else + return vec3() + end + + local gravityAcceleration = vec3(core.getWorldGravity()) + local gravityAccelerationCommand = gravityAcceleration:dot(axisWorldDirection) + + local airResistanceAcceleration = vec3(core.getWorldAirFrictionAcceleration()) + local airResistanceAccelerationCommand = airResistanceAcceleration:dot(axisWorldDirection) + + local currentVelocity = vec3(core.getVelocity()) + local currentAxisSpeedMS = currentVelocity:dot(axisCRefDirection) + + local targetAxisSpeedMS = targetSpeed * constants.kph2m + + if targetSpeedPID == nil then + targetSpeedPID = pid.new(1, 0, 10.0) -- The PID used to compute acceleration to reach target speed + end + + targetSpeedPID:inject(targetAxisSpeedMS - currentAxisSpeedMS) -- update PID + + local accelerationCommand = targetSpeedPID:get() + + local finalAcceleration = (accelerationCommand - airResistanceAccelerationCommand - gravityAccelerationCommand) * axisWorldDirection -- Try to compensate air friction + + -- The hell are these? + --self.system.addMeasure("dynamic", "acceleration", "command", accelerationCommand) + --self.system.addMeasure("dynamic", "acceleration", "intensity", finalAcceleration:len()) + + return finalAcceleration +end + -- Planet Info - https://gitlab.com/JayleBreak/dualuniverse/-/tree/master/DUflightfiles/autoconf/custom with minor modifications function Atlas() return { @@ -5144,7 +5223,7 @@ end -- 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.11 + VERSION_NUMBER = 5.222 SetupComplete = false beginSetup = coroutine.create(function() Nav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, @@ -5300,6 +5379,15 @@ function script.onTick(timerId) system.removeDataFromWidget(widgetCurBrakeDistanceText, widgetCurBrakeDistance) system.removeDataFromWidget(widgetTrajectoryAltitudeText, widgetTrajectoryAltitude) WasInAtmo = true + if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then + -- Put real throttle into PlayerThrottle as we enter + PlayerThrottle = unit.getAxisCommandValue(0) + elseif AtmoSpeedAssist then + -- If they're reentering atmo from cruise, and have atmo speed Assist + -- Put them in throttle mode at 100% + PlayerThrottle = 1 + Nav.control.cancelCurrentControlMasterMode() + end end if atmosphere() == 0 and WasInAtmo then if system.updateData(widgetMaxBrakeTimeText, widgetMaxBrakeTime) == 1 then @@ -5312,6 +5400,10 @@ function script.onTick(timerId) system.addDataToWidget(widgetCurBrakeDistanceText, widgetCurBrakeDistance) end if system.updateData(widgetTrajectoryAltitudeText, widgetTrajectoryAltitude) == 1 then system.addDataToWidget(widgetTrajectoryAltitudeText, widgetTrajectoryAltitude) end + if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then + -- Put PlayerThrottle into the real throttle as we exit so no discrepancies + Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, PlayerThrottle) + end WasInAtmo = false end end @@ -5519,7 +5611,7 @@ function script.onTick(timerId) local currentPitch = math.deg(signedRotationAngle(constrR, velocity, constrF)) -- Let's use a consistent func that uses global velocity stalling = inAtmo and currentYaw < -StallAngle or currentYaw > StallAngle or currentPitch < -StallAngle or currentPitch > StallAngle - local minRollVelocity = 50 -- Min velocity over which advanced rolling can occur + local minRollVelocity = 100 -- Min velocity over which advanced rolling can occur deltaX = system.getMouseDeltaX() deltaY = system.getMouseDeltaY() @@ -5537,11 +5629,10 @@ function script.onTick(timerId) hovGndDet = hoverDetectGround() local gravity = planet:getGravity(core.getConstructWorldPos()):len() * constructMass() targetRoll = 0 - - - maxKinematicUp = core.getMaxKinematicsParametersAlongAxis("ground", core.getConstructOrientationUp())[1] + + if isRemote() == 1 and screen_1 and screen_1.getMouseY() ~= -1 then simulatedX = screen_1.getMouseX() * ResolutionX simulatedY = screen_1.getMouseY() * ResolutionY @@ -5611,6 +5702,7 @@ function script.onTick(timerId) Nav.control.cancelCurrentControlMasterMode() end Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 end if not isWarping and LastIsWarping then if not BrakeIsOn then @@ -5622,20 +5714,15 @@ function script.onTick(timerId) end LastIsWarping = isWarping if inAtmo and atmosphere() > 0.09 then - --if not speedLimitBreaking then - if velMag > (AtmoSpeedLimit / 3.6) then - -- BrakeIsOn = true - -- speedLimitBreaking = true - if Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then - Nav.control.cancelCurrentControlMasterMode() + if velMag > (AtmoSpeedLimit / 3.6) and not AtmoSpeedAssist and not speedLimitBreaking then + BrakeIsOn = true + speedLimitBreaking = true + elseif not AtmoSpeedAssist and speedLimitBreaking then + if velMag < (AtmoSpeedLimit / 3.6) then + BrakeIsOn = false + speedLimitBreaking = false end - end - --else - -- if velMag < (AtmoSpeedLimit / 3.6) then - -- BrakeIsOn = false - -- speedLimitBreaking = false - -- end - --end + end end if BrakeIsOn then brakeInput = 1 @@ -5833,6 +5920,7 @@ function script.onTick(timerId) AutopilotStatus = "Cruising" AutopilotCruising = true Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 apThrottleSet = false end -- Check if accel needs to stop for braking @@ -5841,6 +5929,7 @@ function script.onTick(timerId) AutopilotStatus = "Braking" AutopilotBraking = true Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 apThrottleSet = false end elseif AutopilotBraking then @@ -5874,6 +5963,7 @@ function script.onTick(timerId) 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 ProgradeIsOn = true @@ -6057,7 +6147,7 @@ function script.onTick(timerId) -- We can try it with roll... local rollRad = math.rad(math.abs(roll)) if velMag > minRollVelocity then - targetRoll = utils.clamp(targetYaw/2, -90, 90) + targetRoll = utils.clamp(targetYaw, -90, 90) local origTargetYaw = targetYaw -- I have no fucking clue why we add currentYaw to StallAngle when currentYaw is already potentially a large value outside of the velocity vector -- But it doesn't work otherwise and stalls if we don't do it like that. I don't fucking know. @@ -6127,26 +6217,25 @@ function script.onTick(timerId) -- Fudge it with the distance we'll travel in a tick - or half that and the next tick accounts for the other? idk if distanceToTarget <= brakeDistance + (velMag*deltaTick)/2 then - VectorStatus = "Finalizing Approach" -- Left for compatibility + 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 + PlayerThrottle = 0 if AltitudeHold then ToggleAltitudeHold() -- Don't need this anymore VectorToTarget = true -- But keep this on end BrakeIsOn = true - - if hSpd < 1 or distanceToTarget < 1 then - BrakeLanding = true - VectorToTarget = false - end - elseif not AutoTakeoff then BrakeIsOn = false end - + if VectorStatus == "Finalizing Approach" and (hSpd < 0.1 or distanceToTarget < 0.1 or (LastDistanceToTarget ~= nil and LastDistanceToTarget < distanceToTarget)) then + BrakeLanding = true + VectorToTarget = false + end + LastDistanceToTarget = distanceToTarget end pitchInput2 = oldInput local groundDistance = -1 @@ -6222,7 +6311,7 @@ function script.onTick(timerId) --if LandingGearGroundHeight == 0 then stopDistance = (stopDistance+15+(velMag*deltaTick))*1.1 -- Add leeway for large ships with forcefields or landing gear, and for lag -- And just bad math I guess - local knownAltitude = (CustomTarget ~= nil and planet:getAltitude(CustomTarget.position) > 0) + local knownAltitude = (CustomTarget ~= nil and planet:getAltitude(CustomTarget.position) > 0 and CustomTarget.safe) if knownAltitude then local targetAltitude = planet:getAltitude(CustomTarget.position) @@ -6288,7 +6377,7 @@ function script.onTick(timerId) if targetPitch < 15 and (coreAltitude/HoldAltitude) > 0.75 then AutoTakeoff = false -- No longer in ascent if not spaceLaunch then - if Nav.axisCommandManager:getAxisCommandType(0) == 0 then + if Nav.axisCommandManager:getAxisCommandType(0) == 0 and not AtmoSpeedAssist then Nav.control.cancelCurrentControlMasterMode() end elseif spaceLaunch and velMag < minAutopilotSpeed then @@ -6299,11 +6388,13 @@ function script.onTick(timerId) Nav.control.cancelCurrentControlMasterMode() end Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 elseif spaceLaunch then if Nav.axisCommandManager:getAxisCommandType(0) ~= 0 then Nav.control.cancelCurrentControlMasterMode() end Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 BrakeIsOn = true end elseif spaceLaunch and atmosphere() == 0 and coreAltitude > 75000 then @@ -6452,99 +6543,227 @@ function script.onFlush() local dontKeepCollinearity = 0 -- for easier reading local tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities - -- Rotation - local angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity) - local airAcceleration = vec3(core.getWorldAirFrictionAngularAcceleration()) - angularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction - - Nav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', - tolerancePercentToSkipOtherPriorities) + if system.getMouseWheel() > 0 then + PlayerThrottle = utils.clamp(PlayerThrottle + speedChangeLarge/100, -1, 1) + elseif system.getMouseWheel() < 0 then + PlayerThrottle = utils.clamp(PlayerThrottle - speedChangeLarge/100, -1, 1) + end - -- Brakes - local brakeAcceleration = -finalBrakeInput * - (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir) - Nav:setEngineForceCommand('brake', brakeAcceleration) - - -- AutoNavigation regroups all the axis command by 'TargetSpeed' - local autoNavigationEngineTags = '' - local autoNavigationAcceleration = vec3() - local autoNavigationUseBrake = false - - -- Longitudinal Translation - local longitudinalEngineTags = 'thrust analog longitudinal ' - if ExtraLongitudeTags ~= "none" then longitudinalEngineTags = longitudinalEngineTags..ExtraLongitudeTags end - local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal) - if (longitudinalCommandType == axisCommandType.byThrottle) then + brakeInput2 = 0 + local vSpd = -worldVertical:dot(constructVelocity) + + if inAtmo and AtmoSpeedAssist and Nav.axisCommandManager:getAxisCommandType(0) == axisCommandType.byThrottle then + -- This is meant to replace cruise + -- Uses AtmoSpeedLimit as the desired speed in which to 'cruise' + -- In atmo, if throttle is 100%, it applies a PID to throttle to try to achieve AtmoSpeedLimit + -- Since throttle is already 100% this means nothing except, it should slow them as it approaches it, throttling down + -- Note - Beware reentry. It will throttle them down due to high fall speeds, but they need that throttle + -- We could instead only throttle down when the velMag in the direction of ShipFront exceeds AtmoSpeedLimt. + -- We also need to do braking if the speed is high enough above the desired limit. + -- Braking should happen immediately if the speed is not mostly forward + + -- .. Maybe as a whole we just, also PID brakeForce to keep speed under that limit, so if we barely go over it'll only tap them and throttle down + + -- We're going to want a param, PlayerThrottle, which we always keep (not between loads). We set it in SpeedUp and SpeedDown + -- So we only control throttle if their last throttle input was 100% + + -- Well, no. Even better, do it all the time. We would show their throttle on the HUD, then a red line separating it from our adjusted throttle + -- Along with a message like, "Atmospheric Speed Limit Reached - Press Something to Disable Temporarily" + -- But of course, don't throttle up for them. Only down. + + + + + if (throttlePID == nil) then + throttlePID = pid.new(0.5, 0, 1) -- First param, higher means less range in which to PID to a proper value + -- IE 1 there means it tries to get within 1m/s of target, 0.5 there means it tries to get within 5m/s of target + -- The smaller the value, the further the end-speed is from the target, but also the sooner it starts reducing throttle + -- It is also the same as taking the result * (firstParam), it's a direct scalar + + -- Second value makes it change constantly over time. This doesn't work in this case, it just builds up forever while they're not at max + + -- And third value affects how hard it tries to fix it. Higher values mean it will very quickly go to negative values as you approach target + -- Lower values means it steps down slower + + -- 0.5, 0, 20 works pretty great + -- And I think it was, 0.5, 0, 0.001 is smooth, but gets some braking early + -- 0.5, 0, 1 is v good. One early braking bit then stabilizes easily . 10 as the last is way too much, it's bouncy. Even 2. 1 will do + end + throttlePID:inject((AtmoSpeedLimit/3.6 - constructVelocity:dot(constructForward))) + local pidGet = throttlePID:get() + --system.print(pidGet .. " vs " .. PlayerThrottle) + calculatedThrottle = utils.clamp(pidGet,-1,1) + if calculatedThrottle < PlayerThrottle and (atmosphere > 0.1 or (atmosphere > 0 and vSpd < -5)) then -- Don't limit throttle in low atmo, but still brake in case it's a reentry. + ThrottleLimited = true + Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, utils.clamp(calculatedThrottle,0.01,1)) + else + ThrottleLimited = false + Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, PlayerThrottle) + + end + + + -- Then additionally + if (brakePID == nil) then + brakePID = pid.new(1 * 0.01, 0, 1 * 0.1) + end + brakePID:inject(constructVelocity:len() - (AtmoSpeedLimit/3.6)) + local calculatedBrake = utils.clamp(brakePID:get(),0,1) + if (atmosphere > 0 and vSpd < -5) or atmosphere > 0.1 then -- Don't brake-limit them at <1% atmo if going up (or mostly up), it's mostly safe up there and displays 0% so people would be mad + brakeInput2 = calculatedBrake + end + --if calculatedThrottle < 0 then + -- brakeInput2 = brakeInput2 + math.abs(calculatedThrottle) + --end + if brakeInput2 > 0 then + if ThrottleLimited and calculatedThrottle == 0.01 then + Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) -- We clamped it to >0 before but, if braking and it was at that clamp, 0 is good. + end + --system.print("Braking with " .. brakeInput2*100 .. " %") + else -- For display purposes, keep calculatedThrottle positive in this case + calculatedThrottle = utils.clamp(calculatedThrottle,0.01,1) + end + + -- And finally, do what cruise does for angling wings toward the nose + + local autoNavigationEngineTags = '' + local autoNavigationAcceleration = vec3() + local verticalStrafeEngineTags = 'thrust analog vertical ' + local lateralStrafeEngineTags = 'thrust analog lateral ' + + if ExtraLateralTags ~= "none" then lateralStrafeEngineTags = lateralStrafeEngineTags..ExtraLateralTags end + if ExtraVerticalTags ~= "none" then verticalStrafeEngineTags = verticalStrafeEngineTags..ExtraVerticalTags end + + local verticalStrafeAcceleration = composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical,upAmount*1000) + autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags + autoNavigationAcceleration = autoNavigationAcceleration + verticalStrafeAcceleration + --system.print(vec3(verticalStrafeAcceleration):len()) + + local longitudinalEngineTags = 'thrust analog longitudinal ' + if ExtraLongitudeTags ~= "none" then longitudinalEngineTags = longitudinalEngineTags..ExtraLongitudeTags end + local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal) local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( - longitudinalEngineTags, axisCommandId.longitudinal) - Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity) - elseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then - local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed( - axisCommandId.longitudinal) - autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags - autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration - if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop - Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - -Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking - -- if the longitudinal velocity would need some braking - then - autoNavigationUseBrake = true - end - - end - - -- Lateral Translation - local lateralStrafeEngineTags = 'thrust analog lateral ' - if ExtraLateralTags ~= "none" then lateralStrafeEngineTags = lateralStrafeEngineTags..ExtraLateralTags end - local lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral) - if (lateralCommandType == axisCommandType.byThrottle) then - local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( - lateralStrafeEngineTags, axisCommandId.lateral) - Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity) - elseif (lateralCommandType == axisCommandType.byTargetSpeed) then - local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral) + longitudinalEngineTags, axisCommandId.longitudinal) + + local lateralAcceleration = composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral, 0) autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration - end + --system.print("Lateral accel: " .. vec3(lateralAcceleration):len()) - -- Vertical Translation - local verticalStrafeEngineTags = 'thrust analog vertical ' - if ExtraVerticalTags ~= "none" then verticalStrafeEngineTags = verticalStrafeEngineTags..ExtraVerticalTags end - local verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical) - if (verticalCommandType == axisCommandType.byThrottle) then - local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( - verticalStrafeEngineTags, axisCommandId.vertical) - if upAmount ~= 0 or (BrakeLanding and BrakeIsOn) then - Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', - 'ground', '', tolerancePercentToSkipOtherPriorities) - else - Nav:setEngineForceCommand(verticalStrafeEngineTags, vec3(), keepCollinearity) -- Reset vertical engines but not airfoils or ground - Nav:setEngineForceCommand('airfoil vertical', verticalStrafeAcceleration, keepCollinearity, 'airfoil', - '', '', tolerancePercentToSkipOtherPriorities) - Nav:setEngineForceCommand('ground vertical', verticalStrafeAcceleration, keepCollinearity, 'ground', - '', '', tolerancePercentToSkipOtherPriorities) - end - elseif (verticalCommandType == axisCommandType.byTargetSpeed) then - if upAmount == 0 then - Nav:setEngineForceCommand('hover', vec3(), keepCollinearity) - end - local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed( - axisCommandId.vertical) - autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags - autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration - end + -- Auto Navigation (Cruise Control) + if (autoNavigationAcceleration:len() > constants.epsilon) then + --system.print(autoNavigationEngineTags .. " , " .. vec3(autoNavigationAcceleration):len()) + Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', + '', tolerancePercentToSkipOtherPriorities) + end + -- And let throttle do its thing separately + Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity) + + if finalBrakeInput == 0 then -- If player isn't braking, use cruise assist braking + finalBrakeInput = brakeInput2 + end + + -- Brakes + local brakeAcceleration = -finalBrakeInput * + (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir) + Nav:setEngineForceCommand('brake', brakeAcceleration) - -- Auto Navigation (Cruise Control) - if (autoNavigationAcceleration:len() > constants.epsilon) then - if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward - -- if the velocity is not properly aligned with the forward - then - autoNavigationEngineTags = autoNavigationEngineTags .. ', brake' + else + --PlayerThrottle = 0 + + -- Brakes - Do these first so Cruise can override it + local brakeAcceleration = -finalBrakeInput * + (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir) + Nav:setEngineForceCommand('brake', brakeAcceleration) + + -- AutoNavigation regroups all the axis command by 'TargetSpeed' + local autoNavigationEngineTags = '' + local autoNavigationAcceleration = vec3() + local autoNavigationUseBrake = false + + -- Longitudinal Translation + local longitudinalEngineTags = 'thrust analog longitudinal ' + if ExtraLongitudeTags ~= "none" then longitudinalEngineTags = longitudinalEngineTags..ExtraLongitudeTags end + local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal) + if (longitudinalCommandType == axisCommandType.byThrottle) then + local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( + longitudinalEngineTags, axisCommandId.longitudinal) + Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity) + elseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then + local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed( + axisCommandId.longitudinal) + autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags + autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration + if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop + Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < + -Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking + then + autoNavigationUseBrake = true + end + + end + + -- Lateral Translation + local lateralStrafeEngineTags = 'thrust analog lateral ' + if ExtraLateralTags ~= "none" then lateralStrafeEngineTags = lateralStrafeEngineTags..ExtraLateralTags end + local lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral) + if (lateralCommandType == axisCommandType.byThrottle) then + local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( + lateralStrafeEngineTags, axisCommandId.lateral) + Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity) + elseif (lateralCommandType == axisCommandType.byTargetSpeed) then + local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral) + autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags + autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration + end + + -- Vertical Translation + local verticalStrafeEngineTags = 'thrust analog vertical ' + if ExtraVerticalTags ~= "none" then verticalStrafeEngineTags = verticalStrafeEngineTags..ExtraVerticalTags end + local verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical) + if (verticalCommandType == axisCommandType.byThrottle) then + local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle( + verticalStrafeEngineTags, axisCommandId.vertical) + if upAmount ~= 0 or (BrakeLanding and BrakeIsOn) then + Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', + 'ground', '', tolerancePercentToSkipOtherPriorities) + else + Nav:setEngineForceCommand(verticalStrafeEngineTags, vec3(), keepCollinearity) -- Reset vertical engines but not airfoils or ground + Nav:setEngineForceCommand('airfoil vertical', verticalStrafeAcceleration, keepCollinearity, 'airfoil', + '', '', tolerancePercentToSkipOtherPriorities) + Nav:setEngineForceCommand('ground vertical', verticalStrafeAcceleration, keepCollinearity, 'ground', + '', '', tolerancePercentToSkipOtherPriorities) + end + elseif (verticalCommandType == axisCommandType.byTargetSpeed) then + if upAmount < 0 then + Nav:setEngineForceCommand('hover', vec3(), keepCollinearity) + end + local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed( + axisCommandId.vertical) + autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags + autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration + end + + local targetSpeed = unit.getAxisCommandValue(0) + -- Auto Navigation (Cruise Control) + if (autoNavigationAcceleration:len() > constants.epsilon) then -- This means it's in cruise + if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.8) or velocity:len() > targetSpeed/3.6 -- if the velocity is not properly aligned with the forward + then + autoNavigationEngineTags = autoNavigationEngineTags .. ', brake' + end + Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', + '', tolerancePercentToSkipOtherPriorities) end - Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', - '', tolerancePercentToSkipOtherPriorities) end + -- Rotation + local angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity) + local airAcceleration = vec3(core.getWorldAirFrictionAngularAcceleration()) + angularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction + + Nav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', + tolerancePercentToSkipOtherPriorities) + -- Rockets Nav:setBoosterCommand('rocket_engine') -- Dodgin's Don't Die Rocket Govenor - Cruise Control Edition @@ -6616,6 +6835,7 @@ function script.onActionStart(action) Nav.control.cancelCurrentControlMasterMode() end Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0) + PlayerThrottle = 0 if (vBooster or hover) and hovGndDet == -1 and (atmosphere() > 0 or coreAltitude < ReentryAltitude) then StrongBrakes = ((planet.gravity * 9.80665 * constructMass()) < LastMaxBrakeInAtmo) if not StrongBrakes and velMag > minAutopilotSpeed then @@ -6791,15 +7011,24 @@ function script.onActionStart(action) elseif action == "stopengines" then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal) clearAll() + PlayerThrottle = 0 elseif action == "speedup" then if not holdingCtrl then + if AtmoSpeedAssist then + PlayerThrottle = utils.clamp(PlayerThrottle + speedChangeLarge/100, -1, 1) + end Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, speedChangeLarge) + else IncrementAutopilotTargetIndex() end elseif action == "speeddown" then if not holdingCtrl then - Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -speedChangeLarge) + if AtmoSpeedAssist then + PlayerThrottle = utils.clamp(PlayerThrottle - speedChangeLarge/100, -1, 1) + end + Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -speedChangeLarge) + else DecrementAutopilotTargetIndex() end @@ -6936,10 +7165,16 @@ function script.onActionLoop(action) end elseif action == "speedup" then if not holdingCtrl then + if AtmoSpeedAssist then + PlayerThrottle = utils.clamp(PlayerThrottle + speedChangeSmall/100, -1, 1) + end Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, speedChangeSmall) end elseif action == "speeddown" then if not holdingCtrl then + if AtmoSpeedAssist then + PlayerThrottle = utils.clamp(PlayerThrottle - speedChangeSmall/100, -1, 1) + end Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -speedChangeSmall) end end