Looking for feedback on my code

Ask gaming related questions (AHK v1.1 and older)
User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Looking for feedback on my code

Post by t3h m00kz » 07 Sep 2022, 00:55

New here, wanted to ask for feedback on my script. It functions, it works, haven't run into any severe bugs, and it does what I need it to. But I'd like to know if I'm doing anything weird or if there are any ways to optimize/simplify what I've done here.

Key features include:
- UI Displays pressed inputs
- Dynamic animated Crosshair with separate states for RMB held. Fully animated with a cross, dot, and circle, grow, snap, and decay states
- "Fiiring Mode" system that allows cycling through default, auto, burst (timed default), burst (looped auto), semi-auto, complete with overlay
- Hold prone system (Press and hold to enter prone, release to exit prone, tap prone to toggle)
- Hold crouch to prone (Functional, but I don't use it)
- Hold space to spam jump (I.E. infinite scroll wheel style)
-Hotkeys for refreshing and exiting

Graphics and Audio resources here:
Graphics
Audio

Code: Select all

;;;;;;;;;;;;;;;;;;;;
;; INITIALIZATION ;;
;;;;;;;;;;;;;;;;;;;;
#NoEnv
#Persistent
#SingleInstance,		Force
#MaxHotkeysPerInterval	99000000
#HotkeyInterval			99000000
#KeyHistory				0
#InstallKeybdHook
#UseHook
#MenuMaskKey			vk07
ListLines				Off
SetBatchLines,			-1
SetKeyDelay,			-1,	-1
SetMouseDelay,			-1
SetDefaultMouseSpeed	, 0
SetWinDelay,			-1
SetControlDelay,		-1
;SendMode				Input
DllCall("ntdll\ZwSetTimerResolution","Int",5000,"Int",1,"Int*",MyCurrentTimerResolution) ;setting the Windows Timer Resolution to 0.5ms, THIS IS A GLOBAL CHANGE
SetTitleMatchMode,		2
SetTitleMatchMode,		fast

;Set Icon
	IfExist, %A_ScriptDir%\graphics\Icon.png
	{
	Menu,Tray,Icon, %A_ScriptDir%\graphics\Icon.png
	}

;;;;;;;;;;;;;;;;;;;
;;GLOBAL SETTINGS;;
;;;;;;;;;;;;;;;;;;;
;Set default variables to globals
SetDefaults(){
    global
	}

;Initialize defaults
loadUI()
checkWindow()

;Time intervals
global framesPerSecond			:= "60" ;Game's FPS
global gameTick					:= ((1/framesPerSecond)*1000) ;One gametick / frame

;TOGGLES - Features
global firingMode				:= "Default"		;Currently active firing mode
global firingModeHip			:= "Default"		;Firing mode from the hip
global firingModeADS			:= "Default"		;Firing mode while ADS
global enableBHop				:= "1"				;Enable space bar spam
global enableHoldProne			:= "1"				;Enable hold prone
global enableHoldToMelee		:= "1"				;Enable hold quick melee to switch to melee weapon
global enableHoldToProne		:= "0"				;Enable hold crouch to prone (only if toggle crouch)
global enableAutoBreath			:= "0"				;Enable auto breath hold for snipers
global enableAutoMark			:= "0"				;Enable AutoMark system

;TOGGLES - UI display
global showUI					:= "1"				;Display the UI
global showUI_Inputs			:= "0"				;Display the input UI
global showUI_Directionals		:= "0"				;Display the directional input UI
global showUI_InputBG			:= "0"				;Display the input UI backdrop
global showUI_firingMode		:= "1"				;Display the firing mode
global showUI_Ret				:= "1"				;Display the crosshair
global showUI_RetCross			:= "1"				;Display the crosshair cross
global showUI_RetDot			:= "1"				;Display the crosshair dot
global showUI_RetCircle			:= "1"				;Display the crosshair circle
global showUI_RetAnimate		:= "1"				;Display the crosshair animiations
global retOffsetX				:= "0"				;Ret offset X
global retOffsetY				:= "0"				;Ret offset Y

;AutoMark system
global markOut					:= "0"				;AutoMark is out
global autoMarkCooldown			:= "300"			;AutoMark Cooldown in ticks

;Burst fire system 1
global burst1FireMax			:= "3"				;The number of times burstfire will loop
global burst1FireCount			:= "0"				;The number of times burstfire has looped
global isBursting1				:= "0"				;The player is firing a burstfire shot

;Burst fire system 2
global burst2FireMax			:= "3"				;The number of times burstfire will loop
global burst2FireCount			:= "0"				;The number of times burstfire has looped
global isBursting2				:= "0"				;The player is firing a burstfire shot

;Input systems
global isBHopping				:= "0"				;The player is bhopping
global bHopFirstHop				:= "0"				;Handles the first hop before beginning bhop spam
global bHopSwitch				:= "0"				;Bhop down/up flipper
global isHoldingAim				:= "0"				;The player is holding aim
global isHoldingCrouch			:= "0"				;The player is holding crouch
global isHoldingProne			:= "0"				;The player is holding prone
global chargedProne				:= "0"				;(Hold to Prone) The player has charged prone
global isProning				:= "0"				;(Hold to Prone) The player is proning
global proneCount				:= "0"				;(Hold to Prone) Prone Counter
global proneCountMax			:= "6"				;(Hold to Prone) Maximum number of prones to spam
global unProneCount				:= "0"				;(Hold to Prone) UnProne Counter
global unProneCountMax			:= "6"				;(Hold to Prone) Maximum number of unprones to spam
global isHoldingMelee			:= "0"				;The player is holding melee
global chargedMelee				:= "0"				;The player has charged melee
global cancelMelee				:= "0"				;Cancel the melee
global isHoldingFiringMode		:= "0"				;The player is holding firing mode switch
global chargedFiringMode		:= "0"				;The player has charged firing mode switch
global cancelFiringMode			:= "0"				;Cancel the firing mode switch
global firingModeSound			:= ""				;The firing mode sound to play
global isHoldingFire			:= "0"				;The player is holding fire
global isHoldingSprint			:= "0"				;The player is holding sprint
global isHoldingJump			:= "0"				;The player is holding jump

;UI systems
global scrX						:= A_ScreenWidth
global scrY						:= A_ScreenHeight
global inputUIGap				:= "50"				;movement key UI gap
global windowSelected			:= "1"				;Expected game window is in focus

;UI Crosshair animation system
global retWidthOutline								;Ret cross outline width
global retLengthOutline								;Ret cross outline length
global retDotOutlineSize							;Ret dot outline size
global doneGrow										;Ret animation is finished growing
global doneDecay									;Ret animation is finised decaying
global aniFrameRate									;Ret framerate subdivision
global aniOnResetShowCross							;Show the cross on animation reset
global aniOnResetShowDot							;Show the dot on animaton reset
global retGap										;Ret crosshair center gap size
global retLength									;Ret crosshair bar lengths
global retWidth										;Ret crosshair bar widths
global retOutline									;Ret crosshair bar outline size
global retDotSize									;Ret dot size
global retDotOutline								;Ret dot outline size
global retCircleRadius								;Ret circle radius
global retCircleThickness							;Ret circle thickness
global retCircleOutline								;Ret circle outline size
global aniRateGrowGap								;Grow rate for ret crosshair center gap
global aniRateGrowLength							;Grow rate for ret crosshair bar length
global aniRateGrowWidth								;Grow rate for ret crosshair bar widths
global aniRateGrowOutline							;Grow rate for ret crosshair bar outlin
global aniRateGrowDotSize							;Grow rate for ret dot size
global aniRateGrowDotOutline						;Grow rate for ret dot outline size
global aniRateGrowCircleRadius						;Grow rate for ret circle radius
global aniRateGrowCircleThickness					;Grow rate for ret circle thickness
global aniRateGrowCircleOutline						;Grow rate for ret circle outline size
global aniRateDecayGap								;Decay rate for ret crosshair center gap
global aniRateDecayLength							;Decay rate for ret crosshair bar length
global aniRateDecayWidth							;Decay rate for ret crosshair bar widths
global aniRateDecayOutline							;Decay rate for ret crosshair bar outlin
global aniRateDecayDotSize							;Decay rate for ret dot size
global aniRateDecayDotOutline						;Decay rate for ret dot outline size
global aniRateDecayCircleRadius						;Decay rate for ret circle radius
global aniRateDecayCircleThickness					;Decay rate for ret circle thickness
global aniRateDecayCircleOutline					;Decay rate for ret circle outline size
global aniMinGap									;Minimum value for ret crosshair center gap
global aniMinLength									;Minimum value for ret crosshair bar length
global aniMinWidth									;Minimum value for ret crosshair bar widths
global aniMinOutline								;Minimum value for ret crosshair bar outlin
global aniMinDotSize								;Minimum value for ret dot size
global aniMinDotOutline								;Minimum value for ret dot outline size
global aniMinCircleRadius							;Minimum value for ret circle radius
global aniMinCircleThickness						;Minimum value for ret circle thickness
global aniMinCircleOutline							;Minimum value for ret circle outline size
global aniMaxGap									;Maximum value for ret crosshair center gap
global aniMaxLength									;Maximum value for ret crosshair bar length
global aniMaxWidth									;Maximum value for ret crosshair bar widths
global aniMaxOutline								;Maximum value for ret crosshair bar outlin
global aniMaxDotSize								;Maximum value for ret dot size
global aniMaxDotOutline								;Maximum value for ret dot outline size
global aniMaxCircleRadius							;Maximum value for ret circle radius
global aniMaxCircleThickness						;Maximum value for ret circle thickness
global aniMaxCircleOutline							;Maximum value for ret circle outline size
global aniSnapStepGap								;Snap amount for ret crosshair center gap
global aniSnapStepLength							;Snap amount for ret crosshair bar length
global aniSnapStepWidth								;Snap amount for ret crosshair bar widths
global aniSnapStepOutline							;Snap amount for ret crosshair bar outlin
global aniSnapStepDotSize							;Snap amount for ret dot size
global aniSnapStepDotOutline						;Snap amount for ret dot outline size
global aniSnapStepCircleRadius						;Snap amount for ret circle radius
global aniSnapStepCircleThickness					;Snap amount for ret circle thickness
global aniSnapStepCircleOutline						;Snap amount for ret circle outline size

;Image files
global imgB					:= A_ScriptDir . "\graphics\pixel_BLACK.png"	;1x1 pixel black
global imgW					:= A_ScriptDir . "\graphics\pixel_WHITE.png"	;1x1 pixel white
global imgFiringModeOff		:= A_ScriptDir . "\graphics\Modes\off.png"		;Firing Mode - Off (I.E. resetting to defaults)
global imgFiringModeAuto1	:= A_ScriptDir . "\graphics\Modes\auto1.png"	;Firing Mode - Auto1 (Default)
global imgFiringModeAuto2	:= A_ScriptDir . "\graphics\Modes\auto2.png"	;Firing Mode - Auto2 (Off/On switch)
global imgFiringModeBurst1	:= A_ScriptDir . "\graphics\Modes\burst1.png"	;Firing Mode - burst1 (Timer-based)
global imgFiringModeBurst2	:= A_ScriptDir . "\graphics\Modes\burst2.png"	;Firing Mode - burst2 (Looped shots)
global imgFiringModeSemi	:= A_ScriptDir . "\graphics\Modes\semi.png"		;Firing Mode - Semi-Auto

;UI colors
global UIRGB				:= "111111"		;Default (transparent)
global UIKeyOff				:= "111111"		;Input key off color
global UIKeyOn				:= "00FF00"		;Input key on color

;;;;;;;;;;;;;;;;;;;;
;; TIME INTERVALS ;;
;;;;;;;;;;;;;;;;;;;;
tick(t:="1"){ ;Tick(ticks)
		ticks := gameTick*t
		return ticks
	}

wait(t:="1"){ ;Wait(ticks)
	ticks := (tick*t)
	DllCall("Sleep","UInt", %ticks%)
	return
	}

;;;;;;;;;;;;;;;;;;;;
;; USER INTERFACE ;;
;;;;;;;;;;;;;;;;;;;;
if showUI_Ret{ ;Reticle
	if showUI_RetCross{ ;Cross black outline
		Gui,	retUI_CROSSB:	Color,		%UIRGB%
		Gui		retUI_CROSSB:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretU_blackH +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretD_blackH +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretL_blackH +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretR_blackH +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretU_blackV +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretD_blackV +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretL_blackV +BackgroundTrans,	%imgB%
		Gui,	retUI_CROSSB:	Add,	Picture,	hwndretR_blackV +BackgroundTrans,	%imgB%
		WinSet, TransColor,	%UIRGB% 255
		}
	if showUI_RetDot{ ;Dot black outline
		Gui,	retUI_DOTB:	Color,		%UIRGB%
		Gui		retUI_DOTB:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		Gui,	retUI_DOTB:	Add,	Picture,	hwndretM_blackH +BackgroundTrans,	%imgB%
		Gui,	retUI_DOTB:	Add,	Picture,	hwndretM_blackV +BackgroundTrans,	%imgB%
		WinSet, TransColor,	%UIRGB% 255
		}
	if showUI_RetCircle{ ;Circle black outline
		Gui,	retUI_CIRCLEB:	Color,		000000
		Gui		retUI_CIRCLEB:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		WinGet, UICircleB
		}
	if showUI_RetCross{ ;Cross white body
		Gui,	retUI_CROSSW:	Color,		%UIRGB%
		Gui		retUI_CROSSW:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		Gui,	retUI_CROSSW:	Add,	Picture,	hwndretU_white +BackgroundTrans,	%imgW%
		Gui,	retUI_CROSSW:	Add,	Picture,	hwndretD_white +BackgroundTrans,	%imgW%
		Gui,	retUI_CROSSW:	Add,	Picture,	hwndretL_white +BackgroundTrans,	%imgW%
		Gui,	retUI_CROSSW:	Add,	Picture,	hwndretR_white +BackgroundTrans,	%imgW%
		WinSet, TransColor,	%UIRGB% 255
	}
	if showUI_RetDot{ ;Dot white body
		Gui,	retUI_DOTW:	Color,		%UIRGB%
		Gui		retUI_DOTW:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		Gui,	retUI_DOTW:	Add,	Picture,	hwndretM_white +BackgroundTrans,	%imgW%
		WinSet, TransColor,	%UIRGB% 255
		}
	if showUI_RetCircle{ ;Circle white body
		Gui,	retUI_CIRCLEW:	Color,		FFFFFF
		Gui		retUI_CIRCLEW:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20; +E0x02000000 +E0x00080000
		WinGet, UICircleW
		;WinSet, TransColor,	%UIRGB% 255
		}
	if showUI_RetCircle{ ;Globalize HWNDs and coodrinates
		global HWNDCircleB					:= UICircleB
		global HWNDCircleW					:= UICircleW
		global CircleB_Outer				:= "0"
		global CircleB_Inner				:= "0"
		global CircleW_Outer				:= "0"
		global CircleW_Inner				:= "0"
		global Circle_ULX					:= "0"
		global Circle_ULY					:= "0"
		global Circle_DRX					:= "0"
		global Circle_DRY					:= "0"
		global CircleB_Inner_ULX			:= "0"
		global CircleB_Inner_ULY			:= "0"
		global CircleB_Inner_DRX			:= "0"
		global CircleB_Inner_DRY			:= "0"
		global CircleB_Outer_ULX			:= "0"
		global CircleB_Outer_ULY			:= "0"
		global CircleB_Outer_DRX			:= "0"
		global CircleB_Outer_DRY			:= "0"
		global CircleW_Inner_ULX			:= "0"
		global CircleW_Inner_ULY			:= "0"
		global CircleW_Inner_DRX			:= "0"
		global CircleW_Inner_DRY			:= "0"
		global CircleW_Outer_ULX			:= "0"
		global CircleW_Outer_ULY			:= "0"
		global CircleW_Outer_DRX			:= "0"
		global CircleW_Outer_DRY			:= "0"
		}
	if showUI_RetCross{ ;Globalize height/width HWNDs and coordinates
		global retUp_blackH			:= retU_blackH
		global retDown_blackH		:= retD_blackH
		global retLeft_blackH		:= retL_blackH
		global retRight_blackH		:= retR_blackH
		global retUp_blackV			:= retU_blackV
		global retDown_blackV		:= retD_blackV
		global retLeft_blackV		:= retL_blackV
		global retRight_blackV		:= retR_blackV
		global retUp_white			:= retU_white
		global retDown_white		:= retD_white
		global retLeft_white		:= retL_white
		global retRight_white		:= retR_white
		global U_blackHX			:= "0"
		global U_blackHY			:= "0"
		global D_blackHX			:= "0"
		global D_blackHY			:= "0"
		global L_blackHX			:= "0"
		global L_blackHY			:= "0"
		global R_blackHX			:= "0"
		global R_blackHY			:= "0"
		global U_blackVX			:= "0"
		global U_blackVY			:= "0"
		global D_blackVX			:= "0"
		global D_blackVY			:= "0"
		global L_blackVX			:= "0"
		global L_blackVY			:= "0"
		global R_blackVX			:= "0"
		global R_blackVY			:= "0"		
		global U_whiteX				:= "0"
		global U_whiteY				:= "0"
		global D_whiteX				:= "0"
		global D_whiteY				:= "0"
		global L_whiteX				:= "0"
		global L_whiteY				:= "0"
		global R_whiteX				:= "0"
		global R_whiteY				:= "0"
		}
	if showUI_RetDot{	;Globalize height/width HWNDs and coodrinates
		global retCenter_blackH		:= retM_blackH
		global retCenter_blackV		:= retM_blackV
		global retCenter_white		:= retM_white
		global M_blackHX			:= "0"
		global M_blackHY			:= "0"
		global M_blackVX			:= "0"
		global M_blackVY			:= "0"
		global M_whiteX				:= "0"
		global M_whiteY				:= "0"
		}
	}

if showUI_Inputs{ ;Inputs
	if showUI_InputBG{
		Gui,	inputBGUI:			Color,	%UIRGB% ;Input background
		Gui		inputBGUI:			+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
		Gui,	inputBGUI:			Font,	s36,		Arial
		if showUI_Directionals{ ;Input background directional arrows
			Gui,	inputBGUI:		Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-25 . " y" .				((scrY/2)-59)-inputUIGap . " w50",	^
			Gui,	inputBGUI:		Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								((scrX/2)-67)-inputUIGap . " y" .	(scrY/2)-28 . " w50",				<
			Gui,	inputBGUI:		Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								((scrX/2)+17)+inputUIGap . " y" .	(scrY/2)-28 . " w50",				>
			Gui,	inputBGUI:		Font,	s31,		Aria
			Gui,	inputBGUI:		Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-24 . " y" .				((scrY/2)+14)+inputUIGap . " w50",	v
			}
		Gui,	inputBGUI:			Font,	s24,		Aria
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-40 . " y" .				(scrY/2)+40 . " w50",				Jump
		Gui,	inputBGUI:			Font,	s20,		Aria
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-40 . " y" .				(scrY/2)-135 . " w50",				Melee
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-90 . " y" .				(scrY/2)-105 . " w50",				Fire
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)+40 . " y" .				(scrY/2)-105 . " w50",				Aim
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-115. " y" .				(scrY/2)+70 . " w50",				Crouch
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)-105. " y" .				(scrY/2)+100 . " w50",				Prone
		Gui, 	inputBGUI:			Add,	Text,		% "center 0x201 BackGroundTrans c00FF00 x" . 								(scrX/2)+25. " y" .					(scrY/2)+85 . " w50",				Sprint
		WinSet, TransColor,			%UIRGB% 31
		}
	Gui,	inputUI:			Color,	%UIRGB% ;Inputs
	Gui		inputUI:			+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
	Gui,	inputUI:			Font,	s36,		Arial
	if showUI_Directionals{ ;Directonal arrows
		Gui, 	inputUI:		Add,	Text,		% "center 0x201 BackGroundTrans vmoveForwardText c" .	UIKeyOff . " x" .		(scrX/2)-25 . " y" .				((scrY/2)-59)-inputUIGap . " w50",	^
		Gui, 	inputUI:		Add,	Text,		% "center 0x201 BackGroundTrans vmoveLeftText c" .		UIKeyOff . " x" .		((scrX/2)-67)-inputUIGap . " y" .	(scrY/2)-28 . " w50",				<
		Gui, 	inputUI:		Add,	Text,		% "center 0x201 BackGroundTrans vmoveRightText c" .		UIKeyOff . " x" .		((scrX/2)+17)+inputUIGap . " y" .	(scrY/2)-28 . " w50",				>
		Gui,	inputUI:		Font,	s31,		Arial
		Gui, 	inputUI:		Add,	Text,		% "center 0x201 BackGroundTrans vmoveBackwardText c" .	UIKeyOff . " x" .		(scrX/2)-24 . " y" .				((scrY/2)+14)+inputUIGap . " w50",	v
		}
	Gui,	inputUI:			Font,	s24,		Arial
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vjumpText c" .			UIKeyOff . " x" .		(scrX/2)-40 . " y" .				(scrY/2)+40 . " w50",				Jump
	Gui,	inputUI:			Font,	s20,		Arial
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vmeleeText c" .			UIKeyOff . " x" .		(scrX/2)-40 . " y" .				(scrY/2)-135 . " w50",				Melee
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vfireText c" .			UIKeyOff . " x" .		(scrX/2)-90 . " y" .				(scrY/2)-105 . " w50",				Fire
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vaimText c" .			UIKeyOff . " x" .		(scrX/2)+40 . " y" .				(scrY/2)-105 . " w50",				Aim
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vcrouchText c" .		UIKeyOff . " x" .		(scrX/2)-115. " y" .				(scrY/2)+70 . " w50",				Crouch
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vproneText c" .			UIKeyOff . " x" .		(scrX/2)-105. " y" .				(scrY/2)+100 . " w50",				Prone
	Gui, 	inputUI:			Add,	Text,		% "center 0x201 BackGroundTrans vsprintText c" .		UIKeyOff . " x" .		(scrX/2)+25. " y" .					(scrY/2)+85 . " w50",				Sprint
	WinSet, TransColor,			%UIRGB% 255
	}

