From 370e9748d780e7aeeca63b2a7e28f826b62b15e9 Mon Sep 17 00:00:00 2001 From: archaegeo Date: Fri, 8 Jan 2021 16:09:16 -0500 Subject: [PATCH] User Input Support --- ButtonHUD.conf | 65 +++++++++------- ChangeLog.md | 13 ++++ README.md | 83 ++++++++++----------- scripts/wrap.lua | 2 +- src/ButtonHUD.lua | 186 ++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 257 insertions(+), 92 deletions(-) diff --git a/ButtonHUD.conf b/ButtonHUD.conf index af45341..48796da 100644 --- a/ButtonHUD.conf +++ b/ButtonHUD.conf @@ -1,4 +1,4 @@ -name: ButtonsHud - Dimencia and Archaegeo v4.914 (Minified) +name: ButtonsHud - Dimencia and Archaegeo v4.920 (Minified) slots: core: class: CoreUnit @@ -163,13 +163,16 @@ handlers: fuelTankHandlingRocket = 0 --export: For accurate estimates, set this to the fuel tank handling level of the person who placed the element. Ignored for slotted tanks. ContainerOptimization = 0 --export: For accurate estimates, set this to the Container Optimization level of the person who placed the tanks. Ignored for slotted tanks. FuelTankOptimization = 0 --export: For accurate unslotted fuel tank calculation, set this to the fuel tank optimization skill level of the person who placed the tank. Ignored for slotted tanks. + ExtraLongitudeTags = "none" --export: Enter any extra longitudinal tags you use inside '' seperated by space, i.e. "forward faster major" These will be added to the engines that are control by longitude. + ExtraLateralTags = "none" --export: Enter any extra lateral tags you use inside '' seperated by space, i.e. "left right" These will be added to the engines that are control by lateral. + ExtraVerticalTags = "none" --export: Enter any extra longitudinal tags you use inside '' seperated by space, i.e. "up down" These will be added to the engines that are control by vertical. ExternalAGG = false --export: Toggle On if using an external AGG system. If on will prevent this HUD from doing anything with AGG. UseSatNav = false --export: Toggle on if using Trog SatNav script. This will provide SatNav support. apTickRate = 0.0166667 --export: Set the Tick Rate for your HUD. 0.016667 is effectively 60 fps and the default value. 0.03333333 is 30 fps. The bigger the number the less often the autopilot and hud updates but may help peformance on slower machings. - 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;DisplayOrbit=true;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;TargetGroundAltitude=LandingGearGroundHeight;TotalDistanceTravelled=0.0;TotalFlightTime=0;SavedLocations={}VectorToTarget=false;LocationIndex=0;LastMaxBrake=0;LockPitch=nil;LastMaxBrakeInAtmo=0;AntigravTargetAltitude=core.getAltitude()LastStartTime=0;local a={"userControlScheme","AutopilotTargetOrbit","apTickRate","freeLookToggle","turnAssist","PrimaryR","PrimaryG","PrimaryB","warmup","DeadZone","circleRad","MouseXSensitivity","MouseYSensitivity","MaxGameVelocity","showHud","autoRollPreference","pitchSpeedFactor","yawSpeedFactor","rollSpeedFactor","brakeSpeedFactor","brakeFlatFactor","autoRollFactor","turnAssistFactor","torqueFactor","AutoTakeoffAltitude","TargetHoverHeight","AutopilotInterplanetaryThrottle","hideHudOnToggleWidgets","DampingMultiplier","fuelTankHandlingAtmo","fuelTankHandlingSpace","fuelTankHandlingRocket","RemoteFreeze","speedChangeLarge","speedChangeSmall","brightHud","brakeLandingRate","MaxPitch","ReentrySpeed","AtmoSpeedLimit","ReentryAltitude","centerX","centerY","vSpdMeterX","vSpdMeterY","altMeterX","altMeterY","fuelX","fuelY","LandingGearGroundHeight","TrajectoryAlignmentStrength","RemoteHud","StallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization"}local b={"BrakeToggleStatus","BrakeIsOn","RetrogradeIsOn","ProgradeIsOn","Autopilot","TurnBurn","AltitudeHold","DisplayOrbit","BrakeLanding","Reentry","AutoTakeoff","HoldAltitude","AutopilotAccelerating","AutopilotBraking","AutopilotCruising","AutopilotRealigned","AutopilotEndSpeed","AutopilotStatus","AutopilotPlanetGravity","PrevViewLock","AutopilotTargetName","AutopilotTargetCoords","AutopilotTargetIndex","GearExtended","TargetGroundAltitude","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=false;local b1=false;function LoadVariables()if dbHud_1 then local b2=dbHud_1.hasKey;if not useTheseSettings then for b3,b4 in pairs(a)do if b2(b4)then local b5=f(dbHud_1.getStringValue(b4))if b5~=nil then c(b4 .." "..dbHud_1.getStringValue(b4))_G[b4]=b5;az=true end end end end;coroutine.yield()for b3,b4 in pairs(b)do if b2(b4)then local b5=f(dbHud_1.getStringValue(b4))if b5~=nil then c(b4 .." "..dbHud_1.getStringValue(b4))_G[b4]=b5;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 b6=system.getTime()if LastStartTime+180b8 then b8=b7 end;if ContainerOptimization>0 then b8=b8-b8*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then b8=b8-b8*FuelTankOptimization*0.05 end;return b8 end;function ProcessElements()for b3 in pairs(af)do local type=l(af[b3])if type=="landing gear"then A=true end;if type=="dynamic core"then local b9=h(af[b3])if b9>10000 then aQ=128 elseif b9>1000 then aQ=64 elseif b9>150 then aQ=32 end end;aG=aG+h(af[b3])if fuelX~=0 and fuelY~=0 then if type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank"then local b9=h(af[b3])local ba=m(af[b3])local b7=0;local bb=system.getTime()if type=="Atmospheric Fuel Tank"then local b8=400;local bc=35.03;if b9>10000 then b8=51200;bc=5480 elseif b9>1300 then b8=6400;bc=988.67 elseif b9>150 then b8=1600;bc=182.67 end;b7=ba-bc;if fuelTankHandlingAtmo>0 then b8=b8+b8*fuelTankHandlingAtmo*0.2 end;b8=CalculateFuelVolume(b7,b8)aD[#aD+1]={af[b3],core.getElementNameById(af[b3]),b8,bc,b7,bb}end;if type=="Rocket Fuel Tank"then local b8=320;local bc=173.42;if b9>65000 then b8=40000;bc=25740 elseif b9>6000 then b8=5120;bc=4720 elseif b9>700 then b8=640;bc=886.72 end;b7=ba-bc;if fuelTankHandlingRocket>0 then b8=b8+b8*fuelTankHandlingRocket*0.2 end;b8=CalculateFuelVolume(b7,b8)aF[#aF+1]={af[b3],core.getElementNameById(af[b3]),b8,bc,b7,bb}end;if type=="Space Fuel Tank"then local b8=2400;local bc=182.67;if b9>10000 then b8=76800;bc=5480 elseif b9>1300 then b8=9600;bc=988.67 end;b7=ba-bc;if fuelTankHandlingSpace>0 then b8=b8+b8*fuelTankHandlingSpace*0.2 end;b8=CalculateFuelVolume(b7,b8)aE[#aE+1]={af[b3],core.getElementNameById(af[b3]),b8,bc,b7,bb}end 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 ad then BrakeIsOn=true end;if radar_1 then if l(radar_1.getId())=="Space Radar"then T=true else U=true end end;if door then for _,b4 in pairs(door)do b4.toggle()end end;if switch then for _,b4 in pairs(switch)do b4.toggle()end end;if forcefield then for _,b4 in pairs(forcefield)do b4.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;if TargetGroundAltitude~=nil then Nav.axisCommandManager:setTargetGroundAltitude(TargetGroundAltitude)if TargetGroundAltitude==0 and not A then GearExtended=true end else if GearExtended or not A then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)GearExtended=true else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if ad and not dbHud_1 and(GearExtended or not A)then BrakeIsOn=true end;WasInAtmo=ad end;function ConvertResolutionX(b4)if ResolutionX==1920 then return b4 else return round(ResolutionX*b4/1920,0)end end;function ConvertResolutionY(b4)if ResolutionY==1080 then return b4 else return round(ResolutionY*b4/1080,0)end end;function RefreshLastMaxBrake(bd,be)if bd==nil then bd=core.g()end;bd=round(bd,5)local bf=j()if be~=nil and be or(aC==nil or aC~=bd)then local velocity=core.getVelocity()local bg=vec3(velocity):len()local bh=f(unit.getData()).maxBrake;if bh~=nil and bh>0 and ad then bh=bh/utils.clamp(bg/100,0.1,1)bh=bh/bf;if bh>LastMaxBrakeInAtmo and bf>0.10 then LastMaxBrakeInAtmo=bh end end;if bh~=nil and bh>0 then LastMaxBrake=bh end;aC=bd end end;function MakeButton(bi,bj,bk,bl,bm,bn,bo,bp,bq)local br={enableName=bi,disableName=bj,width=bk,height=bl,x=bm,y=bn,toggleVar=bo,toggleFunction=bp,drawCondition=bq,hovered=false}table.insert(aq,br)return br end;function UpdateAtlasLocationsList()AtlasOrdered={}for b3,b4 in pairs(aS[0])do table.insert(AtlasOrdered,{name=b4.name,index=b3})end;local function bs(bt,bu)return bt.name-1 then aS[0][by]=bx end;UpdateAtlasLocationsList()K=CustomTarget.name.." position updated"end end;function ClearCurrentPosition()local by=-1;for b3,b4 in pairs(aS[0])do if b4.name and b4.name==CustomTarget.name then by=b3 end end;if by>-1 then table.remove(aS[0],by)end;by=-1;for b3,b4 in pairs(SavedLocations)do if b4.name and b4.name==CustomTarget.name then K=b4.name.." saved location cleared"by=b3;break end end;if by~=-1 then table.remove(SavedLocations,by)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(bz)bz[#bz+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 end;function Contains(bA,bB,bm,bn,bk,bl)if bA>bm and bAbn and bBw 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 bC=vec3(core.getConstructWorldOrientationForward())local bD=vec3(core.getConstructWorldOrientationRight())local bE=vec3(core.getWorldVertical())local bF=getPitch(bE,bC,bD)LockPitch=bF;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;I=false;BrakeLanding=false;Reentry=false;autoRoll=true;LockPitch=nil;if not GearExtended and not BrakeIsOn or not ad then AutoTakeoff=false;HoldAltitude=ae;if not a8 and Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;HoldAltitude=ae+AutoTakeoffAltitude;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(500)BrakeIsOn=true end;if a8 then HoldAltitude=100000 end else autoRoll=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;autoRoll=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 then if CustomTarget~=nil then LockPitch=nil;if 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()end else if not VectorToTarget then ToggleVectorToTarget()end end else a7=true end else a8=true;RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then 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 Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;u=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false 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;autoRoll=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;LockPitch=nil;autoRoll=autoRollPreference end end;function CheckDamage(bz)local bG=0;ao=""local bH=aG;local bI=0;local bJ=0;local bK=0;local bL=0;local bM=""for b3 in pairs(af)do local b9=0;local bN=0;bN=h(af[b3])b9=k(af[b3])bI=bI+b9;if b90 and al[11]==af[b3]then for bP in pairs(al)do core.deleteSticker(al[bP])end;al={}end end;bG=d(bI/bH*100)if bG<100 then bz[#bz+1]=[[]]bL=d(bG*2.55)bM=e("rgb(%d,%d,%d)",255-bL,bL,0)if bG<100 then bz[#bz+1]=e([[Elemental Integrity: %i %%]],bM,bG)if bK>0 then bz[#bz+1]=e([[Disabled Modules: %i Damaged Modules: %i]],bM,bK,bJ)elseif bJ>0 then bz[#bz+1]=e([[Damaged Modules: %i]],bM,bJ)end end;bz[#bz+1]=[[<\g>]]end end;function DrawCursorLine(bz)local bQ=d(utils.clamp(a3/(at/4)*255,0,255))bz[#bz+1]=e("",a0,a1,d(PrimaryR+0.5)+bQ,d(PrimaryG+0.5)-bQ,d(PrimaryB+0.5)-bQ)end;function getPitch(bR,bS,bu)local bT=bR:cross(bu):normalize_inplace()local bF=math.acos(utils.clamp(bT:dot(-bS),-1,1))*constants.rad2deg;if bT:cross(-bS):dot(bu)<0 then bF=-bF end;return bF 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;autoRoll=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 b3,b4 in pairs(a)do dbHud_1.setStringValue(b4,g(nil))end;for b3,b4 in pairs(b)do if b4~="SavedLocations"then dbHud_1.setStringValue(b4,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 _,b4 in pairs(aq)do if b4.hovered then if not b4.drawCondition or b4.drawCondition()then b4.toggleFunction()end;b4.hovered=false end end end;function SetButtonContains()local bm=a0+at/2;local bn=a1+au/2;for _,b4 in pairs(aq)do b4.hovered=Contains(bm,bn,b4.x,b4.y,b4.width,b4.height)end end;function DrawButton(bz,bU,hover,bm,bn,bV,bW,bX,bY,bZ,b_)if type(bZ)=="function"then bZ=bZ()end;if type(b_)=="function"then b_=b_()end;bz[#bz+1]=e(""if bU then bz[#bz+1]=e("%s",bZ)else bz[#bz+1]=e("%s",b_)end end;function DrawButtons(bz)local c0="rgb(50,50,50)'"local c1="rgb(210,200,200)"local c2=DrawButton;for _,b4 in pairs(aq)do local bj=b4.disableName;local bi=b4.enableName;if type(bj)=="function"then bj=bj()end;if type(bi)=="function"then bi=bi()end;if not b4.drawCondition or b4.drawCondition()then c2(bz,b4.toggleVar(),b4.hovered,b4.x,b4.y,b4.width,b4.height,c1,c0,bj,bi)end end end;function DrawTank(bz,aP,bm,c3,c4,c5,c6,c7)local c8=1;local c9=2;local ca=3;local cb=4;local cc=5;local cd=6;local ce=""local cf=0;local cg=fuelY;local ch=fuelY+10;if o()==1 and not RemoteHud then cg=cg-50;ch=ch-50 end;bz[#bz+1]=[[]]if c4=="ATMO"then ce="atmofueltank"elseif c4=="SPACE"then ce="spacefueltank"else ce="rocketfueltank"end;cf=_G[ce.."_size"]if#c5>0 then for i=1,#c5 do local bv=string.sub(c5[i][c9],1,12)local ci=0;for bP=1,cf do if c5[i][c9]==f(unit[ce.."_"..bP].getData()).name then ci=bP;break end end;if aP or c6[i]==nil or c7[i]==nil then local cj=0;local ck=0;local cl=0;local cm=0;local bb=system.getTime()if ci~=0 then c7[i]=f(unit[ce.."_"..ci].getData()).percentage;c6[i]=f(unit[ce.."_"..ci].getData()).timeLeft;if c6[i]=="n/a"then c6[i]=0 end else cl=m(c5[i][c8])-c5[i][cb]cj=c5[i][ca]c7[i]=d(0.5+cl*100/cj)ck=c5[i][cc]cm=c5[i][cd]if ck<=cl then c6[i]=0 else c6[i]=d(0.5+cl/((ck-cl)/(bb-cm)))end;c5[i][cc]=cl;c5[i][cd]=bb end end;if bv==c3 then bv=e("%s %d",c4,i)end;if ci==0 then bv=bv.." *"end;local cn;if c6[i]==0 then cn="n/a"else cn=FormatTimeString(c6[i])end;if c7[i]~=nil then local bL=d(c7[i]*2.55)local bM=e("rgb(%d,%d,%d)",255-bL,bL,0)local co=""if cn~="n/a"and c6[i]<120 or c7[i]<5 then if aP then co=[[class="red"]]end end;bz[#bz+1]=e([[ + 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;DisplayOrbit=true;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;TargetGroundAltitude=LandingGearGroundHeight;TotalDistanceTravelled=0.0;TotalFlightTime=0;SavedLocations={}VectorToTarget=false;LocationIndex=0;LastMaxBrake=0;LockPitch=nil;LastMaxBrakeInAtmo=0;AntigravTargetAltitude=core.getAltitude()LastStartTime=0;local a={"userControlScheme","AutopilotTargetOrbit","apTickRate","freeLookToggle","turnAssist","PrimaryR","PrimaryG","PrimaryB","warmup","DeadZone","circleRad","MouseXSensitivity","MouseYSensitivity","MaxGameVelocity","showHud","autoRollPreference","pitchSpeedFactor","yawSpeedFactor","rollSpeedFactor","brakeSpeedFactor","brakeFlatFactor","autoRollFactor","turnAssistFactor","torqueFactor","AutoTakeoffAltitude","TargetHoverHeight","AutopilotInterplanetaryThrottle","hideHudOnToggleWidgets","DampingMultiplier","fuelTankHandlingAtmo","fuelTankHandlingSpace","fuelTankHandlingRocket","RemoteFreeze","speedChangeLarge","speedChangeSmall","brightHud","brakeLandingRate","MaxPitch","ReentrySpeed","AtmoSpeedLimit","ReentryAltitude","centerX","centerY","vSpdMeterX","vSpdMeterY","altMeterX","altMeterY","fuelX","fuelY","LandingGearGroundHeight","TrajectoryAlignmentStrength","RemoteHud","StallAngle","ResolutionX","ResolutionY","UseSatNav","FuelTankOptimization","ContainerOptimization","ExtraLongitudeTags","ExtraLateralTags","ExtraVerticalTags"}local b={"BrakeToggleStatus","BrakeIsOn","RetrogradeIsOn","ProgradeIsOn","Autopilot","TurnBurn","AltitudeHold","DisplayOrbit","BrakeLanding","Reentry","AutoTakeoff","HoldAltitude","AutopilotAccelerating","AutopilotBraking","AutopilotCruising","AutopilotRealigned","AutopilotEndSpeed","AutopilotStatus","AutopilotPlanetGravity","PrevViewLock","AutopilotTargetName","AutopilotTargetCoords","AutopilotTargetIndex","GearExtended","TargetGroundAltitude","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=false;local b1=false;local b2=autoRollPreference;function LoadVariables()if dbHud_1 then local b3=dbHud_1.hasKey;if not useTheseSettings then for b4,b5 in pairs(a)do if b3(b5)then local b6=f(dbHud_1.getStringValue(b5))if b6~=nil then c(b5 .." "..dbHud_1.getStringValue(b5))_G[b5]=b6;az=true end end end end;coroutine.yield()for b4,b5 in pairs(b)do if b3(b5)then local b6=f(dbHud_1.getStringValue(b5))if b6~=nil then c(b5 .." "..dbHud_1.getStringValue(b5))_G[b5]=b6;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 b7=system.getTime()if LastStartTime+180b9 then b9=b8 end;if ContainerOptimization>0 then b9=b9-b9*ContainerOptimization*0.05 end;if FuelTankOptimization>0 then b9=b9-b9*FuelTankOptimization*0.05 end;return b9 end;function ProcessElements()for b4 in pairs(af)do local type=l(af[b4])if type=="landing gear"then A=true end;if type=="dynamic core"then local ba=h(af[b4])if ba>10000 then aQ=128 elseif ba>1000 then aQ=64 elseif ba>150 then aQ=32 end end;aG=aG+h(af[b4])if fuelX~=0 and fuelY~=0 then if type=="Atmospheric Fuel Tank"or type=="Space Fuel Tank"or type=="Rocket Fuel Tank"then local ba=h(af[b4])local bb=m(af[b4])local b8=0;local bc=system.getTime()if type=="Atmospheric Fuel Tank"then local b9=400;local bd=35.03;if ba>10000 then b9=51200;bd=5480 elseif ba>1300 then b9=6400;bd=988.67 elseif ba>150 then b9=1600;bd=182.67 end;b8=bb-bd;if fuelTankHandlingAtmo>0 then b9=b9+b9*fuelTankHandlingAtmo*0.2 end;b9=CalculateFuelVolume(b8,b9)aD[#aD+1]={af[b4],core.getElementNameById(af[b4]),b9,bd,b8,bc}end;if type=="Rocket Fuel Tank"then local b9=320;local bd=173.42;if ba>65000 then b9=40000;bd=25740 elseif ba>6000 then b9=5120;bd=4720 elseif ba>700 then b9=640;bd=886.72 end;b8=bb-bd;if fuelTankHandlingRocket>0 then b9=b9+b9*fuelTankHandlingRocket*0.2 end;b9=CalculateFuelVolume(b8,b9)aF[#aF+1]={af[b4],core.getElementNameById(af[b4]),b9,bd,b8,bc}end;if type=="Space Fuel Tank"then local b9=2400;local bd=182.67;if ba>10000 then b9=76800;bd=5480 elseif ba>1300 then b9=9600;bd=988.67 end;b8=bb-bd;if fuelTankHandlingSpace>0 then b9=b9+b9*fuelTankHandlingSpace*0.2 end;b9=CalculateFuelVolume(b8,b9)aE[#aE+1]={af[b4],core.getElementNameById(af[b4]),b9,bd,b8,bc}end 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 ad then BrakeIsOn=true end;if radar_1 then if l(radar_1.getId())=="Space Radar"then T=true else U=true end end;if door then for _,b5 in pairs(door)do b5.toggle()end end;if switch then for _,b5 in pairs(switch)do b5.toggle()end end;if forcefield then for _,b5 in pairs(forcefield)do b5.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;if TargetGroundAltitude~=nil then Nav.axisCommandManager:setTargetGroundAltitude(TargetGroundAltitude)if TargetGroundAltitude==0 and not A then GearExtended=true end else if GearExtended or not A then Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)GearExtended=true else Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end end;if ad and not dbHud_1 and(GearExtended or not A)then BrakeIsOn=true end;WasInAtmo=ad end;function ConvertResolutionX(b5)if ResolutionX==1920 then return b5 else return round(ResolutionX*b5/1920,0)end end;function ConvertResolutionY(b5)if ResolutionY==1080 then return b5 else return round(ResolutionY*b5/1080,0)end end;function RefreshLastMaxBrake(be,bf)if be==nil then be=core.g()end;be=round(be,5)local bg=j()if bf~=nil and bf or(aC==nil or aC~=be)then local velocity=core.getVelocity()local bh=vec3(velocity):len()local bi=f(unit.getData()).maxBrake;if bi~=nil and bi>0 and ad then bi=bi/utils.clamp(bh/100,0.1,1)bi=bi/bg;if bi>LastMaxBrakeInAtmo and bg>0.10 then LastMaxBrakeInAtmo=bi end end;if bi~=nil and bi>0 then LastMaxBrake=bi end;aC=be end end;function MakeButton(bj,bk,bl,bm,bn,bo,bp,bq,br)local bs={enableName=bj,disableName=bk,width=bl,height=bm,x=bn,y=bo,toggleVar=bp,toggleFunction=bq,drawCondition=br,hovered=false}table.insert(aq,bs)return bs end;function UpdateAtlasLocationsList()AtlasOrdered={}for b4,b5 in pairs(aS[0])do table.insert(AtlasOrdered,{name=b5.name,index=b4})end;local function bt(bu,bv)return bu.name-1 then aS[0][bE]=bz end;UpdateAtlasLocationsList()K=CustomTarget.name.." position updated"AutopilotTargetIndex=0;UpdateAutopilotTarget()else K="Name Not Found"end end;function ClearCurrentPosition()local bE=-1;for b4,b5 in pairs(aS[0])do if b5.name and b5.name==CustomTarget.name then bE=b4 end end;if bE>-1 then table.remove(aS[0],bE)end;bE=-1;for b4,b5 in pairs(SavedLocations)do if b5.name and b5.name==CustomTarget.name then K=b5.name.." saved location cleared"bE=b4;break end end;if bE~=-1 then table.remove(SavedLocations,bE)end;DecrementAutopilotTargetIndex()UpdateAtlasLocationsList()end;function DrawDeadZone(bG)bG[#bG+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 end;function Contains(bH,bI,bn,bo,bl,bm)if bH>bn and bHbo and bIw 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 bJ=vec3(core.getConstructWorldOrientationForward())local bK=vec3(core.getConstructWorldOrientationRight())local bL=vec3(core.getWorldVertical())local bM=getPitch(bL,bJ,bK)LockPitch=bM;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=false else LockPitch=nil end end;function ToggleAltitudeHold()AltitudeHold=not AltitudeHold;if AltitudeHold then Autopilot=false;ProgradeIsOn=false;RetrogradeIsOn=false;I=false;BrakeLanding=false;Reentry=false;b2=true;LockPitch=nil;if not GearExtended and not BrakeIsOn or not ad then AutoTakeoff=false;HoldAltitude=ae;if not a8 and Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end else AutoTakeoff=true;HoldAltitude=ae+AutoTakeoffAltitude;GearExtended=false;Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(500)BrakeIsOn=true end;if a8 then HoldAltitude=100000 end else b2=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;b2=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 then if CustomTarget~=nil then LockPitch=nil;if 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()end else if not VectorToTarget then ToggleVectorToTarget()end end else a7=true end else a8=true;RetrogradeIsOn=false;ProgradeIsOn=false;if j()~=0 then 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 Autopilot=false;AutopilotRealigned=false;VectorToTarget=false;u=false;AutoTakeoff=false;AltitudeHold=false;VectorToTarget=false 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;b2=autoRollPreference end;if BrakeIsOn then AltitudeHold=false;VectorToTarget=false;AutoTakeoff=false;Reentry=false;ProgradeIsOn=false;BrakeLanding=false;AutoLanding=false;AltitudeHold=false;LockPitch=nil;b2=autoRollPreference end end;function CheckDamage(bG)local bN=0;ao=""local bO=aG;local bP=0;local bQ=0;local bR=0;local bS=0;local bT=""for b4 in pairs(af)do local ba=0;local bU=0;bU=h(af[b4])ba=k(af[b4])bP=bP+ba;if ba0 and al[11]==af[b4]then for bV in pairs(al)do core.deleteSticker(al[bV])end;al={}end end;bN=d(bP/bO*100)if bN<100 then bG[#bG+1]=[[]]bS=d(bN*2.55)bT=e("rgb(%d,%d,%d)",255-bS,bS,0)if bN<100 then bG[#bG+1]=e([[Elemental Integrity: %i %%]],bT,bN)if bR>0 then bG[#bG+1]=e([[Disabled Modules: %i Damaged Modules: %i]],bT,bR,bQ)elseif bQ>0 then bG[#bG+1]=e([[Damaged Modules: %i]],bT,bQ)end end;bG[#bG+1]=[[<\g>]]end end;function DrawCursorLine(bG)local bW=d(utils.clamp(a3/(at/4)*255,0,255))bG[#bG+1]=e("",a0,a1,d(PrimaryR+0.5)+bW,d(PrimaryG+0.5)-bW,d(PrimaryB+0.5)-bW)end;function getPitch(bX,bY,bv)local bZ=bX:cross(bv):normalize_inplace()local bM=math.acos(utils.clamp(bZ:dot(-bY),-1,1))*constants.rad2deg;if bZ:cross(-bY):dot(bv)<0 then bM=-bM end;return bM 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;b2=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 b4,b5 in pairs(a)do dbHud_1.setStringValue(b5,g(nil))end;for b4,b5 in pairs(b)do if b5~="SavedLocations"then dbHud_1.setStringValue(b5,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 _,b5 in pairs(aq)do if b5.hovered then if not b5.drawCondition or b5.drawCondition()then b5.toggleFunction()end;b5.hovered=false end end end;function SetButtonContains()local bn=a0+at/2;local bo=a1+au/2;for _,b5 in pairs(aq)do b5.hovered=Contains(bn,bo,b5.x,b5.y,b5.width,b5.height)end end;function DrawButton(bG,b_,hover,bn,bo,c0,c1,c2,c3,c4,c5)if type(c4)=="function"then c4=c4()end;if type(c5)=="function"then c5=c5()end;bG[#bG+1]=e(""if b_ then bG[#bG+1]=e("%s",c4)else bG[#bG+1]=e("%s",c5)end end;function DrawButtons(bG)local c6="rgb(50,50,50)'"local c7="rgb(210,200,200)"local c8=DrawButton;for _,b5 in pairs(aq)do local bk=b5.disableName;local bj=b5.enableName;if type(bk)=="function"then bk=bk()end;if type(bj)=="function"then bj=bj()end;if not b5.drawCondition or b5.drawCondition()then c8(bG,b5.toggleVar(),b5.hovered,b5.x,b5.y,b5.width,b5.height,c7,c6,bk,bj)end end end;function DrawTank(bG,aP,bn,c9,ca,cb,cc,cd)local ce=1;local cf=2;local cg=3;local ch=4;local ci=5;local cj=6;local ck=""local cl=0;local cm=fuelY;local cn=fuelY+10;if o()==1 and not RemoteHud then cm=cm-50;cn=cn-50 end;bG[#bG+1]=[[]]if ca=="ATMO"then ck="atmofueltank"elseif ca=="SPACE"then ck="spacefueltank"else ck="rocketfueltank"end;cl=_G[ck.."_size"]if#cb>0 then for i=1,#cb do local bB=string.sub(cb[i][cf],1,12)local co=0;for bV=1,cl do if cb[i][cf]==f(unit[ck.."_"..bV].getData()).name then co=bV;break end end;if aP or cc[i]==nil or cd[i]==nil then local cp=0;local cq=0;local cr=0;local cs=0;local bc=system.getTime()if co~=0 then cd[i]=f(unit[ck.."_"..co].getData()).percentage;cc[i]=f(unit[ck.."_"..co].getData()).timeLeft;if cc[i]=="n/a"then cc[i]=0 end else cr=m(cb[i][ce])-cb[i][ch]cp=cb[i][cg]cd[i]=d(0.5+cr*100/cp)cq=cb[i][ci]cs=cb[i][cj]if cq<=cr then cc[i]=0 else cc[i]=d(0.5+cr/((cq-cr)/(bc-cs)))end;cb[i][ci]=cr;cb[i][cj]=bc end end;if bB==c9 then bB=e("%s %d",ca,i)end;if co==0 then bB=bB.." *"end;local ct;if cc[i]==0 then ct="n/a"else ct=FormatTimeString(cc[i])end;if cd[i]~=nil then local bS=d(cd[i]*2.55)local bT=e("rgb(%d,%d,%d)",255-bS,bS,0)local cu=""if ct~="n/a"and cc[i]<120 or cd[i]<5 then if aP then cu=[[class="red"]]end end;bG[#bG+1]=e([[ %s %d%% %s - ]],bm,cg,co,bv,bm,ch,bM,c7[i],cn)cg=cg+30;ch=ch+30 end end end;bz[#bz+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(velocity)velocity=vec3(velocity)local bF=-math.deg(math.atan(velocity.y,velocity.z))+180;bF=bF-90;if bF<0 then bF=360+bF end;if bF>180 then bF=-180+bF-180 end;return-bF end;function getRelativeYaw(velocity)velocity=vec3(velocity)local cp=math.deg(math.atan(velocity.y,velocity.x))-90;if cp<-180 then cp=360+cp end;return cp end;function AlignToWorldVector(cq,cr)if not ad or RateOfChange>MinimumRateOfChange+0.08 or aa~=-1 then if cr==nil then cr=as end;cq=vec3(cq):normalize()local cs=vec3(core.getConstructWorldOrientationForward())-cq;local ct=-getMagnitudeInDirection(cs,core.getConstructWorldOrientationRight())*ar;local cu=-getMagnitudeInDirection(cs,core.getConstructWorldOrientationUp())*ar;if am==0 then am=ct/2 end;if an==0 then an=cu/2 end;D=D-(ct+(ct-am)*DampingMultiplier)C=C+cu+(cu-an)*DampingMultiplier;am=ct;an=cu;if math.abs(ct)0 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,cy.height,cy.x-200-30,cy.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)cv=60;cw=300;local bm=10;local bn=au/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",cw,cv,bm,bn,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",cw,cv,bm+cw+20,bn,function()return AltitudeHold end,ToggleAltitudeHold)bn=bn+cv+20;MakeButton("Engage Autoland","Disable Autoland",cw,cv,bm,bn,function()return AutoLanding end,ToggleAutoLanding)MakeButton("Engage Auto Takeoff","Disable Auto Takeoff",cw,cv,bm+cw+20,bn,function()return AutoTakeoff end,ToggleAutoTakeoff)bn=bn+cv+20;MakeButton("Show Orbit Display","Hide Orbit Display",cw,cv,bm,bn,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then K="Orbit Display Enabled"else K="Orbit Display Disabled"end end)bn=bn+cv+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",cw,cv,bm,bn,function()return Reentry end,function()x=true;BeginReentry()end,function()return ae>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",cw,cv,bm+cw+20,bn,function()return Reentry end,BeginReentry,function()return ae>ReentryAltitude end)bn=bn+cv+20;MakeButton("Engage Follow Mode","Disable Follow Mode",cw,cv,bm,bn,function()return I end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",cw,cv,bm+cw+20,bn,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)bn=bn+cv+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",cw,cv,bm,bn,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bn=bn+cv+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,cw*2,cv,bm,bn,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 cz=Nav.axisCommandManager:getAxisCommandType(0)local cA="TRAVEL"if cz==1 then cA="CRUISE"end;if Autopilot then cA="AUTOPILOT"end;return cA end;function updateHud(bz)local cB=ae;local velocity=core.getVelocity()local bg=vec3(velocity):len()local bE=vec3(core.getWorldVertical())local bC=vec3(core.getConstructWorldOrientationForward())local bD=vec3(core.getConstructWorldOrientationRight())local cC=vec3(core.getConstructWorldOrientationUp())local cD=getRoll(bE,bC,bD)local cE=cD/180*math.pi;local cF=math.cos(cE)local cG=math.sin(cE)local bF=getPitch(bE,bC,bD*cF+cC*cG)local cH=cD;local cI=bF;local cJ=j()local cK=d(unit.getThrottle())local cL=bg*3.6;local cM=unit.getAxisCommandValue(0)local cA=GetFlightStyle()local cN="ROLL"local cO=unit.getClosestPlanetInfluence()>0;if cK==nil then cK=0 end;if not cO then if bg>5 then bF=getRelativePitch(velocity)cD=getRelativeYaw(velocity)else bF=0;cD=0 end;cN="YAW"end;bz[#bz+1]=a5;bz[#bz+1]=ao;bz[#bz+1]=a4;if aR%aK==0 then aP=true end;if fuelX~=0 and fuelY~=0 then DrawTank(bz,aP,fuelX,"Atmospheric ","ATMO",aD,aN,aO)DrawTank(bz,aP,fuelX+100,"Space fuel t","SPACE",aE,aL,aM)DrawTank(bz,aP,fuelX+200,"Rocket fuel ","ROCKET",aF,aI,aJ)end;if aP then aP=false;aR=0 end;aR=aR+1;DrawVerticalSpeed(bz,cB)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if cO then DrawRollLines(bz,centerX,centerY,cH,cN,cO)DrawArtificialHorizon(bz,cI,cH,centerX,centerY,cO,d(getRelativeYaw(velocity)),bg)else DrawRollLines(bz,centerX,centerY,cD,cN,cO)DrawArtificialHorizon(bz,bF,cD,centerX,centerY,cO,d(cD),bg)end;DrawAltitudeDisplay(bz,cB,cO)DrawPrograde(bz,velocity,bg,centerX,centerY)end end;DrawThrottle(bz,cA,cK,cM)DrawSpeed(bz,cL)DrawWarnings(bz)DisplayOrbitScreen(bz)if screen_2 then local cP=vec3(core.getConstructWorldPos())local bm=960+cP.x/aU;local bn=450+cP.y/aV;screen_2.moveContent(aW,(bm-80)/19.2,(bn-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(bz)local cQ=aj;local cR=ak;local cS=aj;local cT=ak;if IsInFreeLook()and not brightHud then cQ=[[rgb(]]..d(PrimaryR*0.4+0.5)..","..d(PrimaryG*0.4+0.5)..","..d(PrimaryB*0.3+0.5)..[[)]]cR=[[rgb(]]..d(PrimaryR*0.3+0.5)..","..d(PrimaryG*0.3+0.5)..","..d(PrimaryB*0.2+0.5)..[[)]]end;bz[#bz+1]=e([[ + ]],bn,cm,cu,bB,bn,cn,bT,cd[i],ct)cm=cm+30;cn=cn+30 end end end;bG[#bG+1]=""end;function HideInterplanetaryPanel()system.destroyWidgetPanel(panelInterplanetary)panelInterplanetary=nil end;function getRelativePitch(velocity)velocity=vec3(velocity)local bM=-math.deg(math.atan(velocity.y,velocity.z))+180;bM=bM-90;if bM<0 then bM=360+bM end;if bM>180 then bM=-180+bM-180 end;return-bM end;function getRelativeYaw(velocity)velocity=vec3(velocity)local cv=math.deg(math.atan(velocity.y,velocity.x))-90;if cv<-180 then cv=360+cv end;return cv end;function AlignToWorldVector(cw,cx)if not ad or RateOfChange>MinimumRateOfChange+0.08 or aa~=-1 then if cx==nil then cx=as end;cw=vec3(cw):normalize()local cy=vec3(core.getConstructWorldOrientationForward())-cw;local cz=-getMagnitudeInDirection(cy,core.getConstructWorldOrientationRight())*ar;local cA=-getMagnitudeInDirection(cy,core.getConstructWorldOrientationUp())*ar;if am==0 then am=cz/2 end;if an==0 then an=cA/2 end;D=D-(cz+(cz-am)*DampingMultiplier)C=C+cA+(cA-an)*DampingMultiplier;am=cz;an=cA;if math.abs(cz)0 and CustomTarget~=nil end)MakeButton("Clear Position","Clear Position",200,cE.height,cE.x-200-30,cE.y,function()return true end,ClearCurrentPosition,function()return AutopilotTargetIndex>0 and CustomTarget~=nil end)cB=60;cC=300;local bn=10;local bo=au/2-300;MakeButton("Enable Turn and Burn","Disable Turn and Burn",cC,cB,bn,bo,function()return TurnBurn end,ToggleTurnBurn)MakeButton("Engage Altitude Hold","Disable Altitude Hold",cC,cB,bn+cC+20,bo,function()return AltitudeHold end,ToggleAltitudeHold)bo=bo+cB+20;MakeButton("Engage Autoland","Disable Autoland",cC,cB,bn,bo,function()return AutoLanding end,ToggleAutoLanding)MakeButton("Engage Auto Takeoff","Disable Auto Takeoff",cC,cB,bn+cC+20,bo,function()return AutoTakeoff end,ToggleAutoTakeoff)bo=bo+cB+20;MakeButton("Show Orbit Display","Hide Orbit Display",cC,cB,bn,bo,function()return DisplayOrbit end,function()DisplayOrbit=not DisplayOrbit;if DisplayOrbit then K="Orbit Display Enabled"else K="Orbit Display Disabled"end end)bo=bo+cB+20;MakeButton("Glide Re-Entry","Cancel Glide Re-Entry",cC,cB,bn,bo,function()return Reentry end,function()x=true;BeginReentry()end,function()return ae>ReentryAltitude end)MakeButton("Parachute Re-Entry","Cancel Parachute Re-Entry",cC,cB,bn+cC+20,bo,function()return Reentry end,BeginReentry,function()return ae>ReentryAltitude end)bo=bo+cB+20;MakeButton("Engage Follow Mode","Disable Follow Mode",cC,cB,bn,bo,function()return I end,ToggleFollowMode,function()return o()==1 end)MakeButton("Enable Repair Arrows","Disable Repair Arrows",cC,cB,bn+cC+20,bo,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)bo=bo+cB+20;if not ExternalAGG then MakeButton("Enable AGG","Disable AGG",cC,cB,bn,bo,function()return antigrav.getState()==1 end,ToggleAntigrav,function()return antigrav~=nil end)end;bo=bo+cB+20;MakeButton(function()return e("Toggle Control Scheme - Current: %s",userControlScheme)end,function()return e("Control Scheme: %s",userControlScheme)end,cC*2,cB,bn,bo,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 cF=Nav.axisCommandManager:getAxisCommandType(0)local cG="TRAVEL"if cF==1 then cG="CRUISE"end;if Autopilot then cG="AUTOPILOT"end;return cG end;function updateHud(bG)local cH=ae;local velocity=core.getVelocity()local bh=vec3(velocity):len()local bL=vec3(core.getWorldVertical())local bJ=vec3(core.getConstructWorldOrientationForward())local bK=vec3(core.getConstructWorldOrientationRight())local cI=vec3(core.getConstructWorldOrientationUp())local cJ=getRoll(bL,bJ,bK)local cK=cJ/180*math.pi;local cL=math.cos(cK)local cM=math.sin(cK)local bM=getPitch(bL,bJ,bK*cL+cI*cM)local cN=cJ;local cO=bM;local cP=j()local cQ=d(unit.getThrottle())local cR=bh*3.6;local cS=unit.getAxisCommandValue(0)local cG=GetFlightStyle()local cT="ROLL"local cU=unit.getClosestPlanetInfluence()>0;if cQ==nil then cQ=0 end;if not cU then if bh>5 then bM=getRelativePitch(velocity)cJ=getRelativeYaw(velocity)else bM=0;cJ=0 end;cT="YAW"end;bG[#bG+1]=a5;bG[#bG+1]=ao;bG[#bG+1]=a4;if aR%aK==0 then aP=true end;if fuelX~=0 and fuelY~=0 then DrawTank(bG,aP,fuelX,"Atmospheric ","ATMO",aD,aN,aO)DrawTank(bG,aP,fuelX+100,"Space fuel t","SPACE",aE,aL,aM)DrawTank(bG,aP,fuelX+200,"Rocket fuel ","ROCKET",aF,aI,aJ)end;if aP then aP=false;aR=0 end;aR=aR+1;DrawVerticalSpeed(bG,cH)if o()==0 or RemoteHud then if not IsInFreeLook()or brightHud then if cU then DrawRollLines(bG,centerX,centerY,cN,cT,cU)DrawArtificialHorizon(bG,cO,cN,centerX,centerY,cU,d(getRelativeYaw(velocity)),bh)else DrawRollLines(bG,centerX,centerY,cJ,cT,cU)DrawArtificialHorizon(bG,bM,cJ,centerX,centerY,cU,d(cJ),bh)end;DrawAltitudeDisplay(bG,cH,cU)DrawPrograde(bG,velocity,bh,centerX,centerY)end end;DrawThrottle(bG,cG,cQ,cS)DrawSpeed(bG,cR)DrawWarnings(bG)DisplayOrbitScreen(bG)if screen_2 then local cV=vec3(core.getConstructWorldPos())local bn=960+cV.x/aU;local bo=450+cV.y/aV;screen_2.moveContent(aW,(bn-80)/19.2,(bo-80)/10.8)end end;function IsInFreeLook()return system.isViewLocked()==0 and userControlScheme~="keyboard"and o()==0 end;function HUDPrologue(bG)local cW=aj;local cX=ak;local cY=aj;local cZ=ak;if IsInFreeLook()and not brightHud then cW=[[rgb(]]..d(PrimaryR*0.4+0.5)..","..d(PrimaryG*0.4+0.5)..","..d(PrimaryB*0.3+0.5)..[[)]]cX=[[rgb(]]..d(PrimaryR*0.3+0.5)..","..d(PrimaryG*0.3+0.5)..","..d(PrimaryB*0.2+0.5)..[[)]]end;bG[#bG+1]=e([[ ",ResolutionX,ResolutionY)bz[#bz+1]=aT;bz[#bz+1]=ha;bz[#bz+1]=""b0=true;bz[#bz+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(bz,"")system.setScreen(content)elseif b1 then local ha=table.concat(bz,"")bz={}bz[#bz+1]=e("",ResolutionX,ResolutionY)bz[#bz+1]=aT;bz[#bz+1]=ha;bz[#bz+1]=""end;if not b0 then bz[#bz+1]=e([[]],s,t,a0,a1)end else CheckButtons()a0=0;a1=0 end else a0=a0+h7;a1=a1+h8;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 a1DeadZone then DrawCursorLine(bz)end else SetButtonContains()DrawButtons(bz)end;bz[#bz+1]=e([[]],s,t,a0,a1)end;bz[#bz+1]=[[]]content=table.concat(bz,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end;if ProgradeIsOn then if velMag>w then local hb=AlignToWorldVector(vec3(velocity),0.01)if a7 then autoRoll=true;if hb then ProgradeIsOn=false;x=true;BeginReentry()a7=false;a9=true;autoRoll=autoRollPreference end end end end;if RetrogradeIsOn then if ad then RetrogradeIsOn=false elseif velMag>w then AlignToWorldVector(-vec3(velocity))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 then local P,Q;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(velMag)else P,Q=GetAutopilotTBBrakeDistanceAndTime(velMag)end;P=P;Q=Q;local hc=AutopilotTargetCoords;if orbit.apoapsis==nil and velMag>300 and AutopilotAccelerating then local hd=(vec3(AutopilotTargetCoords)-vec3(core.getConstructWorldPos())):normalize()-vec3(velocity):normalize()local he=getMagnitudeInDirection(hd,AutopilotShipUp)local hf=getMagnitudeInDirection(hd,AutopilotShipRight)local hg=-hf*AutopilotDistance*velMag*TrajectoryAlignmentStrength;local hh=-he*AutopilotDistance*velMag*TrajectoryAlignmentStrength;hc=AutopilotTargetCoords+-hg*vec3(AutopilotShipRight)+-hh*vec3(AutopilotShipUp)end;AutopilotDistance=(vec3(hc)-vec3(core.getConstructWorldPos())):len()local hi=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..getDistanceDisplayString(hi)..'", "unit":""}')local hj=true;local hk=(V.center-(vec3(core.getConstructWorldPos())+vec3(velocity):normalize()*AutopilotDistance)):len()-V.radius;system.updateData(widgetTrajectoryAltitudeText,'{"label": "Projected Altitude", "value": "'..getDistanceDisplayString(hk)..'", "unit":""}')if not AutopilotCruising and not AutopilotBraking then hj=AlignToWorldVector((hc-vec3(core.getConstructWorldPos())):normalize())elseif TurnBurn then hj=AlignToWorldVector(-vec3(velocity):normalize())end;if AutopilotAccelerating then if not hj or BrakeIsOn then AutopilotStatus="Adjusting Trajectory"else AutopilotStatus="Accelerating"end;if vec3(core.getConstructWorldOrientationForward()):dot(velocity)<0 and velMag>300 then BrakeIsOn=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)u=false elseif not u then BrakeIsOn=false;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,AutopilotInterplanetaryThrottle)u=true end;if vec3(core.getVelocity()):len()>=MaxGameVelocity and math.abs(hk-AutopilotTargetOrbit)<1000 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 orbit.periapsis~=nil and orbit.eccentricity<1 then AutopilotStatus="Circularizing"if orbit.eccentricity>L or orbit.apoapsis.altitude0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if hj then if not AutopilotRealigned then AutopilotTargetCoords=vec3(V.center)+(AutopilotTargetOrbit+V.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotRealigned=true;AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()elseif hj 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 autoRoll=true;local hl=0;local cP=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local hm=cP-vec3(core.getConstructWorldPos())local hn=vec3(hm):project_on(vec3(core.getConstructWorldOrientationForward())):len()local ho=vec3(hm):project_on(vec3(core.getConstructWorldOrientationRight())):len()local a3=math.sqrt(hn*hn+ho*ho)AlignToWorldVector(hm:normalize())local hp=40;local hq=a3ht then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(hl-bF)local hu=pitchPID:get()C=hu end end;local d8=vec3(core.getWorldVertical())*-1;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local cO=unit.getClosestPlanetInfluence()>0;local cB=ae;local hv=HoldAltitude-cB;local hw=500+velMag;local hl=(utils.smoothstep(hv,-hw,hw)-0.5)*2*MaxPitch;if not AltitudeHold then hl=0 end;if LockPitch~=nil then if cO then hl=LockPitch else LockPitch=nil end end;autoRoll=true;if Reentry then local hx=ReentrySpeed;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=hx then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,hx)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if not x then hl=-80;if j()>0.02 then K="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;hl=0;autoRoll=autoRollPreference end elseif Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==ReentrySpeed then x=false;Reentry=false;autoRoll=autoRollPreference end end;local hy=C;if velMag>w then AlignToWorldVector(vec3(velocity))end;if VectorToTarget and CustomTarget~=nil and AutopilotTargetIndex>0 then local cs=CustomTarget.position-vec3(core.getConstructWorldPos())AlignToWorldVector(cs)local hz=cs:len()-cs:project_on(d8):len()local bh=LastMaxBrakeInAtmo;local d6=velocity.x*d8.x+velocity.y*d8.y+velocity.z*d8.z;local hA=velocity:len()-math.abs(d6)local hB=vec3(core.getWorldAirFrictionAcceleration())if bh~=nil then P,Q=aZ.computeDistanceAndTime(hA,0,n(),0,0,bh+(hB:len()-hB:project_on(d8):len())*n())else P,Q=aZ.computeDistanceAndTime(hA,0,n(),0,0,LastMaxBrake+vec3(core.getWorldAirFrictionAcceleration()):len()*n())end;StrongBrakes=planet.gravity*9.80665*n()LastTargetDistance and not AltitudeHold and not AutoTakeoff then BrakeLanding=true;VectorToTarget=false end;LastTargetDistance=hz end;C=hy;local bC=vec3(core.getConstructWorldOrientationForward())local bD=vec3(core.getConstructWorldOrientationRight())local bE=vec3(core.getWorldVertical())local ev=-1;local bF=getPitch(bE,bC,bD)local ht=0.1;if BrakeLanding then hl=0;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)local d6=velocity.x*d8.x+velocity.y*d8.y+velocity.z*d8.z;ev=aa;if ev>-1 then if math.abs(hl-bF)50000 then if Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=5000 then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,5000)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end end end;if math.abs(hl-bF)>ht then if pitchPID==nil then pitchPID=pid.new(8*0.01,0,8*0.1)end;pitchPID:inject(hl-bF)local hu=pitchPID:get()C=C+hu end end;L=orbit.eccentricity;if antigrav and not ExternalAGG and ae<200000 then if AntigravTargetAltitude==nil 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;local hC=2;pitchSpeedFactor=math.max(pitchSpeedFactor,0.01)yawSpeedFactor=math.max(yawSpeedFactor,0.01)rollSpeedFactor=math.max(rollSpeedFactor,0.01)hC=math.max(hC,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 hD=utils.clamp(B+C+system.getControlDeviceForwardInput(),-1,1)local hE=utils.clamp(E+H+system.getControlDeviceYawInput(),-1,1)local hF=utils.clamp(F+D-system.getControlDeviceLeftRightInput(),-1,1)local hG=G;local hH=vec3(core.getWorldVertical())local hI=vec3(core.getConstructWorldOrientationUp())local hJ=vec3(core.getConstructWorldOrientationForward())local hK=vec3(core.getConstructWorldOrientationRight())local hL=vec3(core.getWorldVelocity())local hM=vec3(core.getWorldVelocity()):normalize()local hN=getRoll(hH,hJ,hK)local hO=math.abs(hN)local hP=utils.sign(hN)local j=j()local hQ=vec3(core.getWorldAngularVelocity())local hR=hD*pitchSpeedFactor*hK+hE*rollSpeedFactor*hJ+hF*yawSpeedFactor*hI;if hH:len()>0.01 and j>0.0 or ProgradeIsOn then local hS=1.0;if autoRoll==true and hO>hS and hE==0 then local hT=utils.clamp(0,hO-30,hO+30)if rollPID==nil then rollPID=pid.new(autoRollFactor*0.01,0,autoRollFactor*0.1)end;rollPID:inject(hT-hN)local hU=rollPID:get()hR=hR+hU*hJ end end;if hH:len()>0.01 and j>0.0 then local hV=20.0;if turnAssist==true and hO>hV and hD==0 and hF==0 then local hW=turnAssistFactor*0.1;local hX=turnAssistFactor*0.025;local hY=(hO-hV)/(180-hV)*180;local hZ=0;if hY<90 then hZ=hY/90 elseif hY<180 then hZ=(180-hY)/90 end;hZ=hZ*hZ;local h_=-hP*hX*(1.0-hZ)local i0=hW*hZ;hR=hR+i0*hK+h_*hI end end;local i1=1;local i2=0;local i3=1;local i4=hC*(hR-hQ)local i5=vec3(core.getWorldAirFrictionAngularAcceleration())i4=i4-i5;Nav:setEngineTorqueCommand('torque',i4,i1,'airfoil','','',i3)local i6=-hG*(brakeSpeedFactor*hL+brakeFlatFactor*hM)Nav:setEngineForceCommand('brake',i6)local i7=''local i8=vec3()local i9=false;local ia='thrust analog longitudinal'local ib=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if ib==axisCommandType.byThrottle then local ic=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ia,axisCommandId.longitudinal)Nav:setEngineForceCommand(ia,ic,i1)elseif ib==axisCommandType.byTargetSpeed then local ic=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)i7=i7 ..' , '..ia;i8=i8+ic;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then i9=true end end;local id='thrust analog lateral'local ie=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if ie==axisCommandType.byThrottle then local ig=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(id,axisCommandId.lateral)Nav:setEngineForceCommand(id,ig,i1)elseif ie==axisCommandType.byTargetSpeed then local ih=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)i7=i7 ..' , '..id;i8=i8+ih end;local ii='thrust analog vertical'local ij=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if ij==axisCommandType.byThrottle then local ik=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ii,axisCommandId.vertical)if Z~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(ii,ik,i1,'airfoil','ground','',i3)else Nav:setEngineForceCommand(ii,vec3(),i1)Nav:setEngineForceCommand('airfoil vertical',ik,i1,'airfoil','','',i3)Nav:setEngineForceCommand('ground vertical',ik,i1,'ground','','',i3)end elseif ij==axisCommandType.byTargetSpeed then if Z==0 then Nav:setEngineForceCommand('hover',vec3(),i1)end;local il=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)i7=i7 ..' , '..ii;i8=i8+il end;if i8:len()>constants.epsilon then if G~=0 or i9 or math.abs(hM:dot(hJ))<0.95 then i7=i7 ..', brake'end;Nav:setEngineForceCommand(i7,i8,i2,'','','',i3)end;Nav:setBoosterCommand('rocket_engine')if O and not VanillaRockets then local bg=vec3(core.getVelocity()):len()local im=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local io=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bg*3.6>io*(1-im)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bg*3.6=hs*(1-im)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bg=hs*(1-im)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bg0 or aew then K="WARNING: Insufficient Brakes - Attempting landing anyway"end;Reentry=false;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=true;autoRoll=true;GearExtended=false else BrakeIsOn=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end else Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end elseif iq=="light"then if Nav.control.isAnyHeadlightSwitchedOn()==1 then Nav.control.switchOffHeadlights()else Nav.control.switchOnHeadlights()end elseif iq=="forward"then B=B-1 elseif iq=="backward"then B=B+1 elseif iq=="left"then E=E-1 elseif iq=="right"then E=E+1 elseif iq=="yawright"then F=F-1 elseif iq=="yawleft"then F=F+1 elseif iq=="straferight"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,1.0)elseif iq=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,-1.0)elseif iq=="up"then Z=Z+1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,1.0)elseif iq=="down"then Z=Z-1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,-1.0)elseif iq=="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 iq=="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 iq=="option1"then IncrementAutopilotTargetIndex()v=false elseif iq=="option2"then DecrementAutopilotTargetIndex()v=false elseif iq=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;v=false;ToggleWidgets()elseif iq=="option4"then ToggleAutopilot()v=false elseif iq=="option5"then ToggleLockPitch()v=false elseif iq=="option6"then ToggleAltitudeHold()v=false elseif iq=="option7"then wipeSaveVariables()v=false elseif iq=="option8"then ToggleFollowMode()v=false elseif iq=="option9"then if gyro~=nil then gyro.toggle()ah=gyro.getState()==1 end;v=false elseif iq=="lshift"then if system.isViewLocked()==1 then J=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then J=true;b1=false;b0=false end elseif iq=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif iq=="lalt"then if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif iq=="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 iq=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()elseif iq=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)else IncrementAutopilotTargetIndex()end elseif iq=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)else DecrementAutopilotTargetIndex()end elseif iq=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(iq)if iq=="forward"then B=0 elseif iq=="backward"then B=0 elseif iq=="left"then E=0 elseif iq=="right"then E=0 elseif iq=="yawright"then F=0 elseif iq=="yawleft"then F=0 elseif iq=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)elseif iq=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)elseif iq=="up"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif iq=="down"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif iq=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif iq=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif iq=="lshift"then if system.isViewLocked()==1 then J=false;a0=0;a1=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then J=false;b1=false;b0=false end elseif iq=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif iq=="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(iq)if iq=="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 iq=="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 iq=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end elseif iq=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end;script.onStart() + ]],cu,bn,bo+dP,dM,bn,bo+dQ,dL))bE=bE+1;dC=dC*10;if dL==dF then dD=dN else dD=0 end end;table.insert(bG,[[]])end end;function DrawPrograde(bG,velocity,bh,centerX,centerY)if bh>5 and not ad or bh>w then local dh=circleRad;local dR=20;local dS=20;local dT=vec3(velocity)local dU=getRelativePitch(dT)local dV=getRelativeYaw(dT)local dW=-dV/dS*dh;local dX=dU/dR*dh;local bn=centerX+dW;local bo=centerY+dX;local a3=math.sqrt(dW^2+dX^2)if a3',bn,bo)else local dd=math.atan(dX,dW)local dY=centerX+dh*math.cos(dd)local dZ=centerY+dh*math.sin(dd)bG[#bG+1]=e('',dY,dZ)end;dU=getRelativePitch(-dT)dV=getRelativeYaw(-dT)dW=-dV/dS*dh;dX=dU/dR*dh;bn=centerX+dW;bo=centerY+dX;a3=math.sqrt(dW^2+dX^2)if not ad then if a3',bn,bo)else local dd=math.atan(dX,dW)local dY=centerX+dh*math.cos(dd)local dZ=centerY+dh*math.sin(dd)bG[#bG+1]=e('',dY,dZ)end end end end;function DrawWarnings(bG)bG[#bG+1]=e([[DU Hud Version: %.3f]],ConvertResolutionX(1900),ConvertResolutionY(1070),VERSION_NUMBER)bG[#bG+1]=[[]]if unit.isMouseControlActivated()==1 then bG[#bG+1]=e([[ + Warning: Invalid Control Scheme Detected]],ConvertResolutionX(960),ConvertResolutionY(550))bG[#bG+1]=e([[ + Keyboard Scheme must be selected]],ConvertResolutionX(960),ConvertResolutionY(600))bG[#bG+1]=e([[ + Set your preferred scheme in Lua Parameters instead]],ConvertResolutionX(960),ConvertResolutionY(650))end;local d_=ConvertResolutionX(960)local e0=ConvertResolutionY(860)local e1=ConvertResolutionY(880)local e2=ConvertResolutionY(900)local e3=ConvertResolutionY(960)local e4=ConvertResolutionY(200)local e5=ConvertResolutionY(150)local e6=ConvertResolutionY(960)if o()==1 and not RemoteHud then e0=ConvertResolutionY(135)e1=ConvertResolutionY(155)e2=ConvertResolutionY(175)e4=ConvertResolutionY(115)e5=ConvertResolutionY(95)end;if BrakeIsOn then bG[#bG+1]=e([[Brake Engaged]],d_,e0)end;if ad and RateOfChangebrakeLandingRate+5 then bG[#bG+1]=e([[** STALL WARNING **]],d_,e4+50)end;if ah then bG[#bG+1]=e([[Gyro Enabled]],d_,e6)end;if GearExtended then if A then bG[#bG+1]=e([[Gear Extended]],d_,e1)else bG[#bG+1]=e([[Landed (G: Takeoff)]],d_,e1)end;bG[#bG+1]=e([[Hover Height: %s]],d_,e2,getDistanceDisplayString(Nav:getTargetGroundAltitude()))end;if O then bG[#bG+1]=e([[ROCKET BOOST ENABLED]],d_,e3+20)end;if antigrav and not ExternalAGG and antigrav.getState()==1 and AntigravTargetAltitude~=nil then if math.abs(ae-antigrav.getBaseAltitude())<501 then bG[#bG+1]=e([[AGG On - Target Altitude: %d Singluarity Altitude: %d]],d_,e4+20,d(AntigravTargetAltitude),d(antigrav.getBaseAltitude()))else bG[#bG+1]=e([[AGG On - Target Altitude: %d Singluarity Altitude: %d]],d_,e4+20,d(AntigravTargetAltitude),d(antigrav.getBaseAltitude()))end elseif Autopilot and AutopilotTargetName~="None"then bG[#bG+1]=e([[Autopilot %s]],d_,e4+20,AutopilotStatus)elseif LockPitch~=nil then bG[#bG+1]=e([[LockedPitch: %d]],d_,e4+20,d(LockPitch))elseif I then bG[#bG+1]=e([[Follow Mode Engaged]],d_,e4+20)elseif Reentry then bG[#bG+1]=e([[Parachute Re-entry in Progress]],d_,e4+20)end;if AltitudeHold then if AutoTakeoff then bG[#bG+1]=e([[Ascent to %s]],d_,e4,getDistanceDisplayString(HoldAltitude))if BrakeIsOn then bG[#bG+1]=e([[Throttle Up and Disengage Brake For Takeoff]],d_,e4+50)end else bG[#bG+1]=e([[Altitude Hold: %s]],d_,e4,getDistanceDisplayString2(HoldAltitude))end end;if BrakeLanding then if StrongBrakes then bG[#bG+1]=e([[Brake-Landing]],d_,e4)else bG[#bG+1]=e([[Coast-Landing]],d_,e4)end end;if ProgradeIsOn then bG[#bG+1]=e([[Prograde Alignment]],d_,e4)end;if RetrogradeIsOn then bG[#bG+1]=e([[Retrograde Alignment]],d_,e4)end;if TurnBurn then bG[#bG+1]=e([[Turn & Burn Braking]],d_,e5)end;if VectorToTarget then bG[#bG+1]=e([[%s]],d_,e4+30,VectorStatus)end;bG[#bG+1]=""end;function DisplayOrbitScreen(bG)if orbit~=nil and j()<0.2 and planet~=nil and orbit.apoapsis~=nil and orbit.periapsis~=nil and orbit.period~=nil and orbit.apoapsis.speed>5 and DisplayOrbit then local e7=75;local e8=0;local e9=250;local ea=4;e8=e8+ea;local eb=15;local bn=e7+e9+e7/2+ea;local bo=e8+e9/2+5+ea;local ec,ed,ee,ef;ec=e9/4;ef=0;bG[#bG+1]=[[]]bG[#bG+1]=e('',e9+e7*2,e9+e8,ea,ea)if orbit.periapsis~=nil and orbit.apoapsis~=nil then ee=(orbit.apoapsis.altitude+orbit.periapsis.altitude+planet.radius*2)/(ec*2)ed=(planet.radius+orbit.periapsis.altitude+(orbit.apoapsis.altitude-orbit.periapsis.altitude)/2)/ee*(1-orbit.eccentricity)ef=ec-orbit.periapsis.altitude/ee-planet.radius/ee;local eg=""if orbit.periapsis.altitude<=0 then eg='redout'end;bG[#bG+1]=e([[]],eg,e7+e9/2+ef+ea,e8+e9/2+ea,ec,ed)bG[#bG+1]=e('',e7+e9/2+ea,e8+e9/2+ea,planet.radius/ee)end;if orbit.apoapsis~=nil and orbit.apoapsis.speed1 then bG[#bG+1]=e([[]],bn-35,bo-5,e7+e9/2+ec+ef,bo-5)bG[#bG+1]=e([[Apoapsis]],bn,bo)bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,getDistanceDisplayString(orbit.apoapsis.altitude))bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,FormatTimeString(orbit.timeToApoapsis))bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,getSpeedDisplayString(orbit.apoapsis.speed))end;bo=e8+e9/2+5+ea;bn=e7-e7/2+10+ea;if orbit.periapsis~=nil and orbit.periapsis.speed1 then bG[#bG+1]=e([[]],bn+35,bo-5,e7+e9/2-ec+ef,bo-5)bG[#bG+1]=e([[Periapsis]],bn,bo)bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,getDistanceDisplayString(orbit.periapsis.altitude))bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,FormatTimeString(orbit.timeToPeriapsis))bo=bo+eb;bG[#bG+1]=e([[%s]],bn,bo,getSpeedDisplayString(orbit.periapsis.speed))end;bG[#bG+1]=e([[%s]],e7+e9/2+ea,20+ea,planet.name)if orbit.period~=nil and orbit.periapsis~=nil and orbit.apoapsis~=nil and orbit.apoapsis.speed>1 then local eh=orbit.timeToApoapsis/orbit.period*2*math.pi;local ei=ec*math.cos(eh)local ej=ed*math.sin(eh)bG[#bG+1]=e('',e7+e9/2+ei+ef+ea,e8+e9/2+ej+ea)end;bG[#bG+1]=[[]]end end;function getDistanceDisplayString(a3)local ek=a3>100000;local b6=""if ek then b6=round(a3/1000/200,1).." SU"elseif a3<1000 then b6=round(a3,1).." M"else b6=round(a3/1000,1).." KM"end;return b6 end;function getDistanceDisplayString2(a3)local ek=a3>100000;local b6=""if ek then b6=round(a3/1000/200,2).." SU"elseif a3<1000 then b6=round(a3,2).." M"else b6=round(a3/1000,2).." KM"end;return b6 end;function getSpeedDisplayString(bh)return d(round(bh*3.6,0)+0.5).." km/h"end;function FormatTimeString(el)local em=0;local en=0;local eo=0;if el<60 then el=d(el)elseif el<3600 then em=d(el/60)el=d(el%60)elseif el<86400 then en=d(el/3600)em=d(el%3600/60)else eo=d(el/86400)en=d(el%86400/60)end;if eo>0 then return eo.."d "..en.."h "elseif en>0 then return en.."h "..em.."m "elseif em>0 then return em.."m "..el.."s"elseif el>0 then return el.."s"else return"0s"end end;function getMagnitudeInDirection(cw,ep)cw=vec3(cw)ep=vec3(ep):normalize()local b6=cw*ep;return b6.x+b6.y+b6.z end;function UpdateAutopilotTarget()if AutopilotTargetIndex==0 then AutopilotTargetName="None"V=nil;return true end;local eq=AtlasOrdered[AutopilotTargetIndex].index;local er=aS[0][eq]if er.center then AutopilotTargetName=er.name;V=aY[0][eq]if CustomTarget~=nil then if j()==0 then if system.updateData(widgetMaxBrakeTimeText,widgetMaxBrakeTime)~=1 then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;if system.updateData(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)~=1 then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;if system.updateData(widgetCurBrakeTimeText,widgetCurBrakeTime)~=1 then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;if system.updateData(widgetCurBrakeDistanceText,widgetCurBrakeDistance)~=1 then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;if system.updateData(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)~=1 then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end end;if system.updateData(widgetMaxMassText,widgetMaxMass)~=1 then system.addDataToWidget(widgetMaxMassText,widgetMaxMass)end;if system.updateData(widgetTravelTimeText,widgetTravelTime)~=1 then system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)end end;CustomTarget=nil else CustomTarget=er;for _,b5 in pairs(aY[0])do if b5.name==CustomTarget.planetname then V=b5;AutopilotTargetName=CustomTarget.name;break end end;if system.updateData(widgetMaxMassText,widgetMaxMass)~=1 then system.addDataToWidget(widgetMaxMassText,widgetMaxMass)end;if system.updateData(widgetTravelTimeText,widgetTravelTime)~=1 then system.addDataToWidget(widgetTravelTimeText,widgetTravelTime)end end;AutopilotTargetCoords=vec3(V.center)_,AutopilotEndSpeed=a_(V):escapeAndOrbitalSpeed(AutopilotTargetOrbit)AutopilotPlanetGravity=0;AutopilotAccelerating=false;AutopilotBraking=false;AutopilotCruising=false;Autopilot=false;AutopilotRealigned=false;AutopilotStatus="Aligning"return true end;function IncrementAutopilotTargetIndex()AutopilotTargetIndex=AutopilotTargetIndex+1;if AutopilotTargetIndex>#AtlasOrdered then AutopilotTargetIndex=0 end;UpdateAutopilotTarget()end;function DecrementAutopilotTargetIndex()AutopilotTargetIndex=AutopilotTargetIndex-1;if AutopilotTargetIndex<0 then AutopilotTargetIndex=#AtlasOrdered end;UpdateAutopilotTarget()end;function GetAutopilotMaxMass()local es=LastMaxBrakeInAtmo/V:getGravity(V.center+vec3(0,0,1)*V.radius):len()return es end;function GetAutopilotTravelTime()if not Autopilot then if CustomTarget==nil or CustomTarget.planetname~=planet.name then AutopilotDistance=(V.center-vec3(core.getConstructWorldPos())):len()else AutopilotDistance=(CustomTarget.position-vec3(core.getConstructWorldPos())):len()end end;local velocity=core.getWorldVelocity()local bh=vec3(velocity):len()local et,eu=aZ.computeDistanceAndTime(vec3(velocity):len(),MaxGameVelocity,n(),Nav:maxForceForward(),warmup,0)local P,Q;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(MaxGameVelocity)else P,Q=GetAutopilotTBBrakeDistanceAndTime(MaxGameVelocity)end;local _,ev;if not TurnBurn then _,ev=GetAutopilotBrakeDistanceAndTime(bh)else _,ev=GetAutopilotTBBrakeDistanceAndTime(bh)end;local ew=0;local ex=0;if AutopilotCruising or not Autopilot and bh>5 then ex=aZ.computeTravelTime(bh,0,AutopilotDistance)elseif P+et0 then return aZ.computeDistanceAndTime(bh,AutopilotEndSpeed,n(),0,0,LastMaxBrakeInAtmo-AutopilotPlanetGravity*n())else return 0,0 end end end;function GetAutopilotTBBrakeDistanceAndTime(bh)RefreshLastMaxBrake()return aZ.computeDistanceAndTime(bh,AutopilotEndSpeed,n(),Nav:maxForceForward(),warmup,LastMaxBrake-AutopilotPlanetGravity*n())end;function hoverDetectGround()local ez=-1;local eA=-1;if vBooster then ez=vBooster.distance()end;if hover then eA=hover.distance()end;if ez~=-1 and eA~=-1 then if ezProfileTimeMax then ProfileTimeMax=eG end;if eG0 then local eQ=eN:find('identifiedConstructs":%[%]')if eQ==nil and perisPanelID==nil then a6=1;ToggleRadarPanel()end;if eQ~=nil and perisPanelID~=nil then ToggleRadarPanel()end;if radarPanelID==nil then ToggleRadarPanel()end;a4=e([[Radar: %i contacts]],eO,eP,#eM)local eR={}for b4,b5 in pairs(eM)do if radar_1.hasMatchingTransponder(b5)==1 then eR[#eR+1]=b5 end end;if#eR>0 then local bo=ConvertResolutionY(15)local bn=ConvertResolutionX(1370)a4=e([[%sFriendlies In Range]],a4,bn,bo)for b4,b5 in pairs(eR)do bo=bo+20;a4=e([[%s%s]],a4,bn,bo,radar_1.getConstructName(b5))end end else local eS;eS=eN:find('worksInEnvironment":false')if eS then a4=e([[ + Radar: Jammed]],eO,eP)else a4=e([[ + Radar: No Contacts]],eO,eP)end;if radarPanelID~=nil then a6=0;ToggleRadarPanel()end end end end;function DisplayMessage(bG,eT)if eT~="empty"then bG[#bG+1]=[[]]for eU in string.gmatch(eT,"([^\n]+)")do bG[#bG+1]=e([[%s]],eU)end;bG[#bG+1]=[[]]end;if a2~=0 then unit.setTimer("msgTick",a2)a2=0 end end;function updateDistance()local bc=system.getTime()local velocity=vec3(core.getWorldVelocity())local cR=vec3(velocity):len()local eV=bc-ag;if cR>1.38889 then cR=cR/1000;local eW=cR*(bc-ag)TotalDistanceTravelled=TotalDistanceTravelled+eW;W=W+eW end;X=X+eV;TotalFlightTime=TotalFlightTime+eV;ag=bc end;function Atlas()return{[0]={[1]={GM=6930729684,bodyId=1,center={x=17465536.000,y=22665536.000,z=-34464.000},name='Madis',planetarySystemId=0,radius=44300,atmos=true,gravity=0.36},[2]={GM=157470826617,bodyId=2,center={x=-8.000,y=-8.000,z=-126303.000},name='Alioth',planetarySystemId=0,radius=126068,atmos=true,gravity=1.01},[3]={GM=11776905000,bodyId=3,center={x=29165536.000,y=10865536.000,z=65536.000},name='Thades',planetarySystemId=0,radius=49000,atmos=true,gravity=0.50},[4]={GM=14893847582,bodyId=4,center={x=-13234464.000,y=55765536.000,z=465536.000},name='Talemai',planetarySystemId=0,radius=57450,atmos=true,gravity=0.46},[5]={GM=16951680000,bodyId=5,center={x=-43534464.000,y=22565536.000,z=-48934464.000},name='Feli',planetarySystemId=0,radius=60000,atmos=true,gravity=0.48},[6]={GM=10502547741,bodyId=6,center={x=52765536.000,y=27165538.000,z=52065535.000},name='Sicari',planetarySystemId=0,radius=51100,atmos=true,gravity=0.41},[7]={GM=13033380591,bodyId=7,center={x=58665538.000,y=29665535.000,z=58165535.000},name='Sinnen',planetarySystemId=0,radius=54950,atmos=true,gravity=0.44},[8]={GM=18477723600,bodyId=8,center={x=80865538.000,y=54665536.000,z=-934463.940},name='Teoma',planetarySystemId=0,radius=62000,atmos=true,gravity=0.49},[9]={GM=18606274330,bodyId=9,center={x=-94134462.000,y=12765534.000,z=-3634464.000},name='Jago',planetarySystemId=0,radius=61590,atmos=true,gravity=0.50},[10]={GM=78480000,bodyId=10,center={x=17448118.224,y=22966846.286,z=143078.820},name='Madis Moon 1',planetarySystemId=0,radius=10000,atmos=false,gravity=0.08},[11]={GM=237402000,bodyId=11,center={x=17194626.000,y=22243633.880,z=-214962.810},name='Madis Moon 2',planetarySystemId=0,radius=11000,atmos=false,gravity=0.10},[12]={GM=265046609,bodyId=12,center={x=17520614.000,y=22184730.000,z=-309989.990},name='Madis Moon 3',planetarySystemId=0,radius=15005,atmos=false,gravity=0.12},[21]={GM=2118960000,bodyId=21,center={x=457933.000,y=-1509011.000,z=115524.000},name='Alioth Moon 1',planetarySystemId=0,radius=30000,atmos=false,gravity=0.24},[22]={GM=2165833514,bodyId=22,center={x=-1692694.000,y=729681.000,z=-411464.000},name='Alioth Moon 4',planetarySystemId=0,radius=30330,atmos=false,gravity=0.24},[26]={GM=68234043600,bodyId=26,center={x=-1404835.000,y=562655.000,z=-285074.000},name='Sanctuary',planetarySystemId=0,radius=83400,atmos=true,gravity=1.00},[30]={GM=211564034,bodyId=30,center={x=29214402.000,y=10907080.695,z=433858.200},name='Thades Moon 1',planetarySystemId=0,radius=14002,atmos=false,gravity=0.11},[31]={GM=264870000,bodyId=31,center={x=29404193.000,y=10432768.000,z=19554.131},name='Thades Moon 2',planetarySystemId=0,radius=15000,atmos=false,gravity=0.12},[40]={GM=141264000,bodyId=40,center={x=-13503090.000,y=55594325.000,z=769838.640},name='Talemai Moon 2',planetarySystemId=0,radius=12000,atmos=false,gravity=0.10},[41]={GM=106830900,bodyId=41,center={x=-12800515.000,y=55700259.000,z=325207.840},name='Talemai Moon 3',planetarySystemId=0,radius=11000,atmos=false,gravity=0.09},[42]={GM=264870000,bodyId=42,center={x=-13058408.000,y=55781856.000,z=740177.760},name='Talemai Moon 1',planetarySystemId=0,radius=15000,atmos=false,gravity=0.12},[50]={GM=499917600,bodyId=50,center={x=-43902841.780,y=22261034.700,z=-48862386.000},name='Feli Moon 1',planetarySystemId=0,radius=14000,atmos=false,gravity=0.11},[70]={GM=396912600,bodyId=70,center={x=58969616.000,y=29797945.000,z=57969449.000},name='Sinnen Moon 1',planetarySystemId=0,radius=17000,atmos=false,gravity=0.14},[100]={GM=13975172474,bodyId=100,center={x=98865536.000,y=-13534464.000,z=-934461.990},name='Lacobus',planetarySystemId=0,radius=55650,atmos=true,gravity=0.46},[101]={GM=264870000,bodyId=101,center={x=98905288.170,y=-13950921.100,z=-647589.530},name='Lacobus Moon 3',planetarySystemId=0,radius=15000,atmos=false,gravity=0.12},[102]={GM=444981600,bodyId=102,center={x=99180968.000,y=-13783862.000,z=-926156.400},name='Lacobus Moon 1',planetarySystemId=0,radius=18000,atmos=false,gravity=0.14},[103]={GM=211503600,bodyId=103,center={x=99250052.000,y=-13629215.000,z=-1059341.400},name='Lacobus Moon 2',planetarySystemId=0,radius=14000,atmos=false,gravity=0.11},[110]={GM=9204742375,bodyId=110,center={x=14165536.000,y=-85634465.000,z=-934464.300},name='Symeon',planetarySystemId=0,radius=49050,atmos=true,gravity=0.39},[120]={GM=7135606629,bodyId=120,center={x=2865536.700,y=-99034464.000,z=-934462.020},name='Ion',planetarySystemId=0,radius=44950,atmos=true,gravity=0.36},[121]={GM=106830900,bodyId=121,center={x=2472916.800,y=-99133747.000,z=-1133582.800},name='Ion Moon 1',planetarySystemId=0,radius=11000,atmos=false,gravity=0.09},[122]={GM=176580000,bodyId=122,center={x=2995424.500,y=-99275010.000,z=-1378480.700},name='Ion Moon 2',planetarySystemId=0,radius=15000,atmos=false,gravity=0.12}}}end;function SetupAtlas()aS=Atlas()for b4,b5 in pairs(aS[0])do if av==nil or b5.center.xaw then aw=b5.center.x end;if ax==nil or b5.center.yay then ay=b5.center.y end end;aT=""local eX=1.1*(aw-av)/1920;local eY=1.4*(ay-ax)/1080;for b4,b5 in pairs(aS[0])do local bn=960+b5.center.x/eX;local bo=540+b5.center.y/eY;aT=aT..''if not string.match(b5.name,"Moon")and not string.match(b5.name,"Sanctuary")then aT=aT..""..b5.name..""end end;local cV=vec3(core.getConstructWorldPos())local bn=960+cV.x/eX;local bo=540+cV.y/eY;aT=aT..''aT=aT.."You Are Here"aT=aT..[[]]aU=eX;aV=eY;if screen_2 then screen_2.setHTML(''..aT)local cV=vec3(core.getConstructWorldPos())local bn=960+cV.x/eX;local bo=540+cV.y/eY;aT=''aT=aT.."You Are Here"aW=screen_2.addContent((bn-80)/19.20,(bo-80)/10.80,aT)end end;function PlanetRef()local function eZ(e_)return type(e_)=='number'end;local function f0(e_)return type(tonumber(e_))=='number'end;local function f1(f2)return type(f2)=='table'end;local function f3(f4)return type(f4)=='string'end;local function f5(b5)return f1(b5)and eZ(b5.x and b5.y and b5.z)end;local function f6(f7)return f1(f7)and eZ(f7.latitude and f7.longitude and f7.altitude and f7.bodyId and f7.systemId)end;local f8=math.pi/180;local f9=180/math.pi;local fa=1e-10;local p=' *([+-]?%d+%.?%d*e?[+-]?%d*)'local fb='::pos{'..p..','..p..','..p..','..p..','..p..'}'local utils=require('cpml.utils')local vec3=require('cpml.vec3')local fc=utils.clamp;local function fd(fe,ff)if fe==0 then return math.abs(ff)<1e-09 end;if ff==0 then return math.abs(fe)<1e-09 end;return math.abs(fe-ff)=0 then local ga=math.sqrt(g9)local gb=g8+ga;local gc=g8-ga;if gc>0 then return f_,gb,gc elseif gb>0 then return f_,gb,nil end end end;return nil,nil,nil end;function fC:closestBody(gd)assert(type(gd)=='table','Invalid coordinates.')local ge,f_;local gf=vec3(gd)for _,gg in pairs(self)do local gh=(gg.center-gf):len2()if not f_ or gh=0 and gl or 2*math.pi+gl;fA=math.pi/2-math.acos(gk.z/a3)end;return setmetatable({latitude=fA,longitude=fB,altitude=cH,bodyId=self.bodyId,systemId=self.planetarySystemId},fw)end;function fl:convertToWorldCoordinates(fz)local gi=f3(fz)and fy(fz)or fz;if gi.bodyId==0 then return vec3(gi.latitude,gi.longitude,gi.altitude)end;assert(f6(gi),'Argument 1 (mapPosition) is not an instance of "MapPosition".')assert(gi.systemId==self.planetarySystemId,'Argument 1 (mapPosition) has a different planetary system ID.')assert(gi.bodyId==self.bodyId,'Argument 1 (mapPosition) has a different planetary body ID.')local gm=math.cos(gi.latitude)return self.center+(self.radius+gi.altitude)*vec3(gm*math.cos(gi.longitude),gm*math.sin(gi.longitude),math.sin(gi.latitude))end;function fl:getAltitude(fu)return(vec3(fu)-self.center):len()-self.radius end;function fl:getDistance(fu)return(vec3(fu)-self.center):len()end;function fl:getGravity(fu)local gn=self.center-vec3(fu)local go=gn:len2()return self.GM/go*gn/math.sqrt(go)end;return setmetatable(aX,{__call=function(_,...)return fK(...)end})end;function Keplers()local vec3=require('cpml.vec3')local PlanetRef=PlanetRef()local function f3(f4)return type(f4)=='string'end;local function f1(f2)return type(f2)=='table'end;local function fd(fe,ff)if fe==0 then return math.abs(ff)<1e-09 end;if ff==0 then return math.abs(fe)<1e-09 end;return math.abs(fe-ff)0 then gF=gE;gG=gF+gz/2 end;if gG>gz then gG=gG-gz end end;return{periapsis={position=gw,speed=gy/gu,circularOrbitSpeed=math.sqrt(gr/gu),altitude=gu-self.body.radius},apoapsis=gx and{position=gx,speed=gy/gv,circularOrbitSpeed=math.sqrt(gr/gv),altitude=gv-self.body.radius},currentVelocity=b5,currentPosition=cV,eccentricity=gt,period=gz,eccentricAnomaly=gB,meanAnomaly=gD,timeToPeriapsis=gF,timeToApoapsis=gG}end;local function gH(gI)local gg=PlanetRef.BodyParameters(gI.planetarySystemId,gI.bodyId,gI.radius,gI.center,gI.GM)return setmetatable({body=gg},Kepler)end;return setmetatable(Kepler,{__call=function(_,...)return gH(...)end})end;function Kinematics()local aZ={}local gJ=30000000/3600;local gK=gJ*gJ;local gL=100;local function gM(b5)return 1/math.sqrt(1-b5*b5/gK)end;function aZ.computeAccelerationTime(gN,gO,gP)local gQ=gJ*math.asin(gN/gJ)return(gJ*math.asin(gP/gJ)-gQ)/gO end;function aZ.computeDistanceAndTime(gN,gP,gR,gS,gT,gU)gT=gT or 0;gU=gU or 0;local gV=gN<=gP;local gW=gS*(gV and 1 or-1)/gR;local gX=-gU/gR;local gY=gW+gX;if gV and gY<=0 or not gV and gY>=0 then return-1,-1 end;local gZ,g_=0,0;if gW~=0 and gT>0 then local gQ=math.asin(gN/gJ)local h0=math.pi*(gW/2+gX)local h1=gW*gT;local h2=gJ*math.pi;local b5=function(f2)local c0=(h0*f2-h1*math.sin(math.pi*f2/2/gT)+h2*gQ)/h2;local h3=math.tan(c0)return gJ*h3/math.sqrt(h3*h3+1)end;local h4=gV and function(f4)return f4>=gP end or function(f4)return f4<=gP end;g_=2*gT;if h4(b5(g_))then local h5=0;while math.abs(g_-h5)>0.5 do local f2=(g_+h5)/2;if h4(b5(f2))then g_=f2 else h5=f2 end end end;local h6=gN;local h7=g_/gL;for h8=1,gL do local bh=b5(h8*h7)gZ=gZ+(bh+h6)*h7/2;h6=bh end;if g_<2*gT then return gZ,g_ end;gN=h6 end;local gQ=gJ*math.asin(gN/gJ)local b7=(gJ*math.asin(gP/gJ)-gQ)/gY;local h9=gK*math.cos(gQ/gJ)/gY;local a3=h9-gK*math.cos((gY*b7+gQ)/gJ)/gY;return a3+gZ,b7+g_ end;function aZ.computeTravelTime(gN,gO,a3)if a3==0 then return 0 end;if gO>0 then local gQ=gJ*math.asin(gN/gJ)local h9=gK*math.cos(gQ/gJ)/gO;return(gJ*math.acos(gO*(h9-a3)/gK)-gQ)/gO end;assert(gN>0,'Acceleration and initial speed are both zero.')return a3/gN end;function aZ.lorentz(b5)return gM(b5)end;return aZ end;function script.onStart()VERSION_NUMBER=4.920;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()a_=Keplers()AddLocationsToAtlas()UpdateAutopilotTarget()coroutine.yield()unit.hide()system.showScreen(1)collectgarbage("collect")unit.setTimer("apTick",apTickRate)unit.setTimer("oneSecond",1)unit.setTimer("tenthSecond",1/10)if UseSatNav then unit.setTimer("fiveSecond",5)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 bA=j()if door and(bA>0 or bA==0 and ae<10000)then for _,b5 in pairs(door)do b5.toggle()end end;if switch then for _,b5 in pairs(switch)do b5.toggle()end end;if forcefield and(bA>0 or bA==0 and ae<10000)then for _,b5 in pairs(forcefield)do b5.toggle()end end;if dbHud_1 then if not Y then for b4,b5 in pairs(b)do dbHud_1.setStringValue(b5,g(_G[b5]))end;for b4,b5 in pairs(a)do dbHud_1.setStringValue(b5,g(_G[b5]))end;c("Saved Variables to Datacore")end end;if button then button.activate()end end;function script.onTick(ha)if ha=="tenthSecond"then if AutopilotTargetName~="None"then if panelInterplanetary==nil then SetupInterplanetaryPanel()end;if AutopilotTargetName~=nil then local hb=CustomTarget~=nil;planetMaxMass=GetAutopilotMaxMass()system.updateData(interplanetaryHeaderText,'{"label": "Target", "value": "'..AutopilotTargetName..'", "unit":""}')travelTime=GetAutopilotTravelTime()if hb then a3=(vec3(core.getConstructWorldPos())-CustomTarget.position):len()else a3=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()end;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(velMag)R,S=GetAutopilotBrakeDistanceAndTime(MaxGameVelocity)else P,Q=GetAutopilotTBBrakeDistanceAndTime(velMag)R,S=GetAutopilotTBBrakeDistanceAndTime(MaxGameVelocity)end;system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..getDistanceDisplayString(a3)..'", "unit":""}')system.updateData(widgetTravelTimeText,'{"label": "Travel Time", "value": "'..FormatTimeString(travelTime)..'", "unit":""}')system.updateData(widgetCurBrakeDistanceText,'{"label": "Cur Brake distance", "value": "'..getDistanceDisplayString(P)..'", "unit":""}')system.updateData(widgetCurBrakeTimeText,'{"label": "Cur Brake Time", "value": "'..FormatTimeString(Q)..'", "unit":""}')system.updateData(widgetMaxBrakeDistanceText,'{"label": "Max Brake distance", "value": "'..getDistanceDisplayString(R)..'", "unit":""}')system.updateData(widgetMaxBrakeTimeText,'{"label": "Max Brake Time", "value": "'..FormatTimeString(S)..'", "unit":""}')system.updateData(widgetMaxMassText,'{"label": "Maximum Mass", "value": "'..e("%.2f tons",planetMaxMass/1000)..'", "unit":""}')if j()>0 and not WasInAtmo then system.removeDataFromWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)system.removeDataFromWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)system.removeDataFromWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)system.removeDataFromWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)system.removeDataFromWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)WasInAtmo=true end;if j()==0 and WasInAtmo then if system.updateData(widgetMaxBrakeTimeText,widgetMaxBrakeTime)==1 then system.addDataToWidget(widgetMaxBrakeTimeText,widgetMaxBrakeTime)end;if system.updateData(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)==1 then system.addDataToWidget(widgetMaxBrakeDistanceText,widgetMaxBrakeDistance)end;if system.updateData(widgetCurBrakeTimeText,widgetCurBrakeTime)==1 then system.addDataToWidget(widgetCurBrakeTimeText,widgetCurBrakeTime)end;if system.updateData(widgetCurBrakeDistanceText,widgetCurBrakeDistance)==1 then system.addDataToWidget(widgetCurBrakeDistanceText,widgetCurBrakeDistance)end;if system.updateData(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)==1 then system.addDataToWidget(widgetTrajectoryAltitudeText,widgetTrajectoryAltitude)end;WasInAtmo=false end end else HideInterplanetaryPanel()end;if warpdrive~=nil then if f(warpdrive.getData()).destination~="Unknown"and f(warpdrive.getData()).distance>400000 then warpdrive.show()showWarpWidget=true else warpdrive.hide()showWarpWidget=false end end elseif ha=="oneSecond"then ab=false;RefreshLastMaxBrake(nil,true)updateDistance()updateRadar()updateWeapons()local bG={}local cG=GetFlightStyle()DrawOdometer(bG,W,TotalDistanceTravelled,cG,X)CheckDamage(bG)a5=table.concat(bG,"")collectgarbage("collect")elseif ha=="fiveSecond"then ac=dbHud_1.getStringValue("SPBAutopilotTargetName")if ac~=nil and ac~=""and ac~="SatNavNotChanged"then local b6=json.decode(dbHud_1.getStringValue("SavedLocations"))if b6~=nil then _G["SavedLocations"]=b6;local bE=-1;local bz;for b4,b5 in pairs(SavedLocations)do if b5.name and b5.name=="SatNav Location"then bE=b4;break end end;if bE~=-1 then bz=SavedLocations[bE]bE=-1;for b4,b5 in pairs(aS[0])do if b5.name and b5.name=="SatNav Location"then bE=b4;break end end;if bE>-1 then aS[0][bE]=bz end;UpdateAtlasLocationsList()K=bz.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 ha=="msgTick"then local bG={}DisplayMessage(bG,"empty")K="empty"unit.stopTimer("msgTick")a2=3 elseif ha=="animateTick"then b1=true;b0=false;a0=0;a1=0;unit.stopTimer("animateTick")elseif ha=="apTick"then local o=o;RateOfChange=vec3(core.getConstructWorldOrientationForward()):dot(vec3(core.getWorldVelocity()):normalize())ad=j()>0;D=0;H=0;C=0;LastApsDiff=-1;velocity=vec3(core.getWorldVelocity())velMag=vec3(velocity):len()sys=aY[0]planet=sys:closestBody(core.getConstructWorldPos())kepPlanet=a_(planet)orbit=kepPlanet:orbitalParameters(core.getConstructWorldPos(),velocity)aa=hoverDetectGround()local hc=system.getMouseDeltaX()local hd=system.getMouseDeltaY()TargetGroundAltitude=Nav:getTargetGroundAltitude()local he=velMag>8334;if not he and LastIsWarping then if not BrakeIsOn then BrakeToggle()end;if Autopilot then ToggleAutopilot()end end;LastIsWarping=he;if ad and j()>0.09 then if not ai then if velMag>AtmoSpeedLimit/3.6 then BrakeIsOn=true;ai=true end else if velMag]],ResolutionX,ResolutionY)if K~="empty"then DisplayMessage(bG,K)end;if o()==0 and userControlScheme=="virtual joystick"then DrawDeadZone(bG)end;if o()==1 and screen_1 and screen_1.getMouseY()~=-1 then a0=screen_1.getMouseX()*ResolutionX;a1=screen_1.getMouseY()*ResolutionY;SetButtonContains()DrawButtons(bG)if screen_1.getMouseState()==1 then CheckButtons()end;bG[#bG+1]=e([[]],s,t,a0,a1)elseif system.isViewLocked()==0 then if o()==1 and J then if not b0 then a0=a0+hc;a1=a1+hd end;SetButtonContains()DrawButtons(bG)if not b0 and not b1 then local hf=table.concat(bG,"")bG={}bG[#bG+1]=e("",ResolutionX,ResolutionY)bG[#bG+1]=aT;bG[#bG+1]=hf;bG[#bG+1]=""b0=true;bG[#bG+1]=[[]]unit.setTimer("animateTick",0.5)local content=table.concat(bG,"")system.setScreen(content)elseif b1 then local hf=table.concat(bG,"")bG={}bG[#bG+1]=e("",ResolutionX,ResolutionY)bG[#bG+1]=aT;bG[#bG+1]=hf;bG[#bG+1]=""end;if not b0 then bG[#bG+1]=e([[]],s,t,a0,a1)end else CheckButtons()a0=0;a1=0 end else a0=a0+hc;a1=a1+hd;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 a1DeadZone then DrawCursorLine(bG)end else SetButtonContains()DrawButtons(bG)end;bG[#bG+1]=e([[]],s,t,a0,a1)end;bG[#bG+1]=[[]]content=table.concat(bG,"")if not DidLogOutput then system.logInfo(LastContent)DidLogOutput=true end;if ProgradeIsOn then if velMag>w then local hg=AlignToWorldVector(vec3(velocity),0.01)if a7 then b2=true;if hg then ProgradeIsOn=false;x=true;BeginReentry()a7=false;a9=true;b2=autoRollPreference end end end end;if RetrogradeIsOn then if ad then RetrogradeIsOn=false elseif velMag>w then AlignToWorldVector(-vec3(velocity))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 then local P,Q;if not TurnBurn then P,Q=GetAutopilotBrakeDistanceAndTime(velMag)else P,Q=GetAutopilotTBBrakeDistanceAndTime(velMag)end;P=P;Q=Q;local hh=AutopilotTargetCoords;if orbit.apoapsis==nil and velMag>300 and AutopilotAccelerating then local hi=(vec3(AutopilotTargetCoords)-vec3(core.getConstructWorldPos())):normalize()-vec3(velocity):normalize()local hj=getMagnitudeInDirection(hi,AutopilotShipUp)local hk=getMagnitudeInDirection(hi,AutopilotShipRight)local hl=-hk*AutopilotDistance*velMag*TrajectoryAlignmentStrength;local hm=-hj*AutopilotDistance*velMag*TrajectoryAlignmentStrength;hh=AutopilotTargetCoords+-hl*vec3(AutopilotShipRight)+-hm*vec3(AutopilotShipUp)end;AutopilotDistance=(vec3(hh)-vec3(core.getConstructWorldPos())):len()local hn=(AutopilotTargetCoords-vec3(core.getConstructWorldPos())):len()system.updateData(widgetDistanceText,'{"label": "distance", "value": "'..getDistanceDisplayString(hn)..'", "unit":""}')local ho=true;local hp=(V.center-(vec3(core.getConstructWorldPos())+vec3(velocity):normalize()*AutopilotDistance)):len()-V.radius;system.updateData(widgetTrajectoryAltitudeText,'{"label": "Projected Altitude", "value": "'..getDistanceDisplayString(hp)..'", "unit":""}')if not AutopilotCruising and not AutopilotBraking then ho=AlignToWorldVector((hh-vec3(core.getConstructWorldPos())):normalize())elseif TurnBurn then ho=AlignToWorldVector(-vec3(velocity):normalize())end;if AutopilotAccelerating then if not ho or BrakeIsOn then AutopilotStatus="Adjusting Trajectory"else AutopilotStatus="Accelerating"end;if vec3(core.getConstructWorldOrientationForward()):dot(velocity)<0 and velMag>300 then BrakeIsOn=true;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,0)u=false elseif not u then BrakeIsOn=false;Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal,AutopilotInterplanetaryThrottle)u=true end;if vec3(core.getVelocity()):len()>=MaxGameVelocity and math.abs(hp-AutopilotTargetOrbit)<1000 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 orbit.periapsis~=nil and orbit.eccentricity<1 then AutopilotStatus="Circularizing"if orbit.eccentricity>L or orbit.apoapsis.altitude0 then AutopilotAccelerating=true;AutopilotStatus="Accelerating"AutopilotCruising=false end else if ho then if not AutopilotRealigned then AutopilotTargetCoords=vec3(V.center)+(AutopilotTargetOrbit+V.radius)*vec3(core.getConstructWorldOrientationRight())AutopilotRealigned=true;AutopilotShipUp=core.getConstructWorldOrientationUp()AutopilotShipRight=core.getConstructWorldOrientationRight()elseif ho 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 b2=true;local hq=0;local cV=vec3(core.getConstructWorldPos())+vec3(unit.getMasterPlayerRelativePosition())local hr=cV-vec3(core.getConstructWorldPos())local hs=vec3(hr):project_on(vec3(core.getConstructWorldOrientationForward())):len()local ht=vec3(hr):project_on(vec3(core.getConstructWorldOrientationRight())):len()local a3=math.sqrt(hs*hs+ht*ht)AlignToWorldVector(hr:normalize())local hu=40;local hv=a3hy then if pitchPID==nil then pitchPID=pid.new(2*0.01,0,2*0.1)end;pitchPID:inject(hq-bM)local hz=pitchPID:get()C=hz end end;local de=vec3(core.getWorldVertical())*-1;if AltitudeHold or BrakeLanding or Reentry or VectorToTarget or LockPitch~=nil then local cU=unit.getClosestPlanetInfluence()>0;local cH=ae;local hA=HoldAltitude-cH;local hB=500+velMag;local hq=(utils.smoothstep(hA,-hB,hB)-0.5)*2*MaxPitch;if not AltitudeHold then hq=0 end;if LockPitch~=nil then if cU then hq=LockPitch else LockPitch=nil end end;b2=true;if Reentry then local hC=ReentrySpeed;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=hC then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,hC)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end;if not x then hq=-80;if j()>0.02 then K="PARACHUTE DEPLOYED"Reentry=false;BrakeLanding=true;hq=0;b2=autoRollPreference end elseif Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==ReentrySpeed then x=false;Reentry=false;b2=autoRollPreference end end;local hD=C;if velMag>w then AlignToWorldVector(vec3(velocity))end;if VectorToTarget and CustomTarget~=nil and AutopilotTargetIndex>0 then local cy=CustomTarget.position-vec3(core.getConstructWorldPos())AlignToWorldVector(cy)local hE=cy:len()-cy:project_on(de):len()local bi=LastMaxBrakeInAtmo;local dc=velocity.x*de.x+velocity.y*de.y+velocity.z*de.z;local hF=velocity:len()-math.abs(dc)local hG=vec3(core.getWorldAirFrictionAcceleration())if bi~=nil then P,Q=aZ.computeDistanceAndTime(hF,0,n(),0,0,bi+(hG:len()-hG:project_on(de):len())*n())else P,Q=aZ.computeDistanceAndTime(hF,0,n(),0,0,LastMaxBrake+vec3(core.getWorldAirFrictionAcceleration()):len()*n())end;StrongBrakes=planet.gravity*9.80665*n()LastTargetDistance and not AltitudeHold and not AutoTakeoff then BrakeLanding=true;VectorToTarget=false end;LastTargetDistance=hE end;C=hD;local bJ=vec3(core.getConstructWorldOrientationForward())local bK=vec3(core.getConstructWorldOrientationRight())local bL=vec3(core.getWorldVertical())local eB=-1;local bM=getPitch(bL,bJ,bK)local hy=0.1;if BrakeLanding then hq=0;if Nav.axisCommandManager:getAxisCommandType(0)==1 then Nav.control.cancelCurrentControlMasterMode()end;Nav.axisCommandManager:setTargetGroundAltitude(500)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(500)local dc=velocity.x*de.x+velocity.y*de.y+velocity.z*de.z;eB=aa;if eB>-1 then if math.abs(hq-bM)50000 then if Nav.axisCommandManager:getAxisCommandType(0)==0 then Nav.control.cancelCurrentControlMasterMode()end;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)~=5000 then Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.longitudinal,5000)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.vertical,0)Nav.axisCommandManager:setTargetSpeedCommand(axisCommandId.lateral,0)end end end;if math.abs(hq-bM)>hy then if pitchPID==nil then pitchPID=pid.new(8*0.01,0,8*0.1)end;pitchPID:inject(hq-bM)local hz=pitchPID:get()C=C+hz end end;L=orbit.eccentricity;if antigrav and not ExternalAGG and ae<200000 then if AntigravTargetAltitude==nil 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;local hH=2;pitchSpeedFactor=math.max(pitchSpeedFactor,0.01)yawSpeedFactor=math.max(yawSpeedFactor,0.01)rollSpeedFactor=math.max(rollSpeedFactor,0.01)hH=math.max(hH,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 hI=utils.clamp(B+C+system.getControlDeviceForwardInput(),-1,1)local hJ=utils.clamp(E+H+system.getControlDeviceYawInput(),-1,1)local hK=utils.clamp(F+D-system.getControlDeviceLeftRightInput(),-1,1)local hL=G;local hM=vec3(core.getWorldVertical())local hN=vec3(core.getConstructWorldOrientationUp())local hO=vec3(core.getConstructWorldOrientationForward())local hP=vec3(core.getConstructWorldOrientationRight())local hQ=vec3(core.getWorldVelocity())local hR=vec3(core.getWorldVelocity()):normalize()local hS=getRoll(hM,hO,hP)local hT=math.abs(hS)local hU=utils.sign(hS)local j=j()local hV=vec3(core.getWorldAngularVelocity())local hW=hI*pitchSpeedFactor*hP+hJ*rollSpeedFactor*hO+hK*yawSpeedFactor*hN;if hM:len()>0.01 and j>0.0 or ProgradeIsOn then local hX=1.0;if b2==true and hT>hX and hJ==0 then local hY=utils.clamp(0,hT-30,hT+30)if rollPID==nil then rollPID=pid.new(autoRollFactor*0.01,0,autoRollFactor*0.1)end;rollPID:inject(hY-hS)local hZ=rollPID:get()hW=hW+hZ*hO end end;if hM:len()>0.01 and j>0.0 then local h_=20.0;if turnAssist==true and hT>h_ and hI==0 and hK==0 then local i0=turnAssistFactor*0.1;local i1=turnAssistFactor*0.025;local i2=(hT-h_)/(180-h_)*180;local i3=0;if i2<90 then i3=i2/90 elseif i2<180 then i3=(180-i2)/90 end;i3=i3*i3;local i4=-hU*i1*(1.0-i3)local i5=i0*i3;hW=hW+i5*hP+i4*hN end end;local i6=1;local i7=0;local i8=1;local i9=hH*(hW-hV)local ia=vec3(core.getWorldAirFrictionAngularAcceleration())i9=i9-ia;Nav:setEngineTorqueCommand('torque',i9,i6,'airfoil','','',i8)local ib=-hL*(brakeSpeedFactor*hQ+brakeFlatFactor*hR)Nav:setEngineForceCommand('brake',ib)local ic=''local id=vec3()local ie=false;local ig='thrust analog longitudinal 'if ExtraLongitudeTags~="none"then ig=ig..ExtraLongitudeTags end;local ih=Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)if ih==axisCommandType.byThrottle then local ii=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ig,axisCommandId.longitudinal)Nav:setEngineForceCommand(ig,ii,i6)elseif ih==axisCommandType.byTargetSpeed then local ii=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)ic=ic..' , '..ig;id=id+ii;if Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)==0 or Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal)<-Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal)*0.5 then ie=true end end;local ij='thrust analog lateral 'if ExtraLateralTags~="none"then ij=ij..ExtraLateralTags end;local ik=Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)if ik==axisCommandType.byThrottle then local il=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(ij,axisCommandId.lateral)Nav:setEngineForceCommand(ij,il,i6)elseif ik==axisCommandType.byTargetSpeed then local im=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)ic=ic..' , '..ij;id=id+im end;local io='thrust analog vertical 'if ExtraVerticalTags~="none"then io=io..ExtraVerticalTags end;local ip=Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)if ip==axisCommandType.byThrottle then local iq=Nav.axisCommandManager:composeAxisAccelerationFromThrottle(io,axisCommandId.vertical)if Z~=0 or BrakeLanding and BrakeIsOn then Nav:setEngineForceCommand(io,iq,i6,'airfoil','ground','',i8)else Nav:setEngineForceCommand(io,vec3(),i6)Nav:setEngineForceCommand('airfoil vertical',iq,i6,'airfoil','','',i8)Nav:setEngineForceCommand('ground vertical',iq,i6,'ground','','',i8)end elseif ip==axisCommandType.byTargetSpeed then if Z==0 then Nav:setEngineForceCommand('hover',vec3(),i6)end;local ir=Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)ic=ic..' , '..io;id=id+ir end;if id:len()>constants.epsilon then if G~=0 or ie or math.abs(hR:dot(hO))<0.95 then ic=ic..', brake'end;Nav:setEngineForceCommand(ic,id,i7,'','','',i8)end;Nav:setBoosterCommand('rocket_engine')if O and not VanillaRockets then local bh=vec3(core.getVelocity()):len()local is=0.15;if Nav.axisCommandManager:getAxisCommandType(0)==1 then local it=Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)if bh*3.6>it*(1-is)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bh*3.6=hx*(1-is)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bh=hx*(1-is)and IsRocketOn then IsRocketOn=false;Nav:toggleBoosters()elseif bh0 or aew then K="WARNING: Insufficient Brakes - Attempting landing anyway"end;Reentry=false;AutoTakeoff=false;AltitudeHold=false;BrakeLanding=true;b2=true;GearExtended=false else BrakeIsOn=true;Nav.control.extendLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(LandingGearGroundHeight)end else Nav.control.retractLandingGears()Nav.axisCommandManager:setTargetGroundAltitude(TargetHoverHeight)end elseif iv=="light"then if Nav.control.isAnyHeadlightSwitchedOn()==1 then Nav.control.switchOffHeadlights()else Nav.control.switchOnHeadlights()end elseif iv=="forward"then B=B-1 elseif iv=="backward"then B=B+1 elseif iv=="left"then E=E-1 elseif iv=="right"then E=E+1 elseif iv=="yawright"then F=F-1 elseif iv=="yawleft"then F=F+1 elseif iv=="straferight"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,1.0)elseif iv=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral,-1.0)elseif iv=="up"then Z=Z+1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,1.0)elseif iv=="down"then Z=Z-1;Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical,-1.0)elseif iv=="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 iv=="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 iv=="option1"then IncrementAutopilotTargetIndex()v=false elseif iv=="option2"then DecrementAutopilotTargetIndex()v=false elseif iv=="option3"then if hideHudOnToggleWidgets then if showHud then showHud=false else showHud=true end end;v=false;ToggleWidgets()elseif iv=="option4"then ToggleAutopilot()v=false elseif iv=="option5"then ToggleLockPitch()v=false elseif iv=="option6"then ToggleAltitudeHold()v=false elseif iv=="option7"then wipeSaveVariables()v=false elseif iv=="option8"then ToggleFollowMode()v=false elseif iv=="option9"then if gyro~=nil then gyro.toggle()ah=gyro.getState()==1 end;v=false elseif iv=="lshift"then if system.isViewLocked()==1 then J=true;PrevViewLock=system.isViewLocked()system.lockView(1)elseif o()==1 and ShiftShowsRemoteButtons then J=true;b1=false;b0=false end elseif iv=="brake"then if BrakeToggleStatus then BrakeToggle()elseif not BrakeIsOn then BrakeToggle()else BrakeIsOn=true end elseif iv=="lalt"then if o()==0 and not freeLookToggle and userControlScheme=="keyboard"then system.lockView(1)end elseif iv=="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 iv=="stopengines"then Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)clearAll()elseif iv=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,speedChangeLarge)else IncrementAutopilotTargetIndex()end elseif iv=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal,-speedChangeLarge)else DecrementAutopilotTargetIndex()end elseif iv=="antigravity"and not ExternalAGG then if antigrav~=nil then ToggleAntigrav()end end end;function script.onActionStop(iv)if iv=="forward"then B=0 elseif iv=="backward"then B=0 elseif iv=="left"then E=0 elseif iv=="right"then E=0 elseif iv=="yawright"then F=0 elseif iv=="yawleft"then F=0 elseif iv=="straferight"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,-1.0)elseif iv=="strafeleft"then Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral,1.0)elseif iv=="up"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,-1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif iv=="down"then Z=0;Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical,1.0)Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)Nav:setEngineForceCommand('hover',vec3(),1)elseif iv=="groundaltitudeup"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif iv=="groundaltitudedown"then if antigrav and not ExternalAGG and antigrav.getState()==1 then N=OldAntiMod end;if AltitudeHold then M=OldButtonMod end;v=false elseif iv=="lshift"then if system.isViewLocked()==1 then J=false;a0=0;a1=0;system.lockView(PrevViewLock)elseif o()==1 and ShiftShowsRemoteButtons then J=false;b1=false;b0=false end elseif iv=="brake"then if not BrakeToggleStatus then if BrakeIsOn then BrakeToggle()else BrakeIsOn=false end end elseif iv=="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(iv)if iv=="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 iv=="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 iv=="speedup"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,speedChangeSmall)end elseif iv=="speeddown"then if not J then Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal,-speedChangeSmall)end end end;function script.onInputText(iw)local i;local ix="/commands /setname /G /agg /addlocation"local iy,iz;local iA="Command List:\n/commands \n/setname - Updates current selected saved position name\n/G VariableName newValue - Updates global variable to new value\n"iA=iA.."/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"i=string.find(iw," ")if i~=nil then iy=string.sub(iw,0,i-1)iz=string.sub(iw,i+1)elseif i==nil or not string.find(ix,iy)then for eU in string.gmatch(iA,"([^\n]+)")do c(eU)end;return end;if iy=="/setname"then if iz==nil or iz==""then K="Usage: /setname Newname"return end;if AutopilotTargetIndex>0 and CustomTarget~=nil then UpdatePosition(iz)else K="Select a saved target to rename first"end elseif iy=="/addlocation"then if iz==nil or iz==""or string.find(iz,"::")==nil then K="Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}"return end;i=string.find(iz,"::")local bw=string.sub(iz,1,i-2)i=string.find(iz,",")iz=string.sub(iz,i+1)local bV=string.find(iz,",")local bx=tonumber(string.sub(iz,1,bV-1))i=string.find(iz,",")iz=string.sub(iz,i+1)bV=string.find(iz,",")local bn=tonumber(string.sub(iz,1,bV-1))i=string.find(iz,",")iz=string.sub(iz,i+1)bV=string.find(iz,",")local bo=tonumber(string.sub(iz,1,bV-1))i=string.find(iz,",")iz=string.sub(iz,i+1)local by=tonumber(string.sub(iz,1,#iz-1))AddNewLocationByWaypoint(bw,bx,bn,bo,by)elseif iy=="/agg"then if iz==nil or iz==""then K="Usage: /agg targetheight"return end;iz=tonumber(iz)if iz<1000 then iz=1000 end;AntigravTargetAltitude=iz;K="AGG Target Height set to "..iz elseif iy=="/G"then if iz==nil or iz==""then K="Usage: /G VariableName variablevalue"return end;i=string.find(iz," ")local iB=string.sub(iz,0,i-1)local iC=string.sub(iz,i+1)for b4,b5 in pairs(a)do if b5==iB then K="Variable "..iB.." changed to "..iC;local iD=type(_G[b5])if iD=="number"then iC=tonumber(iC)elseif iD=="boolean"then if string.lower(iC)=="true"then iC=true else iC=false end end;_G[b5]=iC;return end end;K="No such global variable: "..iB end end;script.onStart() -- error handling code added by wrap.lua @@ -360,3 +363,9 @@ handlers: local ok, message = xpcall(script.onFlush,__wrap_lua__traceback,system) if not ok then __wrap_lua__error(message) end end + inputText(text): + lua: | + if not __wrap_lua__stopped and script.onInputText then + local ok, message = xpcall(script.onInputText,__wrap_lua__traceback,text,system) + if not ok then __wrap_lua__error(message) end + end diff --git a/ChangeLog.md b/ChangeLog.md index 573d30e..538850d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,18 @@ ## ChangeLog - Most recent changes at the top +Version 4.920 - Support for user input +- Implemented user text input. To use, hit tab and hit enter to send messages to Lua Chat. (this will not cause tab fps slideshow if the chat tab is open first) Currently supported commands: + - /commands - Shows command list and help + - /setname name - renames the current selected saved postion to "name" + - /G variablename value - changes the global variablename to new value, example /G AtmoSpeedLimit 1300 would set that user variable to 1300 or /G circleRad 100 would shrink the artifical horizon + - /agg height - Sets the AGG target height to height. Note that it must still move to this height at 4m/s like normal. + - /addlocation savename waypointpaste - Adds a new saved location based on waypoint. Not as accurate as going to location and using Save button. +- Added three new user variables for engine control (NOTE: if you fill these in, only engines on that axis that have the extra tags will fire): + - ExtraLongitudeTags = "none" -- export: Enter any extra longitudinal tags you use inside "" seperated by space, i.e. "forward faster major" These will be added to the engines that are control by longitude. + - ExtraLateralTags = "none" -- export: Enter any extra lateral tags you use inside "" seperated by space, i.e. "left right" These will be added to the engines that are control by lateral. + - ExtraVerticalTags = "none" -- export: Enter any extra longitudinal tags you use inside "" seperated by space, i.e. "up down" These will be added to the engines that are control by vertical. +- Fixed buttons not working in remote mode. + Version 4.914 - Fix versioning issue from 4.913 for some reason - Major refactor of function definitions outside of script.onStart() (users ignore this) diff --git a/README.md b/README.md index 37cd465..c5f40b3 100644 --- a/README.md +++ b/README.md @@ -28,39 +28,38 @@ | --- | --- | --- | Artificial horizon | Automatic braking | Brake-hold Altimeter | Autopilot to saved locations | Brake landings (brake force > construct mass) -Pitch | Inter-planetary transit routes |Coast landings (brake force < construct mass) -Roll | Orbital insertion | -Yaw | Transit-to-orbit | -Vertical speed indicator | | +Pitch | Inter-planetary transit routes | Coast landings (brake force < construct mass) +Roll | Orbital insertion | Auto-roll | +Yaw | Transit-to-orbit | Pitch lock | +Vertical speed indicator | LUA chat commands | -| Feature Detail / Additional Features | +| Feature Details / Additional Features | | --- | -|Brake indicator / toggle. Brake is now a toggle, and is on by default when entering the seat. There is an onscreen text indicator to show you when the brake is on. You can set brake to work like default with an Edit LUA Parameter setting.| -|Interplanetary Helper - Use __Alt-1__ and __Alt-2__ or __SHIFT-R__ / __SHIFT-T__ to cycle through target planets. Shows distance, travel time (including acceleration, travel, and braking - absolute total), brake time (current and max). Note that currently, Brake Time is inaccurate if you're inside atmosphere. Once you're in space, it will properly read the space brakes and give the correct values. Shows max mass for your ship on planet at sea level based on brakes. Note: If going to a planet with atmosphere, you must get the max mass reading while in atmosphere, and same if going to planet with no atmosphere.| -|Activate Gyyro - Use __Alt-9__ to toggle your placed gyro on and off. When a gyro is on, the ship's perceived orientation shifts to the gyro's orientation vice the core's orientation. So if you mount the gyro facing up, up becomes forward if the gyro is on (and forward down).| +|Brake indicator / toggle. Brake is now a toggle and is on by default when entering the seat. There is an onscreen text indicator to show you when the brake is on. The brake can be set to work like default with an Edit LUA Parameter setting.| +|Interplanetary Helper - Use __Alt-1__ and __Alt-2__ or __SHIFT-R__ / __SHIFT-T__ to cycle through target planets (incl. option SatNav locations). Shows distance, travel time (including acceleration, travel and braking - absolute total), brake time (current and max). Note that currently, Brake Time is inaccurate if you're inside atmosphere. Once you're in space, it will properly read the space brakes and give the correct values. Shows max mass for your ship on planet at sea level based on brakes. Note: If going to a planet with atmosphere, you must get the max mass reading while in atmosphere, and same if going to planet with no atmosphere.| +|Activate Gyyro - Use __Alt-9__ to toggle your placed gyro on and off. When a gyro is on, the ship's perceived orientation shifts to the gyro's orientation vice the core's orientation. So if you mount the gyro facing up, up becomes forward if the gyro is on (orientation of gyro is important, which determines which axis are pointing where).| |Dodgin's Don't Die Rocket Governor - Set your speed with cruise control and press __B__ to have your rocket engines fire up to that speed and no faster| |Auto-Land on Gear Down - Putting down your landing gear sets your hover height to 0, raising it sets it to max. Entering a vehicle with gear down sets the height to 0, entering a vehicle with the gear up sets it to max| -|Door/Ramp Automation - Automatically closes doors/ramps when entering, and opens them when exiting. Requires you to link these to the seat once, and it will remember and relink them each time you configure it afterward. No renaming required.| -|(ButtonHUD) Buttons and custom controls - Custom implementations of virtual joystick and mouse controls, allowing you to use virtual joystick without that disgusting giant circle on your screen. Buttons to use many of the features.| -|Atmospheric Package - Auto-Takeoff, Auto-Land, Altitude Hold, and for Remote Controllers, Follow Mode| -|Fuel Tanks - These are no longer automatically slotted to seat. You still get fuel readouts under the minimap. If you want the standard fuel widget, you will need to link the fuel tank(s) to the seat one time and then run the autoconfig.| -|AutoPilot - Use __Alt-4__ when you have a target selected with the Interplanetary Helper, and you are in space with clear line of sight to the target. The script will align to the optimal vector to place you in a 1SU orbit from the target, accelerate, cut engines when appropriate, and brake until orbit is achieved.| -|Glide Re-Entry - Recommend Before Activate: Align ship prograde and slow to 2000km/hr and be within 20km. Once activated: Ship will angle down to -30 degrees and accelerate(slow) to Re-Entry speed (1050km/hr default). Once the ship reaches Re-Entry Altitiude (2500m by default) it will attempt to level off into altitude hold at that height. If glide re-entry done as a part of saved location autopilot, the ship will then begin alignment and navigation to save point.| -|Parachute Re-Entry - Recommend before Activate: Be within 20-30km of planet. Be at a stop or less than 3000km/hr. Once Activated: Ship will angle down to -80 degrees and accelerate to 1050km/hr (re-entry speed). When atmosphere reaches 0.02, brake landing will activate.| +|Door/Ramp Automation - Automatically closes doors/ramps when entering and opens them when exiting. Requires you to link these to the seat once, and it will remember and relink them each time you configure it afterward. No renaming required.| +|(ButtonHUD) Buttons and custom controls - Custom implementations of virtual joystick and mouse controls, allowing you to use virtual joystick without that disgusting giant circle on your screen. Buttons to use many of the features. Buttons page appears when keeping __SHIFT__ pressed (not in freelook mode).| +|Atmospheric Package - Auto-Takeoff, Auto-Land, Altitude Hold and Follow Mode for Remote Controllers| +|Fuel Tanks - These are no longer automatically slotted to seat. You still get fuel readouts under the minimap. If you want the standard fuel widget, you will need to link the fuel tank(s) to the seat one time and then run the autoconfig. Autoconfig also needs to be run whenever the number of tanks changes in the construct.| +|AutoPilot - Use __Alt-4__ when you have a target selected with the Interplanetary Helper, and you are in space with clear line of sight to the target. The script will align to the optimal vector to place you in a 1 SU orbit from the target, accelerate, cut engines when appropriate, and brake until orbit is achieved.| +|Glide Re-Entry - Recommended before activate: align ship prograde and slow down to 2000km/hr and be within 20km. Once activated: ship will angle down to -30 degrees and accelerate(slow) to Re-Entry speed (1050km/hr default). Once the ship reaches Re-Entry Altitude (default: 2500m) it will attempt to level off into altitude hold at that height. If glide re-entry is done as part of a saved location autopilot, the ship will then begin alignment and navigation to saved waypoint.| +|Parachute Re-Entry - Recommend before activate: be within 20-30km of planet. Be at a stop or less than 3000km/hr. Once activated: Ship will angle down to -80 degrees and accelerate to 1050km/hr (re-entry speed). When atmosphere reaches 0.02, brake landing will activate.| |Trip odometers and information display.| |Fuel level displays for all types of fuel tanks. Ability to unslot fuel tanks to save slots.| |Altitude hold, pitch hold, auto-landing and takeoff functionality.| -|Orbital alignment and maneuver assistants and Orbital information widget which shows apoapsis, periapsis, apogee, perigee, eccentricity for the nearest planet, using these libraries: https://gitlab.com/JayleBreak/dualuniverse/-/tree/master/DUflightfiles/autoconf/custom | -|Radar and periscope for situational awareness.| -|Emergency Warp if target too close or has lock on you.| +|Orbital alignment and maneuver assistants and orbital information widget which shows apoapsis, periapsis, apogee, perigee, eccentricity for the nearest planet, using these libraries: https://gitlab.com/JayleBreak/dualuniverse/-/tree/master/DUflightfiles/autoconf/custom | +|Radar and periscope for situational awareness (only shown when applicable).| |Ability to hide the built-in display windows to keep your flight aesthetic clean and focused.| -|Free-look mode.| -|User Parameters for customizing to your HUD and your flight preference to your ship capabilities.| -|Save parameters between HUD version updates (requires databank).| -|Manual Control HotKey|Pressing Stop engines (__Z__ by default) 2x within 1 second will clear ALL AP / special functions. You will be at 0 engine in throttle mode with brakes off. (normal __Z__ behavior) but all special features like altitude hold, or brake landing or anything else will turn off. (Give me manual control key) Pressing it just once is normal vanilla stop all engines. NOTE: This will NOT turn off antigrav or stop a warp in progress. It does turn off emergency warp active.| -|Ability to change HUD colors (PrimaryR, PrimaryG, PrimaryB)| -|Stall Warning if your alignment drops below StallAngle (35 by default) - EVERY SHIP WILL BE DIFFERENT| +|Free-look mode (__ALT__ as toggle).| +|User Parameters for customization of your HUD elements (e.g. x/y screen position) and your flight preference to your ship capabilities.| +|Save parameters between HUD version updates (requires linking of a databank!).| +|Manual Control HotKey|Pressing Stop engines (__Z__ by default) 2x within 1 second will clear ALL AP / special functions. You will be at 0 engine in throttle mode with brakes off. (normal __Z__ behavior) but all special features like altitude hold or brake landing or anything else will turn off. (Give me manual control key) Pressing it just once is normal vanilla stop all engines. NOTE: This will NOT turn off antigrav or stop a warp in progress.| +|Ability to change HUD colors (RGB in PrimaryR, PrimaryG, PrimaryB)| +|Stall Warning if your alignment drops below configured StallAngle (35 by default) - EVERY SHIP WILL BE DIFFERENT!| [Return to Table of Contents](#table-of-contents) @@ -69,10 +68,10 @@ Vertical speed indicator | | ##### DISCLAIMER: We do not accept any responsibility for incorrect use of the autopilot, which may result in fiery reentry, mountain impacts or undesired entrance into PvP. Read and heed the warnings below! -##### :warning: Auto-Land - Use with supervision. Will only engage if brakes > mass. Uses brakes and hovers / vertical engines to lower you to a safe landing. +##### :warning: Auto-Land - Use with supervision. Will only engage if brakes > total mass. Uses brakes and hovers / vertical engines to lower you to a safe landing. ##### :warning: Autopilot (Space) - Not suitable for interplanetay trips less than 2SU. Ensure you have LOS (line of sight) to the target body before engaging as autopilot is direct flight and does not detect bodies (will fly into a planet / body if in between starting position and destination). ##### :warning: Autopilot to Saved Location - Accurate within roughly 15m of saved and selected location assuming a brake landing is available. If Coast Landing is displayed, you will need to resume control upon arrival at your destination. -##### :warning: Auto-Rentry - Not suitable for bodies without atmosphere. Not suitable for bodies with high altitudes (Thades, etc.). Know the altitude of the surface before using. __Alt-Space__ and/or __Alt-C__ may be used to adjust hover altitude as needed. +##### :warning: Auto-Rentry - Not suitable for bodies without atmosphere. Not suitable for bodies with high altitudes (Thades etc.). Know the altitude of the surface before using! __Alt-Space__ and/or __Alt-C__ may be used to adjust hover altitude as needed. [Return to Table of Contents](#table-of-contents) @@ -88,11 +87,11 @@ Vertical speed indicator | | ##### 1) Pre-installation Notes: ##### :black_small_square: Button - If manually connected to the seat, will be pressed when you enter (sit), and open / extend when you exit (stand). -##### :black_small_square: Databank - Although not required, we recommend a databank be used. This allows the HUD to save your user preferences and some long-term variables. In addition, flight status is saved if you leave and return to the seat. +##### :black_small_square: Databank - Although not required, we recommend a databank to be used. This allows the HUD to save your user preferences and some long-term variables. In addition, flight status is saved if you leave and return to the seat. ##### :black_small_square: Doors / Forcefields - If manually connected to the seat, will close / retract when you enter (sit), and open / extend when you exit (stand). Ensure they are closed / retracted before connecting to the seat. -##### :black_small_square: Fuel tanks - If _not_ manually connected provide a rough estimate of fuel levels. If manually connected, more accurate readings are provided and a non-HUD widget is updated. +##### :black_small_square: Fuel tanks - If _not_ manually connected provide a rough estimate of fuel levels (set parameters for fuel tank handling talent). If manually connected, more accurate readings are provided and a non-HUD widget is updated. -## 2) On the right side of this page, locate and click on "Releases" or select the "Release" listed as the latest. Detailed installation instructions are located there. +## 2) On the right side of this page, locate and click on "Releases" or select the "Release" listed as the latest. Detailed changelog and installation instructions are located there. ##### 3) Post-installation Note: ##### :black_small_square: This HUD uses on-screen buttons, and so needs to be able to use your mouse. The only way to keep DU from trying to use your mouse for input is to set the Control Scheme to Keyboard. You can then right click the seat, Advanced -> Edit LUA Parameters and find the checkboxes to choose which control scheme you would actually like to use. @@ -104,31 +103,31 @@ Vertical speed indicator | | | Item | Key(s) | Brief Description| | --- | --- | --- | -|UI Overlay|Hold __SHIFT__|Displays the UI overlay with mouseover buttons. Mouse over a button and let go of SHIFT to select it.| -|Toggle autopilot targets |Hold __SHIFT__, press __R__ or __T__ (speedup/speeddown)|Cycles through between autopilot targets.| -|Save Location|Hold __SHIFT__ then selecting the __Save Position__ mouseover| Will save the current location in the databank (if installed). This location may be selected by the autopilot option to automatically fly to the destination. It will _not_ monitor for impeeding structures or ships. Monitor during use.| -|Free Look|ALT|Toggles free-look. Please note that your view does not auto center when exiting Free Look. Free Look must be enabled to zoom in 3rd person mode.| +|UI Overlay|Hold __SHIFT__|Displays the UI overlay with mouse-over buttons. Hover with mouse over a button (not click!) and let go of SHIFT to select it.| +|Save Location|Hold __SHIFT__ then selecting the __Save Position__ mouseover| Will save the current location in the databank (if installed). This location may be selected by the autopilot option to automatically fly to the destination. It will _not_ monitor for impeeding structures or ships. Monitor during use. Locations will be named by planet/moon and a number.| +|Update Location|Hold __SHIFT__ then selecting the __Update Position__ mouseover| Select a previously saved location in the Interplanetary Helper to change its name with the name of the closest atmo radar target name. This is a workaround until manual editing/naming of locations is available.| +|Free Look|__ALT__|Toggles free-look mode (mouse moves camera around ship, not flight input). Please note that your view does not auto center when exiting Free Look. Free Look must be enabled to zoom in 3rd person mode.| |Autopilot Destination / Destination Select|__Option 1__ and __Option 2__,
__ALT-1__ and __ALT-2__ or
__SHIFT-R__ and __SHIFT-T__)|Cycles through autopilot destinations (planets / bodies / saved waypoints).| -|Toggle HUD|__Option 3__, or __ALT-3__|Toggles the primary hud display HUD on/off.| -|Autopilot|__Option 4__, or __ALT-4__|Ship will tilt up at preset max angle (30 by default) and fly to 100km then engage autopilot to selected planet. Once it arrives it will establish orbit and align prograde. If saved location chosen, it will glide entry in and then autopilot to location. NOTE: It does not check to see if anything is in front of you on ground (like normal) nor if your target planet is behind current planet even 100km in space. DO NOT USE if your ship cannot power out of atmosphere at 30 deg with 100% engines. USE WITH CAUTION FIRST TIME. Tested Alioth to Sanct and Sanct to Alioth repeatedly.| +|Toggle HUD|__Option 3__, or __ALT-3__|Toggles the primary hud display HUD on/off, i.e. if off the vanilla widgets will appear.| +|Autopilot|__Option 4__, or __ALT-4__|Ship will tilt up at preset max angle (30 by default) and fly to 50km altitude and then engage autopilot to selected planet/moon. Once it arrives it will establish orbit and align to prograde. If a saved location was chosen, it will glide entry in and then autopilot to location. NOTE: It does not check to see if anything is in front of you on ground (like normal) nor if your target planet is behind current planet even 50km in space. DO NOT USE if your ship cannot power out of atmosphere at 30 deg with 100% engines. USE WITH CAUTION FIRST TIME. Tested Alioth to Sanct and Sanct to Alioth repeatedly.| |Lock Pitch|__Option 5__, or __ALT-5__|Will lock your target pitch at current pitch and attempt to maintain that pitch (this is different from Altitude Hold) Most other AP features will cancel Lock Pitch. -|Altitude Hold|__Option 6__, or __ALT-6__|Toggle the altitude hold functionality. Set hold height with LALT-C (down) and LALT-SPACE (up).| -|Save / Clear Databank Settings|__Option 7__, or __ALT-7__|Save or clear the currently saved configuration settings.| +|Altitude Hold|__Option 6__, or __ALT-6__|Toggles the altitude hold functionality. Tries to keep the current altitude in spite of planetary curvatore. Depending on ship's lift/force, the actual height may be less than the targeted height! Adjust altitude with (left) __ALT-C__ (down) and (left) __ALT-SPACE__ (up) in increments (growing increments if key is kept held down).| +|Save / Clear Databank Settings|__Option 7__, or __ALT-7__|Save or clear (double tap!) the currently saved configuration settings.| |Follow Me|__Option 8__, or __ALT-8__|Engage follow mode if you are using Remote Control.| -|Anti-gravity Generator|__ALT-G__ (default mapping) or
HUD button|Once engaged, hold __ALT-C__ to lower target height or __ALT-Space__ to raise target height.| +|Anti-Gravity Generator|__ALT-G__ (default mapping) or
HUD button|Once engaged, hold __ALT-C__ to lower target height or __ALT-Space__ to raise target height. The AGG's actual height will only change at 4m/s up or down toward the target altitude. Initiate new target altitude before leaving seat and AGG will continue changing.| | Item | Detailed Description| | --- | --- | -|UI Overlay|Hold __SHIFT__ to show the UI overlay with buttons. Mouse over a button and let go of SHIFT to select it. While holding SHIFT, press R/T (speedup/speeddown) to cycle between autopilot targets.| +|UI Overlay|Hold __SHIFT__ to show the UI overlay with buttons (not in freelook!). Mouse over a button and let go of __SHIFT__ to select it (not clicking it). While holding SHIFT, press R/T (speedup/speeddown) to cycle between autopilot targets.| |Free Look|__ALT__ is now a toggle for free-look. Because of the way we had to use Keyboard mode, it can't re-center when you lock it back, but that can be desirable in some situations| |Autopilot Destination / Destination Select|__ALT-1__ and __ALT-2__ (__Option1__ and __Option2__) to scroll between target planets for Autopilot and display. This also works using SHIFT-R and SHIFT-T to scroll. This widget will not display if no planet is selected (ie you must press one of these hotkeys after entering the seat in order to show the widget)| |HUD Toggle|__ALT-3__ toggles the HUD and other widgets off/on. Orbital display and autopilot information will still show if HUD is off. There is a parameter you can set to have HUD and Widgets on at same time.| |Autopilot|__ALT-4__ to engage Autopilot for interplanetary travel, if you are in space and have a planet targeted. Ensure you have a clear line of sight to the target. This will align to the target, realign slightly to point 200km to the side of the target, accelerate, cut engines when at max, start braking when appropriate, and hopefully achieve a stable orbit around the target. You can set your target orbit distance in parameters, default is 100km. Recommend do not go less then 35km. -|Lock Pitch|__ALT-5__ (__Option 5__) will lock your your target pitch at current pitch and attempt to maintain that pitch (this is different from Altitude Hold) Most other AP features will cancel Lock Pitch.| -|Altitude Hold - |__ALT-6__ to toggle Altitude Hold. If used while flying (with gear up), this will attempt to hold at the altitude you turned it on at and put you in cruise control at current speed. You can modify target height with LALT+C (down) and LALT+spacebar (up). Cruise speed is modified like normal. Hitting ALT-6 again or tapping brake will stop Alt-Hold mode but leave you in cruise control. ALT-6 while landed (with gear down) to turn on Auto Takeoff - this is simply Altitude Hold that sets you to a paramater-defined distance above your starting position (default 1km). You must control your own thrust and release the brake to takeoff. G (Gear) is a very loaded key. While in atmosphere it will attempt to Brake Land if your brakes are strong enough (stop you and float to ground). If not it will attempt to coast land (angle down till slow enough and within hover/vbooster height then land). If in space it will initiate re-entry to a specific altitude (2500m by default) at a specific re-entry speed (1050km/hr default). You may modify the target values via Edit LUA Parameters, or use alt-C and alt-spacebar to lower and raise target height, and mousewheel to change target cruise speed.|MaxPitch affects all of the below, autotake off, landing, and re-entry. Default value is 20 degrees. +|Lock Pitch|__ALT-5__ (__Option 5__) will lock your pitch at current pitch and attempt to maintain that pitch (this is different from Altitude Hold) Most other AP features will cancel Lock Pitch.| +|Altitude Hold - |__ALT-6__ to toggle Altitude Hold. If used while flying (with gear up), this will attempt to hold at the altitude you turned it on at and put you in cruise control at current speed. You can modify target height with LALT+C (down) and LALT+spacebar (up). Cruise speed is modified like normal. Hitting ALT-6 again or tapping brake will stop Alt-Hold mode but leave you in cruise control. ALT-6 while landed (with gear down) to turn on Auto Takeoff - this is simply Altitude Hold that sets you to a paramater-defined distance above your starting position (default 1km). You must control your own thrust and release the brake to takeoff. G (Gear) is a very loaded key. While in atmosphere it will attempt to Brake Land if your brakes are strong enough (stop you and float to ground). If not it will attempt to coast land (angle down till slow enough and within hover/vbooster height then land). If in space it will initiate re-entry to a specific altitude (2500m by default) at a specific re-entry speed (1050km/hr default). You may modify the target values via Edit LUA Parameters, or use Alt-C and Alt-Spacebar to lower and raise target height, and mousewheel to change target cruise speed.|MaxPitch affects all of the below, autotake off, landing, and re-entry. Default value is 20 degrees. |Save/Clear Variables in Databank|__ALT-7__ to Wipe variables in a databank, you must press it a second time to confirm - Hitting __ALT-7__ 2x will wipe all data except saved locations from databank. To wipe saved locations you must select them as a target and then use Clear button shown while holding shift. Or you can pick up the databank, remove dynamic properties, and then put it back down, this clears everything from it.| |Follow Mode|__ALT-8__ will toggle Follow Mode when using a Remote Controller. This makes your craft lift off and try to follow you wherever you go. It will not go below ground unless you dig out a big enough hole that it would naturally go down while hovering.| -|Toggle Gyro|__ALT-9__ to engage Toggle Gyro. If a gyro is installed on your ship, this will change your ships perceived orientation from Core to Gyro. This is used to allow you to control flight based on gyro orientation and not core orientation. Auto-Brake is not on the UI this version; it is unreliable because it is unable to align your trajectory, and tends to over-brake if it's not perfectly aligned.| +|Toggle Gyro|__ALT-9__ to toggle a linked gyro on or off. If a gyro is installed on your ship, this will change your ships perceived orientation from Core to Gyro. This is used to allow you to control flight based on gyro orientation and not core orientation.| |Radar|Radar indicates below minimap number of targets or if it is jammed (atmosphere in space or space in atmosphere). The radar widget only pops up if targets are detected. The periscope widget only pops up if you click a target and successfully identify it. All widgets close automagically.| [Return to Table of Contents](#table-of-contents) diff --git a/scripts/wrap.lua b/scripts/wrap.lua index 810d98d..a62cac9 100644 --- a/scripts/wrap.lua +++ b/scripts/wrap.lua @@ -3413,7 +3413,7 @@ end filters = {"stop()", "tick(timerId)"} }, system = { - filters = {"actionStart(action)", "actionStop(action)", "actionLoop(action)", "update()", "flush()"} + filters = {"actionStart(action)", "actionStop(action)", "actionLoop(action)", "update()", "flush()", "inputText(text)"} }, library = {} } diff --git a/src/ButtonHUD.lua b/src/ButtonHUD.lua index 393273b..2eae37e 100644 --- a/src/ButtonHUD.lua +++ b/src/ButtonHUD.lua @@ -67,6 +67,9 @@ fuelTankHandlingSpace = 0 -- export: For accurate estimates, set this to the fue fuelTankHandlingRocket = 0 -- export: For accurate estimates, set this to the fuel tank handling level of the person who placed the element. Ignored for slotted tanks. ContainerOptimization = 0 -- export: For accurate estimates, set this to the Container Optimization level of the person who placed the tanks. Ignored for slotted tanks. FuelTankOptimization = 0 -- export: For accurate unslotted fuel tank calculation, set this to the fuel tank optimization skill level of the person who placed the tank. Ignored for slotted tanks. +ExtraLongitudeTags = "none" -- export: Enter any extra longitudinal tags you use inside '' seperated by space, i.e. "forward faster major" These will be added to the engines that are control by longitude. +ExtraLateralTags = "none" -- export: Enter any extra lateral tags you use inside '' seperated by space, i.e. "left right" These will be added to the engines that are control by lateral. +ExtraVerticalTags = "none" -- export: Enter any extra longitudinal tags you use inside '' seperated by space, i.e. "up down" These will be added to the engines that are control by vertical. ExternalAGG = false -- export: Toggle On if using an external AGG system. If on will prevent this HUD from doing anything with AGG. UseSatNav = false -- export: Toggle on if using Trog SatNav script. This will provide SatNav support. apTickRate = 0.0166667 -- export: Set the Tick Rate for your HUD. 0.016667 is effectively 60 fps and the default value. 0.03333333 is 30 fps. The bigger the number the less often the autopilot and hud updates but may help peformance on slower machings. @@ -120,7 +123,8 @@ local saveableVariables = {"userControlScheme", "AutopilotTargetOrbit", "apTickR "speedChangeLarge", "speedChangeSmall", "brightHud", "brakeLandingRate", "MaxPitch", "ReentrySpeed", "AtmoSpeedLimit", "ReentryAltitude", "centerX", "centerY", "vSpdMeterX", "vSpdMeterY", "altMeterX", "altMeterY", "fuelX","fuelY", "LandingGearGroundHeight", "TrajectoryAlignmentStrength", - "RemoteHud", "StallAngle", "ResolutionX", "ResolutionY", "UseSatNav", "FuelTankOptimization", "ContainerOptimization"} + "RemoteHud", "StallAngle", "ResolutionX", "ResolutionY", "UseSatNav", "FuelTankOptimization", "ContainerOptimization", + "ExtraLongitudeTags", "ExtraLateralTags", "ExtraVerticalTags"} local autoVariables = {"BrakeToggleStatus", "BrakeIsOn", "RetrogradeIsOn", "ProgradeIsOn", "Autopilot", "TurnBurn", "AltitudeHold", "DisplayOrbit", "BrakeLanding", @@ -131,6 +135,7 @@ local autoVariables = {"BrakeToggleStatus", "BrakeIsOn", "RetrogradeIsOn", "Prog "TotalFlightTime", "SavedLocations", "VectorToTarget", "LocationIndex", "LastMaxBrake", "LockPitch", "LastMaxBrakeInAtmo", "AntigravTargetAltitude", "LastStartTime"} + -- function localizations for improved performance when used frequently or in loops. local sprint = system.print local mfloor = math.floor @@ -250,6 +255,7 @@ local Kinematic = nil local Kep = nil local Animating = false local Animated = false +local autoRoll = autoRollPreference -- BEGIN FUNCTION DEFINITIONS @@ -294,17 +300,22 @@ function LoadVariables() if (LastStartTime + 180) < time then -- Variables to reset if out of seat (and not on hud) for more than 3 min LastMaxBrakeInAtmo = 0 end - halfResolutionX = round(ResolutionX / 2,0) - halfResolutionY = round(ResolutionY / 2,0) + if valuesAreSet then + halfResolutionX = round(ResolutionX / 2,0) + halfResolutionY = round(ResolutionY / 2,0) + resolutionWidth = ResolutionX + resolutionHeight = ResolutionY + BrakeToggleStatus = BrakeToggleDefault + userControlScheme = string.lower(userControlScheme) + autoRoll = autoRollPreference + end LastStartTime = time - BrakeToggleStatus = BrakeToggleDefault - userControlScheme = string.lower(userControlScheme) if string.find("keyboard virtual joystick mouse", userControlScheme) == nil then msgText = "Invalid User Control Scheme selected. Change userControlScheme in Lua Parameters to keyboard, mouse, or virtual joystick\nOr use shift and button in screen" msgTimer = 5 end MinimumRateOfChange = math.cos(StallAngle*constants.deg2rad) - autoRoll = autoRollPreference + if antigrav and not ExternalAGG then if AntigravTargetAltitude == nil then AntigravTargetAltitude = coreAltitude @@ -566,6 +577,36 @@ function AddLocationsToAtlas() -- Just called once during init really UpdateAtlasLocationsList() end +function AddNewLocationByWaypoint(savename, planetnumber, x, y, z) + if dbHud_1 then + local newLocation = {} + if planetnumber == 0 then + newLocation = { + position = vec3(x, y, z), + name = savename, + atmosphere = 0, + planetname = "Space", + gravity = 0 + } + else + local atmo + if atlas[0][planetnumber].atmos then atmo = 100 else atmo = 0 end + newLocation = { + position = vec3(x, y, z), + name = savename, + atmosphere = atmo, + planetname = atlas[0][planetnumber].name, + gravity = atlas[0][planetnumber].gravity + } + end + SavedLocations[#SavedLocations + 1] = newLocation + table.insert(atlas[0], newLocation) + UpdateAtlasLocationsList() + else + msgText = "Databank must be installed to save locations" + end +end + function AddNewLocation() -- Don't call this unless they have a databank or it's kinda pointless -- Add a new location to SavedLocations if dbHud_1 then @@ -596,25 +637,34 @@ function AddNewLocation() -- Don't call this unless they have a databank or it's end end -function UpdatePosition() +function UpdatePosition(newName) local index = -1 local newLocation for k, v in pairs(SavedLocations) do if v.name and v.name == CustomTarget.name then - --msgText = v.name .. " saved location cleared" index = k break end end if index ~= -1 then - newLocation = { - position = vec3(core.getConstructWorldPos()), - name = SavedLocations[index].name, - atmosphere = unit.getAtmosphereDensity(), - planetname = planet.name, - gravity = unit.getClosestPlanetInfluence() - } - + local updatedName + if newName ~= nil then + newLocation = { + position = SavedLocations[index].position, + name = newName, + atmosphere = SavedLocations[index].atmosphere, + planetname = SavedLocations[index].planetname, + gravity = SavedLocations[index].gravity + } + else + newLocation = { + position = vec3(core.getConstructWorldPos()), + name = SavedLocations[index].name, + atmosphere = unit.getAtmosphereDensity(), + planetname = planet.name, + gravity = unit.getClosestPlanetInfluence() + } + end SavedLocations[index] = newLocation index = -1 for k, v in pairs(atlas[0]) do @@ -627,6 +677,10 @@ function UpdatePosition() end UpdateAtlasLocationsList() msgText = CustomTarget.name .. " position updated" + AutopilotTargetIndex = 0 + UpdateAutopilotTarget() + else + msgText = "Name Not Found" end end @@ -4102,7 +4156,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 = 4.914 + VERSION_NUMBER = 4.920 SetupComplete = false beginSetup = coroutine.create(function() Nav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, @@ -4433,7 +4487,7 @@ function script.onTick(timerId) if not Animating and not Animated then local collapsedContent = table.concat(newContent, "") newContent = {} - newContent[#newContent + 1] = stringf("", ResolutionX, ResolutionY) + newContent[#newContent + 1] = stringf("", ResolutionX, ResolutionY) newContent[#newContent + 1] = GalaxyMapHTML newContent[#newContent + 1] = collapsedContent newContent[#newContent + 1] = "" @@ -5091,7 +5145,8 @@ function script.onFlush() local autoNavigationUseBrake = false -- Longitudinal Translation - local longitudinalEngineTags = 'thrust analog longitudinal' + 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( @@ -5113,7 +5168,8 @@ function script.onFlush() end -- Lateral Translation - local lateralStrafeEngineTags = 'thrust analog lateral' + 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( @@ -5126,7 +5182,8 @@ function script.onFlush() end -- Vertical Translation - local verticalStrafeEngineTags = 'thrust analog vertical' + 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( @@ -5551,4 +5608,91 @@ function script.onActionLoop(action) end end +function script.onInputText(text) + local i + local commands = "/commands /setname /G /agg /addlocation" + local command, arguement + local commandhelp = "Command List:\n/commands \n/setname - Updates current selected saved position name\n/G VariableName newValue - Updates global variable to new value\n" + commandhelp = commandhelp.."/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" + i = string.find(text, " ") + if i ~= nil then + command = string.sub(text, 0, i-1) + arguement = string.sub(text, i+1) + elseif i == nil or not string.find(commands, command) then + for str in string.gmatch(commandhelp, "([^\n]+)") do + sprint(str) + end + return + end + if command == "/setname" then + if arguement == nil or arguement == "" then + msgText = "Usage: /setname Newname" + return + end + if AutopilotTargetIndex > 0 and CustomTarget ~= nil then + UpdatePosition(arguement) + else + msgText = "Select a saved target to rename first" + end + elseif command == "/addlocation" then + if arguement == nil or arguement == "" or string.find(arguement, "::") == nil then + msgText = "Usage: /addlocation savename ::pos{0,2,46.4596,-155.1799,22.6572}" + return + end + i = string.find(arguement, "::") + local savename = string.sub(arguement, 1, i-2) + i = string.find(arguement, ",") + arguement = string.sub(arguement, i+1) + local j = string.find(arguement,",") + local planetnumber = tonumber(string.sub(arguement, 1, j-1)) + i = string.find(arguement, ",") + arguement = string.sub(arguement, i+1) + j = string.find(arguement,",") + local x = tonumber(string.sub(arguement, 1, j-1)) + i = string.find(arguement, ",") + arguement = string.sub(arguement, i+1) + j = string.find(arguement,",") + local y = tonumber(string.sub(arguement, 1, j-1)) + i = string.find(arguement, ",") + arguement = string.sub(arguement, i+1) + local z = tonumber(string.sub(arguement, 1, #arguement-1)) + AddNewLocationByWaypoint(savename, planetnumber, x, y, z) + elseif command == "/agg" then + if arguement == nil or arguement == "" then + msgText = "Usage: /agg targetheight" + return + end + arguement = tonumber(arguement) + if arguement < 1000 then arguement = 1000 end + AntigravTargetAltitude = arguement + msgText = "AGG Target Height set to "..arguement + elseif command == "/G" then + if arguement == nil or arguement == "" then + msgText = "Usage: /G VariableName variablevalue" + return + end + i = string.find(arguement, " ") + local globalVariableName = string.sub(arguement,0, i-1) + local newGlobalValue = string.sub(arguement,i+1) + for k, v in pairs(saveableVariables) do + if v == globalVariableName then + msgText = "Variable "..globalVariableName.." changed to "..newGlobalValue + local varType = type(_G[v]) + if varType == "number" then + newGlobalValue = tonumber(newGlobalValue) + elseif varType == "boolean" then + if string.lower(newGlobalValue) == "true" then + newGlobalValue = true + else + newGlobalValue = false + end + end + _G[v] = newGlobalValue + return + end + end + msgText = "No such global variable: "..globalVariableName + end +end + script.onStart()