SRL Archive - SRL Archives

FindColorChangeGrid


Boreas

2006-10-24 21:16:55

Cliffnotes version: I made this procedure that creates a grid of points in a box and monitors them for color changes. Good for attacking monsters/getting drops/getting rocks/trees as sson as they appear. Tell me what you think.

History: I was fighting a monster and spent a while trying to find a world where no one else was doing the same. A few minutes after I finally did, someone else came and was right clicking it and choosing attack faster than me, so I didn't get my kill, and more importantly the drops. So I made a script to do it for me (just the right clicking it and choosing attack when it appears, I didn't leave it alone). I tried findcolor and popup, and about 4 other methods, but they either didn't work properly or were too slow(even after changing mousespeed in srl.scar). Then I realised, I don't need to find the monster when it appears, I know the general area where it will appear, I jsut need to know when it appears. So I wrote a script that created 5 points (1 was the mouse point, the other 4 created a square around it with the mouse point being in the center) and checked when the color changed (not to any specific color of the monster, just a color different to what it started as). Then it right clicked at the point that changed and choose attack (by going 50 or so pixels lower instead of popup etc but that's not the point). This worked very well. I expanded on the checking points for color changes instead of looking at every pixel and created FindColorChangeGrid.

Info: FindColorChangeGrid(x1, y1, x2, y2, d, giveuptime, WhichEx: integer) sets up a box with the top left point being x1,y1 and the bottom right being x2,y2. It then sets up a grid of points d distance apart (NOTE: in case of having a width of say 100 and having a d of 26 you would have a left over of 22 which is not enough for another point, so it put another point at the end anyway so that 22 is not wasted, same goes for height). It will then remember the color at each of these points and then continuely check each one to see if the color changes. Once it finds a change, it checks whether it should ignore the change (see next paragraph) and if it should ignore it, it continues checking, otherwise it sets srl global x and y to the point where it found the change, and heracles2 global FCCGfound to true (to be used in failsafes to let the script it didn't work). If it doesn't find a change after giveuptime ms it will set FCCGfound to false and exit. The script can now do an action (such as right click and attack) at x,y (or if it didn't work change the parameters and try again etc).

FindColorChangeGridEx(xposex,yposex,which:integer):boolean defines what changes FindColorChangeGrid (FCCG) should ignore. It is put in the script and lets the scripter make custom exceptions. It allows for multiple exceptions which can be choosen in WhichEx in FCCG. The parameters all come from FCCG and are not changed. What the scripter can change is adding branches to the case of, each branch being an exception. For FCCG to ignore a change at a point FindColorChangeGridEx must return false at that point.

It is pretty fast at finding things that move or appear/spawn. A drawback is the hassle of putting FindColorChangeGridEx in the top of the script. Also, the include that it is contained in can only be included if you are going to use it, (therefore no other procs/funcs can be in the same include) due to the forward of FindColorChangeGridEx. Also, it probably has more false positives than other methods (this depends on how good your exceptions are). Trees and mining rocks coming back, enemies and drops respawning come to mind as uses. Walking etc obviously not. Perhaps for randoms but probably not.


So how can I improve it?
Also I know the instructions aren't great, it's hard for me to write because I already know it in my head and I don't want to write a whole tutorial on 1 procedure. So any tips on that would be great too.
Questions/comments/suggestions?
Sorry for the long post, thanks for reading.

A demo.


program FCCGTest;
{.include heracles2.scar}
// use it in paint
//unblank the test section in the heracles2.scar to actually where the points
//are. select the paintbrush and a color. run. it will make the points in
//that color. then change colors and move the mouse across the screen




function FindColorChangeGridEx(xposex,yposex,which:integer):boolean;
begin
case which of
//This is for when you want no exceptions in the box //
1: //
begin //
if (xposex = xposex) and (yposex=yposex) then //
result:=true; //
end; //
//add more exceptions here

else writeln('Error in detector exceptions');
end;
end;
begin
cleardebug;
FindColorChangeGrid(15, 15, 516, 338, 20, 10000,1);
clickmouse(x,y,true);
end.

Pyro

2006-10-24 23:12:12

The only problem with these sorts of thigns is that there is other players near you and they can screw it up. I use a somewhat similar thing in my yew cutter to detect if the tree is gone. But i monitor only those pixels that i find with a tolerance to my tree color. Plus since no one can walk over a tree it works quite well.

Boreas

2006-10-24 23:39:22

True thats why there is FindColorChangeGridEx which the scripter customizes. For example, if you know theres a flickering torch in xa,ya xb,yb make FCCGEx return false when the point is in that box, that way FCCG will ignore all changes in that box. You could also make exception with uptext, or colors like you said.

Pyro

2006-10-25 14:35:13

But still. Anywhere you put it that isnt exactly ontop of a rock or tree or somewhere else where the thing is impossible to be walked over. You will always get false results. Also the screen shifts like 2 pixels every 10 seconds. Most people dont notice it but scar sure as hell does. Sets of my tree detector everytime. Annoying but im working to fix it.

Boreas

2006-10-25 15:25:53

The exception function will ignore most fasle positives.

I was not aware that the screen shifts so often. I just tested it out and found it was moving left pretty steadily and fluctuating in the y axis. My little brother (14 with no programming experience besides watching me) just suggested that I figure out how to track its movement and ignore result changes. That gave me the idea to ignore changes that happen when the whole screen changes. I think it will have to be rewritten quite extensively for this. I'm not sure whether to ignore when 90% (or some percent) of the points change or whether to have a separate section that monitors several points around the edge of the screen, and when most of those change, ignore changes. As I type this I am thinking I might go with the latter and intergrate it into FCCGEx, because messing with the grid setup and stuff in FCCG is a pain in the ass.

Pyro

2006-10-25 23:58:12

press f1 in scar and then ctrl f then search fixmouse. May help you on your journey. I tried switching the points movement to offset the screen movement. Buit i think it actually rotates. Not just to the left. like holding a arrow key down. Almost impossible to compensate for this. Thus i just reset the array when a screen shift occurs

Boreas

2006-10-26 02:06:05

Thanks for that.

Yea rotating would make sense, I probably saw it as it was going from 4 oclock to 8 if you know what I mean, so when I was monitoring a point it went to the left the whole time but the y went down then up. It would also explain why we don't eventually end up somewhere else because it comes back arond.

I was going to build into the exception function a part that monitors several spots with fixmouse so that it returns false when the screen shifts. However that would mean almost every point would be flagged then ignored for a cycle, which could take more than time it takes to shift. Your way of resetting the whole array at once works better.

When looking at how this would connect with the manin function I realized something. I have
if (point has changed) and (FCCGEx doesn't say ignore it) then
begin
return the change
end;

But I don't have something for
if (point has changed) and (FCCGEx says ignore it) oops!!!
I need to put in something to reset the color for those points. I'll do that when I put in the screen shifting support.

After that I might work on figuring out the exact movement of the screen shift.


Thanks for your help, one more thing though. During every period between shifts, it has to take time getting every color in the array, leaving less time to cycle through checking before the next shift. When the number of points in the array increases, the number of checking cycles before shifting decreases due to the increase in cycle size and decrease in time to check left over from the resetting. Because of this expotenial decrease in number of checking cycles, there is a critical point where the number of points in the array causes the percentage of time that the resetting takes out of the time between shifts to become ineffiecient and will severly affect functionality. Do you think it's worth finding out what this maximum number of points is?

Pyro

2006-10-26 02:19:41

Ahhh. Slightly lost :p but i think i know what you mean. I dont think there would be a point in the rs world where getting the colors and then checking them would take longer then the screen rotation period. Wait is that what you mean ? :p. O wait you mean it will take consideably less cycles before shift? Well quite possibly. Although getcolor takes less then 1ms to do. I have a script to test the timing of scar functions. Here are the results

Longest Time Taken Was 342 ms
Shortest Time Taken Was 31 ms
Average Time Taken Was 53.416 ms

that was testing how long it took to do 1000 getcolors. Which is more then you would ever need. I tested it 1000 times to see. That largest is when i move my mouse or someone talks to me on msn or somethign else takes my cpu.

Boreas

2006-10-26 10:09:52

Ok thanks those results put my mind at ease.

Yea I knew that resetting and checking would take less that the time between shifts, I was just worried it wouldn't get to check every point enough times to be efficient. I can see it will those results.

Lets say 50ms to get 1000 colors, and it shifts every second. A checking cycle takes a little longer than resetting but lets just say it's the same. Thats 1 reset and 19 cycles per 1 second shift, 95% efficiency, with 1000 colors. With 100 points it's 99.5% of the time spent searching. The shift time is longer so it would be even higher, and the checking time takes longer than just getcolors so a little lower. But that's still probably more than 90% and definitely way better than 50-75%, so I'm happy.

(Note: those estimates are based on the assumption that it will reset as soon as it shifts)

Pyro

2006-10-26 14:31:44

I think it takes longer then one second for the shift. Atleast thats what my script picks up. It debugs everytime the screen shifts and it resets. You would get more then enough results i would say.