[Tool] GDAutocaster - play šŸŽ¹ builds with ease, autocasting of skills, combos, faster / automatic camera, autohiding of items, centered Inquisitor Seal and more for all games!

Lots of interesting stuff there. My brain is about burned out now, but Iā€™ll look at it more later.

Have you considered creating some documentation other than just the posts here? Iā€™m one of those people who actually like to read the manual. :slight_smile:

How do you think best documentation should look like?
I can only think of explanation of excessive config file with comments,
like in the 2nd part of OP. The tutorial below is unrelated to our conversation.



How to make skills that

  • you autocast all the time
  • have casting animation (i.e. Blood of Dreeg doesnā€™t)
    • for example Wind Devil, Mortar Trap, Judgment

not interrupt your debuffs

[general]
suspend_key=Tab

[autocasting]
master_toggle=q

MAKES WIND DEVIL BE CAST ALL THE TIME IF WE DON'T HOLD RMB
BUT IT'S CAST IF WE HOLD RMB TOO DUE TO OTHER FEATURE LATER
[0] 
toggle_key=0
delay=100
not_hold_keys=RButton

CAST SOME DEBUFFS 1, 2 ONCE ON RMB PRESS (I.E. COF & WOP) 
[combo presses]
combo1=RButton:1,2     
delay1=200             //DELAY BETWEEN DEBUFFS

SPAM SOME ATTACK 3 & 4 WHILE HOLDING RMB
BUT ALSO WIND DEVIL 0, ALL DELAYED BY 400
FOR DEBUFFS ABOVE TO NEVER BE INTERRUPTED
[periodic casts]
cast1=RButton:3,4,0
initial_delay1=400
delay1=100           // THE DELAY HERE IS BETWEEN [3,4,0] AND NEXT [3,4,0] PRESSED
                     // NOT BETWEEN 3 AND 4 AND 0 AS IT IS IN CASE OF COMBO PRESSES

scroll this text window down

To start off, let me say that I think what youā€™ve done is awesome. Just the little bit Iā€™ve done so far has made the game 10x less painful to my aging fingers and I probably wouldnā€™t be able to keep playing this sort of build beyond short periods without it.

For what itā€™s worth, I spent 30 years as a software developer/designer. Iā€™ve been retired for over 8 years, so Iā€™m a bit rusty and while Iā€™ve used and programmed Autohotkey in the past, Iā€™m very very far from an expert. I did look at some of your code, but honestly, itā€™s been to long and Iā€™d have to spend hours on it to make sense of it, so figuring out the sort of stuff I mention below is not on my short list of things to do. :slight_smile:

In regards to documentation, I wouldnā€™t mind seeing some documentation on the keywords and how they relate to each other.

For example, what are all the [section name] sections, what keyword= are valid in each of them. What are valid strings that follow each keyword=, etc. Some examples of thing I donā€™t know just from looking at examples, is what ā€œkeysā€ are valid, is there an order to the sections and the keywords within the sections, what are the defaults for things like delay, how do things like multiple casts or combos on the same key press interrelate? I can pick up a lot of that by looking at all the posts, but I almost have to create documentation in my brain or in notes to keep it all together.

Documented examples are awesome, but by understanding how the keywords and sections interact, I would be better able to create my own uses.

To jump to something else, from what I read in some of the earlier posts, if I want to have different profiles (.ini files) for different characters, Iā€™d have to make copies of the program with different names and matching named profiles. I donā€™t see any other way to do it, but I may be missing something. If there isnā€™t, would you consider either having a start-up input parameter with the profile name and/or a way to tell an already running version of the program to refresh with a new named profile? Obviously, this isnā€™t a critical need, but it would be very nice to have.

Thank you again for the program and for your exceptionally quick responses!

1 Like

Something I forgot that really needs documenting is what assumptions you make about keybinds. An example is that your program assumes that 1-0 are bound to skills. Iā€™m sure there are others. For example, how about the camera rotation keys? It isnā€™t working right for me and I suspect it is because of my strange keybinds.

Edit- I figured out my camera rotation problem. All my own fault.

