[Source] Pixel Combat / Rotation Bot menu

Shout-Out

User Tag List

Results 1 to 11 of 11
  1. #1
    mazer's Avatar Active Member
    Reputation
    56
    Join Date
    Sep 2007
    Posts
    87
    Thanks G/R
    11/28
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Source] Pixel Combat / Rotation Bot

    Hi folks,
    I want to share my recently updated pixel-reader combat/rotation helper that I've been using over the last decade.
    It's a two-part solution that works with ConRO (or can be adapted for other rotation addons like Ovale or Hekili).

    How it works:

    • The Lua addon creates a tiny 1x1 pixel frame at the top-left corner of your WoW window. This pixel changes color based on ConRO's spell suggestions, with 10 different colors mapped to keys 1-0. The addon is smart enough to not change colors during casting or when Global Cooldown is active.
    • The AutoIt script runs alongside WoW and continuously monitors this pixel. When it detects a color change, it sends the corresponding keypress (1-0).

    Features include:


    • Three different key-sending methods for compatibility
    • Adjustable delay between keypresses
    • Optional random delay variation
    • Simple GUI interface with status indicators
    • Hotkeys for quick pause/resume (DEL) and color checking (INS)

    Key Features:

    • Works with any class and level (thanks to ConRO compatibility)
    • Customizable delay
    • Easy to modify for different keybinds or color mappings
    • Includes visual feedback through the GUI
    • Automatically pauses during casting and GCD

    Requirements:

    • ConRO addon (+ConRO data for your class) installed and setup in WoW (set only display on hostile)
    • AutoIt and SciTE for running the pixel reader
    • Spells bound to number keys 1-0


    The code is well-documented and can be easily modified to work with other rotation addons or different key mappings. Feel free to use it as a base for your own solutions or experiments.

    AutoIT Script:
    Code:
    #include  <GUIConstants.au3>
    #include  <Misc.au3>
    
    
    ; =================================================================================================
    ; This script is a color helper tool that scans a specific pixel in World of Warcraft
    ; and sends corresponding keystrokes based on the color detected.
    ; It includes a GUI for control and various sending methods for compatibility.
    ; =================================================================================================
    
    
    ; Constants for window detection and scanning
    Global Const $WINDOW_STRING = "[TITLE:World of Warcraft]"
    Global Const $SCAN_POSITION_X = 1    ; X coordinate of the pixel to scan
    Global Const $SCAN_POSITION_Y = 1    ; Y coordinate of the pixel to scan
    Global Const $SOUND_PAUSE = 500      ; Frequency for pause sound notification
    Global Const $SOUND_RESUME = 1000    ; Frequency for resume sound notification
    
    
    ; Constants for different key sending methods
    Global Const $SEND_METHOD_CONTROL = 1 ; Using ControlSend function
    Global Const $SEND_METHOD_SEND = 2    ; Using Send function
    Global Const $SEND_METHOD_KEYS = 3    ; Using direct keyboard input via DLL calls
    
    
    ; Global variables for program state and GUI elements
    Global $pause = True                  ; Program starts in paused state
    Global $guiHandle                     ; Main GUI window handle
    Global $statusLabel                   ; Shows if program is running or paused
    Global $colorLabel                    ; Shows current color being detected
    Global $keyLabel                      ; Shows last key that was sent
    Global $radioControl                  ; Radio button for ControlSend method
    Global $radioSend                     ; Radio button for Send method
    Global $radioKeys                     ; Radio button for direct keyboard input
    Global $btnToggle                     ; Button to start/pause the program
    Global $btnColor                      ; Button to check current color
    Global $btnExit                       ; Button to exit program
    Global $sendMethod = $SEND_METHOD_KEYS ; Default send method
    Global $colorMap = _InitColorMap()     ; Initialize color to key mapping
    Global $dll                           ; Handle for user32.dll
    Global $sliderDelay                   ; Slider for controlling delay between keypresses
    Global $checkboxRandom                ; Checkbox for enabling random delay
    Global $minDelay = 100               ; Minimum delay between actions in milliseconds
    Global $maxDelay = 130               ; Maximum delay (calculated based on minDelay if random is enabled)
    
    
    ; Set up hotkeys
    HotKeySet("{DEL}", "_TogglePause")    ; DEL key toggles pause/resume
    HotKeySet("{INS}", "_ShowCurrentColor") ; INS key shows current color
    
    
    ; Initialize DLL and GUI
    $dll = DllOpen("user32.dll")
    _CreateGUI()
    
    
    ; Start main program loop
    MainLoop()
    
    
    ; Creates and initializes the GUI window
    Func _CreateGUI()
        $guiHandle = GUICreate("Color Helper", 300, 240)
    
    
        ; Status indicators
        GUICtrlCreateLabel("Status:", 10, 10)
        $statusLabel = GUICtrlCreateLabel("Paused", 100, 10)
    
    
        GUICtrlCreateLabel("Current Color:", 10, 40)
        $colorLabel = GUICtrlCreateLabel("-", 100, 40, 180)
    
    
        GUICtrlCreateLabel("Last Key:", 10, 70)
        $keyLabel = GUICtrlCreateLabel("-", 100, 70)
    
    
        ; Create radio buttons for different send methods
        Local $groupSend = GUICtrlCreateGroup("Send Method", 10, 95, 280, 50)
        $radioControl = GUICtrlCreateRadio("ControlSend", 20, 115, 80, 20)
        $radioSend = GUICtrlCreateRadio("Send", 110, 115, 80, 20)
        $radioKeys = GUICtrlCreateRadio("Keys", 200, 115, 80, 20)
        GUICtrlSetState($radioKeys, $GUI_CHECKED)
        $sendMethod = $SEND_METHOD_KEYS
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create delay control elements
        GUICtrlCreateGroup("Delay Settings", 10, 145, 280, 70)
        GUICtrlCreateLabel("ms Delay:", 20, 165, 55, 20)
        $sliderDelay = GUICtrlCreateSlider(80, 165, 150, 20)
        GUICtrlSetLimit($sliderDelay, 500, 10)
        GUICtrlSetData($sliderDelay, 100)
        Global $labelDelayValue = GUICtrlCreateLabel("100", 235, 165, 40, 20)
        $checkboxRandom = GUICtrlCreateCheckbox("Add random delay (+30%)", 20, 185, 140, 20)
        GUICtrlSetState($checkboxRandom, $GUI_CHECKED)
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create control buttons
        $btnToggle = GUICtrlCreateButton("Start/Pause (DEL)", 10, 210, 100, 25)
        $btnColor = GUICtrlCreateButton("Check Color (INS)", 120, 210, 100, 25)
        $btnExit = GUICtrlCreateButton("Exit", 230, 210, 60, 25)
    
    
        GUISetState(@SW_SHOW)
    EndFunc
    
    
    ; Initializes the color-to-key mapping array
    ; Each entry contains a hex color code and its corresponding key to send
    Func _InitColorMap()
        Local $map[10][2]
        $map[0][0] = "00FF00" ; Green   -> Key 1
        $map[0][1] = "1"
        $map[1][0] = "0000FF" ; Blue    -> Key 2
        $map[1][1] = "2"
        $map[2][0] = "FFFF00" ; Yellow  -> Key 3
        $map[2][1] = "3"
        $map[3][0] = "FF00FF" ; Magenta -> Key 4
        $map[3][1] = "4"
        $map[4][0] = "00FFFF" ; Cyan    -> Key 5
        $map[4][1] = "5"
        $map[5][0] = "808080" ; Gray    -> Key 6
        $map[5][1] = "6"
        $map[6][0] = "FF8000" ; Orange  -> Key 7
        $map[6][1] = "7"
        $map[7][0] = "00FF80" ; Turquoise -> Key 8
        $map[7][1] = "8"
        $map[8][0] = "8000FF" ; Purple  -> Key 9
        $map[8][1] = "9"
        $map[9][0] = "FF0000" ; Red     -> Key 0
        $map[9][1] = "0"
        Return $map
    EndFunc
    
    
    ; Main program loop that handles color detection and key sending
    Func MainLoop()
        Local $lastActionTime = 0
        Local $nextDelay = Random(100, 250)
    
    
        While 1
            _CheckGUIEvents()
    
    
            If WinActive($WINDOW_STRING) And Not $pause Then
                Local $currentTime = TimerInit()
    
    
                ; Check if enough time has passed since last action
                If $currentTime - $lastActionTime >= $nextDelay Then
                    ; Get color at scan position and find corresponding key
                    Local $currentColor = Hex(PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y), 6)
                    Local $key = _GetKeyForColor($currentColor)
    
    
                    If $key Then
                        SendKeyToWin($key)
                        GUICtrlSetData($keyLabel, $key)
                        GUICtrlSetData($colorLabel, $currentColor)
                        $lastActionTime = $currentTime
                        _UpdateDelays()
                        $nextDelay = Random($minDelay, $maxDelay)
                    EndIf
                EndIf
            EndIf
    
    
            Sleep(10) ; Prevent high CPU usage
        WEnd
    EndFunc
    
    
    ; Handles GUI events (button clicks, radio buttons, etc.)
    Func _CheckGUIEvents()
        Local $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                _Exit()
            Case $btnToggle
                _TogglePause()
            Case $btnColor
                _ShowCurrentColor()
            Case $btnExit
                _Exit()
            Case $radioControl
                $sendMethod = $SEND_METHOD_CONTROL
            Case $radioSend
                $sendMethod = $SEND_METHOD_SEND
            Case $radioKeys
                $sendMethod = $SEND_METHOD_KEYS
            Case $sliderDelay
                $minDelay = GUICtrlRead($sliderDelay)
            Case $checkboxRandom
                _UpdateDelays()
        EndSwitch
    EndFunc
    
    
    ; Updates delay settings based on slider and random checkbox
    Func _UpdateDelays()
        $minDelay = GUICtrlRead($sliderDelay)
        If BitAND(GUICtrlRead($checkboxRandom), $GUI_CHECKED) Then
            $maxDelay = Int($minDelay * 1.3) ; Add 30% for maximum random delay
        Else
            $maxDelay = $minDelay ; No randomization
        EndIf
    EndFunc
    
    
    ; Finds the corresponding key for a given color from the color map
    Func _GetKeyForColor($hexColor)
        For $i = 0 To UBound($colorMap) - 1
            If $colorMap[$i][0] = $hexColor Then
                Return $colorMap[$i][1]
            EndIf
        Next
        Return ""
    EndFunc
    
    
    ; Sends a key to the window using the selected send method
    Func SendKeyToWin($key)
        Switch $sendMethod
            Case $SEND_METHOD_CONTROL
                ControlSend($WINDOW_STRING, "", "", $key, 1)
            Case $SEND_METHOD_SEND
                If WinActive($WINDOW_STRING) Then
                    Send($key)
                EndIf
            Case $SEND_METHOD_KEYS
                If WinActive($WINDOW_STRING) Then
                    _SendKeys($key)
                EndIf
        EndSwitch
    EndFunc
    
    
    ; Sends keys using direct keyboard input via DLL calls
    Func _SendKeys($key)
        Local $code = Asc($key)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 0, "int", 0)  ; Key down
        Sleep(1)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 2, "int", 0)  ; Key up
    EndFunc
    
    
    ; Toggles the pause state of the program
    Func _TogglePause()
        $pause = Not $pause
        If $pause Then
            Beep($SOUND_PAUSE, 100)
            GUICtrlSetData($statusLabel, "Paused")
        Else
            Beep($SOUND_RESUME, 100)
            GUICtrlSetData($statusLabel, "Active")
        EndIf
    EndFunc
    
    
    ; Shows the current color at the scan position
    Func _ShowCurrentColor()
        Local $color = PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y)
        Local $hexColor = Hex($color, 6)
        GUICtrlSetData($colorLabel, $hexColor)
    EndFunc
    
    
    ; Cleans up and exits the program
    Func _Exit()
        GUIDelete($guiHandle)
        DllClose($dll)
        Exit
    EndFunc
    LUA Code (create an Addon or use WowLua Addon and run from there):
    Code:
    -- =====================================================================
    -- This script creates a color indicator frame in World of Warcraft
    -- It reads text from ConROWindow and changes colors based on the number displayed
    -- The frame changes to white during casting, channeling, or when GCD is active
    -- =====================================================================
    
    
    -- Clean up any existing frame to prevent duplicates
    if ColorFrame then
       ColorFrame:Hide()
       ColorFrame:ClearAllPoints()
       ColorFrame:SetParent(nil)
       ColorFrame = nil
    end
    
    
    -- Define color mapping array
    -- Each entry contains RGB values (red, green, blue) from 0 to 1
    -- Index corresponds to the number displayed in ConROWindow (0-9)
    local colors = {
       {1, 0, 0},    -- 0: Red
       {0, 1, 0},    -- 1: Green
       {0, 0, 1},    -- 2: Blue
       {1, 1, 0},    -- 3: Yellow
       {1, 0, 1},    -- 4: Magenta
       {0, 1, 1},    -- 5: Cyan
       {0.5, 0.5, 0.5}, -- 6: Gray
       {1, 0.5, 0},  -- 7: Orange
       {0, 1, 0.5},  -- 8: Turquoise
       {0.5, 0, 1}   -- 9: Purple
    }
    
    
    -- Create the main frame
    -- Attaches to WorldFrame to ensure it's always visible
    -- Uses BackdropTemplate for visual debugging
    local f = CreateFrame("Frame", "ColorFrame", WorldFrame, "BackdropTemplate")
    f:SetHeight(1)
    f:SetWidth(1)
    f:SetPoint("TOPLEFT", WorldFrame, "TOPLEFT", 0, 0)  -- Position at top-left corner
    f:SetIgnoreParentScale(true)  -- Prevent inheritance of parent's scaling
    f:SetScale(1)
    
    
    -- Create and setup the texture for the frame
    -- Uses a white 8x8 texture as base which will be colored
    local t = f:CreateTexture(nil, "ARTWORK")
    t:SetTexture("Interface\\BUTTONS\\WHITE8X8")
    t:SetTexCoord(0.07, 0.93, 0.07, 0.93)  -- Adjust texture coordinates to prevent bleeding
    t:SetAllPoints(f)  -- Make texture fill the entire frame
    t:SetVertexColor(1, 1, 1, 1)  -- Start with white color
    f.texture = t
    
    
    -- Add a debug backdrop to make frame visible during development
    -- Creates a black semi-transparent background with a black border
    f:SetBackdrop({
          bgFile = "Interface\\Buttons\\WHITE8X8",
          edgeFile = "Interface\\Buttons\\WHITE8X8",
          edgeSize = 1,
    })
    f:SetBackdropColor(0, 0, 0, 0.5)  -- Semi-transparent black background
    f:SetBackdropBorderColor(0, 0, 0, 1)  -- Solid black border
    
    
    -- Update timing configuration
    local updateInterval = 0.1  -- Check for updates every 0.1 seconds
    local timeSinceLastUpdate = 0
    
    
    -- Function to check if Global Cooldown (GCD) is active
    -- Uses spell ID 61304 which represents the global cooldown
    local function IsGCDActive()
        local spellCooldownInfo = C_Spell.GetSpellCooldown(61304)
        if spellCooldownInfo.startTime == 0 then return false end
        return (spellCooldownInfo.startTime + spellCooldownInfo.duration - GetTime()) > 0
    end
    
    
    -- Main update function that runs on every frame
    f:SetScript("OnUpdate", function(self, elapsed)
          timeSinceLastUpdate = timeSinceLastUpdate + elapsed
          
          -- Only update at specified interval to reduce performance impact
          if timeSinceLastUpdate >= updateInterval then
             timeSinceLastUpdate = 0
             
             -- Check player state (casting, channeling, GCD)
             local casting = UnitCastingInfo("player") ~= nil
             local channeling = UnitChannelInfo("player") ~= nil
             local gcdActive = IsGCDActive()
             
             -- Set color to white if player is casting, channeling, or GCD is active
             if casting or channeling or gcdActive then
                t:SetVertexColor(1, 1, 1, 1)
                return
             end
             
             -- Color logic when player is not casting and GCD is not active
             -- Reads number from ConROWindow and sets corresponding color
             if ConROWindow and ConROWindow.fontkey and ConROWindow.fontkey:IsVisible() then
                local text = ConROWindow.fontkey:GetText()
                if text then
                   local number = tonumber(text)
                   if number and colors[number + 1] then
                      -- Set color from our color mapping array
                      local r, g, b = unpack(colors[number + 1])
                      t:SetVertexColor(r, g, b, 1)
                   else
                      -- Default to white if number is invalid
                      t:SetVertexColor(1, 1, 1, 1)
                   end
                else
                   -- Default to white if no text
                   t:SetVertexColor(1, 1, 1, 1)
                end
             else
                -- Default to white if ConROWindow is not visible
                t:SetVertexColor(1, 1, 1, 1)
             end
          end
    end)
    
    
    -- Show the frame
    f:Show()
    
    
    --print("ColorFrame script loaded successfully!")  -- Debug message
    Last edited by mazer; 01-10-2025 at 05:06 PM.

    [Source] Pixel Combat / Rotation Bot
  2. Thanks pickleback, hackerlol (2 members gave Thanks to mazer for this useful post)
  3. #2
    Kutar's Avatar Member
    Reputation
    1
    Join Date
    Jul 2016
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great work!!! going to try, but can u make a video or something how to setup or using in game????

  4. #3
    AsherGray's Avatar Member
    Reputation
    1
    Join Date
    Jan 2025
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by mazer View Post
    Hi folks,
    I want to share my recently updated pixel-reader combat/rotation helper that I've been using over the last decade.
    It's a two-part solution that works with ConRO (or can be adapted for other rotation addons like Ovale or Hekili).

    How it works:

    • The Lua addon creates a tiny 1x1 pixel frame at the top-left corner of your WoW window. This pixel changes color based on ConRO's spell suggestions, with 10 different colors mapped to keys 1-0. The addon is smart enough to not change colors during casting or when Global Cooldown is active.
    • The AutoIt script runs alongside WoW and continuously monitors this pixel. When it detects a color change, it sends the corresponding keypress (1-0).

    Features include:


    • Three different key-sending methods for compatibility
    • Adjustable delay between keypresses
    • Optional random delay variation
    • Simple GUI interface with status indicators
    • Hotkeys for quick pause/resume (DEL) and color checking (INS)

    Key Features:

    • Works with any class and level (thanks to ConRO compatibility)
    • Customizable delay
    • Easy to modify for different keybinds or color mappings
    • Includes visual feedback through the GUI
    • Automatically pauses during casting and GCD

    Requirements:

    • ConRO addon (+ConRO data for your class) installed and setup in WoW (set only display on hostile)
    • AutoIt and SciTE for running the pixel reader
    • Spells bound to number keys 1-0


    The code is well-documented and can be easily modified to work with other rotation addons or different key mappings. Feel free to use it as a base for your own solutions or experiments.

    AutoIT Script:
    Code:
    #include  <GUIConstants.au3>
    #include  <Misc.au3>
    
    
    ; =================================================================================================
    ; This script is a color helper tool that scans a specific pixel in World of Warcraft
    ; and sends corresponding keystrokes based on the color detected.
    ; It includes a GUI for control and various sending methods for compatibility.
    ; =================================================================================================
    
    
    ; Constants for window detection and scanning
    Global Const $WINDOW_STRING = "[TITLE:World of Warcraft]"
    Global Const $SCAN_POSITION_X = 1    ; X coordinate of the pixel to scan
    Global Const $SCAN_POSITION_Y = 1    ; Y coordinate of the pixel to scan
    Global Const $SOUND_PAUSE = 500      ; Frequency for pause sound notification
    Global Const $SOUND_RESUME = 1000    ; Frequency for resume sound notification
    
    
    ; Constants for different key sending methods
    Global Const $SEND_METHOD_CONTROL = 1 ; Using ControlSend function
    Global Const $SEND_METHOD_SEND = 2    ; Using Send function
    Global Const $SEND_METHOD_KEYS = 3    ; Using direct keyboard input via DLL calls
    
    
    ; Global variables for program state and GUI elements
    Global $pause = True                  ; Program starts in paused state
    Global $guiHandle                     ; Main GUI window handle
    Global $statusLabel                   ; Shows if program is running or paused
    Global $colorLabel                    ; Shows current color being detected
    Global $keyLabel                      ; Shows last key that was sent
    Global $radioControl                  ; Radio button for ControlSend method
    Global $radioSend                     ; Radio button for Send method
    Global $radioKeys                     ; Radio button for direct keyboard input
    Global $btnToggle                     ; Button to start/pause the program
    Global $btnColor                      ; Button to check current color
    Global $btnExit                       ; Button to exit program
    Global $sendMethod = $SEND_METHOD_KEYS ; Default send method
    Global $colorMap = _InitColorMap()     ; Initialize color to key mapping
    Global $dll                           ; Handle for user32.dll
    Global $sliderDelay                   ; Slider for controlling delay between keypresses
    Global $checkboxRandom                ; Checkbox for enabling random delay
    Global $minDelay = 100               ; Minimum delay between actions in milliseconds
    Global $maxDelay = 130               ; Maximum delay (calculated based on minDelay if random is enabled)
    
    
    ; Set up hotkeys
    HotKeySet("{DEL}", "_TogglePause")    ; DEL key toggles pause/resume
    HotKeySet("{INS}", "_ShowCurrentColor") ; INS key shows current color
    
    
    ; Initialize DLL and GUI
    $dll = DllOpen("user32.dll")
    _CreateGUI()
    
    
    ; Start main program loop
    MainLoop()
    
    
    ; Creates and initializes the GUI window
    Func _CreateGUI()
        $guiHandle = GUICreate("Color Helper", 300, 240)
    
    
        ; Status indicators
        GUICtrlCreateLabel("Status:", 10, 10)
        $statusLabel = GUICtrlCreateLabel("Paused", 100, 10)
    
    
        GUICtrlCreateLabel("Current Color:", 10, 40)
        $colorLabel = GUICtrlCreateLabel("-", 100, 40, 180)
    
    
        GUICtrlCreateLabel("Last Key:", 10, 70)
        $keyLabel = GUICtrlCreateLabel("-", 100, 70)
    
    
        ; Create radio buttons for different send methods
        Local $groupSend = GUICtrlCreateGroup("Send Method", 10, 95, 280, 50)
        $radioControl = GUICtrlCreateRadio("ControlSend", 20, 115, 80, 20)
        $radioSend = GUICtrlCreateRadio("Send", 110, 115, 80, 20)
        $radioKeys = GUICtrlCreateRadio("Keys", 200, 115, 80, 20)
        GUICtrlSetState($radioKeys, $GUI_CHECKED)
        $sendMethod = $SEND_METHOD_KEYS
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create delay control elements
        GUICtrlCreateGroup("Delay Settings", 10, 145, 280, 70)
        GUICtrlCreateLabel("ms Delay:", 20, 165, 55, 20)
        $sliderDelay = GUICtrlCreateSlider(80, 165, 150, 20)
        GUICtrlSetLimit($sliderDelay, 500, 10)
        GUICtrlSetData($sliderDelay, 100)
        Global $labelDelayValue = GUICtrlCreateLabel("100", 235, 165, 40, 20)
        $checkboxRandom = GUICtrlCreateCheckbox("Add random delay (+30%)", 20, 185, 140, 20)
        GUICtrlSetState($checkboxRandom, $GUI_CHECKED)
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create control buttons
        $btnToggle = GUICtrlCreateButton("Start/Pause (DEL)", 10, 210, 100, 25)
        $btnColor = GUICtrlCreateButton("Check Color (INS)", 120, 210, 100, 25)
        $btnExit = GUICtrlCreateButton("Exit", 230, 210, 60, 25)
    
    
        GUISetState(@SW_SHOW)
    EndFunc
    
    
    ; Initializes the color-to-key mapping array
    ; Each entry contains a hex color code and its corresponding key to send
    Func _InitColorMap()
        Local $map[10][2]
        $map[0][0] = "00FF00" ; Green   -> Key 1
        $map[0][1] = "1"
        $map[1][0] = "0000FF" ; Blue    -> Key 2
        $map[1][1] = "2"
        $map[2][0] = "FFFF00" ; Yellow  -> Key 3
        $map[2][1] = "3"
        $map[3][0] = "FF00FF" ; Magenta -> Key 4
        $map[3][1] = "4"
        $map[4][0] = "00FFFF" ; Cyan    -> Key 5
        $map[4][1] = "5"
        $map[5][0] = "808080" ; Gray    -> Key 6
        $map[5][1] = "6"
        $map[6][0] = "FF8000" ; Orange  -> Key 7
        $map[6][1] = "7"
        $map[7][0] = "00FF80" ; Turquoise -> Key 8
        $map[7][1] = "8"
        $map[8][0] = "8000FF" ; Purple  -> Key 9
        $map[8][1] = "9"
        $map[9][0] = "FF0000" ; Red     -> Key 0
        $map[9][1] = "0"
        Return $map
    EndFunc
    
    
    ; Main program loop that handles color detection and key sending
    Func MainLoop()
        Local $lastActionTime = 0
        Local $nextDelay = Random(100, 250)
    
    
        While 1
            _CheckGUIEvents()
    
    
            If WinActive($WINDOW_STRING) And Not $pause Then
                Local $currentTime = TimerInit()
    
    
                ; Check if enough time has passed since last action
                If $currentTime - $lastActionTime >= $nextDelay Then
                    ; Get color at scan position and find corresponding key
                    Local $currentColor = Hex(PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y), 6)
                    Local $key = _GetKeyForColor($currentColor)
    
    
                    If $key Then
                        SendKeyToWin($key)
                        GUICtrlSetData($keyLabel, $key)
                        GUICtrlSetData($colorLabel, $currentColor)
                        $lastActionTime = $currentTime
                        _UpdateDelays()
                        $nextDelay = Random($minDelay, $maxDelay)
                    EndIf
                EndIf
            EndIf
    
    
            Sleep(10) ; Prevent high CPU usage
        WEnd
    EndFunc
    
    
    ; Handles GUI events (button clicks, radio buttons, etc.)
    Func _CheckGUIEvents()
        Local $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                _Exit()
            Case $btnToggle
                _TogglePause()
            Case $btnColor
                _ShowCurrentColor()
            Case $btnExit
                _Exit()
            Case $radioControl
                $sendMethod = $SEND_METHOD_CONTROL
            Case $radioSend
                $sendMethod = $SEND_METHOD_SEND
            Case $radioKeys
                $sendMethod = $SEND_METHOD_KEYS
            Case $sliderDelay
                $minDelay = GUICtrlRead($sliderDelay)
            Case $checkboxRandom
                _UpdateDelays()
        EndSwitch
    EndFunc
    
    
    ; Updates delay settings based on slider and random checkbox
    Func _UpdateDelays()
        $minDelay = GUICtrlRead($sliderDelay)
        If BitAND(GUICtrlRead($checkboxRandom), $GUI_CHECKED) Then
            $maxDelay = Int($minDelay * 1.3) ; Add 30% for maximum random delay
        Else
            $maxDelay = $minDelay ; No randomization
        EndIf
    EndFunc
    
    
    ; Finds the corresponding key for a given color from the color map
    Func _GetKeyForColor($hexColor)
        For $i = 0 To UBound($colorMap) - 1
            If $colorMap[$i][0] = $hexColor Then
                Return $colorMap[$i][1]
            EndIf
        Next
        Return ""
    EndFunc
    
    
    ; Sends a key to the window using the selected send method
    Func SendKeyToWin($key)
        Switch $sendMethod
            Case $SEND_METHOD_CONTROL
                ControlSend($WINDOW_STRING, "", "", $key, 1)
            Case $SEND_METHOD_SEND
                If WinActive($WINDOW_STRING) Then
                    Send($key)
                EndIf
            Case $SEND_METHOD_KEYS
                If WinActive($WINDOW_STRING) Then
                    _SendKeys($key)
                EndIf
        EndSwitch
    EndFunc
    
    
    ; Sends keys using direct keyboard input via DLL calls
    Func _SendKeys($key)
        Local $code = Asc($key)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 0, "int", 0)  ; Key down
        Sleep(1)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 2, "int", 0)  ; Key up
    EndFunc
    
    
    ; Toggles the pause state of the program
    Func _TogglePause()
        $pause = Not $pause
        If $pause Then
            Beep($SOUND_PAUSE, 100)
            GUICtrlSetData($statusLabel, "Paused")
        Else
            Beep($SOUND_RESUME, 100)
            GUICtrlSetData($statusLabel, "Active")
        EndIf
    EndFunc
    
    
    ; Shows the current color at the scan position
    Func _ShowCurrentColor()
        Local $color = PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y)
        Local $hexColor = Hex($color, 6)
        GUICtrlSetData($colorLabel, $hexColor)
    EndFunc
    
    
    ; Cleans up and exits the program
    Func _Exit()
        GUIDelete($guiHandle)
        DllClose($dll)
        Exit
    EndFunc
    LUA Code (create an Addon or use WowLua Addon and run from there):
    Code:
    -- =====================================================================
    -- This script creates a color indicator frame in World of Warcraft
    -- It reads text from ConROWindow and changes colors based on the number displayed
    -- The frame changes to white during casting, channeling, or when GCD is active
    -- =====================================================================
    
    
    -- Clean up any existing frame to prevent duplicates
    if ColorFrame then
       ColorFrame:Hide()
       ColorFrame:ClearAllPoints()
       ColorFrame:SetParent(nil)
       ColorFrame = nil
    end
    
    
    -- Define color mapping array
    -- Each entry contains RGB values (red, green, blue) from 0 to 1
    -- Index corresponds to the number displayed in ConROWindow (0-9)
    local colors = {
       {1, 0, 0},    -- 0: Red
       {0, 1, 0},    -- 1: Green
       {0, 0, 1},    -- 2: Blue
       {1, 1, 0},    -- 3: Yellow
       {1, 0, 1},    -- 4: Magenta
       {0, 1, 1},    -- 5: Cyan
       {0.5, 0.5, 0.5}, -- 6: Gray
       {1, 0.5, 0},  -- 7: Orange
       {0, 1, 0.5},  -- 8: Turquoise
       {0.5, 0, 1}   -- 9: Purple
    }
    
    
    -- Create the main frame
    -- Attaches to WorldFrame to ensure it's always visible
    -- Uses BackdropTemplate for visual debugging
    local f = CreateFrame("Frame", "ColorFrame", WorldFrame, "BackdropTemplate")
    f:SetHeight(1)
    f:SetWidth(1)
    f:SetPoint("TOPLEFT", WorldFrame, "TOPLEFT", 0, 0)  -- Position at top-left corner
    f:SetIgnoreParentScale(true)  -- Prevent inheritance of parent's scaling
    f:SetScale(1)
    
    
    -- Create and setup the texture for the frame
    -- Uses a white 8x8 texture as base which will be colored
    local t = f:CreateTexture(nil, "ARTWORK")
    t:SetTexture("Interface\\BUTTONS\\WHITE8X8")
    t:SetTexCoord(0.07, 0.93, 0.07, 0.93)  -- Adjust texture coordinates to prevent bleeding
    t:SetAllPoints(f)  -- Make texture fill the entire frame
    t:SetVertexColor(1, 1, 1, 1)  -- Start with white color
    f.texture = t
    
    
    -- Add a debug backdrop to make frame visible during development
    -- Creates a black semi-transparent background with a black border
    f:SetBackdrop({
          bgFile = "Interface\\Buttons\\WHITE8X8",
          edgeFile = "Interface\\Buttons\\WHITE8X8",
          edgeSize = 1,
    })
    f:SetBackdropColor(0, 0, 0, 0.5)  -- Semi-transparent black background
    f:SetBackdropBorderColor(0, 0, 0, 1)  -- Solid black border
    
    
    -- Update timing configuration
    local updateInterval = 0.1  -- Check for updates every 0.1 seconds
    local timeSinceLastUpdate = 0
    
    
    -- Function to check if Global Cooldown (GCD) is active
    -- Uses spell ID 61304 which represents the global cooldown
    local function IsGCDActive()
        local spellCooldownInfo = C_Spell.GetSpellCooldown(61304)
        if spellCooldownInfo.startTime == 0 then return false end
        return (spellCooldownInfo.startTime + spellCooldownInfo.duration - GetTime()) > 0
    end
    
    
    -- Main update function that runs on every frame
    f:SetScript("OnUpdate", function(self, elapsed)
          timeSinceLastUpdate = timeSinceLastUpdate + elapsed
          
          -- Only update at specified interval to reduce performance impact
          if timeSinceLastUpdate >= updateInterval then
             timeSinceLastUpdate = 0
             
             -- Check player state (casting, channeling, GCD)
             local casting = UnitCastingInfo("player") ~= nil
             local channeling = UnitChannelInfo("player") ~= nil
             local gcdActive = IsGCDActive()
             
             -- Set color to white if player is casting, channeling, or GCD is active
             if casting or channeling or gcdActive then
                t:SetVertexColor(1, 1, 1, 1)
                return
             end
             
             -- Color logic when player is not casting and GCD is not active
             -- Reads number from ConROWindow and sets corresponding color
             if ConROWindow and ConROWindow.fontkey and ConROWindow.fontkey:IsVisible() then
                local text = ConROWindow.fontkey:GetText()
                if text then
                   local number = tonumber(text)
                   if number and colors[number + 1] then
                      -- Set color from our color mapping array
                      local r, g, b = unpack(colors[number + 1])
                      t:SetVertexColor(r, g, b, 1)
                   else
                      -- Default to white if number is invalid
                      t:SetVertexColor(1, 1, 1, 1)
                   end
                else
                   -- Default to white if no text
                   t:SetVertexColor(1, 1, 1, 1)
                end
             else
                -- Default to white if ConROWindow is not visible
                t:SetVertexColor(1, 1, 1, 1)
             end
          end
    end)
    
    
    -- Show the frame
    f:Show()
    
    
    --print("ColorFrame script loaded successfully!")  -- Debug message
    Thanks for sharing it.

  5. #4
    SterlingHolt's Avatar Member
    Reputation
    1
    Join Date
    Jan 2025
    Posts
    2
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by mazer View Post
    Hi folks,
    I want to share my recently updated pixel-reader combat/rotation helper that I've been using over the last decade.
    It's a two-part solution that works with ConRO (or can be adapted for other rotation addons like Ovale or Hekili).

    How it works:

    • The Lua addon creates a tiny 1x1 pixel frame at the top-left corner of your WoW window. This pixel changes color based on ConRO's spell suggestions, with 10 different colors mapped to keys 1-0. The addon is smart enough to not change colors during casting or when Global Cooldown is active.
    • The AutoIt script runs alongside WoW and continuously monitors this pixel. When it detects a color change, it sends the corresponding keypress (1-0).

    Features include:


    • Three different key-sending methods for compatibility
    • Adjustable delay between keypresses
    • Optional random delay variation
    • Simple GUI interface with status indicators
    • Hotkeys for quick pause/resume (DEL) and color checking (INS)

    Key Features:

    • Works with any class and level (thanks to ConRO compatibility)
    • Customizable delay
    • Easy to modify for different keybinds or color mappings
    • Includes visual feedback through the GUI
    • Automatically pauses during casting and GCD

    Requirements:

    • ConRO addon (+ConRO data for your class) installed and setup in WoW (set only display on hostile)
    • AutoIt and SciTE for running the pixel reader
    • Spells bound to number keys 1-0


    The code is well-documented and can be easily modified to work with other rotation addons or different key mappings. Feel free to use it as a base for your own solutions or experiments.

    AutoIT Script:
    Code:
    #include  <GUIConstants.au3>
    #include  <Misc.au3>
    
    
    ; =================================================================================================
    ; This script is a color helper tool that scans a specific pixel in World of Warcraft
    ; and sends corresponding keystrokes based on the color detected.
    ; It includes a GUI for control and various sending methods for compatibility.
    ; =================================================================================================
    
    
    ; Constants for window detection and scanning
    Global Const $WINDOW_STRING = "[TITLE:World of Warcraft]"
    Global Const $SCAN_POSITION_X = 1    ; X coordinate of the pixel to scan
    Global Const $SCAN_POSITION_Y = 1    ; Y coordinate of the pixel to scan
    Global Const $SOUND_PAUSE = 500      ; Frequency for pause sound notification
    Global Const $SOUND_RESUME = 1000    ; Frequency for resume sound notification
    
    
    ; Constants for different key sending methods
    Global Const $SEND_METHOD_CONTROL = 1 ; Using ControlSend function
    Global Const $SEND_METHOD_SEND = 2    ; Using Send function
    Global Const $SEND_METHOD_KEYS = 3    ; Using direct keyboard input via DLL calls
    
    
    ; Global variables for program state and GUI elements
    Global $pause = True                  ; Program starts in paused state
    Global $guiHandle                     ; Main GUI window handle
    Global $statusLabel                   ; Shows if program is running or paused
    Global $colorLabel                    ; Shows current color being detected
    Global $keyLabel                      ; Shows last key that was sent
    Global $radioControl                  ; Radio button for ControlSend method
    Global $radioSend                     ; Radio button for Send method
    Global $radioKeys                     ; Radio button for direct keyboard input
    Global $btnToggle                     ; Button to start/pause the program
    Global $btnColor                      ; Button to check current color
    Global $btnExit                       ; Button to exit program
    Global $sendMethod = $SEND_METHOD_KEYS ; Default send method
    Global $colorMap = _InitColorMap()     ; Initialize color to key mapping
    Global $dll                           ; Handle for user32.dll
    Global $sliderDelay                   ; Slider for controlling delay between keypresses
    Global $checkboxRandom                ; Checkbox for enabling random delay
    Global $minDelay = 100               ; Minimum delay between actions in milliseconds
    Global $maxDelay = 130               ; Maximum delay (calculated based on minDelay if random is enabled)
    
    
    ; Set up hotkeys
    HotKeySet("{DEL}", "_TogglePause")    ; DEL key toggles pause/resume
    HotKeySet("{INS}", "_ShowCurrentColor") ; INS key shows current color
    
    
    ; Initialize DLL and GUI
    $dll = DllOpen("user32.dll")
    _CreateGUI()
    
    
    ; Start main program loop
    MainLoop()
    
    
    ; Creates and initializes the GUI window
    Func _CreateGUI()
        $guiHandle = GUICreate("Color Helper", 300, 240)
    
    
        ; Status indicators
        GUICtrlCreateLabel("Status:", 10, 10)
        $statusLabel = GUICtrlCreateLabel("Paused", 100, 10)
    
    
        GUICtrlCreateLabel("Current Color:", 10, 40)
        $colorLabel = GUICtrlCreateLabel("-", 100, 40, 180)
    
    
        GUICtrlCreateLabel("Last Key:", 10, 70)
        $keyLabel = GUICtrlCreateLabel("-", 100, 70)
    
    
        ; Create radio buttons for different send methods
        Local $groupSend = GUICtrlCreateGroup("Send Method", 10, 95, 280, 50)
        $radioControl = GUICtrlCreateRadio("ControlSend", 20, 115, 80, 20)
        $radioSend = GUICtrlCreateRadio("Send", 110, 115, 80, 20)
        $radioKeys = GUICtrlCreateRadio("Keys", 200, 115, 80, 20)
        GUICtrlSetState($radioKeys, $GUI_CHECKED)
        $sendMethod = $SEND_METHOD_KEYS
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create delay control elements
        GUICtrlCreateGroup("Delay Settings", 10, 145, 280, 70)
        GUICtrlCreateLabel("ms Delay:", 20, 165, 55, 20)
        $sliderDelay = GUICtrlCreateSlider(80, 165, 150, 20)
        GUICtrlSetLimit($sliderDelay, 500, 10)
        GUICtrlSetData($sliderDelay, 100)
        Global $labelDelayValue = GUICtrlCreateLabel("100", 235, 165, 40, 20)
        $checkboxRandom = GUICtrlCreateCheckbox("Add random delay (+30%)", 20, 185, 140, 20)
        GUICtrlSetState($checkboxRandom, $GUI_CHECKED)
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    
    
        ; Create control buttons
        $btnToggle = GUICtrlCreateButton("Start/Pause (DEL)", 10, 210, 100, 25)
        $btnColor = GUICtrlCreateButton("Check Color (INS)", 120, 210, 100, 25)
        $btnExit = GUICtrlCreateButton("Exit", 230, 210, 60, 25)
    
    
        GUISetState(@SW_SHOW)
    EndFunc
    
    
    ; Initializes the color-to-key mapping array
    ; Each entry contains a hex color code and its corresponding key to send
    Func _InitColorMap()
        Local $map[10][2]
        $map[0][0] = "00FF00" ; Green   -> Key 1
        $map[0][1] = "1"
        $map[1][0] = "0000FF" ; Blue    -> Key 2
        $map[1][1] = "2"
        $map[2][0] = "FFFF00" ; Yellow  -> Key 3
        $map[2][1] = "3"
        $map[3][0] = "FF00FF" ; Magenta -> Key 4
        $map[3][1] = "4"
        $map[4][0] = "00FFFF" ; Cyan    -> Key 5
        $map[4][1] = "5"
        $map[5][0] = "808080" ; Gray    -> Key 6
        $map[5][1] = "6"
        $map[6][0] = "FF8000" ; Orange  -> Key 7
        $map[6][1] = "7"
        $map[7][0] = "00FF80" ; Turquoise -> Key 8
        $map[7][1] = "8"
        $map[8][0] = "8000FF" ; Purple  -> Key 9
        $map[8][1] = "9"
        $map[9][0] = "FF0000" ; Red     -> Key 0
        $map[9][1] = "0"
        Return $map
    EndFunc
    
    
    ; Main program loop that handles color detection and key sending
    Func MainLoop()
        Local $lastActionTime = 0
        Local $nextDelay = Random(100, 250)
    
    
        While 1
            _CheckGUIEvents()
    
    
            If WinActive($WINDOW_STRING) And Not $pause Then
                Local $currentTime = TimerInit()
    
    
                ; Check if enough time has passed since last action
                If $currentTime - $lastActionTime >= $nextDelay Then
                    ; Get color at scan position and find corresponding key
                    Local $currentColor = Hex(PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y), 6)
                    Local $key = _GetKeyForColor($currentColor)
    
    
                    If $key Then
                        SendKeyToWin($key)
                        GUICtrlSetData($keyLabel, $key)
                        GUICtrlSetData($colorLabel, $currentColor)
                        $lastActionTime = $currentTime
                        _UpdateDelays()
                        $nextDelay = Random($minDelay, $maxDelay)
                    EndIf
                EndIf
            EndIf
    
    
            Sleep(10) ; Prevent high CPU usage
        WEnd
    EndFunc
    
    
    ; Handles GUI events (button clicks, radio buttons, etc.)
    Func _CheckGUIEvents()
        Local $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                _Exit()
            Case $btnToggle
                _TogglePause()
            Case $btnColor
                _ShowCurrentColor()
            Case $btnExit
                _Exit()
            Case $radioControl
                $sendMethod = $SEND_METHOD_CONTROL
            Case $radioSend
                $sendMethod = $SEND_METHOD_SEND
            Case $radioKeys
                $sendMethod = $SEND_METHOD_KEYS
            Case $sliderDelay
                $minDelay = GUICtrlRead($sliderDelay)
            Case $checkboxRandom
                _UpdateDelays()
        EndSwitch
    EndFunc
    
    
    ; Updates delay settings based on slider and random checkbox
    Func _UpdateDelays()
        $minDelay = GUICtrlRead($sliderDelay)
        If BitAND(GUICtrlRead($checkboxRandom), $GUI_CHECKED) Then
            $maxDelay = Int($minDelay * 1.3) ; Add 30% for maximum random delay
        Else
            $maxDelay = $minDelay ; No randomization
        EndIf
    EndFunc
    
    
    ; Finds the corresponding key for a given color from the color map
    Func _GetKeyForColor($hexColor)
        For $i = 0 To UBound($colorMap) - 1
            If $colorMap[$i][0] = $hexColor Then
                Return $colorMap[$i][1]
            EndIf
        Next
        Return ""
    EndFunc
    
    
    ; Sends a key to the window using the selected send method
    Func SendKeyToWin($key)
        Switch $sendMethod
            Case $SEND_METHOD_CONTROL
                ControlSend($WINDOW_STRING, "", "", $key, 1)
            Case $SEND_METHOD_SEND
                If WinActive($WINDOW_STRING) Then
                    Send($key)
                EndIf
            Case $SEND_METHOD_KEYS
                If WinActive($WINDOW_STRING) Then
                    _SendKeys($key)
                EndIf
        EndSwitch
    EndFunc
    
    
    ; Sends keys using direct keyboard input via DLL calls
    Func _SendKeys($key)
        Local $code = Asc($key)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 0, "int", 0)  ; Key down
        Sleep(1)
        DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 2, "int", 0)  ; Key up
    EndFunc
    
    
    ; Toggles the pause state of the program
    Func _TogglePause()
        $pause = Not $pause
        If $pause Then
            Beep($SOUND_PAUSE, 100)
            GUICtrlSetData($statusLabel, "Paused")
        Else
            Beep($SOUND_RESUME, 100)
            GUICtrlSetData($statusLabel, "Active")
        EndIf
    EndFunc
    
    
    ; Shows the current color at the scan position
    Func _ShowCurrentColor()
        Local $color = PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y)
        Local $hexColor = Hex($color, 6)
        GUICtrlSetData($colorLabel, $hexColor)
    EndFunc
    
    
    ; Cleans up and exits the program
    Func _Exit()
        GUIDelete($guiHandle)
        DllClose($dll)
        Exit
    EndFunc
    LUA Code (create an Addon or use WowLua Addon and run from there):
    Code:
    -- =====================================================================
    -- This script creates a color indicator frame in World of Warcraft
    -- It reads text from ConROWindow and changes colors based on the number displayed
    -- The frame changes to white during casting, channeling, or when GCD is active
    -- =====================================================================
    
    
    -- Clean up any existing frame to prevent duplicates
    if ColorFrame then
       ColorFrame:Hide()
       ColorFrame:ClearAllPoints()
       ColorFrame:SetParent(nil)
       ColorFrame = nil
    end
    
    
    -- Define color mapping array
    -- Each entry contains RGB values (red, green, blue) from 0 to 1
    -- Index corresponds to the number displayed in ConROWindow (0-9)
    local colors = {
       {1, 0, 0},    -- 0: Red
       {0, 1, 0},    -- 1: Green
       {0, 0, 1},    -- 2: Blue
       {1, 1, 0},    -- 3: Yellow
       {1, 0, 1},    -- 4: Magenta
       {0, 1, 1},    -- 5: Cyan
       {0.5, 0.5, 0.5}, -- 6: Gray
       {1, 0.5, 0},  -- 7: Orange
       {0, 1, 0.5},  -- 8: Turquoise
       {0.5, 0, 1}   -- 9: Purple
    }
    
    
    -- Create the main frame
    -- Attaches to WorldFrame to ensure it's always visible
    -- Uses BackdropTemplate for visual debugging
    local f = CreateFrame("Frame", "ColorFrame", WorldFrame, "BackdropTemplate")
    f:SetHeight(1)
    f:SetWidth(1)
    f:SetPoint("TOPLEFT", WorldFrame, "TOPLEFT", 0, 0)  -- Position at top-left corner
    f:SetIgnoreParentScale(true)  -- Prevent inheritance of parent's scaling
    f:SetScale(1)
    
    
    -- Create and setup the texture for the frame
    -- Uses a white 8x8 texture as base which will be colored
    local t = f:CreateTexture(nil, "ARTWORK")
    t:SetTexture("Interface\\BUTTONS\\WHITE8X8")
    t:SetTexCoord(0.07, 0.93, 0.07, 0.93)  -- Adjust texture coordinates to prevent bleeding
    t:SetAllPoints(f)  -- Make texture fill the entire frame
    t:SetVertexColor(1, 1, 1, 1)  -- Start with white color
    f.texture = t
    
    
    -- Add a debug backdrop to make frame visible during development
    -- Creates a black semi-transparent background with a black border
    f:SetBackdrop({
          bgFile = "Interface\\Buttons\\WHITE8X8",
          edgeFile = "Interface\\Buttons\\WHITE8X8",
          edgeSize = 1,
    })
    f:SetBackdropColor(0, 0, 0, 0.5)  -- Semi-transparent black background
    f:SetBackdropBorderColor(0, 0, 0, 1)  -- Solid black border
    
    
    -- Update timing configuration
    local updateInterval = 0.1  -- Check for updates every 0.1 seconds
    local timeSinceLastUpdate = 0
    
    
    -- Function to check if Global Cooldown (GCD) is active
    -- Uses spell ID 61304 which represents the global cooldown
    local function IsGCDActive()
        local spellCooldownInfo = C_Spell.GetSpellCooldown(61304)
        if spellCooldownInfo.startTime == 0 then return false end
        return (spellCooldownInfo.startTime + spellCooldownInfo.duration - GetTime()) > 0
    end
    
    
    -- Main update function that runs on every frame
    f:SetScript("OnUpdate", function(self, elapsed)
          timeSinceLastUpdate = timeSinceLastUpdate + elapsed
          
          -- Only update at specified interval to reduce performance impact
          if timeSinceLastUpdate >= updateInterval then
             timeSinceLastUpdate = 0
             
             -- Check player state (casting, channeling, GCD)
             local casting = UnitCastingInfo("player") ~= nil
             local channeling = UnitChannelInfo("player") ~= nil
             local gcdActive = IsGCDActive()
             
             -- Set color to white if player is casting, channeling, or GCD is active
             if casting or channeling or gcdActive then
                t:SetVertexColor(1, 1, 1, 1)
                return
             end
             
             -- Color logic when player is not casting and GCD is not active
             -- Reads number from ConROWindow and sets corresponding color
             if ConROWindow and ConROWindow.fontkey and ConROWindow.fontkey:IsVisible() then
                local text = ConROWindow.fontkey:GetText()
                if text then
                   local number = tonumber(text)
                   if number and colors[number + 1] then
                      -- Set color from our color mapping array
                      local r, g, b = unpack(colors[number + 1])
                      t:SetVertexColor(r, g, b, 1)
                   else
                      -- Default to white if number is invalid
                      t:SetVertexColor(1, 1, 1, 1)
                   end
                else
                   -- Default to white if no text
                   t:SetVertexColor(1, 1, 1, 1)
                end
             else
                -- Default to white if ConROWindow is not visible
                t:SetVertexColor(1, 1, 1, 1)
             end
          end
    end)
    
    
    -- Show the frame
    f:Show()
    
    
    --print("ColorFrame script loaded successfully!")  -- Debug message

    Great works! Thanks for sharing.
    Last edited by SterlingHolt; 02-24-2025 at 03:34 AM.

  6. #5
    Erkana's Avatar Member
    Reputation
    1
    Join Date
    Jan 2025
    Posts
    1
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fantastic! Working reliably then any other rotation bot I have tried over the years(even all the way back to original HB days), what a simple yet amazing approach! That being said maybe it is just me being a AutoIt newbie I but can't seem to manage to change Start/Pause key on the code from DEL to something else; I would appreciate any pointers on how to do it. Thank you again for your fantastic effort!

  7. #6
    mazer's Avatar Active Member
    Reputation
    56
    Join Date
    Sep 2007
    Posts
    87
    Thanks G/R
    11/28
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Erkana View Post
    Fantastic! Working reliably then any other rotation bot I have tried over the years(even all the way back to original HB days), what a simple yet amazing approach! That being said maybe it is just me being a AutoIt newbie I but can't seem to manage to change Start/Pause key on the code from DEL to something else; I would appreciate any pointers on how to do it. Thank you again for your fantastic effort!
    take a look at this lines:
    Code:
    ; Set up hotkeys
    HotKeySet("{DEL}", "_TogglePause")    ; DEL key toggles pause/resume
    HotKeySet("{INS}", "_ShowCurrentColor") ; INS key shows current color
    now look at Function HotKeySet
    where you will find this Function Send

    with this information you should be able to set the hotkey to whatever you want

  8. Thanks Erkana (1 members gave Thanks to mazer for this useful post)
  9. #7
    alic's Avatar Member
    Reputation
    2
    Join Date
    Mar 2025
    Posts
    10
    Thanks G/R
    1/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How can I change the code so that it also works with Hekili? With Conro, the defensive abilities are displayed in a different window, thus not included in the rotation. This is bad for druid tanks, for example.

  10. #8
    alic's Avatar Member
    Reputation
    2
    Join Date
    Mar 2025
    Posts
    10
    Thanks G/R
    1/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is there nobody here who could make the code work with hekili? That would be very nice.


    -- =====================================================================
    -- This script creates a color indicator frame in World of Warcraft
    -- It reads text from ConROWindow and changes colors based on the number displayed
    -- The frame changes to white during casting, channeling, or when GCD is active
    -- =====================================================================


    -- Clean up any existing frame to prevent duplicates
    if ColorFrame then
    ColorFrame:Hide()
    ColorFrame:ClearAllPoints()
    ColorFrame:SetParent(nil)
    ColorFrame = nil
    end


    -- Define color mapping array
    -- Each entry contains RGB values (red, green, blue) from 0 to 1
    -- Index corresponds to the number displayed in ConROWindow (0-9)
    local colors = {
    {1, 0, 0}, -- 0: Red
    {0, 1, 0}, -- 1: Green
    {0, 0, 1}, -- 2: Blue
    {1, 1, 0}, -- 3: Yellow
    {1, 0, 1}, -- 4: Magenta
    {0, 1, 1}, -- 5: Cyan
    {0.5, 0.5, 0.5}, -- 6: Gray
    {1, 0.5, 0}, -- 7: Orange
    {0, 1, 0.5}, -- 8: Turquoise
    {0.5, 0, 1} -- 9: Purple
    }


    -- Create the main frame
    -- Attaches to WorldFrame to ensure it's always visible
    -- Uses BackdropTemplate for visual debugging
    local f = CreateFrame("Frame", "ColorFrame", WorldFrame, "BackdropTemplate")
    f:SetHeight(1)
    f:SetWidth(1)
    f:SetPoint("TOPLEFT", WorldFrame, "TOPLEFT", 0, 0) -- Position at top-left corner
    f:SetIgnoreParentScale(true) -- Prevent inheritance of parent's scaling
    f:SetScale(1)


    -- Create and setup the texture for the frame
    -- Uses a white 8x8 texture as base which will be colored
    local t = f:CreateTexture(nil, "ARTWORK")
    t:SetTexture("Interface\\BUTTONS\\WHITE8X8")
    t:SetTexCoord(0.07, 0.93, 0.07, 0.93) -- Adjust texture coordinates to prevent bleeding
    t:SetAllPoints(f) -- Make texture fill the entire frame
    t:SetVertexColor(1, 1, 1, 1) -- Start with white color
    f.texture = t


    -- Add a debug backdrop to make frame visible during development
    -- Creates a black semi-transparent background with a black border
    f:SetBackdrop({
    bgFile = "Interface\\Buttons\\WHITE8X8",
    edgeFile = "Interface\\Buttons\\WHITE8X8",
    edgeSize = 1,
    })
    f:SetBackdropColor(0, 0, 0, 0.5) -- Semi-transparent black background
    f:SetBackdropBorderColor(0, 0, 0, 1) -- Solid black border


    -- Update timing configuration
    local updateInterval = 0.1 -- Check for updates every 0.1 seconds
    local timeSinceLastUpdate = 0


    -- Function to check if Global Cooldown (GCD) is active
    -- Uses spell ID 61304 which represents the global cooldown
    local function IsGCDActive()
    local spellCooldownInfo = C_Spell.GetSpellCooldown(61304)
    if spellCooldownInfo.startTime == 0 then return false end
    return (spellCooldownInfo.startTime + spellCooldownInfo.duration - GetTime()) > 0
    end


    -- Main update function that runs on every frame
    f:SetScript("OnUpdate", function(self, elapsed)
    timeSinceLastUpdate = timeSinceLastUpdate + elapsed

    -- Only update at specified interval to reduce performance impact
    if timeSinceLastUpdate >= updateInterval then
    timeSinceLastUpdate = 0

    -- Check player state (casting, channeling, GCD)
    local casting = UnitCastingInfo("player") ~= nil
    local channeling = UnitChannelInfo("player") ~= nil
    local gcdActive = IsGCDActive()

    -- Set color to white if player is casting, channeling, or GCD is active
    if casting or channeling or gcdActive then
    t:SetVertexColor(1, 1, 1, 1)
    return
    end

    -- Color logic when player is not casting and GCD is not active
    -- Reads number from ConROWindow and sets corresponding color
    if ConROWindow and ConROWindow.fontkey and ConROWindow.fontkey:IsVisible() then
    local text = ConROWindow.fontkey:GetText()
    if text then
    local number = tonumber(text)
    if number and colors[number + 1] then
    -- Set color from our color mapping array
    local r, g, b = unpack(colors[number + 1])
    t:SetVertexColor(r, g, b, 1)
    else
    -- Default to white if number is invalid
    t:SetVertexColor(1, 1, 1, 1)
    end
    else
    -- Default to white if no text
    t:SetVertexColor(1, 1, 1, 1)
    end
    else
    -- Default to white if ConROWindow is not visible
    t:SetVertexColor(1, 1, 1, 1)
    end
    end
    end)


    -- Show the frame
    f:Show()


    --print("ColorFrame script loaded successfully!") -- Debug message

  11. #9
    HudsonGrant's Avatar Member
    Reputation
    1
    Join Date
    Mar 2025
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The pixel-reader combat/rotation helper you've created seems to be a very practical solution for World of Warcraft players using ConRO, offering automatic key presses based on real-time color changes
    Last edited by HudsonGrant; 05-05-2025 at 01:30 AM.

  12. #10
    pachulius's Avatar Private
    Reputation
    1
    Join Date
    Dec 2021
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Awesome work Mazer, was just about to do something like this. Many thanks
    Managed to port it to Hekili, plus added some more keybinds.

    Function keys only work with sendKeys option
    Make sure you don't have the same ability key-bound in multiple places

    auto-it script
    #include <GUIConstants.au3>
    #include <Misc.au3>


    ; ================================================================================ =================
    ; This script is a color helper tool that scans a specific pixel in World of Warcraft
    ; and sends corresponding keystrokes based on the color detected.
    ; It includes a GUI for control and various sending methods for compatibility.
    ; ================================================================================ =================


    ; Constants for window detection and scanning
    Global Const $WINDOW_STRING = "[TITLE:World of Warcraft]"
    Global Const $SCAN_POSITION_X = 1 ; X coordinate of the pixel to scan
    Global Const $SCAN_POSITION_Y = 1 ; Y coordinate of the pixel to scan
    Global Const $SOUND_PAUSE = 500 ; Frequency for pause sound notification
    Global Const $SOUND_RESUME = 1000 ; Frequency for resume sound notification


    ; Constants for different key sending methods
    Global Const $SEND_METHOD_CONTROL = 1 ; Using ControlSend function
    Global Const $SEND_METHOD_SEND = 2 ; Using Send function
    Global Const $SEND_METHOD_KEYS = 3 ; Using direct keyboard input via DLL calls


    ; Global variables for program state and GUI elements
    Global $pause = True ; Program starts in paused state
    Global $guiHandle ; Main GUI window handle
    Global $statusLabel ; Shows if program is running or paused
    Global $colorLabel ; Shows current color being detected
    Global $keyLabel ; Shows last key that was sent
    Global $radioControl ; Radio button for ControlSend method
    Global $radioSend ; Radio button for Send method
    Global $radioKeys ; Radio button for direct keyboard input
    Global $btnToggle ; Button to start/pause the program
    Global $btnColor ; Button to check current color
    Global $btnExit ; Button to exit program
    Global $sendMethod = $SEND_METHOD_KEYS ; Default send method
    Global $colorMap = _InitColorMap() ; Initialize color to key mapping
    Global $dll ; Handle for user32.dll
    Global $sliderDelay ; Slider for controlling delay between keypresses
    Global $checkboxRandom ; Checkbox for enabling random delay
    Global $minDelay = 100 ; Minimum delay between actions in milliseconds
    Global $maxDelay = 130 ; Maximum delay (calculated based on minDelay if random is enabled)


    ; Set up hotkeys
    HotKeySet("{DEL}", "_TogglePause") ; DEL key toggles pause/resume
    HotKeySet("{INS}", "_ShowCurrentColor") ; INS key shows current color


    ; Initialize DLL and GUI
    $dll = DllOpen("user32.dll")
    _CreateGUI()


    ; Start main program loop
    MainLoop()


    ; Creates and initializes the GUI window
    Func _CreateGUI()
    $guiHandle = GUICreate("Color Helper", 300, 240)


    ; Status indicators
    GUICtrlCreateLabel("Status:", 10, 10)
    $statusLabel = GUICtrlCreateLabel("Paused", 100, 10)


    GUICtrlCreateLabel("Current Color:", 10, 40)
    $colorLabel = GUICtrlCreateLabel("-", 100, 40, 180)


    GUICtrlCreateLabel("Last Key:", 10, 70)
    $keyLabel = GUICtrlCreateLabel("-", 100, 70)


    ; Create radio buttons for different send methods
    Local $groupSend = GUICtrlCreateGroup("Send Method", 10, 95, 280, 50)
    $radioControl = GUICtrlCreateRadio("ControlSend", 20, 115, 80, 20)
    $radioSend = GUICtrlCreateRadio("Send", 110, 115, 80, 20)
    $radioKeys = GUICtrlCreateRadio("Keys", 200, 115, 80, 20)
    GUICtrlSetState($radioKeys, $GUI_CHECKED)
    $sendMethod = $SEND_METHOD_KEYS
    GUICtrlCreateGroup("", -99, -99, 1, 1)


    ; Create delay control elements
    GUICtrlCreateGroup("Delay Settings", 10, 145, 280, 70)
    GUICtrlCreateLabel("ms Delay:", 20, 165, 55, 20)
    $sliderDelay = GUICtrlCreateSlider(80, 165, 150, 20)
    GUICtrlSetLimit($sliderDelay, 500, 10)
    GUICtrlSetData($sliderDelay, 100)
    Global $labelDelayValue = GUICtrlCreateLabel("100", 235, 165, 40, 20)
    $checkboxRandom = GUICtrlCreateCheckbox("Add random delay (+30%)", 20, 185, 140, 20)
    GUICtrlSetState($checkboxRandom, $GUI_CHECKED)
    GUICtrlCreateGroup("", -99, -99, 1, 1)


    ; Create control buttons
    $btnToggle = GUICtrlCreateButton("Start/Pause (DEL)", 10, 210, 100, 25)
    $btnColor = GUICtrlCreateButton("Check Color (INS)", 120, 210, 100, 25)
    $btnExit = GUICtrlCreateButton("Exit", 230, 210, 60, 25)


    GUISetState(@SW_SHOW)
    EndFunc


    ; Initializes the color-to-key mapping array
    ; Each entry contains a hex color code and its corresponding key to send
    Func _InitColorMap()
    Local $map[22][2] ; Increased size to accommodate all the colors and keys

    ; Original colors
    $map[0][0] = "FF0000" ; Red -> Key 1
    $map[0][1] = "1"
    $map[1][0] = "00FF00" ; Green -> Key 2
    $map[1][1] = "2"
    $map[2][0] = "0000FF" ; Blue -> Key 3
    $map[2][1] = "3"
    $map[3][0] = "FFFF00" ; Yellow -> Key 4
    $map[3][1] = "4"
    $map[4][0] = "FF00FF" ; Magenta -> Key 5
    $map[4][1] = "5"
    $map[5][0] = "00FFFF" ; Cyan -> Key 6
    $map[5][1] = "6"
    $map[6][0] = "F5F5DC" ; Beige -> Key 7
    $map[6][1] = "7"
    $map[7][0] = "FF8000" ; Orange -> Key 8
    $map[7][1] = "8"
    $map[8][0] = "00FF80" ; Turquoise -> Key 9
    $map[8][1] = "9"
    $map[9][0] = "8000FF" ; Purple -> Key 0
    $map[9][1] = "0"

    ; Additional keys
    $map[10][0] = "CCCCCC" ; Light Gray -> Key z
    $map[10][1] = "z"
    $map[11][0] = "33B233" ; Light Green -> Key x
    $map[11][1] = "x"
    $map[12][0] = "993399" ; Violet -> Key c
    $map[12][1] = "c"

    ; Shift modifier colors
    $map[13][0] = "E61A1A" ; Dark Red -> Key S1
    $map[13][1] = "S1"
    $map[14][0] = "1AE61A" ; Dark Green -> Key S2
    $map[14][1] = "S2"
    $map[15][0] = "1A1AE6" ; Dark Blue -> Key S3
    $map[15][1] = "S3"
    $map[16][0] = "E6E61A" ; Dark Yellow -> Key S4
    $map[16][1] = "S4"

    ; Function keys colors,
    ;WILL ONLY WORK WITH SENDKEYS
    $map[17][0] = "808000" ; Olive -> Key F1
    $map[17][1] = "{F1}"
    $map[18][0] = "800080" ; Dark Magenta -> Key F2
    $map[18][1] = "{F2}"
    $map[19][0] = "008080" ; Teal -> Key F3
    $map[19][1] = "{F3}"
    $map[20][0] = "808080" ; Grayish -> Key F4
    $map[20][1] = "{F4}"

    ; Backtick key and shift modifier
    $map[21][0] = "#B3B3B3" ; Silver/Light Gray -> Key `
    $map[21][1] = "`"

    Return $map
    EndFunc



    ; Main program loop that handles color detection and key sending
    Func MainLoop()
    Local $lastActionTime = 0
    Local $nextDelay = Random(100, 250)


    While 1
    _CheckGUIEvents()


    If WinActive($WINDOW_STRING) And Not $pause Then
    Local $currentTime = TimerInit()


    ; Check if enough time has passed since last action
    If $currentTime - $lastActionTime >= $nextDelay Then
    ; Get color at scan position and find corresponding key
    Local $currentColor = Hex(PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y), 6)
    Local $key = _GetKeyForColor($currentColor)


    If $key Then
    SendKeyToWin($key)
    GUICtrlSetData($keyLabel, $key)
    GUICtrlSetData($colorLabel, $currentColor)
    $lastActionTime = $currentTime
    _UpdateDelays()
    $nextDelay = Random($minDelay, $maxDelay)
    EndIf
    EndIf
    EndIf


    Sleep(10) ; Prevent high CPU usage
    WEnd
    EndFunc


    ; Handles GUI events (button clicks, radio buttons, etc.)
    Func _CheckGUIEvents()
    Local $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE
    _Exit()
    Case $btnToggle
    _TogglePause()
    Case $btnColor
    _ShowCurrentColor()
    Case $btnExit
    _Exit()
    Case $radioControl
    $sendMethod = $SEND_METHOD_CONTROL
    Case $radioSend
    $sendMethod = $SEND_METHOD_SEND
    Case $radioKeys
    $sendMethod = $SEND_METHOD_KEYS
    Case $sliderDelay
    $minDelay = GUICtrlRead($sliderDelay)
    Case $checkboxRandom
    _UpdateDelays()
    EndSwitch
    EndFunc


    ; Updates delay settings based on slider and random checkbox
    Func _UpdateDelays()
    $minDelay = GUICtrlRead($sliderDelay)
    If BitAND(GUICtrlRead($checkboxRandom), $GUI_CHECKED) Then
    $maxDelay = Int($minDelay * 1.3) ; Add 30% for maximum random delay
    Else
    $maxDelay = $minDelay ; No randomization
    EndIf
    EndFunc


    ; Finds the corresponding key for a given color from the color map
    Func _GetKeyForColor($hexColor)
    For $i = 0 To UBound($colorMap) - 1
    If $colorMap[$i][0] = $hexColor Then
    Return $colorMap[$i][1]
    EndIf
    Next
    Return ""
    EndFunc


    ; Sends a key to the window using the selected send method
    Func SendKeyToWin($key)
    Switch $sendMethod
    Case $SEND_METHOD_CONTROL
    ControlSend($WINDOW_STRING, "", "", $key, 1)
    Case $SEND_METHOD_SEND
    If WinActive($WINDOW_STRING) Then
    Send($key)
    EndIf
    Case $SEND_METHOD_KEYS
    If WinActive($WINDOW_STRING) Then
    _SendKeys($key)
    EndIf
    EndSwitch
    EndFunc


    ; Sends keys using direct keyboard input via DLL calls
    Func _SendKeys($key)
    Local $code = Asc($key)
    DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 0, "int", 0) ; Key down
    Sleep(1)
    DllCall($dll, "int", "keybd_event", "int", $code, "int", 0, "int", 2, "int", 0) ; Key up
    EndFunc


    ; Toggles the pause state of the program
    Func _TogglePause()
    $pause = Not $pause
    If $pause Then
    Beep($SOUND_PAUSE, 100)
    GUICtrlSetData($statusLabel, "Paused")
    Else
    Beep($SOUND_RESUME, 100)
    GUICtrlSetData($statusLabel, "Active")
    EndIf
    EndFunc


    ; Shows the current color at the scan position
    Func _ShowCurrentColor()
    Local $color = PixelGetColor($SCAN_POSITION_X, $SCAN_POSITION_Y)
    Local $hexColor = Hex($color, 6)
    GUICtrlSetData($colorLabel, $hexColor)
    EndFunc


    ; Cleans up and exits the program
    Func _Exit()
    GUIDelete($guiHandle)
    DllClose($dll)
    Exit
    EndFunc

    -- Remove old frame if it exists
    if ColorFrame then
    ColorFrame:Hide()
    ColorFrame:ClearAllPoints()
    ColorFrame:SetParent(nil)
    ColorFrame = nil
    end

    -- Color mapping based on spell name or keybind index (customize this as needed)
    local colors = {
    ["1"] = {1, 0, 0}, -- Red
    ["2"] = {0, 1, 0}, -- Green
    ["3"] = {0, 0, 1}, -- Blue
    ["4"] = {1, 1, 0}, -- Yellow
    ["5"] = {1, 0, 1}, -- Magenta
    ["6"] = {0, 1, 1}, -- Cyan
    ["7"] = {245, 245 , 220}, -- Orange
    ["8"] = {1, 0.5, 0}, -- Orange
    ["9"] = {0, 1, 0.5}, -- Turquoise
    ["0"] = {0.5, 0, 1}, -- Purple
    ["None"] = {1, 1, 1}, -- White default

    -- Additional keys for zxc
    ["z"] = {0.8, 0.8, 0.8}, -- Light Gray
    ["x"] = {0.2, 0.7, 0.2}, -- Light Green
    ["c"] = {0.6, 0.2, 0.6}, -- Violet

    -- Shift modifiers (S1-S4)
    ["S1"] = {0.9, 0.1, 0.1}, -- Dark Red
    ["S2"] = {0.1, 0.9, 0.1}, -- Dark Green
    ["S3"] = {0.1, 0.1, 0.9}, -- Dark Blue
    ["S4"] = {0.9, 0.9, 0.1}, -- Dark Yellow

    -- Function keys (F1-F4)
    ["F1"] = {0.5, 0.5, 0}, -- Olive
    ["F2"] = {0.5, 0, 0.5}, -- Dark Magenta
    ["F3"] = {0, 0.5, 0.5}, -- Teal
    ["F4"] = {0.5, 0.5, 0.5}, -- Gray

    -- Backtick key (`) and its shift modifier (Shift + `)
    ["`"] = {0.7, 0.7, 0.7}, -- Silver/Light Gray
    }

    -- Create the frame
    local f = CreateFrame("Frame", "ColorFrame", WorldFrame, "BackdropTemplate")
    f:SetSize(1, 1)
    f:SetPoint("TOPLEFT", WorldFrame, "TOPLEFT", 0, 0)
    f:SetIgnoreParentScale(true)
    f:SetScale(1)

    -- Texture for color
    local t = f:CreateTexture(nil, "ARTWORK")
    t:SetTexture("Interface\\BUTTONS\\WHITE8X8")
    t:SetTexCoord(0.07, 0.93, 0.07, 0.93)
    t:SetAllPoints(f)
    t:SetVertexColor(1, 1, 1, 1)
    f.texture = t

    -- Optional backdrop for development visibility
    f:SetBackdrop({
    bgFile = "Interface\\Buttons\\WHITE8X8",
    edgeFile = "Interface\\Buttons\\WHITE8X8",
    edgeSize = 1,
    })
    f:SetBackdropColor(0, 0, 0, 0.5)
    f:SetBackdropBorderColor(0, 0, 0, 1)

    -- Update configuration
    local updateInterval = 0.1
    local timeSinceLastUpdate = 0

    -- Check if GCD is active
    local function IsGCDActive()
    local info = C_Spell.GetSpellCooldown(61304)
    return info.startTime > 0 and (info.startTime + info.duration - GetTime()) > 0
    end

    local lastKey = ""
    -- Update function
    f:SetScript("OnUpdate", function(self, elapsed)
    timeSinceLastUpdate = timeSinceLastUpdate + elapsed
    if timeSinceLastUpdate < updateInterval then return end
    timeSinceLastUpdate = 0

    local casting = UnitCastingInfo("player") ~= nil
    local channeling = UnitChannelInfo("player") ~= nil
    local gcd = IsGCDActive()

    -- White color during casting or GCD
    if casting or channeling or gcd then
    t:SetVertexColor(1, 1, 1, 1)
    return
    end

    -- Get recommendation from Hekili
    local _, _, info = Hekili_GetRecommendedAbility("Primary", 1)
    local key = (info and info.keybind) or "None"
    local color = colors[key] or colors["None"]

    t:SetVertexColor(unpack(color))
    -- Print the keybind if it changed
    if key ~= lastKey then
    print("Recommended keybind:", key)
    lastKey = key
    end
    end)

    f:Show()
    Last edited by pachulius; 04-21-2025 at 04:53 AM.

  13. #11
    joshroxu4's Avatar Member
    Reputation
    1
    Join Date
    Aug 2025
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Super simple, ty!

Similar Threads

  1. [Selling] IcyPixl Easiest To Use World Of Warcraft Automated Pixel Combat Rotation Bot
    By IcyPixl in forum World of Warcraft Buy Sell Trade
    Replies: 1
    Last Post: 07-05-2022, 05:52 AM
  2. Replies: 1
    Last Post: 05-16-2022, 02:08 PM
  3. looking for good swtor combat rotation bot
    By Deanobro in forum SWTOR Bots and Programs
    Replies: 4
    Last Post: 07-26-2020, 05:35 AM
  4. Looking for combat rotation bot
    By warksy in forum Final Fantasy XIV
    Replies: 6
    Last Post: 05-27-2020, 08:08 AM
  5. Combat Rotations bot (Dungeons/pvp)
    By lolzchicken in forum WoW Bots Questions & Requests
    Replies: 3
    Last Post: 05-25-2016, 09:56 PM
All times are GMT -5. The time now is 12:13 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search