if showUI_firingMode{
	Gui,	firingModeHip:		Color,	%UIRGB% ;Hipfire Firing Mode
	Gui		firingModeHip:		+LastFound +AlwaysOnTop -Caption +ToolWindow	 +Disabled +E0x20
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageOff		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeOff%
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageSemi		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeSemi%
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageBurst2	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeBurst2%
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageBurst1	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeBurst1%
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageAuto		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeAuto2%
	Gui,	firingModeHip:		Add,	Picture,	vfiringModeHipImageDefault	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeAuto1%
	WinSet, TransColor,		%UIRGB% 255
	Gui,	firingModeADS:		Color,	%UIRGB% ;ADS Firing Mode
	Gui		firingModeADS:		+LastFound +AlwaysOnTop -Caption +ToolWindow	 +Disabled +E0x20
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageOff		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeOff%
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageSemi		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeSemi%
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageBurst2	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeBurst2%
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageBurst1	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeBurst1%
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageAuto		+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeAuto2%
	Gui,	firingModeADS:		Add,	Picture,	vfiringModeADSImageDefault	+BackgroundTrans X0 Y0 W64 H64,	%imgFiringModeAuto1%
	WinSet, TransColor,		%UIRGB% 255
	Gui,	firingModeHipDark:	Color, 0x000000 ; HipFire darkening
	Gui		firingModeHipDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
	WinSet, Transparent, 127
	Gui,	firingModeADSDark:	Color, 0x000000 ; ADS darkening
	Gui		firingModeADSDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
	WinSet, Transparent, 127
	}

