Everytime a loop breaks it repeats the last set of actions twice Topic is solved

Ask gaming related questions (AHK v1.1 and older)
ftlsxp
Posts: 13
Joined: 02 Jan 2022, 23:31

Everytime a loop breaks it repeats the last set of actions twice

Post by ftlsxp » 03 Jul 2022, 11:21

Hi there. As I stated on the title of the post I made a script following this logic to create it:


A main loop for it to repeat indefinitely:

Loop for check condition 1. If reached break the loop and send a hotket. Starts a new loop to check for condition 2. If reached it triggers a sequence of actions (about 9 clicks). Rinse and repeat.

Everything was working ok'ish until I decided I wanted to be able to start/pause the loop with a hotkey but without pausing/suspending the whole script since my idea was to merge another 3 scripts I have made here and it starts to get messy to have more then 5 icons on the taskbar. The best solution I've been able to find with some help was to use (toggle := !toggle) and use the condition of (toggle=0) on the breaks for the loops. It works but every time I "turn off" the script it launches the the last sequence part twice in a row and then it stand by.

I tried using timers and labels instead but it would got stuck on the loop so the solution above was the best I could reach with the level of knowledge that I have on coding that is almost none.

So please if you can help me I would appreciate it a lot. Also if you have an idea to a more elegant/efficient approach I would love to hear about it.

Thank you so much.

Almost forgot the code.

Code: Select all

;========================
#NoEnv 
#SingleInstance, force
;~ #persistent
#MaxThreadsPerHotkey, 2
CoordMode, Pixel, screen
CoordMode, Mouse, screen
SetKeyDelay,-1
SendMode Input
SetBatchLines, -1
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
WinGet, OutputVar, ID, ahk_exe client.exe
WinSet, Transparent, 1, ahk_exe client.exe
SetWorkingDir %A_ScriptDir%
IniRead, mx, %A_ScriptFullPath%, SavedVariables, CharSqmX
IniRead, my, %A_ScriptFullPath%, SavedVariables, CharSqmY
IniRead, pxX2, %A_ScriptFullPath%, SavedVariables, RightSqmX
IniRead, pxY2, %A_ScriptFullPath%, SavedVariables, RightSqmy
OnExit("ExitFunc")



; ImageSearch Variables - AutoAtack
VarAtk := 105
VarBL := 90
corHp := EC0505

; ImageSearch Variables - Atk Status
X1 := 2382
Y1 := 479
X2 := 2558
Y2 := 587

; ImageSearch Variables - Battle List 
xB1 := 2380
yB1 := 479
xB2 := 2558
yB2 := 806

; Looter Variables 
var := (pxX2 - mx)
var2 := (var * 0.1)
Random, rVar, -%var2%, %var2%
RSMin := 85
RSMax := 111
;================================
mx1 := (mx - var) - rVar
my1 := (my - var) - rVar
mx2 := (mx) + rVar
my2 := (my - var) - rVar
mx3 := (mx + var) + rVar
my3 := (my - var) - rVar
;================================
mx4 := (mx + var) + rVar
my4 := (my) + rVar
mx5 := (mx + var) + rVar
my5 := (my + var) + rVar
mx6 := (mx) + rVar
my6 := (my + var) + rVar
;================================
mx7 := (mx - var) - rVar
my7 := (my + var) + rVar
mx8 := (mx - var) - rVar
my8 := (my) + rVar
mx9 := (mx) + rVar
my9 := (my) + rVar


;~ #If WinActive("ahk_exe client.exe")



; |Auto Atack| - Thurn this aid On/Off

F9::
(toggle := !toggle)
ToolTip, Auto Atack is %toggle%
SetTimer, ToolTipOff, -3000

