AutoHotKey Script (v0.1) : spell casting with one key press

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
LordYig
Posts: 175
Joined: Wed Jul 04, 2012 5:45 pm

AutoHotKey Script (v0.1) : spell casting with one key press

Post by LordYig »

Hello all, this is my first post here.

While waiting for the editor to come out, I roamed the web reading articles and reviews about Grimrock to finally find the great script by D32, techzen and Adakos that you can find on the following post : viewtopic.php?f=14&t=589

I found it quite cool to be able to enhanced the game bindings system with a free and open third party tool such as Autohotkey.
But while this was great and easy to use it lacked what all mage fans wants... Spell Bindings.

Looking for a way to make a spell cast feature with AutoHotKey, I carefully to look at D32, techzen and Adakos script and started digging.
After a few hours of trials and errors, I finaly found a way to automate rune clicking in a customizable way. The following script is the result.
Be aware that my work is heavily inspired by D32, techzen and Adakos's work, the two scripts shares some variables and functions and could even be merged to add all the features in a single script.

I'd like to thanks D32, techzen and Adakos for the initial script and for the original idea of using AutoHotKey and automate actions, without their script this would have not been possible.

Script Features
  1. Automatic spell cast system for all four characters.
  2. Support for all four elemental schools of magic. Spellcraft spells are currently out of the scope.
  3. Works as follows : Activate the spell runes panel, select runes and validate the spell casting.
  4. Only support attack spells, utility and shields spells are currently out of the scope.
  5. Customizable bindings based on a .Ini file and AutoHotKey bindings.
Installation and Usage
  1. Download Autohotkey and install it.
  2. Download the script file from mediafire: Link
  3. Extract the archive content.
  4. Change the bindings as you like in 'grimrock-spells-bindings.ini'.
  5. Doubleclick the file.
  6. Enjoy the script features.
OR
  1. Create file named 'grimrock-spells.ahk' on your desktop (or anywhere else on your computer).
  2. Paste the code found below at The Script section of this post into the file.
  3. Save the file.
  4. Create file named 'grimrock-spells-bindings.ini' in the same location as the previous file.
  5. Paste the code found below at The .Ini Configuration File section of this post into the file.
  6. Save the file.
  7. Change the bindings as you like in 'grimrock-spells-bindings.ini'.
  8. Doubleclick the file.
  9. Enjoy the script features.
Changing the bindings

To change the bindings, you should first refer to the AutoHotKey Manual in order to learn how to declare keys for AutoHotKey.
You can find the AutoHotKey Documentation Online at the following adress : http://www.autohotkey.com/docs/
You can also find a complete key list at the following page : http://www.autohotkey.com/docs/KeyList.htm

If you want to be quick and use the script as it is the following keys have been set in the .ini file :
  • è : Fire Burst from back left character
  • Alt + è : Fire Ball from back left character
  • _ : Ice Shards from back left character
  • Alt + _ : Frost Bolt from back left character
  • ) : Shock from back right character
  • Alt + ) : Lightning Bolt from back right character
  • = : Ice Shards from back right character
  • Alt + = : Frost Bolt from back right character
Limitations
  • Does not work if the spell rune panel is already activated / opened.
    Well... It could work in theory, but it is better to keep it closed.
  • Does not work if some of the spell runes are already activated.
  • Does not work while the target character available actions are on cooldown.
  • Does not detect that the character is out of Energy.
    If this happens you will have to cast the selected spell yourself or to deselect the runes manually.
  • While the script is active, your binded keys will be desactivated in other programs.
    If you are an heavy Alt-Tab user like me, this can be annoying.
    I haven't found a workaround yet.
The Script
SpoilerShow

Code: Select all

; ---------- ---------- ---------- ---------- ---------- ;
;	Legend of Grimrock
; ---------- ---------- ---------- ---------- ---------- ;
;
;	AutoHotKey Script
;	Spell Keys by LordYig
;	v 0.1	21/07/2012
;	
;	Based on original Attack keys v 0.2
;	Created by d32
;	Character swapping by techzen, Adakos
;	Download AutoHotKey at: http://www.autohotkey.com/
;
; ---------- ---------- ---------- ---------- ---------- ;
#SingleInstance force
SetTitleMatchMode, 2
SetDefaultMouseSpeed, 0
CoordMode, Mouse,

