Jump to content

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

WASD Controls script for Titan Quest and Torchlight


  • Please log in to reply
18 replies to this topic
Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
Not being happy with the (very few) WASD control scripts floating around the internet, I read up on Autohotkey scripting and made my own. Top-down RPGs like Torchlight and Titan Quest require you to click on the ground to move your character, which gets annoying and sometimes painful. This script implements full eight-directional WASD movement that only applies to the game window, so you can still type normally outside it. It also scales gracefully to different resolutions and window sizes.

New update, v3. Download page with newest version is at http://www.desiquint...om/wasdcontrols, source code for v3 is below.

Changelog for v3:[*:2576bzcr]Fixed the problem with the script suppressing drop-down menus in some games.
[*:2576bzcr]Improved performance by setting coordinates only once at runtime, instead of every 1 millisecond. =\
[*:2576bzcr]Tightened offset coordinates so that tapping a key will make the character move the shortest distance possible for better control: no more accidentally walking into fireballs. (Note: Titan Quest controls are improved, but still quite loose because TQ requires you to place clicks quite far away from the character for them to register. Torchlight controls are perfect.)
[*:2576bzcr]Allowed mouse to snap back to where the user originally placed it when no WASD buttons are pressed.WASD Controls For Torchlight, v3
;
; WASD Controls For Torchlight v3
; Author:         Desi Quintans <[email protected]>
; Website:         http://www.desiquintans.com
;
; Script Function:
;   Enables WASD controls in Torchlight. Works across all resolutions, and in both
;   Windowed and Full-Screen modes. Does not mess up your typing outside the game.
;	M key now toggles Automap (in place of A).
;	F now switches weapons (in place of W).
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Persistent
#MaxHotkeysPerInterval, 200
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetDefaultMouseSpeed, 0
; Initialise variables.
final_x_coord = 0
final_y_coord = 0
are_coordinates_initialised = 0

SetTimer, Button_Pressed, 1
return

