Jump to content
calvinc5

finding wrong color

Recommended Posts

In my script it needs to look for a color on a stamina bar to know when its full. I have tried time and time again but it always shows the same color for depleted as it does for full. could this be an anti bot feature? what are some other ways i could make the script know when stamina has filled?

Link to comment
Share on other sites

This is my script.

 

program FindStaminaColor;

 

var

x,y: Integer;

 

const

StaminaColor = 6469463;

 

begin

if(FindColor(x,y,StaminaColor,170,35,180,45)) then

begin

Writeln('Full Stamina');

end;

end.

 

 

this script definitely works. I used the paint app to test it and it has accurate every time but when I use it on specifically the stamina bar in the game it reads it as full even when its depleted. even the color selector tool sees it as the correct color on the stamina bar.

Link to comment
Share on other sites

That is very useful! So when I did that I found that even when the stamina is depleted scar sees it as full. but oddly the similar food and health bars showed where they should. Can you think of anyway I can make this work? All my scripts will be basic and limited without the ability to know when the stamina as recharged.

Link to comment
Share on other sites

That is very useful! So when I did that I found that even when the stamina is depleted scar sees it as full. but oddly the similar food and health bars showed where they should. Can you think of anyway I can make this work? All my scripts will be basic and limited without the ability to know when the stamina as recharged.

 

To be honest, if SCAR can't see it, I don't know any way around it, as that's the basics principle upon which SCAR operates. I'm quite surprised that it would work like this though, generally either SCAR can see the game or it can't.

Link to comment
Share on other sites

Maybe if I turn off the hardware acceleration option in my control panel it would change small things like that? Also would it be possible for someone to write an add on to help scar see these things it is missing? I was able to make a very inefficient work around using screen shot but doing that gave me an idea. Could I use scar in any way to take a screenshot and check a pixel on it for color. Then discard the picture again all in the background?

 

If I cannot find a way to do this with scar do you think this command in visual basics could have different results?

http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.getpixel.aspx

 

Thank you for all the help!

 

- - - Updated - - -

 

I don't know how good this would work. but I could have scar hit the in game button to save a screenshot. Then have a visual basics program in the background constantly checking the screenshot folder for new pictures. Once it checks the picture it can make a color on screen that scar can identify and deletes the picture. Do you think this would be very slow and not worth while? Sorry for the overflow of questions!

Link to comment
Share on other sites

The .NET GetPixel function performs a direct call to the GetPixel funciton in the Win32 GD API. This is also what SCAR does with GetColor, only GetColor will also try alternative methods if GetPixel fails to retrieve any color. You can perform essentially any color detection related method on a bitmap in SCAR as well, by loading it into a TSCARBitmap and using that as a temporary target client. But I'd recommend first trying to see if it can capture the window correctly if you simply select the desktop. This is easily achieved by using the default window SCAR has selected when it starts or by clicking the Reset Client menu option. It's quite possible that it will correctly display the window when it processes the entire desktop. At that point it's up to you to set up the script to work with that, rather than the window itself. SCAR does prodive some very flexible methods that allow you to send input to the window, whilst processing visual input from another source. You can even set the area of the other source which it has to use, so your coordinates would still be correctly offset for the window. But as I said, I'd recommend first trying to grab the entire desktop as I described and check if that does work.

Link to comment
Share on other sites

Ok, well, then you'll want to set up a client based on the client you select which captures the image from the desktop rather than the window itself. You can do that like this:

procedure SetupClient;    
var
 OldClient, NewClient: TSCARClient;  
begin  
 OldClient := GetClient;
 NewClient := TSCARWindowClient.Create(GetDesktopWindow);
 NewClient.ImageArea := OldClient.InputArea;           
 NewClient.InputArea := OldClient.InputArea;    
 SetClient(NewClient);   
 OldClient.Free;
end;

begin
 SetupClient;      

 DebugBitmap(GetClient.Capture);
 MoveMouse(0, 0);
end.

 

You just select the game like you did before, but you add the SetupClient function to your script and add it at the top of the script's main function as I did in the script. The script is just for testing, but will show you if all goes well, the image that SCAR will work with, using this setup, as well as move the mouse to the 0,0 coordinate of the area it will work in. Essentially, this will just recreate the client you selected, but capture the image from the desktop and specifically tell SCAR that it has to work with the area where the window is located to get the image. Do keep in mind that using this method, you will not be able/allowed to move the window. If you call update on this client, it will still work with the desktop, but lose any context relating to the window, so it'll just think the desktop is the window. You could technically get around that by storing the original client in advance and just call the Setup function without destroying the old client every time you move the window, but it's really a lot easier to just not move the window :P

 