titleOfGrimrockWindow=Legend of Grimrock
; ---------- ---------- ---------- ---------- ---------- ;
;	Global Variables
; ---------- ---------- ---------- ---------- ---------- ;
xAdjust := 1 ;	Accuracy adjustment for the X axis
yAdjust := 1 ;	Accuracy adjustment for the Y axis

; ---------- ---------- ---------- ---------- ---------- ;
;	relative positions of weapon slots and character bars
; ---------- ---------- ---------- ---------- ---------- ;
;	dx1l := 0.14 ;	X position of 1st and 3rd char left hand
;	dx2l := 0.62 ;	X position of 2nd and 4th char left hand
dx1r := 0.34 ;	X position of 1st and 3rd char right hand
dx2r := 0.81 ;	X position of 2nd and 4th char right hand
dy1  := 0.32 ;	Y position of 1st and 2nd char hands
dy2  := 0.79 ;	Y position of 3rd and 4th char hands


; ---------- ---------- ---------- ---------- ---------- ;
;	SPELLS MATRIX - COORDINATES
; ---------- ---------- ---------- ---------- ---------- ;
;	(1) - FIRE - First Row - Left Column
;	(2) - LIFE - First Row - Middle Column
;	(3) - AIR - First Row - Right Column
;	(4) - SPIRITUALITY - Second Row - Left Column
;	(5) - BALANCE - Second Row - Middle Column
;	(6) - PHYSICALITY - Second Row - Right Column
;	(7) - EARTH - Third Row - Left Column
;	(8) - DEATH - Third Row - Middle Column
;	(9) - ICE - Third Row - Right Column
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	Runes Columns
; ---------- ---------- ---------- ---------- ---------- ;
xLcLrC := 0.10 ;	position of 1st and 3rd char left rune column
xLcMrC := 0.20 ;	position of 1st and 3rd char middle rune column
xLcRrC := 0.30 ;	position of 1st and 3rd char right rune column
xRcLrC := 0.58 ;	position of 2nd and 4th char left rune column
xRcMrC := 0.68 ;	position of 2nd and 4th char middle rune column
xRcRrC := 0.78 ;	position of 2nd and 4th char right rune column
; ---------- ---------- ---------- ---------- ---------- ;
;	Runes Rows
; ---------- ---------- ---------- ---------- ---------- ;
yTcTrR := 0.14 ;	position of 1st and 2nd char top rune row
yTcMrR := 0.26 ;	position of 1st and 2nd char middle rune row
yTcBrR := 0.38 ;	position of 1st and 2nd char bottom rune row
yBcTrR := 0.63 ;	position of 3rd and 4th char top rune row
yBcMrR := 0.75 ;	position of 3rd and 4th char middle rune row
yBcBrR := 0.87 ;	position of 3rd and 4th char bottom rune row
; ---------- ---------- ---------- ---------- ---------- ;
;	Cast Spell Button
; ---------- ---------- ---------- ---------- ---------- ;
xLcCsC := 0.40 ;	position of 1st and 3rd char cast spell column
xRcCsC := 0.85 ;	position of 2nd and 4th char cast spell column
yTcCsR := 0.38 ;	position of 1st and 2nd char cast spell row
yBcCsR := 0.87 ;	position of 3rd and 4th char cast spell row
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	reads the resolution, determins the corner of characters' rectangle
; ---------- ---------- ---------- ---------- ---------- ;
init()
{
	global
	sysget, resX, 0
	sysget, resY, 1
	chHei := resY * 0.32
	if (chHei > 345) chHei := 345 ;	this seems to be maximum height of the characters' bar
	chWid := chHei / 0.76
	chWid := chWid * xAdjust
	chHei := chHei * yAdjust
	chX := resX-chWid
	chY := resY-chHei
	initBindings()
}

