Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[DotA] DotA Master Utilities - item hotkey script (+extras)


  • Please log in to reply
No replies to this topic
seedling
  • Members
  • 5 posts
  • Last active: Feb 07 2012 12:44 PM
  • Joined: 19 Apr 2011
[OVERVIEW]
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**)

Posted Image

#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. :D

** 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 :D . (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
*/