setRetCoords(){ ;UI - Crosshair - re-calculate crosshair coordinates (fuck this finnicky ass shit)
	if showUI_Ret{
		retLengthOutline	:= retLength+(retOutline*2)
		retDotOutlineSize	:= retDotSize+(retDotOutline*2)
		retWidthOutline		:= retWidth+(retOutline*2)
		U_whiteX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX))
		U_whiteY			:=Round(((((scrY/4)-retLength)		/2)+retOffsetY)	-(retLength/2)	-retGap)
		D_whiteX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX))
		D_whiteY			:=Round(((((scrY/4)-retLength)		/2)+retOffsetY)	+(retLength/2)	+retGap)
		L_whiteX			:=Round(((((scrX/4)-retLength)		/2)+retOffsetX)	-(retLength/2)	-retGap)
		L_whiteY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY))
		R_whiteX			:=Round(((((scrX/4)-retLength)		/2)+retOffsetX)	+(retLength/2)	+retGap)
		R_whiteY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY))
		M_whiteX			:=Round(((((scrX/8)-retDotSize)		/2)+retOffsetX))
		M_whiteY			:=Round(((((scrY/8)-retDotSize)		/2)+retOffsetY))
		U_blackHX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX)								-retOutline)
		U_blackHY			:=Round(((((scrY/4)-retLength)		/2)+retOffsetY)	-(retLength/2)	-retGap)
		D_blackHX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX)								-retOutline)
		D_blackHY			:=Round(((((scrY/4)-retLength)		/2)+retOffsetY)	+(retLength/2)	+retGap)
		L_blackHX			:=Round(((((scrX/4)-retLength)		/2)+retOffsetX)	-(retLength/2)	-retGap)
		L_blackHY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY)								-retOutline)
		R_blackHX			:=Round(((((scrX/4)-retLength)		/2)+retOffsetX)	+(retLength/2)	+retGap)
		R_blackHY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY)								-retOutline)
		U_blackVX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX))
		U_blackVY			:=Round((((((scrY/4)-retLength)		/2)+retOffsetY)	-(retLength/2)	-retGap)	-retOutline)
		D_blackVX			:=Round(((((scrX/4)-retWidth)		/2)+retOffsetX))
		D_blackVY			:=Round((((((scrY/4)-retLength)		/2)+retOffsetY)	+(retLength/2)	+retGap)	-retOutline)
		L_blackVX			:=Round((((((scrX/4)-retLength)		/2)+retOffsetX)	-(retLength/2)	-retGap)	-retOutline)
		L_blackVY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY))
		R_blackVX			:=Round((((((scrX/4)-retLength)		/2)+retOffsetX)	+(retLength/2)	+retGap)	-retOutline)
		R_blackVY			:=Round(((((scrY/4)-retWidth)		/2)+retOffsetY))
		M_blackHX			:=Round(((((scrX/8)-retDotSize)		/2)+retOffsetX)								-retDotOutline)
		M_blackHY			:=Round(((((scrY/8)-retDotSize)		/2)+retOffsetY))
		M_blackVX			:=Round(((((scrX/8)-retDotSize)		/2)+retOffsetX))
		M_blackVY			:=Round(((((scrY/8)-retDotSize)		/2)+retOffsetY)								-retDotOutline)
		Circle_ULX			:=Round(((((scrX/8)					/2)+retOffsetX)	-(retCircleRadius*2)))
		Circle_ULY			:=Round(((((scrY/8)					/2)+retOffsetY)	-(retCircleRadius*2)))
		Circle_DRX			:=Round(((((scrX/8)					/2)+retOffsetX)	+(retCircleRadius*2)		+1))
		Circle_DRY			:=Round(((((scrY/8)					/2)+retOffsetY)	+(retCircleRadius*2)		+1))
		CircleW_Inner_ULX	:=Circle_ULX
		CircleW_Inner_ULY	:=Circle_ULY
		CircleW_Inner_DRX	:=Circle_DRX
		CircleW_Inner_DRY	:=Circle_DRY
		CircleW_Outer_ULX	:=(Circle_ULX-retCircleThickness)
		CircleW_Outer_ULY	:=(Circle_ULY-retCircleThickness)
		CircleW_Outer_DRX	:=(Circle_DRX+retCircleThickness)
		CircleW_Outer_DRY	:=(Circle_DRY+retCircleThickness)
		CircleB_Inner_ULX	:=(Circle_ULX+retCircleOutline)
		CircleB_Inner_ULY	:=(Circle_ULY+retCircleOutline)
		CircleB_Inner_DRX	:=(Circle_DRX-retCircleOutline)
		CircleB_Inner_DRY	:=(Circle_DRY-retCircleOutline)
		CircleB_Outer_ULX	:=(CircleW_Outer_ULX-retCircleOutline)
		CircleB_Outer_ULY	:=(CircleW_Outer_ULY-retCircleOutline)
		CircleB_Outer_DRX	:=(CircleW_Outer_DRX+retCircleOutline)
		CircleB_Outer_DRY	:=(CircleW_Outer_DRY+retCircleOutline)
		CircleB_Outer := DllCall("CreateEllipticRgn", "Int", CircleB_Outer_ULX,	"Int", CircleB_Outer_ULY,	"Int", CircleB_Outer_DRX,	"Int", CircleB_Outer_DRY)
		CircleB_Inner := DllCall("CreateEllipticRgn", "Int", CircleB_Inner_ULX,	"Int", CircleB_Inner_ULY,	"Int", CircleB_Inner_DRX,	"Int", CircleB_Inner_DRY)
		CircleW_Outer := DllCall("CreateEllipticRgn", "Int", CircleW_Outer_ULX,	"Int", CircleW_Outer_ULY,	"Int", CircleW_Outer_DRX,	"Int", CircleW_Outer_DRY)
		CircleW_Inner := DllCall("CreateEllipticRgn", "Int", CircleW_Inner_ULX,	"Int", CircleW_Inner_ULY,	"Int", CircleW_Inner_DRX,	"Int", CircleW_Inner_DRY)
		drawCrosshair()
		}
	return
	}

drawCrosshair(){ ;Draw the crosshar - Black to White, Cross, Dot, to Circle in that order
	GuiControl,	Move,	%retUp_blackH%,		W%retWidthOutline%		H%retLength%			X%U_blackHX%	Y%U_blackHY%
	GuiControl,	Move,	%retUp_blackV%,		W%retWidth%				H%retLengthOutline%		X%U_blackVX%	Y%U_blackVY%
	GuiControl,	Move,	%retDown_blackH%,	W%retWidthOutline%		H%retLength%			X%D_blackHX%	Y%D_blackHY%
	GuiControl,	Move,	%retDown_blackV%,	W%retWidth%				H%retLengthOutline%		X%D_blackVX%	Y%D_blackVY%
	GuiControl,	Move,	%retLeft_blackV%,	W%retLengthOutline%		H%retWidth%				X%L_blackVX%	Y%L_blackVY%
	GuiControl,	Move,	%retLeft_blackH%,	W%retLength%			H%retWidthOutline%		X%L_blackHX%	Y%L_blackHY%
	GuiControl,	Move,	%retRight_blackV%,	W%retLengthOutline%		H%retWidth%				X%R_blackVX%	Y%R_blackVY%
	GuiControl,	Move,	%retRight_blackH%,	W%retLength%			H%retWidthOutline%		X%R_blackHX%	Y%R_blackHY%
	GuiControl,	Move,	%retCenter_blackH%,	W%retDotOutlineSize%	H%retDotSize%			X%M_blackHX%	Y%M_blackHY%
	GuiControl,	Move,	%retCenter_blackV%,	W%retDotSize%			H%retDotOutlineSize%	X%M_blackVX%	Y%M_blackVY%		
	DllCall("CombineRgn", "UInt", CircleB_Outer, "UInt", CircleB_Outer, "UInt", CircleB_Inner, "Int", 3) ; RGN_XOR = 3
	DllCall("SetWindowRgn", "UInt", HWNDCircleB, "UInt", CircleB_Outer, "UInt", true)
	GuiControl,	Move,	%retUp_white%,		W%retWidth%				H%retLength%			X%U_whiteX%		Y%U_whiteY%
	GuiControl,	Move,	%retDown_white%,	W%retWidth%				H%retLength%			X%D_whiteX%		Y%D_whiteY%
	GuiControl,	Move,	%retLeft_white%,	W%retLength%			H%retWidth%				X%L_whiteX%		Y%L_whiteY%
	GuiControl,	Move,	%retRight_white%,	W%retLength%			H%retWidth%				X%R_whiteX%		Y%R_whiteY%
	GuiControl,	Move,	%retCenter_white%,	W%retDotSize%			H%retDotSize%			X%M_whiteX%		Y%M_whiteY%		
	DllCall("CombineRgn", "UInt", CircleW_Outer, "UInt", CircleW_Outer, "UInt", CircleW_Inner, "Int", 3) ; RGN_XOR = 3
	DllCall("SetWindowRgn", "UInt", HWNDCircleW, "UInt", CircleW_Outer, "UInt", true)
	return
	}