; ---------- ---------- ---------- ---------- ---------- ;
;	reads the bindings in grimrock-spells-bindings.ini
;	associates the hotkeys to the selected spell label
; ---------- ---------- ---------- ---------- ---------- ;
initBindings()
{

	; ---------- ---------- ---------- ---------- ---------- ;
	;	Top Left Character Bindings
	; ---------- ---------- ---------- ---------- ---------- ;
	IniRead, tlcFireBurst, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,FIREBURST
	IniRead, tlcFireBall, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,FIREBALL
	IniRead, tlcIceShards, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,ICESHARDS
	IniRead, tlcIceBolt, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,ICEBOLT
	IniRead, tlcPoisonCloud, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,POISONCLOUD
	IniRead, tlcPoisonBolt, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,POISONBOLT
	IniRead, tlcShock, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,SHOCK
	IniRead, tlcLightningBolt, grimrock-spells-bindings.ini, TopLeftCharacterMageSpells,LIGHTNINGBOLT

	if tlcFireBurst
		Hotkey, %tlcFireBurst%, TopLeftCharFireBurst
	if tlcFireBall
		Hotkey, %tlcFireBall%, TopLeftCharFireBall
	if tlcIceShards
		Hotkey, %tlcIceShards%, TopLeftCharIceShards
	if tlcIceBolt
		Hotkey, %tlcIceBolt%, TopLeftCharFrostBolt
	if tlcPoisonCloud
		Hotkey, %tlcPoisonCloud%, TopLeftCharPoisonCloud
	if tlcPoisonBolt
		Hotkey, %tlcPoisonBolt%, TopLeftCharPoisonBolt
	if tlcShock
		Hotkey, %tlcShock%, TopLeftCharShock
	if tlcLightningBolt
		Hotkey, %tlcLightningBolt%, TopLeftCharLightningBolt
	
	; ---------- ---------- ---------- ---------- ---------- ;
	;	Top Right Character Bindings
	; ---------- ---------- ---------- ---------- ---------- ;
	IniRead, trcFireBurst, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,FIREBURST
	IniRead, trcFireBall, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,FIREBALL
	IniRead, trcIceShards, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,ICESHARDS
	IniRead, trcIceBolt, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,ICEBOLT
	IniRead, trcPoisonCloud, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,POISONCLOUD
	IniRead, trcPoisonBolt, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,POISONBOLT
	IniRead, trcShock, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,SHOCK
	IniRead, trcLightningBolt, grimrock-spells-bindings.ini, TopRightCharacterMageSpells,LIGHTNINGBOLT

	if trcFireBurst
		Hotkey, %trcFireBurst%, TopRightCharFireBurst
	if trcFireBall
		Hotkey, %trcFireBall%, TopRightCharFireBall
	if trcIceShards
	Hotkey, %trcIceShards%, TopRightCharIceShards
	if trcIceBolt
		Hotkey, %trcIceBolt%, TopRightCharFrostBolt
	if trcPoisonCloud
		Hotkey, %trcPoisonCloud%, TopRightCharPoisonCloud
	if trcPoisonBolt
		Hotkey, %trcPoisonBolt%, TopRightCharPoisonBolt
	if trcShock
		Hotkey, %trcShock%, TopRightCharShock
	if trcLightningBolt
		Hotkey, %trcLightningBolt%, TopRightCharLightningBolt

	; ---------- ---------- ---------- ---------- ---------- ;
	;	Bottom Left Character Bindings
	; ---------- ---------- ---------- ---------- ---------- ;
	IniRead, blcFireBurst, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,FIREBURST
	IniRead, blcFireBall, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,FIREBALL
	IniRead, blcIceShards, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,ICESHARDS
	IniRead, blcIceBolt, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,ICEBOLT
	IniRead, blcPoisonCloud, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,POISONCLOUD
	IniRead, blcPoisonBolt, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,POISONBOLT
	IniRead, blcShock, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,SHOCK
	IniRead, blcLightningBolt, grimrock-spells-bindings.ini, BottomLeftCharacterMageSpells,LIGHTNINGBOLT

	if blcFireBurst
		Hotkey, %blcFireBurst%, BottomLeftCharFireBurst
	if blcFireBall
		Hotkey, %blcFireBall%, BottomLeftCharFireBall
	if blcIceShards
		Hotkey, %blcIceShards%, BottomLeftCharIceShards
	if blcIceBolt
		Hotkey, %blcIceBolt%, BottomLeftCharFrostBolt
	if blcPoisonCloud
		Hotkey, %blcPoisonCloud%, BottomLeftCharPoisonCloud
	if blcPoisonBolt
		Hotkey, %blcPoisonBolt%, BottomLeftCharPoisonBolt
	if blcShock
		Hotkey, %blcShock%, BottomLeftCharShock
	if blcLightningBolt
		Hotkey, %blcLightningBolt%, BottomLeftCharLightningBolt
		
	; ---------- ---------- ---------- ---------- ---------- ;
	;	Bottom Right Character Bindings
	; ---------- ---------- ---------- ---------- ---------- ;
	IniRead, brcFireBurst, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,FIREBURST
	IniRead, brcFireBall, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,FIREBALL
	IniRead, brcIceShards, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,ICESHARDS
	IniRead, brcIceBolt, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,ICEBOLT
	IniRead, brcPoisonCloud, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,POISONCLOUD
	IniRead, brcPoisonBolt, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,POISONBOLT
	IniRead, brcShock, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,SHOCK
	IniRead, brcLightningBolt, grimrock-spells-bindings.ini, BottomRightCharacterMageSpells,LIGHTNINGBOLT

	if brcFireBurst
		Hotkey, %brcFireBurst%, BottomRightCharFireBurst
	if brcFireBall
		Hotkey, %brcFireBall%, BottomRightCharFireBall
	if brcIceShards
	Hotkey, %brcIceShards%, BottomRightCharIceShards
	if brcIceBolt
		Hotkey, %brcIceBolt%, BottomRightCharFrostBolt
	if brcPoisonCloud
		Hotkey, %brcPoisonCloud%, BottomRightCharPoisonCloud
	if brcPoisonBolt
		Hotkey, %brcPoisonBolt%, BottomRightCharPoisonBolt
	if brcShock
		Hotkey, %brcShock%, BottomRightCharShock
	if brcLightningBolt
		Hotkey, %brcLightningBolt%, BottomRightCharLightningBolt

	return
}

