Warframe Macros (including Slide-Attack Macro)

Post gaming related scripts
Arsonistic
Posts: 1
Joined: 10 Oct 2019, 13:51

Warframe Macros (including Slide-Attack Macro)

17 Oct 2019, 20:41

I threw together some "anti-athritis" macros for Warframe.
They all work concurrently by multi-threading through the use of Timers.

Slide-Attack: Shift+Alt(+movement in direction of your choice). Hold Alt for spam. Ctrl+Up/Down (arrows) to change delay between attacks (Warframe uses a queue-system for melee attacks, so if melee is spammed too quickly you'll get normal attacks in between your slide-attacks). Note: Requires U bound as secondary button for melee.
Rapid-Fire: Ctrl+L to activate/deactivate. Hold left/scroll-click to spam Primary-/Secondary-Fire as quick as possible.
Ability-Spam: AltGr+AbilityButton (1-4) to toggle On/Off. AltGr+PageUp/Down to adjust delay between activations. Ctrl+PageUp/Down to change increment for changing the delay. Win+AbilityButton to choose ability to change.

I will likely not update the code pasted here, refer to the gist for potential updates/fixes: gist.github.com/KarlRamstedt/758553272a042c4a94bef02ab5bdec2c

Code: Select all

#NoEnv			; Recommended for performance and compatibility with future AutoHotkey releases
SendMode Input	; Recommended for new scripts due to superior speed and reliability

; Modifiers(place before button to require/ignore extra buttons): [+ = Shift] [! = Alt] [^ = Ctrl] [# = Win] [* = Ignores modifiers] [~ = Also uses original function]
; Hotkeys will repeat without loop (akin to holding down a letter when typing to make it repeat), but making it a loop will make it repeat without a delay before the repeat starts, along with not stopping when pressing other keys (like movement keys to change direction)
; All time values listed are in ms(MilliSeconds), which are 1/1000 of a second. 1000/loopDelay = activationsPerSecond. I.e: 50ms delay -> 1000/50 = 20 per sec

global rapidFire := false
global shooting := false

global spinning := false
global spinDelay := 200 ; 200ms (1000/200 = 5 per sec) is close to the (slide)Attack Speed cap for Whips. 160 is too fast and will yield normal, non-slide attacks
global spinDelayIncrement := 10 ; How much you want it to change with each adjustment

global autoSpam := true
global spammingAbility := [false, false, false, false]
global abilitySpam := [false, false, false, false]
global abilityDelay := [500, 9000, 9000, 10500]	; Delay between activations for ability 1, 2, 3 and 4, respectively
global delayToModify := 4
global incrementIncrement := 50
global abilityDelayIncrement := 500

#MaxThreadsPerHotkey 1	; Looping hotkeys only start timers and should not be able to have multiple instances

#IfWinActive Warframe	; Only allow macros to run when Warframe Window is active

	^L::	; Ctrl+L toggles auto-spam for Primary- and Secondary-Fire. For use with rapid-fire Semi-Auto weapons
		rapidFire := !rapidFire
		if (rapidFire)
			CenteredToolTip("Rapid-Fire On")
		else
			CenteredToolTip("Rapid-Fire Off")
	return

	~*LButton::	; Ignores modifiers(*) to ensure that sliding and running don't interrupt shooting. Without ~ clicks in Steam-Overlay stop working
		if (rapidFire && !shooting){
			shooting := true
			PFireDown()
		}
	return
	PFireDown(){
		if (rapidFire && GetKeyState("LButton", "P")){
			Send, {LButton down}	; Works without up and down, but ingame UI clicks stop registering without them
			SetTimer, PFireUp, -25	; Negative values are single-trigger
		} else
			shooting := false
	}
	PFireUp(){
		Send, {LButton up}
		SetTimer, PFireDown, -25	; Total delay is 50ms, i.e: 20 per sec. I believe Semi-Auto weapons have a cap of 10 shots per second
	}

	~*MButton:: ; Secondary-Fire, mainly for use with Amps
		if (rapidFire && !shooting){
			shooting := true
			SetTimer, SecondaryFire, 50
		}
	return
	SecondaryFire(){
		if (rapidFire && GetKeyState("MButton", "P")){
			Send, {MButton}
		} else {
			shooting := false
			SetTimer, SecondaryFire, Off
		}
	}

	; Warframe uses a command queue system for melee inputs, so to avoid queueing up a normal attack after a slide you can tune the value with Shift+PageUp/Down
	+PgUp::
		spinDelay := spinDelay+spinDelayIncrement
		CenteredToolTip("SpinDelay: " . spinDelay . "ms")	; Periods concatenate strings
		if (spinning)
			SetTimer, Spin, %spinDelay%
	return
	+PgDn::
		if (spinDelay > spinDelayIncrement) ; Avoid 0 and negative values
			spinDelay := spinDelay-spinDelayIncrement
		CenteredToolTip("SpinDelay: " . spinDelay . "ms")
		if (spinning)
			SetTimer, Spin, %spinDelay%
	return

	+LAlt::							; Triggers with Shift+LeftAlt. Swap to "*" to trigger without holding Shift
		if (!spinning){
			spinning := true
			SetTimer, Spin, %spinDelay%
			Spin()
		}
	return
	Spin(){
		if (GetKeyState("LAlt", "P")){	; Loops while holding the button
			Send, {LCtrl down}			; Crouch key
			Send, u						; Melee key
			Send, {LCtrl up}			; No delay needed between Crouch down and up. Also has the bonus of removing the "shake" of spam-crouching
		} else {
			spinning := false
			SetTimer, Spin, Off
		}
	}

	; Win+AbilityKey to select ability for modification of delay
	#1::
		delayToModify := 1
		CenteredToolTip("Modifying Ability 1 (Current Delay: " . abilityDelay[delayToModify] . "ms)")
	return
	#2::
		delayToModify := 2
		CenteredToolTip("Modifying Ability 2 (Current Delay: " . abilityDelay[delayToModify] . "ms)")
	return
	#3::
		delayToModify := 3
		CenteredToolTip("Modifying Ability 3 (Current Delay: " . abilityDelay[delayToModify] . "ms)")
	return
	#4::
		delayToModify := 4
		CenteredToolTip("Modifying Ability 4 (Current Delay: " . abilityDelay[delayToModify] . "ms)")
	return
	
	; Ctrl+PageUp/Down to adjust increment for adjusting delay between ability activations
	^PgUp::
		abilityDelayIncrement := abilityDelayIncrement+incrementIncrement
		CenteredToolTip("Ability Delay Increment: " . abilityDelayIncrement . "ms")
	return
	^PgDn::
		if (abilityDelayIncrement > incrementIncrement)	; Avoid 0 and negative values
			abilityDelayIncrement := abilityDelayIncrement-incrementIncrement
		CenteredToolTip("Ability Delay Increment: " . abilityDelayIncrement . "ms")
	return
	
	; AltGr+PageUp/Down to adjust delay between ability activations
	<^>!PgUp::
		abilityDelay[delayToModify] := abilityDelay[delayToModify]+abilityDelayIncrement
		CenteredToolTip("Ability " . delayToModify . " Delay: " . abilityDelay[delayToModify] . "ms")
		if (abilitySpam[delayToModify] && autoSpam)
			SetTimer, Spam%delayToModify%, % abilityDelay[delayToModify]	; Update running timers
	return
	<^>!PgDn::
		if (abilityDelay[delayToModify] > abilityDelayIncrement)	; Avoid 0 and negative values
			abilityDelay[delayToModify] := abilityDelay[delayToModify]-abilityDelayIncrement
		CenteredToolTip("Ability " . delayToModify . " Delay: " . abilityDelay[delayToModify] . "ms")
		if (abilitySpam[delayToModify] && autoSpam)
			SetTimer, Spam%delayToModify%, % abilityDelay[delayToModify]
	return
	
	<^>!K::	; AltGr+K to turn On/Off automatic spam of abilities
		autoSpam := !autoSpam
		if (autoSpam){
			CenteredToolTip("Auto-Spam On")
			for i, spam in abilitySpam {
				if (spam){
					SetTimer, Spam%i%, % abilityDelay[i]
					Send, %i%
				}
			}
		} else
			CenteredToolTip("Auto-Spam Off")
	return

	; Turn on ability spam by pressing AltGr+AbilityKey for the one you want to turn it on for
	<^>!1::
		abilitySpam[1] := !abilitySpam[1]
		if (abilitySpam[1]){
			CenteredToolTip("Ability 1 Spam On (Delay: " . abilityDelay[1] . "ms)")
			if (autoSpam){
				Send, 1
				SetTimer, Spam1, % abilityDelay[1]
			}
		} else
			CenteredToolTip("Ability 1 Spam Off")
	return
	~*1::
		if (abilitySpam[1] && !spammingAbility[1]){
			spammingAbility[1] := true
			SetTimer, Spam1, % abilityDelay[1]
		}
	return
	Spam1(){
		if (abilitySpam[1] && (autoSpam || GetKeyState("1", "P"))){
			Send, 1
		} else {
			spammingAbility[1] := false
			SetTimer, Spam1, Off
		}
	}
	
	<^>!2::
		abilitySpam[2] := !abilitySpam[2]
		if (abilitySpam[2]){
			CenteredToolTip("Ability 2 Spam On (Delay: " . abilityDelay[2] . "ms)")
			if (autoSpam){
				Send, 2
				SetTimer, Spam2, % abilityDelay[2]
			}
		} else
			CenteredToolTip("Ability 2 Spam Off")
	return
	~*2::
		if (abilitySpam[2] && !spammingAbility[2]){
			spammingAbility[2] := true
			SetTimer, Spam2, % abilityDelay[2]
		}
	return
	Spam2(){
		if (abilitySpam[2] && (autoSpam || GetKeyState("2", "P"))){
			Send, 2
		} else {
			spammingAbility[2] := false
			SetTimer, Spam2, Off
		}
	}
	
	<^>!3::
		abilitySpam[3] := !abilitySpam[3]
		if (abilitySpam[3]){
			CenteredToolTip("Ability 3 Spam On (Delay: " . abilityDelay[3] . "ms)")
			if (autoSpam){
				Send, 3
				SetTimer, Spam3, % abilityDelay[3]
			}
		} else
			CenteredToolTip("Ability 3 Spam Off")
	return
	~*3::
		if (abilitySpam[3] && !spammingAbility[3]){
			spammingAbility[3] := true
			SetTimer, Spam3, % abilityDelay[3]
		}
	return
	Spam3(){
		if (abilitySpam[3] && (autoSpam || GetKeyState("3", "P"))){
			Send, 3
		} else {
			spammingAbility[3] := false
			SetTimer, Spam3, Off
		}
	}
	
	<^>!4::
		abilitySpam[4] := !abilitySpam[4]
		if (abilitySpam[4]){
			CenteredToolTip("Ability 4 Spam On (Delay: " . abilityDelay[4] . "ms)")
			if (autoSpam){
				Send, 4
				SetTimer, Spam4, % abilityDelay[4]
			}
		} else
			CenteredToolTip("Ability 4 Spam Off")
	return
	~*4::
		if (abilitySpam[4] && !spammingAbility[4]){
			spammingAbility[4] := true
			SetTimer, Spam4, % abilityDelay[4]
		}
	return
	Spam4(){
		if (abilitySpam[4] && (autoSpam || GetKeyState("4", "P"))){
			Send, 4
		} else {
			spammingAbility[4] := false
			SetTimer, Spam4, Off
		}
	}

#IfWinActive

^P::Suspend		; Ctrl+P toggles hotkeys On/Off
#P::Pause		; Win+P toggles execution Pause
<^>!R::Reload	; AltGr+R reloads script

CenteredToolTip(text, duration = 999){		; Duration in ms (MilliSeconds). Default value can be optionally overridden
	ToolTip, %text%, A_ScreenWidth/2, A_ScreenHeight/2
	SetTimer, RemoveToolTip, -%duration%	; Negative to only trigger once
}
RemoveToolTip(){
	ToolTip
}

#MaxThreadsBuffer On				; To make auto-repeat quicker for implicit auto-spam of operator mode
~*CapsLock::SetCapsLockState, Off	; Automatically disable after pressing. Because I'm using CapsLock as Transference key
#MaxThreadsBuffer Off
WhiskeyJack_98
Posts: 2
Joined: 03 Nov 2019, 06:23

Re: Warframe Macros (including Slide-Attack Macro)

03 Nov 2019, 06:31

hi, since slide attack was nerfed this past update, i was wondering if you can help me. I was hoping you can create a simple script for spam "e" for melee. The action im referring to is I wanted to Hold E in order for continous melee... thank you
jensenbeach
Posts: 1
Joined: 15 Dec 2018, 22:33

Re: Warframe Macros (including Slide-Attack Macro)

15 Nov 2019, 04:33

yes i would love a script for spamming "e" for melee for orthos prime :)

Return to “Gaming”

Who is online

Users browsing this forum: No registered users and 8 guests