PDA

View Full Version : Bank Browsing- BlackLists



Boreas
02-22-2007, 10:52 PM
Bank Browsing- BlackLists

Level: Intermediate


Follow up tutorial (read this first) BlackLists with color (http://www.villavu.com/forum/showthread.php?t=6283)

About B4 and this series of tutorials-
I am developing a system called B4 (Bank Browser By Boreas) made up of functions for finding, withdrawing, and depositing bank items. It will be fast and efficient, using techniques especially designed for using minimal resources and still getting the job done. One of the features will be only searching for something once, and then remembering where it is. It will also be easy to use, with high level functions like MakeInventory('18 coal, 9 iron'); that will take care of everything. It will also make DTM/bitmap/color creation easier, so you can spend more time scripting. As well as the high level functions like MakeInventory, it will contain many lower level functions that you can combine to make your own personalized higher level functions. This series of tutorials will teach you how to use the functions, and how they work. It is partly a user manual for the B4 system, but it is also a series of scripting tutorial, teaching problem solving, scripting techniques, and ways of thinking. The more you know about how something works, the better you can use it. All of these tutorials will be labeled intermediate or advanced. The material will not be too tricky, but I do expect you to be comfortable with arrays etc. Also, B4 will make banking very easy, but I still want beginner scripters to learn the old fashioned way of doing it. Therefore, these tutorials are for intermediate-advanced scripters who want to spend less time writing banking routines and more time on interesting things, although you may also learn some scripting techniques too.

About this tutorial-
BlackLists are lists of black dots, duh. Let me explain. A great way of finding items in the bank and inventory is by making a DTM containing points on the black(65536) outline of the item, because it never changes. (Note a DTM like this will work the same for gold bars and steel bars, because they have the same outline. To make it only work for gold, you will need a point on the gold color, with some tolerance, because it does change. See a DTM tut for more info, as BlackLists don't worry about this.) Ok, so every (type of) item has a black outline which can be used to identify it. This outline is a bunch of points, which have the color 65536. Basically (<<keyword), these points are the BlackList for that item.

When you look in a bank, and scroll to the top (FixBank) there are 48 visible BankSlots, 6 rows of 8. In B4 these 48 are numbered like in the inventory, reading left to right, top to bottom, 1 to 48. The corners of these BankSlots can be found with a formula, for BlackLists we just need the top left. Each BankSlot is 31 by 31 pixels, 961 pixels. Now, we want to look at the pixels for black(65536), but we don't need all of them. So the question is, which pixels do we look at? For that we need a TPointArray. A TPointArray is an array of TPoints. Each TPoint contains 2 values, the x and y. In this case, they x and y are the distances between the pixel we want to look at, and the top left corner of the box (BankSlot) we are looking in. First we declare a variable to hold our list of points to check.
var MyList:TPointArray;

Next we need a function that creates the TPointArray of the points relative to the top left of bankslots we want to look at. The following creates an array with about 385 points, which is 40% of all the points in a bankslot. All the numbers are from 0 to 31, because its relative to the top left corner of the bankslot.

{************************************************* ******************************
function Create40PercentTPA:TPointArray;
By: Boreas
Note: Purely an internal function, used in setup.
Description: Returns a TPointArray containing the relative (to x1,y1 of a BSlot)
for 385 points (out of 31*31, hence 40%). Only needs to be done once, to create
the list of points to check for 65536. Only takes like 15ms, and I didn't
feel like typing them all out.
************************************************** *****************************}
function Create40PercentTPA:TPointArray;
var Counter,hx,hy:integer;
var TPointsToCheck:array [0..384] of TPoint;
begin
repeat
hy:=15;
hx:=hx+1;
repeat
hy:=hy+1;
if (((hx mod 4)=0) or ((hy mod 4)=0)) then
begin
TPointsToCheck[Counter].x:=hx;
TPointsToCheck[Counter].y:=hy;
Counter:=Counter+1;
end;
until hy=31;
until hx=31;
result:=TPointsToCheck;
end;

Oops. It's not 40% or 385 points. It's more like 208 points, 22%. This is because I added the hy:=15;, so that it ignores the part where the yellow amount number is. I will change the name when B4 comes out.

You can create you own function (see pwnaz0r's max accuracy one on page 2), just make sure to skip the top 15 pixels where the number is. The one above looks like a net, with 7 lines across and 7 lines down, like how a tic-tac-toe(naughts and crosses for UK) board has 2. You can make it slower but more accurate by changing the mod 4 to mode 2, which will give it 15 lines both way. You can do the opposite by changing to 8, giving 3. You could also do something with circles. I chose the net pattern because you can't draw a line (more than 3 pixels long) without catching the net. You don't even need a formula, but doing it by hand can take a while. Basically, you just need a TPointArray containing the points in the BankSlot you want to look at, with the top left being 0,0. More points is more accurate but slower.

MyList:=Create40PercentTPA;

Here's how to get the coords of the top left corner of a bankslot. I won't go into how it works, this is just how I do it for B4.
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);

So we have a list a points in a BankSlot we want to look at. The next step is to go through the list for an item and check which are black(65536). This is fairly simple, go through the list you created, adding the coords in the TPoints to the top left corner, and check if the color there is black. If it is, add the index of the list to another list, an array of integers. This is faster and simpler than making another TPoint array, because we will need to output the list somehow later.

{************************************************* ******************************
function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
By: Boreas
Description: Looks at the points in the list for an item, and returns an array
contatining the indexes of the points that are black.
Usage: WhichBankSlot-just what it sounds like. WhichList-the TPointArray
containing positions relative to the x1,y1 of a bankslot which you want to check
************************************************** *****************************}

function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
var Counter,Counter2,Tmpx1,Tmpy1,ListLength:integer;
var TmpArray:array of integer;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichList)-1;
setarraylength(tmparray,1);
for Counter:= 0 to ListLength do
begin

if GetColor(Tmpx1+WhichList[Counter].x,Tmpy1+WhichList[Counter].y)=65536 then
begin
TmpArray[Counter2]:=Counter;
Counter2:=Counter2+1;
setarraylength(TmpArray,Counter2+1);

end;
end;
result:=TmpArray;
end;

Now, to make a BlackList for an item, just declare an array of integers....
var tmpList:array of integer;
put the item in a bankslot (45 for example), and make the TPointArray as discussed before.
tmplist:=CreateItemBlackList(45,MyList);

Now tmplist is the BlackList used to identify that type of item. If you create the list during runtime, just use that array of integer. If you want to make it when writing a script, like traditional DTMs, you need to convert it into something you can transfer. For that, you can use
writeln(intarraytostr(tmplist2));
IntArrayToStr by Moparisthebest is in SRL/Misc/ArrayLoaders.scar

This will display a bunch of numbers with spaces between them. To put them back into the usable array, use StrToIntArray. This is like DTMFromString. Once you have the string, remember what item it goes to, and what TPointArray was used to create it (in this case, it was MyList made with Create40PercentTPA), it will only work later if you use the same TPointArray. B4 will make this process easier.

So now you have the BlackList for an item type, the next step is using that to identify that item type again. You could use the following:
{************************************************* ******************************
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
By: Boreas
Description: Returns true if an items blacklist matches the one in the parameters
************************************************** *****************************}
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
var Counter,Tmpx1,Tmpy1,ListLength:integer;
var TheBoolean:boolean;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichBlackList)-1;
TheBoolean:=true;
repeat
if not(getcolor(Tmpx1+Whichlist[WhichBlacklist[Counter]].x,
Tmpy1+Whichlist[WhichBlacklist[Counter]].y)=65536) then
TheBoolean:=false;
Counter:=Counter+1;
until ((not(TheBoolean)) or (Counter=(ListLength+1)));
result:=TheBoolean;
end;

