AutoWalk Script

Post gaming related scripts
User avatar
megnatar
Posts: 92
Joined: 27 Oct 2014, 20:49
Location: The Netherlands
Contact:

AutoWalk Script

10 Mar 2020, 04:39

Hey Folk

WORK IN PROGRESS...................

Someone asked me if I could write a better version of my autowalk function. So I written this script that enables autowalking for most games. Both 3D and those with a isometric camera are supported. I thought to share it here, maybe you find it useful.

script features:
- Autowalk for any game
- option to enable ingame isometric camera to auto follow the player.
- All hotkey's and sendkeys are configurable
- Active edit controlls that insert key name uppon pressing one. Controllers are supported
- The abillity to add extra hotkey's and code to the script.
- Some handy functions for sending key's and stuff. To make life easy.
- Remebers perviouse added games and they can easilly be loaded from a listview with icons.

Work in progress:
- Fully configurable spamkey function
- Pixel based autopot

Code: Select all

/*
    Autowalk v1.0.4.1 writen by Megnatar ⬖⬘⬗⬙

    Everyone is free to use, add code and redistribute this script.
    But you MUST always credit ME Megnatar for creating the source!
    The source code for this script can be found on my Github repository:
     https://github.com/Megnatar/AHK-Scripts/blob/master/Autowalk.ahk

    Usage:
    To add a new game, just drop the executable on the gui or use the browse button.

    Click in a edit box to set a new hotkey. Any posible key will do. The script will write
    the name of the key to the edit control. For example pressing numpad1 after a click inside a edit
    control will write numpad1 to it, not 1. Game controllers are supported.

    Enable the checkbox "RPG Games" for games with a isometric camera (top Down view).
    All these games use left mouse button Down to move around. Thus, double click the left
    mouse button to send LButton Down. Click again, once or twice, to stop.
    The hotkey and the key to send, are both configurable.

    When the camera does not automatically follow the player enable "Turn camera" and
    specify the two keys used by the game to rotate the camera left or right.
    A double click will now also enable auto rotation of the camera.

    IMPORTANT:
    - If the game does not accept input. Then enable admin mode and try again!
    - Droping files will NOT work when the script is running in admin mode.
    - You have to use the real executable for you're game, not a shortcut that looks like a exe.
      This is usually the case with games build on the Unreal engine. Look for a folder named Binaries or Bin.

    Great thanx to Turul1989 for helping me debug and undestand what needs to be added.
*/

#NoEnv
#SingleInstance force
#InstallKeybdHook
#KeyHistory 0
;#Include, Gdip_all.ahk
;ListLines off
SetBatchLines -1
SetTitleMatchMode 3
SetKeyDelay 5, 1
SetWorkingDir %A_ScriptDir%
sendmode Input
CoordMode, Mouse, screen

Global Wm_LbuttonDown   := 0x201
, Wm_Mousemove          := 0x200
, Wm_DraggGui           := 0x5050
, WM_NCLBUTTONDOWN      := 0xA1
, Ws_Caption            := 0xC00000
, Ws_Border             := 0x800000
, InputActive           := 0
, TipsOff               := 0
, ConfigFile            := A_ScriptDir "\Settings.ini"
, Profiles              := A_ScriptDir "\GameProfiles\GamesConfig.ini"
, IconLib               := []
, hScriptGui
, ControlBelowMouse
, ControlOldBelowMouse
, ctrlTxt
, A_hotKey
, now_x
, now_y
, Title

MenuItems           := {"Toggle Admin": "Admin", "Toggle Tooltips": "TipsOff", "Toggle OnTop": "OnTop", "Show Game List": "ShowGameList"}
DropNotice          := "Drop you're game executable here"
OpenFolder_TT       := "Open game installation dir.`nControl+Click to open script dir."
hKey_TT             := "HOTKEY.`nClick then press a button to change."
sKey_TT             := "SENDKEY.`nClick then press a button to change."
RunGame_TT          := "Start a new game session.`nActivates it, if it's already running."
LeftKey_TT          := "The key used by the game to turn camera left."
RightKey_TT         := "The key used by the game to turn camera right."
Browse_TT           := "Browse for a game to add."
LeftKey             := "Left"
RightKey            := "Right"
Gui_X               := "Center"
Gui_Y               := "Center"
KeyState            := "Up"
sKey                := "W"
hKey                := "XButton2"
RPGGames            := 0
TurnCamera          := 0
Admin               := 0
ShowGameList        := 0
OnTop               := 0
i                   := 0

If (FileExist(ConfigFile)) {
    iniRead(ConfigFile)
}

if (Admin & !A_IsAdmin) {
    Try {
        if (A_IsCompiled) {
            Run, *RunAs "%A_ScriptFullPath%"
        } else {
            Run, *RunAs "%A_AhkPath%" /ErrorStdOut "%A_ScriptFullPath%"
        }
    } Catch ThisError {
        MsgBox % ThisError
    }
    ExitApp
}

GUI % "+LastFound " (tgl := !OnTop ? "-" : "+") "AlwaysOnTop +OwnDialogs +hWndhScriptGui -Theme"
Menu GameMenu, Add, Get Vars, MenuGame
Menu Menu, Add, &Game, :GameMenu
Menu OptionsMenu, Add, Toggle Tooltips, MenuToggleOptions
Menu OptionsMenu, Add, Toggle Admin, MenuToggleOptions
Menu OptionsMenu, Add, Toggle OnTop, MenuToggleOptions
Menu OptionsMenu, Add
Menu OptionsMenu, Add, Show Game List, MenuToggleOptions
Menu Menu, Add, &Options, :OptionsMenu
Menu ToolsMenu, Add, Add Code, MenuTools
Menu ToolsMenu, Add, Spy Glass, MenuTools
Menu Menu, Add, &Tools, :ToolsMenu
Gui Menu, Menu