Button_Pressed:
	IfWinActive, Torchlight
	{
		if (are_coordinates_initialised != 1)
		{
			; Set coordinate offsets specific to the game. This only initialises once, when the script first detects the game window
			; as active. If the user changes game resolutions the script will need to be reloaded, but this is still much better
			; than performing the same calculations to set the same variables with the same values every 1 millisecond.
				WinGetPos,,, total_width, total_height, A ; In case of running a Window, or in a resolution not matching the Desktop's.
				x_axis_centre := round(total_width//2)
				y_axis_centre := round(total_height*0.51) ; This is corrected for true horizontal movement.
				up_coord := y_axis_centre-round(total_height*0.05)
				down_coord := y_axis_centre+round(total_height*0.06)
				left_coord := x_axis_centre-round(total_width*0.045)
				right_coord := x_axis_centre+round(total_width*0.045)
				are_coordinates_initialised = 1
		}
			
		if GetKeyState("w", "P") || GetKeyState("s", "P") || GetKeyState("a", "P") || GetKeyState("d", "P")
		{
			; Remember the position of the mouse pointer before the WASD keys were pressed.
				MouseGetPos, prior_x_pos, prior_y_pos
	
			; Use the chosen coordinates as their respective keys get pressed to direct the mouse pointer.
				if GetKeyState("w", "P")
				{
					final_y_coord := up_coord
				}
				else if GetKeyState("s", "P")
				{
					final_y_coord := down_coord
				}
				else
				{
					final_y_coord := y_axis_centre
				}
				
				if GetKeyState("a", "P")
				{
					final_x_coord := left_coord
				}
				else if GetKeyState("d", "P")
				{
					final_x_coord := right_coord
				}
				else
				{
					final_x_coord := x_axis_centre
				}
				
				; Perform the directed click. This is a click-hold that immediately gets released.
				; Click-hold is necessary as some games don't register a single click.
				Click down %final_x_coord% %final_y_coord%
				Click up
				
				; Put the mouse pointer back in its original place.
				Sleep, 40
				Click, %prior_x_pos% %prior_y_pos% Left 0
		}
	}
return

#IfWinActive, Torchlight
{
	s::Numpad2 ; Remaps intrusive keys to prevent then from opening the skill window and automap.
	a::Numpad4
	w::Numpad8
	f::w ; F now switches weapons
	m::a ; M now toggles automap.
}
WASD Controls For Titan Quest Series, v3
;
; WASD Movement For Titan Quest Series v3
; Author:         Desi Quintans <[email protected]>
; Website:         http://www.desiquintans.com
;
; Script Function:
;   Enables WASD controls in the Titan Quest series of RPGs. Works across all resolutions, and in both
;   Windowed and Full-Screen modes. Does not mess up your typing outside the game.
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Persistent
#MaxHotkeysPerInterval, 200
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetDefaultMouseSpeed, 0
; Initialise variables.
final_x_coord = 0
final_y_coord = 0
are_coordinates_initialised = 0

SetTimer, Button_Pressed, 1
return

Button_Pressed:
	if WinActive("Titan Quest") || WinActive("Titan Quest: Immortal Throne")
	{
		if (are_coordinates_initialised != 1)
		{
			; Set coordinate offsets specific to the game. This only runs once, when the script first detects the game window
			; as active. If the user changes game resolutions the script will need to be reloaded, but this is still much better
			; than performing the same calculations to set the same variables with the same values every 1 millisecond.
				WinGetPos,,, total_width, total_height, A ; In case of running a Window, or in a resolution not matching the Desktop's.
				x_axis_centre := round(total_width//2)
				y_axis_centre := round(total_height*0.575) ; This is corrected for true horizontal movement.
				up_coord := y_axis_centre-round(total_height*0.095)
				down_coord := y_axis_centre+round(total_height*0.16)
				left_coord := x_axis_centre-round(total_width*0.07)
				right_coord := x_axis_centre+round(total_width*0.07)
				are_coordinates_initialised = 1
		}
		
		if GetKeyState("w", "P") || GetKeyState("s", "P") || GetKeyState("a", "P") || GetKeyState("d", "P")
		{
			; Remember the position of the mouse pointer before the WASD keys were pressed.
				MouseGetPos, prior_x_pos, prior_y_pos

			; Use the chosen coordinates as their respective keys get pressed to direct the mouse pointer.
				if GetKeyState("w", "P")
				{
					final_y_coord := up_coord
				}
				else if GetKeyState("s", "P")
				{
					final_y_coord := down_coord
				}
				else
				{
					final_y_coord := y_axis_centre
				}
				
				if GetKeyState("a", "P")
				{
					final_x_coord := left_coord
				}
				else if GetKeyState("d", "P")
				{
					final_x_coord := right_coord
				}
				else
				{
					final_x_coord := x_axis_centre
				}
				
				; Perform the directed click. This is a click-hold that immediately gets released.
				; Click-hold is necessary as some games don't register a single click.
				Click down %final_x_coord% %final_y_coord%
				Click up
				
				; Put the mouse pointer back in its original place.
				Sleep, 40
				Click, %prior_x_pos% %prior_y_pos% Left 0
		}
	}
return


Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
Version 2 offers 100% support for Torchlight, loading of customised offset coordinates tailored to each game, as well as more elegant code.

Update: This old code shows support for Diablo. I removed this in v2.1 because I could not test it.

;
; WASD Movement in top-down action RPGs v2
; Author:			Desi Quintans <[email protected]>
; Website:			http://www.desiquintans.com
;
; Script Function:
;	Enables WASD controls in popular top-down action RPGs like Titan Quest, Diablo et al. Works across all resolutions, and in both
;	Windowed and Full-Screen modes. Does not mess up your typing outside the game.
;	Sadly, the script *must* hijack your mouse because of user permission problems when trying to pass 'invisible' mouseclicks
;	in Windows Vista and Windows 7. You'd basically use WASD while exploring or travelling, and switch to normal mouse control when
;	fighting.
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Persistent
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetDefaultMouseSpeed, 0
final_x_coord = 0
final_y_coord = 0

SetTimer, Button_Pressed, 1
return

Titan_Quest_Coords:
	WinGetPos,,, total_width, total_height, A ; In case of running in Windowed mode, or in a resolution not matching the Desktop's.
	x_axis_centre := round(total_width//2)
	y_axis_centre := round(total_height*0.575) ; This is corrected for true horizontal movement.
	up_coord := y_axis_centre-round(total_height*0.16)
	down_coord := y_axis_centre+round(total_height*0.06)
	left_coord := x_axis_centre-round(total_width*0.085)
	right_coord := x_axis_centre+round(total_width*0.085)
return

Torchlight_Coords:
	WinGetPos,,, total_width, total_height, A ; In case of running in Windowed mode, or in a resolution not matching the Desktop's.
	x_axis_centre := round(total_width//2)
	y_axis_centre := round(total_height*0.51) ; This is corrected for true horizontal movement.
	up_coord := y_axis_centre-round(total_height*0.13)
	down_coord := y_axis_centre+round(total_height*0.1)
	left_coord := x_axis_centre-round(total_width*0.08)
	right_coord := x_axis_centre+round(total_width*0.08)
return

	
#IfWinActive, Torchlight
{
	s::Numpad2 ; Remaps intrusive keys to prevent then from opening the skill window and automap.
	a::Numpad4
	m::a ; M now toggles automap.
}

Button_Pressed:
	if WinActive("Titan Quest: Immortal Throne") || WinActive("Titan Quest") || WinActive("Torchlight") || WinActive("Diablo") || WinActive("Diablo 2") || WinActive("Diablo II") ; Wasn't quite sure of the Diablo window titles.
	{
		; Some games (eg. Torchlight) do not receive a single click and only register a Click Down. This is here to undo the
		; Click Down that comes at the end of the loop, or else the user would press a button and continue walking towards
		; the mouse cursor forever.
		Click up
		if GetKeyState("w", "P") || GetKeyState("s", "P") || GetKeyState("a", "P") || GetKeyState("d", "P")
		{
			; Decide which set of coordinates to use in the game.
				if WinActive("Titan Quest: Immortal Throne") || WinActive("Titan Quest")
				{
					Gosub, Titan_Quest_Coords
				}
				else
				{
					Gosub, Torchlight_Coords
				}
	
			; Use the chosen coordinates as their respective keys get pressed to direct the mouse pointer.
				if GetKeyState("w", "P")
				{
					final_y_coord := up_coord
				}
				else if GetKeyState("s", "P")
				{
					final_y_coord := down_coord
				}
				else
				{
					final_y_coord := y_axis_centre
				}
				
				if GetKeyState("a", "P")
				{
					final_x_coord := left_coord
				}
				else if GetKeyState("d", "P")
				{
					final_x_coord := right_coord
				}
				else
				{
					final_x_coord := x_axis_centre
				}
				
				Click down %final_x_coord% %final_y_coord%
		}
	}
return


promagnum
  • Guests
  • Last active:
  • Joined: --
Doesn't work for me on win7 in Titan Quest: Immortal Throne in windowed mode. (havent tried fullscreen.)

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
Gimme a sec.

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
Okay, please redownload from http://www.desiquint...om/wasdcontrols. The built-in Torchlight support was screwing with Titan Quest, so I separated the scripts. Just run the Titan Quest one and ignore the Torchlight one. Compiled .exes and source .ahks included as normal.

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
New version, v3. Check the original post in this thread for Changelog, updated code, and download link.

geigertron
  • Members
  • 7 posts
  • Last active: Jul 21 2011 01:25 PM
  • Joined: 06 Jul 2011
Hi Desi,

I'm quite new to this stuff. I tried all your guidelines, and all I get is the mouse cursor flickering in all direction. The character does NOT move at all.

The only good effect I see is the auto map going from A to M, and I cant access the skill tree/Window (S by default).

I'm using Windows 7, but I also tested your mod in Windows XP, and same effect as stated above. I tried downloading the Autohotkey program, and all I get is the same results.

It does NOT work whether in Fullscreen or Window mode. Does this work with any version (patch) of the game? Or is the operating system a factor?

Either way, I can't move the character with supposed WASD key control, just the mouse cursor/pointer flickering in all direction when I press the WASD keys.

geigertron
  • Members
  • 7 posts
  • Last active: Jul 21 2011 01:25 PM
  • Joined: 06 Jul 2011
I also tried the mod for Titan Quest, and same problems and results as stated above.

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
The cursoring moving and flickering is an unavoidable part of the script; it's basically moving the cursor around your character and applying a click every forty milliseconds. If you are not moving, then it means that the cursor is placing itself on top of your character instead of on the ground around him or her.

To fix this, open the script in a text editor and find the following lines.

up_coord := y_axis_centre-round(total_height*[color=red]0.05[/color])
down_coord := y_axis_centre+round(total_height*[color=red]0.06[/color])
left_coord := x_axis_centre-round(total_width*[color=red]0.045[/color])
right_coord := x_axis_centre+round(total_width*[color=red]0.045[/color])

The numbers in red tell the cursor how far from the centre of the screen it should be placed. Increase these numbers by small amounts until you find something that works consistently. I recommend increasing in increments of 0.005 or 0.01.

geigertron
  • Members
  • 7 posts
  • Last active: Jul 21 2011 01:25 PM
  • Joined: 06 Jul 2011
Thanks, giving it another shot!

geigertron
  • Members
  • 7 posts
  • Last active: Jul 21 2011 01:25 PM
  • Joined: 06 Jul 2011
Dear Desi...

Your a f-----g GENIUS!!!! 8)

But, let me explain, I decided to try one of your older works, the VERSION 2 from one of your older post on Oct. 29, 2010. I decided to try since I could never get to work your recent suggestion.

VERSION 2 works as smooth as silk, it might be that certain parameters might be missing from VERSION 3.1 (don't know which). But man, I'll go with this setup, I'm gonna save it as an AHK file.

Anyway, thanks so much work you great piece of work, regardless of what version. Keep up the good work! :)

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
The only difference between v2 and the current code (aside from Titan Quest and Torchlight code being separated into their own scripts) is that the red numbers I showed you are much larger (almost twice as large). Still, if those parameters suit you, then that is awesome. :wink:

geigertron
  • Members
  • 7 posts
  • Last active: Jul 21 2011 01:25 PM
  • Joined: 06 Jul 2011
Desi,

Just a suggestion, any chance you could (if you have any free time) try making WASD AHK's for these two PC RPG games?

Sacred 1 (and it's Underworld Expansion)
Divine Divinity

I'll do some tinkering myself in my spare times.

Desi
  • Members
  • 162 posts
  • Last active: Apr 15 2015 09:51 AM
  • Joined: 29 Oct 2010
Modifying the current script to support any game is pretty simple. Here is the Torchlight script as an example.

1. Change the window titles (in orange) to match the window title of the new game.
2. Adjust the offset multipliers (the numbers in red) to make WASD keypresses deliver clicks as close to the player character as possible, while still being reliably detected. This is a trial-and-error operation. You'll probably need to have asymmetrical offset multipliers, as I have below, to account for the height of the player character, and if the character is actually off-centre.

The final #IfWinActive is used to disable the WASD keys, meaning that the game cannot detect them whereas your script still can. Not keeping this section may cause the game to open inventory windows etc. while you're trying to move around.

;
; WASD Controls For Torchlight v3.1
; Author:         Desi Quintans <[email protected]>
; Website:         http://www.desiquintans.com
;
; Script Function:
;   Enables WASD controls in Torchlight. Works across all resolutions, and in both
;   Windowed and Full-Screen modes. Does not mess up your typing outside the game.
;	M key now toggles Automap (in place of A).
;	F now switches weapons (in place of W).
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Persistent
#MaxHotkeysPerInterval, 200
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetDefaultMouseSpeed, 0
SetTitleMatchMode, 3
; Initialise variables.
final_x_coord = 0
final_y_coord = 0
are_coordinates_initialised = 0

SetTimer, Button_Pressed, 1
return

Button_Pressed:
	IfWinActive, [color=orange]Torchlight[/color]
	{
		if (are_coordinates_initialised != 1)
		{
			; Set coordinate offsets specific to the game. This only initialises once, when the script first detects the game window
			; as active. If the user changes game resolutions the script will need to be reloaded, but this is still much better
			; than performing the same calculations to set the same variables with the same values every 1 millisecond.
				WinGetPos,,, total_width, total_height, A ; In case of running a Window, or in a resolution not matching the Desktop's.
				x_axis_centre := round(total_width//2)
				y_axis_centre := round(total_height*[color=red]0.51[/color]) ; This is corrected for true horizontal movement.
				up_coord := y_axis_centre-round(total_height*[color=red]0.05[/color])
				down_coord := y_axis_centre+round(total_height*[color=red]0.06[/color])
				left_coord := x_axis_centre-round(total_width*[color=red]0.045[/color])
				right_coord := x_axis_centre+round(total_width*[color=red]0.045[/color])
				are_coordinates_initialised = 1
		}
			
		if GetKeyState("w", "P") || GetKeyState("s", "P") || GetKeyState("a", "P") || GetKeyState("d", "P")
		{
			; Remember the position of the mouse pointer before the WASD keys were pressed.
				MouseGetPos, prior_x_pos, prior_y_pos
	
			; Use the chosen coordinates as their respective keys get pressed to direct the mouse pointer.
				if GetKeyState("w", "P")
				{
					final_y_coord := up_coord
				}
				else if GetKeyState("s", "P")
				{
					final_y_coord := down_coord
				}
				else
				{
					final_y_coord := y_axis_centre
				}
				
				if GetKeyState("a", "P")
				{
					final_x_coord := left_coord
				}
				else if GetKeyState("d", "P")
				{
					final_x_coord := right_coord
				}
				else
				{
					final_x_coord := x_axis_centre
				}
				
				; Perform the directed click. This is a click-hold that immediately gets released.
				; Click-hold is necessary as some games don't register a single click.
				Click down %final_x_coord% %final_y_coord%
				Click up
				
				; Put the mouse pointer back in its original place.
				Sleep, 40
				Click, %prior_x_pos% %prior_y_pos% Left 0
		}
	}
return

#IfWinActive, [color=orange]Torchlight[/color]
{
	s::Numpad2 ; Remaps intrusive keys to prevent then from opening the skill window and automap.
	a::Numpad4
	w::Numpad8
	f::w ; F now switches weapons
	m::a ; M now toggles automap.
}


Pestilaence
  • Guests
  • Last active:
  • Joined: --
Hey guys, I can't seem to get the script to work at all... messed with the cursor positioning for a while and just couldn't get it to move my character. I can see that the cursor is being hijacked whenever I try to run the program and then use the wasd keys to move, but it won't do anything. Any hints or tips? Just can't seem to get it to work... :/