Loop
{
	Loop
	{
		ImageSearch, ISY, ISY, 2370, 477, 2559, 595, *%VarBL% Imagens\BattleList.png
		BattleList := ErrorLevel
		if (BattleList = 1) || (toggle=0) ; Battle list not empty
		{
			break
		}
	}
	ControlFocus,, ahk_id %OutputVar%
	ControlSend,, {Space}, ahk_id %OutputVar% ; Send atack Hotkey
	Loop ; Whait monster to die
	{
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkVerde.png
		AtkBoxG := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkAmarelo.png
		AtkBoxY := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkVermelho.png
		AtkBoxR := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkCrit.png
		AtkBoxC := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkVerdeRed.png
		AtkBoxGR := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkAmareloRed.png
		AtkBoxYR := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkVermelhoRed.png
		AtkBoxRR := ErrorLevel
		ImageSearch, ISX, ISY, X1, Y1, X2, Y2, *%VarAtk% Imagens\TesteAtkCritRed.png
		AtkBoxCR := ErrorLevel
		if ((AtkBoxG = 1) && (AtkBoxY = 1) && (AtkBoxR = 1) && (AtkBoxC = 1) && (AtkBoxGR = 1) && (AtkBoxYR = 1) && (AtkBoxRR = 1) && (AtkBoxCR = 1)) || (toggle=0)
		{
			break
		}
	}
	if (toggle=0)
	{
		break
	}
	Sleep 100
	MouseGetPos, aX, aY
	Send {Shift Down}
	Sleep 50
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx1, my1)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx2, my2)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx3, my3)
	RandSleep(RSMin,RSMax)
	;========================================
	RightClickRandomized(mx4, my4)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx5, my5)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx6, my6)
	RandSleep(RSMin,RSMax)
	;========================================
	RightClickRandomized(mx7, my7)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx8, my8)
	RandSleep(RSMin,RSMax)
	RightClickRandomized(mx9, my9)
	RandSleep(RSMin,RSMax)
	Sleep 50
	Send {Shift Up}
	MouseMove, aX, aY 
}
return

;~ #If WinActive

; |SQM Position Setup| - If Autoloot is not clicking on the correct SQM it needs to be configured. Position the cursor on the center of the SQM of your character and press the hotkey bellow.