Gui Add, CheckBox, x368 y1 w10 h10 Checked%ShowGameList% vShowGameList gShowGameList -theme +0x1020 +E0x20000
Gui Add, GroupBox, x8 y0 w362 h194 +Center, % Admin ? "" : DropNotice
Gui Add, GroupBox, x16 y8 w345 h64
Gui Font, s10 Bold
Gui Add, Text, x24 y36 w329 h19 +Center +BackgroundTrans +0x200 vTitle, %Title%
Gui Font
Gui Add, Picture, x20 y18 w50 h50 +0x09 vPic, % "HICON:*" hIcon := LoadPicture(FullPath, "GDI+ Icon1 w50", ImageType)
Gui Add, Button, x307 y18 w50 h18 vBrowse, Browse
Gui Add, Button, x16 y160 w70 h23 vRunGame, &Start Game
Gui Add, Button, x88 y160 w70 h23 vOpenFolder, Open Folder
Gui Add, Button, x304 y160 w60 h23 gGuiClose, Exit
Gui Add, Button, x160 y160 w70 h23 vDelConf gDelConf, Delete ini
Gui Add, Button, x232 y160 w70 h23 vEndGame gEndGame, End Game
Gui Add, GroupBox, x16 y72 w345 h83
Gui Add, Text, x24 y80 w99 h14, Autowalk keys
Gui Add, Edit, x24 y100 w63 h21 Limit1 -TabStop vhKey, %hKey%
Gui Add, Edit, x24 y126 w63 h21 Limit1 -TabStop vskey, %skey%
Gui Add, CheckBox, x120 y104 w82 h23 Checked%RPGGames% vRPGGames gRPGGames, RPG Games
Gui Add, CheckBox, x120 y128 w82 h23 +Disabled Checked%TurnCamera% vTurnCamera gTurnCamera, Turn Camera
Gui Add, Edit, x212 y128 w60 h21 +Disabled Limit1 -TabStop vLeftKey, %LeftKey%
Gui Add, Edit, x280 y128 w60 h21 +Disabled Limit1 -TabStop vRightKey, %RightKey%
Gui Add, GroupBox, x376 y0 w154 h193 +Hidden vGBGameList
Gui Add, ListView, x384 y16 w137 h169 vLoadGameSetting gLoadGameSetting hWndhLVItems +Hidden, Icon|Window Title

LoadIcons()

if (RPGGames) {
    GuiControl([["Enable", "TurnCamera"]])
    if (TurnCamera = 1) {
        GuiControl([["Enable", "LeftKey"], ["Enable", "RightKey"]])
    }
}

For MenuItemTxt, VariableName in MenuItems
{
    if (%VariableName% = 1)
       Menu OptionsMenu, ToggleCheck, % MenuItemTxt
}

if (ShowGameList) {
    GuiControl([["Show", "GBGameList"], ["Show","LoadGameSetting"]])
    Gui Show, % "w" (Gui_W := 538) " h201 x" Gui_X " y" Gui_Y, AutoWalk
} else {
    Gui Show, % "w" (Gui_W := 378) " h201 x" Gui_X " y" Gui_Y, AutoWalk
}

OnMessage(Wm_MouseMove, "WM_Mouse"), OnMessage(Wm_LbuttonDown, "WM_Mouse"), OnMessage(Wm_DraggGui, "WM_Mouse"), OnExit("SaveSettings")
Return

;_______________________________________ Game Specific Code _______________________________________

#IfWinExist, AutoWalk
{
    #IfWinNotActive, AutoWalk
    {
        #IfWinExist, ahk_group ClientGroup
        {
            #IfWinActive, ahk_group ClientGroup
            {
                ; When this file "UserCode.ahk" resides in the same folder as where the script is.
                ; Then the code in that file is used by this script when the game window is active.
                ; Read comment on function ButtonSingleDouble() for more instructions.
                ;
                #Include *i UserCode.ahk

                HotKeyAutoWalk:
                If (RPGGames) {
                    If (A_Hotkey := KeyWait()) {
                        If (ErrLvL := KeyWait(A_hotKey, "D T0.2", 1) = 0) {
                            keywait(A_hotKey), KeyState := KeyState != "Down" ? "Down" : "Up"
                            Send {%A_hotKey% %KeyState%}

                            If ((TurnCamera = 1) & (KeyState = "Down")) {
                                AutoTurnCamera(A_hotKey, LeftKey, RightKey, VirtualKey := 1)
                            }
                        } else {
                            if (KeyState = "Down") {
                                KeyState := "Up"
                                Send {%A_hotKey% %KeyState%}
                            }
                        }
                    }
                } Else If (!RPGGames) {
                    InterruptDownState:

                    if (KeyState = "Down")
                        KeyWait()

                    KeyState := KeyState != "Down" ? "Down" : "Up"
                    Send {%sKey% %KeyState%}

                    if (KeyState = "Down") {
                        Hotkey, ~*Vk057, InterruptDownState, ON     ; Vk057 = w
                        Hotkey, ~*Vk01, InterruptDownState, ON      ; Vk01  = LButton
                    } else if (KeyState = "Up") {
                        Hotkey, ~*Vk057, InterruptDownState, OFF
                        Hotkey, ~*Vk01, InterruptDownState, OFF
                    }
                    Return
                }
                Return
            }
        }
    }
}
Return

;_______________________________________ Script Lables _______________________________________

MenuGame:
    If (A_ThisMenuItem = "Get Vars") {
        Gosub, ButtonStartGame
    }
Return