loadUI(){ ;Load the UI
	setTimer, loadUI1, % tick(90)
	return
	}

loadUI1:
	{
	setTimer, loadUI1, off
	setTimer, loadUI2, % tick(90)
	updateFiringModeHipUI()
	updateFiringModeADSUI()
	retState()
	return
	}

loadUI2:
	{
	UI_Show()
	UI_forceTop()
	setTimer, loadUI2, off
	return
	}

checkWindow(){ ;Check to see if the game window is active
	setTimer, checkWindow, % tick(300)
	return	
	}

checkWindow:
	{
	setTimer, checkWindow, % tick(60)
	if (WinActive("game")
	OR WinActive("Visual Studio")){
		if !windowSelected{
			windowSelected := "1"
			UI_Show()
			UI_forceTop()
			return
			}
		}
	else{
		windowSelected	:= "0"
		UI_hide()
		return
		}
	return
	}

UI_show(){ ;Show the UI
	if (showUI){
		UI_showInputs()
		UI_showRet()
		UI_showFiringModes()
		UI_forceTop()
		}
	return
	}

UI_showInputs(){ ;Show input overlay
	if showUI_Inputs{
		if showUI_InputBG{
			Gui,		inputBGUI:		Show,% "W" . scrX . " H" . scrY . " X0 Y0 NoActivate"
			}
		if showUI_Inputs{			
			Gui,		inputUI:		Show,% "W" . scrX . " H" . scrY . " X0 Y0 NoActivate"
			}
		}
	Return
	}

UI_showRet(){ ;Show reticle: Black to White, Cross, Dot to Circle in that order
	if showUI_Ret{
		if showUI_RetCross{
			Gui		retUI_CROSSB:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_CROSSB:	Show,% "W" . scrX/4 . " H" . scrY/4 . " X" . (((scrx/2)-((scrx/4)/2))) . " Y" . (((scry/2)-((scry/4)/2))) . " NoActivate"
			}
		if showUI_RetDot{
			Gui		retUI_DOTB:		+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_DOTB:		Show,% "W" . scrX/8 . " H" . scrY/8 . " X" . (((scrx/2)-((scrx/8)/2))) . " Y" . (((scry/2)-((scry/8)/2))) . " NoActivate"
			}
		if showUI_RetCircle{
			Gui		retUI_CIRCLEB:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_CIRCLEB:	Show,% "W" . scrX/8 . " H" . scrY/8 . " X" . (((scrx/2)-((scrx/8)/2))) . " Y" . (((scry/2)-((scry/8)/2))) . " NoActivate"
			}
		if showUI_RetCross{
			Gui		retUI_CROSSW:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_CROSSW:	Show,% "W" . scrX/4 . " H" . scrY/4 . " X" . (((scrx/2)-((scrx/4)/2))) . " Y" . (((scry/2)-((scry/4)/2))) . " NoActivate"
			}
		if showUI_RetDot{
			Gui		retUI_DOTW:		+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_DOTW:		Show,% "W" . scrX/8 . " H" . scrY/8 . " X" . (((scrx/2)-((scrx/8)/2))) . " Y" . (((scry/2)-((scry/8)/2))) . " NoActivate"
			}
		if showUI_RetCircle{
			Gui		retUI_CIRCLEW:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			Gui,	retUI_CIRCLEW:	Show,% "W" . scrX/8 . " H" . scrY/8 . " X" . (((scrx/2)-((scrx/8)/2))) . " Y" . (((scry/2)-((scry/8)/2))) . " NoActivate"
			}
		}
	return
	}

UI_showFiringModes(){ ;Show Firing Modes
	if showUI_firingMode{
		Gui,		firingModeHip:		Show,W64 H64 X1692 Y869 NoActivate
		Gui, 		firingModeHipDark:	Show,W64 H64 X1692 Y869 NoActivate
		Gui,		firingModeADS:		Show,W64 H64 X1756 Y869 NoActivate
		Gui, 		firingModeADSDark:	Show,W64 H64 X1756 Y869 NoActivate
		}
	return
	}

UI_hide(){ ;Hide UI
	UI_hideRet()
	UI_hideInputs()
	UI_hideFiringModes()
	return
	}

UI_hideRet(){ ;Hide reticle
	Gui retUI_CIRCLEB:		hide
	Gui retUI_CROSSB:		hide
	Gui retUI_DOTB:			hide
	Gui retUI_CIRCLEW:		hide
	Gui retUI_CROSSW:		hide
	Gui retUI_DOTW:			hide
	return
	}

UI_hideInputs(){ ;Hide Input Overlay
	Gui inputBGUI:			hide
	Gui inputUI:			hide
	return
	}

UI_hideFiringModes(){ ;Hide Firing Modes
	Gui firingModeHip:		hide
	Gui firingModeADS:		hide
	Gui firingModeHipDark:	hide
	Gui firingModeADSdark:	hide
	}

UI_forceTop(){ ;Force the UI to render over active window
	Gui retUI_DOTB:			+AlwaysOnTop
	Gui retUI_CROSSB:		+AlwaysOnTop
	Gui retUI_CIRCLEB:		+AlwaysOnTop
	Gui retUI_DOTW:			+AlwaysOnTop
	Gui retUI_CROSSW:		+AlwaysOnTop
	Gui retUI_CIRCLEW:		+AlwaysOnTop
	Gui inputBGUI:			+AlwaysOnTop
	Gui inputUI:			+AlwaysOnTop
	Gui firingModeHip:		+AlwaysOnTop
	Gui firingModeADS:		+AlwaysOnTop
	Gui firingModeHipDark:	+AlwaysOnTop
	Gui firingModeADSdark:	+AlwaysOnTop
	return
	}

retState(s:=0){ ;Reticle state settings
	aniFrameRate						:= "1"
	switch s{
		case 1:
			showUI_RetDot				:= "1"
			showUI_RetCross				:= "1"
			showUI_RetCircle			:= "1"
			aniOnResetShowCross			:= "1"
			aniOnResetShowDot			:= "1"
			aniStepsGrow				:= "24"
			aniStepsDecay				:= (aniStepsGrow/4)
			retGap						:= "14"
			retLength					:= "12"
			retWidth					:= "2"
			retOutline					:= "1"
			retDotSize					:= "2"
			retDotOutline				:= "0"
			retCircleRadius				:= "10"
			retCircleThickness			:= "2"
			retCircleOutline			:= "0"
			aniMaxGap					:= "30"
			aniMaxLength				:= "20"
			aniMaxWidth					:= "2"
			aniMaxOutline				:= "1"
			aniMaxDotSize				:= "4"
			aniMaxDotOutline			:= "1"
			aniMaxCircleRadius			:= "15"
			aniMaxCircleThickness		:= "1"
			aniMaxCircleOutline			:= "1"
			aniSnapStepGap				:=(aniMaxGap				/6)
			aniSnapStepLength			:=(aniMaxLength				/6)
			aniSnapStepWidth			:=(aniMaxWidth				/6)
			aniSnapStepOutline			:=(aniMaxOutline			*2)
			aniSnapStepDotSize			:=(aniMaxDotSize			*2)
			aniSnapStepDotOutline		:=(aniMaxDotOutline			*2)
			aniSnapStepCircleRadius		:=(aniMaxCircleRadius		/6)
			aniSnapStepCircleThickness	:=(aniMaxCircleThickness	*2)
			aniSnapStepCircleOutline	:=(aniMaxCircleOutline		*2)
		case 2:
			showUI_RetDot				:= "1"
			showUI_RetCross				:= "1"
			showUI_RetCircle			:= "1"
			aniOnResetShowCross			:= "1"
			aniOnResetShowDot			:= "1"
			aniStepsGrow				:= "24"
			aniStepsDecay				:= (aniStepsGrow/4)
			retGap						:= "13"
			retLength					:= "5"
			retWidth					:= "2"
			retOutline					:= "1"
			retDotSize					:= "2"
			retDotOutline				:= "0"
			retCircleRadius				:= "8"
			retCircleThickness			:= "1"
			retCircleOutline			:= "0"
			aniMaxGap					:= "17"
			aniMaxLength				:= "3"
			aniMaxWidth					:= "4"
			aniMaxOutline				:= "1"
			aniMaxDotSize				:= "2"
			aniMaxDotOutline			:= "1"
			aniMaxCircleRadius			:= "10"
			aniMaxCircleThickness		:= "1"
			aniMaxCircleOutline			:= "1"
			aniSnapStepGap				:=(aniMaxGap				/6)
			aniSnapStepLength			:=(aniMaxLength				/6)
			aniSnapStepWidth			:=(aniMaxWidth				/6)
			aniSnapStepOutline			:=(aniMaxOutline			*2)
			aniSnapStepDotSize			:=(aniMaxDotSize			*2)
			aniSnapStepDotOutline		:=(aniMaxDotOutline			*2)
			aniSnapStepCircleRadius		:=(aniMaxCircleRadius		/6)
			aniSnapStepCircleThickness	:=(aniMaxCircleThickness	*2)
			aniSnapStepCircleOutline	:=(aniMaxCircleOutline		*2)
		default:
			showUI_RetDot				:= "1"
			showUI_RetCross				:= "1"
			showUI_RetCircle			:= "1"
			aniOnResetShowCross			:= "1"
			aniOnResetShowDot			:= "1"
			aniStepsGrow				:= "24"
			aniStepsDecay				:= (aniStepsGrow/4)
			retGap						:= "1"
			retLength					:= "1"
			retWidth					:= "2"
			retOutline					:= "1"
			retDotSize					:= "2"
			retDotOutline				:= "1"
			retCircleRadius				:= "1"
			retCircleThickness			:= "2"
			retCircleOutline			:= "1"
			aniMaxGap					:= "1"
			aniMaxLength				:= "1"
			aniMaxWidth					:= "2"
			aniMaxOutline				:= "1"
			aniMaxDotSize				:= "2"
			aniMaxDotOutline			:= "1"
			aniMaxCircleRadius			:= "1"
			aniMaxCircleThickness		:= "2"
			aniMaxCircleOutline			:= "1"
			aniSnapStepGap				:=(aniMaxGap				/6)
			aniSnapStepLength			:=(aniMaxLength				/6)
			aniSnapStepWidth			:=(aniMaxWidth				/6)
			aniSnapStepOutline			:=(aniMaxOutline			*2)
			aniSnapStepDotSize			:=(aniMaxDotSize			*2)
			aniSnapStepDotOutline		:=(aniMaxDotOutline			*2)
			aniSnapStepCircleRadius		:=(aniMaxCircleRadius		/6)
			aniSnapStepCircleThickness	:=(aniMaxCircleThickness	*2)
			aniSnapStepCircleOutline	:=(aniMaxCircleOutline		*2)
		}
		
	aniMinGap						:= retGap
	aniMinLength					:= retLength
	aniMinWidth						:= retWidth
	aniMinOutline					:= retOutline	
	aniMinDotSize					:= retDotSize
	aniMinDotOutline				:= retDotOutline
	aniMinCircleRadius				:= retCircleRadius
	aniMinCircleThickness			:= retCircleThickness
	aniMinCircleOutline				:= retCircleOutline
	aniRateGrowGap					:= ((aniMaxGap				-retGap)				/ aniStepsGrow)
	aniRateGrowLength				:= ((aniMaxLength			-retLength)				/ aniStepsGrow)
	aniRateGrowWidth				:= ((aniMaxWidth			-retWidth)				/ aniStepsGrow)
	aniRateGrowOutline				:= ((aniMaxOutline			-retOutline)			/ aniStepsGrow)*8
	aniRateGrowDotSize				:= ((aniMaxDotSize			-retDotSize)			/ aniStepsGrow)*8
	aniRateGrowDotOutline			:= ((aniMaxDotOutline		-retDotOutline)			/ aniStepsGrow)*8
	aniRateGrowCircleRadius			:= ((aniMaxCircleRadius		-retCircleRadius)		/ aniStepsGrow)
	aniRateGrowCircleThickness		:= ((aniMaxCircleThickness	-retCircleThickness)	/ aniStepsGrow)*8
	aniRateGrowCircleOutline		:= ((aniMaxCircleOutline	-retCircleOutline)		/ aniStepsGrow)*8
	aniRateDecayGap					:= ((aniMaxGap				-retGap)				/ aniStepsDecay)
	aniRateDecayLength				:= ((aniMaxLength			-retLength)				/ aniStepsDecay)
	aniRateDecayWidth				:= ((aniMaxWidth			-retWidth)				/ aniStepsDecay)
	aniRateDecayOutline				:= ((aniMaxOutline			-retOutline)			/ aniStepsDecay)
	aniRateDecayDotSize				:= ((aniMaxDotSize			-retDotSize)			/ aniStepsDecay)
	aniRateDecayDotOutline			:= ((aniMaxDotOutline		-retDotOutline)			/ aniStepsDecay)
	aniRateDecayCircleRadius		:= ((aniMaxCircleRadius		-retCircleRadius)		/ aniStepsDecay)
	aniRateDecayCircleThickness		:= ((aniMaxCircleThickness	-retCircleThickness)	/ aniStepsDecay)
	aniRateDecayCircleOutline		:= ((aniMaxCircleOutline	-retCircleOutline)		/ aniStepsDecay)
	setRetCoords()	
	return
	}

ani_Snap(){ ;Reticle snap animation
	setTimer, ani_Decay, off
	setTimer, ani_Grow, off
	if showUI_RetAnimate
		{
		retGap				:= retGap+aniSnapStepGap
		if (retGap			> aniMaxGap){
			retGap			:= aniMaxGap
			}
		retLength			:= retLength+aniSnapStepLength
		if (retLength		> aniMaxLength){
			retLength		:= aniMaxLength
			}
		retWidth			:= retWidth+aniSnapStepWidth
		if (retWidth		> aniMaxWidth){
			retWidth		:= aniMaxWidth
			}
		retOutline			:= retOutline+aniSnapStepOutline
		if (retOutline		> aniMaxOutline){
			retOutline		:= aniMaxOutline
			}
		retDotSize			:= retDotSize+aniSnapStepDotSize
		if (retDotSize		> aniMaxDotSize){
			retDotSize		:= aniMaxDotSize
			}
		retDotOutline		:= retDotOutline+aniSnapStepDotOutline
		if (retDotOutline	> aniMaxDotOutline){
			retDotOutline	:= aniMaxDotOutline
			}
		retCircleRadius		:= retCircleRadius+aniSnapStepCircleRadius
		if (retCircleRadius	> aniMaxCircleRadius){
			retCircleRadius	:= aniMaxCircleRadius
			}
		retCircleThickness		:= retCircleThickness+aniSnapStepCircleThickness
		if (retCircleThickness	> aniMaxCircleThickness){
			retCircleThickness	:= aniMaxCircleThickness
			}
		retCircleOutline		:= retCircleOutline+aniSnapStepCircleOutline
		if (retCircleOutline	> aniMaxCircleOutline){
			retCircleOutline	:= aniMaxCircleOutline
			}
		setRetCoords()
		setTimer, delayDecay, % tick()
		}
	return
	}

ani_Grow(){ ;Reticle grow animation
	if showUI_RetAnimate{
		doneGrow := 0
		showUI_RetCross	:= 1
		showUI_RetDot	:= 1
		setTimer, ani_Decay, off
		setTimer, ani_Grow, % tick(aniFrameRate)
		goSub ani_Grow
		}
	return
	}

delayDecay:
	{
	setTimer, delayDecay, off
	ani_Decay()
	return
	}

ani_Decay(){ ;Reticle decay animation
	if showUI_RetAnimate{
		doneDecay := 0
		showUI_RetCross	:= "1"
		showUI_RetDot	:= "1"
		setTimer, ani_Grow, off
		setTimer, ani_Decay, % tick(aniFrameRate)
		goSub ani_Decay
		}
	return
	}

ani_Grow:
	{
	if	(retGap				>= aniMaxGap)
	AND	(retLength			>= aniMaxLength)
	AND	(retWidth			>= aniMaxWidth)
	AND	(retOutline			>= aniMaxOutline)
	AND	(retDotSize			>= aniMaxDotSize)
	AND	(retDotOutline		>= aniMaxDotOutline)
	AND	(retCircleRadius	>= aniMaxCircleRadius)
	AND	(retCircleThickness	>= aniMaxCircleThickness)
	AND	(retCircleOutline	>= aniMaxCircleOutline){
	doneGrow := 1
	}
	if !doneGrow{
		if (retGap			< aniMaxGap){
			retGap			:= (retGap			+(aniRateGrowGap))
			}
		if (retGap			>= aniMaxGap){
			retGap			:= aniMaxGap
			}
		if (retLength		< aniMaxLength){
			retLength		:= (retLength		+(aniRateGrowLength))
			}
		if (retLength		>= aniMaxLength){
			retLength		:= aniMaxLength
			}
		if (retWidth		< aniMaxWidth){
			retWidth		:= (retWidth		+(aniRateGrowWidth))
			}
		if (retWidth		>= aniMaxWidth){
			retWidth		:= aniMaxWidth
			}
		if (retOutline		< aniMaxOutline){
			retOutline		:= (retOutline		+(aniRateGrowOutline))
			}
		if (retOutline		>= aniMaxOutline){
			retOutline		:= aniMaxOutline
			}
		if (retDotSize		< aniMaxDotSize){
			retDotSize		:= (retDotSize		+(aniRateGrowDotSize))
			}
		if (retDotSize		>= aniMaxDotSize){
			retDotSize		:= aniMaxDotSize
			}
		if (retDotOutline	< aniMaxDotOutline){
			retDotOutline	:= (retDotOutline	+(aniRateGrowDotOutline))
			}
		if (retDotOutline	>= aniMaxDotOutline){
			retDotOutline	:= aniMaxDotOutline
			}
		if (retCircleRadius	< aniMaxCircleRadius){
			retCircleRadius	:= (retCircleRadius	+(aniRateGrowCircleRadius))
			}
		if (retCircleRadius	>= aniMaxCircleRadius){
			retCircleRadius	:= aniMaxCircleRadius
			}
		if (retCircleThickness	< aniMaxCircleThickness){
			retCircleThickness	:= (retCircleThickness	+(aniRateGrowCircleThickness))
			}
		if (retCircleThickness	>= aniMaxCircleThickness){
			retCircleThickness	:= aniMaxCircleThickness
			}
		if (retCircleOutline	< aniMaxCircleOutline){
			retCircleOutline	:= (retCircleOutline	+(aniRateGrowCircleOutline))
			}
		if (retCircleOutline	>= aniMaxCircleOutline){
			retCircleOutline	:= aniMaxCircleOutline
			}
		setTimer, ani_Grow, % tick(aniFrameRate)
		}
	if doneGrow{
		setTimer, ani_Grow, off
		}
	setRetCoords()
	return
	}

ani_Decay:
	{
	if	(retGap				<= aniMinGap)
	AND	(retLength			<= aniMinLength)
	AND	(retWidth			<= aniMinWidth)
	AND	(retOutline			<= aniMinOutline)
	AND	(retDotSize			<= aniMinDotSize)
	AND	(retDotOutline		<= aniMinDotOutline)
	AND	(retCircleRadius	<= aniMinCircleRadius)
	AND	(retCircleThickness	<= aniMinCircleThickness)
	AND	(retCircleOutline	<= aniMinCircleOutline){
		doneDecay := 1
		}
	if !doneDecay{
		if (retGap			> aniMinGap){
			retGap			:= (retGap			-(aniRateDecayGap))
			}
		if (retGap			<= aniMinGap){
			retGap			:= aniMinGap
			}
		if (retLength		> aniMinLength){
			retLength		:= (retLength		-(aniRateDecayLength))
			}
		if (retLength		<= aniMinLength){
			retLength		:= aniMinLength
			}
		if (retWidth		> aniMinWidth){
			retWidth		:= (retWidth		-(aniRateDecayWidth))
			}
		if (retWidth		<= aniMinWidth){
			retWidth		:= aniMinWidth
			}
		if (retOutline		> aniMinOutline){
			retOutline		:= (retOutline		-(aniRateDecayOutline))
			}
		if (retOutline		<= aniMinOutline){
			retOutline		:= aniMinOutline
			}
		if (retDotSize		> aniMinDotSize){
			retDotSize		:= (retDotSize		-(aniRateDecayDotSize))
			}
		if (retDotSize		<= aniMinDotSize){
			retDotSize		:= aniMinDotSize
			}
		if (retDotOutline	> aniMinDotOutline){
			retDotOutline	:= (retDotOutline	-(aniRateDecayDotOutline))
			}
		if (retDotOutline	<= aniMinDotOutline){
			retDotOutline	:= aniMinDotOutline
			}
		if (retCircleRadius	> aniMinCircleRadius){
			retCircleRadius	:= (retCircleRadius	-(aniRateDecayCircleRadius))
			}
		if (retCircleRadius	<= aniMinCircleRadius){
			retCircleRadius	:= aniMinCircleRadius
			}
		if (retCircleThickness	> aniMinCircleThickness){
			retCircleThickness	:= (retCircleThickness	-(aniRateDecayCircleThickness))
			}
		if (retCircleThickness	<= aniMinCircleThickness){
			retCircleThickness	:= aniMinCircleThickness
			}
		if (retCircleOutline	> aniMinCircleOutline){
			retCircleOutline	:= (retCircleOutline	-(aniRateDecayCircleOutline))
			}
		if (retCircleOutline	<= aniMinCircleOutline){
			retCircleOutline	:= aniMinCircleOutline
			}
		setTimer, ani_Decay, % tick(aniFrameRate)
		}
	if doneDecay{
		if !aniOnResetShowDot
			{
			showUI_RetDot	:=0
			}
		if !aniOnResetShowCross
			{
			showUI_RetCross	:=0
			}
		setTimer, ani_Decay, off
		}
	setRetCoords()
	return
	}

updateInputUI(c:="",s:=""){ ;Update the input key text
	if showUI_Inputs{
		if ((c = "") || (c = UIKeyOff)){
				GuiControl,	inputUI: +c%UIKeyOff%, %s%,
				gui,		inputUI: color
			}
		else{
				GuiControl,	inputUI: +c%c% +Redraw, %s%,
			}
		}
	return
	}

hideFiringModeHip(){ ;Hide firing mode images - HipFire
	if showUI_firingMode{
		GuiControl,	firingModeHip:	Hide, firingModeHipImageOff
		GuiControl,	firingModeHip:	Hide, firingModeHipImageDefault
		GuiControl,	firingModeHip:	Hide, firingModeHipImageAuto
		GuiControl,	firingModeHip:	Hide, firingModeHipImageBurst1
		GuiControl,	firingModeHip:	Hide, firingModeHipImageBurst2
		GuiControl,	firingModeHip:	Hide, firingModeHipImageSemi
		}
	return
	}

hideFiringModeADS(){ ;Hide firing mode images - ADS
	if showUI_firingMode{
		GuiControl,	firingModeADS:	Hide, firingModeADSImageOff
		GuiControl,	firingModeADS:	Hide, firingModeADSImageDefault
		GuiControl,	firingModeADS:	Hide, firingModeADSImageAuto
		GuiControl,	firingModeADS:	Hide, firingModeADSImageBurst1
		GuiControl,	firingModeADS:	Hide, firingModeADSImageBurst2
		GuiControl,	firingModeADS:	Hide, firingModeADSImageSemi
		}
	return
	}

updateFiringModeHipUI(s:="default"){ ;Update the firing mode image - HipFire
	if showUI_firingMode{
		hideFiringModeHip()
		switch s{
			case "default":
				GuiControl,	firingModeHip:	Show, firingModeHipImageDefault
			case "auto":
				GuiControl,	firingModeHip:	Show, firingModeHipImageAuto
			case "burst1":
				GuiControl,	firingModeHip:	Show, firingModeHipImageBurst1
			case "burst2":
				GuiControl,	firingModeHip:	Show, firingModeHipImageBurst2

			case "semi":
				GuiControl,	firingModeHip:	Show, firingModeHipImageSemi
			default:
				msgbox ERROR in updateFiringModeHipUI() %firingModeHip%
			}
		}
	return
	}

updateFiringModeADSUI(s:="default"){ ;Update the firing mode image - ADS
	if showUI_firingMode{
		hideFiringModeADS()
		switch s{
			case "default":
				GuiControl,	firingModeADS:	Show, firingModeADSImageDefault
			case "auto":
				GuiControl,	firingModeADS:	Show, firingModeADSImageAuto
			case "burst1":
				GuiControl,	firingModeADS:	Show, firingModeADSImageBurst1
			case "burst2":
				GuiControl,	firingModeADS:	Show, firingModeADSImageBurst2
			case "semi":
				GuiControl,	firingModeADS:	Show, firingModeADSImageSemi
			default:
				msgbox ERROR in updateFiringModeADSUI() %firingModeADS%
			}
		}
	return
	}

;;;;;;;;;;;;;;
;;INPUT KEYS;;
;;;;;;;;;;;;;;
#If WinActive("ahk_exe game.exe")
	{
	*$~LBUTTON::
		gosub firePressed
		return	
	*$~LBUTTON up::
		gosub fireReleased
		return
		
	if showUI_Directionals{ ;WASD directionals
		*$~W::
			updateInputUI(UIKeyOn, "moveForwardText")
			return		
		*$~W up::
			updateInputUI(UIKeyOff, "moveForwardText")
			return
		
		*$~S::
			updateInputUI(UIKeyOn, "moveBackwardText")
			return		
		*$~S up::
			updateInputUI(UIKeyOff, "moveBackwardText")
			return
		
		*$~A::
			updateInputUI(UIKeyOn, "moveLeftText")
			return		
		*$~A up::
			updateInputUI(UIKeyOff, "moveLeftText")
			return
		
		*$~D::
			updateInputUI(UIKeyOn, "moveRightText")
			return		
		*$~D up::
			updateInputUI(UIKeyOff, "moveRightText")
			return
		}
	
	*$~RBUTTON::
		gosub aimPressed
		return	
	*$~RBUTTON up::
		gosub aimReleased
		return
	
	*$~XBUTTON2::
		gosub meleePressed
		return	
	*$~XBUTTON2 up::
		gosub meleeReleased
		return
		
	*$~WHEELUP::
	*$~WHEELDOWN::
		gosub wheelScrolled
		return
	
	*$~LCTRL::
		gosub pronePressed
		return	
	*$~LCTRL up::
		gosub proneReleased
		return
	
	*$~LSHIFT::
		gosub sprintPressed
		return	
	*$~LSHIFT up::
		gosub sprintReleased
		return
	
	*$~LALT::
		gosub crouchPressed
		return	
	*$~LALT up::
		gosub crouchReleased
		return
	
	*$~TAB::
		gosub tabPressed
		return	
	*$~TAB up::
		return
	
	*$~Space::
		gosub jumpPressed
		return
	*$~Space up::
		gosub jumpReleased
		return
	
	*$~X::
		gosub firingModePressed
		return	
	*$~X up::
		gosub firingModeRelease
		return
	
	f9::
		;Breakpoint
		return
	}

;;;;;;;;;;;;;;;;;;;
;; FIRING SYSTEM ;;
;;;;;;;;;;;;;;;;;;;
firePressed: ;Fire pressed
	{
	if !isHoldingFire{
		isHoldingFire := 1
		switch firingMode{
			case "default":
				goSub fireDefault1
			case "auto":
				goSub fireAuto1
			case "burst1":
				if !isBursting1{
					goSub fireBurst1_1
					}
			case "burst2":
				if !isBursting2{
					goSub fireBurst2_1
					}
			case "semi":
				goSub fireSemi1
			default:
				msgBox ERROR in firePressed() %firingMode%
			}
		if enableAutoMark{
			gosub sendMark1
			}
		}
	return
	}

fireReleased: ;Fire released
	{
	isHoldingFire := 0
	if !isBursting1{
		updateInputUI(UIKeyOff, "fireText")
		send {insert up}
		ani_Decay()
		}
	setTimer, fireSemi1, off
	setTimer, fireSemi2, off
	setTimer, fireAuto1, off
	setTimer, fireAuto2, off
	return
	}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;FIRING MODE SELECTION SYSTEM;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
firingModePressed: ;Firing Mode Switch pressed
	{
	if !isHoldingFiringMode{
		isHoldingFiringMode = 1
		cancelFiringMode := 0
		setTimer, resetFiringMode, % tick(20)
		}
	return
	}

firingModeRelease: ;Firing Mode Switch released
	{
	isHoldingFiringMode := 0
	if !chargedFiringMode{
		if isHoldingAim{
			goSub switchFiringModeADS
			firingMode := firingModeADS
			updateFiringModeADSUI(firingModeADS)
			}
		if !isHoldingAim{
			goSub switchFiringModeHip
			firingMode := firingModeHip
			updateFiringModeHipUI(firingModeHip)
			}
		setTimer, resetFiringMode, off
		}
	if chargedFiringMode{
		firingModeSound := "audio\sound_default.AHK"
		updateFiringModeADSUI(firingModeADS)
		updateFiringModeHipUI(firingModeHip)
		}
	setTimer, playFiringModeSound, % tick(16)
	chargedFiringMode := 0
	return
	}

switchFiringModeHip: ;Cycle firing modes - HipFire
	{
	switch firingModeHip{
		case "default":
			firingModeSound := "audio\sound_fullauto.AHK"
			firingModeHip := "auto"
		case "auto":
			firingModeSound := "audio\sound_burst.AHK"
			firingModeHip := "burst1"
		case "burst1":
			firingModeSound := "audio\sound_burst.AHK"
			firingModeHip := "burst2"
		case "burst2":
			firingModeSound := "audio\sound_semiauto.AHK"
			firingModeHip := "semi"
		case "semi":
			firingModeSound := "audio\sound_default.AHK"
			firingModeHip := "default"
		default:
			msgbox ERROR in switchFiringModeHip() firingModeHip: %firingModeHip%
		}
	return
	}

switchFiringModeADS: ;Cycle firing modes - ADS
	{
	switch firingModeADS{
		case "default":
			firingModeSound := "audio\sound_fullauto.AHK"
			firingModeADS := "auto"
		case "auto":
			firingModeSound := "audio\sound_burst.AHK"
			firingModeADS := "burst1"
		case "burst1":
			firingModeSound := "audio\sound_burst.AHK"
			firingModeADS := "burst2"
		case "burst2":
			firingModeSound := "audio\sound_semiauto.AHK"
			firingModeADS := "semi"
		case "semi":
			firingModeSound := "audio\sound_default.AHK"
			firingModeADS := "default"
		default:
			msgbox ERROR in switchFiringModeADS() firingModeADS: %firingModeADS%
		}
	return
	}

playFiringModeSound: ;Play firing mode switch audio
	{
	run %firingModeSound%
	setTimer, playFiringModeSound, off
	return
	}

resetFiringMode: ;Reset the firing mode
	{
	if getKeyState("X", "p"){
		chargedFiringMode := 1
		firingMode := "default"
		firingModeHip := "default"
		firingModeADS := "default"
			hideFiringModeHip()
			hideFiringModeADS()
			GuiControl,	firingModeHip:	Show, firingModeHipImageOff
			GuiControl,	firingModeADS:	Show, firingModeADSImageOff
		}
	setTimer, resetFiringMode, off
	return
	}

;;;;;;;;;;;;;;;;;;
;; FIRING MODES ;;
;;;;;;;;;;;;;;;;;;
fireDefault1: ;Default
	{
	send {insert down}
	ani_Grow()
	updateInputUI(UIKeyOn, "fireText")
	return
	}

fireAuto1: ;Auto Phase 1
	{
	if isHoldingFire{
		send {insert down}
		updateInputUI(UIKeyOn, "fireText")
		ani_Snap()
		setTimer, fireAuto1, off
		setTimer, fireAuto2, % tick()
		return
		}
	else if !isHoldingFire{
		goSub fireReleased
		return
		}
	return
	}

fireAuto2: ;Auto Phase 2
	{
	if isHoldingFire{
		send {insert up}
		updateInputUI("FF8800", "fireText")
		setTimer, fireAuto2, off
		setTimer, fireAuto1, % tick()
		return
		}
	else if !isHoldingFire{
		gosub fireReleased
		return
		}
	return
	}

fireBurst1_1: ;Burst Fire 1 phase 1
	{
	isBursting1 := 1
	updateInputUI(UIKeyOn, "fireText")
	send {insert down}
	ani_Grow()
	setTimer, fireBurst1_1, off
	setTimer, fireBurst1_2, % ((tick(5))/burst1FireMax)*2
	setTimer, fireBurst1_3, % ((tick(5))*burst1FireMax)+tick()
	return
	}