EDIT: And if you really want to move the window... Call UpdateClient at the start of the script [after getting the original client] and every time the window has moved:

var
 OrigClient: TSCARClient;

procedure UpdateClient;    
var
 OldClient, NewClient: TSCARClient;  
begin  
 OrigClient.Update;
 NewClient := TSCARWindowClient.Create(GetDesktopWindow);
 NewClient.ImageArea := OrigClient.InputArea;           
 NewClient.InputArea := OrigClient.InputArea;    
 OldClient := SetClient(NewClient);     
 if OldClient <> OrigClient then
   OldClient.Free;
end;

begin
 OrigClient := GetClient;
 UpdateClient;               

 DebugBitmap(GetClient.Capture);
 MoveMouse(0, 0);
end.

Edited by Freddy
Link to comment
Share on other sites

thank you so much that works perfectly. I can set the game as the focus and it still sees it correctly. So is the second code only for if I wasn't using full screen? Do you think I could use scar to make a bot that can walk around in a this first person game? Thank you very much again!

Link to comment
Share on other sites

thank you so much that works perfectly. I can set the game as the focus and it still sees it correctly. So is the second code only for if I wasn't using full screen? Do you think I could use scar to make a bot that can walk around in a this first person game? Thank you very much again!

 

Yes, I suppose, full screen would indeed generally not be a moving window :P There's nothing stopping you from doing that, but it will be very complicated and hard to achieve.

Edited by Freddy
Link to comment
Share on other sites

So all was going fine until today when me and my friend both ran into the same problem with ours scripts. Whenever the scar window is ontop of the game client it gets the colors correct. But as soon as scar is run in the back ground it won't find the colors. If I alt+tab back to scar while the script is running it starts properly picking up the colors again. Any suggestions?

Link to comment
Share on other sites

I have currently resized the game and scar to both fit on screen and that is working. Unless you know of a better way I'll keep doing this because it works. I've started putting my procedures in includes. But I ran into to the problem that I can't have the same constants in different includes.

 

For example I have one include called corefiles.scar and another called actionfiles.scar but I want to have my const findstamina and findaction work for both. Should I just rename the constants in one file or is there somewhere I could put it that it will work for all? Alternatively I could just get rid of the constants and put the color code right in the findcolor command. But that's just a pain if I ever need to change it

Link to comment
Share on other sites

So all was going fine until today when me and my friend both ran into the same problem with ours scripts. Whenever the scar window is ontop of the game client it gets the colors correct. But as soon as scar is run in the back ground it won't find the colors. If I alt+tab back to scar while the script is running it starts properly picking up the colors again. Any suggestions?

 

Does the game change the screen resolution? If so, then that's probably the problem. Generally with SCAR it's best to work in windowed mode.

 

I'm not sure I understand your constants problem.

Link to comment
Share on other sites

Everything is at 1920x1080. The tv the game and the desktop. I had the game on windowed fullscreen while experiencing this problem. My friend solved the problem by using a second monitor so the game and scar client have thier own screen. I am going to get a second tomorrow morning.

 

- - - Updated - - -

 

I have the same problems with variable as I do with the constants. Ill to explain better.

 

This is how I have it set up so I can organize things.

 

program Run;

 

{$I Includes\checkup.scar}

{$I Includes\startfiles.scar}

{$I Includes\corefiles.scar}

{$I Includes\equipfiles.scar}

{$I Includes\actions.scar}

 

var

Start: integer;

Tick: integer;

 

begin

Start := 0;

while Start <> 1 do

begin

Starting;

Inc(Start);

end;

 

repeat

FindDrinkWater;

FindEatFood;

Workmine;

Tick:= Tick + 1;

Wait(2000);

WorkCheckUntil;

until(Tick >= 50);

end.

 

 

In corefiles.scar I need to look for two of the same colors in the same spots as in actions.scar. I have the color codes as constants like this.

 

const

StaminaColor1 = 819220;

ActionColor1 = 8285023;

 