This will look at the integers in the BlackList, match them up to the indexs of the TPoint in the WhichList, look at the corresponding TPoints, and then add those values to the top left of the bankslot you are looking at, and check if the color at those pixels are black.

That works, however there is another way shown below, that may take a little more time, but is still very fast. The above method runs into the same problem as DTMs, whereas the method below does not. The problem is, if you make a DTM of a unstrung bow, it will be found in a strung bow. The method below creates a BlackList of an item in question, and compares it to the one you made before. Since you are using the exact same method to make the list, they will be exactly the same if they are the same type of item.

Let's assume tmplist is a BlackList for cut gems you made by looking at diamond. Also assume that there is another cut gem (lets say a sapphire) in spot 46. The script below will make a BlackList for the item in spot 46, in the same way tmplist was made. It will see that they are both cut gems and say yes.

tmplist2:=CreateItemBlackList(46,MyList);
if CompareIntArrays(tmplist,tmplist2) then writeln('yes')

For this you need CompareIntArrays which simply looks at each integer in an array, and if they all match up, returns true.
{************************************************* ******************************
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
By: Boreas
Description: Returns true both arrays are the same
************************************************** ****************************}
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
var Counter:integer;
begin
if not(getarraylength(FirstIntArray)=getarraylength(S econdIntArray)) then
result:=false;


if (getarraylength(FirstIntArray)=getarraylength(Seco ndIntArray)) then
begin
result:=true;
repeat
if not(FirstIntArray[Counter]=SecondIntArray[Counter]) then
result:=false;
Counter:=Counter+1;
until ((Counter=getarraylength(FirstIntArray)) or (result=false));
end;
end;

Run the following script on the picture below to see it in action.


program New;
{.include SRL/SRL.scar}
var MyList:TPointArray;
var tmpList,tmpList2:array of integer;


var t:integer;
{************************************************* ******************************
function Create40PercentTPA:TPointArray;
By: Boreas
Note: Purely an internal function, used in setup.
Description: Returns a TPointArray containing the relative (to x1,y1 of a BSlot)
for 385 points (out of 31*31, hence 40%). Only needs to be done once, to create
the list of points to check for 65536. Only takes like 15ms, and I didn't
feel like typing them all out.
************************************************** *****************************}
function Create40PercentTPA:TPointArray;
var Counter,hx,hy:integer;
var TPointsToCheck:array [0..384] of TPoint;
begin
repeat
hy:=15;
hx:=hx+1;
repeat
hy:=hy+1;
if (((hx mod 4)=0) or ((hy mod 4)=0)) then
begin
TPointsToCheck[Counter].x:=hx;
TPointsToCheck[Counter].y:=hy;
Counter:=Counter+1;
end;
until hy=31;
until hx=31;
result:=TPointsToCheck;
end;