; ---------- ---------- ---------- ---------- ---------- ;
;	storeMousePos
; ---------- ---------- ---------- ---------- ---------- ;
storeMousePos() 
{
	global
	MouseGetPos, mX, mY
}

; ---------- ---------- ---------- ---------- ---------- ;
;	restoreMousePos
; ---------- ---------- ---------- ---------- ---------- ;
restoreMousePos() 
{
	global
	MouseMove, mX, mY
}

; ---------- ---------- ---------- ---------- ---------- ;
;	OFFENSIVES SPELLS - FROM THE FRONT CHARACTERS
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	FIRE SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
topLeftFireBurst()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcTrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topLeftFireBall()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcTrR)
	clickRune(xLcRrC, yTcTrR)
	clickRune(xLcRrC, yTcMrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightFireBurst()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcTrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightFireBall()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcTrR)
	clickRune(xRcRrC, yTcTrR)
	clickRune(xRcRrC, yTcMrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	ICE SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
topLeftIceShards()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcBrR)
	clickRune(xLcRrC, yTcBrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topLeftFrostBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcRrC, yTcTrR)
	clickRune(xLcRrC, yTcBrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightIceShards()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcBrR)
	clickRune(xRcRrC, yTcBrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightFrostBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcRrC, yTcTrR)
	clickRune(xRcRrC, yTcBrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	AIR SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
topLeftShock()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcRrC, yTcTrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topLeftLightningBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcMrR)
	clickRune(xLcRrC, yTcTrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightShock()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcRrC, yTcTrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightLightningBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcMrR)
	clickRune(xRcRrC, yTcTrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	EARTH SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
topLeftPoisonCloud()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcBrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topLeftPoisonBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xLcLrC, yTcBrR)
	clickRune(xLcRrC, yTcTrR)
	;	Cast
	clickRune(xLcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightPoisonCloud()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcBrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
topRightPoisonBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy1))
	;	Runes
	clickRune(xRcLrC, yTcBrR)
	clickRune(xRcRrC, yTcTrR)
	;	Cast
	clickRune(xRcCsC, yTcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;


; ---------- ---------- ---------- ---------- ---------- ;
;	OFFENSIVES SPELLS - FROM THE BACK CHARACTERS
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	FIRE SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftFireBurst()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcTrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftFireBall()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcTrR)
	clickRune(xLcRrC, yBcTrR)
	clickRune(xLcRrC, yBcMrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightFireBurst()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcTrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightFireBall()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcTrR)
	clickRune(xRcRrC, yBcTrR)
	clickRune(xRcRrC, yBcMrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	ICE SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftIceShards()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcBrR)
	clickRune(xLcRrC, yBcBrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftFrostBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcRrC, yBcTrR)
	clickRune(xLcRrC, yBcBrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightIceShards()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcBrR)
	clickRune(xRcRrC, yBcBrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightFrostBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcRrC, yBcTrR)
	clickRune(xRcRrC, yBcBrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	AIR SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftShock()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcRrC, yBcTrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftLightningBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcMrR)
	clickRune(xLcRrC, yBcTrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightShock()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcRrC, yBcTrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightLightningBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcMrR)
	clickRune(xRcRrC, yBcTrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	EARTH SPELLS
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftPoisonCloud()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcBrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomLeftPoisonBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx1r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xLcLrC, yBcBrR)
	clickRune(xLcRrC, yBcTrR)
	;	Cast
	clickRune(xLcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightPoisonCloud()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcBrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;
bottomRightPoisonBolt()
{
	global
	storeMousePos()
	startSpellCast(chX+(chWid*dx2r),  chY+(chHei*dy2))
	;	Runes
	clickRune(xRcLrC, yBcBrR)
	clickRune(xRcRrC, yBcTrR)
	;	Cast
	clickRune(xRcCsC, yBcCsR)
	restoreMousePos()
	return
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	SPELLS UTILITY FUNCTIONS
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
;	startSpellCast
; ---------- ---------- ---------- ---------- ---------- ;
startSpellCast(x, y)
{
	MouseClick, right, x, y
}
; ---------- ---------- ---------- ---------- ---------- ;
;	clickRune
; ---------- ---------- ---------- ---------- ---------- ;
clickRune(xFactor, yFactor)
{
	global
	iX := chX+(chWid*xFactor)
	iY := chY+(chHei*yFactor)
	MouseMove, iX, iY
	MouseClick, left, iX, iY
}
; ---------- ---------- ---------- ---------- ---------- ;

; ---------- ---------- ---------- ---------- ---------- ;
#IfWinActive Grimrock ahk_class EWindowClass
; ---------- ---------- ---------- ---------- ---------- ;
	init()

	;	TOP LEFT CHARACTER
	TopLeftCharFireBurst:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftFireBurst() ;	cast fireburst
	Return
	TopLeftCharFireBall:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftFireBall() ;	cast fireburst
	Return
	TopLeftCharPoisonCloud:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftPoisonCloud()  ;	cast poison cloud
	Return
	TopLeftCharPoisonBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftPoisonBolt() ;	cast poison bolt
	Return
	TopLeftCharShock:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftShock() ;	cast shock
	Return
	TopLeftCharLightningBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftLightningBolt() ;	cast lightning bolt
	Return
	TopLeftCharIceShards:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftIceShards() ;	cast ice shards
	Return
	TopLeftCharFrostBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topLeftFrostBolt() ;	cast frostbolt
	Return
	
	;	TOP RIGHT CHARACTER
	TopRightCharFireBurst:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightFireBurst() ;	cast fireburst
	Return
	TopRightCharFireBall:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightFireBall() ;	cast fireburst
	Return
	TopRightCharPoisonCloud:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightPoisonCloud()  ;	cast poison cloud
	Return
	TopRightCharPoisonBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightPoisonBolt() ;	cast poison bolt
	Return
	TopRightCharShock:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightShock() ;	cast shock
	Return
	TopRightCharLightningBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightLightningBolt() ;	cast lightning bolt
	Return
	TopRightCharIceShards:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightIceShards() ;	cast ice shards
	Return
	TopRightCharFrostBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			topRightFrostBolt() ;	cast frostbolt
	Return
	
	;	BOTTOM LEFT CHARACTER
	BottomLeftCharFireBurst:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftFireBurst() ;	cast fireburst
	Return
	BottomLeftCharFireBall:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftFireBall() ;	cast fireburst
	Return
	BottomLeftCharPoisonCloud:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftPoisonCloud()  ;	cast poison cloud
	Return
	BottomLeftCharPoisonBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftPoisonBolt() ;	cast poison bolt
	Return
	BottomLeftCharShock:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftShock() ;	cast shock
	Return
	BottomLeftCharLightningBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftLightningBolt() ;	cast lightning bolt
	Return
	BottomLeftCharIceShards:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftIceShards() ;	cast ice shards
	Return
	BottomLeftCharFrostBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomLeftFrostBolt() ;	cast frostbolt
	Return

	;	BOTTOM RIGHT CHARACTER
	BottomRightCharFireBurst:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightFireBurst() ;	cast fireburst
	Return
	BottomRightCharFireBall:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightFireBall() ;	cast fireburst
	Return
	BottomRightCharPoisonCloud:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightPoisonCloud()  ;	cast poison cloud
	Return
	BottomRightCharPoisonBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightPoisonBolt() ;	cast poison bolt
	Return
	BottomRightCharShock:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightShock() ;	cast shock
	Return
	BottomRightCharLightningBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightLightningBolt() ;	cast lightning bolt
	Return
	BottomRightCharIceShards:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightIceShards() ;	cast ice shards
	Return
	BottomRightCharFrostBolt:
		If WinActive(titleOfGrimrockWindow) and WinActive("ahk_class EWindowClass")
			bottomRightFrostBolt() ;	cast frostbolt
	Return

	; Debug test
	^t::
	{
		init()
		MouseMove, chX, resY-10, 6
		MouseMove, chX, chY, 6
		MouseMove, resX-10, chY, 6
		MouseMove, resX-10, resY-10, 6
		MouseMove, chX, resY-10, 6
		return
	}
	
#IfWinActive
The .Ini Configuration File
SpoilerShow

Code: Select all

; ---------- ---------- ---------- ---------- ---------- ;
;	Legend of Grimrock
; ---------- ---------- ---------- ---------- ---------- ;
;
;	AutoHotKey Binding Ini
;	Spell Keys by LordYig
;	v 0.1	21/07/2012
;	
;	To change the bindings, please refer to the AutoHotKey Manual.
;
;	You can find the AutoHotKey Documentation Online at the following adress :
;		http://www.autohotkey.com/docs/
;
;	you can also find a complete key list at the follwoing page :
;		http://www.autohotkey.com/docs/KeyList.htm
;
;	If you do not need a specific bonding leave it empty.
;	The script will check this file for a binding
;	and only affect it to a comand if it exist.
; ---------- ---------- ---------- ---------- ---------- ;
[TopLeftCharacterMageSpells]
FIREBURST=
FIREBALL=
ICESHARDS=
ICEBOLT=
POISONCLOUD=
POISONBOLT=
SHOCK=
LIGHTNINGBOLT=
[TopRightCharacterMageSpells]
FIREBURST=
FIREBALL=
ICESHARDS=
ICEBOLT=
POISONCLOUD=
POISONBOLT=
SHOCK=
LIGHTNINGBOLT=
[BottomLeftCharacterMageSpells]
FIREBURST=è
FIREBALL=!è
ICESHARDS=_
ICEBOLT=!_
POISONCLOUD=
POISONBOLT=
SHOCK=
LIGHTNINGBOLT=
[BottomRightCharacterMageSpells]
FIREBURST=
FIREBALL=
ICESHARDS==
ICEBOLT=!=
POISONCLOUD=
POISONBOLT=
SHOCK=)
LIGHTNINGBOLT=!)
Possibles Enhancements / Debug / Tweaking
SpoilerShow
  • Tweaking function from D32, techzen and Adakos's script :
    If the script seems to miss the right areas to perform the cast, you can adjust the xAdjust & yAdjust variables in the script to modify its size (>1 means bigger - 1.1 means 110% - <1 means smaller, x for width y for height).
  • Merge with part of the D32, techzen and Adakos's script.
  • Merge with all the D32, techzen and Adakos's script.
