User:Felix/Macros
This page contains the suite of macros I created for use with UCGO, running with AutoHotKey software. It could probably be optimized a bit, but it works as-is.
The script in full is at the end of the page, but first I'll go block by block to explain what each bit does. For more in-depth information, the documentation within AHK is very useful.
Header
Some of these lines are commented already and provided by the software itself, and therefore need no explanation, like the first two lines.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. #Warn ; Enable warnings to assist with detecting common errors.
I have never gotten anything thanks to #Warn, but YMMW.
#SingleInstance, Force #Persistent
The first line here is protection for if you accidentally reopen the script while you already have it running (in case you don't realize it's up, if you forgot to close it).
- There's only a single instance of the script allowed, no duplicates.
- Instead of opening a dialog box to ask you what you want it to do, it will simply force the original script to close, effectively the same as reloading the script.
The second line just says the script won't automatically exit unless you specifically tell it to - it will stay open and wait for you to hit hotkeys.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
The above lines were placed in the script by default, and I haven't touched them (yet). Now, onto the part I wrote.
Ctrl Shift 1: Mining Loop
^+1:: ; miner
The very first part of any AHK command (when you're using a hotkey-based setup and not something that auto-runs) is the hotkey itself. In this case:
- ^ is the Ctrl key
- + is the Shift key
- 1 is simply the number 1
- :: is the separator between the hotkey and the code you're writing, which in this case is on the next line.
Comments in AHK are put behind semicolons, which can come at the front of a line or after whitespace after code as in this case.
if not WinExist("UCClient") { MsgBox faildetect return }
If a window named "UCClient" doesn't exist (that's UCGO, of course), then display a little text messagebox so I know I did something wrong, and don't go any further. Otherwise...
else { WinActivate, UCClient
First, activate the window (bring it to the front so it gets clicks instead of any other applications that are running).
while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop {
It is very important that if you run things in a loop, you give yourself a way to break out of it. This loop only runs while two things are BOTH true:
- UCGO is active (in front), AND
- the Q key is not true (it's not pressed).
However, it only checks those two conditions at the start of a new loop. I could make it check with each operation, but that would be a lot more code and I didn't feel like it.
Click, 421 1037 ; get bar Sleep 150 Send /mine{Enter}
In these three statements you find the vast majority of what makes up the rest of the script, which will prevent me from needing to explain a lot more.
- The first line clicks the mouse at x/y coordinates, which happen to be the text input bar, thus the comment.
- The second line waits (sleeps) for 0.15 seconds (times given are in milliseconds).
- The third line sends text to the program - UCClient - in this case the literal text string
/mine
and then the Enter key.
Sleep 12500 ; wait for mining
After mining, you wait. Roughly 12.5 seconds works for me, but this may need to be adjusted based on your internet.
Click, 1063 577 ; OK (1 item) Sleep 50 Click, 1063 586 ; OK (2 item) Sleep 50 Click, 1063 595 ; OK (3 items) Sleep 50 Click, 1063 604 ; OK (4 items) Sleep 50 Click, 1063 613 ; OK (5 items) Sleep 50 Click, 1063 622 ; OK (6 items)
This section clicks multiple times to accept the results of mining. Since you may get a different number of items after mining, depending on your luck and how full your inventory is, I mapped out the location of the OK button from 1 to 6 items - or rather I did it at I think 3, 4, and 5 and noticed they were 9 pixels apart and then extrapolated the other positions accordingly. Math is fun.
Sleep 150 } } return
And that's the end of the loop, and the statement itself; you hit the return once you're out of the loop. You may notice I use 'Sleep 150' a lot between actions. Clicking multiple times with a 0ms break seemed like a bad idea to me as it might trigger some sort of anti-cheat protection, so I decided to save myself some heartache ahead of time, just in case. You're welcome to remove those lines if you're feeling adventurous though.
Ctrl Shift 2: Refining Loop
^+2:: ; smelt 10x loop
All of the hotkeys are Ctrl+Shift+(something), so here's 2, for refining.
if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop {
All the same headers and conditions as the first one, for consistency.
Click, 971 150 2 ; open factory Sleep 150
For all the building interactions, you need not just x/y coordinates, but also the number of clicks to be 2 so you're opening the UI instead of just selecting. Obviously you also need to have your camera in a position where that x/y will actually hit the building as well.
Click, 453 190 ; take out 1 Sleep 650 Click, 453 190 ; take out 2 Sleep 150
For failed refines you need to remove both materials. After you take out the first one, there's a longer delay before the 'take out' button becomes interactable again, which is why this Sleep is larger than the others.
Click, 453 223 ; refine Sleep 150 Click, 466 284 ; next Sleep 150
Factories have a variety of different windows so you'll need to make sure all the x/y coords are correct. My usual monitor is 1920x1080 and I have tried not to mess with the UI window positions too much, but I know they're not default any more.
; START QUANT BLOCK Click, 300 260 ; select quantity Sleep 150 Send 0 ; add a zero (1 -> 10) Sleep 150 ; END QUANT BLOCK
There are a number of ways you could manipulate this block if you so chose, but the way it's set up is for 10x refines in order to take advantage of the 1.1x refine multiplier (refine 10, get 11) while still doing a large enough number of refine operations to feel like I'm chipping away at my refining skills. Normally I save this for TCC or luna; if it's steel I'll often do it all at once.
Click, 374 544 ; start Sleep 3000 ; WAIT TIME VARIES
As the note says, it's hard to time this one specifically because different metals refine for different lengths of time, unlike mining. So I just have it loop repeatedly, and catch the confirmation on the next line. It used to be a much shorter sleep time, but I almost locked myself into a loop that way; 3 seconds allows enough time to get to the taskbar and manually pause the script (there is now a hotkey for that, you may notice).
Click, 1100 565 ; confirm success/fail Sleep 150 } } return
No additional notes here, it's the end of a loop just like any other.
Ctrl Shift 3: Weapon Crafting Loop
(todo 3-6 and p: getting sleepy)
Ctrl Shift 4: MS Crafting Single
Ctrl Shift 5: MS Dismantling Single
Ctrl Shift 6: MS Crafting/Dismantling Loop
Ctrl Shift P: Pause
Full script
Copy this entire section, starting with the header, into a text file and save it as any_name_you_want.ahk
and you'll have the script as it is on my computer. As noted in the sections above though, you'll probably need to change values and/or move windows around before it works properly for you.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. #Warn ; Enable warnings to assist with detecting common errors. #SingleInstance, Force #Persistent SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. ^+1:: ; miner if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop { Click, 421 1037 ; get bar Sleep 150 Send /mine{Enter} Sleep 12500 ; wait for mining Click, 1063 577 ; OK (1 item) Sleep 50 Click, 1063 586 ; OK (2 item) Sleep 50 Click, 1063 595 ; OK (3 items) Sleep 50 Click, 1063 604 ; OK (4 items) Sleep 50 Click, 1063 613 ; OK (5 items) Sleep 50 Click, 1063 622 ; OK (6 items) Sleep 150 } } return ^+2:: ; smelt 10x loop if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop { Click, 971 150 2 ; open factory Sleep 150 Click, 453 190 ; take out 1 Sleep 650 Click, 453 190 ; take out 2 Sleep 150 Click, 453 223 ; refine Sleep 150 Click, 466 284 ; next Sleep 150 ; START QUANT BLOCK Click, 300 260 ; select quantity Sleep 150 Send 0 ; add a zero (1 -> 10) Sleep 150 ; END QUANT BLOCK Click, 374 544 ; start Sleep 3000 ; WAIT TIME VARIES Click, 1100 565 ; confirm success/fail Sleep 150 } } return
^+3:: ; make weapon if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop { Click, 971 150 2 ; open factory Sleep 150 Click, 438 171 ; take out Sleep 150 Click, 438 255 ; develop Sleep 150 Click, 1112 790 ; next Sleep 150 Click, 1160 620 ; start Sleep 3000 ; WAIT TIME VARIES Click, 1080 570 ; confirm success/fail Sleep 150 } } return ^+4:: ; make vehicle single if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient Click, 1109 567 ; confirm previous action Sleep 150 Click, 971 150 2 ; open factory Sleep 150 Click, 1215 292 ; take out Sleep 150 Click, 1215 435 ; develop Sleep 150 Click, 1235 651 ; next Sleep 150 Click, 377 472 ; start } return
^+5:: ; dismantle vehicle single if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient Click, 1109 567 ; confirm previous action Sleep 150 Click, 971 150 2 ; open factory Sleep 150 Click, 1215 370 ; dismantle Sleep 150 Click, 377 335 ; next } return ^+6:: ; make/dismantle vehicle if not WinExist("UCClient") { MsgBox faildetect return } else { WinActivate, UCClient while WinActive("UCClient") and !GetKeyState("q") ; hold Q to terminate at the end of a loop { Click, 1109 567 ; confirm previous action Sleep 150 Click, 971 150 2 ; open factory Sleep 150 Click, 1215 292 ; take out Sleep 150 Click, 1215 435 ; develop Sleep 150 Click, 1235 651 ; next Sleep 150 Click, 377 472 ; start Sleep 13000 Click, 1109 567 ; confirm previous action Sleep 150 Click, 971 150 2 ; open factory Sleep 150 Click, 1215 370 ; dismantle Sleep 150 Click, 377 335 ; next Sleep 13000 } } return ^+p::Pause