{************************************************* ******************************
function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
By: Boreas
Description: Looks at the points in the list for an item, and returns an array
contatining the indexes of the points that are black.
Usage: WhichBankSlot-just what it sounds like. WhichList-the TPointArray
containing positions relative to the x1,y1 of a bankslot which you want to check
************************************************** *****************************}

function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
var Counter,Counter2,Tmpx1,Tmpy1,ListLength:integer;
var TmpArray:array of integer;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichList)-1;
setarraylength(tmparray,1);
for Counter:= 0 to ListLength do
begin

if GetColor(Tmpx1+WhichList[Counter].x,Tmpy1+WhichList[Counter].y)=65536 then
begin
TmpArray[Counter2]:=Counter;
Counter2:=Counter2+1;
setarraylength(TmpArray,Counter2+1);

end;
end;
result:=TmpArray;
end;
{************************************************* ******************************
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
By: Boreas
Description: Returns true if an items blacklist matches the one in the parameters
************************************************** *****************************}
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
var Counter,Tmpx1,Tmpy1,ListLength:integer;
var TheBoolean:boolean;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichBlackList)-1;
TheBoolean:=true;
repeat
if not(getcolor(Tmpx1+Whichlist[WhichBlacklist[Counter]].x,
Tmpy1+Whichlist[WhichBlacklist[Counter]].y)=65536) then
TheBoolean:=false;
Counter:=Counter+1;
until ((not(TheBoolean)) or (Counter=(ListLength+1)));
result:=TheBoolean;
end;

{************************************************* ******************************
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
By: Boreas
Description: Returns true both arrays are the same
************************************************** ****************************}
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
var Counter:integer;
begin
if not(getarraylength(FirstIntArray)=getarraylength(S econdIntArray)) then
result:=false;


if (getarraylength(FirstIntArray)=getarraylength(Seco ndIntArray)) then
begin
result:=true;
repeat
if not(FirstIntArray[Counter]=SecondIntArray[Counter]) then
result:=false;
Counter:=Counter+1;
until ((Counter=getarraylength(FirstIntArray)) or (result=false));
end;
end;
function intArrayToStr(intArray: array of Integer): string;
var
i, arrayLength: Integer;
begin
arrayLength := GetArrayLength(intArray);
repeat
Result := Result + IntToStr(intArray[i]);
if (not (i = (arrayLength - 1))) then
Result := Result + ' ';
i := i + 1;
until (i = arrayLength)
end;

function strToIntArray(intArray: string): array of Integer;
var
i, spacePos: Integer;
begin
repeat
SetArrayLength(Result, i + 1);
spacePos := Pos(' ', intArray);
if (not (spacePos = 0)) then
begin
Result[i] := StrToInt(Copy(intArray, 1, spacePos - 1));
end
else
begin
Result[i] := StrToInt(Copy(intArray, 1, Length(intArray)));
break;
end;
Delete(intArray, 1, spacePos);
i := i + 1;
until (False)
end;

begin
setupsrl;
t:=getsystemtime;
MyList:=Create40PercentTPA;
tmplist:=CreateItemBlackList(45,MyList);
tmplist2:=CreateItemBlackList(46,MyList);
//writeln(inttostr(getarraylength(tmplist2)));
//writeln(intarraytostr(tmplist2));
if CompareIntArrays(tmplist,tmplist2) then writeln('yes')

//if (tmplist=tmplist2) then writeln('yes');
//writeln(inttostr(getsystemtime-t)+'ms');
{
if CheckItemBlackList(46,tmplist,mylist) then
writeln('yes');
writeln(inttostr(getsystemtime-t));
}end.

http://img180.imageshack.us/img180/7964/bankcq0.th.png (http://img180.imageshack.us/my.php?image=bankcq0.png)

Please note that is a small technique, to be combined with others. It is a very small part of B4, and doesn't do that much without the rest. But I thought I would post it here now so you can use it if you want. Plus, unlike most of B4, this doesn't require any edits to SRL, or lower level supporting functions (because it is one) besides the ones I posted above.

Please note this tutorial is very rough. If anyone is interested and needs me to clean it up a bit, I will. Any questions, feel free to ask. Since I created it, it's hard for me to explain it, as I was never taught it, so I may have left out important parts lol.

:D Hehe I had 3 tuts out and none were about actual scripting, so I had to fix that lol:D

Smartzkid
02-22-2007, 11:11 PM
Wow, Awesome! Wow...:p I'm spellbound

Thanks so much! This will be a big help to the community

:D FIRST POST W00T!

EDIT:
Ouch! My head hurts! =D

Boreas
02-22-2007, 11:17 PM
Thanks for reading :D

Please let me know any improvements I can make on the tutorial (appearance and understandability) and the method (efficiency and ease of use), as this will change by the time I release B4.

Smartzkid
02-23-2007, 03:13 AM
Well, I have yet to read it and understand everything, but I'm nowhere near as good a scripter as you, so I wouldn't expect to

Lookin forward to seeing you release this 'B4', maybe when I'm done with my powercutter, I'll make a banker of some sort...

Boreas
02-23-2007, 03:23 AM
If it's hard to understand, it's because I threw it together pretty quickly. Lemme know and I'll fix it.

I will probably be releasing parts of B4 as I go along, if they are helpful on their own. This way people can make use of them and I can get feedback to refine them before releasing the whole system. Expect more stuff like this because I have more time to script now.