MenuToggleOptions:
    ; Check or uncheks the menuitem. Then toggles the value for the variable that is accosiated
    ; with the menuitem to the opsite. Saves or remove the variable to/from ini file.
    For MenuItemTxt, VariableName in MenuItems
    {
        If (A_ThisMenuItem = MenuItemTxt) {
            Menu %A_ThisMenu%, ToggleCheck, %MenuItemTxt%

            if (%VariableName% := %VariableName% ? 0 : 1) {
                IniWrite, % %VariableName%, %ConfigFile%, Settings, %VariableName%
            } else {
                IniDelete, %ConfigFile%, Settings, %VariableName%
            }
        }
    }
    ; Menu specific actions. They pritty much speak for them self.
    If (A_ThisMenuItem = "Toggle Admin") {
        i := Admin ? Reload() : ExitApp()
    }
    else If (A_ThisMenuItem = "Toggle OnTop") {
        tgl := OnTop = 0 ? "-" : "+"
        Gui 1:%tgl%AlwaysOnTop
    }
    else If (A_ThisMenuItem = "Show Game List") {
        if (ShowGameList) {
            WinMove, AutoWalk,,,, 538
            GuiControl([["Show", "GBGameList"], ["Show","LoadGameSetting"], ["", "ShowGameList", ShowGameList]])
        } else {
            GuiControl([["Hide", "GBGameList"], ["Hide","LoadGameSetting"], ["", "ShowGameList", ShowGameList]])
            WinMove, AutoWalk,,,, 384
        }
    }
Return

MenuTools:
    If (A_ThisMenuItem = "Add Code") {
		if (!DefaultEditor) {
			RegRead, DefaultEditor, HKEY_CLASSES_ROOT\AutoHotkeyScript\Shell\Edit\Command
			if (ErrorLevel) {
                MsgBox, 0x24, Missing default editor, % "It seems you're machine hase no default editor installed.`nDo you wish to select one?`n`nYes:`nFile association for *.ahk files will be configured for you're chosen tool.`n`nNo:`nThe script will use notepad to edit *.ahk files."

                IfMsgBox Yes, {
                    FileSelectFile DefaultEditor, 2,, Select your editor, Programs (*.exe, *.ahk)
                    if ErrorLevel
                        return
                    RegWrite REG_SZ, HKCR, AutoHotkeyScript\Shell\Edit\Command,, "%DefaultEditor%" "`%1"
                } Else IfMsgBox No, {
                    RegWrite REG_SZ, HKCR, AutoHotkeyScript\Shell\Edit\Command,, "Notepad.exe" "`%1"
                }
			} else if (!ErrorLevel) {
                MsgBox, 0x24, Missing default editor, % "A script editor is installed on you're machine.`nDo you want to use it to add code, using #include, to the script?`n`nYes to use you're default editor.`nNo will enable a editbox to add code."
                IfMsgBox Yes, {
                    IniWrite, % StrReplace(DefaultEditor, """" `%1 """"), %ConfigFile%, Settings, DefaultEditor
                } else {
                    Return
                }
            }
        }
    }
Return
ShowGameList:
    Menu OptionsMenu, ToggleCheck, Show Game List

    if (ShowGameList := ShowGameList ? 0 : 1) {
        WinMove, AutoWalk,,,, 538
        GuiControl([["Show", "GBGameList"], ["Show","LoadGameSetting"]])

        IniWrite, %ShowGameList%, %ConfigFile%, Settings, ShowGameList
    } else {
        GuiControl([["Hide", "GBGameList"], ["Hide","LoadGameSetting"]])
        WinMove, AutoWalk,,,, 384

        IniDelete, %ConfigFile%, Settings, ShowGameList
    }
Return

LoadGameSetting:
    Loop {
        if (!(RowNumber := LV_GetNext(RowNumber)))
            break
        LV_GetText(GameTitle, RowNumber, 2)
    }
    if (!GameTitle)
        Return

    MsgBox,0x24, Load new settings, % "Do you want to load the settings for this game:`n " GameTitle ""
    IfMsgBox Yes
    {
        If (FileExist(ConfigFile))
            FileDelete %ConfigFile%

        If (FileExist(Profiles)) {
            Loop, parse, % FileOpen(Profiles, 0).read(), `n, `r
            {
                if ((InStr(A_LoopField, "[",, 1, 1)) = 1) {
                    SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")

                } else if (GameTitle = SectionName) {
                    VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1), %VarRef% := SubStr(A_LoopField, InStr(A_LoopField, "=")+1)
                    if (%VarRef%)
                        IniWrite, % %VarRef%, %ConfigFile%, Settings, %VarRef%
                }
            }
            Reload()
        }
    }
return

AddCode:
Return

SpyGlass:
    SpyGlass := 1
    OnMessage(Wm_LbuttonDown, ""), OnMessage(Wm_DraggGui, "")
    CoordMode, Mouse, screen
    zoom = 2
    Ws_Caption := 0xC00000
    Ws_Border := 0x800000

    MouseGetPos, X, Y, hWndWinBelowCur

    Gui 2:+AlwaysOnTop +ToolWindow +OwnDialogs -0xC00000 -0x800000 +0x40000000 +E0x80000 +HwndhWndScript
    Gui 2:Show, w250 h250 x%X% y%Y%, Magnifier

    OnMessage(Wm_Mousemove, "Wm_Mousemove")
    WinGetClass, ClientGuiClass, ahk_id %hWndScript%
    WinSet, Region, 0-0 W150 H150 E, ahk_class %ClientGuiClass%
    WinSet, Transparent , 254, Magnifier

    SetTimer, MoveWin, 10

    ;retrieve the unique ID number (HWND/handle) of that window
    WinGet, hWndWinBelowCur, id
    hdc_frame := DllCall("GetDC", UInt, hWndScript)
    hdd_frame := DllCall("GetDC", UInt, hWndWinBelowCur)
    hdc_buffer := DllCall("gdi32.dll\CreateCompatibleDC", UInt,  hdc_frame)  ; buffer
    hbm_buffer := DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc_frame, Int,A_ScreenWidth, Int,A_ScreenHeight)
    SystemCursor("Toggle")
    Gosub, Repaint
return

