目次

解説

このスクリプトは、AutoHotkey v2 で動作する ARAD.exe 向けのアイテム自動移動ツールです。Ctrl+Shift+O を押すと、あらかじめ決められた座標の組み合わせに従ってアイテムを自動的にドラッグ&ドロップします。

留意点

  • この記事はAIによって書かれています。

スクリプト

#Requires AutoHotkey v2.0

; ============================================================
; ARAD.exe アイテム移動スクリプト (Ctrl+Shift+O)
; ------------------------------------------------------------
; 前提:
;   ・ARAD.exe のウィンドウは 16:10 の比率
;   ・下記の座標はウィンドウサイズが 1440x900 のときの座標
; ============================================================

CoordMode "Mouse", "Screen"
CoordMode "Pixel", "Screen"

; --- 基準解像度 (この解像度のときの座標として以下を定義) ---
REF_W := 1440
REF_H := 900

; --- 基準座標 (移動元 / 移動先) の一覧 ---
; { src: [x, y], dst: [x, y] }
MOVES := [
    { src: [1120, 570], dst: [920, 140] },
    { src: [1120, 620], dst: [920, 190] },
    { src: [1120, 670], dst: [920, 240] },
    { src: [1120, 720], dst: [920, 290] },

    { src: [1160, 570], dst: [1180, 140] },
    { src: [1160, 620], dst: [1180, 190] },
    { src: [1160, 670], dst: [1180, 240] },
    { src: [1160, 720], dst: [1180, 290] },

    { src: [1210, 570], dst: [980, 320] },
    { src: [1210, 620], dst: [1050, 330] },
    { src: [1210, 670], dst: [1120, 320] },
    { src: [1210, 705], dst: [1050, 280], checkRadius: 2 },
]

; ARAD.exe がアクティブウィンドウのときだけ ^+o を有効にする
#HotIf WinActive("ahk_exe ARAD.exe")
^+o:: {
    winTitle := "ahk_exe ARAD.exe"

    ; 1. ARAD.exe のウィンドウの位置とサイズを取得
    ;    (タイトルバー・枠を除いたクライアント領域を基準にする)
    WinGetClientPos(&cx, &cy, &cw, &ch, winTitle)

    ; 2. 基準座標(1440x900前提)を実際のウィンドウサイズに合わせてスケーリング
    scaleX := cw / REF_W
    scaleY := ch / REF_H

    ; 3. 一覧の座標を順番にドラッグ&ドロップ
    for m in MOVES {
        srcX := cx + Round(m.src[1] * scaleX)
        srcY := cy + Round(m.src[2] * scaleY)
        dstX := cx + Round(m.dst[1] * scaleX)
        dstY := cy + Round(m.dst[2] * scaleY)

        ; checkRadius 指定時: src 座標を中心とした円が全て 0x040404, 0x050505,
        ; 0x060505 のいずれかに一致するかどうかで移動方向を決める
        ;   ・一致する      → dst から src へ移動(逆方向)、移動後 Ctrl+左クリックでロック
        ;   ・一致しない    → src から dst へ移動(通常方向)
        matched := false
        if m.HasOwnProp("checkRadius") {
            radius := Round(m.checkRadius * ((scaleX + scaleY) / 2))
            matched := IsCircleColor(srcX, srcY, radius, [0x040404, 0x050505, 0x060505])
            if matched {
                temp := [srcX, srcY]
                srcX := dstX, srcY := dstY
                dstX := temp[1], dstY := temp[2]
            }
        }

        DragMouse(srcX, srcY, dstX, dstY)

        ; 一致していた場合、移動完了後に Ctrl+左クリックでアイテムをロックする
        if matched
            CtrlLeftClick(dstX, dstY)
    }
}
#HotIf

