用溪流 WarKey 輔助紅警開局快捷操作

2023-01-19 12:01:25

背景

自從發現紅警除了 ddraw 修補程式可以在最新的系統裡玩後,就開始懷舊了。但是由於手殘,遇到別人搶地盤基本上直接崩了。偶然有一次發現像 08 這樣的高手點 30 個坦克使用工具的。那麼,我開局用工具造兵營、碉堡,是不是顯得不那麼可恥了呢?

說幹就幹,我有支援 lua 指令碼的溪流 WayKey,理論上都能做到。

實現一次性點 30 個坦克

這個場景沒有手速要求,只是為了不麻煩,所以我們實現地簡單些:要求先把滑鼠放好位置,然後設定快捷鍵,直接給點選 N 次。

實現很簡單,30 次這個次數作為引數傳進來,主函數裡就是 PressMouseButton(Mouse.LBUTTON)、ReleaseMouseButton(Mouse.LBUTTON) 來 30 下:

Extension =
{
    Application   = "xlWarKey",
    Version       = "3.0",
    NameSpace     = "http://www.streamlet.org/Software/xlWarKey/",

    ExtensionName = "滑鼠連點",
    Author        = "溪流",
    Description   = "該指令碼可以用來在紅警2中一次性造多個單位。",

    Configuration =
    {
        Count    =
        {
            Type  = "number",
            Desc  = "連點次數"
        }
    },

    Entrance      = function (id)

        local config = Extension.Configuration;
        --config.Count 就是使用者在軟體介面上設定的連點次數

        for i = 1, config.Count, 1
        do 
            PressMouseButton(Mouse.LBUTTON);
            ReleaseMouseButton(Mouse.LBUTTON);
        end

        return true;
    end
};

(指令碼檔案見 https://www.streamlet.org/software/xlwarkey/)

儲存為 .lua 檔案放到溪流 WarKey 目錄下的 Scripts 下,退出溪流 WarKey 重新開啟,即可看到指令碼生效。

因為溪流 WarKey 本是為魔獸寫的,因此預設會勾上「僅在魔獸爭霸中應用」,要去掉它。

然後改鍵動作選擇「滑鼠連點」指令碼,並設定引數 Count 為 30 即可:

實現快速造兵營、碉堡

難點主要是在定位按鈕的位置。

我們在不同解析度下截幾張圖,發現一個規律:不管解析度如何,面板寬度總是固定為 168 畫素,面板內部的各個元件大小也是固定的。這就好辦了。經過測量,得出如下結論:

  • 頂部到按鈕區域高度:227
  • 面板寬度 168,左右空隙 20、22,按鈕區域寬度126
  • 按鈕大小 63x50

所以,對於第 r 行、第 c 列(r、c 均從 0 開始)的按鈕,其中心座標的計算公式為

x = WIDTH - 168 + 20 + 63 * c + 63/2
y = 227 + r * 50 + 50/2

點選面板按鈕可以組織成一個函數:

ClickPanel = function(row, column, count)
    if count == nil then
        count = 1
    end
    local width, height = GetClientSize()
    local target_x = width - 168 + 20 + 63 * column + 32
    local target_y = 227 + row * 50 + 25
    MoveMouse(target_x, target_y)
    for i = 1, count, 1
    do 
        ClickMouse()
        Delay(10)
    end
end

有了 ClickPanel,我們可以寫出造任何東西的程式碼了。完整指令碼如下:

Extension =
{
    Application   = "xlWarKey",
    Version       = "3.0",
    NameSpace     = "http://www.streamlet.org/Software/xlWarKey/",

    ExtensionName = "紅警開局快速操作",
    Author        = "溪流",
    Description   = "幫助紅警手殘黨不要一開始就被搶死,提高遊戲體驗",

    Configuration =
    {
        Type =
        {
            Type  = "number",
            Desc  = "1=造電廠,2=造兵營,3=造礦場碉堡1工程師,4=造碉堡,5=造3條狗,6=造10個兵"
        }
    },

    Entrance = function (id)

        ClickKey = function (key)
            PressKey(key)
            ReleaseKey(key)
        end

        ClickMouse = function ()
            PressMouseButton(Mouse.LBUTTON)
            ReleaseMouseButton(Mouse.LBUTTON)
        end

        ClickPanel = function(row, column, count)
            if count == nil then
                count = 1
            end
            local width, height = GetClientSize()
            -- 紅警面板總是在右側固定寬度位置 168 畫素,其中
            -- 內邊框左側 20 畫素,右側 22 畫素,中間 126 畫素為按鈕,分兩列,每列 63px
            -- 頂部到按鈕高度 227 畫素,按鈕高度 50 畫素
            local target_x = width - 168 + 20 + 63 * column + 32
            local target_y = 227 + row * 50 + 25
            MoveMouse(target_x, target_y)
            for i = 1, count, 1
            do 
                ClickMouse()
                Delay(10)
            end
        end

        local config = Extension.Configuration
        local start_x, start_y = GetCursorPosition()

        if config.Type == 1 then
            -- 造電廠
            ClickKey(Keys.VK_Q)
            ClickPanel(0, 0)
            MoveMouse(start_x, start_y)
        elseif config.Type == 2 then
            -- 造兵營
            ClickKey(Keys.VK_Q)
            ClickPanel(1, 0)
            MoveMouse(start_x, start_y)
        elseif config.Type == 3 then
            -- 造礦場
            ClickKey(Keys.VK_Q)
            ClickPanel(0, 1)
            MoveMouse(start_x, start_y)
        elseif config.Type == 4 then
            -- 造碉堡
            ClickKey(Keys.VK_W)
            ClickPanel(0, 1)
            MoveMouse(start_x, start_y)
        elseif config.Type == 5 then
            -- 造3條狗
            ClickKey(Keys.VK_Q)
            ClickPanel(1, 0, 3)
            MoveMouse(start_x, start_y)
        elseif config.Type == 6 then
            -- 造10個兵
            ClickKey(Keys.VK_Q)
            ClickPanel(0, 0, 10)
            MoveMouse(start_x, start_y)
        end

        return true
    end
}

因為面板按鈕會隨著遊戲進行而會有變化,所以上述指令碼只適用於開局。