Repaint:
    if (GetKeyState("LButton", "D")) {
        SetTimer, Repaint, Off
        OnMessage(Wm_LbuttonDown, "WM_Mouse"), OnMessage(Wm_DraggGui, "WM_Mouse")
    }

   MouseGetPos, X, Y, hWndWinBelowCur             ;  position of mouse
   WinGetPos, wx, wy, ww, wh, Magnifier
   wh2 := wh

   DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 0 )  ; No Antializing

   DllCall("gdi32.dll\StretchBlt", UInt, hdc_frame, Int, 0, Int, 0, Int, ww, Int, wh, UInt, hdd_frame, Int, X-(ww / 2 / zoom), Int, Y-(wh/2/zoom), Int, ww/zoom, Int, wh2/zoom ,UInt,0xCC0020) ; SRCCOPY

   SetTimer, Repaint , 0
Return

MoveWin:
MouseGetPos, now_x, now_y`
now_x -= 75
now_y -= 75
WinMove, Magnifier, , %now_x%, %now_y%
Return

!+WheelUp::			; Alt+Shift+WheelUp to zoom in
  If zoom != 16
      zoom *= 2
Return

!+WheelDown::		; Alt+Shift+WheelUp to zoom out
  If zoom != 2
      zoom /= 2
Return

!x::
    SystemCursor("On")
    DllCall("gdi32.dll\DeleteObject", UInt,hbm_buffer)
    DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
    DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
    DllCall("gdi32.dll\DeleteDC", UInt,hdc_buffer)
    Gui 2:Destroy
Return

GuiDropFiles:
    Loop, parse, A_GuiEvent, `n, `r
        FullPath := A_LoopField, Path := SubStr(A_LoopField, 1, InStr(A_LoopField, "\", ,-1)-1), ExeFile := SubStr(A_LoopField, InStr(A_LoopField, "\", ,-1)+1), FileDrop := 1

ButtonBrowse:
    If (!FileDrop) {
        FileSelectFile, FullPath, M3, , ,*.exe
        Loop, parse, % FullPath, `n, `r
            A_Index <= 1 ? Path := A_LoopField : ExeFile := A_LoopField
        if (ErrorLevel)
            Exit
    }

    FileGetSize, fileSize, %FullPath%, K
    if ((FileSize < 1024) & (FileSize != ""))
        MsgBox,,FileSize: %FileSize% KB, % "The size of you're file is less then 1MB`n`nAre you sure this is the real exe and not a shortcut`nto a ecxecutable some folders below`n`nFile size: " FileSize "KB"

    If (FileExist(ConfigFile))
        FileDelete %ConfigFile%

    IniWrite, % Admin := 1, %ConfigFile%, Settings, Admin
    IniWrite, % TipsOff := 1, %ConfigFile%, Settings, TipsOff
    IniWrite % FullPath := Trim(Path) "\" Trim(ExeFile), %ConfigFile%, Settings, FullPath
    IniWrite %Path%, %ConfigFile%, Settings, Path
    IniWrite %ExeFile%, %ConfigFile%, Settings, ExeFile
    IniWrite % Title := "Ready to start you're game", %ConfigFile%, Settings, Title
    IniWrite, % OnTop := 0, %ConfigFile%, Settings, OnTop
    Reload()
Return

RPGGames:
    GUI, submit, nohide
    IniWrite, %RPGGames%, %ConfigFile%, Settings, RPGGames
    if (RPGGames) {
        ;sKey := hKey := "LButton"
        GuiControl([[ , "hKey", "LButton"], [ , "sKey", "LButton"], ["Enable", "TurnCamera"]])
        IniWrite, % hKey := "LButton", %ConfigFile%, Settings, hKey
        IniWrite, % sKey := "LButton", %ConfigFile%, Settings, sKey
    } else {
        ;TurnCamera := ""
        GuiControl([["enable", "hKey"], ["Disable", "TurnCamera"], ["Disable", "LeftKey"], ["Disable", "RightKey"], [ , "TurnCamera", "0"]])
        IniWrite, % TurnCamera := "", %ConfigFile%, Settings, TurnCamera
    }
    GUI, submit, nohide
Return

TurnCamera:
    GUI, submit, nohide
    IniWrite, %TurnCamera%, %ConfigFile%, Settings, TurnCamera
    if (TurnCamera) {
        GuiControl([["Enable", "LeftKey"], ["Enable", "RightKey"]])
    } else {
        GuiControl([["Disable", "LeftKey"], ["Disable", "RightKey"]])
    }
    GUI, submit, nohide
Return

