--[[ This type of scripts uses the same API as GamepadFX scripts, but has extra inputs. Since 0.3.0, these scripts can override inputs without mouse steering as well. ]] local settings = ac.INIConfig.scriptSettings():mapConfig({ GAMMA = { GAS = 1, BRAKE = 1, STEERING = 1, HANDBRAKE = 1, CLUTCH = 1, } }) local exchange = ac.writeMemoryMappedFile('AcTools.CSP.Wooting.v0', { _explicit = ac.StructItem.explicit(), key = ac.StructItem.uint32(), frame = ac.StructItem.uint32(), frames = ac.StructItem.array(ac.StructItem.struct { keys = ac.StructItem.array(ac.StructItem.uint8(), 256) }, 4) }) exchange.key = math.randomKey() local died = false os.runConsoleProcess({ filename = 'C:/Games/AssettoCorsa/extension/internal/plugins/AcTools.Wooting.exe', environment = { ACCSPWOOTING_KEY = 'AcTools.CSP.Wooting.v0', ACCSPWOOTING_ID = tostring(exchange.key) }, inheritEnvironment = true }, function(err, data) died = true if err then ac.error(err) else ac.warn(data.exitCode, data.stderr, data.stdout) end end) local buttons = ac.INIConfig.controlsConfig():mapConfig({ KEYBOARD = { BRAKE = -1, GAS = -1, LEFT = -1, RIGHT = -1, }, HANDBRAKE = { KEY = -1 }, __EXT_KEYBOARD_CLUTCH = { KEY = -1 }, }) local function readButton(btn, gamma) return btn >= 0 and btn < 256 and exchange.frames[exchange.frame].keys[btn] / 255 or 0 end local steer = 0 ---@param dt number @Time passed in seconds. ---@param deltaX number @Horizontal mouse shift since the last frame, relative, can be adjusted in controls settings. ---@param deltaY number @Vertical mouse shift since the last frame, relative, can be adjusted in controls settings. ---@param useMouseButtons boolean @Please use mouse buttons for controls only if this value is `true`, and keep in mind middle mouse button might be used to toggle mouse steering in general. ---@param useMouseSteering boolean @If mouse steering is active or not. If not active, `script.update()` won’t be called unless `[CORE] MOUSELESS` in manifest is set to `1`. If it is inactive, deltaX, deltaY and useMouseButtons are `0` and `false`. function script.update(dt, deltaX, deltaY, useMouseButtons, useMouseSteering) if died then ac.setMessage('Wooting', 'Wooting plugin has died') ac.skipProcessing() -- just use the original logic instead return end local state = ac.getJoypadState() if useMouseSteering and useMouseButtons then -- Gas and brake will be set by original implementation, taking into account AC mouse steering traction control else state.gas = readButton(buttons.KEYBOARD.GAS, settings.GAMMA.GAS) state.brake = readButton(buttons.KEYBOARD.BRAKE, settings.GAMMA.BRAKE) end ac.debug('deltaX', deltaX) if useMouseSteering then ac.overrideKeyboard() -- do not use original AC keyboard logic, we have our fancy inputs steer = math.clamp(steer + deltaX, -1, 1) state.steer = steer ac.debug('steer', steer) else steer = 0 state.steer = readButton(buttons.KEYBOARD.RIGHT, settings.GAMMA.STEERING) - readButton(buttons.KEYBOARD.LEFT, settings.GAMMA.STEERING) end state.handbrake = readButton(buttons.HANDBRAKE.KEY, settings.GAMMA.HANDBRAKE) if buttons.__EXT_KEYBOARD_CLUTCH.KEY >= 0 then state.clutch = 1 - readButton(buttons.__EXT_KEYBOARD_CLUTCH.KEY, settings.GAMMA.CLUTCH) end end