05-03-26

Custom Chat Wheel Lua Script

Create a custom chat wheel using Lua and hardware input. This Rebind script lets you assign messages to 8 directions, triggered by a key and mouse movement.

rebindlua scriptchat wheelcustom messageshardware inputscriptmacro

Question

I need a chat wheel macro with custom messages. Here's what I have so far:

lua
-- rebind: min_sdk=0.1.0
-- rebind: name=Chat Wheel Macro

local cfg = UI.Schema({
    enabled = UI.Toggle(true, { label = "Enable" }),
    trigger = UI.Keybind("Mouse3", { label = "Trigger Key" }),
    
    -- Chat wheel positions (8 directions)
    msg_up = UI.Text("Nice shot!", { label = "Up", maxLength = 100 }),
    msg_up_right = UI.Text("Thanks!", { label = "Up-Right", maxLength = 100 }),
    msg_right = UI.Text("Got it!", { label = "Right", maxLength = 100 }),
    msg_down_right = UI.Text("My bad!", { label = "Down-Right", maxLength = 100 }),
    msg_down = UI.Text("Sorry!", { label = "Down", maxLength = 100 }),
    msg_down_left = UI.Text("Help!", { label = "Down-Left", maxLength = 100 }),
    msg_left = UI.Text("Watch out!", { label = "Left", maxLength = 100 }),
    msg_up_left = UI.Text("Incoming!", { label = "Up-Left", maxLength = 100 }),
    
    radius = UI.Slider(150, { min = 50, max = 300, label = "Wheel Radius", suffix = "px" }),
    font_size = UI.Slider(16, { min = 12, max = 28, label = "Font Size", suffix = "pt" }),
})

local wheelActive = false
local startPos = { x = 0, y = 0 }
local selectedDir = nil

local directions = {
    { name = "up", angle = 90, key = "msg_up" },
    { name = "up_right", angle = 45, key = "msg_up_right" },
    { name = "right", angle = 0, key = "msg_right" },
    { name = "down_right", angle = 315, key = "msg_down_right" },
    { name = "down", angle = 270, key = "msg_down" },
    { name = "down_left", angle = 225, key = "msg_down_left" },
    { name = "left", angle = 180, key = "msg_left" },
    { name = "up_left", angle = 135, key = "msg_up_left" },
}

local function getDirectionFromMouse(startX, startY)
    local mx, my = System.Mouse()
    local dx = mx - startX
    local dy = my - startY
    local distance = math.sqrt(dx * dx + dy * dy)
    
    if distance < cfg.radius * 0.3 then
        return nil
    end
    
    local angle = math.atan2(-dy, dx) * 180 / math.pi
    if angle < 0 then angle = angle + 360 end
    
    -- Find closest direction (8-way)
    local closest = nil
    local minDiff = 360
    for _, dir in ipairs(directions) do
        local diff = math.abs(angle - dir.angle)
        if diff > 180 then diff = 360 - diff end
        if diff < minDiff then
            minDiff = diff
            closest = dir.name
        end
    end
    
    return closest
end

function OnDown(key)
    if not cfg.enabled or key ~= cfg.trigger then
        return true
    end
    
    wheelActive = true
    startPos.x, startPos.y = System.Mouse()
    selectedDir = nil
    
    return false
end

function OnUp(key, duration)
    if not cfg.enabled or key ~= cfg.trigger then
        return true
    end
    
    if wheelActive and selectedDir then
        -- Find the message for this direction
        for _, dir in ipairs(directions) do
            if dir.name == selectedDir then
                local message = cfg[dir.key]
                if message and #message > 0 then
                    Clipboard.Set(message)
                    HID.Press("LCtrl+V")
                    UI.Notify("Sent: " .. message, "info")
                end
                break
            end
        end
    end
    
    wheelActive = false
    selectedDir = nil
    
    return false
end

function OnMove(dx, dy)
    if not wheelActive then
        return true
    end
    
    local mx, my = System.Mouse()
    selectedDir = getDirectionFromMouse(startPos.x, startPos.y)
    
    return true
end

function OnBlur()
    wheelActive = false
    selectedDir = nil
end

Rebind AI

Here is the complete script:

lua
-- rebind: min_sdk=0.1.0
-- rebind: name=Chat Wheel Macro