juessx
02-23-2007, 04:41 AM
Works, and thanks =D.

I'd like to add. You are very clever, people could save memb usage and everything this! Noice, man. YEE.

EDIT:

I understand most of it, because WhiteShadow, taught me TPointArrays stuff. But i'll probably need to study those coord math things a bit more. :p

P.S - LOLLL I was the person talking to you earlier bechus i was messing with him comp. :D

Boreas
02-23-2007, 04:53 AM
Thanks. :D

If you mean
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
then look at this

Players[player].BankSlot[i].row:=((i-1)/8)+1;
Players[player].BankSlot[i].column:=((i+7)mod 8)+1;
Players[player].BankSlot[i].x1:=79+((Players[player].Bankslot[i].column-1)*47);
Players[player].Bankslot[i].y1:=62+((Players[player].Bankslot[i].row-1)*38);
Players[player].BankSlot[i].x2:=Players[player].Bankslot[i].x1+31;
Players[player].BankSlot[i].y2:=Players[player].Bankslot[i].y1+31;

i is slot number
First it gets the row and column number
Then it uses the fact the distance between the left edge of 2 adjacent bank slots is 47 (31 is the width with 16 in between)

The tmpx1 line above is just this condensed.

Ah ok lol.

JAD
02-23-2007, 04:09 PM
GREAT tut boreas! very nice. i just have one question though. how can somebody as uber as you at scripting, not have any scripts? lol. cause we could all say you know some of the basics of scar scripting no? :P

Boreas
02-23-2007, 09:57 PM
Hehe I like making functions and stuff more. When I'm not busy with B4 and MouseHelper (move mouse and monitor uptext/randoms at the same time), I'll work on a lumbridge script, maybe some other stuff. Most of my scripts are for weird things that are only useful for me, like ring crafter etc, plus I modified a few of other peoples scripts, other than that, I mostly write functions.

ATM I'm working on another function, and maybe a tutorial to go with it, for combining BlackLists with color, so that you can distinguish between a steel bar and gold bar.

Ejjman
02-23-2007, 10:30 PM
Boreas, your the man. ;)

++rep for dinner?

Boreas
02-23-2007, 10:45 PM
Hehe thanks, I'll put it on the pizza :p

Smartzkid
02-23-2007, 10:50 PM
Wow! Simply amazing! I dread the day when your Lumby script comes out :p gonna make everything else look like crap ;)

Boreas
02-23-2007, 10:52 PM
Hehe, won't be for a while. Ran into a problem with FindColorSkipBoxArray. So just B4 for now :D

pwnaz0r
02-24-2007, 12:22 AM
+ rep bro nice job explaining

EDIT : how long have you been working on your lumby script? I think you were still working on it be4 I even came here?

Boreas
02-24-2007, 12:41 AM
Around 1st week of jan. Tried a couple techniques for finding doors, found one that I like but it's not working. That's as far as I got lol.

pwnaz0r
02-24-2007, 02:09 AM
watcha doin?

WhiteShadow
02-24-2007, 04:11 AM
@juessx - your dead meat foo. Ima eat you.


lols, that's poon Boreas.

EDIT: sorry fixd it.

Boreas
02-24-2007, 04:19 AM
lol I don't really understand those 2 posts:confused:

YoHoJo
02-24-2007, 08:21 PM
Whiteshadow talks funny =)
Im used to it on MSN ill translate:

Whiteshadow is just pointing out that he taught JEssux TpointArrays,
He likes your procedure because it poons
And i think he fixed something?

Hooblah!

Boreas
02-24-2007, 09:23 PM
Ahhh I see now lol

Smartzkid
02-25-2007, 10:48 PM
Hey, I read the whole thing, and I actually understood it! :cool: nice functions, I'm gonna see if I can utilize them in one of my three upcoming scripts =)

Boreas
04-09-2007, 02:06 AM
Cool. Check out the other one too, as this isn't much use without it. (except for finding things that there are one type of, chisels, threads, nooby shield, er can't think of anything else but I know there's more)

Edit:

Here is an Easy BlackList Maker

Open up a bank, make sure the items you want to create BlackLists for are in the top 48, make sure its scrolled up all the way, and run

program New;
{.include SRL/SRL.scar}

type
BlackList = array of integer;

type
BlackListNet = array of Tpoint;
{************************************************* ******************************
function CreateTightNet : BlackListNet;
By: Boreas
Note: Purely an internal function, used in setup.
Description: Same as above but takes a little (not noticeable) longer and is
more accurate. 38% of the slot. 74% of slot without amount
************************************************** *****************************}
function CreateTightNet :BlackListNet;
var Counter,hx,hy:integer;
var TPointsToCheck:array [0..367] of TPoint;
begin
repeat
hy:=15;
hx:=hx+1;
repeat
hy:=hy+1;
if (((hx mod 2)=0) or ((hy mod 2)=0)) then
begin
TPointsToCheck[Counter].x:=hx;
TPointsToCheck[Counter].y:=hy;
Counter:=Counter+1;
end;
until hy=31;
until hx=31;
result:=TPointsToCheck;
end;
{************************************************* ******************************
function CreateItemBlackList(WhichBankSlot:integer;WhichNet :BlackListNet):BlackList;
By: Boreas
Description: Looks at the points in the list for an item, and returns an array
contatining the indexes of the points that are black.
Usage: WhichBankSlot-just what it sounds like. WhichList-the TPointArray
containing positions relative to the x1,y1 of a bankslot which you want to check
************************************************** *****************************}
function CreateItemBlackList(WhichBankSlot:integer;WhichNet :BlackListNet):BlackList;
var Counter,Counter2,Tmpx1,Tmpy1,ListLength:integer;
var TmpArray:array of integer;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichNet)-1;
setarraylength(tmparray,1);
for Counter:= 0 to ListLength do
begin

if GetColor(Tmpx1+WhichNet[Counter].x,Tmpy1+WhichNet[Counter].y)=65536 then
begin
TmpArray[Counter2]:=Counter;
Counter2:=Counter2+1;
setarraylength(TmpArray,Counter2+1);

end;
end;
setarraylength(tmpArray,Counter2);
result:=TmpArray;
end;
{************************************************* ******************************
function GetNameOfItemInBank: string;
By: Boreas, bases off of Ron's Replace
Description: Takes item name from uptext in bankscreen, and changes spaces
to underscores
************************************************** *****************************}
function GetNameOfItemInBank: string;
var
a : LongInt;
TheString:string;
begin
TheString:=GetUptext;
a := Pos('Withdraw 1 ', TheString);
if(a = 0)then
begin
// Do nothing..
end else
begin
Delete(TheString, a, Length('Withdraw 1 '));
Insert('', TheString, a);
a := Pos(' /', TheString);
delete(thestring,a,Length(TheString));
repeat
a := Pos(' ', TheString);
if a<>0 then
begin
Delete(TheString, a, 1);
Insert('_', TheString, a);
end;
until a=0;
repeat
a := Pos(chr(39), TheString);
if a<>0 then
begin
Delete(TheString, a, 1);
end;
until a=0;

Result := TheString;
end;
end;

{************************************************* ******************************
function LongTextBreakDown(TheString):string;
By: Ron and Boreas
Description: Formats a long string so that it looks like the result of
DTM to text. Pretty much only useful for BlackList to Text
************************************************** *****************************}

function LongTextBreakDown(TheString:string):array of string;
var iter:integer;
tmpstring:string;
begin
tmpstring:=TheString;
if length(tmpstring) > 62 then
begin
setarraylength(result,iter+1);
result[iter]:=copy(tmpstring, 1, 61)+chr(39)+' +';
delete(tmpstring, 1, 61);
while length(tmpstring) > 69 do
begin
iter:=iter+1;
setarraylength(result,iter+1);
result[iter]:=' '+chr(39)+copy(tmpstring, 1, 53)+chr(39)+' +';
delete(tmpstring, 1, 53);
end;
iter:=iter+1;
setarraylength(result,iter+1);
result[iter]:=' '+chr(39)+tmpstring;
end else
begin
setarraylength(result,1);
result[0]:=tmpstring;
end;
end;
{************************************************* ******************************
procedure WriteBlackList(TheBlackList: BlackList);
By: Boreas/moparisthebest
Description: Displays a BlackList as a string in debug box. Basically
array of integer -> string and DTM editor's DTM to Text put together
************************************************** *****************************}
procedure WriteBlackList(TheBlackList: BlackList);
var
i, arrayLength: Integer;
mystr,tmpstr,tmpresult:string;
aos:array of string;
begin
arrayLength := GetArrayLength(TheBlackList);
repeat
tmpresult := tmpresult + IntToStr(TheBlackList[i]);
if (not (i = (arrayLength - 1))) then
tmpresult := tmpresult + ' ';
i := i + 1;
until (i = arrayLength)
mystr:=GetNameOfItemInBank;
if mystr='' then mystr:='BlackList';
tmpresult:=' BL_'+mystr+' := LoadBlackListFromString('+chr(39)+tmpresult+chr(39 )+');';
aos:=LongTextBreakDown(tmpresult);
for i:=0 to getarraylength(aos)-1 do
writeln(aos[i]);
end;


var MyNet:BlackListNet;
MyList:Blacklist;
slot1:integer;

begin
SetupSRL;
MyNet:=CreateTightNet;
writeln('Put mouse over item and press f12');
repeat
repeat
wait(30);
until ((isfkeydown(12)) or (isfkeydown(11)));
if not(isfkeydown(11)) then
begin
getmousepos(x,y);
slot1:=(((((y-62) div 38)+1)-1)*8)+(((x-79) div 47)+1);
MyList:=CreateItemBlackList(slot1,MyNet);
WriteBlackList(Mylist);
writeln('Press F12 to do another one');
writeln('Press F11 to end');
end;
until isfkeydown(11);
end.

You can use the output with {************************************************* ******************************
function LoadBlackListFromString(BlackListString: string): BlackList;
By: Boreas/moparisthebest
Description: Loads a BlackList from a string given by WriteBlackList. Basically
string -> array or integer
************************************************** *****************************}
function LoadBlackListFromString(BlackListString: string): BlackList;
var
i, spacePos: Integer;
begin
repeat
SetArrayLength(Result, i + 1);
spacePos := Pos(' ', BlackListString);
if (not (spacePos = 0)) then
begin
Result[i] := StrToInt(Copy(BlackListString, 1, spacePos - 1));
end
else
begin
Result[i] := StrToInt(Copy(BlackListString, 1, Length(BlackListString)));
break;
end;
Delete(BlackListString, 1, spacePos);
i := i + 1;
until (False)
end;
which will be in the BlackList include I am putting together.

YoHoJo
04-09-2007, 03:06 AM
Nice Stuff =)
Ima use these in my fletcher maybey =)

Boreas
04-09-2007, 03:09 AM
I should have it working for inventory too in the next couple of days :D

A G E N T
04-09-2007, 03:30 AM
I understand it! *pats self on back* Very nice! This is a very useful tool and I look forward to using it. On the topic of bankbrowsing, is there such thing as a function that scrolls the bank scroller thingy?

Ejjman
04-09-2007, 03:32 AM
Fixbank; scrolls to the top.

Boreas
04-09-2007, 03:43 AM
For the impatient

procedure QuickFixBank;
begin
if Bankscreen then
if (GetColor(475, 75) = 1777699) then
mouse(470+random(482-470),76+random(83-76),0,0,true);
end;

|-|0/\/\13 /\/\4|\|
04-18-2007, 02:00 PM
WoW nice tut ... thats good...!

n3ss3s
05-19-2007, 03:28 PM
amazing and
When I'm not busy with B4 and MouseHelper (move mouse and monitor uptext/randoms at the same time)
Thats what ive been waiting for! It will totally chance opportunities of randomizing and autofighting.

Boreas
05-23-2007, 07:59 PM
A lil update:

Open RS when bank is open and run this
program New;
{.include srl/srl.scar}
var BankBmp,w,h:integer;
begin
//+3 for opening bitmap in paint
GetClientDimensions(w,h);
BankBmp:=BitmapfromString(w,h,'');
CopyClientToBitmap(BankBmp,3,3,w+3,h+3);
SaveBitmap(BankBmp,apppath+'perfectscreenie2.bmp') ;
end.


There will be a picture saved in the SCAR folder, open it with paint. You can close RS now.

Run the following on the picture.
program New;
{.include SRL/SRL.scar}
var MyList:TPointArray;
var tmpList,tmpList2:array of integer;


var t:integer;
{************************************************* ******************************
function CreateCustomNet(Num:integer):TPointArray;
By: Boreas
Note: Purely an internal function, used in setup.
Description: Returns a TPointArray containing the relative (to x1,y1 of a BSlot)
for a custom amount of points. Only needs to be done once, to create
the list of points to check for 65536. Only takes like 15ms, and I didn't
feel like typing them all out.
Num=1 will check every point
Num=2 will make a net with 1x1 holes
Num=4 will make a net with 3x3 holes
************************************************** *****************************}
function CreateCustomNet(Num:integer):TPointArray;
var Counter,hx,hy,tAL:integer;
var TPointsToCheck:array of TPoint;
begin
repeat
hy:=15;
hx:=hx+1;
repeat
hy:=hy+1;
if (((hx mod Num)=0) or ((hy mod Num)=0)) then
begin
tAL:=tAL+1;
setarraylength(TPointsToCheck,tAL);
TPointsToCheck[Counter].x:=hx;
TPointsToCheck[Counter].y:=hy;
Counter:=Counter+1;
end;
until hy=31;
until hx=31;
result:=TPointsToCheck;
end;

{************************************************* ******************************
function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
By: Boreas
Description: Looks at the points in the list for an item, and returns an array
contatining the indexes of the points that are black.
Usage: WhichBankSlot-just what it sounds like. WhichList-the TPointArray
containing positions relative to the x1,y1 of a bankslot which you want to check
************************************************** *****************************}

function CreateItemBlackList(WhichBankSlot:integer;WhichLis t:TPointArray):array of integer;
var Counter,Counter2,Tmpx1,Tmpy1,ListLength:integer;
var TmpArray:array of integer;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichList)-1;
setarraylength(tmparray,1);
for Counter:= 0 to ListLength do
begin

if GetColor(Tmpx1+WhichList[Counter].x,Tmpy1+WhichList[Counter].y)=65536 then
begin
TmpArray[Counter2]:=Counter;
Counter2:=Counter2+1;
setarraylength(TmpArray,Counter2+1);

end;
end;
result:=TmpArray;
end;
{************************************************* ******************************
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
By: Boreas
Description: Returns true if an items blacklist matches the one in the parameters
************************************************** *****************************}
function CheckItemBlackList(WhichBankSlot:integer;WhichBlac kList:array of integer;WhichList:TPointArray):boolean;
var Counter,Tmpx1,Tmpy1,ListLength:integer;
var TheBoolean:boolean;
begin
Tmpx1:=79+((((WhichBankSlot+7)mod 8))*47);
Tmpy1:=62+((((WhichBankSlot-1)/8))*38);
ListLength:=getarraylength(WhichBlackList)-1;
TheBoolean:=true;
repeat
if not(getcolor(Tmpx1+Whichlist[WhichBlacklist[Counter]].x,
Tmpy1+Whichlist[WhichBlacklist[Counter]].y)=65536) then
TheBoolean:=false;
Counter:=Counter+1;
until ((not(TheBoolean)) or (Counter=(ListLength+1)));
result:=TheBoolean;
end;

{************************************************* ******************************
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
By: Boreas
Description: Returns true both arrays are the same
************************************************** ****************************}
function CompareIntArrays(FirstIntArray,SecondIntArray:arra y of integer):boolean;
var Counter:integer;
begin
if not(getarraylength(FirstIntArray)=getarraylength(S econdIntArray)) then
result:=false;


