This is a script I made a while ago and have been using personally for some time. It is a lightweight hotkey tool made for people who (still) play the DotA custom map on Warcraft III. The functions it contains are as listed below:
- Item hotkey assignment (Spacebar is always assigned to item (7))
- mouse trap
- automatic typing (primarily used for lane calling) via the mouse wheel
- special hero hotkeys (namely Nevermore* and Invoker**)
#Note: DMU by default uses memory reading to read Warcraft III for certain information. This should be used at your own risk (of whatever rules you might be breaking. AFAIK, it's impossible for this to be detected server-sided so you are quite safe). Of course, there is an alternative method, which I call 'manual' mode. This information DMU needs in particular is simply to tell whether chat bar is on, or if the user is in game. So that way you don't get annoying text7like7this7when7you7type. I'll elaborate on the manual mode later.
[HOTKEYS]
DMU's main menu can only be accessed if Warcraft III is on. You can exit it by right clicking its icon in the taskbar. The hotkeys for DMU are as follows:
Ctrl-Alt : brings up main menu
F5 : turns on mouse trap (for those playing in windowed mode)
F6 : turns off mouse trap
#Note: The scrolllock light turns on if mouse trap is on.
End : Toggle DMU on and off (as shown by numlock light)
Ctrl-End : Restart DMU
[HERO HOTKEYS]
The special hero hotkeys for Nevermore and Invoker deserve some special mention:
* The hotkeys for Nevermore have been assigned to e,r,t,g. The keys e,r and t are for his razes from shortest to furthest. There is an added feature of automatic raze stopping. Basically if the user right clicks within a certain period of time during the raze animation, DMU will emulate the s key (which is action cancel) then proceed with the right click. Another feature is chain razing, where the user can press all three keys for the three razes in any order, and DMU will automatically time them one after another in series. This can be useful as DotA only allows you to chain at most two razes. This leads to the last feature, which I believe is crap. The raze chaining works by DMU counting down in ticks, so the razes are timed to be (moderately) fast. There is however a trick in DotA to always manually chain razes as fast as possible, and it is not something that a quick google search can't get you.
** Special hotkeys for Invoker are extremely useful, in that you only have to press one button for DMU to invoke up the spell as well as cast it. I know there have been previous scripts designed for this, but I believe mine is better nuff said . (not serious at all). Basically how it works is that when you press a certain hotkey, lets say d (which would invoke sunstrike), DMU first presses the actual hotkey for sunstrike, wait a very short amount of time, then press the hotkeys necessary to invoke, then cast sunstrike (so it would be e,e,e,r,t). The way this is so amazing in its simplicity is because if the spell had already been previously invoked, the cursor would turn into the crosshair target, thus disabling any other hotkeys from doing anything. Hence, this eliminates the trouble of having to guess what spells already exist, which other Invoker scripts out there do). Spam away! (works best when playing with minimal lag, or as host)
Invoker Hotkeys:
q - Chaos Meteor
w - Deafening Blast
e - Tornado
r - Ghost Walk (power balls always switch to Wex (x3) on cast for extra movespeed)
t - Ice Wall
d - Sun Strike
f - Forge Spirit
g - Cold Snap
c - Alacrity
v - EMP
b - Rotate through orbs
#Note: If shift is held when using any of those hotkeys, DMU will invoke the spells but not cast. This is particularly useful for spells that do not have targeting, such as ice wall and ghost walk. This way you can keep them ready under your belt without being forced to having to use them. Also another note, DMU does not initiate the ghost walk combo with a cast, else when it tries invoking it, windwalk will be broken. As a result, you can use ctrl+hotkey, to not invoke and only cast. That way you don't have to waste mana invoking if you previously invoked the spell already. (Ctrl-hotkey also works for ice wall)
#Note: For techies, pressing y makes him suicide on the spot (not a really elegant way of doing it but meh)
[MISC.]
whew.
I'll quickly talk about the other misc stuff, such as editing the looks of DMU's main menu and 'manual' mode. Running DMU will create a settings.ini file that contains the saved settings for basically everything. You can edit it with notepad. The important areas are namely the words to type for mouse wheel hotkeys and the colours, etc for the graphical interface. The first two digits for the RGB hexadecimal is the transparency value. You can explore the other graphic settings yourself.
What 'manual' mode is is basically colour detection. To use manual mode, you have to set the coordinates to check the colour against every time you use one of the hotkeys. That's what the two buttons are for, each for the two different team menu graphic schemes (Sentinel - leafs, Scourge - bones). When you click first set, you would be prompted to LEFT-click any spot of the screen. The appropriate location to click would be a pixel ON the menu (as the colour of that spot stays the same throughout the game), UNDER where the chat bar thingo would overlap. This way, if you press enter to type something, the chat bat would pop up, change the colour of that pixel, and DMU will then know to turn hotkeys off for the pleasure of your typing. Second set removes the hassle of finding a spot, and instead records the colour at the SAME coordinates you set with first set. So you essentially need to either find a nice pixel that is on the menu under the chat bar for both sides, or simply reset first set every time you are playing on a different side. (My instructions here probably don't make much sense :? )
...Hopefully the memory reading mode works for you and you can use it. Saves you quite a bit of hassle.
I'll add more stuff to this already ranting post if people are interested in this script at all. Just a few notes:
- DMU needs to run with admin to work. I also strongly recommend you to play in windowed mode with this. A quick google search will help if you don't know how.
- I had to quickly remove some of my more 'personal' functions from DMU before I uploaded it, so the code might contain some random variables that aren't in use any more.
- Not sure how the autohotkey_L and autohotkey compatibility works nowadays. As far as I am concerned the codes load fine on my (I believe outdated) 'vanilla' autohotkey. I'll just leave a separate download link for the compiled .exe.
- I'll try to answer any question you might have.
- Credits to tic for his Gdip library, which I used extensively in DMU
- and also credits to whoever's ReadMemory() function I used in DMU, been a while and I couldn't remember who I stole it from. :oops:
TL;DR - This is basically a very useful program to play DotA with.
[Download links]
.ahk files
.exe file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SCRIPT CONFIGURATIONS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #SingleInstance force ;Only one instance of the program will run (new instances will replace previous ones) #MaxThreads 20 ;Sets the maximum amount of simultaneous threads to 20 SetBatchLines, -1 ;Program will run at maximum speed SetTitleMatchMode, 3 ;Window titles must be an exact match Sendmode Play ;Send and Sendinput will be in "play" mode SetWorkingDir, %A_ScriptDir% ;Set program to use its folder as working directory SetNumLockState, AlwaysOn ;Number Lock light is on (indicating that program is running) SetScrollLockState, AlwaysOff ;Scroll Lock light is off (indicating state of mouse lock) ;;;;;;;;;;;;;;;;;;;;;;;; ;; GENERAL SETTINGS ;; ;;;;;;;;;;;;;;;;;;;;;;;; DMU_VERSION = 2.01 ;Verson of Program (will be written into %SETTINGS_NAME%) EXPIRY_YEAR = 2013 ;Year of which the program will self-delete on startup (Date is detected via %TIMESERVER% if user is online) APPLICATION_NAME = DotA Master Utilities.exe ;Variable containing the full name of the program SETTINGS_NAME = Settings.ini ;Variable containing the full name of the Settings ini file XFIRE_INTEGRATION = WarIM.exe ;Varaible containing the name of the XFIRE integration program (not in use) ;Memory Addresses for w3l.exe v1.25.1.6397 ;Memory address to check for in game, but has the glitch of returning 1 in single player custom map menu. The return freezes at 1 until a game is exited or a waiting room is left ; - 1873504484 (Returns 1 starting from waiting room until the closing of end-game scoreboard) ;BETA memory address to check for in game. Not fully tested and not known if it has returns other than exact 1/0 but does not have the glitch of the code above ; - 1873471690 (Returns 1 starting from game load until the closing of end-game scoreboard) ;Alternate memory address to check for in game. Not recommended but returns exact and fast 1/0 values ; - 1873602105 (Returns 1 starting from Custom Game (online) menu until the showing of end-game scoreboard) ADDRESS_INGAME = 1873471690 ;Address containing the value indicating in-game ADDRESS_CHATBAR = 1873614320 ;Address containing the value indicating chat bar on/off #Include, Gdip.ahk ;The script that contains the GDI+ library #Include, DMU Functions.ahk ;The script that contains the majority of DMU functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MISC. VARIABLE DECLARATIONS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #IfWinNotActive, Warcraft III Suspend On ;Program suspension on Warcraft III inactivity #IfWinActive, Warcraft III Suspend Off ;Program resume VarSetCapacity(OUTPUT, 2, 0) ;Capacity setting for the variable of READMEMORY() MOUSE_TRAPPED = False ;Variable indicating the current status of Mouse Trap (True/False) JUST_CALLED = False ;Variable that is used to limit the amount of mouse calls per wheel roll MSGBOX_TIMEOUT_LONG = 5 ;Variable indicating the amount of timeout for messageboxes (seconds) MSGBOX_TIMEOUT_SHORT = 0.5 ;Variable indicating the amount of timeout for messageboxes (seconds) Menu, Tray, NoStandard ;Removes the standard tray icon menu Menu, Tray, Add, Exit, TERMINATE_APP ;Adds the Exit option to the tray icon menu MSN_TRANSPARENCY = 150 ;Transparency value for MSN windows activated via MSN Sync GDIPSTARTUPCHECK() ;Function to detect the availability of GDI+ library OnExit, TERMINATE_APP ;Program will Goto TERMINATE_APP on exit or reload ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SETTINGS CALIBRATION ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; IfNotExist, %SETTINGS_NAME% FileAppend, % DEFAULTSETTINGS(), %SETTINGS_NAME% ;If Settings ini file does not exist, create one with default settings ;;;;;;;;;;;;;;;;;;;; ;; GUI SETTINGS ;; ;;;;;;;;;;;;;;;;;;;; ;The GUI thread priority numbers essential for GUI creation GUI_ITEMHOTKEYS = 2 ;The main menu of the program conataining the controls GDI_BACKGROUND = 3 ;The GDI menu of the program that accompanies the main menu GDI_MESSAGEBOX = 4 ;The menu for all GDI+ messageboxes GUI_ITEMHOTKEYS_TITLE = DMU_Foreground ;The title of %GUI_ITEMHOTKEYS% GDI_BACKGROUND_TITLE = DMU_Background ;The title of %GDI_BACKGROUND% LOADGDIGUISETTINGS() ;The function to load the settings for GDI+ from %SETTINGS_NAME% (color, frame width etc.) GDI_TEXT_COLOR := SubStr(GDI_TEXT_COLOR, 3, 8) ;The text color of the GDI background has to be SubStr since parameter only does not accept "0x" GUI_WIDTH = 159 ;Width of GDI background and GUI menu GUI_HEIGHT = 260 ;HEight of GDI background and GUI menu DEFAULT_SETTINGSICON_X = 130 ;X location of the settings button DEFAULT_SETTINGSICON_Y = 119 ;Y location of the settings button SETTINGSICON_X = %DEFAULT_SETTINGSICON_X% ;This variable is used in the process of creating the settings button SETTINGSICON_Y = %DEFAULT_SETTINGSICON_Y% ;This variable is used in the process of creating the settings button SETTINGSICON_WIDTH = 19 ;Width of the settings button SETTINGSICON_HEIGHT = 19 ;Height of the settings button ;;;;;;;;;;;;;;;;;;;;; ;; HERO SETTINGS ;; ;;;;;;;;;;;;;;;;;;;;; HERO_AVAILABLE = None||Nevermore|Invoker|Techies ;This is the list of heroes to display in the dropdownlist of the menu CURRENT_HEROHOTKEYS = ;This variable will store the string of hotkeys belonging to the chosen hero NEVERMORE_SLEEP = 800 ;This variable is the amount of time Nevermore pauses between chain razing (in milliseconds) INVOKER_SLEEP1 = 290 ;These three variables are the amount of time Invoker pauses after he invokes, before he casts the second time(in milliseconds) INVOKER_SLEEP2 = 400 INVOKER_SLEEP3 = 500 INVOKER_SLEEP = %Invoker_Sleep2% ;This program only allows one choice of sleep time for Invoker INVOKER_SLEEPPICK = 2 ;Not in Use INVOKER_DELAY = 25 ;This variable is the short amoount of time Invoker pauses after initial casting, before invoking (in milliseconds) CURRENTBALLVAR = 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; Enter New Hero Codes Here ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ;; SETTINGS LOAD ;; ;;;;;;;;;;;;;;;;;;;;; LOADSETTINGS() ;This function loads all the necessary configurations (hotkeys, manual mode settings, mouse calls etc) MONITORITEMHOTKEYS() ;This function is responsible for monitoring and comparing item and hero hotkeys. If recurrences or overlapping of hotkeys are found, item hotkeys are reset to default TURNONITEMHOTKEYS() ;This function turns on the hotkeys of items ;;;;;;;;;;;;;;;;;;;;;;; ;; DEFAULT HOTKEYS ;; ;;;;;;;;;;;;;;;;;;;;;;; Hotkey, F5, MOUSETRAP, On ;This section turns on the default hotkeys (mouse lock and mouse call hotkeys) Hotkey, F6, MOUSEUNTRAP, On Hotkey, WheelUp, FIRSTCALL, On Hotkey, MButton, SECONDCALL, On Hotkey, WheelDown, THIRDCALL, On Hotkey, MButton & WheelUp, FOURTHCALL, On Hotkey, MButton & WheelDown, FIFTHCALL, On ;;;;;;;;;;;;;;;;;;;;;;; ;; GUI_ITEMHOTKEYS ;; ;;;;;;;;;;;;;;;;;;;;;;; Gui, %GUI_ITEMHOTKEYS%: Color, % "0x" . SubStr(GDI_BACKGROUND_COLOR, 5, 6) ;This sets the background color of the main GUI menu to be the same color of the GDI background Gui, %GUI_ITEMHOTKEYS%: -Caption +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, w48 r1 y41 x29 Section Disabled, Space ;This adds the read-only "Space" hotkey Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, gTAB wp hp yp x+5 vHOTKEY2 Limit254, %HOTKEY2% ;These add the remaining five editable hotkeys. They are laid out in the same format as the item slots Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, gTAB wp hp y+5 xs vHOTKEY3 Limit254, %HOTKEY3% Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, gTAB wp hp yp x+5 vHOTKEY4 Limit254, %HOTKEY4% Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, gTAB wp hp y+5 xs vHOTKEY5 Limit254, %HOTKEY5% Gui, %GUI_ITEMHOTKEYS%: Add, Hotkey, gTAB wp hp yp x+5 vHOTKEY6 Limit254, %HOTKEY6% If StrLen(SENTINELCOLOR) = 8 ;If the color values for SENTINELCOLOR is available, the manual mode checkbox will not be disabled and { ; the "Set" buttons will contain the appropriate text Gui, %GUI_ITEMHOTKEYS%: Add, Checkbox, x26 y+25 vMANUAL Checked%MANUAL% Gui, %GUI_ITEMHOTKEYS%: Add, Button, gFIRSTSET w62 x15, Reset First Gui, %GUI_ITEMHOTKEYS%: Add, Button, gSECONDSET w62 yp xp+67, Set Second } Else ;If the color values for SENTINELCOLOR is unavailable, the manual mode checkbox and the button for { ; "Second Set" will be disabled MANUAL = 0 Gui, %GUI_ITEMHOTKEYS%: Add, Checkbox, x26 y+25 vMANUAL Disabled Check%MANUAL% Gui, %GUI_ITEMHOTKEYS%: Add, Button, gFIRSTSET w62 x15, Set First Gui, %GUI_ITEMHOTKEYS%: Add, Button, gSECONDSET w62 yp xp+67 Disabled, Set Second } ;The code below adds the dropdownlist for hero hotkey selection Gui, %GUI_ITEMHOTKEYS%: Add, DropDownList, % "x"(GUI_WIDTH-110)//2 . " " . "y+35" . " " . "w110" . " " . "gCHOSEHERO" . " " . "vSELECTED_HERO", %HERO_AVAILABLE% ;;;;;;;;;;;;;;;;;;;;;; ;; GDI_BACKGROUND ;; ;;;;;;;;;;;;;;;;;;;;;; Gui, %GDI_BACKGROUND%: -Caption +E0x80000 +LastFound +ToolWindow +OwnDialogs ;The GDI background is created and ready to be edited by GDI+ Gui, %GDI_BACKGROUND%: Show, x200 w0 h0 NA, %GDI_BACKGROUND_TITLE% ;It is shown at 0x0 so users cannot see it GDIPSETUP(GDI_BACKGROUND_TITLE, GUI_WIDTH, GUI_HEIGHT) ;This function prepares the necessary window values needed for GDI+ to work upon GDIPFONTSETUP() ;This function checks to see if the chosen font exists on the system GDIPDRAW() ;This function draws background color, a frame, text, the settings button and seperator lines Gui, %GDI_BACKGROUND%: Cancel ;The GDI background is hidden until it is needed again by the user GDIPUPDATE(0,0, GUI_WIDTH, GUI_HEIGHT) ;This function applies the GDI+ changes to the window OnMessage(0x201, "WM_LBUTTONDOWN") ;This code is necessary to detect mouse clicks (left) on the settings buton DMU_READY = 1 Return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; GUI_ITEMHOTKEYS SHOW & SAVE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ^Alt:: If DMU_READY = 1 { ERASING_HOTKEY2 = %HOTKEY2% ;These variables save the hotkeys to be turned off later before they are updated by new inputs ERASING_HOTKEY3 = %HOTKEY3% ERASING_HOTKEY4 = %HOTKEY4% ERASING_HOTKEY5 = %HOTKEY5% ERASING_HOTKEY6 = %HOTKEY6% GuiControl, %GUI_ITEMHOTKEYS%: Focus, MANUAL ;This shifts the focus of control to the checkbox to prevent hotkeys from being accidentally modified GuiControl, %GUI_ITEMHOTKEYS%:, HOTKEY2, %HOTKEY2% ;The controls are modified to contain the last valid hotkeys GuiControl, %GUI_ITEMHOTKEYS%:, HOTKEY3, %HOTKEY3% GuiControl, %GUI_ITEMHOTKEYS%:, HOTKEY4, %HOTKEY4% GuiControl, %GUI_ITEMHOTKEYS%:, HOTKEY5, %HOTKEY5% GuiControl, %GUI_ITEMHOTKEYS%:, HOTKEY6, %HOTKEY6% GuiControl, %GUI_ITEMHOTKEYS%:, MANUAL, %MANUAL% ;The Manual Mode checkbox is modified according to "MANUAL" WARCENTER(GUI_WIDTH, GUI_HEIGHT) ;This function returns the values necessary to position the program menu in the center of Warcraft III Gui, %GDI_BACKGROUND%: Show, %WARCENTER%, %GDI_BACKGROUND_TITLE% ;The GDI background is shown Gui, %GUI_ITEMHOTKEYS%: Show, %WARCENTER%, %GUI_ITEMHOTKEYS_TITLE% ;The GUI menu is shown and is set to be at the appropritate transparency level via the code below WinSet, Transcolor, % "0x" . SubStr(GDI_BACKGROUND_COLOR, 5, 6) . " " . GUI_TRANSPARENCY, %GUI_ITEMHOTKEYS_TITLE% If MOUSE_TRAPPED = True ;If Mouse Trap was on, "True" will be assigned to the variable TRAP_WAS_ON, and vice versa TRAP_WAS_ON = True Else TRAP_WAS_ON = False MOUSE_TRAPPED = False SetScrollLockState, AlwaysOff ;Turn scroll lock off, indicating mouse trap is off Loop ;Proceed if both GUI menu and GDI background is not active { WinWaitNotActive, %GUI_ITEMHOTKEYS_TITLE% IfWinNotActive, %GDI_BACKGROUND_TITLE% IfWinNotActive, %GUI_ITEMHOTKEYS_TITLE% Break } TURNOFFITEMHOTKEYS() ;Turn off the previous existing item hotkeys using the variables assigned with the old hotkey values (ERASING_*) TURNOFFHEROHOTKEYS() ;Turn off previous existing hero hotkeys Gui, %GUI_ITEMHOTKEYS%: Submit ;Hide both GUI menu and GDI background Gui, %GDI_BACKGROUND%: Cancel If SELECTED_HERO = Nevermore ;Assign the appropriate string of hotkeys to CURRENT_HEROHOTKEYS according to the hero selected in the dropdownlist { CURRENT_HEROHOTKEYS = ertg } Else If SELECTED_HERO = Invoker { CURRENT_HEROHOTKEYS = wqtvgrdecfb } Else If SELECTED_HERO = Techies { CURRENT_HEROHOTKEYS = y } Else If SELECTED_HERO = None { CURRENT_HEROHOTKEYS = } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; Enter New Hero Codes Here ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MONITORITEMHOTKEYS() TURNONITEMHOTKEYS() TURNONHEROHOTKEYS() SAVESETTINGS() ;IniWrite the updated configurations to %SETTINGS_NAME% If TRAP_WAS_ON = True ;If Mouse Trap was on, the RETRAP() function will retrap the mouse providing Warcraft III is the active window RETRAP() } Return ;;;;;;;;;;;;;;; ;; AUTOTAB ;; ;;;;;;;;;;;;;;; TAB: ;This label shifts focus to the next hotkey control when the one is edited, providing convenience and efficiency Sendinput {Tab} Return ;;;;;;;;;;;;;;;;;; ;; MOUSE TRAP ;; ;;;;;;;;;;;;;;;;;; MOUSETRAP: { Thread, Priority, -2 IfWinActive, Warcraft III ;If Warcraft III is active, pressing F5 will lock the mouse within the boundaries of the window { HWND:= WinExist("Warcraft III") If HWND { VarSetCapacity(LPRECT, 16, 0) DllCall("GetClientRect", "UInt", HWND, "UInt", &LPRECT) DllCall("ClientToScreen", "Uint", HWND, "Uint", &LPRECT) DllCall("ClientToScreen", "Uint", HWND, "Uint", &LPRECT+8) DllCall("ClipCursor", "UInt", &LPRECT) MOUSE_TRAPPED = True ;MOUSE_TRAPPED is set to "True" to indicate mouse trap state SetScrollLockState, AlwaysOn ;Scroll Lock is turned on to indicated mosue trap state } Loop ;The loop will wait for Warcraft III to become inactive, or for F6 to be pressed. If Warcraft III becomes { ; inactive, it will wait for Warcraft III to become active again. Once its reactivated, the MOUSETRAP label If MOUSE_TRAPPED = False ; will be reactivated, retrapping the mouse Break IfWinNotActive, Warcraft III { MOUSE_TRAPPED = False SetScrollLockState, AlwaysOff WinWaitActive, Warcraft III GoTo, MOUSETRAP } Sleep, 1000 } } } Return MOUSEUNTRAP: { DllCall("ClipCursor", "UInt", 0) ;If F6 is pressed, the loop in MOUSETRAP will be broken and mouse trap will be turned off MOUSE_TRAPPED = False SetScrollLockState, AlwaysOff } Return RETRAP() { Global IfWinActive, Warcraft III ;This function is only used to retrap the mouse after the GUI menu is hidden, or after MSN sync { HWND := WinExist( "Warcraft III ahk_class Warcraft III" ) If HWND { VarSetCapacity(LPRECT, 16, 0) DllCall("GetClientRect", "UInt", HWND, "UInt", &LPRECT) DllCall("ClientToScreen", "Uint", HWND, "Uint", &LPRECT) DllCall("ClientToScreen", "Uint", HWND, "Uint", &LPRECT+8) DllCall("ClipCursor", "UInt", &LPRECT) MOUSE_TRAPPED = True SetScrollLockState, AlwaysOn } } } ;;;;;;;;;;;;;;;;;;;; ;; ITEM HOTKEYS ;; ;;;;;;;;;;;;;;;;;;;; USEITEM1: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 ;This function can return the values "00", "10", and "11". If "10" is returned, the target key will be sent { Sendinput {Numpad7} } Else { Sendinput {Space} } } Return USEITEM2: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Sendinput {Numpad8} } Else { Sendinput {Blind}%HOTKEY2% } } Return USEITEM3: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Sendinput {Numpad4} } Else { Sendinput {Blind}%HOTKEY3% } } Return USEITEM4: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Sendinput {Numpad5} } Else { Sendinput {Blind}%HOTKEY4% } } Return USEITEM5: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Sendinput {Numpad1} } Else { Sendinput {Blind}%HOTKEY5% } } Return USEITEM6: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Sendinput {Numpad2} } Else { Sendinput {Blind}%HOTKEY6% } } Return ;;;;;;;;;;;;;;;;;;;;; ;; MOUSE HOTKEYS ;; ;;;;;;;;;;;;;;;;;;;;; FIRSTCALL: { If JUST_CALLED = False ;This If statement helps limit the amount of mouse call per "wheel roll" to one (this function can be turned off) { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Loop, %CALLAMOUNT% ;This variable indicates the amount of time the text is to be sent per thread (usefull for spamming) { Sendinput {Enter} ;Turns on Chat Bar Sleep, 15 Sendinput %MOUSEUP% Sleep, 15 Sendinput {Enter} ;Turns off Chat Bar } If CALLLIMIT = 1 ;The variable CALLLIMIT can be assigned the values 1 or 0. 1 will turn on call limit whereas 0 will turn it off { SetTimer, CALLCAP, -150 ;The timer CALLCAP is turned on. This label helps monitor the amount of calls per "wheel roll" JUST_CALLED = True ;JUST_CALLED is assigned "True" to indicate that there was a recent mouse call. No call can occur when this = "True" } } Else { Sendinput {Click WheelUp} } } Else { SetTimer, CALLCAP, -150 ;If a mouse call is attempted very soon after a recent call, the timer CALLCAP will be restarted. This effectively JUST_CALLED = True ; means that there must be at least a 150 millisecond delay between calls } } Return SECONDCALL: { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 ;Since the middle button cannot be accidentally spammed, there is no call limit function for this hotkey { Loop, %CALLAMOUNT% { Sendinput {Enter} Sleep, 15 Sendinput %MOUSEMIDDLE% Sleep, 15 Sendinput {Enter} } } Else { Sendinput {Click Middle} } } Return THIRDCALL: { If JUST_CALLED = False { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Loop, %CALLAMOUNT% { Sendinput {Enter} Sleep, 15 Sendinput %MOUSEDOWN% Sleep, 15 Sendinput {Enter} } If CALLLIMIT = 1 { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Else { Sendinput {Click WheelDown} } } Else { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Return FOURTHCALL: { If JUST_CALLED = False { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Loop, %CALLAMOUNT% { Sendinput {Enter} Sleep, 15 Sendinput %MOUSEUPMIDDLE% Sleep, 15 Sendinput {Enter} } If CALLLIMIT = 1 { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Else { Sendinput {Click WheelUp} } } Else { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Return FIFTHCALL: { If JUST_CALLED = False { If ReadMemory(ADDRESS_INGAME, ADDRESS_CHATBAR) = 10 { Loop, %CALLAMOUNT% { Sendinput {Enter} Sleep, 15 Sendinput %MOUSEDOWNMIDDLE% Sleep, 15 Sendinput {Enter} } If CALLLIMIT = 1 { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Else { Sendinput {Click WheelDown} } } Else { SetTimer, CALLCAP, -150 JUST_CALLED = True } } Return CALLCAP: { JUST_CALLED = False ;After 150 milliseconds, this timer will set JUST_CALL to "False', allowing other calls to be sent. (only runs once) } Return ;;;;;;;;;;;;;;;;;; ;; MANUAL SET ;; ;;;;;;;;;;;;;;;;;; FIRSTSET: { Gui, %GUI_ITEMHOTKEYS%: Cancel ;Hides GUI menu Gui, %GDI_BACKGROUND%: Cancel ;Hides GDI background IfWinExist, Warcraft III ;If Warcraft III window exists, show first set prompt GUI { GDIPMSGBOX("Please Set Location", "First Set", 210, 95, -1) WinActivate, Warcraft III Hotkey, LButton, MANUALSET, On ;On left mouse click, go to MANUALSET label } Else { GDIPMSGBOX("Run Warcraft III", "ERROR", 200, 95, MSGBOX_TIMEOUT_LONG) ;If Warcraft III window does not exist, show appropriate messagebox } } Return SECONDSET: { Gui, %GUI_ITEMHOTKEYS%: Cancel Gui, %GDI_BACKGROUND%: Cancel IfWinExist, Warcraft III { WinActivate, Warcraft III PixelGetColor, SCOURGECOLOR, %COORDX%, %COORDY% ;Obtain the color values of the pixel at the same coordinates recorded during first set If SCOURGECOLOR <> %SENTINELCOLOR% ;If the color values are different to %SENTINELCOLOR%, save the new configurations { SAVESETTINGS() Suspend, Permit GDIPMSGBOX("Second Set Successful", "RELOADED", 250, 95, MSGBOX_TIMEOUT_SHORT) Reload } Else { ;If the color values are similar to %SENTINELCOLOR%, display the appropriate messagebox GDIPMSGBOX("Second Set must be done on the opposite team of First Set", "ERROR", 350, 115, MSGBOX_TIMEOUT_LONG) } } Else { GDIPMSGBOX("Run Warcraft III", "ERROR", 200, 95, MSGBOX_TIMEOUT_LONG) } } Return MANUALSET: { IfWinExist, Warcraft III { Gui, %GDI_MESSAGEBOX%: Destroy WinActivate, Warcraft III MouseGetPos, COORDX, COORDY ;Obtain the coordinates of the cursor PixelGetColor, SENTINELCOLOR, %COORDX%, %COORDY% ;Obtain the color values at the coords of the cursor SCOURGECOLOR = 0x000000 ;Resets SCOURGECOLOR to default SAVESETTINGS() ;Saves the updated configurations to %SETTINGS_NAME% Suspend, Permit GDIPMSGBOX("First Set Successful", "RELOADED", 250, 95, MSGBOX_TIMEOUT_SHORT) ;Display the appropriate messagebox and reload the program Reload } Else { GDIPMSGBOX("Run Warcraft III", "ERROR", 200, 95, MSGBOX_TIMEOUT_LONG) } } Return ;;;;;;;;;;;;;;;;;; ;; CHOSE HERO ;; ;;;;;;;;;;;;;;;;;; CHOSEHERO: GuiControlGet, SELECTED_HERO,, SELECTED_HERO ;This label does nothing significant at this point ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; Enter New Hero Codes Here ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Return #Include, DMU Hero Hotkeys.ahk ;The script that contains the labels for all hero hotkeys ;;;;;;;;;;;;;;;;;;;; ;; MISCELLANEOUS ;; ;;;;;;;;;;;;;;;;;;;; WM_LBUTTONDOWN() ;When the program receives a left click on its menu, the cursor location will be analysed to see if it is { ; over the settings button. If it is, %SETTINGS_NAME% will be run Global SETTINGS_NAME, DEFAULT_SETTINGSICON_X, DEFAULT_SETTINGSICON_Y, SETTINGSICON_WIDTH, SETTINGSICON_HEIGHT CoordMode, Mouse, Relative MouseGetPos, POSX, POSY If (POSX > DEFAULT_SETTINGSICON_X && POSX < DEFAULT_SETTINGSICON_X + SETTINGSICON_WIDTH) { If (POSY > DEFAULT_SETTINGSICON_Y && POSY < (DEFAULT_SETTINGSICON_Y + SETTINGSICON_HEIGHT)) { Run, %SETTINGS_NAME% } } } *End:: ;Pressing {End} will toggle program suspension on/off Suspend, Permit SUSPENDED := not SUSPENDED If (SUSPENDED == True) { GoSub, MOUSEUNTRAP Suspend, On SetNumLockState, AlwaysOff } Else { Suspend, Off SetNumLockState, AlwaysOn } Return ^End:: ;Pressing Ctrl+End will reload the program Suspend, Permit GDIPMSGBOX("DMU Reloaded", "RELOADED", 200, 95, MSGBOX_TIMEOUT_SHORT) Reload Return TERMINATE_APP: ;This is the label to be executed on exit. GDI+ is exited and the program will self-delete if required Critical Gdip_Shutdown(pToken) ExitApp Return /* ^l:: ;This hotkey is used for debugging purposes and should be removed or disabled on compilation ListVars Return */