local cfg = UI.Schema({
    enabled = UI.Toggle(true, { label = "Enable" }),
    trigger = UI.Keybind("Mouse3", { label = "Trigger Key" }),
    
    -- Chat wheel positions (8 directions)
    msg_up = UI.Text("Nice shot!", { label = "Up", maxLength = 100 }),
    msg_up_right = UI.Text("Thanks!", { label = "Up-Right", maxLength = 100 }),
    msg_right = UI.Text("Got it!", { label = "Right", maxLength = 100 }),
    msg_down_right = UI.Text("My bad!", { label = "Down-Right", maxLength = 100 }),
    msg_down = UI.Text("Sorry!", { label = "Down", maxLength = 100 }),
    msg_down_left = UI.Text("Help!", { label = "Down-Left", maxLength = 100 }),
    msg_left = UI.Text("Watch out!", { label = "Left", maxLength = 100 }),
    msg_up_left = UI.Text("Incoming!", { label = "Up-Left", maxLength = 100 }),
    
    radius = UI.Slider(150, { min = 50, max = 300, label = "Wheel Radius", suffix = "px" }),
    font_size = UI.Slider(16, { min = 12, max = 28, label = "Font Size", suffix = "pt" }),
})

local wheelActive = false
local startPos = { x = 0, y = 0 }
local selectedDir = nil

local directions = {
    { name = "up", angle = 90, key = "msg_up" },
    { name = "up_right", angle = 45, key = "msg_up_right" },
    { name = "right", angle = 0, key = "msg_right" },
    { name = "down_right", angle = 315, key = "msg_down_right" },
    { name = "down", angle = 270, key = "msg_down" },
    { name = "down_left", angle = 225, key = "msg_down_left" },
    { name = "left", angle = 180, key = "msg_left" },
    { name = "up_left", angle = 135, key = "msg_up_left" },
}

local function getDirectionFromMouse(startX, startY)
    local mx, my = System.Mouse()
    local dx = mx - startX
    local dy = my - startY
    local distance = math.sqrt(dx * dx + dy * dy)
    
    if distance < cfg.radius * 0.3 then
        return nil
    end
    
    local angle = math.atan2(-dy, dx) * 180 / math.pi
    if angle < 0 then angle = angle + 360 end
    
    -- Find closest direction (8-way)
    local closest = nil
    local minDiff = 360
    for _, dir in ipairs(directions) do
        local diff = math.abs(angle - dir.angle)
        if diff > 180 then diff = 360 - diff end
        if diff < minDiff then
            minDiff = diff
            closest = dir.name
        end
    end
    
    return closest
end

function OnDown(key)
    if not cfg.enabled or key ~= cfg.trigger then
        return true
    end
    
    wheelActive = true
    startPos.x, startPos.y = System.Mouse()
    selectedDir = nil
    
    return false
end

function OnUp(key, duration)
    if not cfg.enabled or key ~= cfg.trigger then
        return true
    end
    
    if wheelActive and selectedDir then
        -- Find the message for this direction
        for _, dir in ipairs(directions) do
            if dir.name == selectedDir then
                local message = cfg[dir.key]
                if message and #message > 0 then
                    Clipboard.Set(message)
                    HID.Press("LCtrl+V")
                    UI.Notify("Sent: " .. message, "info")
                end
                break
            end
        end
    end
    
    wheelActive = false
    selectedDir = nil
    
    return false
end

function OnMove(dx, dy)
    if not wheelActive then
        return true
    end
    
    local mx, my = System.Mouse()
    selectedDir = getDirectionFromMouse(startPos.x, startPos.y)
    
    return true
end

function OnBlur()
    wheelActive = false
    selectedDir = nil
end

This script creates a chat wheel macro that sends custom messages based on mouse direction. Here's how it works:

Features

  • 8-directional wheel: Up, Up-Right, Right, Down-Right, Down, Down-Left, Left, Up-Left
  • Customizable messages: Define your own text for each direction in the UI
  • Mouse-based selection: Move your mouse in a direction while holding the trigger key
  • Adjustable radius: Control how far you need to move to select a direction
  • Dead zone: Movement within 30% of radius is ignored (center area)
  • Clipboard paste: Messages are pasted using Ctrl+V for reliability

How to Use

  1. Hold your trigger key (default: Mouse3/middle click)
  2. Move your mouse in one of 8 directions
  3. Release to send the message
  4. Customize all 8 messages in the UI

UI Configuration

  • Trigger Key: Which button activates the wheel
  • 8 Message Fields: Customize text for each direction
  • Wheel Radius: Distance you need to move to register a selection
  • Font Size: Available for future UI wheel rendering

The script uses angle detection to find the closest direction, so you don't need to be perfectly aligned. Move your mouse roughly toward one of the 8 cardinal/diagonal directions and it will snap to the closest one.

Learn more: