calvinc5 Posted June 14, 2014 Share Posted June 14, 2014 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? Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 14, 2014 Share Posted June 14, 2014 I'm guessing that you might have some sort of bug in your script. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 15, 2014 Author Share Posted June 15, 2014 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. Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 15, 2014 Share Posted June 15, 2014 Try selecting the client and run: begin DebugBitmap(GetClient.Capture); end. That should show you what SCAR sees. It is possible that SCAR can't actually see the game if it is hardware accelerated. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 15, 2014 Author Share Posted June 15, 2014 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. Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 15, 2014 Share Posted June 15, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 15, 2014 Author Share Posted June 15, 2014 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! Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 15, 2014 Share Posted June 15, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 15, 2014 Author Share Posted June 15, 2014 Thank you sir you're right it sees it correctly with the desktop as the focus Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 15, 2014 Share Posted June 15, 2014 (edited) 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 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 June 15, 2014 by Freddy Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 15, 2014 Author Share Posted June 15, 2014 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! Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 16, 2014 Share Posted June 16, 2014 (edited) 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 There's nothing stopping you from doing that, but it will be very complicated and hard to achieve. Edited June 16, 2014 by Freddy Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 17, 2014 Author Share Posted June 17, 2014 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? Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 17, 2014 Author Share Posted June 17, 2014 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 Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 17, 2014 Share Posted June 17, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 17, 2014 Author Share Posted June 17, 2014 (edited) 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 June 17, 2014 by calvinc5 Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 17, 2014 Share Posted June 17, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 19, 2014 Author Share Posted June 19, 2014 (edited) 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 June 19, 2014 by calvinc5 Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 19, 2014 Share Posted June 19, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 19, 2014 Author Share Posted June 19, 2014 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? Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 20, 2014 Share Posted June 20, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 20, 2014 Author Share Posted June 20, 2014 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? Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 20, 2014 Share Posted June 20, 2014 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. Quote Link to comment Share on other sites More sharing options...
calvinc5 Posted June 21, 2014 Author Share Posted June 21, 2014 (edited) 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 June 23, 2014 by Freddy Quote Link to comment Share on other sites More sharing options...
FHannes Posted June 23, 2014 Share Posted June 23, 2014 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 Quote Link to comment Share on other sites More sharing options...