; 指定座標(x0, y0)を中心とした半径 radius px の円内の全ピクセルが
; colors に含まれるいずれかの色に一致するかどうかを判定する
; (colors は単一の色、または色の配列)
IsCircleColor(x0, y0, radius, colors := [0x040404, 0x050505, 0x060505]) {
    if !(colors is Array)
        colors := [colors]

    CircleScan:
    loop (radius * 2 + 1) {
        dy := A_Index - 1 - radius
        maxDx := Round(Sqrt(radius ** 2 - dy ** 2))
        loop (maxDx * 2 + 1) {
            dx := A_Index - 1 - maxDx
            pixelColor := PixelGetColor(x0 + dx, y0 + dy)

            matched := false
            for c in colors {
                if pixelColor = c {
                    matched := true
                    break
                }
            }
            if !matched
                return false
        }
    }

    return true
}

; 指定座標から指定座標へアイテムをドラッグ&ドロップする
DragMouse(x1, y1, x2, y2, delay := 80, moveDelay := 80) {
    MouseMove(x1, y1, 0)
    Sleep(moveDelay)
    Click("Down Left")
    Sleep(delay)
    MouseMove(x2, y2, 0)
    Sleep(moveDelay)
    Click("Up Left")
    Sleep(delay)
}

; 指定座標で Ctrl+左クリックする(アイテムをロックする操作)
; Ctrl 押下 → 100ms待機 → 左クリック押下 → 100ms待機
; → 左クリック解放 → 100ms待機 → Ctrl 解放、と各操作を個別に分けて実行する
CtrlLeftClick(x, y, moveDelay := 80) {
    MouseMove(x, y, 0)
    Sleep(moveDelay)
    Send("{Ctrl Down}")
    Sleep(100)
    Click("Down Left")
    Sleep(100)
    Click("Up Left")
    Sleep(100)
    Send("{Ctrl Up}")
}

処理の流れ

  1. ウィンドウの確認 ahk_exe ARAD.exe というウィンドウが存在するかを WinExist でチェックし、見つからない場合はツールチップでエラーを表示して処理を中断します。

  2. クライアント領域の位置・サイズ取得 WinGetClientPos で、タイトルバーや枠を除いたゲーム画面本体(クライアント領域)の座標 (cx, cy) とサイズ (cw, ch) を取得します。座標計算はすべてこのクライアント領域を基準に行われます。

  3. ウィンドウのアクティブ化 ドラッグ操作を受け付けさせるため、WinActivate でウィンドウをアクティブにし、WinWaitActive でアクティブになるまで待機します(最大1秒)。アクティブ化に失敗した場合もエラー表示して中断します。

  4. 座標のスケーリング MOVES 配列にはあらかじめ「ウィンドウサイズが 1440×900 のときの座標」として移動元 (src) と移動先 (dst) が定義されています。実際のウィンドウサイズは環境によって異なるため、

    • scaleX = 実際のウィンドウ幅 / 1440
    • scaleY = 実際のウィンドウ高さ / 900

    という倍率を計算し、基準座標をこの倍率で拡大・縮小することで、どのウィンドウサイズでも同じ位置(アイテム欄など)を正しくクリックできるようにしています。

  5. ドラッグ&ドロップの実行 MOVES の各要素についてループし、DragMouse 関数でアイテムを移動元から移動先へドラッグします。DragMouse は以下の手順で1回のドラッグ操作を再現しています。

    • 移動元座標へマウスを移動
    • 少し待機(moveDelay)
    • 左クリック押下(Click("Down Left"))
    • 少し待機(delay)
    • 移動先座標へマウスを移動
    • 少し待機(moveDelay)
    • 左クリック解放(Click("Up Left"))
    • 少し待機(delay)

    ゲームクライアント側の入力受付タイミングに対応するため、各操作の間に短い Sleep を挟んでいます。

まとめ

つまりこのスクリプトは、「1440×900 の画面を基準にしたアイテム欄の座標リスト」を実際のウィンドウサイズに合わせて自動計算し、ホットキー一発で複数のアイテムを連続してドラッグ移動させる、という仕組みになっています。