@Kuma Yeah this sucks man. That’s the reason why I’ve switched to M&K to play melee Primal Strike. The guy doesn’t approach enemies and sometimes swings in the air whereas with M&K he approaches automatically and you never swing in the air. Unfortunately I cannot do anything about since I don’t read the game’s memory and I cannot read the position of the monster you are targetting with a controller (the cursor is hidden and is in a completely different place then)
@klasperstanze Inquisitor Seal cast under your feet when using mouse and keyboard
SendMode Input
;#UseHook
#NoEnv
#SingleInstance Force
#MaxHotkeysPerInterval 1000
#MaxThreadsPerHotkey 1
#KeyHistory 50
;#InstallKeybdHook
;#InstallMouseHook
SetWorkingDir %A_ScriptDir%
s::
WinGetActiveStats, Title, Width, Height, X, Y
MouseGetPos, xpos, ypos
BlockInput, MouseMove
MouseMove, Width/2, Height/2
Sleep 10 ;Sleep, 25 lowered it, needs testing in specific case
Send {3}
;Sleep, 25 not needed in most cases, test it
MouseMove, xpos, ypos
BlockInput, MouseMoveOff
Return
A few remarks:
I included my settings in the beginning since not all scripts work well if I mess them up
s:: -> the key you’d like to cast the seal with
Send {3} -> bind this key to da Seal
The keys in 2) and 3) should be different. I can make it work when it’s one and the same key but it has some minor problems so I would prefer these to be different. But if you really need this to be one key, tell me
Thanks. I know this of course and tested it in some previous program and it didn’t work that’s why I made up this Loop stuff glad it’s not needed. It must have not worked due to some silly mistake. I deleted the post so that it doesn’t confuse people.
[edit] No, it sometimes doesn’t work. When I configure keys to rotate, they don’t work in-game with this directive and work without it. When I configure scroll to rotate, it works (and keys work after scrolling for one time). Very weird behaviour that’s why I’m going back to Loop. I really don’t understand it. And I saw messages on some forums with people having the same problem.
~LButton::
KeyWait, LButton, T0.2
if ErrorLevel
{
while GetKeyState("LButton", "P")
{
Send {7} ;key Savagery is bound to
Sleep, 1900 ;delay to Savagery so that we use it just to keep the buff up
}
}
Return
The number of Primal Stack attacks barely changes since the animation of Savagery after Primal Strike is very short. Especially with high attack speed.
Don’t know if you’re using the seal macro at the moment but it still works for me if I remove the second sleep and lower the first sleep from 25 to 10 (less cursor flickering and more fluid).
Tried it. Flicker is not observable anymore. But sometimes in combat the script fails to hit the middle of the screen. Cannot really say why. Not too big of an issue though.
This happens when the sleep is too low, especially in the middle of the combat with lower fps. Just need to find the lowest value that doesn’t cause that
Hey, I´m currently struggling with something:
As long as my LMB is pressed, I want to apply ABB every 4 seconds and 2 other buffs every 30 seconds.
I cannot make two separate loops for that, as far as I can see - since the 1st loop never ends. Any quick suggestions? Would go for a counter being checked by modulo 30, but idk how to write this in “script”.
Better autocasting of multiple skills (frequencies, delays)
I’ve written such stuff for Diablo 3 but the code was very complicated (the loop was external always working in the background, different skills had different frequencies, you could pause them, toggle some of the skills etc) and I used the modulo (it’s clean and great for minimizing number of threads). It doesn’t need to be complicated though
Let’s assume the step for Modulo is 100 ms (instead of 1000 ms) so that we can set the frequencies to 1300 ms, 2700 ms etc instead of just 1, 2, 3, 4 s (can be changed to bigger 200, 500, 1000 ms if there are some performance issues)
Now we want choose the big number we are going to divide to check whether it’s time to use our skills. You want your skills to be cast 1) every 40 x 100 ms 2) every 300 x 100 ms. We want to choose a number that is divisible buy both 40 and 300. Let’s take the Lowest Common Multiple
LCM(40, 300) = 600
If we choose for example 3 skills with 1.3 s, 2.5 s and 10 s (13 x 100ms , 25 x 100 ms, 100 x 100 ms)
we would take LCM(13, 25, 100) = 1300
Testing code for you to test
; my settings, highly recommend them for your scripts, they make a difference
SendMode Input
#NoEnv
#SingleInstance Force
#MaxHotkeysPerInterval 1000
#MaxThreadsPerHotkey 1
#KeyHistory 50
SetWorkingDir %A_ScriptDir%
~*LButton:: ; * makes it work with Shift and other modifiers
KeyWait, LButton, T0.2
if ErrorLevel
{
counter := 0 ;0 for the first skill to be casted ASAP
;1 for the first skill to be casted later
while GetKeyState("LButton", "P")
{
if !Mod(counter, 30) ;every 30 x 100 ms
send {1}
if !Mod(counter - 5, 30) ;every 30 x 100 ms, -5 for the 2th skill to be cast 0.5s later
send {2} ; to avoid skill conflict when you just started holding The Left Click
if GetKeyState("Shift", "P") and !Mod(counter - 10, 30) ;combining with Shift for fun
send {3} ;every 30 x 100 ms, -10 for the 3th skill to be cast 1s later
; to avoid conflict when you just started holding Left Click
Sleep, 100 ; 100 ms instead of 1s for more freedom
counter := Mod(counter + 1, 6000) ; in this example it could be 30 because
; LCM(30, 30, 30) = 30 or any multiple of 30 like 6000
}
}
Return
The code doing exactly what you wanted (worse for testing, only changed fragment)
if !Mod(counter, 40) ;every 40 x 100 ms
send {1}
if !Mod(counter - 5, 300) ;every 300 x 100 ms, -5 for the 2th skill to be cast 0.5s later
send {2} ; to avoid skill conflict when you just started holding The Left Click
if !Mod(counter - 10, 300)
send {3} ;every 300 x 100 ms, -10 for the 3th skill to be cast 1s later
; to avoid conflict when you just started holding Left Click
Sleep, 100 ; 100 ms instead of 1s for more freedom
counter := Mod(counter + 1, 600) ; LCM(40, 300, 300) = 600
; or any multiple of 600 i.e 40 x 300 x 300
The problem is in Grim Dawn when you want to cast 2-3 skills at the same time sometimes not all of them fire (the skills interrupt each other). You know, when you have your skill to be casted every 30s and it for some reason it’s not casted and you have to wait another 30s? You have a problem. My workaround for that has been trying to cast skills more often than needed (for example I would try to cast Totem/Wind Devil every 1s not every 5s) but the workaround has to be always tailored to the specific case. In this code I added time shifts for 2th, 3rd skills (counter -5, counter - 10) to prevent this when you start holding the Left Click. This could be combined with higher frequencies to be sure, for example trying to cast skills every 15 seconds instead of 30 seconds. You could probably improve the code so that there’s never conflict between skills but the code complication would be far greater than the benefits. You could make the counter global, to change the behavior a little bit. You could make the buffs to fire only once etc.
Another little problem is these times probably won’t be precise. What I mean is for example when the loop Sleep is 100 ms, the loop step will probably take longer than 100 ms (? I don’t know for sure though)
There’s also a possibility to have external loop working constantly in the background and you only “toggling” it with a hotkey, not having to hold a button if needed.
Tweak the code to your liking, it has lots of freedom and many ways of adjusting autocasting so that it plays very well. Almost anything can be achieved in Autohotkey but sometimes it takes me weeks to figure out some bugs/behaviors. I have lots of fun writing and testing these scripts so write if you have any problems. And as it’s always the case I’ve learnt something and got the code I’ll use myself.
Video of Testing Code (at first we don’t hold shift so Devouring Swarm doesn’t fire)
PS Some new stuff
dual mode Left Click Hold
(cast some skills when you just hold Left Click and some more skills when you additionaly hold Shift)
~*LButton:: ; ~ means Left Click still clicks, * means it works with Shift, Ctrl etc
KeyWait, LButton, T0.2
if ErrorLevel
{
while GetKeyState("LButton", "P")
{
Send {7} ;key for Wind Devil
if GetKeyState("Shift", "P") ;When Shift pressed do something else as well
Send {8} ;key responsible for War Cry/Wendigo Totem which we only
Sleep, 500 ; sleep time low to cast skills with very little delay
}
}
Return
suspending only selected hotkeys with a hotkey (not all of them with Suspend function):
When I used to play a caster Ritualist before, the piano playstyle immediately made me dislike the build.
Then I figured out I can just use X-Mouse to make my left-click do its original purpose (use the skill assigned to it) while repeatedly executing simulated keystrokes as well (press keyboard keys where other skills are assigned) as long as the button is pressed down.
You can even add delays between keystrokes (to allow for some skill casting animations to complete before the next one) as well as delays on repeating the whole keystroke cycle while the mouse button is held down (to prevent X-Mouse from immediately repeating the same keystrokes especially for skills with cooldowns).
My current code is different with 3 skills each with different behaviour
Wind Devil - cast as soon as cooldown ends when you hold Left Click (key sent every 200 ms)
War Cry - cast as soon as cooldown ends when you hold both Left Click and Shift (key sent every 200ms)
Wendigo Totem - cast only once as soon as cooldown ends when you hold both Left Click and Shift and then it waits for 14 seconds to cast it again unless you release, click and hold Shift again, then you can cast it sooner (as soon as cooldown ends if you click and release Shift frequently, i.e. if moving from pack to pack when you want Totems more often) [this is how I play - I hold Left Click permanently, hold Shift when fighting one pack, Right click for movement skill]
There’s a mechanism to ensure than Wendigo Totem is definitely cast and not interrupted by Primal Strike from Left Click or other skills
~*LButton::
KeyWait, LButton, T0.2
if ErrorLevel
{
counter := 0
while GetKeyState("LButton", "P")
{
if GetKeyState("Shift", "P")
{
if counter < 10 ;we try casting Totem 10 times (for 10 x 200 ms = 2s) for 100% chance
{
Send {7} ; Wendigo Totem
}
Send {6} ; War Cry
counter := Mod(counter + 1, 70) ;70 means 70 x 200 ms = 14s because Totem has 15s duration
}
else
counter := 0
Send {8} ; Wind Devil
Sleep, 200
}
}
Return
Longer version example (when you move with Left Click & fight with Left Click + Shift)
~*LButton::
KeyWait, LButton, T0.2
if ErrorLevel
{
items_hidden := false ;ITEMS SHOWN BEFORE THE FIGHT
while GetKeyState("LButton", "P")
{
;SKILLS CAST WHILE WALKING
if GetKeyState("Shift", "P") ;FIGHT MODE
{
if !items_hidden ;HIDING ITEMS IF SHIFT IS HELD
{
Send {LAlt}
items_hidden := true
}
;SKILLS CAST WHILE FIGHTING
}
else
{
if items_hidden ; SHOWING ITEMS IF SHIFT IS RELEASED FIRST
{
items_hidden := false
Send {LAlt}
}
}
Sleep, 200
}
}
Return
~*LButton UP:: ;SHOWING ITEMS IF LEFT CLICK IS RELEASED FIRST
if items_hidden
{
items_hidden := false
Send {LAlt}
}
Return