ButtonStartGame:
    ; Is the game already running?
    If (!(HwndClient := WinExist("ahk_exe " ExeFile))) {
        Run %ExeFile%, %Path%
        sleep, 10

        loop {
            ; Keep on checking for our window to appear. This is untill var HwndClient holds some value.
            If (!(HwndClient := WinExist("ahk_exe " ExeFile))) {
                if (CheckWinExist < 60) {
                    CheckWinExist += 1

                    ; Show a counter in the GUI when the script is waiting longer then 4 seconds.
                    if (CheckWinExist > 9)
                        GuiControl([[ , "Title", Title " " CheckWinExist ]])

                ; After 30 second a timeout will occur.
                } else if ((!HwndClient) & (CheckWinExist > 59)) {
                    MsgBox,0x24, Something is not oke!?, % "Unable to find client GUI!`nDo you wish to wait a nother 30 seconds?"
                    IfMsgBox Yes, {
                        CheckWinExist := ""
                        Continue
                    } else {
                        HwndClient := "", CheckWinExist := "NotFound"
                        break
                    }
                }
                sleep, 500
            }
            else If (HwndClient) {
                WinGetClass, GuiClass, ahk_exe %ExeFile%
                if (GuiClass = "DIEmWin" || GuiClass = "D3DProxyWindow" || GuiClass = "DXGIWatchdogThreadWindow"){
                    HwndClient := ""
                    Continue
                } else {
                    Break
                }
            }
        }
        ; Whem a timeout occurred and while() broke. Then jump back to the last return because messagebox choise was No.
        if (CheckWinExist = "NotFound") {
            Return
        } else {
            ; Remove timer from gui only when it started.
            if (CheckWinExist > 9)
                GuiControl([[ , "Title", Title]])

            WinGet, WinState, MinMax, ahk_exe %ExeFile%, , AutoWalk
        }
    ; When the game was already running.
    } else if (HwndClient) {
        WinGet, WinState, MinMax, ahk_exe %ExeFile%, , AutoWalk

    }
    sleep 5000

    if (WinState = -1) {
        WinSet, Bottom,, AutoWalk
        WinRestore, ahk_id %hWndClient%,, AutoWalk
        WinSet, Top,, ahk_id %hWndClient%
    } else {
        WinSet, Bottom,, AutoWalk
        WinActivate, ahk_id %hWndClient%,, AutoWalk
        WinSet, Top,, ahk_id %hWndClient%
    }

    ; Is active window the game window? A top most window is not always the active one.
    If (WinActive("A") != HwndClient)
        WinActivate, ahk_id %hWndClient%, , AutoWalk

    ;If ((Wintitle) & (Wintitle != "Ready to start you're game"))
    ; Some games launch a different window first.
    ; A window must exist by now. But is it our window? A game GUI never contains any
    ; controls in it. So getting all controls of the window that was just launched.
    WinGet, EmptyCtrlList, ControlList, ahk_exe %ExeFile%

    ; Eveluates true when var EmptyCtrlList is indeed empty.
    ; And if the game was not already launched by the script.
    If (EmptyCtrlList ? 0 : 1) {

        ; Get the window title and it's class name when a new game is launched for the first time.
        ; Save class and title to setting.ini file and put the title on the gui.
        If ((InStr(Title, "Ready to start you're game")) | (!Title)) {
            WinGetTitle, Title, ahk_exe %ExeFile%
            WinGetClass, ClientGuiClass, ahk_exe %ExeFile%

            IniWrite %Title%, %ConfigFile%, Settings, Title
            IniWrite %ClientGuiClass%, %ConfigFile%, Settings, ClientGuiClass

            GuiControl([[ , "Title", Title], ["MoveDraw", "Pic"]])
        }
    } else if (!ClientGroup & !OddCLient) {
        MsgBox,0x24, Game Window!?, % "This does not look like a game window!`n`nDo you want to Reload() the script?`nYou should then press the Start Game`nbutton once the game window is active."
        IfMsgBox Yes, {
            Reload()
        } else If (!OddCLient) {
            If ((InStr(Title, "Ready to start you're game")) | (!Title)) {
                WinGetTitle, Title, ahk_exe %ExeFile%
                WinGetClass, ClientGuiClass, ahk_exe %ExeFile%

                IniWrite %Title%, %ConfigFile%, Settings, Title
                IniWrite %ClientGuiClass%, %ConfigFile%, Settings, ClientGuiClass
                IniWrite % OddCLient := 1, %ConfigFile%, Settings, OddCLient

                GuiControl([[ , "Title", Title], ["MoveDraw", "Pic"]])
            }
        }
    }

    ; Create ClientGroup only once. The "ahk_group ClientGroup" is used by #IfWin[Not]Exist
    ; and #IfWin[Not]Active. All directives are loaded before ahk runs a script. Thus they
    ; don't understand variables. However ahk_group is supported.
    if (!ClientGroup, ClientGroup := 1)
        GroupAdd, ClientGroup, ahk_class %ClientGuiClass%

    Hotkey, ~%hKey%, HotKeyAutoWalk, On
Return

ButtonOpenFolder:
    KeyWait("LButton")
    If ((GetKeyState("LControl", "P")) | (GetKeyState("RControl", "P"))) {
        Run, Explorer.exe "%A_ScriptDir%"
    } else {
        Run, Explorer.exe "%Path%"
    }
Return

DelConf:
    If (FileExist(ConfigFile))
        FileDelete %ConfigFile%
    Reload()
Return

EndGame:
    WinClose, ahk_class %ClientGuiClass%
    Reload()
Return

GuiEscape:
GuiClose:
    ExitApp

;_______________________________________ Script Functions _______________________________________


LoadIcons() {
    Global

    Loop, parse, % FileOpen(Profiles, 0).read(), `n, `r
    {
        if ((InStr(A_LoopField, "[",, 1, 1)) = 1) {
            i += 1, SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")
            IniRead, Iconfile%i%, %Profiles%, %SectionName%, FullPath
            IconLib[i, 1] := Iconfile%i%, IconLib[i, 2] := SectionName
        }
    }

    i := 0, IconList := IL_Create(IconLib.Length())
    LV_SetImageList(IconList)

    loop % IconLib.Length()
    {
        IL_Add(IconList, IconLib[A_Index, 1]), LV_Add("Icon" . A_Index, , IconLib[A_Index, 2])
    }
    LV_ModifyCol("Hdr")
}

