My code:
Func myFunc()
$lag = 1300
while (1)
MouseMove(870, 189)
sleep(10)
LC(870, 189)
sleep(1200 + $lag)
LC(1010,333)
sleep(100)
RC(826,115)
sleep(50)
LC(870,212)
sleep(50)
send("{ESC}")
sleep(150)
$x = 0
$y = 0
For $i = 0 To 27 Step 1
sleep(11)
MouseClick("left", 1158 + $x ,260 + $y)
$x+=42
if ($x = 168) Then
$x = 0
$y+=36
EndIf
Next
WEnd
EndFunc
The only delay within the for loop is the sleep(11) but it takes about .5 seconds (500ms) for each iteration rather than 11ms + whatever small delay. Also, completely removing the sleep(11) part of the loop still results in an approximately 500ms delay.
Incase anyone was wondering, it's a video game macro; the first part of the while loop opens an interface and sets something up while the second part (the for loop) is suppose to click through the inventory very quickly.
The mouse cursor takes time to move. Set the speed parameter to 0 to make it move instantly
MouseClick("left", 1158 + $x ,260 + $y,1,0)
Related
I'm having a little problem with my script here using a Logitech mouse. I will be using it for farming in a game.
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 5 then
for i = 0, 300 do
PressAndReleaseKey("f9")
Sleep(400)
PressAndReleaseKey("enter")
Sleep(600)
PressAndReleaseKey("f5")
Sleep(50)
PressMouseButton(1)
Sleep(50)
ReleaseMouseButton(1)
end
PressAndReleaseKey("1")
repeat
until IsMouseButtonPressed(3)
end
end
So it will loop for 300 times and then press 1 when it's done, then repeat the loop again for 300 times, so on & so on. Problem I'm facing is, when I'm trying to abort the script, it will first finish the for-loop before being stopped by using Right-click button(IsMouseButtonPressed(3)), which is really hard to time (300x is a lot)
How can I pause/stop it during the for-loop, would it be possible?
Frequently check if the button is pressed and break the loop.
Break up those long blocking Sleeps.
Instead of Sleep(400) consider doing something like
for i = 1, 400, 50 do
Sleep(50)
if IsMouseButtonPressed(3) then break end
end
You can use break to jump out of your for loop when IsMouseButtonPressed(3)
for i = 0, 300 do
if IsMouseButtonPressed(3) then
break -- exit for loop.
end
PressAndReleaseKey("f9")
Sleep(400)
PressAndReleaseKey("enter")
Sleep(600)
PressAndReleaseKey("f5")
Sleep(50)
PressMouseButton(1)
Sleep(50)
ReleaseMouseButton(1)
end
doing it like this means you can expect a maximum delay of 1.1 seconds due to the sleep calls, for the exit to be registered.
You could change your code by adding a function to poll IsMouseButtonPressed(3) during your sleep intervals.
local function MousePollingSleep(time)
loopCount = time / 50
for i = loopCount, 0, -1 do
if IsMouseButtonPressed(3) then
return false
end
sleepTime = (i >= 1 and 1 or i) * 50
Sleep(sleepTime)
end
return true
end
and change your for loop to
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 5 then
repeat
for i = 0, 300 do
PressAndReleaseKey("f9")
if MousePollingSleep(400) == false then break end
PressAndReleaseKey("enter")
if MousePollingSleep(600) == false then break end
PressAndReleaseKey("f5")
if MousePollingSleep(50) == false then break end
PressMouseButton(1)
if MousePollingSleep(50) == false then break end
ReleaseMouseButton(1)
end
ReleaseMouseButton(1)
PressAndReleaseKey("1")
until IsMouseButtonPressed(3)
end
end
I want to receive a string from an array using a variables' integer as the array index. But it is not working.
Attempt 1
; Suspended | 0 = No, 1 = Yes
global Suspended := 0
global SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
Pause::
Suspend
if suspended = 0 ; If script is not suspended
{
TrayTip, Paused, SuspendedMsg[Suspended], 3
Suspended++
} else ; If it is suspended
{
TrayTip, Activated, SuspendedMsg[Suspended], 3
Suspended--
}
return
Attempt #1 will just display the string "SuspendedMsg[Suspended]" because I don't know where to set the variable indicator %. Even if I set it to SuspendedMsg[%Suspended%] it will either display [1] or [0].
Attempt 2
; Suspended | 0 = No, 1 = Yes
global Suspended := 0
global SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
global SendSuspendMsg := SuspendedMsg[Suspended]
Pause::
Suspend
if suspended = 0 ; If script is not suspended
{
TrayTip, Paused, %SendSuspendMsg%, 3
Suspended++
} else ; If it is suspended
{
TrayTip, Activated, %SendSuspendMsg%, 3
Suspended--
}
return
Attempt #2 won't do as well, it doesn't even display any message. I tried fiddling arround with % inside the global SendSuspendMsg := SuspendedMsg[Suspended] variable but it won't do no good. Anyone care to help me out?
#Blauhim missed an important point, although his answer is mostly correct. First the Index in an Array when created like you did, always starts at 1, then proceeds to 2 etc, etc... So your code was flawed when you tried to use your Boolean variable to call to an index as a 0 Index does not exist (not to mention that you didn't force and Expression on that TrayTip Command).
; Set our variable to 1 why? Because we are going to use a Logical switch below.
Suspended := 1
; This was correct format and I left it, although I removed Global's as they are not needed
SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
Pause::
; Suspend toggles each time it's called
Suspend
; Here we are toggling the value of our variable using !
; We started with a 1 so that it would be correctly
;Changed to a 0 for the code below.
suspended := !suspended
; Nothing changed here
if suspended = 0 ; If script is not suspended
{
; In order to pass an Array or Object or Expression to a Command you Force it
; using the a Percent Sign with a space on either side.
; Also note you were trying to use your Logical True/False 0 or 1 variable to
; itterate. This didn't work because Array's always start with an Index of 1.
; Below I've accounted for this by simply added a 1 to your suspended so it correctly
; points to the Index in our Array.
TrayTip, Paused, % SuspendedMsg[suspended + 1], 3
} else ; If it is suspended
{
TrayTip, Activated, % SuspendedMsg[suspended + 1], 3
}
return
Instead of TrayTip, Paused, SuspendedMsg[Suspended], 3 or TrayTip, Paused, SuspendedMsg[%Suspended%], 3, try
TrayTip, Paused, % SuspendedMsg[Suspended], 3
. TrayTip asks you for a
specify the message to display
which means as much as a String. So, variables names aren't handled as variables here, but as strings instead (as most of the times in commands). It would make sense to state TrayTip, Paused, %SuspendedMsg[%Suspended%]%, 3
, but you cannot nest variable's percent signs. So, we'll have to use the percent sign to force an expression:
Force an expression: An expression can be used in a parameter that does not directly support it (except OutputVar parameters) by preceding the expression with a percent sign and a space or tab. In [v1.1.21+], this prefix can be used in the InputVar parameters of all commands except the traditional IF commands (use If (expression) instead). This technique is often used to access arrays.
Concerning your second problem: I don't think Arrays can be declared like that, can they..? (but I'm not sure). Also see this short article. So I guess the problem lies within the 3rd line of your code, because the rest of it looks good to me
I am using perl to work with database queries that return multiple results like this:
select name,percent from table order by percent desc
I want to retrieve only those values in the if condition as in this code:
while (#data=$sth->fetchrow_array()) {
$toto = $data[0];
$percent = $data[1];
foreach $percent (#data) {
if ($percent > 80) {
$output .= $toto.'='.$percent.'%,';
$state = "BAD";
}
elsif ($percent > 60 && $percent < 80){
$output .= $toto.'='.$percent.'%,';
$state = "NOTGOOD";
}
}
}
my $str = "$state $output";
# Display Ouptut
print $str."\n";
undef($str);
exit $ERRORS{$status};
This code only prints the last statement (NOTGOOD); I would like to print BAD for each missing value.
here is the result of the query:
test 40
test2 80
test3 75
test4 90
test5 50
test6 45
and here the print output:
NOTGOOD test4=90%,test2=80%,test3=75%,
all the values are good but wrong state
Your logic is very strange here. But because it's not clear whay you're trying to do, it's impossible for me to fix it for you. I can, however, hopefully explain what your current code is doing in the hope that you can work out how to fix it.
Let's assume that your query returns the following data:
Name,Percent
John,100
Paul,75
George,50
Ringo,25
Now let's step through your code a line at a time.
while (#data=$sth->fetchrow_array()) {
At this point, #data contains "John" and "100".
$toto = $data[0];
$percent = $data[1];
This puts "John" into $toto and "100" into $percent.
foreach $percent (#data) {
This is weird. It iterates over #data putting each element in turn into $percent. So on the first iteration $percent gets set to "John" (overwriting the "100" that you previously put there.
if ($percent > $opt_c) {
I don't know what $opt_c contains. Let's assume it's 50. But $percent contains "John" - which isn't a number. If you have use warnings turned on (and you really should), then Perl will give you a warning at this point as you're trying to do a numerical comparison with something that isn't a number. But Perl will convert your non-number to 0 and do the comparison. 0 isn't greater than 50, so the else branch is executed.
$output .= $toto.'='.$percent.'%,';
$state = "BAD";
}
elsif ($percent > $opt_w && $percent < $opt_c){
Again, I don't know what $opt_w is. Let's assume it's 25. But $percent is still 0 when treated as a number. So this code isn't executed either.
$output .= $toto.'='.$percent.'%,';
$state = "NOTGOOD";
}
}
}
The next time round your inner loop, $percent is set to 100. So your if code is executed and $outer gets set to "John=100%". And $state is set to "BAD". But you never do anything with $state, so it gets overwritten the next time round your outer (while) loop.
Your foreach $percent (#data) line is extremely questionable. I'm really not sure what you're trying to do there. And the reason that you only ever see one $state is because you're (presumably) printing it outside of the loop and only seeing the final value that it gets set to.
It's always a good idea to turn on use strict and use warnings. And then to fix the errors that they will show you.
I'm making a screensaver and I need to know what's wrong with my code.
GraphicsWindow.title="Screen Saver"
GraphicsWindow.Width=500
GraphicsWindow.Height=500
For i=1 To
Colour = GraphicsWindow.GetRandomColor()
GraphicsWindow.BrushColor=Colour
XCoord = Math.GetRandomNumber(1200)
YCoord = Math.GetRandomNumber(1200)
width=math.GetRandomNumber (300)
GraphicsWindow.Fillellipse(XCoord,YCoord,width,width)
Program.Delay(200)
EndFor
ContinueForEver = "Yes"
While ContinueForEver = "Yes"
EndWhile
I'm supposed to use for i=? to ? to make an infinite loop and I'm supposed to use While EndWhile for the continuation. So basically I'm supposed to make a screensaver which generates circles forever.
Something like this?
GraphicsWindow.title="Screen Saver"
GraphicsWindow.Width=500
GraphicsWindow.Height=500
While 1 = 1
Colour = GraphicsWindow.GetRandomColor()
GraphicsWindow.BrushColor=Colour
XCoord = Math.GetRandomNumber(1200)
YCoord = Math.GetRandomNumber(1200)
width=math.GetRandomNumber (300)
GraphicsWindow.Fillellipse(XCoord,YCoord,width,width)
Program.Delay(200)
EndWhile
You were very close. But you can not have a For loop without an end number like this:
For i = 1 to
You need to have an end number:
For i = 1 to 10 '<-- the loop will run 10 times
A While statement will run as long as its input is true. So in this case, as long as 1 = 1 the loop will continue (Which is forever).
Does that help? :D
I've got 53 variables named W1_C14_0 to W1_C14_52, and each has a value from 1 to 15. I need to find how many "spells" of each number there are in this list - i.e. how many seperate runs of 1's, 2's etc in each case. This is what I'm doing and it's working fine, but is there any way to condense it into a loop?
DO REPEAT first = W1_C14_0 to W1_C14_51 /
second = W1_C14_1 to W1_C14_52 .
DO IF (SYSMIS(first) OR first<>second) .
DO IF (second=1) .
COMPUTE W1_spells1 = W1_spells1 + 1 .
ELSE IF (second=2) .
COMPUTE W1_spells2 = W1_spells2 + 1 .
ELSE IF (second=3) .
COMPUTE W1_spells3 = W1_spells3 + 1 .
*and so on down to...
ELSE IF (second=15) .
COMPUTE W1_spells15 = W1_spells15 + 1 .
END IF.
END IF.
END REPEAT .
You can loop through the spell variables using the VECTOR command.
VECTOR W1_spells = W1_spells1 TO W1_spells15.
DO REPEAT first = W1_C14_0 to W1_C14_51 /
second = W1_C14_1 to W1_C14_52 .
DO IF (SYSMIS(first) OR first<>second).
LOOP #i=1 TO 15.
DO IF (second=#i) .
COMPUTE W1_spells(#i) = W1_spells(#i) + 1.
END IF.
END LOOP.
END IF.
END REPEAT.