But I had to make the names different in the actions.scar because if they were the same as the names in corefiles.scar I would get an error about duplicates. Is there a way I can use just one constant across both of them? I think I remember seeing an include before that was full of just constants. That would be very helpful but would it slow everything down? I hope that made more sense. my problem with variables is very similar but I need to sleep and cannot explain it right now. Thank you!!!

Edited by calvinc5
Link to comment
Share on other sites

But I had to make the names different in the actions.scar because if they were the same as the names in corefiles.scar I would get an error about duplicates. Is there a way I can use just one constant across both of them? I think I remember seeing an include before that was full of just constants. That would be very helpful but would it slow everything down? I hope that made more sense. my problem with variables is very similar but I need to sleep and cannot explain it right now. Thank you!!!

 

The problem is that if you include a file in 2 files and then you include those 2 files in another file, you've included the original include twice, duplicating all of the code in that file. You could resolve this issue by replacing $I with $IO (or $INCLUDE_ONCE), which will only add the file into the script at the first position it was requested.

Link to comment
Share on other sites

That fixed my problems thank you! Ive ran into another problem though! my script is working fine on its own and the form ive made is also working fine. but once i combine them together i start getting errors.

 

if combobox1.text = 'Fish' then

Writeln('You chose to fish');

startaction;

 

This part is working fine but in the next part it stops and crashes right after my Starting function in here.

 

procedure StartAction;

begin

Start := 0;

while Start <> 1 do

begin

Starting;

Inc(Start);

end;

 

 

repeat

FindDrinkWater;

FindEatFood;

WorkFish;

Tick:= Tick + 1;

Wait(5000);

WorkCheckUntil;

until(Tick >= 20);

clickmouse(1288,9,false);

wait(1000);

clickmouse(818,550,false);

 

this is the function

 

{$IO Includes\const.scar}

 

procedure SetupClient;

var

OldClient, NewClient: TSCARClient;

begin

OldClient := GetClient;

NewClient := TSCARWindowClient.Create(GetDesktopWindow);

NewClient.ImageArea := OldClient.InputArea;

NewClient.InputArea := OldClient.InputArea;

SetClient(NewClient);

OldClient.Free;

Writeln('Client set')

end;

 

procedure Starting;

begin

WriteLn('Starting in 5 seconds');

Wait(1000);

WriteLn('Starting in 4 seconds');

Wait(1000);

WriteLn('Starting in 3 seconds');

Wait(1000);

WriteLn('Starting in 2 seconds');

Wait(1000);

WriteLn('Starting in 1 second');

Wait(1000);

WriteLn('Running');

Setupclient;

end;

 

I dont understand whats going wrong. this is the error. Could not call proc. it makes it as far as WriteLn('Running'); any procedure i try to make run gets an error.

Edited by calvinc5
Link to comment
Share on other sites

The code you provided there is not sufficient for me to figure out what you're doing wrong. But make sure that you DO NOT call script code from an event handler in a form. For example, don't run the script code from an OnClick event of a button. It will be running in the main thread instead of the script thread and cause all sorts of issues.

Link to comment
Share on other sites

Okay that is what I am doing. I'm running the procedure from the on click! How do I get around this while still clicking the button to start the program?

 

Just set a variable in the OnClick handler to determine what was selected when the form is closed. Assuming you just have like an OK button or something, you could just assign combobox1.text to a string variable in the onclick handler. I'm not 100% OnClick will still be called if you do so, but I think you can just assign a value to the button's ModalResult like mrOk, which will close the form if you opened it (properly) using ShowModal.

Link to comment
Share on other sites

Is it bad to use alot of includes like I am? After I figure out how to start the script off a button. How do I have the option I choose in tcombobox change the procedure WorkMine; in here to WorkFish; or whatever else I have in the drop the menu?

 

procedure StartAction;

begin

Start := 0;

while Start <> 1 do

begin

Starting;

Inc(Start);

end;

 

 

repeat

FindDrinkWater;

FindEatFood;

Workmine;

Tick:= Tick + 1;

Wait(5000);

WorkCheckUntil;

until(Tick >= 20);

clickmouse(1288,9,false);

wait(1000);

clickmouse(818,550,false);

end;

 

Thanks for all this help it is really appreciated!

 

- - - Updated - - -

 

I was hoping to have the form open while the script is running so that I could easily monitor specific things about the number of actions done and time taken. Will this not be possible?

Link to comment
Share on other sites