; Read ini file and create variables. Sections are supported.
; Referenced variables are not local to functions. So %VarRef% represents global
; variables to which some value is added %VarRef% := "ValueOfVar"
;
iniRead(InputFile, LoadSection = 0) {
    if (LoadSection) {
        if (IsObject(LoadSection)) {                                            ; Load multiple sections from object
             for i, Name in LoadSection
             {
                Loop, parse, % FileOpen(InputFile, 0).read(), `n, `r
                {
                    if (InStr(A_Loopfield, Name)) {
                        SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")
                        Continue
                    }
                    if (SectionName) {
                        if (((InStr(A_LoopField, "[",, 1, 1)) = 1) | ((InStr(A_LoopField, "`;",, 1, 1)) = 1) | (!A_LoopField)) {
                            if (((InStr(A_LoopField, "`;",, 1, 1)) = 1) | (!A_LoopField)) {
                                Continue
                            } else {
                                SectionName := ""
                                break
                            }
                        }
                        VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1), %VarRef% := SubStr(A_LoopField, InStr(A_LoopField, "=")+1)
                    }
                }
            }
        } else if (!IsObject(LoadSection)) {
            if ((InStr(LoadSection, " ")) > 1) {                                ; Load multiple sections
                Sections := []
                Loop, Parse, LoadSection, " ", A_Space
                    Sections[A_Index] := A_Loopfield
                for i, Name in Sections
                {
                    Loop, parse, % FileOpen(InputFile, 0).read(), `n, `r
                    {
                        if (InStr(A_Loopfield, Name)) {
                            SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")
                            Continue
                        }
                        if (SectionName) {
                            if (((InStr(A_LoopField, "[",, 1, 1)) = 1) | ((InStr(A_LoopField, "`;",, 1, 1)) = 1) | (!A_LoopField)) {
                                if (((InStr(A_LoopField, "`;",, 1, 1)) = 1) | (!A_LoopField)) {
                                    Continue
                                } else {
                                    SectionName := ""
                                    break
                                }
                            }
                            VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1), %VarRef% := SubStr(A_LoopField, InStr(A_LoopField, "=")+1)
                        }
                    }
                }
            } Else {                                                        ; Load single section
                Loop, parse, % FileOpen(InputFile, 0).read(), `n, `r
                {
                    if (InStr(A_Loopfield, LoadSection)) {
                        SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")
                        Continue
                    }
                    If (SectionName) {
                        if ((InStr(A_LoopField, "[",, 1, 1)) = 1)
                            Break
                        VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1), %VarRef% := SubStr(A_LoopField, InStr(A_LoopField, "=")+1)
                    }
                }
            }
        }
    } else if (!LoadSection) {                                              ; Load all variables from ini
        Loop, parse, % FileOpen(InputFile, 0).read(), `n, `r
        {
            if (((InStr(A_LoopField, "[",, 1, 1)) = 1) | ((InStr(A_LoopField, "`;",, 1, 1)) = 1) | (!A_LoopField))
                Continue
            VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1), %VarRef% := SubStr(A_LoopField, InStr(A_LoopField, "=")+1)
        }
    }
    Return
}

; KeyWait as a function for more flexible usage. Returns the key it waited for or ErrorLevel.
; When no parameters are used, keywait will use the value in A_ThisHotkey as the key to wait for.
;
KeyWait(Key = 0, Options = 0, ErrLvL = 0) {
    keywait, % ThisKey := Key ? Key : RegExReplace(A_ThisHotkey, "[~\*\$]"), % Options
    Return ErrLvL = 1 ? ErrorLevel : ThisKey
}

; Returns the last hotkey used with all basic modifiers removed from it.
ThisHotKey() {
    Return RegExReplace(A_ThisHotkey, "[~\*\$]")
}

/*
    GuiControl as a function for more flexible usage. Parameter ControlID can be a array.
    For example, if you want to use the GuiControl command 3 times in a row.
    Then the array should look something like:
    ControlID := [[SubCommand, ControlID, Value], [SubCommand, ControlID], [ , ControlID, Value]]

    You can also insert objects directly on the parameter for ControlID.
    GuiControl([[SubCommand, ControlID, Value], [SubCommand, ControlID], [ , ControlID, Value]])

    Command options. See ahk manual for details.

    • (Blank): Puts new contents into the control.
    • Text: Changes the text/caption of the control.
    • Move: Moves and/or resizes the control.
    • MoveDraw: Moves and/or resizes the control and repaints the region occupied by it.
    • Focus: Sets keyboard focus to the control.
    • Disable: Disables (grays out) the control.
    • Enable: Enables the control.
    • Hide: Hides the control.
    • Show: Shows the control.
    • Delete: Not yet implemented.
    • Choose: Selects the specified item number in a multi-item control.
    • ChooseString: Selects a item in a multi-item control whose leading part matches a string.
    • Font: Changes the control's font typeface, size, color, and style.
    • Options: Add or remove various control-specific or general options and styles.
*/
GuiControl(ControlID, SubCommand = 0, Value = 0) {
    If (IsObject(ControlID)) {
        Loop % ControlID.Length() {
            GuiControl % ControlID[A_index][1], % ControlID[A_index][2], % ControlID[A_index][3]
        }
    } else {
        GuiControl % SubCommand, % ControlID, % Value
    }
    Return ErrorLevel
}

; Keep track of mouse movement and left mouse button state inside the GUI.
WM_Mouse(wParam, lParam, msg, hWnd) {
    Static ClsNNPrevious, ClsNNCurrent, _TT, CurrControl, PrevControl
    ListLines off   ; Even when globaly enabled. Best to set it off here.

    ; ClsNNPrevious and ClsNNCurrent will hold the same value while the mouse moves inside a control.
    ClsNNPrevious := ClsNNCurrent
    MouseGetPos, , , , ClsNNCurrent
    ControlBelowMouse := ClsNNCurrent

    ; When the mouse moved from one control to the other. ClsNNPrevious and ClsNNCurrent, both hold a different value.
    if (ClsNNPrevious != ClsNNCurrent)
        ControlOldBelowMouse := ClsNNPrevious

    if (msg = WM_MOUSEMOVE) {
        If (SpyGlass = 1) {
            MouseGetPos, now_x, now_y
            now_x -= 75
            now_y -= 75
            WinMove, Magnifier, , %now_x%, %now_y%
            ToolTip % now_x "  " now_y
        }

        if (!TipsOff) {
            CurrControl := A_GuiControl

            if ((ClsNNPrevious != ClsNNCurrent) & (!InStr(CurrControl, " "))) {
                ToolTip  ; Turn off any previous tooltip.
                SetTimer, DisplayToolTip, 750
                PrevControl := CurrControl
            }
            return

            DisplayToolTip:
            SetTimer, DisplayToolTip, Off
            ToolTip % %CurrControl%_TT  ; The leading percent sign tell it to use an expression.
            SetTimer, RemoveToolTip, 5000
            return

            RemoveToolTip:
            SetTimer, RemoveToolTip, Off
            ToolTip
            return
        }
    }
    if (msg = Wm_LbuttonDown) {
        SetTimer, RemoveToolTip, Off
        ToolTip

        ; When some control under the mouse is a Edit control and the script is not already getting a key.
        If ((InputActive = 0) & (InputActive := InStr(ControlBelowMouse, "Edit"))) {
            GuiControlGet, IsControlOn, Enabled, %ControlBelowMouse%

            ; Ignore the windows used by autohotkey for ListVars, ListLines and so on.
            If (WinGetActiveTitle() != "AutoWalk")
             Return

            ; And when this control is not disabled.
            If (IsControlOn = 1) {

                ; store it's text and give the control input focus (actually it's the other way around, hehe).
                ControlFocus, %ControlBelowMouse%
                ControlGetText, ctrlTxt, %ControlBelowMouse%

                ; Briefly enable this control to call function EditGetKey when it recieves some input.
                GuiControl([["+gEditGetKey", ControlBelowMouse], [ , ControlBelowMouse], ["-gEditGetKey", ControlBelowMouse]])
            } else {
                InputActive := 0
            }
        }
        if ((GetKeyState("LButton", "P")) & (!A_GuiControl)) {
            PostMessage, Wm_DraggGui
        }
        Return
    }

    if (msg = Wm_DraggGui) {
        if ((GetKeyState("LButton", "P")) & (!A_GuiControl)) {
            FadeInOut(hScriptGui, 1)
            PostMessage, WM_NCLBUTTONDOWN, 2
            KeyWait("LButton")
            FadeInOut(hScriptGui)
        }
        Return
    }
}