Changelog
SpoilerShow
  • 21.07.2012 : v 0.1
    Original Release
You can report any bug, send feedback, rage for problems, or anything else in this post. Enjoy ;)
User avatar
Jirodyne
Posts: 211
Joined: Sat Jul 21, 2012 6:07 am

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Jirodyne »

No offence, this is just my opinion, but.... While the runes were all kinda crazy the first play through and not knowing what they are... It really isn't that complicated when you learn them. Now that I know how the runes work, I guess and use every spell in the game. Then again, seeing as every school has only 4 spells, a basic attack, a long range attack, enchant arrows, and defense shield. (and Invisible for Air too.) It's very easy to remember. Like for example, the Defense shield and Enchant arrows spells are all the same except 1 rune, which is switched between the 4 runes that make of Fire, Ice, Air, and Earth. Do people really need something like this? Especially since You can find scrolls as well that tell you the spells, and you can cue the spells before a fight. I just don't see how this is... Useful. All it changes is.... what? save the 2 seconds it takes to open the rune menu and hit the right runes? Especially with the bugs you have pointed out with it, that you know of so far. Just seems too complicated and unneeded.

Also, if they rely on your script, they won't learn the runes and the spells. So what happens when/if the game continues with a #2, and they have a more complicated rune system with even more spells? They won't know or understand the basics, cause someone held their hand through it all.
User avatar
LordYig
Posts: 175
Joined: Wed Jul 04, 2012 5:45 pm

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by LordYig »