Is it bad to use alot of includes like I am? After I figure out how to start the script off a button. How do I have the option I choose in tcombobox change the procedure WorkMine; in here to WorkFish; or whatever else I have in the drop the menu?

 

procedure StartAction;

begin

Start := 0;

while Start <> 1 do

begin

Starting;

Inc(Start);

end;

 

 

repeat

FindDrinkWater;

FindEatFood;

Workmine;

Tick:= Tick + 1;

Wait(5000);

WorkCheckUntil;

until(Tick >= 20);

clickmouse(1288,9,false);

wait(1000);

clickmouse(818,550,false);

end;

 

Thanks for all this help it is really appreciated!

 

- - - Updated - - -

 

I was hoping to have the form open while the script is running so that I could easily monitor specific things about the number of actions done and time taken. Will this not be possible?

 

As I said, you store the selected value in a variable, then you can use if-statements or case-statements to call the correct function. As for opening the script while it's running... It is possible, but hardly recommended, because then you are running 2 threads simultaneously and when you try to write any data through a form interaction you will be doing so without any synchronization, which again can cause any number of unforeseen issues. It might work, some times, but it could just as well crash SCAR completely.

Link to comment
Share on other sites

I still cannot get the program to start off a button. Do you think you could possibly try explaining how to do this to me again? This is the form part of my code. run.scar contains the procedure StartAction;. Whenever I call FreeForm(Form1_1); it freezes scar completely. Also does the TerminateScript; command not work in the form? Thanks!

 

{$I run.scar}
{$IO Includes\const.scar}

procedure Choice;
begin
 if Window=2 then
 StartAction;
end; 

procedure Click (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if combobox1.text = 'Fish' then
  begin  
  FreeForm(Form1_1);
   Writeln('You chose to fish'); 
   Window := 2; 
   Choice;
   end else 
    begin
 if combobox1.text = 'Mine' then
 begin
   Writeln('You chose to mine');             
 end;  
 end; 
 end;

procedure Form1_1_Init;
begin
 Form1_1 := CreateForm;
 ComboBox1 := TComboBox.Create(Form1_1);
 Button1 := TButton.Create(Form1_1);
 Edit1 := TEdit.Create(Form1_1);
 with Form1_1 do
 begin
   Left := 653;
   Top := 350;
   Caption := 'Wurm Bot';
   ClientHeight := 664;
   ClientWidth := 896;
   Color := clWindow;
   Font.Charset := DEFAULT_CHARSET;
   Font.Color := clWindowText;
   Font.Height := -11;
   Font.Name := 'Tahoma';
   Font.Style := [];
   OldCreateOrder := False;
   PixelsPerInch := 96;
 end;
 with ComboBox1 do
 begin
   Parent := Form1_1;
   Left := 120;
   Top := 84;
   Width := 252;
   Height := 21;
   TabOrder := 0;
   Text := 'Action to do'; 
   Items.Add('Fish');
   Items.Add('Mine'); 
 end;
 with Button1 do
 begin
   Parent := Form1_1;
   Left := 677;
   Top := 52;
   Width := 99;
   Height := 53;
   Caption := 'Go';
   TabOrder := 1;
 end;
 begin
    button1.OnMouseDown := @Click;
 end;
 with Edit1 do
 begin
   Parent := Form1_1;
   Left := 492;
   Top := 84;
   Width := 88;
   Height := 21;
   TabOrder := 2;
   Text := 'How many times';
 end;
end;

procedure Form1_1_SafeInit;
var
 v: TVariantArray;
begin
 SetLength(v, 0);
 ThreadSafeCall('Form1_1_Init', v);
end;

function Form1_1_ShowModal: Boolean;
begin
 Result := Form1_1.ShowModal = mrOk;
end;

function Form1_1_SafeShowModal: Boolean;
var
 v: TVariantArray;
begin
 SetLength(v, 0);
 Result := ThreadSafeCall('Form1_1_ShowModal', v);
end;

begin
 Form1_1_SafeInit;
 if Form1_1_SafeShowModal then
   WriteLn('Form returned modalresult ok');
 FreeForm(Form1_1);
end.

Edited by Freddy
Link to comment
Share on other sites

You should not call FreeForm in an event handler for that form. The form is what calls the eventhandler essentially, what you're doing is destroying the item it will return to when your code has been executed. Furthermore, you also call it twice, you should only ever free the form once.

 

I remember back in the day I made a script for wurm, good times ^_^

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
  • Create New...