if (getarraylength(FirstIntArray)=getarraylength(Seco ndIntArray)) then
begin
result:=true;
repeat
if not(FirstIntArray[Counter]=SecondIntArray[Counter]) then
result:=false;
Counter:=Counter+1;
until ((Counter=getarraylength(FirstIntArray)) or (result=false));
end;
end;
function intArrayToStr(intArray: array of Integer): string;
var
i, arrayLength: Integer;
begin
arrayLength := GetArrayLength(intArray);
repeat
Result := Result + IntToStr(intArray[i]);
if (not (i = (arrayLength - 1))) then
Result := Result + ' ';
i := i + 1;
until (i = arrayLength)
end;

function strToIntArray(intArray: string): array of Integer;
var
i, spacePos: Integer;
begin
repeat
SetArrayLength(Result, i + 1);
spacePos := Pos(' ', intArray);
if (not (spacePos = 0)) then
begin
Result[i] := StrToInt(Copy(intArray, 1, spacePos - 1));
end
else
begin
Result[i] := StrToInt(Copy(intArray, 1, Length(intArray)));
break;
end;
Delete(intArray, 1, spacePos);
i := i + 1;
until (False)
end;

var BankBmp:integer;
procedure HighlightSlot(Slot,Color:integer);
var sx1,sx2,sy1,sy2:integer;
begin
sx1:=79+((((Slot+7)mod 8)+1-1)*47)-79+1;
sy1:=62+((((Slot-1)/8)+1-1)*38)-62+1;
sx2:=79+((((Slot+7)mod 8)+1-1)*47)+31-79+1;
sy2:=62+((((Slot-1)/8)+1-1)*38)+31-62+1;

for x:=sx1 to sx2 do
begin
for y:=sy1 to sy2 do
begin
if FastGetPixel(BankBmp,x,y)=65536 then
FastSetPixel(BankBmp,x,y,Color);
end;
end;
CopyCanvas(getbitmapcanvas(BankBmp),getdebugcanvas ,0,0,439-79,283-62,0+5,0+5,439-79+5,283-62+5);
DisplayDebugImgWindow(439-79+10,283-62+10);
end;

procedure StartBankDisplay;
begin
DisplayDebugImgWindow(439-79+10,283-62+10);
BankBmp:=BitmapfromString(1+439-79,1+283-62,'');
CopyClientToBitmap(BankBmp,79,62,439+1,283+1);
CopyCanvas(getbitmapcanvas(BankBmp),getdebugcanvas ,0,0,1+439-79,1+283-62,0+5,0+5,1+439-79+5,1+283-62+5);

DisplayDebugImgWindow(439-79+10,283-62+10);
end;
var i,i2,color:integer;
begin
setupsrl;
t:=getsystemtime;
MyList:=CreateCustomNet(2);
tmplist:=CreateItemBlackList(24,MyList);
tmplist2:=CreateItemBlackList(6,MyList);
//writeln(inttostr(getarraylength(tmplist2)));
//writeln(intarraytostr(tmplist2));
if CompareIntArrays(tmplist,tmplist2) then writeln('yes')

StartBankDisplay
for i2:=1 to 48 do
begin
//StartBankDisplay
tmplist:=CreateItemBlackList(i2,MyList);
color:=random(256*256*256);
for i:=1 to 48 do
begin
tmplist2:=CreateItemBlackList(i,MyList);
if CompareIntArrays(tmplist,tmplist2) then
begin
HighlightSlot(i,color);
end;
end;
// repeat
//wait(30);
// until isfkeydown(12);

end;
FreeBitmap(BankBmp);


//if (tmplist=tmplist2) then writeln('yes');
//writeln(inttostr(getsystemtime-t)+'ms');
{
if CheckItemBlackList(46,tmplist,mylist) then
writeln('yes');
writeln(inttostr(getsystemtime-t));
}end.

You may notice the first function is new. I was playing around with the number 4 in
{************************************************* ******************************
function Create40PercentTPA:TPointArray;
By: Boreas
Note: Purely an internal function, used in setup.
Description: Returns a TPointArray containing the relative (to x1,y1 of a BSlot)
for 385 points (out of 31*31, hence 40%). Only needs to be done once, to create
the list of points to check for 65536. Only takes like 15ms, and I didn't
feel like typing them all out.
************************************************** *****************************}
function Create40PercentTPA:TPointArray;
var Counter,hx,hy:integer;
var TPointsToCheck:array [0..384] of TPoint;
begin
repeat
hy:=15;
hx:=hx+1;
repeat
hy:=hy+1;
if (((hx mod 4)=0) or ((hy mod 4)=0)) then
begin
TPointsToCheck[Counter].x:=hx;
TPointsToCheck[Counter].y:=hy;
Counter:=Counter+1;
end;
until hy=31;
until hx=31;
result:=TPointsToCheck;
end;

And found that when it is 4, runes show up the same as ess, and when it is 2, they are different. In the example above you can change the 2 to a 4 on line 184 and see for yourself (assuming you have runes and ess in your bank).

Anyways, I have found that DTMs can confuse cowhides, runes, bars, clay, gems etc, if not tweaked. And the idea is that this is automatic. So if anything has the same highlight color when you run this, please let me know.

