[READ-ONLY] Mirror of https://github.com/thoda-dev/du-default-autoconf. default autoconfig files from Dual Universe
0

Configure Feed

Select the types of activity you want to include in your feed.

du v1.4

Thomas (Jun 20, 2023, 6:34 PM +0200) 5e53cfc3 31da2ef6

+8 -8
+1 -1
json/ecu/default.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\ncontainer = {}\ncontainer_size = 0\n-- End of auto-generated code\nNav = Navigator.new(system, core, unit)\nplanetInfluenceThreshold = 0.6\nif antigrav ~= nil then\n antigrav.activate()\n antigrav.show()\nend\n"}, {"key": "1", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "local verticalAutoLandingSpeed = 20 --export: Vertical auto landing speec in km/h\nlocal power = 3\nlocal worldUp = vec3(core.getConstructWorldOrientationUp())\nlocal worldForward = vec3(core.getConstructWorldOrientationForward())\nlocal worldRight = vec3(core.getConstructWorldOrientationRight())\nlocal worldVertical = vec3(core.getWorldVertical())\n\n-- are we in deep space or are we near a planet ?\nlocal planetInfluence = Nav.control.getClosestPlanetInfluence()\nif planetInfluence > 0\nthen\n -- stabilize orientation along the gravity\n if (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\n end\n\n local yawVelocity = vec3(core.getWorldAngularVelocity()):dot(worldUp)\n local currentRoll = getRoll(worldVertical, worldForward, worldRight)\n local currentPitch = -math.asin(worldForward:dot(worldVertical)) * constants.rad2deg\n rollPID:inject(-currentRoll)\n pitchPID:inject(-currentPitch)\n local yawAcceleration = - power * yawVelocity\n angularAcceleration = rollPID:get() * worldForward + pitchPID:get() * worldRight + yawAcceleration * worldUp\nelse\n -- cancel rotation\n local worldAngularVelocity = vec3(core.getWorldAngularVelocity())\n angularAcceleration = - power * worldAngularVelocity\nend\n\nif planetInfluence > planetInfluenceThreshold\nthen\n -- go down at verticalTargetSpeed when very close to a planet\n targetVelocity = (verticalAutoLandingSpeed / 3.6) * worldVertical\nelse\n -- immobilize ship when not\n targetVelocity = vec3()\nend\nNav:setEngineCommand('torque', vec3(), angularAcceleration)\nstabilization = power * (targetVelocity - vec3(core.getWorldVelocity()))\nNav:setEngineCommand('vertical, brake, horizontal', stabilization -vec3(core.getWorldGravity()), vec3(), false)\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "local accelThreshold = 0.1\nlocal speedThreshold = 0.1\n\n-- auto stopping mechanism when immobile and close to planet\nlocal accel = vec3(Nav.core.getWorldAcceleration()):len()\nlocal speed = vec3(Nav.core.getWorldVelocity()):len()\nif accel < accelThreshold\n and speed < speedThreshold\n and Nav.control.getClosestPlanetInfluence() > planetInfluenceThreshold\nthen\n unit.exit()\nend\n"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\ncontainer = {}\ncontainer_size = 0\n-- End of auto-generated code\nNav = Navigator.new(system, core, unit)\nplanetInfluenceThreshold = 0.6\nif antigrav ~= nil then\n antigrav.activate()\n antigrav.showWidget()\nend\n"}, {"key": "1", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "local verticalAutoLandingSpeed = 20 --export: Vertical auto landing speec in km/h\nlocal power = 3\nlocal worldUp = vec3(construct.getWorldOrientationUp())\nlocal worldForward = vec3(construct.getWorldOrientationForward())\nlocal worldRight = vec3(construct.getWorldOrientationRight())\nlocal worldVertical = vec3(core.getWorldVertical())\n\n-- are we in deep space or are we near a planet ?\nlocal planetInfluence = unit.getClosestPlanetInfluence()\nif planetInfluence > 0\nthen\n -- stabilize orientation along the gravity\n if (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\n end\n\n local yawVelocity = vec3(construct.getWorldAngularVelocity()):dot(worldUp)\n local currentRoll = getRoll(worldVertical, worldForward, worldRight)\n local currentPitch = -math.asin(worldForward:dot(worldVertical)) * constants.rad2deg\n rollPID:inject(-currentRoll)\n pitchPID:inject(-currentPitch)\n local yawAcceleration = - power * yawVelocity\n angularAcceleration = rollPID:get() * worldForward + pitchPID:get() * worldRight + yawAcceleration * worldUp\nelse\n -- cancel rotation\n local worldAngularVelocity = vec3(construct.getWorldAngularVelocity())\n angularAcceleration = - power * worldAngularVelocity\nend\n\nif planetInfluence > planetInfluenceThreshold\nthen\n -- go down at verticalTargetSpeed when very close to a planet\n targetVelocity = (verticalAutoLandingSpeed / 3.6) * worldVertical\nelse\n -- immobilize ship when not\n targetVelocity = vec3()\nend\nNav:setEngineCommand('torque', vec3(), angularAcceleration)\nstabilization = power * (targetVelocity - vec3(construct.getWorldVelocity()))\nNav:setEngineCommand('vertical, brake, horizontal', stabilization -vec3(core.getWorldGravity()), vec3(), false)\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "local accelThreshold = 0.1\nlocal speedThreshold = 0.1\n\n-- auto stopping mechanism when immobile and close to planet\nlocal accel = vec3(construct.getWorldAcceleration()):len()\nlocal speed = vec3(construct.getWorldVelocity()):len()\nif accel < accelThreshold\n and speed < speedThreshold\n and unit.getClosestPlanetInfluence() > planetInfluenceThreshold\nthen\n unit.exit()\nend\n"}], "methods": [], "events": []}
+1 -1
json/gunner_module/default.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- Proxy array to access auto-plugged slots programmatically\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "start()", "args": []}, "code": "-- Proxy array to access auto-plugged slots programmatically\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\n"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- Proxy array to access auto-plugged slots programmatically\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\n"}], "methods": [], "events": []}
+1 -1
json/hover_seat/flying.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif warpdrive ~= nil then warpdrive.show() end\nif gyro ~= nil then gyro.show() end\nif shield ~= nil then shield.show() end\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif warpdrive ~= nil then warpdrive.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(core.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif warpdrive ~= nil then warpdrive.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\nif shield ~= nil then shield.showWidget() end\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif warpdrive ~= nil then warpdrive.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(construct.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}
+1 -1
json/hover_seat/ground.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif gyro ~= nil then gyro.show() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif Nav.control.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() == 0 then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionLoop(backward)", "args": [{"value": "backward"}]}, "code": "loopDirection(direction.backward)"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "startBackward()"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "stopBackward()"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionLoop(forward)", "args": [{"value": "forward"}]}, "code": "loopDirection(direction.forward)"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "startForward()"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "stopForward()"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(up)", "args": [{"value": "up"}]}, "code": "if unit.isMouseControlActivated() == 0 then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() == 0 then\n jumpDelta = 0\nend\n"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = 0"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "40", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "loopDirection(direction.forward)"}, {"key": "41", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "startForward()"}, {"key": "42", "filter": {"slotKey": "-4", "signature": "onActionStop(speedup)", "args": [{"value": "speedup"}]}, "code": "stopForward()"}, {"key": "43", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "startBackward()"}, {"key": "44", "filter": {"slotKey": "-4", "signature": "onActionStop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "stopBackward()"}, {"key": "45", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "loopDirection(direction.backward)"}, {"key": "46", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}, "14": {"name": "slot15", "type": {"methods": [], "events": []}}, "15": {"name": "slot16", "type": {"methods": [], "events": []}}, "16": {"name": "slot17", "type": {"methods": [], "events": []}}, "17": {"name": "slot18", "type": {"methods": [], "events": []}}, "18": {"name": "slot19", "type": {"methods": [], "events": []}}, "19": {"name": "slot20", "type": {"methods": [], "events": []}}, "20": {"name": "slot21", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif unit.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionLoop(backward)", "args": [{"value": "backward"}]}, "code": "loopDirection(direction.backward)"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "startBackward()"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "stopBackward()"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionLoop(forward)", "args": [{"value": "forward"}]}, "code": "loopDirection(direction.forward)"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "startForward()"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "stopForward()"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(up)", "args": [{"value": "up"}]}, "code": "if unit.isMouseControlActivated() then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() then\n jumpDelta = 0\nend\n"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = 0"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "40", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "loopDirection(direction.forward)"}, {"key": "41", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "startForward()"}, {"key": "42", "filter": {"slotKey": "-4", "signature": "onActionStop(speedup)", "args": [{"value": "speedup"}]}, "code": "stopForward()"}, {"key": "43", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "startBackward()"}, {"key": "44", "filter": {"slotKey": "-4", "signature": "onActionStop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "stopBackward()"}, {"key": "45", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "loopDirection(direction.backward)"}, {"key": "46", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}
+1 -1
json/pilot_seat/flying.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif warpdrive ~= nil then warpdrive.show() end\nif gyro ~= nil then gyro.show() end\nif shield ~= nil then shield.show() end\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif warpdrive ~= nil then warpdrive.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(core.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif warpdrive ~= nil then warpdrive.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\nif shield ~= nil then shield.showWidget() end\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif warpdrive ~= nil then warpdrive.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(construct.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}
+1 -1
json/pilot_seat/ground.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif gyro ~= nil then gyro.show() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif Nav.control.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() == 0 then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionLoop(backward)", "args": [{"value": "backward"}]}, "code": "loopDirection(direction.backward)"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "startBackward()"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "stopBackward()"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionLoop(forward)", "args": [{"value": "forward"}]}, "code": "loopDirection(direction.forward)"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "startForward()"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "stopForward()"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(up)", "args": [{"value": "up"}]}, "code": "if unit.isMouseControlActivated() == 0 then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() == 0 then\n jumpDelta = 0\nend\n"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = 0"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "40", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "loopDirection(direction.forward)"}, {"key": "41", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "startForward()"}, {"key": "42", "filter": {"slotKey": "-4", "signature": "onActionStop(speedup)", "args": [{"value": "speedup"}]}, "code": "stopForward()"}, {"key": "43", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "startBackward()"}, {"key": "44", "filter": {"slotKey": "-4", "signature": "onActionStop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "stopBackward()"}, {"key": "45", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "loopDirection(direction.backward)"}, {"key": "46", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}, "10": {"name": "slot11", "type": {"methods": [], "events": []}}, "11": {"name": "slot12", "type": {"methods": [], "events": []}}, "12": {"name": "slot13", "type": {"methods": [], "events": []}}, "13": {"name": "slot14", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif unit.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionLoop(backward)", "args": [{"value": "backward"}]}, "code": "loopDirection(direction.backward)"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "startBackward()"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "stopBackward()"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionLoop(forward)", "args": [{"value": "forward"}]}, "code": "loopDirection(direction.forward)"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "startForward()"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "stopForward()"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(up)", "args": [{"value": "up"}]}, "code": "if unit.isMouseControlActivated() then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() then\n jumpDelta = 0\nend\n"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = 0"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "40", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "loopDirection(direction.forward)"}, {"key": "41", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "startForward()"}, {"key": "42", "filter": {"slotKey": "-4", "signature": "onActionStop(speedup)", "args": [{"value": "speedup"}]}, "code": "stopForward()"}, {"key": "43", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "startBackward()"}, {"key": "44", "filter": {"slotKey": "-4", "signature": "onActionStop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "stopBackward()"}, {"key": "45", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "loopDirection(direction.backward)"}, {"key": "46", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}
+1 -1
json/remote_control/flying.json
··· 1 - {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif warpdrive ~= nil then warpdrive.show() end\nif gyro ~= nil then gyro.show() end\nif shield ~= nil then shield.show() end\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif warpdrive ~= nil then warpdrive.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(core.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\nrollInput = 0\nyawInput = 0\nbrakeInput = 0\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {1000, 5000, 10000, 20000, 30000})\nNav.axisCommandManager:setTargetGroundAltitude(4)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif warpdrive ~= nil then warpdrive.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\nif shield ~= nil then shield.showWidget() end\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif warpdrive ~= nil then warpdrive.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu\n\nlocal pitchSpeedFactor = 0.8 --export: This factor will increase/decrease the player input along the pitch axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal yawSpeedFactor = 1 --export: This factor will increase/decrease the player input along the yaw axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal rollSpeedFactor = 1.5 --export: This factor will increase/decrease the player input along the roll axis<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 3 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 1 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal autoRoll = false --export: [Only in atmosphere]<br>When the pilot stops rolling, flight model will try to get back to horizontal (no roll)\nlocal autoRollFactor = 2 --export: [Only in atmosphere]<br>When autoRoll is engaged, this factor will increase to strength of the roll back to 0<br>Valid values: Superior or equal to 0.01\n\nlocal turnAssist = true --export: [Only in atmosphere]<br>When the pilot is rolling, the flight model will try to add yaw and pitch to make the construct turn better<br>The flight model will start by adding more yaw the more horizontal the construct is and more pitch the more vertical it is\nlocal turnAssistFactor = 2 --export: [Only in atmosphere]<br>This factor will increase/decrease the turnAssist effect<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\nlocal torqueFactor = 2 -- Force factor applied to reach rotationSpeed<br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\n\n-- validate params\npitchSpeedFactor = math.max(pitchSpeedFactor, 0.01)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nrollSpeedFactor = math.max(rollSpeedFactor, 0.01)\ntorqueFactor = math.max(torqueFactor, 0.01)\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nautoRollFactor = math.max(autoRollFactor, 0.01)\nturnAssistFactor = math.max(turnAssistFactor, 0.01)\n\n-- final inputs\nlocal finalPitchInput = pitchInput + system.getControlDeviceForwardInput()\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical()) -- along gravity\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentRollDegAbs = math.abs(currentRollDeg)\nlocal currentRollDegSign = utils.sign(currentRollDeg)\n\n-- Rotation\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal targetAngularVelocity = finalPitchInput * pitchSpeedFactor * constructRight\n + finalRollInput * rollSpeedFactor * constructForward\n + finalYawInput * yawSpeedFactor * constructUp\n\n-- In atmosphere?\nif worldVertical:len() > 0.01 and unit.getAtmosphereDensity() > 0.0 then\n local autoRollRollThreshold = 1.0\n -- autoRoll on AND currentRollDeg is big enough AND player is not rolling\n if autoRoll == true and currentRollDegAbs > autoRollRollThreshold and finalRollInput == 0 then\n local targetRollDeg = utils.clamp(0,currentRollDegAbs-30, currentRollDegAbs+30); -- we go back to 0 within a certain limit\n if (rollPID == nil) then\n rollPID = pid.new(autoRollFactor * 0.01, 0, autoRollFactor * 0.1) -- magic number tweaked to have a default factor in the 1-10 range\n end\n rollPID:inject(targetRollDeg - currentRollDeg)\n local autoRollInput = rollPID:get()\n\n targetAngularVelocity = targetAngularVelocity + autoRollInput * constructForward\n end\n local turnAssistRollThreshold = 20.0\n -- turnAssist AND currentRollDeg is big enough AND player is not pitching or yawing\n if turnAssist == true and currentRollDegAbs > turnAssistRollThreshold and finalPitchInput == 0 and finalYawInput == 0 then\n local rollToPitchFactor = turnAssistFactor * 0.1 -- magic number tweaked to have a default factor in the 1-10 range\n local rollToYawFactor = turnAssistFactor * 0.025 -- magic number tweaked to have a default factor in the 1-10 range\n\n -- rescale (turnAssistRollThreshold -> 180) to (0 -> 180)\n local rescaleRollDegAbs = ((currentRollDegAbs - turnAssistRollThreshold) / (180 - turnAssistRollThreshold)) * 180\n local rollVerticalRatio = 0\n if rescaleRollDegAbs < 90 then\n rollVerticalRatio = rescaleRollDegAbs / 90\n elseif rescaleRollDegAbs < 180 then\n rollVerticalRatio = (180 - rescaleRollDegAbs) / 90\n end\n\n rollVerticalRatio = rollVerticalRatio * rollVerticalRatio\n\n local turnAssistYawInput = - currentRollDegSign * rollToYawFactor * (1.0 - rollVerticalRatio)\n local turnAssistPitchInput = rollToPitchFactor * rollVerticalRatio\n\n targetAngularVelocity = targetAngularVelocity\n + turnAssistPitchInput * constructRight\n + turnAssistYawInput * constructUp\n end\nend\n\n-- Engine commands\nlocal keepCollinearity = 1 -- for easier reading\nlocal dontKeepCollinearity = 0 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal angularAcceleration = torqueFactor * (targetAngularVelocity - constructAngularVelocity)\nlocal airAcceleration = vec3(construct.getWorldAirFrictionAngularAcceleration())\nangularAcceleration = angularAcceleration - airAcceleration -- Try to compensate air friction\nNav:setEngineTorqueCommand('torque', angularAcceleration, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput + 1"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "pitchInput = pitchInput - 1"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, 1.0)\n"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, -1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(currentGroundAltitudeStabilization)\n"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, 5.0)"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, 1.0)"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, -5.0)"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, -1.0)"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}
+1 -1
json/remote_control/ground.json
··· 1 - {"slots":{"0":{"name":"core","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}}},"handlers":[{"code":"-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.show()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.show() end\nif gyro ~= nil then gyro.show() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif Nav.control.isRemoteControlled() == 1 then\n system.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"0"},{"code":"_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hide() end\nif gyro ~= nil then gyro.hide() end\ncore.hide()\nNav.control.switchOffHeadlights()\n","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"1"},{"code":"-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif Nav.control.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(core.getConstructWorldOrientationUp())\nlocal constructForward = vec3(core.getConstructWorldOrientationForward())\nlocal constructRight = vec3(core.getConstructWorldOrientationRight())\nlocal constructVelocity = vec3(core.getWorldVelocity())\nlocal constructVelocityDir = vec3(core.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(core.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n","filter":{"args":[],"signature":"onFlush()","slotKey":"-4"},"key":"2"},{"code":"Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() == 0 then\n local currentVelocity = vec3(self.core.getVelocity())\n local axisCRefDirection = vec3(self.core.getConstructOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"3"},{"code":"gearExtended = not gearExtended\nif gearExtended then\n Nav.control.extendLandingGears()\nelse\n Nav.control.retractLandingGears()\nend\n","filter":{"args":[{"value":"gear"}],"signature":"onActionStart(gear)","slotKey":"-4"},"key":"4"},{"code":"if Nav.control.isAnyHeadlightSwitchedOn() == 1 then\n Nav.control.switchOffHeadlights()\nelse\n Nav.control.switchOnHeadlights()\nend\n","filter":{"args":[{"value":"light"}],"signature":"onActionStart(light)","slotKey":"-4"},"key":"5"},{"code":"loopDirection(direction.backward)","filter":{"args":[{"value":"backward"}],"signature":"onActionLoop(backward)","slotKey":"-4"},"key":"6"},{"code":"startBackward()","filter":{"args":[{"value":"backward"}],"signature":"onActionStart(backward)","slotKey":"-4"},"key":"7"},{"code":"stopBackward()","filter":{"args":[{"value":"backward"}],"signature":"onActionStop(backward)","slotKey":"-4"},"key":"8"},{"code":"loopDirection(direction.forward)","filter":{"args":[{"value":"forward"}],"signature":"onActionLoop(forward)","slotKey":"-4"},"key":"9"},{"code":"startForward()","filter":{"args":[{"value":"forward"}],"signature":"onActionStart(forward)","slotKey":"-4"},"key":"10"},{"code":"stopForward()","filter":{"args":[{"value":"forward"}],"signature":"onActionStop(forward)","slotKey":"-4"},"key":"11"},{"code":"shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n","filter":{"args":[{"value":"lshift"}],"signature":"onActionStart(lshift)","slotKey":"-4"},"key":"12"},{"code":"shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n","filter":{"args":[{"value":"lshift"}],"signature":"onActionStop(lshift)","slotKey":"-4"},"key":"13"},{"code":"rollInput = rollInput - 1","filter":{"args":[{"value":"left"}],"signature":"onActionStart(left)","slotKey":"-4"},"key":"14"},{"code":"rollInput = rollInput + 1","filter":{"args":[{"value":"left"}],"signature":"onActionStop(left)","slotKey":"-4"},"key":"15"},{"code":"rollInput = rollInput + 1","filter":{"args":[{"value":"right"}],"signature":"onActionStart(right)","slotKey":"-4"},"key":"16"},{"code":"rollInput = rollInput - 1","filter":{"args":[{"value":"right"}],"signature":"onActionStop(right)","slotKey":"-4"},"key":"17"},{"code":"Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)","filter":{"args":[{"value":"straferight"}],"signature":"onActionStart(straferight)","slotKey":"-4"},"key":"18"},{"code":"Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)","filter":{"args":[{"value":"straferight"}],"signature":"onActionStop(straferight)","slotKey":"-4"},"key":"19"},{"code":"Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)","filter":{"args":[{"value":"strafeleft"}],"signature":"onActionStart(strafeleft)","slotKey":"-4"},"key":"20"},{"code":"Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)","filter":{"args":[{"value":"strafeleft"}],"signature":"onActionStop(strafeleft)","slotKey":"-4"},"key":"21"},{"code":"baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n","filter":{"args":[{"value":"up"}],"signature":"onActionStart(up)","slotKey":"-4"},"key":"22"},{"code":"if unit.isMouseControlActivated() == 0 then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n","filter":{"args":[{"value":"up"}],"signature":"onActionLoop(up)","slotKey":"-4"},"key":"23"},{"code":"Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() == 0 then\n jumpDelta = 0\nend\n","filter":{"args":[{"value":"up"}],"signature":"onActionStop(up)","slotKey":"-4"},"key":"24"},{"code":"Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n","filter":{"args":[{"value":"down"}],"signature":"onActionStart(down)","slotKey":"-4"},"key":"25"},{"code":"Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n","filter":{"args":[{"value":"down"}],"signature":"onActionStop(down)","slotKey":"-4"},"key":"26"},{"code":"Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)","filter":{"args":[{"value":"groundaltitudeup"}],"signature":"onActionStart(groundaltitudeup)","slotKey":"-4"},"key":"27"},{"code":"Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n","filter":{"args":[{"value":"groundaltitudeup"}],"signature":"onActionLoop(groundaltitudeup)","slotKey":"-4"},"key":"28"},{"code":"Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)","filter":{"args":[{"value":"groundaltitudedown"}],"signature":"onActionStart(groundaltitudedown)","slotKey":"-4"},"key":"29"},{"code":"Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)","filter":{"args":[{"value":"groundaltitudedown"}],"signature":"onActionLoop(groundaltitudedown)","slotKey":"-4"},"key":"30"},{"code":"yawInput = yawInput - 1","filter":{"args":[{"value":"yawright"}],"signature":"onActionStart(yawright)","slotKey":"-4"},"key":"31"},{"code":"yawInput = yawInput + 1","filter":{"args":[{"value":"yawright"}],"signature":"onActionStop(yawright)","slotKey":"-4"},"key":"32"},{"code":"yawInput = yawInput + 1","filter":{"args":[{"value":"yawleft"}],"signature":"onActionStart(yawleft)","slotKey":"-4"},"key":"33"},{"code":"yawInput = yawInput - 1","filter":{"args":[{"value":"yawleft"}],"signature":"onActionStop(yawleft)","slotKey":"-4"},"key":"34"},{"code":"brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n","filter":{"args":[{"value":"brake"}],"signature":"onActionStart(brake)","slotKey":"-4"},"key":"35"},{"code":"brakeInput = 0","filter":{"args":[{"value":"brake"}],"signature":"onActionStop(brake)","slotKey":"-4"},"key":"36"},{"code":"local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n","filter":{"args":[{"value":"brake"}],"signature":"onActionLoop(brake)","slotKey":"-4"},"key":"37"},{"code":"Nav:toggleBoosters()","filter":{"args":[{"value":"booster"}],"signature":"onActionStart(booster)","slotKey":"-4"},"key":"38"},{"code":"Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)","filter":{"args":[{"value":"stopengines"}],"signature":"onActionStart(stopengines)","slotKey":"-4"},"key":"39"},{"code":"loopDirection(direction.forward)","filter":{"args":[{"value":"speedup"}],"signature":"onActionLoop(speedup)","slotKey":"-4"},"key":"40"},{"code":"startForward()","filter":{"args":[{"value":"speedup"}],"signature":"onActionStart(speedup)","slotKey":"-4"},"key":"41"},{"code":"stopForward()","filter":{"args":[{"value":"speedup"}],"signature":"onActionStop(speedup)","slotKey":"-4"},"key":"42"},{"code":"startBackward()","filter":{"args":[{"value":"speeddown"}],"signature":"onActionStart(speeddown)","slotKey":"-4"},"key":"43"},{"code":"stopBackward()","filter":{"args":[{"value":"speeddown"}],"signature":"onActionStop(speeddown)","slotKey":"-4"},"key":"44"},{"code":"loopDirection(direction.backward)","filter":{"args":[{"value":"speeddown"}],"signature":"onActionLoop(speeddown)","slotKey":"-4"},"key":"45"},{"code":"if antigrav ~= nil then antigrav.toggle() end","filter":{"args":[{"value":"antigravity"}],"signature":"onActionStart(antigravity)","slotKey":"-4"},"key":"46"}],"methods":[],"events":[]} 1 + {"slots": {"-1": {"name": "unit", "type": {"methods": [], "events": []}}, "-3": {"name": "player", "type": {"methods": [], "events": []}}, "-2": {"name": "construct", "type": {"methods": [], "events": []}}, "-4": {"name": "system", "type": {"methods": [], "events": []}}, "0": {"name": "core", "type": {"methods": [], "events": []}}, "-5": {"name": "library", "type": {"methods": [], "events": []}}, "1": {"name": "slot2", "type": {"methods": [], "events": []}}, "2": {"name": "slot3", "type": {"methods": [], "events": []}}, "3": {"name": "slot4", "type": {"methods": [], "events": []}}, "4": {"name": "slot5", "type": {"methods": [], "events": []}}, "5": {"name": "slot6", "type": {"methods": [], "events": []}}, "6": {"name": "slot7", "type": {"methods": [], "events": []}}, "7": {"name": "slot8", "type": {"methods": [], "events": []}}, "8": {"name": "slot9", "type": {"methods": [], "events": []}}, "9": {"name": "slot10", "type": {"methods": [], "events": []}}}, "handlers": [{"key": "0", "filter": {"slotKey": "-1", "signature": "onStart()", "args": []}, "code": "-- category panel display helpers\n_autoconf = {}\n_autoconf.panels = {}\n_autoconf.panels_size = 0\n_autoconf.displayCategoryPanel = function(elements, size, title, type, widgetPerData)\n widgetPerData = widgetPerData or false -- default to one widget for all data\n if size > 0 then\n local panel = system.createWidgetPanel(title)\n local widget\n if not widgetPerData then\n widget = system.createWidget(panel, type)\n end\n for i = 1, size do\n if widgetPerData then\n widget = system.createWidget(panel, type)\n end\n system.addDataToWidget(elements[i].getWidgetDataId(), widget)\n end\n _autoconf.panels_size = _autoconf.panels_size + 1\n _autoconf.panels[_autoconf.panels_size] = panel\n end\nend\n_autoconf.hideCategoryPanels = function()\n for i=1,_autoconf.panels_size do\n system.destroyWidgetPanel(_autoconf.panels[i])\n end\nend\n-- Proxy array to access auto-plugged slots programmatically\n\natmofueltank = {}\natmofueltank_size = 0\n\nspacefueltank = {}\nspacefueltank_size = 0\n\nrocketfueltank = {}\nrocketfueltank_size = 0\n\nweapon = {}\nweapon_size = 0\n\nradar = {}\nradar_size = 0\n-- End of auto-generated code\npitchInput = 0\npitchInputFromDevice = 0\nrollInput = 0\nyawInput = 0\nverticalStrafeInput = 0\nlateralStrafeInput = 0\nbrakeInput = 0\ngoingBack = false\ngoingForward = false\nshiftPressed = false\njumpDelta = 0\nbaseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g\n\nNav = Navigator.new(system, core, unit)\nNav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})\nNav.axisCommandManager:setTargetGroundAltitude(6)\n\n-- Parenting widget\nparentingPanelId = system.createWidgetPanel(\"Docking\")\nparentingWidgetId = system.createWidget(parentingPanelId,\"parenting\")\nsystem.addDataToWidget(unit.getWidgetDataId(),parentingWidgetId)\n\n-- Combat stress widget\ncoreCombatStressPanelId = system.createWidgetPanel(\"Core combat stress\")\ncoreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,\"core_stress\")\nsystem.addDataToWidget(core.getWidgetDataId(),coreCombatStressgWidgetId)\n\n-- element widgets\n-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.\n_autoconf.displayCategoryPanel(weapon, weapon_size, \"Weapons\", \"weapon\", true)\ncore.showWidget()\n_autoconf.displayCategoryPanel(radar, radar_size, \"Periscope\", \"periscope\")\nplaceRadar = true\nif atmofueltank_size > 0 then\n _autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, \"Atmo Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\nif spacefueltank_size > 0 then\n _autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, \"Space Fuel\", \"fuel_container\")\n if placeRadar then\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\n end\nend\n_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, \"Rocket Fuel\", \"fuel_container\")\nif placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels\n _autoconf.displayCategoryPanel(radar, radar_size, \"Radar\", \"radar\")\n placeRadar = false\nend\nif antigrav ~= nil then antigrav.showWidget() end\nif gyro ~= nil then gyro.showWidget() end\n\nthrottleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle<br>Valid values: From 0.01 to 1\nthrottleStep = utils.clamp(throttleStep, 0.01, 1)\n\n-- freeze the player in he is remote controlling the construct\nif unit.isRemoteControlled() then\n player.freeze(1)\nend\n\n-- landing gear\n-- make sure every gears are synchonized with the first\ngearExtended = unit.isAnyLandingGearDeployed()\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n\n-- forward/backward functions\nstartForward = function ()\n if Nav:isTravelMode() then\n brakeInput = 0\n local throttle = 1\n if not shiftPressed then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n end\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingForward = true\n end\nend\n\nstopForward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingForward = false\n if goingBackward then\n startBackward()\n end\n end\nend\n\ndirection = {forward=1, backward = -1}\nloopDirection = function (direction)\n if Nav:isTravelMode() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n\n lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)\n\n if (lastCurrentSpeed * direction < 0) then\n brakeInput = 1\n autobrake = true\n else\n if autobrake == true then\n autobrake = false\n brakeInput = 0\n end\n end\n else\n Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)\n end\nend\n\nstartBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n brakeInput = 0\n\n local maxGBackward = Nav:maxForceBackward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)\n\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\n goingBack = true\n end\nend\n\nstopBackward = function ()\n if Nav:isTravelMode() then\n pitchInput = 0\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)\n brakeInput = 0.5\n goingBack = false\n if goingForward then\n startForward()\n end\n end\nend\n"}, {"key": "1", "filter": {"slotKey": "-1", "signature": "onStop()", "args": []}, "code": "_autoconf.hideCategoryPanels()\nif antigrav ~= nil then antigrav.hideWidget() end\nif gyro ~= nil then gyro.hideWidget() end\ncore.hideWidget()\nunit.switchOffHeadlights()\n"}, {"key": "2", "filter": {"slotKey": "-4", "signature": "onFlush()", "args": []}, "code": "-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu<br>in degree<br>Valid values: Superior or equal to 1\nlocal rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude<br>in degree<br>Valid values: Superior or equal to 1\nlocal pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)\nlocal yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\nlocal yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor<br>Valid values: Superior or equal to 0.01\n\nlocal lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines<br>Valid values: Superior or equal to 0.01\nlocal lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis<br>Valid values: Superior or equal to 0.01\n\nlocal brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity<br>Valid values: Superior or equal to 0.01\nlocal brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction><br>(higher value may be unstable)<br>Valid values: Superior or equal to 0.01\nlocal autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust\n\n-- validate params\nbrakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)\nbrakeFlatFactor = math.max(brakeFlatFactor, 0.01)\nrollAmplitude = math.max(rollAmplitude, 1)\npitchAmplitude = math.max(pitchAmplitude, 1)\nyawSpeedFactor = math.max(yawSpeedFactor, 0.01)\nyawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)\n\nif (rollPID == nil) then\n rollPID = pid.new(0.2, 0, 10)\n pitchPID = pid.new(0.2, 0, 10)\nend\n\n-- final inputs\nif unit.isMouseDirectControlActivated() then\n -- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control\n -- this helps a lot for ground construct control\n pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)\nelse\n pitchInputFromDevice = system.getControlDeviceForwardInput()\nend\nlocal finalPitchInput = pitchInput + pitchInputFromDevice\nlocal finalRollInput = rollInput + system.getControlDeviceYawInput()\nlocal finalYawInput = yawInput - system.getControlDeviceLeftRightInput()\nlocal combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);\nlocal finalVerticalStrafeInput = verticalStrafeInput\nlocal finalLateralStrafeInput = lateralStrafeInput;\nlocal finalBrakeInput = brakeInput\n\n-- Axis\nlocal worldVertical = vec3(core.getWorldVertical())\nlocal constructUp = vec3(construct.getWorldOrientationUp())\nlocal constructForward = vec3(construct.getWorldOrientationForward())\nlocal constructRight = vec3(construct.getWorldOrientationRight())\nlocal constructVelocity = vec3(construct.getWorldVelocity())\nlocal constructVelocityDir = vec3(construct.getWorldVelocity()):normalize()\nlocal constructAngularVelocity = vec3(construct.getWorldAngularVelocity())\nlocal constructYawVelocity = constructAngularVelocity:dot(constructUp)\n\n-- Engine commands\nlocal keepCollinearity = 0 -- for easier reading\nlocal dontKeepCollinearity = 1 -- for easier reading\nlocal tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities\n\n-- Rotation\nlocal currentRollDeg = getRoll(worldVertical, constructForward, constructRight)\nlocal currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg\nlocal targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)\nlocal targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)\nrollPID:inject(targetRollDeg - currentRollDeg)\npitchPID:inject(targetPitchDeg - currentPitchDeg)\n\nlocal constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor\nlocal constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)\n\nlocal constructTargetAngularVelocity = rollPID:get() * constructForward\n + pitchPID:get() * constructRight\n + constructYawTargetAcceleration * constructUp\n\nNav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)\n\n-- Brakes\nif (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then\n finalBrakeInput = 1\nend\nlocal brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)\nNav:setEngineForceCommand('brake', brakeAcceleration)\n\n-- AutoNavigation regroups all the axis command by 'TargetSpeed'\nlocal autoNavigationEngineTags = ''\nlocal autoNavigationAcceleration = vec3()\nlocal autoNavigationUseBrake = false\n\n-- Longitudinal Translation\nlocal longitudinalEngineTags = 'thrust analog longitudinal'\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byThrottle) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)\n Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)\nelseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration\n if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop\n Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking\n then\n autoNavigationUseBrake = true\n end\n\nend\n\n-- Lateral Translation\nlocal lateralStrafeEngineTags = 'thrust analog lateral'\nlocal lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)\nif (lateralCommandType == axisCommandType.byThrottle) then\n local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)\n Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)\nelseif (lateralCommandType == axisCommandType.byTargetSpeed) then\n local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration\nend\n\n-- Vertical Translation\nlocal verticalStrafeEngineTags = 'thrust analog vertical'\nlocal verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)\nif (verticalCommandType == axisCommandType.byThrottle) then\n local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)\n Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)\nelseif (verticalCommandType == axisCommandType.byTargetSpeed) then\n local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)\n autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags\n autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration\nend\n\n-- Auto Navigation (Cruise Control)\nif (autoNavigationAcceleration:len() > constants.epsilon) then\n if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward\n then\n autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'\n end\n Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)\nend\n\n-- Rockets\nNav:setBoosterCommand('rocket_engine')\n"}, {"key": "3", "filter": {"slotKey": "-4", "signature": "onUpdate()", "args": []}, "code": "Nav:update()\nif system.getThrottleInputFromMouseWheel() ~= 0.0 then\n brakeInput = 0\nend\n\nif unit.isMouseControlActivated() then\n local currentVelocity = vec3(construct.getVelocity())\n local axisCRefDirection = vec3(construct.getOrientationForward())\n local v = currentVelocity:dot(axisCRefDirection)\n local minv = 20\n local maxPitch = 0.4\n if v < minv or not goingForward then\n pitchInput = 0\n else\n if not goingBack and goingForward then\n pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)\n end\n end\nend\n\npitchInput = pitchInput + jumpDelta\n"}, {"key": "4", "filter": {"slotKey": "-4", "signature": "onActionStart(gear)", "args": [{"value": "gear"}]}, "code": "gearExtended = not gearExtended\nif gearExtended then\n unit.deployLandingGears()\nelse\n unit.retractLandingGears()\nend\n"}, {"key": "5", "filter": {"slotKey": "-4", "signature": "onActionStart(light)", "args": [{"value": "light"}]}, "code": "if unit.isAnyHeadlightSwitchedOn() then\n unit.switchOffHeadlights()\nelse\n unit.switchOnHeadlights()\nend\n"}, {"key": "6", "filter": {"slotKey": "-4", "signature": "onActionLoop(backward)", "args": [{"value": "backward"}]}, "code": "loopDirection(direction.backward)"}, {"key": "7", "filter": {"slotKey": "-4", "signature": "onActionStart(backward)", "args": [{"value": "backward"}]}, "code": "startBackward()"}, {"key": "8", "filter": {"slotKey": "-4", "signature": "onActionStop(backward)", "args": [{"value": "backward"}]}, "code": "stopBackward()"}, {"key": "9", "filter": {"slotKey": "-4", "signature": "onActionLoop(forward)", "args": [{"value": "forward"}]}, "code": "loopDirection(direction.forward)"}, {"key": "10", "filter": {"slotKey": "-4", "signature": "onActionStart(forward)", "args": [{"value": "forward"}]}, "code": "startForward()"}, {"key": "11", "filter": {"slotKey": "-4", "signature": "onActionStop(forward)", "args": [{"value": "forward"}]}, "code": "stopForward()"}, {"key": "12", "filter": {"slotKey": "-4", "signature": "onActionStart(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = true\nif goingForward then\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)\nend\n"}, {"key": "13", "filter": {"slotKey": "-4", "signature": "onActionStop(lshift)", "args": [{"value": "lshift"}]}, "code": "shiftPressed = false\nif goingForward then\n local maxGForward = Nav:maxForceForward() / (construct.getTotalMass() * 9.81)\n local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)\n Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)\nend\n"}, {"key": "14", "filter": {"slotKey": "-4", "signature": "onActionStart(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput - 1"}, {"key": "15", "filter": {"slotKey": "-4", "signature": "onActionStop(left)", "args": [{"value": "left"}]}, "code": "rollInput = rollInput + 1"}, {"key": "16", "filter": {"slotKey": "-4", "signature": "onActionStart(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput + 1"}, {"key": "17", "filter": {"slotKey": "-4", "signature": "onActionStop(right)", "args": [{"value": "right"}]}, "code": "rollInput = rollInput - 1"}, {"key": "18", "filter": {"slotKey": "-4", "signature": "onActionStart(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)"}, {"key": "19", "filter": {"slotKey": "-4", "signature": "onActionStop(straferight)", "args": [{"value": "straferight"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)"}, {"key": "20", "filter": {"slotKey": "-4", "signature": "onActionStart(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)"}, {"key": "21", "filter": {"slotKey": "-4", "signature": "onActionStop(strafeleft)", "args": [{"value": "strafeleft"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)"}, {"key": "22", "filter": {"slotKey": "-4", "signature": "onActionStart(up)", "args": [{"value": "up"}]}, "code": "baseAltitude = Nav:getTargetGroundAltitude()\nNav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)\n"}, {"key": "23", "filter": {"slotKey": "-4", "signature": "onActionLoop(up)", "args": [{"value": "up"}]}, "code": "if unit.isMouseControlActivated() then\n jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)\nend\n"}, {"key": "24", "filter": {"slotKey": "-4", "signature": "onActionStop(up)", "args": [{"value": "up"}]}, "code": "Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)\nif unit.isMouseControlActivated() then\n jumpDelta = 0\nend\n"}, {"key": "25", "filter": {"slotKey": "-4", "signature": "onActionStart(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()\nNav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)\n"}, {"key": "26", "filter": {"slotKey": "-4", "signature": "onActionStop(down)", "args": [{"value": "down"}]}, "code": "Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)\nNav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)\n"}, {"key": "27", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)"}, {"key": "28", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudeup)", "args": [{"value": "groundaltitudeup"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)\njumpDelta = 0\n"}, {"key": "29", "filter": {"slotKey": "-4", "signature": "onActionStart(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)"}, {"key": "30", "filter": {"slotKey": "-4", "signature": "onActionLoop(groundaltitudedown)", "args": [{"value": "groundaltitudedown"}]}, "code": "Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)"}, {"key": "31", "filter": {"slotKey": "-4", "signature": "onActionStart(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput - 1"}, {"key": "32", "filter": {"slotKey": "-4", "signature": "onActionStop(yawright)", "args": [{"value": "yawright"}]}, "code": "yawInput = yawInput + 1"}, {"key": "33", "filter": {"slotKey": "-4", "signature": "onActionStart(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput + 1"}, {"key": "34", "filter": {"slotKey": "-4", "signature": "onActionStop(yawleft)", "args": [{"value": "yawleft"}]}, "code": "yawInput = yawInput - 1"}, {"key": "35", "filter": {"slotKey": "-4", "signature": "onActionStart(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = brakeInput + 1\nlocal longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "36", "filter": {"slotKey": "-4", "signature": "onActionStop(brake)", "args": [{"value": "brake"}]}, "code": "brakeInput = 0"}, {"key": "37", "filter": {"slotKey": "-4", "signature": "onActionLoop(brake)", "args": [{"value": "brake"}]}, "code": "local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)\nif (longitudinalCommandType == axisCommandType.byTargetSpeed) then\n local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)\n if (math.abs(targetSpeed) > constants.epsilon) then\n Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))\n end\nend\n"}, {"key": "38", "filter": {"slotKey": "-4", "signature": "onActionStart(booster)", "args": [{"value": "booster"}]}, "code": "Nav:toggleBoosters()"}, {"key": "39", "filter": {"slotKey": "-4", "signature": "onActionStart(stopengines)", "args": [{"value": "stopengines"}]}, "code": "Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)"}, {"key": "40", "filter": {"slotKey": "-4", "signature": "onActionLoop(speedup)", "args": [{"value": "speedup"}]}, "code": "loopDirection(direction.forward)"}, {"key": "41", "filter": {"slotKey": "-4", "signature": "onActionStart(speedup)", "args": [{"value": "speedup"}]}, "code": "startForward()"}, {"key": "42", "filter": {"slotKey": "-4", "signature": "onActionStop(speedup)", "args": [{"value": "speedup"}]}, "code": "stopForward()"}, {"key": "43", "filter": {"slotKey": "-4", "signature": "onActionStart(speeddown)", "args": [{"value": "speeddown"}]}, "code": "startBackward()"}, {"key": "44", "filter": {"slotKey": "-4", "signature": "onActionStop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "stopBackward()"}, {"key": "45", "filter": {"slotKey": "-4", "signature": "onActionLoop(speeddown)", "args": [{"value": "speeddown"}]}, "code": "loopDirection(direction.backward)"}, {"key": "46", "filter": {"slotKey": "-4", "signature": "onActionStart(antigravity)", "args": [{"value": "antigravity"}]}, "code": "if antigrav ~= nil then antigrav.toggle() end"}], "methods": [], "events": []}