Jump to content

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

hotkeys script for invoker (dota, warcraft 3), help me debug


  • Please log in to reply
6 replies to this topic
iloreon
  • Members
  • 1 posts
  • Last active: Feb 12 2008 03:13 AM
  • Joined: 12 Feb 2008
(If there's something that isn't clear, please do mention it and I will clarify it.)

Below is my own custom script for the hero invoker. For those who don't know what DotA is, it is simply a modified map for Warcraft III where you get to control a hero and strengthen it to fight for your side. This hero, the Invoker, has 4 basic skills. The first 3 are 'balls' each of which have specific bonus gains for Invoker. A maximum of 3 balls can be conjured at anytime. The 4th skill is called Invoke, which creates a total of two spells (5th and 6th spell). A unique spell is created by Invoke with whatever combination of the 3 balls you are currently using. For example (let's distinguish the balls as Ice, Fire, and Bolt for simplicity's sake), 'invoking' while the hero has 3 Ice balls conjured will procure the spell 'Cold Snap'. Invoking while having each of the balls conjured (one each) will procure the spell 'Deafening Blast'. Since there are only 3 types of balls, the total possible combination (not permutation) is 10. Therefore, 10 spells.

Assuming now that two spells have been invoked (first invoked spell: Cold Snap, and second invoked spell: Deafening Blast) and still you want to invoke another spell, the older spell of the two current spells will be replaced (in this case, the Cold Snap). So now you have Deafening Blast and the new spell. Yet still you want to experiment more and try another combination. Invoking then will have the Deafening Blast replaced. So now you have the two new spells in your arsenal.

So the purpose of my code is to simplify the invoking by pressing only one letter in the keyboard. Without this script, I will have to press the hotkeys for the balls, then the hotkey for Invoke, then the hotkey for the invoked Spell. It's bound to be difficult memorizing all the combinations and the hotkeys for each spell, that's why I came up with creating this script. As I have just said, one letter press and a spell will be invoked in an instant and then you only need to decide where to cast the spell by clicking the mouse.

The general structure of the script is this:
Since only two spells can be procured at a time, I added a simple function and some variables. The pseudoscript would be

First Part: Identify Warcraft 3 and label it with an id
Second Part: Define Subtract function (the value of all variables is subtracted by 1 unit. the variables are not declared since when I tried loading the script, it did not seem to have errors relating to the variable declaration)

Note: the variables will be used to identify whether the spells are currently in the skill set of the hero. Variables having the value of 1 and 2 means their corresponding spell are currently in the skill set. If it's 0 or below, then it's not. I know I am not so good at explaining so again I am giving an example at the third part of the pseudoscript.

Third Part: (this part will only work if warcraft 3 is active) Hotkeys
If I press a hotkey of a spell it will check if the spell is in the skill set.
If it is in the skill set (if variable is greater than 0), it will directly let you cast the spell.

If not, the script will proceed to invoke the spell so that you can use it. It will then set the variable for invoked spell to 3 and perform the subtract function. (The reason why i set the value for the variable to 3 is that the subtract function subtracts all the value of all variables by 1 including that of the invoked spell. Doing so, it remains having a value of 2.)

Example: Early in the game, the Invoker does not have any spells yet. By using the script I decided on invoking the Tornado spell. Since all variable at the start have 0 value, the script will proceed to invoking the spell and tada... Tornado spell is born, and after that Tornado's corresponding variable will now have the value of 2 (initially 3 but 2 after the script runs the subtract() function remember?). Pressing Tornado's hotkey again will not use the Invoke skill, since its variable is greater than 0.

