PDA

View Full Version : MicroPaint (BotWatch™)



bob_dole
06-13-2013, 03:39 AM
[SMART] Implementing MicroPaint (BotWatch™)
[Scroll to the bottom if you simply want to see the code. This is a learning community but I do not have any issues with people copy/pasting my code.]


What is MicroPaint (BotWatch™)
MicroPaint (BotWatch™) is a system similar to paint that allows you to monitor your bot's location and progress in a tiny window, without having your SMART window open. It includes the bot's name, a small snapshot of the bot in-game, and optionally some quick statistics regarding the bot.

BotWatch™ also includes a color border that will signal to you how the bot is doing. The colors go from Bright Neon Green (Just mined/chopped/looted/etc.) to green (Recently mined/chopped/looted) to yellow (been a little while since last ore mined, log chopped, or item looted) to Orange (Been a long time since last ore mined, log chopped, or item looted) to Red (It's been too long since the last loot, about to fail) to Bright Red (Script timed out, terminated, you were random'ed, or died).

BotWatch™ is especcially useful to those running several different bots as you can do something as awesome as this:


http://img203.imageshack.us/img203/6462/botwatch.png

One look at your screen and you can instantly check the status of all bots running Simba on your computer. The colored borders are an instant gauge of where your bots are at and what their status is. The top line is the nickname, the middle is a quick snapshot of your character, and the last three lines are optional statistics.

The Functions

As this tutorial is hopefully in Advanced Tutorials, a simple explanation of the functions and a quick example should be sufficient.
The following is the code used to determine what color the border will be.



function PercToCol (percent: integer): longint;
begin

if (percent <= 10) then
result := RGBtoColor (255 - (percent * 5), 0 ,0);

if (percent > 10) then
result := RGBtoColor (225 - (percent * 3), 0, 0);
if (percent > 30) then
result := RGBtoColor (255, 155 + ((percent - 35) * 3), 50 - percent);

if (percent > 45) then
result := RGBtoColor (255, 247 - (4 * (60 - percent)), percent);

if (percent > 60) then
result := RGBtoColor (20, 20 + (percent), 20);

if (percent > 75) then
result := RGBtoColor (20, 100 + (percent * (17 / 10)), 20);

if (percent >= 95) then
result := RGBtoColor (0, 255 ,0);

end;



PercToCol Color Outputs:

http://img692.imageshack.us/img692/3951/perctocol.png

Using PercToCol

While the PercToCol function converts a percentage into a color, how to determine that percentage is completely up the scripter to decide. For my woodcutting script my formula to determine color is:


if (lasttree < 0) then
lasttree := 0 ;

id := 100 - round(sqrt((LastTree)) / 6);
TheStatus := PercToCol(id);


You should mess around with the calculations and change them to be best fit depending on what you are doing, average time between successes, and any possible failures that could occur. LastTree is quite obviously the TimeFromMark of the last tree cut. It is then fed through my formula, converted into an id, and shoved into the color converter.

Neon Green - 0 to 900 milliseconds from last cut, basically when it has just cut down a tree.
Green - 900 milliseconds to 57.6 seconds
Orange/Yellow - 57.6 seconds to 176.4 seconds (~3 minutes)
Red/Dead - 176.4 seconds to 360 seconds (6 minutes)

The formula can easily be adjusted depending on what you are doing. If it is something takes a while, increase the time limit for each color. If it is something that should be done fast, decrease the time limit.


UpdateWatch(LastTree: integer)

UpdateWatch is the function that creates the actual bitmap and sends it to your SRL debug window. It is really the only function that matters. This function should be called right after a success, a Show-ending event such as random/death/out of supplies, and at the end of the script. The more often you can call this procedure, the better. Word for word here is the function as in my woodcutter. I have added comments for those that need a some help decrypting my code.


Procedure UpdateWatch(LastTree: integer); // UpdateWatch function, includes how long since the last logs were recieved.
var
bot, w, h, image, text, id: integer;
TheStatus: longint;
offset: TPoint;
PHour: string
begin
// Calculates the percentage based off of last time logs were received.
id := 100 - round(sqrt((LastTree)) / 6);

