--[[ An example of an Automated Manual Transmission implementation. Doesn’t do anything fancy, basically blocks gearbox inputs and instead does its own shifts. To use, include the file like this: ```lua local automatedManualTransmission = require('shared/physics/automated-manual-transmission')() function script.update(dt) automatedManualTransmission.update() end function script.reset() automatedManualTransmission.reset() end ``` This one requires you to set SUPPORTS_SHIFTER to 0, this is how this script can shift gears efficiently. For more advanced customization, you can specify custom shifting logic by replacing the first line with: ```lua local automatedManualTransmission = require('shared/physics/automated-manual-transmission')({ shiftingLogic = automaticGearboxUtils.simpleDriveFnFactory(), -- or pass your own function }) ``` And, of course, feel free to instead just copy the entire logic into your own “script.lua” and change anything you want any way you want. This thing is meant to be an example and a shortcut for modders who are not entirely familiar with Lua scripting. ]] ---@param options nil|{shiftingLogic: AutomaticLogicFn} ---@return {update: fun(dt: number), reset: fun()} return function (options) if _G.__atConfigured then _G.__atConfigured = true error('Another custom transmission has already been configured') end -- Load automatic gearbox helper library: local automaticGearboxUtils = require('shared/physics/automatic-transmission-utils') -- Load settings: options = options or {} local shiftingLogic = options.shiftingLogic or automaticGearboxUtils.simpleDriveFnFactory() local automatedManualTransmission = {} local carPh = ac.accessCarPhysics() -- To simplify shifts logic, we can just reuse AC’s sequential gearbox. Let’s make sure it’s available: local cfgDrivetrain = ac.INIConfig.carData(car.index, 'drivetrain.ini') if cfgDrivetrain:get('GEARBOX', 'SUPPORTS_SHIFTER', true) then error('Set GEARBOX/SUPPORTS_SHIFTER in drivetrain.ini to 0 for AMT transmission to work properly') end -- This thing will help to compute when to shift as the car drives along: local automaticLogic = automaticGearboxUtils.logicHelper( shiftingLogic, 0.25, 2, cfgDrivetrain:get('GEARS', 'COUNT', 5) + 1) -- And this thing will intercept car gear shift inputs and convert them into a R/N/P/D gearbox, -- including visual representation: local shifter = require('shared/physics/rnpd-shifting')() -- Other settings: local brakeDamageThreshold = cfgDrivetrain:get('SCRIPT_AUTOMATIC_GEARBOX', 'BRAKE_DAMAGE_THRESHOLD_KMH', 5) function automatedManualTransmission.update(dt) -- Disabling automatic clutch so the car would start driving from stationary when shifted into D: ac.overrideSpecificValue(ac.CarPhysicsValueID.ForcedAutoclutch, false) -- Update R/N/P/D gearbox logic: shifter:update() -- Three different programs based on selected gear: local curProgram = shifter:program() if curProgram == 'P' or curProgram == 'N' then -- P and N both shift into neutral: carPh.requestedGearIndex = 1 -- P can also brake with the gearbox: if curProgram == 'P' then automaticGearboxUtils.parkingBrake(brakeDamageThreshold) end else -- Non-P programs without pressed brakes should awake the car to get it to roll: if carPh.brake < 0.01 then ac.awakeCarPhysics() end if curProgram == 'R' then -- R program is simple, just engage rear gear and that’s it: carPh.requestedGearIndex = 0 elseif curProgram == 'D' then -- For D program, we’re asking our gears computing helper what is a better gear: local newGear = automaticLogic(carPh.targetGear ~= -1 and carPh.targetGear or carPh.gear, dt) ac.debug('newGear', newGear) if carPh.targetGear == -1 then -- And shift into it, but only if it’s the first frame of a shift: if newGear > carPh.gear then carPh.gearUp = true elseif newGear < carPh.gear then carPh.gearDown = true end end end end -- Debugging info: if __monitored then ac.debug('base gear', carPh.gear) ac.debug('target gear', carPh.targetGear) end end function automatedManualTransmission.reset() -- Make sure to let R/N/P/D thing know car has been reset: shifter:reset() end return automatedManualTransmission end