ScrollLock:: 
MouseGetPos, mx, my
IniWrite, %mx%, %A_ScriptFullPath%, SavedVariables, CharSqmX
IniWrite, %my%, %A_ScriptFullPath%, SavedVariables, CharSqmY
ToolTip, Position 1 Setup OK`nPut you cursor on the next SQM to the right and press %A_ThisHotkey% again. ->
KeyWait, %A_ThisHotkey%, U
KeyWait, %A_ThisHotkey%, D
ToolTip,
MouseGetPos, pxX2, pxY2
IniWrite, %pxX2%, %A_ScriptFullPath%, SavedVariables, RightSqmX
IniWrite, %pxY2%, %A_ScriptFullPath%, SavedVariables, RightSqmy
ToolTip, Position 2 Setup OK
KeyWait, %A_ThisHotkey%, U
ToolTip,
return


;~ +Esc::
;~ ExitApp
;~ return



ToolTipOff:
ToolTip
return


ExitFunc() 
{
    ControlFocus,, ahk_id %OutputVar%
    WinSet, Transparent, 255, ahk_exe client.exe
    return
}


RandSleep(x,y) 
{
	Random, rand, %x%, %y%
	Sleep %rand%
}


LeftClick(x, y)
{
	click, %x%, %y%
}


LeftClickRandomized(x, y)
{
	LeftClick(AddRandomToPosition(x), AddRandomToPosition(y))
}


RightClick(x, y)
{
	click, right, %x%, %y%
}


RightClickRandomized(x, y)
{
	RightClick(AddRandomToPosition(x), AddRandomToPosition(y))
}


AddRandomToPosition(pos, minDeviation:=0.0, maxDeviation:=8.0)
{
	Random, rand, minDeviation, maxDeviation
	Random, sumOrSubtract, 1, 2

	if (Mod(sumOrSubtract, 2) > 0) {
		return pos + rand
	} else {
		return pos - rand
	}



/*
This is an ini saved variable section.
You can write whatever you want here because AHK sees it as a comment.
Anything [insideBrackets] starts a new section. This is what the script looks for when dealing with ini files.

[SavedVariables]
CharSqmX =1829
CharSqmY =365
RightSqmX =1875
RightSqmy =367

*/
;============================== End Script ==============================


[Mod action: Moved topic to “Gaming”]
Last edited by ftlsxp on 03 Jul 2022, 13:39, edited 2 times in total.

RussF
Posts: 1268
Joined: 05 Aug 2021, 06:36

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by RussF » 03 Jul 2022, 11:41

More people will be inclined to look at your code if you post it here rather than from a link. I know that I, at least, am hesitant to follow an unknown link. Be sure to put it between [code][/code] tags.

Russ

User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Everytime a loop breaks it repeats the last set of actions twice  Topic is solved

Post by mikeyww » 03 Jul 2022, 11:43

How to debug a computer program? One helpful addition can be displaying the values of your variables, conditional statements, & functions. You can also have a look at ListLines. These approaches will help you to pinpoint the issue quickly.

Variables inside functions are null unless you set them there or use a globally declared variable.

You can shorten your script, to test just the most critical parts that you think could be involved in your bug.

ImageSearch can have three possible ErrorLevels: 0, 1, or 2.

ftlsxp
Posts: 13
Joined: 02 Jan 2022, 23:31

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by ftlsxp » 03 Jul 2022, 13:17

It is a pastebin link. 🤔 What is wrong with pastebin?

But I've pasted the code on the body of the message.

Thanks for your time.
@RussF
Last edited by ftlsxp on 03 Jul 2022, 13:26, edited 1 time in total.

ftlsxp
Posts: 13
Joined: 02 Jan 2022, 23:31

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by ftlsxp » 03 Jul 2022, 13:22

mikeyww wrote:
03 Jul 2022, 11:43
How to debug a computer program? One helpful addition can be displaying the values of your variables, conditional statements, & functions. You can also have a look at ListLines. These approaches will help you to pinpoint the issue quickly.

Variables inside functions are null unless you set them there or use a globally declared variable.

You can shorten your script, to test just the most critical parts that you think could be involved in your bug.

ImageSearch can have three possible ErrorLevels: 0, 1, or 2.
Hey Mikeyww how are you?

I already tried debugging in. The image searches are OK. Returning the appropriate errorLevels.

There are no functions on my code that interfere with the main loop. So that is not the case also.

Really don't know what can be the cause of it.

User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by mikeyww » 03 Jul 2022, 13:44

A demonstration is below. If it works, it gives you a basis to expand. An alternative is a SetTimer, but a timed routine will still complete its iteration unless Return, Reload, Pause, or something else stops it.

Code: Select all

#MaxThreadsPerHotkey 2
F3::
on := !on
SoundBeep, 1000 + 500 * on
While on {
 Loop {
  Sleep, 400 * on
  If on
   Send 0               ; Do something
 } Until !on || 1 = 1   ; Check condition 1. If reached, break the loop,
 If on
  Send 1                ;  and send a key
 Loop {
  Sleep, 400 * on
  If (2 = 2 && on) {    ; Check condition 2. If reached,
   Send 2               ;  trigger a sequence of actions
   Send 3
  }
 } Until !on || 3 = 3   ; Check condition 3. If reached, break the loop
}
Return
It sounds like you have not reached the point where you are checking each variable, conditional statement, and returned function value.

ftlsxp
Posts: 13
Joined: 02 Jan 2022, 23:31

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by ftlsxp » 03 Jul 2022, 15:47

mikeyww wrote:
03 Jul 2022, 13:44
A demonstration is below. If it works, it gives you a basis to expand. An alternative is a SetTimer, but a timed routine will still complete its iteration unless Return, Reload, Pause, or something else stops it.

Code: Select all

#MaxThreadsPerHotkey 2
F3::
on := !on
SoundBeep, 1000 + 500 * on
While on {
 Loop {
  Sleep, 400 * on
  If on
   Send 0               ; Do something
 } Until !on || 1 = 1   ; Check condition 1. If reached, break the loop,
 If on
  Send 1                ;  and send a key
 Loop {
  Sleep, 400 * on
  If (2 = 2 && on) {    ; Check condition 2. If reached,
   Send 2               ;  trigger a sequence of actions
   Send 3
  }
 } Until !on || 3 = 3   ; Check condition 3. If reached, break the loop
}
Return
It sounds like you have not reached the point where you are checking each variable, conditional statement, and returned function value.
Thanks for the guidance. I just dont get this "* on". What does it do?

User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by mikeyww » 03 Jul 2022, 16:34

I wanted to be able to start/pause the loop with a hotkey but without pausing/suspending the whole script
on is a toggle that tells the rest of the routine whether to keep going. It doesn't actually pause, but causes the routine to end (more precisely, causes the remaining commands to be skipped). If you actually need a pause or simulated pause, then you would need (for example) variables to track the routine's progress, a series of additional loops that could check a variable or other status, or a separate script where you can use a Pause command.

In many cases, Pause can work. This command does not prevent hotkeys from being triggered. A demonstration of Pause is below.

Code: Select all

Loop {
 Send x
 Sleep, 20
}
F3::Pause
F4::
Send 1
Send 2
Return
Unlike Suspend -- which disables hotkeys and hotstrings -- turning on pause will freeze the current thread. As a side-effect, any interrupted threads beneath it will lie dormant. Whenever any thread is paused, timers will not run. By contrast, explicitly launched threads such as hotkeys and menu items can still be launched; but when their threads finish, the underlying thread will still be paused. In other words, each thread can be paused independently of the others.

ftlsxp
Posts: 13
Joined: 02 Jan 2022, 23:31

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by ftlsxp » 03 Jul 2022, 17:05

mikeyww wrote:
03 Jul 2022, 16:34
I wanted to be able to start/pause the loop with a hotkey but without pausing/suspending the whole script
on is a toggle that tells the rest of the routine whether to keep going. It doesn't actually pause, but causes the routine to end (more precisely, causes the remaining commands to be skipped). If you actually need a pause or simulated pause, then you would need (for example) variables to track the routine's progress, a series of additional loops that could check a variable or other status, or a separate script where you can use a Pause command.

In many cases, Pause can work. This command does not prevent hotkeys from being triggered. A demonstration of Pause is below.

Code: Select all

Loop {
 Send x
 Sleep, 20
}
F3::Pause
F4::
Send 1
Send 2
Return
Unlike Suspend -- which disables hotkeys and hotstrings -- turning on pause will freeze the current thread. As a side-effect, any interrupted threads beneath it will lie dormant. Whenever any thread is paused, timers will not run. By contrast, explicitly launched threads such as hotkeys and menu items can still be launched; but when their threads finish, the underlying thread will still be paused. In other words, each thread can be paused independently of the others.
Sorry i think i was not able to make myself clear. I do get what is the "on" part. I wasn't able to get the " * on " but i was tinkering with your example and it is literally "times 0 or 1" right? Depending on the state of "on".

Thank you for your help.

Can you please guide me towards making the script modular? Or do you think it is better to make one script with only the hotkeys that launch other scripts?

User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Everytime a loop breaks it repeats the last set of actions twice

Post by mikeyww » 03 Jul 2022, 18:47

Correct, as * in an expression denotes multiplication, !0 = 1, !1 = 0, and !"" = 1.

You can put that hotkey routine into another script if you wish.

Post Reply

Return to “Gaming Help (v1)”