// Converts the percentage into a color. Function discussed above.
TheStatus := PercToCol(id);

// Offset from base cords that the client capture will be taken from.
offset := point (8, 24);
// Creating the bitmap to be worked with.
image := CreateBitmap (115,115);
// Taking the snapshot of the client.
bot := BitmapFromClient (200 + offset.x, 100 + offset.y, 300 + offset.x, 200 + offset.y);

// Drawing the colored border to the image.
RectangleBitmap(image, inttobox (0, 0, 114, 114), TheStatus);

// Draws the client snapshot on top of the colored border.
FastDrawTransparent(7, 7, bot, image);

// Draws the current player's name in the smallest size available.
text := BitmapFromText(Players[CurrentPlayer].Name, StatChars07);
// Measured the width and height of the name bitmap, in order to properly center.
GetBitmapSize(text, w, h);
// Sets the text's black background as transparent.
SetTransparentcolor (text, 0);
// Uses the width/height measured to properly center the players name.
FastDrawTransparent(round ((115 * 0.5) - (w / 2)), 12, text, image);
// Frees the bitmap. All the bitmaps we are making, they NEED to be free'd.
FreeBitmap(text);


// Prints the 'Time' label. Very similar to the above script.
text := BitmapFromText('Time: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14, 74, text, image)
FreeBitmap(text);

// Prints the time running. Timize can be found in my tutorial on paint. Similar to above.
text := BitmapFromText(timize(round (GetTimeRunning / 1000)), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 74, text, image);
FreeBitmap(text);

// Prints the 'Logs' label. Similar to above...
text := BitmapFromText('Logs: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14, 84, text, image)
FreeBitmap(text);

// Prints the amount of logs cut. Similar to above...
text := BitmapFromText(groupdigits (magics, ','), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 84, text, image);
FreeBitmap(text);

// Prints the 'cash' label. Similar to above...
text := BitmapFromText('Cash: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14,94, text, image)
FreeBitmap(text);

// Prints the amount of cash made. Similar to above...
text := BitmapFromText(groupdigits (magics * price, ','), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 94, text, image);
FreeBitmap(text);

// Loads and displays the MicroPaint.
DrawBitmapDebugImg(image);
DisplayDebugImgWindow(115, 115);

// Frees out bitmaps, an absolute must.
FreeBitmap(bot);
FreeBitmap(image);

end;


Final Product. (See BotWatch in action)

While I am sure most scriptwriters here already know how to implement this code into their script, I will write a simple program to show the final product for those who would rather copy and paste. I threw together a quick magic tree simulator. Copy and paste this code into your Simba to see what BotWatch can do.


program BotWatch;
{$DEFINE SMART8}
{$I SRL-OSR/SRL.Simba}
const
Player_Name = 'zezima'; // Player's name. In real script this would come from declareplayers.
Price = 1200; // The price of each log.
var
Logs_Cut, Last_Cut: integer;


function ClockReel(i: integer): string;
begin

if (i < 10) then
begin
result := '0' + inttostr(i);
Exit;
end;

result := inttostr(i);

end;
function Timize(Time: Integer): String;
var
seconds, minutes, hours: integer;
final: String;
begin

if (time < 60) then
begin
seconds := time;
Result := '0:00:' + clockReel(time);
Exit;
end;

hours := floor(time / 3600);
time := time - (hours * 3600);

minutes := floor(time / 60);
time := time - (minutes * 60);

seconds := time;

final := (inttostr(hours) + ':' + clockReel(minutes) + ':' + clockReel(seconds));

Result := final;

end;
function PercToCol (percent: integer): longint;
begin

if (percent <= 10) then
result := RGBtoColor (255 - (percent * 5), 0 ,0);

if (percent > 10) then
result := RGBtoColor (225 - (percent * 3), 0, 0);
if (percent > 30) then
result := RGBtoColor (255, 155 + ((percent - 35) * 3), 50 - percent);

if (percent > 45) then
result := RGBtoColor (255, 247 - (4 * (60 - percent)), percent);

if (percent > 60) then
result := RGBtoColor (20, 20 + (percent), 20);

if (percent > 75) then
result := RGBtoColor (20, 100 + (percent * (17 / 10)), 20);

if (percent >= 95) then
result := RGBtoColor (0, 255 ,0);

end;

Procedure UpdateWatch(LastTree: integer); // UpdateWatch function, includes how long since the last logs were recieved.
var
bot, w, h, image, text, id: integer;
TheStatus: longint;
offset: TPoint;
begin
// Calculates the percentage based off of last time logs were received.
id := 100 - round(sqrt((LastTree)) / 6);

// Converts the percentage into a color. Function discussed above.
TheStatus := PercToCol(id);

// Offset from base cords that the client capture will be taken from.
offset := point (8, 24);
// Creating the bitmap to be worked with.
image := CreateBitmap (115,115);
// Taking the snapshot of the client.
bot := BitmapFromClient (200 + offset.x, 100 + offset.y, 300 + offset.x, 200 + offset.y);

// Drawing the colored border to the image.
RectangleBitmap(image, inttobox (0, 0, 114, 114), TheStatus);

// Draws the client snapshot on top of the colored border.
FastDrawTransparent(7, 7, bot, image);

// Draws the current player's name in the smallest size available.
text := BitmapFromText(Player_Name, StatChars07);
// Measured the width and height of the name bitmap, in order to properly center.
GetBitmapSize(text, w, h);
// Sets the text's black background as transparent.
SetTransparentcolor (text, 0);
// Using our width and height we can center the players name.
FastDrawTransparent(round ((115 * 0.5) - (w / 2)), 12, text, image);
// Frees the bitmap. All the bitmaps we are making, they NEED to be free'd.
FreeBitmap(text);


// Prints the 'Time' label. Very similar to the above script.
text := BitmapFromText('Time: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14, 74, text, image)
FreeBitmap(text);

// Prints the time running. Timize can be found in my tutorial on paint. Similar to above.
text := BitmapFromText(timize(round (GetTimeRunning / 1000)), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 74, text, image);
FreeBitmap(text);

// Prints the 'Logs' label. Similar to above...
text := BitmapFromText('Logs: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14, 84, text, image)
FreeBitmap(text);

// Prints the amount of logs cut. Similar to above...
text := BitmapFromText(groupdigits (logs_cut, ','), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 84, text, image);
FreeBitmap(text);

// Prints the 'cash' label. Similar to above...
text := BitmapFromText('Cash: ', StatChars07);
SetTransparentcolor (text, 0);
FastDrawTransparent(14,94, text, image)
FreeBitmap(text);

// Prints the amount of cash made. Similar to above...
text := BitmapFromText(groupdigits (logs_cut * price, ','), StatChars07);
GetBitmapSize(text, w, h);
SetTransparentcolor (text, 0);
FastDrawTransparent(99 - w, 94, text, image);
FreeBitmap(text);

// Loads and displays the MicroPaint.
DrawBitmapDebugImg(image);
DisplayDebugImgWindow(115, 115);

// Frees out bitmaps, an absolute must.
FreeBitmap(bot);
FreeBitmap(image);

end;

Procedure Kill;
begin
writeLn ('Script terminated, you must restart.');

UpdateWatch(360000);

end;
begin
setupSRL;
AddOnTerminate('kill');
MarkTime(Last_Cut);

Repeat

if (RandomRange (1,15) = 1) then
begin
Logs_cut := Logs_cut + 1;
writeln ('We recieved some logs.');
MarkTime(Last_Cut);
UpdateWatch (0);
end;

UpdateWatch (TimeFromMark(Last_Cut));
wait (randomrange(200,4000));

until (false);

end.



If you haven't already please check out my guide for Paint over in the intermediate section. Any comments, suggestions, questions are always welcome. If one person was helped by this tutorial the time spent on it has been worth it.

Haxz
06-13-2013, 04:43 AM
I think this is really cool!

dzpliu
06-13-2013, 04:47 AM
i agree, this is well thought :D

bob_dole
06-14-2013, 09:38 AM
Thanks guys. If there are any scripts you use that would like this scripted into just post them below and I can add it for you.

Chris!
06-14-2013, 10:53 AM
Thanks guys. If there are any scripts you use that would like this scripted into just post them below and I can add it for you.

To get your thread moved, either PM a staff member, mention them or report your thread and ask for a move. :3

Very nice guide and idea here.

Sjoe
08-01-2013, 10:22 PM
Saw this on your signature, this is really cool :p

bob_dole
08-02-2013, 01:47 AM
Saw this on your signature, this is really cool :p

Thanks. Hoping to get this a little more exposure. I think it can be really useful, mainly to those who bot multiple accounts.

rj
08-02-2013, 03:29 AM
This looks like a neat little tool

Flight
08-02-2013, 04:09 AM
This idea looks pretty clever indeed. Original, very helpful for both users and scripters alike, and I will always be in support of new and original, progressive ideas; I'm a huge fan of ingenuity. But, if I might ask, in essence does this simply draw & display a colored bitmap of a specified area on the current target window and add text / status debugging to it? If that's the case how would it differ from simply hovering the mouse over the target (browser or SMART) while the script is running, to get a glimpse of the script in action?

bob_dole
08-02-2013, 10:21 AM
This idea looks pretty clever indeed. Original, very helpful for both users and scripters alike, and I will always be in support of new and original, progressive ideas; I'm a huge fan of ingenuity. But, if I might ask, in essence does this simply draw & display a colored bitmap of a specified area on the current target window and add text / status debugging to it? If that's the case how would it differ from simply hovering the mouse over the target (browser or SMART) while the script is running, to get a glimpse of the script in action?

Yep that's exactly what it does, along with a color border. Most users can simply hover over the window to see the script's status, but will not be able to see the additional information/color-border of the script. Users operating on windows XP or older will also not be able to do this. BotWatch however, allows a user to check the status of all bots on the computer at the exact same time without needing to individually hover over each window.

I am currently designing a script that will allow a botter to view and manage bots on several different systems all from one computer or possibly even from their smartphone.

xtrapsp
08-02-2013, 10:40 AM
Yep that's exactly what it does, along with a color border. Most users can simply hover over the window to see the script's status, but will not be able to see the additional information/color-border of the script. Users operating on windows XP or older will also not be able to do this. BotWatch however, allows a user to check the status of all bots on the computer at the exact same time without needing to individually hover over each window.

I am currently designing a script that will allow a botter to view and manage bots on several different systems all from one computer or possibly even from their smartphone.

Bob Dole,

I would really love to offer my help with this :) Would it be possible to make it so this posts the image once every 30 minutes to a server and displays it on a web page? I can do all the PHP etc. It would be amazing to make a page for each script created which shows the hotspots and possibly compare them to the rest of the RS map? :P

masterBB
08-02-2013, 11:20 AM
May I suggest:

function PercToCol (percent: integer): longint;
begin
result := HSLtoColor(I / 3.0, 100, 50);
end;

bob_dole
08-02-2013, 02:03 PM
Bob Dole,

I would really love to offer my help with this :) Would it be possible to make it so this posts the image once every 30 minutes to a server and displays it on a web page? I can do all the PHP etc. It would be amazing to make a page for each script created which shows the hotspots and possibly compare them to the rest of the RS map? :P

Yes, this is more than possible. I was going to go even as far as to use JQuery to display a crude video that also allows you to send clicks to be executed on the SMART window. The PHP/MySQL is my favorite part.

xtrapsp
08-02-2013, 03:04 PM
Yes, this is more than possible. I was going to go even as far as to use JQuery to display a crude video that also allows you to send clicks to be executed on the SMART window. The PHP/MySQL is my favorite part.

If you have it under control no worries ^^

bob_dole
08-03-2013, 12:30 AM
If you have it under control no worries ^^

Yes it may take a little while before it is finished/released to the public. Meanwhile, if you need I can whip up a quick script that will send a picture of the SMART window to your server every X minutes.