There does seem to be something off about the angle. Is it in degrees? 60x6 should rotate me completely around, but instead 8 times takes me just a little past a complete circle.

I sympathize with you having so much to read :laughing:

My hands are fine but just mastering pressing of buttons is not my thing. Also automatization is fun on its own. Controller is even better for ergonomy and you can even automate stuff just like in GDAutocaster in Big Picture (well maybe not that flexible but still very good):

Ā 

Iā€™m not an expert either and Iā€™m bad at programming in general as well (I know nothing about design, havenā€™t studied it etc). Iā€™ve only written a few programs in AHK and I donā€™t even know how youā€™re supposed to do it. But let me tell you some things only look complicated or are complicated because they had to be because I didnā€™t figure out how to make it better or because I felt like they should be done in a particular way even though I didnā€™t understand them. Iā€™ll explain shorty some complicated things. I donā€™t mind if you donā€™t want to spend time on it:

  1. HotkeysCollector.ahk
    This weird class is so that I can define multiple hotkeys throughout the code (i.e. multiple RButton:: /some code/ [these hotkeys are defined dynamically though, using functions like Func and ObjBindMethod, and they thrown into the dictionary / object and executed one by one when you press an appropriate button.

  2. All the classes and files. At some point everything was literally in one file. But it got too big for me, especially since I donā€™t use any IDE. So I fortunately figured out a way to separate all the code into files and ā€œclassesā€ and itā€™s just so that the code is readable. To create functions ready to be thrown into HotkeyCollector I use this ObjBindMethod function.

  3. MainLoop in GDAutocaster.ahk
    Normally for a program to work only in game you do something like this
    #IfWinActive ahk_class Grim Dawn
    It never worked well for me though so the whole big ass loop is for as good as possible blockage of the program when itā€™s supposed to not be working and suspending on demand.
    (by the way I should really extract some more code from this file into other files to make it more readable).
    Also remember that you can use GDAutocaster with other games

  4. All the weird timers in the code and splitting functions into multiple parts and those parts run from timers
    fn := ObjBindMethod(this, "PeriodicCastInitialTimer", pressed_keys, held_keys, delay)
    SetTimer, %fn%, -%initial_delay%
    Most of these because Sleeps block some parts of the program and donā€™t work well whereas timers work flawlessly. They do make the program much harder to comprehend, especially if you literally split a function into two because you want to put a timer in the middle of it.

Ā 

Just as I said, Iā€™m a bad programmer, Iā€™ve never really written a documentation :wink: And Iā€™m not a quick learning person. However all keywords & sections should be here GDAutocaster.ini and almost all are optional.

Ā 

Almost all possible sections are constant and can be seen in the representative extensive config file GDAutocaster.ini
The rest / exception to the rule are the [0], [1], ā€¦ [9] sections. They are for the 1st feature of autocasting (the other one is [periodic casts]). By default you have 0 - 9 buttons pressed and [0], [1], ā€¦ [9] possible to be read by the program. But you can overwrite that and have different buttons pressed and sections possible to be read by the program in the following way
[autocasting]
pressed_buttons=q,w,e,1,Tab
Then youā€™ll have [q], [w], [e], [1], [Tab] sections available to read.

Ā 

For

  • [combo presses]
  • [combo holds]
  • [center casts]

itā€™s comboN=X:Y1,Y2,Y3,ā€¦,YK
(or castN in case of [combo holds])

For [periodic casts] itā€™s
castN=X1,X2,ā€¦,XK:Y1,Y2,Y3,ā€¦,YL

Ā 

All keys should be valid. There maybe some weird cases that if you repeat the same button in multiple features across multiple feature or maybe in the same feature in a form of Key:Key it may not work. But I put a lot of work for that not to be the case.

Ā 

I donā€™t know the specifics (I havenā€™t seen documentation ont it) but I can tell you this:

  • sections can be in whatever order

  • but there should be only one section of a particular name

  • keywords can be in whatever order

Ā 

All the defaults used in the program should be here Defaults.ahk
However I think itā€™s best (well I do that) to just specify them, i.e.

[periodic casts]
delay=100        //global delay for all the casts 
cast1=Tab:Space
delay1=200      // unless you specify otherwise as follows

Ā 

They all should work. This is thanks to HotkeysCollector.ahk I mentioned before. You should assume they all start working at the same moment. All the (initial_)delays are for to make it work in-game and skill animations not interrupt each other. But you can always try simpler config without too many delays first and it may still work well for you.

Ā 

Sorry for no good documentation. I would prefer not to spend my time at the moment for that because I can easy get overwhelmed and stressed out since Iā€™m a perfectionist very focused on details and not the grand picture and Iā€™m scared I would not be able to stop. Iā€™m not good at doing things quickly and leaving them when theyā€™re good enough.

Ā 

With this method multiple instances of the program could run simultaneously if you forget about it and it could pose the problem. Sure I could use that too and some people already asked for that. Personally I use command line and when I want to use some config file I just copy it to GDAutocaster.ini and restart the program. Iā€™ll think about something.

Ā 

The 1st feature of autocasting kinda assumes that (but you can overwrite this). I explained it earlier in the post in detail.

Ā 

I use 60 degrees. The thing is my intention here is to not need to ever be aligned with North.
60 degrees is a perfect angle for me to quickly change the angle I approach the monster and I donā€™t think I care too much if Iā€™m not perfectly aligned sometimes.
Although I admit to correcting the camera slightly at times.

Iā€™m not sure if this is fixable to be honest because itā€™s a hack honestly.
You know that itā€™s working by literally dragging the cursor at the bottom of the screen
(literally mouse rotation - you just donā€™t see the cursor too much because itā€™s so quick and at the bottom although you can if you look well enough :slight_smile:

However 8 times 60 just past a complete circle? Seem way too much off. I donā€™t think Iā€™ve ever had anything like that. I though there could be only minor errors. Is your resolution 16 x 9 (although I donā€™t remember the code and it it makes any difference). Iā€™ll look into the code now.

Ā 

Btw the rotation works in a very simple way:

It drags the cursor on the bottom of the screen by

SCREEN_WIDTH * ANGLE / 180

pixels in the appropriate direction (from left to right or in reverse)

Like it would if you were to do it manually.

Possible solutions to your problem

  • maybe youā€™re pressing it to quickly one after another

  • maybe your fps is bad (it influences the rotation I think) I try to have close to 60 FPS

  • maybe you can try increasing the delay parameter, i.e. from 40 to 80
    (it should be as low as possible provided itā€™s still working well)

  • or maybe I should implement a scaling/correcting factor in the config if itā€™s not working correctly for you for unknown reason, what do you think?

I tested it myself and 6 x 60 is just a bit over 360.

RE: rotation
My screen resolution is 1920x1080. I tried slow presses and changing the delay. Not change. It is pretty consistent that a press with angle at 60 is a little over 22.5 degrees (2x presses gets my just past 45 degrees of turn).

RE: Documentation

Yeah, documentation is definitely a rats nest. I think a lot of what gave me problems is the additions and just making sense of the whole thing since stuff is spread out throughout this forum. I can easily understand why you donā€™t want to jump in to it.

The annotated stuff you have in your original post isnā€™t bad, although incomplete. If you had that for all of the possible sections and keywords (including the newer stuff that isnā€™t in the OP), that would go a very long way. The .ini file you linked is great, except since there arenā€™t any comments explaining it, one still has a lot of puzzling out to do.

RE: other stuff
Speaking of comments in the .ini file, is there a way to put comments in that are ignored by GDautocastre? I tried ā€œ//ā€, but that didnā€™t work well as I started getting error messages from AHK.

I think Iā€™m starting to get a handle on this stuff now.

Hereā€™s a newer version of my .ini file for that same character build:

[general]
suspend_key=Tab

[autocasting]
master_hold=`
master_toggle=`

[camera]
angle=60					
counter_clockwise=Numpad7
clockwise=Numpad9
rotation_key=Mbutton
delay=40

[combo presses]
combo1=h:y,0,9,8,7,y		
delay1=650					

combo2=RButton:5,1,7,9		
delay2=100					

combo3=f:4					


[periodic casts]
cast1=f:2,3					
delay1=100
initial_delay=100			

cast2=f:4					
delay=4500					
initial_delay=4500			

cast3=RButton:5,1,7,9		
delay=500					
Initial_delay=500

[6]
toggle_key=t				
delay=15000	

I had it all commented, but as mentioned above, I had to delete the comments.


Uploaded
https://github.com/kowariantny/GDAutocaster/raw/master/GDAutocaster.exe

I literally deleted one line and put

FileSelectFile, config_name,Select Config File,Configs (*.ini)

instead

You may want to add a command line switch so that the old behavior is available for compatibility, otherwise this is awesome.

The program is compatible with the previous version though. It will work with the previous config. Besides who would want that. I mean if you want it or some other person, then sure Iā€™ll add but until then Iā€™ll skip. Would you use it?

If someone only has one configuration or doesnā€™t want to have to deal with selecting a .ini file from the directory every time, why make them spend the extra time on it?

In my case, since Iā€™ve been making incremental changes to one config file over and over, it would just be a bit faster to just use that as the GDAutocaster.ini file.

Another alternative would be to see if there is a GDAutocaster.ini and use that if there is, but if there isnā€™t, ask what .ini to use.

I tested

cast2=Space:6 ; test

and

cast2=Space:6 //test

and it worked really badly. I have T for swapping Hotbars and it really swapped them when I pressed Space :wink:

So I guess the only way is just whole lines of comments like this (it works)

[periodic casts]
MOVEMENT SKILL
cast1=Space:6

SAVAGERY
cast2=RButton:6
delay2=1900

btw I donā€™t have control over how config is read. I just use IniRead function and it does everything on its own.
https://www.autohotkey.com/docs/commands/IniRead.htm

Iā€™d also use the behavior where it asks for a .ini file, since I do have multiple builds Iā€™m playing. This is just the only one Iā€™ve tried GDAutocaster upon.

Thinking of that, is there a way to have a key that effectively presses and holds ā€œforced moveā€ while executing one or multiple skills? What I want to do is be able to use Vireā€™s Might, but since by default that will hit a target if one is near the cursor, I virtually always want to do a forced move to go past any target and move all the way to the cursor position, leaving the fire trail behind.

Iā€™ll add no_dialog flag or something

To the Vireā€™s Might thingy - I need to do it in-game because I donā€™t think Iā€™ve ever done anything like that / fully understand what you saying. Also never used Forced move in Grim Dawn. But yeah, I should be possible just let me try it in-game normally.

Wow. I never knew Force Move works like this. Actually I thought it was not working for me because itā€™s working completely differently in i.e. Diablo 3. Now I want to use it with my scripts as well and think how to use it. For example if you want to Forcewave just in between monster and not target lock on any of them. Thanks a lot.

Vireā€™s Might is a movement skill that leaves a trail of fire behind it. The skill can target an enemy or the ground. If your mouse pointer (cursor) is near an enemy, the game treats it as if the cursor was on the enemy. So, if your cursor is just past an enemy, but not a good bit past, the game will treat it as being on the enemy and instead of going past, you will hit the enemy. If you press your Forced Move key, the game doesnā€™t do the bit of treating near as being on the enemy and you will go right to the cursor (or as far as the power can go).

Note that you have to hold the Forced Move key when you press the Vireā€™s Might key.

1 Like

Iā€™m jumping in a little late in the documentation convo but I would mention if it hasnā€™t been already that if you know programming already AHK is really easy overall and the documentation on its website is very good and easy to follow and shouldnā€™t take extensive reading to understand what to do.

1 Like

[Edit] I overdid it. There was more complicated config before with [combo holds].
Simply bind periodic cast to Force Move and wellā€¦ press Force Move :slight_smile:

[periodic casts]
cast1=FM_BUTTON:VM_BUTTON

even initial_delay is not needed

Iā€™m guessing that the colon means to do both at once.

Powbam,

Yes, if you can do programming, you can do AHK. I wasnā€™t asking about AHK documentation, I was asking about documentation of what is in GDAutocasterā€™s .ini files.