WinGetActiveTitle() {
    WinGetActiveTitle OutputVar
    Return OutputVar
}

; Write back the name of any keyboard, mouse or joystick button to a edit control.
EditGetKey() {
    static InputKeys := ["LButton", "RButton", "MButton", "XButton1", "XButton2", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9","Numpad10","NumpadEnter", "NumpadAdd", "NumpadSub","NumpadMult", "NumpadDev", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Left", "Right", "Up", "Down", "Home","End", "PgUp", "PgDn", "Del", "Ins", "Capslock", "Numlock", "PrintScreen", "Pause", "LControl", "RControl", "LAlt", "RAlt", "LShift","RShift", "LWin", "RWin", "AppsKey", "BackSpace", "space", "Tab", "Esc", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N","O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", ".", "/", "[", "]", "\", "'", ";", "` ","Joy1", "Joy2", "Joy3", "Joy4", "Joy5", "Joy6", "Joy7", "Joy8", "Joy9", "Joy10", "Joy11", "Joy12", "Joy13", "Joy14", "Joy15", "Joy16", "Joy17","Joy18", "Joy19", "Joy20", "Joy21", "Joy22", "Joy23", "Joy24", "Joy25", "Joy26", "Joy27", "Joy28", "Joy29", "Joy30","Joy31", "Joy32"]

    KeyWait("LButton")

    ; Prevent a right click from showing the context menu.
    Hotkey, IfWinExist, AutoWalk
    Hotkey, Vk02 Up, RbttnUp, On     ; Vk02 = RButton

    ; Loop untill the user pressed some button or as long as the mouse is over some edit box.
    Critical
    loop {
        ; Getting user input from array Inputkeys.
        For k, ThisKey in InputKeys {
            if (GetKeyState(ThisKey, "P")) {
                GuiControl(ControlBelowMouse, "", ThisKey)
                ExitLoop := KeyWait(ThisKey)
                Break
            }
            ; When ControlBelowMouse does not contain the word "Edit". Then the mouse moved away from the control.
            If (!InStr(ControlBelowMouse, "Edit") & InStr(ControlOldBelowMouse, "Edit")) {
                ExitLoop := 1
                GuiControl(ControlOldBelowMouse, "", ctrlTxt)
                ControlFocus, %ControlBelowMouse%
                Break
            }
        }
        If (ExitLoop)
            break
    }
    Critical Off
    ControlFocus, Button2
    GUI, submit, nohide

    ; Save new values to Settings.ini if the For loop didn't break when the mouse moved outside the control.
    If (ExitLoop != 1)
        IniWrite, %ThisKey%, %ConfigFile%, Settings, %A_GuiControl%

    RbttnUp:
        Hotkey, IfWinExist, AutoWalk
        Hotkey, Vk02 Up, RbttnUp, Off

    InputActive := 0
    Return
}

; Send some key on a sinlge or double press of a button.
; The hotkey is optional and when ThisHotKey is empty Keywait() will return the last hokey used.
; This function can be used with the UserCode.ahk file e.g.:
; Below code would send A when F is pressed once. And B when F is pressed twice
; F::
;   ButtonSingleDouble("A", "B")
; Return
;
; And this will send B when you double click the right mouse button
; ~RButton::
;   ButtonSingleDouble("", "B")
; Return
;
ButtonSingleDouble(KeySingle, KeyDouble, ThisHotKey = 0, WaitRelease = 0) {
    if (WaitRelease) {
        Send {%KeySingle% Down}
        A_hotKey := ThisHotKey ? keywait(ThisHotKey) : keywait()
        Send {%KeySingle% Up}

        if (keywait(A_hotKey, "D T0.1", 1) = 0) {
            Send {%KeyDouble% Down}
            KeyWait(A_hotKey)
            Send {%KeyDouble% Up}
        }
    } else if (!WaitRelease) {
        A_hotKey := ThisHotKey ? keywait(ThisHotKey) : keywait()

        if (keywait(A_hotKey, "D T0.1", 1) = 0) {
            Send {%KeyDouble% Down}{%KeyDouble% Up}
        } else {
            Send {%KeySingle% Down}{%KeySingle% Up}
        }
    }
    Return
}

; Automaticly turn the ingame camera to follow the player when some key is down.
AutoTurnCamera(KeyDown, RotateL, RotateR, VirtualKey = 0, DownPeriod = 40, DeadZone = 35) {
    Static Rad := 180 / 3.1415926

    ; The width and hight of the client gui might change in between calls, so getting them here.
    WinGetPos, , ,gW, gH, A

    ; Check mouse position and turns the camera when the mouse moved outside a deadszone while the key in KeyDown has status Down.
    ; By default the physical key state is monitored. Set parameter VirtualKey to 1 to check the logical key state. Logical is when
    ; a key is send Down by the send command or in some other way.
    ;
    While(GetKeyState(KeyDown, (!VirtualKey ? "P" : ""))) {
        MouseGetPos, mX, mY

        ; Calculate cursor position, where the vertical/horizontal centre of the display are seen as zero. Both the left and right side
        ; of the display are seen as positive (Abs). A triangle (ATan) of 70 degrees (35*2) is created from the very centre to the top/bottom.
        ; These triangles will be the dead zone, where the camera does not turn.
        ;
        if (((((X := mX - gW/2) * mX) + ((Y := gH/2 - mY) * mY) < 10000) | (Y > 0)) & ((Abs(ATan(X/Y)) * Rad) < DeadZone)) {
            continue
        }

        ; Turn the ingame camera left or right when the mouse moved outside the deadzone.
        ; I advice to make the value in DownPeriod not greater then the 50ms sleep. If you do,
        ; then also increase the sleep period to somthing greater then the down perdiod.
        ; This will result in a smoother turning of the camera.
        ;
        if (X < 0) {
            Send {%RotateL% Down}
            Sleep, %DownPeriod%
            Send {%RotateL% Up}
        } else {
            Send {%RotateR% Down}
            Sleep, %DownPeriod%
            Send {%RotateR% Up}
        }
        sleep 50
    }
    Return
}

; Fade transparency out or in while dragging the Gui.
FadeInOut(hWnd, dragg = 0) {
    static Transparency := 250
    if (dragg = 1) {
        Loop {
            If (A_TickCount >= WaitNextTick) {
                WaitNextTick := A_TickCount+50
                WinSet, Transparent, % Transparency -= 20, ahk_id %hWnd%
                If (Transparency <= 210)
                    break
            }
        }
    } else if (dragg = 0) {
        Loop {
            If (A_TickCount >= WaitNextTick) {
                WaitNextTick := A_TickCount+50
                WinSet, Transparent, % Transparency += 20, ahk_id %hWnd%
                If (Transparency >= 255) {
                    WinSet, Transparent, Off, ahk_id %hWnd%
                    break
                }
            }
        }
    }
    return
}

; Not mine, but borrowed from the ahk manual.
SystemCursor(OnOff=1)   ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
{
    static AndMask, XorMask, $, h_cursor
        , c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors
        , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13    ; blank cursors
        , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13    ; handles of default cursors
    if (OnOff = "Init" or OnOff = "I" or $ = "")        ; init when requested or at first call
    {
        $ := "h"                                       ; active default cursors
        VarSetCapacity( h_cursor,4444, 1 )
        VarSetCapacity( AndMask, 32*4, 0xFF )
        VarSetCapacity( XorMask, 32*4, 0 )
        system_cursors := "32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650"
        StringSplit c, system_cursors, `,
        Loop %c0%
        {
            h_cursor   := DllCall( "LoadCursor", "Ptr",0, "Ptr",c%A_Index% )
            h%A_Index% := DllCall( "CopyImage", "Ptr",h_cursor, "UInt",2, "Int",0, "Int",0, "UInt",0 )
            b%A_Index% := DllCall( "CreateCursor", "Ptr",0, "Int",0, "Int",0
                , "Int",32, "Int",32, "Ptr",&AndMask, "Ptr",&XorMask )
        }
    }
    if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T"))
        $ := "b"  ; use blank cursors
    else
        $ := "h"  ; use the saved cursors

    Loop %c0%
    {
        h_cursor := DllCall( "CopyImage", "Ptr",%$%%A_Index%, "UInt",2, "Int",0, "Int",0, "UInt",0 )
        DllCall( "SetSystemCursor", "Ptr",h_cursor, "UInt",c%A_Index% )
    }
}

; Reload and below exit, the script without calling function SaveSettings() first.
; Also handy because functions can be called from shorthand operators like "?".
Reload() {
    OnExit("SaveSettings", 0)
    Reload
}

ExitApp() {
    OnExit("SaveSettings", 0)
    ExitApp
}

; This is called right before the script terminates. It saves the position of the GUI and copies
; all current variables from the settings.ini to \GameProfiles\GamesConfig.ini. 
; GamesConfig.ini contains all variables from the previous used games.
SaveSettings() {
    WinGetPos, Gui_X, Gui_Y, ,, AutoWalk

     ; Remember the position of the script GUI.
    if ((Gui_X > -1) & (Gui_Y > -1)) {
        IniWrite, %Gui_X%, %ConfigFile%, Settings, Gui_X
        IniWrite, %Gui_Y%, %ConfigFile%, Settings, Gui_Y
    }

    if (Title) {
        If (!FileExist(Profiles)) {
            FileCreateDir, GameProfiles
            FileAppend,, %Profiles%
        }

        If (Title != "Ready to start you're game") {
            Loop, parse, % FileOpen(ConfigFile, 0).read(), `n, `r
            {
                if (InStr(A_Loopfield, "[")) {
                    SectionName := StrReplace(A_Loopfield, "["), SectionName := StrReplace(SectionName, "]")
                    IniDelete, %Profiles%, %Title%
                    FileAppend, % "[" Title "]", %Profiles%
                }
                Else If (SectionName && A_LoopField) {
                    VarRef := SubStr(A_LoopField, 1, InStr(A_LoopField, "=")-1)
                    IniWrite, % %VarRef%, %Profiles%, %Title%, %VarRef%
                }
            }
        }
    }
}
alexionut32
Posts: 3
Joined: 04 Jul 2020, 17:36

Re: AutoWalk Script

05 Jul 2020, 05:18

how can i select my game if it opens only with launcher , i mean if i choose launcher nothing happens , i need to choose the game.exe but if i chose it i cant open it without launcher

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 8 guests