Last active
August 17, 2023 23:46
-
-
Save asaf400/0b238b9ea567c6096f8b666888d6705c to your computer and use it in GitHub Desktop.
Elite Dangerous Fire Groups keybinding with AutoHotKey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; written by https://github.com/asaf400 | |
; version 0.3 | |
; Settings | |
gameLocation := "H:\SteamLibrary\steamapps\common\Elite Dangerous" | |
; Change log file location | |
global LogFile := "H:\SteamLibrary\steamapps\common\Elite Dangerous\AX.log" | |
; in-game next group button | |
global nextButton := "n" | |
global targetButton := "t" | |
global modeButton := "m" | |
; game window Title | |
global gameTitle := "Elite - Dangerous (CLIENT)" | |
#Persistent | |
SetKeyDelay, 50 | |
#SingleInstance Force | |
I_Icon = %gameLocation%\ED.ico | |
IfExist, %I_Icon% | |
Menu, Tray, Icon, %I_Icon% | |
;return | |
global supportedActionsConfig := {} | |
supportedActionsConfig.Collector := {type: "Click", target: "None", mode: "Either"} | |
supportedActionsConfig.Decontamination := {type: "Click", target: "None", mode: "Either"} | |
supportedActionsConfig.Research := {type: "Click", target: "Preselected", mode: "Either"} | |
supportedActionsConfig.Repair := {type: "Click", target: "None", mode: "Either"} | |
supportedActionsConfig.XenoScanner := {type: "Hold", target: "Preselected", hold: 10000, mode: "Either"} | |
supportedActionsConfig.FieldNeuralyzer := {type: "Click", target: "None", mode: "Combat"} | |
supportedActionsConfig["D-Scanner"] := {type: "Hold", target: "Preselected", hold: 5500, mode: "Analysis"} | |
supportedActionsConfig["Comp.Scanner"] := {type: "Hold", target: "Preselected", hold: 5000, mode: "Analysis"} | |
; Change these values according to your game's settings | |
global fireGroups := [] | |
fireGroups.Insert({Primary: "Weapon", Secondary: "Weapon"}) | |
fireGroups.Insert({Primary: "Collector", Secondary: "Decontamination"}) | |
fireGroups.Insert({Primary: "Research", Secondary: "Repair"}) | |
fireGroups.Insert({Primary: "XenoScanner", Secondary: "FieldNeuralyzer"}) | |
fireGroups.Insert({Primary: "D-Scanner", Secondary: "Comp.Scanner"}) | |
global currentFireGroup := 1 | |
global currentMode := "Combat" | |
; Caculate how many times to press 'next group' button (defaults n) | |
DistanceFromGroup(action) | |
{ | |
Loop, % fireGroups.Length() | |
{ | |
index := A_Index | |
For key, value in fireGroups[index] | |
{ | |
if (value == action) | |
{ | |
return, {index: index, key: key} | |
} | |
} | |
} | |
} | |
; Press the 'next group' button N amount | |
MoveToGroup(presses) | |
{ | |
Loop, % presses | |
{ | |
Send % nextButton | |
Sleep, 100 | |
} | |
} | |
; Caculate overflow location for returning back (used for debugging only) | |
LoopAround(change) | |
{ | |
newGroup := currentFireGroup+change | |
if (newGroup == fireGroups.Length()+1) | |
{ | |
currentFireGroup := 1 | |
FileAppend currentFireGroup '%currentFireGroup%' `n, % LogFile | |
} | |
else | |
{ | |
FileAppend, unknown condition `n, % LogFile | |
FileAppend, %newGroup% `n, % LogFile | |
} | |
} | |
ChangeMode(mode){ | |
if (mode != currentMode and mode != "Either") | |
{ | |
Send % modeButton | |
} | |
} | |
PerformFire(clickType) | |
{ | |
clickb := "" | |
if (clickType == "Primary") | |
{ | |
FileAppend, Clicking LMB `n, % LogFile | |
clickb := "left" | |
} | |
else if (clickType == "Secondary") | |
{ | |
FileAppend, Clicking RMB `n, % LogFile | |
clickb := "right" | |
} | |
MouseClick, %clickb% | |
} | |
PerformHold(clickType, groupIndex, action) | |
{ | |
delay := supportedActionsConfig[action].hold | |
mode := supportedActionsConfig[action].mode | |
FileAppend, Holding click for '%delay%' `n, % LogFile | |
clickb := "" | |
if (clickType == "Primary") | |
{ | |
FileAppend, Clicking LMB `n, % LogFile | |
clickb := "Left" | |
} | |
else if (clickType == "Secondary") | |
{ | |
FileAppend, Clicking RMB `n, % LogFile | |
clickb := "Right" | |
} | |
ChangeMode(mode) | |
Click, %clickb%, , , , Down | |
Sleep, % delay | |
Click, %clickb%, , , , Up | |
ChangeMode(mode) | |
} | |
PerformAction(action) | |
{ | |
; Sadly, it seems that ControlClick which should allow sending keys\clicks to a non-active window | |
; doesn't work with ED, most likely the devs have blocked non-raw device input maybe, or maybe DirectX has.. | |
; Any ways, this makes sure that at least the keys are not doing anything if ED is not active, but it must remain the active window during action execution! | |
if not WinActive(gameTitle) | |
{ | |
return | |
} | |
FileAppend, Searching Firegroup for '%action%' `n, % LogFile | |
moveTo := DistanceFromGroup(action) | |
moveToIndex := moveTo.index | |
moveToKey := moveTo.key | |
moveToPresses := moveToIndex - 1 | |
FileAppend, Scrolling to Firegroup '%moveToIndex%' by pressing 'n' '%moveToPresses%' times `n, % LogFile | |
MoveToGroup(moveToPresses) | |
currentFireGroup += moveToPresses | |
FileAppend, Mouseclicking on currentFireGroup '%currentFireGroup%' `n, % LogFile | |
if (supportedActionsConfig[action].target == "None") | |
{ | |
Send % targetButton | |
} | |
actionType := supportedActionsConfig[action].type | |
if (actionType == "Click") | |
{ | |
PerformFire(moveToKey) | |
} | |
else if (actionType == "Hold") | |
{ | |
PerformHold(moveToKey, moveToIndex, action) | |
} | |
FileAppend, returning to DefaultFireGroup `n, % LogFile | |
moveBack := FireGroups.Length() - moveToIndex + 1 | |
MoveToGroup(moveBack) | |
LoopAround(moveBack) | |
return | |
} | |
; define hotkeys as actions | |
~5:: | |
PerformAction("Collector") | |
return | |
~6:: | |
PerformAction("Decontamination") | |
return | |
~7:: | |
PerformAction("Repair") | |
return | |
~8:: | |
PerformAction("Research") | |
return | |
~9:: | |
PerformAction("XenoScanner") | |
return | |
~0:: | |
PerformAction("FieldNeuralyzer") | |
return | |
~\:: | |
PerformAction("D-Scanner") | |
return |
0.3:
A more generic and easily modifable settings has been introduced in: supportedActionsConfig
Supporting action type, targeting*, mode selection.
* targeting is a bit flawed since there's no in-game button to untarget
, so it's up to the user to look in space to an empty region,
in order to deploy limpets that conflict with selected target.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
0.2:
Added active window protection - will only perform the actions if the ED window is focused.
Added ability to hold-down a button,
like for Discovery-Scanner or Comp.Scanner
fixed logging, for some reason, it didn't want to use the gameLocation vairable..