fireBurst1_2: ;Burst Fire 1 phase 2
	{
	updateInputUI("FF8800", "fireText")
	setTimer, fireBurst1_2, off
	setTimer, fireBurst1_2_2, % ((tick(5))/burst1FireMax)*2
	return
	}

fireBurst1_2_2: ;Burst Fire 1 phase 2 and a half
	{
	updateInputUI(UIKeyOn, "fireText")
	setTimer, fireBurst1_2_2, off
	setTimer, fireBurst1_2, % ((tick(5))/burst1FireMax)*2
	return
	}

fireBurst1_3: ;Burst Fire 1 phase 3
	{
	isBursting1 := 0
	updateInputUI(UIKeyOff, "fireText")
	if isHoldingFire{
		updateInputUI("FF8800", "fireText")
		}
	send {insert up}
	ani_Decay()
	setTimer, fireBurst1_3, off
	setTimer, fireBurst1_2, off
	setTimer, fireBurst1_2_2, off
	return
	}

fireBurst2_1: ;Burst Fire 2 phase 1
	{
	isBursting2 := 1
	burst2FireCount ++
	send {insert down}
	updateInputUI(UIKeyOn, "fireText")
	ani_Snap()
	setTimer, fireBurst2_1, off
	setTimer, fireBurst2_2, % tick(4)
	return
	}

fireBurst2_2: ;Burst Fire 2 phase 2
	{
	send {insert up}
	setTimer, fireBurst2_2, off
	if (burst2FireCount < burst2FireMax){
		updateInputUI("FF8800", "fireText")
		setTimer, fireBurst2_1, % tick(4)
		}
	else if (burst2FireCount >= burst2FireMax){
		burst2FireCount := 0
		isBursting2 := 0
		if isHoldingFire{
			updateInputUI("FF8800", "fireText")
			}
		else if !isHoldingFire{
			updateInputUI(UIKeyOff, "fireText")
			}
		setTimer, fireBurst2_1, off
		}
	return
	}

fireSemi1: ;Semi Auto phase 1
	{
	if isHoldingFire{
		send {insert down}
		updateInputUI(UIKeyOn, "fireText")
		ani_Snap()
		setTimer, fireSemi2, % tick(2)
		setTimer, fireSemi1, off
		return
		}
	return
	}

fireSemi2: ;Semi Auto phase 2
	{
	send {insert up}
	if isHoldingFire{
		updateInputUI("FF8800", "fireText")
		setTimer, fireSemi2, off
		} 
	return
	}

;;;;;;;;;;;;;;;;;;;;;;;;;;
;; HOLD TO PRONE SYSTEM ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
crouchPressed: ;Crouch pressed
	{
	if !isHoldingCrouch{
		updateInputUI(UIKeyOn, "crouchText")
		isHoldingCrouch := 1
		send {PgUp down}
		if enableHoldToProne{
			setTimer, goProne1, % tick(16)
			}
		}
	goSub jumpReleased
	return
	}

crouchReleased: ;Crouch released
	{
	isHoldingCrouch := 0
	updateInputUI(UIKeyOff, "crouchText")
	send {PgUp up}
	if !getKeyState("LCtrl", "p"){
		updateInputUI(UIKeyOff, "proneText")
		}
	setTimer, goProne1, off
	setTimer, goProne2, off
	return
	}

goProne1: ;Go Prone phase 1
	{
	send {PgDn down}
	updateInputUI("FFFF00", "proneText")
	setTimer, goProne2, % tick(4)
	setTimer, goProne1, off
	return
	}

goProne2: ;Go Prone phase 2
	{
	send {PgDn up}
	updateInputUI("FF8800", "proneText")
	setTimer, goProne1, % tick(4)
	setTimer, goProne2, off
	return
	}

;;;;;;;;;;;;;;;;;;
;; PRONE SYSTEM ;;
;;;;;;;;;;;;;;;;;;
pronePressed: ;Prone pressed
	{
	if !isHoldingProne{
		isholdingProne := 1
		if enableHoldProne{
			if !isProning{
				updateInputUI(UIKeyOn, "proneText")
				isProning := 1
				goSub proneSpam1
				setTimer, holdToProne, % tick(44)
				}
			}
		else if !enableHoldProne{
			updateInputUI(UIKeyOn, "proneText")
			}
		}
	goSub jumpReleased
	return
	}

proneReleased: ;Prone released
	{
	isHoldingProne := 0
	if !enableHoldProne{
		updateInputUI(UIKeyOff, "proneText")
		isProning := 0
		return
		}
	if (enableHoldProne && chargedProne && isProning){
		goSub unProneSpam1
		return
		}
	return
	}

proneSpam1: ;Prone Spam phase 1
	{
	if (proneCount < proneCountMax){
		proneCount++
		updateInputUI(UIKeyOn, "proneText")
		send {PgDn down}
		setTimer, proneSpam2, % tick(2)
		setTimer, proneSpam1, off
		}
	else if (proneCount >= proneCountMax){
		setTimer, proneSpam2, off
		}
	setTimer, proneSpam1, off
	return
	}

proneSpam2: ;Prone Spam phase 2
	{
	send {PgDn up}
	if (proneCount < proneCountMax){
		updateInputUI("008800", "proneText")
		setTimer, proneSpam1, % tick(2)
		}
	else if (proneCount >= proneCountMax){
		updateInputUI("FF8800", "proneText")
		proneCount := 0
		setTimer, proneSpam1, off
		}
	setTimer, proneSpam2, off
	return
	}

holdToProne: ;Prone held
	{
	if isholdingProne{
		updateInputUI("FFFF00", "proneText")
		chargedProne := 1
		setTimer, holdToProne, off
		return
		}
	else if !isholdingProne{
		updateInputUI(UIKeyOff, "proneText")
		chargedProne := 0
		isProning := 0
		setTimer, holdToProne, off
		return
		}
	setTimer, holdToProne, off
	return
	}

unProneSpam1: ;Unprone Spam phase 1
	{
	if (unProneCount < unProneCountMax){
		unProneCount++
		updateInputUI("FF8800", "proneText")
		send {PgUp down}
		setTimer, unproneSpam2, % tick(2)
		}
	else if (unProneCount >= unProneCountMax){
		setTimer, unproneSpam2, off
		}
	setTimer, unproneSpam1, off
	return
	}

unproneSpam2: ;Unprone Spam phase 2
	{
	updateInputUI("CC6600", "proneText")
	send {PgUp up}
	if (unProneCount < unProneCountMax){
		setTimer, unproneSpam1, % tick(2)
		}
	else if (unProneCount >= unProneCountMax){
		unProneCount := 0
		updateInputUI("FF8800", "proneText")
		setTimer, unproneSpam3, % tick(2)
		}
	setTimer, unproneSpam2, off
	return
	}

unProneSpam3: ;Unprone Spam phase 3
	{
	updateInputUI(UIKeyOff, "proneText")
	chargedProne := 0
	isProning := 0
	setTimer, unProneSpam1, off
	setTimer, unProneSpam2, off
	setTimer, unProneSpam3, off
	return
	}

;;;;;;;;;;;;;;;;;;
;; MELEE SYSTEM ;;
;;;;;;;;;;;;;;;;;;
meleePressed: ;Melee pressed
	{
	cancelMelee := 0
	if !isHoldingMelee{
		updateInputUI(UIKeyOn, "meleeText")
		isHoldingMelee := 1
		if enableHoldToMelee{
			setTimer, switchMelee1, % tick(16)
			}
		}
	return
	}

meleeReleased: ;Melee released
	{
	isHoldingMelee := 0
	updateInputUI(UIKeyOff, "meleeText")
	send {numpad5 up}
	if !cancelMelee{
		if !chargedMelee{
			goSub fastMelee1
			}
		if chargedMelee{
			setTimer, meleeReleasedSwitchBack1, % tick(2)
			}
		}
	chargedMelee := 0
	setTimer, switchMelee1, off
	setTimer, switchMelee2, off
	setTimer, switchMelee3, off
	return
	}

fastMelee1: ;Fast melee phase 1
	{
	send {numpad4 down}
	setTimer, fastMelee2, % tick(4)
	setTimer, fastMelee1, off
	return
	}

fastMelee2: ;Fast melee phase 2
	{
	send {numpad4 up}
	setTimer, fastMelee1, off
	setTimer, fastMelee2, off
	return
	}

switchMelee1: ;Switch to melee weapon phase 1
	{
	updateInputUI("FFFF00", "meleeText")
	chargedMelee := 1
	goSub switchMelee2
	setTimer, switchMelee1, off
	return
	}

switchMelee2: ;Switch to melee weapon phase 2
	{
	send {numpad5 down}
	setTimer, switchMelee3, % tick(2)
	setTimer, switchMelee2, off
	return
	}

switchMelee3: ;Switch to melee weapon phase 3
	{
	send {numpad5 up}
	setTimer, switchMelee2, % tick(2)
	setTimer, switchMelee3, off
	return
	}

meleeReleasedSwitchBack1: ;Switch from melee weapon to previous phase 1
	{
	send {numpad6 down}
	setTimer, meleeReleasedSwitchBack2, % tick(2)
	setTimer, meleeReleasedSwitchBack1, off
	return
	}

meleeReleasedSwitchBack2: ;Switch from melee weapon to previous phase 2
	{
	send {numpad6 up}
	setTimer, meleeReleasedSwitchBack2, off
	return
	}

;;;;;;;;;;;;;;;;;;;;;;;;
;; MOUSE WHEEL SYSTEM ;;
;;;;;;;;;;;;;;;;;;;;;;;;
wheelScrolled: ;Mouse Wheel scrolled
	{
	if chargedMelee{
		updateInputUI("CC6600", "meleeText")
		send {numpad5 up}
		cancelMelee := 1
		chargedMelee := 0
		setTimer, switchMelee1, off
		setTimer, switchMelee2, off
		setTimer, switchMelee3, off
		}
	return
	}	

;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BUNNY HOPPING SYSTEM ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
jumpPressed: ;Jump pressed
	{
	if !isHoldingJump{
		isHoldingJump := 1
		if enableBHop{
			goSub firstHop1
			setTimer, bHop1, % tick(16)
			setTimer, bHopHUD, % tick(16)
			}
		else if !enableBHop{
			updateInputUI(UIKeyOn, "jumpText")
			send {pause down}
			}
		}
	return
	}

jumpReleased: ;Jump released
	{
	setTimer, firstHop1, off
	setTimer, firstHop2, off
	setTimer, bHop1, off
	setTimer, bHop2, off
	isHoldingJump := 0
	updateInputUI(UIKeyOff, "jumpText")
	send {space up}
	send {pause up}
	return
	}

firstHop1: ;Initial Bhop Jump phase 1
	{
	updateInputUI(UIKeyOn, "jumpText")
	send {pause down}
	setTimer, firstHop2, % tick(8)
	setTimer, firstHop1, off
	return
	}

firstHop2: ;Initial Bhop Jump phase 2
	{
	updateInputUI("FF8800", "jumpText")
	send {pause up}
	setTimer, firstHop2, off
	return
	}

