Тема: AHK: Использование движений мышью для выбора оружия
Хочу поделиться скриптом которым пользуюсь в играх для быстрого выбора оружия. Он позволяет использовать сочетание горячей клавиши и движение мышью (влево-вправо,вверх-вниз). Так же данный скрипт блокирует движение камеры во время выбора. В коде я создаю таймер 1 мс, для этого используется драйвер в папке WaitableTimer, его необходимо разблокировать.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Использование мыши для выбора оружия ;;;
;;; Claus555, 14/02/2018г. ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Данный скрипт позволяет применять движения мыши (влево-вправо,вверх-вниз)
;в сочетании с горячей клавишей для подтверждения выбора.
;Если взять стандартную мышь, то на ней присутствует 4 и 5 кнопки мыши
;-это два возможных действия. Но если к нажатой кнопке добавить движение мышью,
;получится 2х4=8 действий(где 4-четыре направления мыши).
;Вместо 2 получаем 8 клавиш!
#SingleInstance force
#Persistent
;меняем раскладку на английскую
ControlGetFocus, CtrlFocus, % "ahk_id" WinExist("A")
PostMessage, 0x50, 0, 0x4090409, %CtrlFocus% ;английский
setkeydelay -1 ; нет пауз между нажатиями
BasicData:=["XButton1","XButton2"]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Создание основного таймера ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include CLR.ahk
asm:=CLR_LoadLibrary("WaitableTimer\WaitableTimer.dll")
wt:=asm.CreateInstance("WaitableTimer")
MyTimer := wt.Create(Func("Entry"), 1)
MyTimer.Start()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MouseDelta ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SMX:=OldSMX:=SMY:=OldSMY:=DSX:=DSY:=0
#include MouseDelta.ahk
md:=new MouseDelta("MouseEvent").Start()
md.SetState(0)
SetTimer, SpeedMouse, 100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Основной цикл ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
S1:
Loop % BasicData.MaxIndex() ;просмотр всех элементов массива
{
variable:=BasicData[A_Index]
if variable in XButton1,XButton2
PS:="P" ;определяем физическое состояние
else
PS:="" ;логическое
%variable%:=GetKeyState(BasicData[A_Index],PS)
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Выбор оружия ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (XButton1 and !MB4)
md.SetState(1),MB4:=1
if (!XButton1 and MB4)
md.SetState(0),MB4:=0,MV4:=0
R1:=(MV4=1)?1:0,ST1:=T(D("R1"),"ST1",100),PRESS40(ST1,"vk31")
R2:=(MV4=2)?1:0,ST2:=T(D("R2"),"ST2",100),PRESS40(ST2,"vk32")
R3:=(MV4=3)?1:0,ST3:=T(D("R3"),"ST3",100),PRESS40(ST3,"vk33")
R4:=(MV4=4)?1:0,ST4:=T(D("R4"),"ST4",100),PRESS40(ST4,"vk34")
if (XButton2 and !MB5)
md.SetState(1),MB5:=1
if (!XButton2 and MB5)
md.SetState(0),MB5:=0,MV5:=0
R5:=(MV5=5)?1:0,ST5:=T(D("R5"),"ST5",100),PRESS40(ST5,"vk35")
R6:=(MV5=6)?1:0,ST6:=T(D("R6"),"ST6",100),PRESS40(ST6,"vk36")
R7:=(MV5=7)?1:0,ST7:=T(D("R7"),"ST7",100),PRESS40(ST7,"vk37")
R8:=(MV5=8)?1:0,ST8:=T(D("R8"),"ST8",100),PRESS40(ST8,"vk38")
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; "Невидимые"(экранированные) клавиши ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*XButton1::Return
*XButton2::Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Завершение работы скрипта ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
End::ExitApp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Таймер-вход ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Entry(){
Gosub, S1
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Физическое нажатие(клавиатура-40мс повтор) ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRESS40(X,Y,Z="P")
{
global
if (X and !%Z%1%Y%)
{
send {Blind}{%Y% Down}
%Z%1%Y%:=1,%Z%2%Y%:=A_TickCount
}
if (X and A_TickCount-%Z%2%Y%>=40)
{
send {Blind}{%Y% Down}
%Z%2%Y%:=A_TickCount
}
if (!X and %Z%1%Y%)
{
send {Blind}{%Y% Up}
%Z%1%Y%:=0
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Срабатывание ;;;; ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
D(X)
{
local Z
Z:=(%X%!=d%X% and %X%)?1:0,d%X%:=%X%
Return Z
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Таймер ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
T(X,Y,V)
{
global
if (X and !T1%Y%)
T1%Y%:=1,T2%Y%:=A_TickCount
if (T2%Y%="" or A_TickCount-T2%Y%>=V)
T1%Y%:=0
Return T1%Y%
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Мышь-блокировка камеры ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MouseEvent(MouseID, x := 0, y := 0){
global
if (MouseID)
{
SMX+=x,SMY+=y
DllCall("mouse_event",uint,1,int,-x,int,-y,uint,0,int,0)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Мышь-режим джойстика ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SpeedMouse:
DSX:=SMX-OldSMX,OldSMX:=SMX,DSY:=SMY-OldSMY,OldSMY:=SMY
if (MB4 and abs(DSX)>abs(DSY))
{
if (DSX>1 and !MV4) ;смещение вправо
MV4:=3
if (DSX<-1 and !MV4) ;смещение влево
MV4:=1
}
else if MB4
{
if (DSY>1 and !MV4) ;смещение вниз
MV4:=4
if (DSY<-1 and !MV4) ;смещение вверх
MV4:=2
}
if (MB5 and abs(DSX)>abs(DSY))
{
if (DSX>1 and !MV5) ;смещение вправо
MV5:=7
if (DSX<-1 and !MV5) ;смещение влево
MV5:=5
}
else if MB5
{
if (DSY>1 and !MV5) ;смещение вниз
MV5:=8
if (DSY<-1 and !MV5) ;смещение вверх
MV5:=6
}
Return