But wait! I only have 1 spell in my skill set. I want to add one more! What about Chaos Meteor! I then press it's hotkey. The script proceeds to check if its variable is greater than 0. No it isn't (since it's variable is probably -1 after the subtract() when invoking the Tornado spell) so it proceeds to the invoking part of the script. Its variable will then have a value of 2 after the subtract() function. By then, the value of Tornado's variable is also subtracted by 1, so it's value is 1.

Invoking another spell again will have the value of Tornado's variable to 0, which is right since values of 0 and below means it's been replaced and not in the skill set. Chaos Meteor should now have the variable value of 1. Invoking yet another spell will replace Chaos Meteor.

So since Tornado and Chaos Meteor have been replaced, pressing their hotkeys will have the script proceed to invoking them again.

That's how my script works.

But my script has a bug. Here's an instance when the bug occurs,

Invoke Tornado (its variable should be 2)
Invoke Deafening Blast (its variable should be 2, Tornado's is 1)
Invoke Chaos Meteor (Tornado should be replaced since variable is 0)

(all spells mention in this instance are just examples, any spell will produce the bug)

But if I try to invoke Tornado, it doesn't work!!!!! Somehow the script still thinks the spell is currently in the skill set! That could mean that it's variable is still greater than 0! This is my problem!

I feel there is something wrong in my Subtract() function. But I really do not know since I am just a casual programmer. I have tried correcting the errors but to no avail.


; Select invoker first before running this script. Do not run more than 1 instance of warcraft III.

;Grab unique window ID's
WinGet, warcraftid, List, Warcraft III

;Set warcraft III as idmain
idMain = %warcraftid1%

WinActivate, ahk_id %idMain%

; *******************
; ***Subtract Function***
; ****************
Subtract()
{
  Var1 = Var1 - 1
  Var2 = Var2 - 1
  Var3 = Var3 - 1
  Var4 = Var4 - 1
  Var5 = Var5 - 1
  Var6 = Var6 - 1
  Var7 = Var7 - 1
  Var8 = Var8 - 1
  Var9 = Var9 - 1
  Var10 = Var10 - 1
return
}

; *******************
; ***Turn on/off Suspend Program***
; ****************
#IfWinActive, Warcraft III
^s::Suspend 
return

; *******************
; ***Remapped Balls Hotkeys***
; ****************

#IfWinActive, Warcraft III
   ; *** All Quas Balls ***
   ~,::
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
return

#IfWinActive, Warcraft III
   ; *** All Wex Balls ***
   ~.::
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
return

#IfWinActive, Warcraft III
   ; *** All Exort Balls ***
   ~/::
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
return

; *******************
; ***Remapped Abilities Hotkeys***
; ****************

#IfWinActive, Warcraft III
   ; *** EMP [var 1]***
   ~C::
   If Var1 > 0
{
   ControlSend,,{C down}{C up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{C down}{C up},  ahk_id %idMain%
   Var1 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Chaos Meteor ***
   D::
   If Var2 > 0
{
   ControlSend,,{D down}{D up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{D down}{D up},  ahk_id %idMain%
   Var2 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Deafening Blast ***
   ~B::
   If Var3 > 0
{
   ControlSend,,{B down}{B up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{B down}{B up},  ahk_id %idMain%
   Var3 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Tornado ***
   ~X::
   If Var4 > 0
{
   ControlSend,,{X down}{X up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{X down}{X up},  ahk_id %idMain%
   Var4 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Sun Strike ***
   ~T::
   If Var5 > 0
{
   ControlSend,,{T down}{T up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{T down}{T up},  ahk_id %idMain%
   Var5 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Ghost Walk ***
   ~V::
   If Var6 > 0
{
   ControlSend,,{V down}{V up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{V down}{V up},  ahk_id %idMain%
   Var6 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** ICe Wall ***
   ~G::
   If Var7 > 0
{
   ControlSend,,{G down}{G up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{G down}{G up},  ahk_id %idMain%
   Var7 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Summons ***
   ~F::
   If Var8 > 0
{
   ControlSend,,{F down}{F up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{E down}{E up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{F down}{F up},  ahk_id %idMain%
   Var8 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Cold Snap ***
   ~Y::
   If Var9 > 0
{
   ControlSend,,{Y down}{Y up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{Q down}{Q up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{Y down}{Y up},  ahk_id %idMain%
   Var9 = 3
   Subtract()
}
return

#IfWinActive, Warcraft III
   ; *** Alacrity ***
   ~Z::
   If Var10 > 0
{
   ControlSend,,{Z down}{Z up},  ahk_id %idMain%
}
else 
{
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{W down}{W up},  ahk_id %idMain%
   ControlSend,,{R down}{R up},  ahk_id %idMain%
   Sleep, 100
   ControlSend,,{Z down}{Z up},  ahk_id %idMain%
   Var10 = 3
   Subtract()
}
return



Buckie
  • Members
  • 15 posts
  • Last active: Sep 05 2008 09:55 AM
  • Joined: 13 Feb 2008
Hi iloreon

Fancy script you made...making things simpler often eliminates bugs. Anyway, I made a similar script with for friend, it went something like this

^Q::
Send Q
Sleep 20
Send Q
Sleep 20
Send Q 
Sleep 20
Send R
return
// and so on


The script worked fine, although we ran into a problem about the orbs sometimes not changing, the reason for this (we found out later) was not the script, but Wc3...it has a build in bug of some sort that simply screws the orbs -

We found that calling a function that presses 3 random (and by random i don't mean in any mathematic way) orbs after each skill change, the problem stopped.

Maybe this could solve your problem as well, I hope so

wondTer
  • Guests
  • Last active:
  • Joined: --
I'm not sure if this helps but I think you missed a 'tilda' at the beginning of the function invoking Chaos Meteor.

#IfWinActive, Warcraft III
   ; *** Chaos Meteor ***
;perhaps it should be >> ~D:: 
   D::
   If Var2 > 0
{
   ControlSend,,{D down}{D up},  ahk_id %idMain%
}

dunno, but your code is interesting..!

Furthermore, invoker learns his ulti at level 5 (latest version, 6.51) with only a max of 1 spell to invoke. Then when he gets to lvl 10, you can invoke 2 spells. I think your code works with the assumption that the hero can invoke at most 2 spells.
Try modifying the script to handle Invoker at levels 5-9.
ie. at level 5:
-->invoke emp (var 1 = 2)
-->invoke chaos meteor (var 1 = 1; var 2 = 2)
-->Invoke emp again (var 1 = 1) >> this could be the bug, as the script will not go to the 'else' part of the function.

Cheers, I hope you succeed!!

jindaxia
  • Members
  • 1 posts
  • Last active: Jan 03 2009 02:56 PM
  • Joined: 01 Jan 2009
then,you should disable the key R

Caedium
  • Members
  • 1 posts
  • Last active: Feb 12 2009 12:05 PM
  • Joined: 08 Feb 2009
Today I was trying to write a similar code for the invoker, and I found that topic. I read your code, but I think that the main problem is that if the "invoke" skill is in cooldown, autohotkey trys to use it anyway and variables go out of sync with the game...

I dont know if it's possible, i discovered autohotkey just today, but the most reliable way to know what skill is already invoked or not is to read it right from the game. Do you think it's possible in any way? I read in homepage that sentence: "Automate game actions by detecting images and pixel colors", so I think that what I just said is possible :) But really don't know how XD

Xealous
  • Guests
  • Last active:
  • Joined: --
I'm not sure why, but when I got rid of the "VarX = 3" commands that trigger after hitting the hotkey and changed the subtract() schema to "VarX-=1", the bug was solved.

I know this is a practically dead thread, but I figure I should post this for anyone else who comes across it.

Abijah
  • Members
  • 19 posts
  • Last active: Jan 12 2014 03:40 PM
  • Joined: 22 Nov 2009
i made a msgbox hotkey showing me var1 value
and the substract function doesnt work at all in the original code. the spells always stay at 3 after using them once.

i cant get the fix working. the vars dont change at all.