Jirodyne wrote:No offence, this is just my opinion, but.... (...)
Well, Jirodyne, I understand clearly your point, but...
For some time there was people asking on this forum for this kind of feature or help. I only propose a solution to what some people may think is a lacking feature in the game when it is actually a deliberate design choice from the devs.

I do not agree when you say that it is useless to save 2 seconds while casting spells. During some of my playthrough I have made several mistakes during fights and my party or part of it died miserably partly due to the time taken while casting spells. I kept seeing one of my mage dying helplessy while I was clicking and assembling the runes on several occasions. I remember falling at the fighter challenge several times while my mages where totally useless and I was not even beeing able to cast a second spell before they die. I know how this situation can be quite frustating.

But, I do think that the casting system is an important part of the game and that it is part of the experience the game provide. I also understand people beeing frustrated by this and trying to bypass it. I only provide a way to do this if they want to. I was in the position to make this simple script and it actually works quite well, with the limitations I have explained.

Like you, I also know the rune system very well and all spells from the game. I have finished the game two times already and i'm planning another solo playtrough with Toorum. So I understand your point when you say that this is simple.
Back in my younger days, I also learned the rune system from Dungeon Master which was more complicated that the system in LoG, and I had no problem to deal with it. But the gameplay was quite different that the gameplay of LoG, the movements of the party especially was quicker, much quicker.

