背景
自從發現紅警除了 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=造礦場,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
}
因為皮膚按鈕會隨著遊戲進行而會有變化,所以上述指令碼只適用於開局。