bHop1: ;Bhop Spam phase 1
	{
	;updateInputUI("FFFF00", "jumpText")
	send {pause down}
	setTimer, bHop2, % tick()
	setTimer, bHop1, off
	return
	}

bHop2: ;Bhop Spam phase 2
	{
	send {pause up}
	setTimer, bHop1, % tick()
	setTimer, bHop2, off
	if !getKeyState("Space", "P"){
		goSub jumpReleased
		}
	return
	}

bHopHUD: ;Bhop HUD
	{
	if getKeyState("Space", "P"){
		updateInputUI("FFFF00", "jumpText")
		}
	setTimer, bHopHUD, off
	return
	}

;;;;;;;;;;;;;;;;;;;
;; AIMING SYSTEM ;;
;;;;;;;;;;;;;;;;;;;
aimPressed: ;Aim pressed
	{
	if !isHoldingAim{
		isHoldingAim := 1
		if enableAutoBreath{
			send {numpad7 down}
			}
		UI_hideRet()
		retState(2)
		UI_showRet()
		if showUI_firingMode{
		updateInputUI(UIKeyOn, "aimText")
			Gui		firingModeADSDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			WinSet, Transparent, 0
			Gui		firingModeHipDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
			WinSet, Transparent, 127
			}
		if !chargedFiringMode{
			firingMode := firingModeADS
			}
		}
	goSub jumpReleased
	return
	}

aimReleased: ;Aim released
	{
	isHoldingAim := 0
	updateInputUI(UIKeyOff, "aimText")
	UI_hideRet()
	retState(1)
	UI_showRet()
	if showUI_firingMode{
		Gui		firingModeHipDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
		WinSet, Transparent, 0
		Gui		firingModeADSDark:	+LastFound +AlwaysOnTop -Caption +ToolWindow +Disabled +E0x20
		WinSet, Transparent, 127
		}
	send {numpad7 up}
	if !chargedFiringMode{
		firingMode := firingModeHip
		}
	return
	}

;;;;;;;;;;;;;;;;;;;
;; SPRINT SYSTEM ;;
;;;;;;;;;;;;;;;;;;;
sprintPressed: ;Sprint pressed
	{
	if !isHoldingSprint{
		updateInputUI(UIKeyOn, "sprintText")
		isHoldingSprint := 1
		send {numpad7 down}
		goSub crouchReleased
		goSub proneReleased
		goSub jumpReleased
		proneCount := proneCountMax
		}
	return
	}

sprintReleased: ;Sprint released
	{
	updateInputUI(UIKeyOff, "sprintText")
	isHoldingSprint := 0
	if !getKeyState("RBUTTON", "p"){
		send {numpad7 up}
		}
	proneCount := 0
	return
	}

;;;;;;;;;;;;;;;;;;;;;
;; AUTOMARK SYSTEM ;;
;;;;;;;;;;;;;;;;;;;;;
sendMark1: ;Send AutoMark phase 1
	{
	setTimer, sendMark1, off
	if !markOut AND isHoldingAim AND isHoldingFire{
		setTimer, sendMark2, % tick(2)
		markOut := "1"
		send {Q down}
		setTimer, sendMark3, % tick(autoMarkCooldown)
		}
	return
	}

sendMark2: ;Send AutoMark phase 2
	{
	setTimer, sendMark2, off
	send {Q Up}
	return
	}

sendMark3: ;Send AutoMark phase 3
	{
	setTimer, sendMark3, off
	markOut := "0"
	if isHoldingAim AND isHoldingFire{
		setTimer, sendMark1, % tick(2)
		}
	}

;;;;;;;;;;;;;;;;
;; TAB SYSTEM ;;
;;;;;;;;;;;;;;;;
tabPressed: ;Tab pressed
	{
	if getKeyState("LAlt", "p"){
		keywait LAlt
		send {LAlt up}
		reload
		}
	return
	}

;;;;;;;;;;;;;;;;;;;
;;SCRIPT HANDLING;;
;;;;;;;;;;;;;;;;;;;
Shift & F5:: ;Shift F5 to exit
	keepscript := "game.ahk"
			for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process where name = 'Autohotkey.exe' and not CommandLine like '%" keepscript "%' "){
		process, close, % process.ProcessId
	}	
	exitapp

;#If WinActive("ahk_exe game.exe")
F5:: ;F5 to refresh
	send {F5}
	reload
	return

LAlt & Tab:: ;ALT Tab handler
	goSub crouchReleased
	send {blind}{Alt up}
	send {blind}{Tab up}
	send {Alt down}{tab}
	keywait LAlt
	keywait Tab
	return
thanks.
Attachments
Preview.png
Preview of UI
Preview.png (10.83 KiB) Viewed 790 times

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Looking for feedback on my code

Post by t3h m00kz » 16 Sep 2022, 22:00

Bumping this ONCE.

I want to know if there are ways to optimize what I'm doing here.

tes
Posts: 15
Joined: 13 Feb 2021, 09:41

Re: Looking for feedback on my code

Post by tes » 17 Sep 2022, 04:31

Not that i have fully read your script to make sense of it because i haven't but one thing i did notice though.

You have a lot of variables Make your variables local if there is no need for them to be global better for performance. Side note all variables outside of a function are considered global so you don't need to define them as global. Try to invoke your variables inside each function or hotkey instead of globally its faster and the variable is cleared from memory when that code is finished. Otherwise if you need a global then you need one. Try to minimize your variable count if any of those values are constants then they don't need a variable.

Make use of #include to where you can split your code up over several ahk scripts so that you can have an easier time reading it. Example environment flags and #directives go in its own script one for UI one for hotkeys etc you don't have to do this but breaking your code up over several scripts helps readability, for example when you know something is wrong with the UI or you want to make changes then you can go and look at that script without all the other stuff in your way. No one likes scrolling lines its nice when a script can fit on you screen and you can read the whole thing without zooming out or paging/scrolling.

less code is probably the best thing to account for try to achieve what you want to do with less lines this is the biggest performance saver.

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Looking for feedback on my code

Post by boiler » 17 Sep 2022, 05:59

tes wrote: Side note all variables outside of a function are considered global so you don't need to define them as global.
They have to be declared as global in order for them to be used inside functions, or else the functions can’t see them. If not, they are only in the global namespace outside of any functions.

tes wrote: Make use of #include to where you can split your code up over several ahk scripts so that you can have an easier time reading it. … No one likes scrolling lines its nice when a script can fit on you screen and you can read the whole thing without zooming out or paging/scrolling.
Splitting code into separate files by logical sections is one thing (if desired — I generally don’t except for library functions). Breaking a script up arbitrarily so that each section fits on your screen without scrolling is not something I recommend and I believe most would not consider a good practice. Scrolling is not necessarily worse than having to jump between files.

Unless you’re just using Notepad, your editor probably has features that let you jump directly to desired functions and subroutines rather than just scrolling until you find them. There are AHK scripts you can add to almost any editor to add this functionality if your editor doesn’t have it. See TillaGoto.

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Looking for feedback on my code

Post by t3h m00kz » 21 Sep 2022, 18:10

tes wrote:
17 Sep 2022, 04:31
Not that i have fully read your script to make sense of it because i haven't but one thing i did notice though.

You have a lot of variables Make your variables local if there is no need for them to be global better for performance. Side note all variables outside of a function are considered global so you don't need to define them as global. Try to invoke your variables inside each function or hotkey instead of globally its faster and the variable is cleared from memory when that code is finished. Otherwise if you need a global then you need one. Try to minimize your variable count if any of those values are constants then they don't need a variable.
I'm definitely throwing around a ton of variables at the moment, as I have a ton of systems in place interacting with each other. I'm mainly focusing on keeping it decently legible, so I wouldn't doubt for a second there's cleaner ways of doing things. Though if there are any tricks or practices I haven't implemented, I can't say I know what they are.

If there are any obvious "why the f are you doing it the hard way" bits that stick out, I'm open to learning better techniques
tes wrote:
17 Sep 2022, 04:31
less code is probably the best thing to account for try to achieve what you want to do with less lines this is the biggest performance saver.
agreed.

I have a lot of large lines that are very similar with the exception of one or two components, and I'm uncertain how to consolidate them further.
boiler wrote:
17 Sep 2022, 05:59
Splitting code into separate files by logical sections is one thing (if desired — I generally don’t except for library functions). Breaking a script up arbitrarily so that each section fits on your screen without scrolling is not something I recommend and I believe most would not consider a good practice. Scrolling is not necessarily worse than having to jump between files.
I have to agree with this - I used to do this when I was first learning, trying to split up various sections into separate files to keep things more organized, but it just turned into an include-fest and skimming through tabs trying to CTRL+F through 10+ files trying to find what I'm looking for and it's honestly more trouble than just scrolling through. VSCode has a very nice scroll preview that helps a ton and reduces headache
boiler wrote:
17 Sep 2022, 05:59
Unless you’re just using Notepad, your editor probably has features that let you jump directly to desired functions and subroutines rather than just scrolling until you find them. There are AHK scripts you can add to almost any editor to add this functionality if your editor doesn’t have it. See TillaGoto.
My current workspace is a mix of VS Code and Notepad++.
layout.png
layout.png (246.51 KiB) Viewed 527 times
VSCode has a ton of nice features and debugging capabilities, but sometimes NP++ is just cleaner for quick edits. Plus VSCode doesn't spit script crashes or errors at me, even though I could've sworn it used to somewhere... Still learning the UI after using NP++ exclusively for so long. 💦

But I'll definitely have a look at TillaGoto

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Looking for feedback on my code

Post by boiler » 22 Sep 2022, 06:38

I still use Notepad++ a lot for text files and stuff, but for AHK, I solely use VSCode (except for CodeQuickTester by Geek for small scripts that I’m not even going to save to a file). It has some really nice editing features that even NP++ doesn’t have. I think you’ll find as you get more comfortable with VSCode, you won’t need or want to use both anymore, but I don’t know exactly what you’re finding NP++ better for other than familiarity. Not sure what you mean about the crashes/errors that you’re not getting from VSCode.

User avatar
t3h m00kz
Posts: 10
Joined: 07 Sep 2022, 00:25

Re: Looking for feedback on my code

Post by t3h m00kz » 24 Sep 2022, 21:21

boiler wrote:
22 Sep 2022, 06:38
I still use Notepad++ a lot for text files and stuff, but for AHK, I solely use VSCode (except for CodeQuickTester by Geek for small scripts that I’m not even going to save to a file). It has some really nice editing features that even NP++ doesn’t have. I think you’ll find as you get more comfortable with VSCode, you won’t need or want to use both anymore, but I don’t know exactly what you’re finding NP++ better for other than familiarity. Not sure what you mean about the crashes/errors that you’re not getting from VSCode.
VSCode isn't spitting these out for me. It just fails to run with no prompt as to what failed.
image.png
image.png (14.62 KiB) Viewed 438 times

Post Reply

Return to “Gaming Help (v1)”