Bin deinen Code mal kurz überflogen, daher generelles Zeug:
Nutze wenn möglich Singleton bei solchen Tools.
Code:
#include <Misc.au3>
_Singleton(@ScriptName)
Damit immer nur eine Instanz läuft.
Den wenn die Leute so "blöd" sind es zwei mal zu öffnen dann funktioniert nur bei einer die Hotkeys (entsprechend der Exit hotkey) , was etwas unschön ist und mit Pech Probleme erzeugt.
Konfigurierbare Hotkeys finde ich in jedem fall ne super Idee, hab ich meist auch hardcoded.
u.U. musst du abprüfen das keine Doppelt Belegt sind, falls jemand so blöd ist und das eingibt (dann gilt nur der letzte Hotkey, der andere hat keine Funktion).
Das Tool sollte nur laufen wenn Diablo III auch offen ist ; beendet man Diablo III macht es Sinn das Tool gleich mit zu beenden.
Entsprechend bietet es sich an wenn du im While 1 einfach "While WinExists" machst, das sorgt entsprechend für eine schnelle einfache Lösung.
Du benutzt blockinput, was "gut" ist, beachte aber das man dazu Adminrechte benötigt.
Entsprechend macht es Sinn einen "#requireAdmin" hinzuzufügen, damit die Leute das auch richtig machen.
send("{SPACE}") soll das dafür sorgen, dass das Inventar geschlossen wird ?
Bin grad auf Arbeit und habe kein D3 hier, aber wenn "ja" gut so.
Die sleeps halte ich für unnötig an der Stelle, aber u.U. haben die ja einen Zweck.
Warum ein MouseMove ? Ergibt sich mir nicht warum das benötigt wird.
Nutze wenns geht "ControllClick" anstatt MouseClick, das ist einfach klar "superior". Sendet den Befehl direkt an das angegebene Controll und ist wohl auch einfach schneller (siehe dazu meinen Referenz Code, der macht das hoffentlich deutlich, ansonsten F1 in AutoIT sollte auch helfen).
Größter Vorteil von ControllClick, die Maus selbst wird nicht bewegt, es werden nur die Befehle gesendet, dadurch kann der Nutzer eigentlich tun was er will (sollte trotzdem BlockInput sein, den das macht das Macro einfach kaputt wenn der User dazwischen funkt).
Logging würde ich in jedem fall "optional" machen.
In meiner Referenz siehst du eine Alternative für das Macro.
Anstelle mit Rechtsklick verwende ich eine linksklick und füge die Items direkt dort ein wo sie hinsollen.
Das macht die Sache mit "Alt" unnötig und die Recorder Funktion erlaubt es mit jeder Auflösung seine Einstellung zu tätigen.
Die Option mit Rechtsklick und Alt funktioniert natürlich auch, im Detail müsste man das stärker Vergleichen ob es unterschiede gibt (nicht nur Geschwindigkeit, sondern Sicherheit auf Fehler, bzw. wie das Spiel in bestimmten Situation anders handelt, wenn vielleicht einmal eine 2h Waffe verwendet wird und im magic Set je 2x Einhand usw.).
Mein Recorder speichert einfach .ini files mit den Koordinaten als Namen die Auflösung.
Generell kann man einiges tun damit das Tool einfach "schöner" funktioniert und mehr Optionen zur Verfügung stehen, den die "eigentliche" Funktion des EquipWechsel ist ja ziemlich trivial.
Nur als Referenz Code:
RECORDER.au3
Code:
#include <Misc.au3>
_Singleton(@ScriptName)
AutoItSetOption ( "MouseCoordMode", 2)
Global $winTitle = "Diablo III"
Global $hWnd = WinGetHandle($winTitle)
HotKeySet("{ESC}", "_exit")
Func _exit()
Exit 0
EndFunc
Global $iniFile = getIniFileName()
Func getIniFileName()
local $clientSize = WinGetClientSize($winTitle)
local $name = "COORD_" & $clientSize[0] & "x" & $clientSize[1] & ".ini"
return $name
EndFunc
Global $item_names[13] = ["Helm","Shoulder","Body","Hand","Arm","Leg","Boots","Belt","Amulet","LeftRing","RightRing","LeftWeapon","RightSupport"]
Global $curCoordCount = 0
Global $coordMode = "Inventory"
HotKeySet("{Right}", "_countNext")
Func _countNext()
if ($coordMode == "Inventory") Then
$coordMode = "BodyPart"
Else
$curCoordCount+=1
if ($curCoordCount >= UBound($item_names)) Then
$curCoordCount = 0
EndIf
$coordMode = "Inventory"
EndIf
EndFunc
HotKeySet("{Left}", "_countBack")
Func _countBack()
if ($coordMode == "Inventory") Then
$curCoordCount-=1
if ($curCoordCount < 0) Then
$curCoordCount = UBound($item_names)-1
EndIf
$coordMode = "BodyPart"
Else
$coordMode = "Inventory"
EndIf
EndFunc
HotKeySet("{+}", "_addCoord")
Func _addCoord()
local $mousePos = MouseGetPos()
local $x = $mousePos[0]
local $y = $mousePos[1]
if ($coordMode == "Inventory") Then
IniWrite($iniFile, $item_names[$curCoordCount], $coordMode & "_x", $x)
IniWrite($iniFile, $item_names[$curCoordCount], $coordMode & "_y", $y)
Else
IniWrite($iniFile, $item_names[$curCoordCount], $coordMode & "_x", $x)
IniWrite($iniFile, $item_names[$curCoordCount], $coordMode & "_y", $y)
EndIf
_countNext()
EndFunc
HotKeySet("{-}", "_removeCoord")
Func _removeCoord()
_countBack()
if ($coordMode == "Inventory") Then
IniDelete($iniFile, $item_names[$curCoordCount], $coordMode & "_x")
IniDelete($iniFile, $item_names[$curCoordCount], $coordMode & "_y")
Else
IniDelete($iniFile, $item_names[$curCoordCount], $coordMode & "_x")
IniDelete($iniFile, $item_names[$curCoordCount], $coordMode & "_y")
EndIf
EndFunc
ToolTip("RECORDER READY",0,0)
While (WinExists($winTitle))
local $mousePos = MouseGetPos()
ToolTip("Item: " & $item_names[$curCoordCount] & " : " & $coordMode & @CRLF & _
"MousePos[" & $mousePos[0] & ", " & $mousePos[1] & "]",0,0)
sleep(50)
WEnd
AutoEquipper.au3
Code:
#RequireAdmin
#include <Misc.au3>
_Singleton(@ScriptName)
AutoItSetOption ( "MouseCoordMode", 2)
Global $winTitle = "Diablo III"
Global $hWnd = WinGetHandle($winTitle)
HotKeySet("{ESC}", "_exit")
Func _exit()
Exit 0
EndFunc
Global $iniFile = getIniFileName()
Func getIniFileName()
local $clientSize = WinGetClientSize($winTitle)
local $name = "COORD_" & $clientSize[0] & "x" & $clientSize[1] & ".ini"
return $name
EndFunc
Global $item_names[13] = ["Helm","Shoulder","Body","Hand","Arm","Leg","Boots","Belt","Amulet","LeftRing","RightRing","LeftWeapon","RightSupport"]
Global $Inventory_coords[13][2]
Global $BodyPart_coords[13][2]
Func _readCoordsFromIniFile()
if (NOT FileExists($iniFile)) Then
MsgBox("", "ERROR", $iniFile & " not found. Use Record first")
_exit()
EndIf
local $sectionNames = IniReadSectionNames($iniFile)
if (UBound($sectionNames) < 1) Then
local $ret
$ret = MsgBox(1, $iniFile & " ERROR", $iniFile & " is empty, delete it ?")
if ($ret == 1) Then
FileDelete($iniFile)
_exit()
Else
_exit()
EndIf
EndIf
ReDim $Inventory_coords[UBound($sectionNames)][2]
ReDim $BodyPart_coords[UBound($sectionNames)][2]
for $i = 1 to UBound($sectionNames)-1
$Inventory_coords[$i][0] = IniRead($iniFile, $sectionNames[$i], "Inventory_x", 0)
$Inventory_coords[$i][1] = IniRead($iniFile, $sectionNames[$i], "Inventory_y", 0)
$BodyPart_coords[$i][0] = IniRead($iniFile, $sectionNames[$i], "BodyPart_x", 0)
$BodyPart_coords[$i][1] = IniRead($iniFile, $sectionNames[$i], "BodyPart_y", 0)
Next
EndFunc
HotKeySet("{F1}", "_equip")
Func _equip()
BlockInput(1)
ControlSend($winTitle, "", $hWnd, "s")
sleep(100)
ControlSend($winTitle, "", $hWnd, "c")
for $i = 1 to UBound($Inventory_coords)-1
ControlClick($winTitle, "", $hWnd, "left", 1, $Inventory_coords[$i][0], $Inventory_coords[$i][1])
ControlClick($winTitle, "", $hWnd, "left", 1, $BodyPart_coords[$i][0], $BodyPart_coords[$i][1])
Next
ControlSend($winTitle, "", $hWnd, "c")
BlockInput(0)
EndFunc
HotKeySet("{F2}", "_unequip")
Func _unequip()
BlockInput(1)
ControlSend($winTitle, "", $hWnd, "s")
sleep(100)
ControlSend($winTitle, "", $hWnd, "c")
for $i = 1 to UBound($Inventory_coords)-1
ControlClick($winTitle, "", $hWnd, "left", 1, $BodyPart_coords[$i][0], $BodyPart_coords[$i][1])
ControlClick($winTitle, "", $hWnd, "left", 1, $Inventory_coords[$i][0], $Inventory_coords[$i][1])
Next
ControlSend($winTitle, "", $hWnd, "c")
BlockInput(0)
EndFunc
_readCoordsFromIniFile()
While (WinExists($winTitle))
sleep(500)
WEnd