# This is a file describing a standard autoconfiguration, do not edit.
# See custom/sample.conf for a more generic template and explanation on the syntax.
name: ui_cu_autoconf_construct_ground
slots:
core:
class: CoreUnit
antigrav:
class: AntiGravityGeneratorUnit
atmofueltank:
class: AtmoFuelContainer
select: all
spacefueltank:
class: SpaceFuelContainer
select: all
rocketfueltank:
class: RocketFuelContainer
select: all
gyro:
class: GyroUnit
weapon:
class: WeaponUnit
select: manual
radar:
class: RadarPVPUnit
select: manual
handlers:
unit:
onStart:
lua: |
pitchInput = 0
pitchInputFromDevice = 0
rollInput = 0
yawInput = 0
verticalStrafeInput = 0
lateralStrafeInput = 0
brakeInput = 0
goingBack = false
goingForward = false
shiftPressed = false
jumpDelta = 0
baseAcceleration = 0.8 --export: Acceleration provided when 'forward' is hit, expressed in g
Nav = Navigator.new(system, core, unit)
Nav.axisCommandManager:setupCustomTargetSpeedRanges(axisCommandId.longitudinal, {100, 500, 1000, 5000})
Nav.axisCommandManager:setTargetGroundAltitude(6)
-- Parenting widget
parentingPanelId = system.createWidgetPanel("Docking")
parentingWidgetId = system.createWidget(parentingPanelId,"parenting")
system.addDataToWidget(unit.getDataId(),parentingWidgetId)
-- Combat stress widget
coreCombatStressPanelId = system.createWidgetPanel("Core combat stress")
coreCombatStressgWidgetId = system.createWidget(coreCombatStressPanelId,"core_stress")
system.addDataToWidget(core.getDataId(),coreCombatStressgWidgetId)
-- element widgets
-- For now we have to alternate between PVP and non-PVP widgets to have them on the same side.
_autoconf.displayCategoryPanel(weapon, weapon_size, L_TEXT("ui_lua_widget_weapon", "Weapons"), "weapon", true)
core.show()
_autoconf.displayCategoryPanel(radar, radar_size, L_TEXT("ui_lua_widget_periscope", "Periscope"), "periscope")
placeRadar = true
if atmofueltank_size > 0 then
_autoconf.displayCategoryPanel(atmofueltank, atmofueltank_size, L_TEXT("ui_lua_widget_atmofuel", "Atmo Fuel"), "fuel_container")
if placeRadar then
_autoconf.displayCategoryPanel(radar, radar_size, L_TEXT("ui_lua_widget_radar", "Radar"), "radar")
placeRadar = false
end
end
if spacefueltank_size > 0 then
_autoconf.displayCategoryPanel(spacefueltank, spacefueltank_size, L_TEXT("ui_lua_widget_spacefuel", "Space Fuel"), "fuel_container")
if placeRadar then
_autoconf.displayCategoryPanel(radar, radar_size, L_TEXT("ui_lua_widget_radar", "Radar"), "radar")
placeRadar = false
end
end
_autoconf.displayCategoryPanel(rocketfueltank, rocketfueltank_size, L_TEXT("ui_lua_widget_rocketfuel", "Rocket Fuel"), "fuel_container")
if placeRadar then -- We either have only rockets or no fuel tanks at all, uncommon for usual vessels
_autoconf.displayCategoryPanel(radar, radar_size, L_TEXT("ui_lua_widget_radar", "Radar"), "radar")
placeRadar = false
end
if antigrav ~= nil then antigrav.show() end
if gyro ~= nil then gyro.show() end
throttleStep = 0.25 --export: When pressing the SpeedUp/SpeedDown buttons, this step will be using to increment/decrement the throttle
Valid values: From 0.01 to 1
throttleStep = utils.clamp(throttleStep, 0.01, 1)
-- freeze the player in he is remote controlling the construct
if Nav.control.isRemoteControlled() == 1 then
system.freeze(1)
end
-- landing gear
-- make sure every gears are synchonized with the first
gearExtended = (Nav.control.isAnyLandingGearExtended() == 1) -- make sure it's a lua boolean
if gearExtended then
Nav.control.extendLandingGears()
else
Nav.control.retractLandingGears()
end
-- forward/backward functions
startForward = function ()
if Nav:isTravelMode() then
brakeInput = 0
local throttle = 1
if not shiftPressed then
local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)
throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)
end
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)
goingForward = true
end
end
stopForward = function ()
if Nav:isTravelMode() then
pitchInput = 0
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)
brakeInput = 0.5
goingForward = false
if goingBackward then
startBackward()
end
end
end
direction = {forward=1, backward = -1}
loopDirection = function (direction)
if Nav:isTravelMode() then
local currentVelocity = vec3(self.core.getVelocity())
local axisCRefDirection = vec3(self.core.getConstructOrientationForward())
lastCurrentSpeed = currentVelocity:dot(axisCRefDirection)
if (lastCurrentSpeed * direction < 0) then
brakeInput = 1
autobrake = true
else
if autobrake == true then
autobrake = false
brakeInput = 0
end
end
else
Nav.axisCommandManager.axisCommands[axisCommandId.longitudinal]:updateCommandFromActionLoop(direction)
end
end
startBackward = function ()
if Nav:isTravelMode() then
pitchInput = 0
brakeInput = 0
local maxGBackward = Nav:maxForceBackward() / (self.core.getConstructMass() * 9.81)
local throttle = utils.clamp(baseAcceleration / maxGBackward, -1, 0)
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)
goingBack = true
end
end
stopBackward = function ()
if Nav:isTravelMode() then
pitchInput = 0
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 0)
brakeInput = 0.5
goingBack = false
if goingForward then
startForward()
end
end
end
onStop:
lua: |
_autoconf.hideCategoryPanels()
if antigrav ~= nil then antigrav.hide() end
if gyro ~= nil then gyro.hide() end
core.hide()
Nav.control.switchOffHeadlights()
system:
onFlush:
lua: |
-- constants: use 'myvar = defaultValue --export: description' to expose the variable in context menu
in degree
Valid values: Superior or equal to 1
local rollAmplitude = 30 --export: When turning, the auto roll won't go over or under rollAmplitude
in degree
Valid values: Superior or equal to 1
local pitchAmplitude = 25 --export: When pitching, the pitch won't go over or under pitchAmplitude (in degree)
local yawSpeedFactor = 1.5 --export When turning, the inputs will be multiplied by this factor
Valid values: Superior or equal to 0.01
local yawAccelerationFactor = 3 --export: When turning, the yaw response will be multiplied by this factor
Valid values: Superior or equal to 0.01
local lateralAntiDriftFactor = 1 --export: When compensating for drift, this factor will increase/decrease the drift force requested to engines
Valid values: Superior or equal to 0.01
local lateralStrafeFactor = 5 --export: This factor will increase/decrease the player input along the horizontal strafe axis axis
Valid values: Superior or equal to 0.01
local brakeSpeedFactor = 1 --export: When braking, this factor will increase the brake force by brakeSpeedFactor * velocity
Valid values: Superior or equal to 0.01
local brakeFlatFactor = 4 --export: When braking, this factor will increase the brake force by a flat brakeFlatFactor * velocity direction>
(higher value may be unstable)
Valid values: Superior or equal to 0.01
local autoBrakeSpeed = 15 --export: Auto brake when speed is below that value (in m/s), with no thrust
-- validate params
brakeSpeedFactor = math.max(brakeSpeedFactor, 0.01)
brakeFlatFactor = math.max(brakeFlatFactor, 0.01)
rollAmplitude = math.max(rollAmplitude, 1)
pitchAmplitude = math.max(pitchAmplitude, 1)
yawSpeedFactor = math.max(yawSpeedFactor, 0.01)
yawAccelerationFactor = math.max(yawAccelerationFactor, 0.01)
if (rollPID == nil) then
rollPID = pid.new(0.2, 0, 10)
pitchPID = pid.new(0.2, 0, 10)
end
-- final inputs
if Nav.control.isMouseDirectControlActivated() then
-- in direct control, we tweak the pitch to behave inbetween virtual joystick and direct control
-- this helps a lot for ground construct control
pitchInputFromDevice = utils.clamp(pitchInputFromDevice + system.getControlDeviceForwardInput() * system.getActionUpdateDeltaTime(), -1.0, 1.0)
else
pitchInputFromDevice = system.getControlDeviceForwardInput()
end
local finalPitchInput = pitchInput + pitchInputFromDevice
local finalRollInput = rollInput + system.getControlDeviceYawInput()
local finalYawInput = yawInput - system.getControlDeviceLeftRightInput()
local combinedRollYawInput = utils.clamp(finalRollInput - finalYawInput, -1.0, 1.0);
local finalVerticalStrafeInput = verticalStrafeInput
local finalLateralStrafeInput = lateralStrafeInput;
local finalBrakeInput = brakeInput
-- Axis
local worldVertical = vec3(core.getWorldVertical())
local constructUp = vec3(core.getConstructWorldOrientationUp())
local constructForward = vec3(core.getConstructWorldOrientationForward())
local constructRight = vec3(core.getConstructWorldOrientationRight())
local constructVelocity = vec3(core.getWorldVelocity())
local constructVelocityDir = vec3(core.getWorldVelocity()):normalize()
local constructAngularVelocity = vec3(core.getWorldAngularVelocity())
local constructYawVelocity = constructAngularVelocity:dot(constructUp)
-- Engine commands
local keepCollinearity = 0 -- for easier reading
local dontKeepCollinearity = 1 -- for easier reading
local tolerancePercentToSkipOtherPriorities = 1 -- if we are within this tolerance (in%), we don't go to the next priorities
-- Rotation
local currentRollDeg = getRoll(worldVertical, constructForward, constructRight)
local currentPitchDeg = -math.asin(constructForward:dot(worldVertical)) * constants.rad2deg
local targetRollDeg = utils.clamp(combinedRollYawInput * rollAmplitude, -rollAmplitude, rollAmplitude)
local targetPitchDeg = utils.clamp(finalPitchInput * pitchAmplitude, -pitchAmplitude, pitchAmplitude)
rollPID:inject(targetRollDeg - currentRollDeg)
pitchPID:inject(targetPitchDeg - currentPitchDeg)
local constructYawTargetVelocity = -combinedRollYawInput * yawSpeedFactor
local constructYawTargetAcceleration = yawAccelerationFactor * (constructYawTargetVelocity - constructYawVelocity)
local constructTargetAngularVelocity = rollPID:get() * constructForward
+ pitchPID:get() * constructRight
+ constructYawTargetAcceleration * constructUp
Nav:setEngineTorqueCommand('torque', constructTargetAngularVelocity, keepCollinearity, 'airfoil', '', '', tolerancePercentToSkipOtherPriorities)
-- Brakes
if (finalBrakeInput == 0 and autoBrakeSpeed > 0 and Nav.axisCommandManager.throttle == 0 and constructVelocity:len() < autoBrakeSpeed) then
finalBrakeInput = 1
end
local brakeAcceleration = -finalBrakeInput * (brakeSpeedFactor * constructVelocity + brakeFlatFactor * constructVelocityDir)
Nav:setEngineForceCommand('brake', brakeAcceleration)
-- AutoNavigation regroups all the axis command by 'TargetSpeed'
local autoNavigationEngineTags = ''
local autoNavigationAcceleration = vec3()
local autoNavigationUseBrake = false
-- Longitudinal Translation
local longitudinalEngineTags = 'thrust analog longitudinal'
local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)
if (longitudinalCommandType == axisCommandType.byThrottle) then
local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(longitudinalEngineTags,axisCommandId.longitudinal)
Nav:setEngineForceCommand(longitudinalEngineTags, longitudinalAcceleration, keepCollinearity)
elseif (longitudinalCommandType == axisCommandType.byTargetSpeed) then
local longitudinalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.longitudinal)
autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. longitudinalEngineTags
autoNavigationAcceleration = autoNavigationAcceleration + longitudinalAcceleration
if (Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal) == 0 or -- we want to stop
Nav.axisCommandManager:getCurrentToTargetDeltaSpeed(axisCommandId.longitudinal) < - Nav.axisCommandManager:getTargetSpeedCurrentStep(axisCommandId.longitudinal) * 0.5) -- if the longitudinal velocity would need some braking
then
autoNavigationUseBrake = true
end
end
-- Lateral Translation
local lateralStrafeEngineTags = 'thrust analog lateral'
local lateralCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.lateral)
if (lateralCommandType == axisCommandType.byThrottle) then
local lateralStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(lateralStrafeEngineTags,axisCommandId.lateral)
Nav:setEngineForceCommand(lateralStrafeEngineTags, lateralStrafeAcceleration, keepCollinearity)
elseif (lateralCommandType == axisCommandType.byTargetSpeed) then
local lateralAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.lateral)
autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. lateralStrafeEngineTags
autoNavigationAcceleration = autoNavigationAcceleration + lateralAcceleration
end
-- Vertical Translation
local verticalStrafeEngineTags = 'thrust analog vertical'
local verticalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.vertical)
if (verticalCommandType == axisCommandType.byThrottle) then
local verticalStrafeAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromThrottle(verticalStrafeEngineTags,axisCommandId.vertical)
Nav:setEngineForceCommand(verticalStrafeEngineTags, verticalStrafeAcceleration, keepCollinearity, 'airfoil', 'ground', '', tolerancePercentToSkipOtherPriorities)
elseif (verticalCommandType == axisCommandType.byTargetSpeed) then
local verticalAcceleration = Nav.axisCommandManager:composeAxisAccelerationFromTargetSpeed(axisCommandId.vertical)
autoNavigationEngineTags = autoNavigationEngineTags .. ' , ' .. verticalStrafeEngineTags
autoNavigationAcceleration = autoNavigationAcceleration + verticalAcceleration
end
-- Auto Navigation (Cruise Control)
if (autoNavigationAcceleration:len() > constants.epsilon) then
if (brakeInput ~= 0 or autoNavigationUseBrake or math.abs(constructVelocityDir:dot(constructForward)) < 0.95) -- if the velocity is not properly aligned with the forward
then
autoNavigationEngineTags = autoNavigationEngineTags .. ', brake'
end
Nav:setEngineForceCommand(autoNavigationEngineTags, autoNavigationAcceleration, dontKeepCollinearity, '', '', '', tolerancePercentToSkipOtherPriorities)
end
-- Rockets
Nav:setBoosterCommand('rocket_engine')
onUpdate:
lua: |
Nav:update()
if system.getThrottleInputFromMouseWheel() ~= 0.0 then
brakeInput = 0
end
if unit.isMouseControlActivated() == 0 then
local currentVelocity = vec3(self.core.getVelocity())
local axisCRefDirection = vec3(self.core.getConstructOrientationForward())
local v = currentVelocity:dot(axisCRefDirection)
local minv = 20
local maxPitch = 0.4
if v < minv or not goingForward then
pitchInput = 0
else
if not goingBack and goingForward then
pitchInput = utils.clamp((maxPitch/minv) * (v - minv), 0, maxPitch)
end
end
end
pitchInput = pitchInput + jumpDelta
onActionStart:
args: [gear]
lua: |
gearExtended = not gearExtended
if gearExtended then
Nav.control.extendLandingGears()
else
Nav.control.retractLandingGears()
end
onActionStart:
args: [light]
lua: |
if Nav.control.isAnyHeadlightSwitchedOn() == 1 then
Nav.control.switchOffHeadlights()
else
Nav.control.switchOnHeadlights()
end
onActionLoop:
args: [backward]
lua: loopDirection(direction.backward)
onActionStart:
args: [backward]
lua: startBackward()
onActionStop:
args: [backward]
lua: stopBackward()
onActionLoop:
args: [forward]
lua: loopDirection(direction.forward)
onActionStart:
args: [forward]
lua: startForward()
onActionStop:
args: [forward]
lua: stopForward()
onActionStart:
args: [lshift]
lua: |
shiftPressed = true
if goingForward then
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, 1)
end
onActionStop:
args: [lshift]
lua: |
shiftPressed = false
if goingForward then
local maxGForward = Nav:maxForceForward() / (self.core.getConstructMass() * 9.81)
local throttle = utils.clamp(baseAcceleration / maxGForward, 0, 1)
Nav.axisCommandManager:setThrottleCommand(axisCommandId.longitudinal, throttle)
end
onActionStart:
args: [left]
lua: rollInput = rollInput - 1
onActionStop:
args: [left]
lua: rollInput = rollInput + 1
onActionStart:
args: [right]
lua: rollInput = rollInput + 1
onActionStop:
args: [right]
lua: rollInput = rollInput - 1
onActionStart:
args: [straferight]
lua: Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, 1.0)
onActionStop:
args: [straferight]
lua: Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, -1.0)
onActionStart:
args: [strafeleft]
lua: Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.lateral, -1.0)
onActionStop:
args: [strafeleft]
lua: Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.lateral, 1.0)
onActionStart:
args: [up]
lua: |
baseAltitude = Nav:getTargetGroundAltitude()
Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude + 4)
onActionLoop:
args: [up]
lua: |
if unit.isMouseControlActivated() == 0 then
jumpDelta = utils.clamp(jumpDelta + 0.01, 0, 0.6)
end
onActionStop:
args: [up]
lua: |
Nav.axisCommandManager:setTargetGroundAltitude(baseAltitude)
if unit.isMouseControlActivated() == 0 then
jumpDelta = 0
end
onActionStart:
args: [down]
lua: |
Nav.axisCommandManager:deactivateGroundEngineAltitudeStabilization()
Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.vertical, -1.0)
onActionStop:
args: [down]
lua: |
Nav.axisCommandManager:updateCommandFromActionStop(axisCommandId.vertical, 1.0)
Nav.axisCommandManager:activateGroundEngineAltitudeStabilization(defaultGroundAltitudeStabilization)
onActionStart:
args: [groundaltitudeup]
lua: Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(1.0)
onActionLoop:
args: [groundaltitudeup]
lua: |
Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(1.0)
jumpDelta = 0
onActionStart:
args: [groundaltitudedown]
lua: Nav.axisCommandManager:updateTargetGroundAltitudeFromActionStart(-1.0)
onActionLoop:
args: [groundaltitudedown]
lua: Nav.axisCommandManager:updateTargetGroundAltitudeFromActionLoop(-1.0)
onActionStart:
args: [yawright]
lua: yawInput = yawInput - 1
onActionStop:
args: [yawright]
lua: yawInput = yawInput + 1
onActionStart:
args: [yawleft]
lua: yawInput = yawInput + 1
onActionStop:
args: [yawleft]
lua: yawInput = yawInput - 1
onActionStart:
args: [brake]
lua: |
brakeInput = brakeInput + 1
local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)
if (longitudinalCommandType == axisCommandType.byTargetSpeed) then
local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)
if (math.abs(targetSpeed) > constants.epsilon) then
Nav.axisCommandManager:updateCommandFromActionStart(axisCommandId.longitudinal, - utils.sign(targetSpeed))
end
end
onActionStop:
args: [brake]
lua: brakeInput = 0
onActionLoop:
args: [brake]
lua: |
local longitudinalCommandType = Nav.axisCommandManager:getAxisCommandType(axisCommandId.longitudinal)
if (longitudinalCommandType == axisCommandType.byTargetSpeed) then
local targetSpeed = Nav.axisCommandManager:getTargetSpeed(axisCommandId.longitudinal)
if (math.abs(targetSpeed) > constants.epsilon) then
Nav.axisCommandManager:updateCommandFromActionLoop(axisCommandId.longitudinal, - utils.sign(targetSpeed))
end
end
onActionStart:
args: [booster]
lua: Nav:toggleBoosters()
onActionStart:
args: [stopengines]
lua: Nav.axisCommandManager:resetCommand(axisCommandId.longitudinal)
onActionLoop:
args: [speedup]
lua: loopDirection(direction.forward)
onActionStart:
args: [speedup]
lua: startForward()
onActionStop:
args: [speedup]
lua: stopForward()
onActionStart:
args: [speeddown]
lua: startBackward()
onActionStop:
args: [speeddown]
lua: stopBackward()
onActionLoop:
args: [speeddown]
lua: loopDirection(direction.backward)
onActionStart:
args: [antigravity]
lua: if antigrav ~= nil then antigrav.toggle() end