Ejjman
05-25-2007, 02:28 AM
Did, Chaos Tally wasn't in gorup ;)

And if anyone can't understand Boreas, its quite simple.

1. Go into RS, onto your main I guess; or banker.
2. Drag client, run that first script. It will take a pic and save.
3. Open up paint, and go open the picture. It is inside the SCAR 3.06 folder.
4. Make around the screenie, doesn't have to be perfect, and cilck and drag crosshairs. It will find it. ;)
5. Run the script. A debug image will pop up, and it will be sweet and fun to watch :)

PS. On step 4, Run the second script :p

Boreas
05-26-2007, 01:54 AM
Chaos tally is different, not my problem :p

Thanks for explaining :)

gerauchert
08-02-2007, 04:15 AM
i understand the whole detection thing of the items in each slot...but how would you get it to click the item once found? Sry if there is a real obvious answer, but its late here and all that code is running together lolz...

idk ill play around with it but it looks really sweet (using your FindCoins atm for my merchanter)

ty :D

Boreas
08-02-2007, 07:39 PM
I release MouseSlot somewhere, can't remember where. I'll write it again later.

LordGregGreg
08-13-2007, 02:18 AM
I don't care if i am a little late on reading this... boreas, this is amazing... god, everytime I get discoraged thinking "why am i at some imature little forum about a 13 year olds game" someting really ingeniously clever like this comes to my knwledge.

this is really smart. ++rep

dvdcrayola
08-24-2007, 07:58 PM
gravedig for me.. who cares, its a tut... im going to read this tonight when i have more time.. might not use it right away... but hopefully will learn

Bobzilla69
05-01-2011, 07:21 AM
why is it when i run this to get BL count i get a different number depending on which row of bank the item is in?

so if i had soft clay on first row i get 50 but if i move it to second row i get 46 ?

for i:=1 to 11 do
begin
Items:= BankIndexToMSBox(i);
MMouse(item.x + 5, item.y + 5, 2, 2);
Wait(250);
Writeln('Item is : '+rs_GetUpTextAt(89, 5) +' and has a BL count of '+inttostr(CountColor(SRL_OUTLINE_BLACK, Items.X1 , Items.Y1 + 14, Items.X2 , Items.Y2)));
end;

also great tutorial which is why i am asking this question :)

Sex
05-01-2011, 07:23 AM
Possibly BankIndexToMSBox is returning different sized/placed boxes for each spot?

Bobzilla69
05-01-2011, 07:37 AM
Possibly BankIndexToMSBox is returning different sized/placed boxes for each spot?

yes it is, the first line is all the same.

so
row one would be 50*50
row two would be 51*51
row three would be 52*52

for i:=1 to 40 do
begin
Items:= BankIndexToMSBox(i);
item:= BankIndexToMSPoint(i);
if CountColor(SRL_OUTLINE_BLACK, Items.X1 , Items.Y1 + b, Items.X2 , Items.Y2) = 0 then exit;
MMouse(item.x+8, item.y+10, 0, 0);
Wait(250);
if (i = 11) or (i = 21) or (i = 31) then
begin
b:= b - 1;
end;
Writeln('Item at Spot '+inttostr(i)+' is '+rs_GetUpTextAt(89,5)+'has a BL count of '+inttostr(CountColor(SRL_OUTLINE_BLACK, Items.X1 , Items.Y1 + b, Items.X2 , Items.Y2)));

end;

i thought they would all be the same size :(

Sex
05-01-2011, 07:44 AM
Weird, they should be...rewrite it bro ;D.

cycrosism
05-01-2011, 08:14 AM
Does this still work? Its from 07

Bobzilla69
05-01-2011, 08:29 AM
yes the stuff on first pages does :)


Compiled succesfully in 577 ms.
SRL Compiled in 16 msec
yes
Successfully executed.


had to only select the bank screen as image but works like a treat

Echo_
05-01-2011, 01:40 PM
Thanks for bumping this, its really an interesting read

Boreas
05-02-2011, 10:17 PM
I guess concept wise this thread is still valid, but code wise Nielsie made a newer version a while back. Not sure where it is, or whether it needs updating for Simba, but it would be awesome if one or more people would take that on.


Please note the difference between a BlackList and a count of how many black pixels an item has (ie the length of a BlackList, call it a BlackCount or something). Two different items (I mean completely different shape, not gold bar vs silver bar), can have the same BlackCount but have different BlackLists, as BlackLists include the positions (relative to the top left of the slot) of the black pixels. This is why InvBox, BankIndexToMSBox, and GE/store/tradescreen equivalents, need to be absolutely perfect and easily update-able for BlackLists to work (I think I rewrote InvBox when I started BlackLists), where as they just need to be pretty close for BlackCounts/DTMs/etc . Remember, you don't scan and find a BlackList in an area like with a DTM, you generate a BlackList from a specific spot, and compare it to a stored BlackList (comparing the lengths first, then checking the positions), then check the next spot etc.

Bonfield
05-02-2011, 11:15 PM
What scripts have used this to it's full extent?

I have tried this, it works really well but I don't think I used it to it's capability all I did was compare a countcolor of the outline, a color taken from the middle of the item box an a width check I also had a primitive area check but was going to implement a floodfill function but never got around to it

What I would like to know is what else is needed to be a blacklist?