Anyway, if nobody finds this usefull, well that's not a problem for me, I enjoyed playing with AutoHotKey while testing the script and learning to automate stuff with this tool. But if at least one person on this forum use this and finds it usefull, well, it was worth the time I spend on this. :)

Thanks for taking the time to clearly explain your opinion Jirodyne.
User avatar
leewroy
Posts: 531
Joined: Fri May 25, 2012 10:17 pm

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by leewroy »

I relly appreciate your effort friend, but seems more complicaed to me to hit alt + something and all that stuff than choose the runes once you get used.
I believe that some people will like, though. I´m not here to diss your job. Thanks for sharing this script :)
pzico
Posts: 5
Joined: Wed Aug 15, 2012 4:20 am

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by pzico »

I have just barely started the game, but in my opinion we do need this kind of scripts. This is fast paced game (during action) without ability to put things in queue for action round, like in Wizardry 8 (correct me if I'm wrong here). Avoiding those 2 seconds and 2 mouse clicks do help here. Also being able to minimize usage of mouse and do a lot from keyboard, is convenient and does make me playing longer.

It's great we have choices! Thanks LordYig, your work is appreciated.
User avatar
Dr.Disaster
Posts: 2876
Joined: Wed Aug 15, 2012 11:48 am

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Dr.Disaster »

The mere existence of this thread states that the caster interface needs to be improved.
User avatar
Sol_HSA
Posts: 681
Joined: Fri Mar 02, 2012 3:10 pm
Location: Nowhere whenever
Contact:

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Sol_HSA »

Dr.Disaster wrote:The mere existence of this thread states that the caster interface needs to be improved.
Could be, not necessarily should be, and whether thIs is an improvement or a cheat is a matter of taste..
Reminder: moderators (green names) don't work for almost human. | http://iki.fi/sol/ - My schtuphh..
User avatar
Dr.Disaster
Posts: 2876
Joined: Wed Aug 15, 2012 11:48 am

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Dr.Disaster »

Sol_HSA wrote:
Dr.Disaster wrote:The mere existence of this thread states that the caster interface needs to be improved.
Could be, not necessarily should be, and whether thIs is an improvement or a cheat is a matter of taste..
Agreed, seeing AutoHotKey as improvement or cheat is a matter of taste.

Yet that people think about using it hints more into "should" then "could" direction. I mean: would they otherwise bother using AutoHotKey?

As a reminder: by start of LoG Beta the user interface was split into char portraits at the top left and action hands at the botton right. During Beta (or end, not sure here) the interface got a big overhaul by combining the portaits with action hands. Now improving the caster interface may be not that obvious but even small things can make a big difference.
User avatar
Thels
Posts: 481
Joined: Wed Apr 25, 2012 8:42 am
Location: The Netherlands
Contact:

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Thels »

Dr.Disaster wrote:
Sol_HSA wrote:
Dr.Disaster wrote:The mere existence of this thread states that the caster interface needs to be improved.
Could be, not necessarily should be, and whether thIs is an improvement or a cheat is a matter of taste..
Agreed, seeing AutoHotKey as improvement or cheat is a matter of taste.

Yet that people think about using it hints more into "should" then "could" direction. I mean: would they otherwise bother using AutoHotKey?

As a reminder: by start of LoG Beta the user interface was split into char portraits at the top left and action hands at the botton right. During Beta (or end, not sure here) the interface got a big overhaul by combining the portaits with action hands. Now improving the caster interface may be not that obvious but even small things can make a big difference.
There are also trainers for a lot of other games that make your characters superhuman, or simply jump to the victory screen from the very start of the game.

I guess you consider those options should be implemented into the base game as well?



You're not talking about "improving" the caster interface, but changing it so that it appeals more to some. At the same time, it will appeal less to others. The caster interface is the charm of the mages, and a balance to the powerful spells they can launch.

If you don't like the caster interface, play fighter/fighter/rogue/rogue, and you'll be fine!
User avatar
Dr.Disaster
Posts: 2876
Joined: Wed Aug 15, 2012 11:48 am

Re: AutoHotKey Script (v0.1) : spell casting with one key pr

Post by Dr.Disaster »

Thels wrote:
Dr.Disaster wrote:
Sol_HSA wrote: Could be, not necessarily should be, and whether thIs is an improvement or a cheat is a matter of taste..
Agreed, seeing AutoHotKey as improvement or cheat is a matter of taste.

Yet that people think about using it hints more into "should" then "could" direction. I mean: would they otherwise bother using AutoHotKey?

As a reminder: by start of LoG Beta the user interface was split into char portraits at the top left and action hands at the botton right. During Beta (or end, not sure here) the interface got a big overhaul by combining the portaits with action hands. Now improving the caster interface may be not that obvious but even small things can make a big difference.
There are also trainers for a lot of other games that make your characters superhuman, or simply jump to the victory screen from the very start of the game.
If people need a trainer to play a game they should not even bother.
Thels wrote:I guess you consider those options should be implemented into the base game as well?
Wrong. IMO people relying on trainers don't play games. They plain cheat and miss all the good stuff about playing a game like challenge/experience/joy/satisfaction/...

Beside, you do an interesting leap there from a "control improvement" request to a "build-in cheats" guess.
Thels wrote:You're not talking about "improving" the caster interface, but changing it so that it appeals more to some. At the same time, it will appeal less to others. The caster interface is the charm of the mages, and a balance to the powerful spells they can launch.
Sorry, here you plain err. Don't get that wrong; i think the game balancing was done very well and mage spells are fine but they are by far not powerful enough to justify both a caster cooldown PLUS a handling delay.
Thels wrote:YouIf you don't like the caster interface, play fighter/fighter/rogue/rogue, and you'll be fine!
I LIKE the caster interface although i've played your suggested fighter/fighter/rogue/rogue party.

Well last party i played was an all ranged 4 rogue party. 2 throwers in front, 2 missile users in the back. Hard diff with 10.75 hours in the game, 3460 ranged attacks so far with ZERO(!) other attacks at start endgame point and everything else completed, including fighters challenge. The point is: once the rogues got access to enough ammo (6+ per used type) and double-throw/volley they literally scred thru anything. Their damage-output is both higher and faster as that of my 4 mage party which is already impressive. The rogues can kill a Goromorg with 8 attacks and less while the mages need 10..12 spells.
Post Reply