SRL Archive - Test corner

FindSymbol


nielsie95

2009-05-05 16:30:09

Hey,

I was thinking of a new way to find symbols on the MiniMap. First I was thinking of using the relation between colors. This worked pretty good and fast, but the main problem was that a lot of symbols have some of the same colors and thus relations. So this didn't work out.

My second idea was using bitmaps. I came up with the plan to search for slices of the symbol. This was working out pretty good. I didn't feel like making a bitmap for every symbol, so I tried to automate the process (with help of the RS WorldMap). Of course, it didn't make as good bitmaps as when I did it myself, but it was good enough. This worked pretty good and accurate, but slow.

Sooo I mixed both and I think the result's pretty good. It gets the colors + relations from the bitmap, tries to find the new colors, stores those colors and then tries to search for slices of the symbol in a small area around the place found with colors.

It's not a lot faster than SRL's FindSymbol, but it does find the symbol more easily. The first time it finds the symbol is the slowest, because it has to look for new colors. The time it takes depends on the symbol and the place.

Here's an example of the BankSymbol at the Grand Exchange in world 1 (in other words: crowded):


Searching for Bank symbol.
Getting SymbolColors from the MiniMap
time:47
626,74


program New;

{.include SRL/SRL.scar}

const
Symbol = 'Bank'; //Index or Name

{Available Names:

achievement diary | agility training | altar
amulet shop | anvil | apothecary
archery shop | axe shop | bank
brewery | candle shop | chainmail shop
clothes shop | combat training | cookery shop
cooking range | crafting shop | dairy churn
distractions/diversions | dungeon | estate agent
farming patch | farming shop | fired up beacon
fishing shop | fishing spot | food shop
fur trader | furnace | gem shop
general store | grand exchange | guide
hairdresser | helmet shop | herbalist
holiday event | hunter store | hunter training
jewellery shop | kebab seller | loom
mace shop | magic shop | makeover mage
mini obelisk | minigame | mining shop
mining site | pet shop | platebody shop
platelegs shop | plateskirt shop | poh portal
pottery wheel | pub / bar | quest start
rare trees | sandpit | sawmill
scimitar shop | shield shop | shortcut
silk trader | silver shop | slayer master
spice shop | spinning wheel | staff shop
summoning obelisk | summoning store | sword shop
tannery | transportation | vegetable store
water source | windmill | woodcutting stump
}

{.$DEFINE DeformedSymbolBackup}
{.$DEFINE ExtendedSymbolSliceSearch}

var
ig_SymbolColors: array[1..78] of array [0..2] of TIntegerArray;

function symbol_RelativeColors(Bitmap1, Bitmap2, x1, y1, x2, y2, TranspCol: Integer): Boolean;
var
x, y: Integer;
c: array [0..1] of array [0..1] of Integer;
r, g, b: array [0..1] of array [0..1] of Integer;
Info: array[0..2] of Variant;
begin
Result := False;

try
if ((x2 - x1) > 1) then
begin
Info[0] := (y2 - y1) - 1;
Info[1] := (x2 - x1) - 1;
Info[2] := False;
end
else if ((y2 - y1) > 1) then
begin
Info[0] := (x2 - x1) - 1;
Info[1] := (y2 - y1) - 1;
Info[2] := True;
end
else
Exit;

for y := 0 to Integer(Info[0]) do
begin
if Info[2] then
begin
c[0][0] := FastGetPixel(Bitmap1, y, 0);
c[1][0] := FastGetPixel(Bitmap2, y + x1, y1);
end
else
begin
c[0][0] := FastGetPixel(Bitmap1, 0, y);
c[1][0] := FastGetPixel(Bitmap2, x1, y + y1);
end;

for x := 1 to Integer(Info[1]) do
begin
if Info[2] then
begin
c[0][1] := FastGetPixel(Bitmap1, y, x);
c[1][1] := FastGetPixel(Bitmap2, y + x1, x + y1);
end
else
begin
c[0][1] := FastGetPixel(Bitmap1, x, y);
c[1][1] := FastGetPixel(Bitmap2, x + x1, y + y1);
end;

if (c[0][0] = TranspCol) or (c[0][1] = TranspCol) or
(c[1][0] = TranspCol) or (c[1][1] = TranspCol) or
((c[0][0] - c[0][1]) = (c[1][0] - c[1][1])) then
begin
c[0][0] := c[0][1];
c[1][0] := c[1][1];
Continue;
end;

ColorToRGB(c[0][0], r[0][0], g[0][0], b[0][0]);
ColorToRGB(c[0][1], r[0][1], g[0][1], b[0][1]);
ColorToRGB(c[1][0], r[1][0], g[1][0], b[1][0]);
ColorToRGB(c[1][1], r[1][1], g[1][1], b[1][1]);

if (((r[0][0] - r[1][0]) = (r[0][1] - r[1][1])) or (r[1][0] - r[0][0] + r[1][0] <= 2) or (r[1][0] - r[0][0] + r[1][0] >= 254) or (r[1][1] - r[0][1] + r[1][1] <= 2) or (r[1][1] - r[0][1] + r[1][1] >= 254)) and
(((g[0][0] - g[1][0]) = (g[0][1] - g[1][1])) or (g[1][0] - g[0][0] + g[1][0] <= 2) or (g[1][0] - g[0][0] + g[1][0] >= 254) or (g[1][1] - g[0][1] + g[1][1] <= 2) or (g[1][1] - g[0][1] + g[1][1] >= 254)) and
(((b[0][0] - b[1][0]) = (b[0][1] - b[1][1])) or (b[1][0] - b[0][0] + b[1][0] <= 2) or (b[1][0] - b[0][0] + b[1][0] >= 254) or (b[1][1] - b[0][1] + b[1][1] <= 2) or (b[1][1] - b[0][1] + b[1][1] >= 254)) then
begin
c[0][0] := c[0][1];
c[1][0] := c[1][1];
Continue;
end;
Exit;
end;
end;
Result := True;
finally
end;
end;

function symbol_FindSlice(
out p: TPoint;
bmp, xSlice, ySlice,
xs, ys, xe, ye,
TranspColor, Tolerance: Integer): Boolean;
var
b, Target, Width, Height,
i, c, x, y, w, h: Integer;
Box: TBox;
c1, c2: TCanvas;
t: TPointArray;
Cols: TIntegerArray;
Handle: HDC;

{$IFDEF ExtendedSymbolSliceSearch}
tpa: TPointArray;
{$ENDIF}
begin
Result := False;
try Handle := GetClientCanvas.Handle; except Exit; end;

{$IFNDEF SCAR320_UP}
FastReplaceColor(b, TranspColor, clBlack);
TranspColor := clBlack;
{$ENDIF}

Target := BitmapFromString(xe - xs, ye - ys, '');
CopyClientToBitmap(Target, xs, ys, xe, ye);

GetBitmapSize(bmp, Width, Height);
xSlice := Min(xSlice, Width);
ySlice := Min(ySlice, Height);
t := TPAFromBox(IntToBox(0, 0, xSlice - 1, ySlice - 1));
b := BitmapFromString(xSlice, ySlice, '');

try
SetTargetBitmap(Target);

c1 := GetBitmapCanvas(bmp);
c2 := GetBitmapCanvas(b);
w := Ceil(Width / xSlice);
h := Ceil(Height / ySlice);

for x := 0 to w do
for y := 0 to h do
begin
Box.x1 := (xSlice * x);
Box.x2 := (xSlice * x) + xSlice;
Box.y1 := (ySlice * y);
Box.y2 := (ySlice * y) + ySlice;
if (Box.x2 > Width) then
begin
Box.x1 := Width - xSlice;
Box.x2 := Width;
end;
if (Box.y2 > Height) then
begin
Box.y1 := Height - ySlice;
Box.y2 := Height;
end;

CopyCanvas(c1, c2, Box.x1, Box.y1, Box.x2, Box.y2, 0, 0, xSlice, ySlice);

SetTargetBitmap(b);
//WriteLn(FloatToStr(CountColor(TranspColor, 0, 0, xSlice - 1, ySlice - 1) * 100 / Length(t)));
//if (CountColor(TranspColor, 0, 0, xSlice - 1, ySlice - 1) > 4) then
if ((CountColor(TranspColor, 0, 0, xSlice - 1, ySlice - 1) * 100 / Length(t)) > 50) then
Continue;
SetLength(Cols, 0);
Cols := GetColors(t);
ClearSameIntegers(Cols);
c := Length(Cols);
for i := High(Cols) downto 0 do
if (Cols[i] = TranspColor) then
Dec(c);
if (c < 2) then
Continue;

SetTargetBitmap(Target);
{$IFNDEF SCAR320_UP}
if FindBitmapToleranceIn(b, p.x, p.y, 0, 0, xe - xs, ye - ys, Tolerance) then
if symbol_RelativeColors(b, Target, p.x, p.y, p.x + xSlice, p.y + ySlice, TranspColor) then
begin
p.x := p.x + xs;
p.y := p.y + ys;
Result := True;
Exit;
end;
{$ELSE}
(*{$IFDEF ExtendedSymbolSliceSearch}
if FindTransparentBitmapsTolerance(b, tpa, TranspColor, 0, 0, xe - xs, ye - ys, Tolerance) then
for i := High(tpa) downto 0 do
if symbol_RelativeColors(b, Target, tpa[i].x, tpa[i].y, tpa[i].x + xSlice, tpa[i].y + ySlice, TranspColor) then
begin
p.x := tpa[i].x + xs;
p.y := tpa[i].y + ys;
Result := True;
Exit;
end;
{$ELSE}*)
if FindTransparentBitmapTolerance(b, p.x, p.y, TranspColor, 0, 0, xe - xs, ye - ys, Tolerance) then
if symbol_RelativeColors(b, Target, p.x, p.y, p.x + xSlice, p.y + ySlice, TranspColor) then
begin
p.x := p.x + xs;
p.y := p.y + ys;
Result := True;
Exit;
end;
//{$ENDIF}
{$ENDIF}
end;
finally
SetTargetDC(Handle);
FreeBitmap(b);
FreeBitmap(Target);
end;
end;

function SymbolNameToIndex(Symbol: string): Integer;
begin
Result := -1;

case LowerCase(Symbol) of
'achievement diary': Result := 1;
'agility training': Result := 2;
'altar': Result := 3;
'amulet shop': Result := 4;
'anvil': Result := 5;
'apothecary': Result := 6;
'archery shop': Result := 7;
'axe shop': Result := 8;
'bank': Result := 9;
'brewery': Result := 10;
'candle shop': Result := 11;
'chainmail shop': Result := 12;
'clothes shop': Result := 13;
'combat training': Result := 14;
'cookery shop': Result := 15;
'cooking range', 'range': Result := 16;
'crafting shop': Result := 17;
'dairy churn': Result := 18;
'distractions/diversions',
'distraction',
'diversion': Result := 19;
'dungeon': Result := 20;
'estate agent': Result := 21;
'farming patch', 'farm': Result := 22;
'farming shop': Result := 23;
'fired up beacon': Result := 24;
'fishing shop': Result := 25;
'fishing spot',
'fish', 'fishing': Result := 26;
'food shop': Result := 27;
'fur trader': Result := 28;
'furnace': Result := 29;
'gem shop': Result := 30;
'general store': Result := 31;
'grand exchange', 'ge': Result := 32;
'guide': Result := 33;
'hairdresser': Result := 34;
'helmet shop': Result := 35;
'herbalist': Result := 36;
'holiday event',
'holiday': Result := 37;
'hunter store': Result := 38;
'hunter training',
'hunter': Result := 39;
'jewellery shop': Result := 40;
'kebab seller', 'kebab': Result := 41;
'loom': Result := 42;
'mace shop': Result := 43;
'magic shop': Result := 44;
'makeover mage': Result := 45;
'mini obelisk': Result := 46;
'minigame': Result := 47;
'mining shop': Result := 48;
'mining site',
'mine', 'mining': Result := 49;
'pet shop': Result := 50;
'platebody shop': Result := 51;
'platelegs shop': Result := 52;
'plateskirt shop': Result := 53;
'poh portal': Result := 54;
'pottery wheel': Result := 55;
'pub / bar',
'pub', 'bar': Result := 56;
'quest start', 'quest': Result := 57;
'rare trees',
'tree', 'trees': Result := 58;
'sandpit': Result := 59;
'sawmill': Result := 60;
'scimitar shop': Result := 61;
'shield shop': Result := 62;
'shortcut': Result := 63;
'silk trader': Result := 64;
'silver shop': Result := 65;
'slayer master': Result := 66;
'spice shop': Result := 67;
'spinning wheel': Result := 68;
'staff shop': Result := 69;
'summoning obelisk': Result := 70;
'summoning store': Result := 71;
'sword shop': Result := 72;
'tannery': Result := 73;
'transportation',
'transport': Result := 74;
'vegetable store': Result := 75;
'water source', 'water': Result := 76;
'windmill': Result := 77;
'woodcutting stump': Result := 78;
else
WriteLn('Unknown Symbol ' + Symbol);
end;
end;

function SymbolIndexToName(Symbol: Integer): string;
var
Names: TStringArray;
begin
Result := '';

Names :=
['Achievement Diary', 'Agility Training', 'Altar', 'Amulet Shop', 'Anvil',
'Apothecary', 'Archery Shop', 'Axe Shop', 'Bank', 'Brewery', 'Candle Shop',
'Chainmail Shop', 'Clothes Shop', 'Combat Training', 'Cookery Shop',
'Cooking Range', 'Crafting Shop', 'Dairy Churn', 'Distractions/Diversions',
'Dungeon', 'Estate Agent', 'Farming Patch', 'Farming Shop', 'Fired Up Beacon',
'Fishing Shop', 'Fishing Spot', 'Food Shop', 'Fur Trader', 'Furnace', 'Gem Shop',
'General Store', 'Grand Exchange', 'Guide', 'Hairdresser', 'Helmet Shop',
'Herbalist', 'Holiday Event', 'Hunter Store', 'Hunter Training',
'Jewellery Shop', 'Kebab Seller', 'Loom', 'Mace Shop', 'Magic Shop',
'Makeover Mage', 'Mini Obelisk', 'Minigame', 'Mining Shop', 'Mining Site',
'Pet Shop', 'Platebody Shop', 'Platelegs shop', 'Plateskirt Shop',
'POH Portal', 'Pottery Wheel', 'Pub / Bar', 'Quest Start', 'Rare Trees', 'Sandpit',
'Sawmill', 'Scimitar Shop', 'Shield Shop', 'Shortcut', 'Silk Trader', 'Silver Shop',
'Slayer Master', 'Spice Shop', 'Spinning Wheel', 'Staff Shop', 'Summoning Obelisk',
'Summoning Store', 'Sword Shop', 'Tannery', 'Transportation', 'Vegetable Store',
'Water Source', 'Windmill', 'Woodcutting Stump'];

if (InRange(Symbol - 1, Low(Names), High(Names))) then
Result := Names[Symbol - 1]
else
WriteLn('Unknown SymbolIndex ' + IntToStr(Symbol));
end;

function GetSymbolBitmap(Symbol: Variant; out bmp: Integer): Boolean;
begin
Result := True;

if (VarType(Symbol) = varString) then
Symbol := SymbolNameToIndex(Symbol);

case Integer(Symbol) of
1: bmp := BitmapFromString(11, 11, 'beNplkDEOgCAQBK/AxJ6X2NoZn8M77G2s70P+SdesbOAgm0u4nYUDs8c65XMOnVbLtQFAHa39XtEXAKWSQxYMXAJwUd1dLrNk6FKcKigdUyudwFu+Zsmo7LS3cM4/WGcQoFcoC0Yuha0Ar2v8EACd9QIxDHgw'); //Achievement Diary
2: bmp := BitmapFromString(9, 9, 'beNpjYPjPAEUMDIxANH/+fLgIXBAZIQsCFaMx0BTADUQ2GU0KiJAtRbML03lwu3CJQ9hwS9HFAS3QOLw='); //Agility Training
3: bmp := BitmapFromString(7, 8, 'beNr79/c/AwME/f3HicYGkhAEZ8+fPx/Cng8GQEZ7cxMm+vfvLyYCit979AAZYVWMXTsAFVp3Ug=='); //Altar
4: bmp := BitmapFromString(7, 9, 'beNqbP/8/AwMQrd0j+fcfJxBBuBARIDkfDCDizVFQEbgaiPjqWiY0EQh6fIUJbiZEF1AlXBCuEigItx2IICqrqsSBgnDFcEvhikHOAgDT4Ftu'); //Amulet Shop
5: bmp := BitmapFromString(9, 7, 'beNpjYCguKbK1s//PwAAkiUFA9UDFmLrmz58P5KIhXOIQ7UASTRYijmwRslHICKQRAHqrPSQ='); //Anvil
6: bmp := BitmapFromString(7, 10, 'beNqbP/8/AwMQtZWnlWWFRflYQLgQNDP0a16CYzjfvPnz5yMLZprfAiI0QYg4XBAiAlcMEWmb9OTw2YdwQaDJQDayCFwQWS9QBIiAJsDVQAThdsHVAEXmAwA4QGQd'); //Apothecary
7: bmp := BitmapFromString(9, 9, 'beNpjYPjPgIIiwsPT0zPbm5vmz5+PJgWRhSA08dm5DhMSbWzt7IEIU7whQgdoGrIUsjjEouX6sh7qvJjiIEuNeCGyaOIQBBQHyoYxMWJ1MEQWRQoAs09YFA=='); //Archery Shop
8: bmp := BitmapFromString(10, 10, 'beNpjYPjPgEC2dvZAhCwCR8UlRcHeXkDZ+fPnY0pFhIcDEVABpixQECIL1Dsh0Qar4fM7IoFSVqa66emZQNOQ3QCRaojQAZoDlAIqgMvCpYCWAs0HSgFJiAO2l4cDpbJCtOeDAVAL0HAIG6Ir3VoUwoMaBWMDpSKMeJGlEAgAyetyBg=='); //Axe Shop
9: bmp := BitmapFromString(7, 13, 'beNpjYPjPAEIbFzlDEIQLF/n6bTJcCi4CR9kBAhARIANCQhBc8P0FRSA5HwyAghAuhAQiuC1AEQjCFIerh7sKWRDuKjRBuIFwM4GCEAZcBOgkoIFAEu5skAgAy7CB+g=='); //Bank
10: bmp := BitmapFromString(9, 11, 'beNptjzEKgDAMRXuBShcFNxdxdxK8gKNj8QIOHsOD5Kj64EMIKDxK819IG7MnJahzvvYC99FzKoRtyqhzbWUFOckyNr+W/GsZq1KW0iGnASWrNqHP6K4hEZKhK/EJzzVHNu6l17UXltKh08zi1g65vUxnSUo='); //Brewery
11: bmp := BitmapFromString(7, 10, 'beNqbP/8/AwMEfVvHBGfDRSAITfD9z3AgOX/+fGRlEEFkxb/rJN5fUASS88EAIvjv398XN9du21gNFyFSEMgGIrgghAsXh6P5AL9xdO8='); //Candle Shop
12: bmp := BitmapFromString(11, 9, 'beNpjYPjPAEXp6ZlAZGtnD2HAxSEoIjy8vbkJIgVEEDaaLFwNMoksW1xShKwGzobYDmQHe3uV19aiyQJJiC0QLlwcqBIiBVcAREAT0MxH8wiyCUASUwGyGoQCABbYd2w='); //Chainmail Shop
13: bmp := BitmapFromString(11, 9, 'beNpjYPjPAEWGUx1Z/VgkPFSYm/WBbLg4BKk02AIFIWogDGQ1QFk4gstC2GiycAXIXIia+fPnA62GiECkgCIQEmILVgUQcbhL4AogapClkBXADcFUAERAP8LNhyoAAIs2ZJc='); //Clothes Shop
14: bmp := BitmapFromString(8, 9, 'beNqbPz/dWhQT/WdgAJLz58+HkECQFaINYcAVANlAMjtAAEjC1UMEJyTabNtYvX/HLLg4RM38jkigIBDBTQYKNkTo9FSFrFzYCETtzU1w8aoqcZA5kzOB4kASbi9ECqgFaBrcHLgUxA3zASsUW3Y='); //Combat Training
15: bmp := BitmapFromString(9, 10, 'beNqbP/8/AwMQtTc3QRhAVF5bi8wAkvPnz4ezi0uKgAwgCRREJiFS6emZEFkgA8JGkwIiIGM+GEAMhHAhUhCj4LYjS0GcgcyGcCck2gBRQ4QOnAtkQ5RB2Fkh2shSEDZEHF0KAHsbc/4='); //Cookery Shop
16: bmp := BitmapFromString(11, 6, 'beNpjYPjPwJBuLQpBi0JlgSRQBBlhilio8nmo88IRXCMQRRiBRIhRMB8J4FKAbCmaAohGqCwA0zM5pg=='); //Cooking Range
17: bmp := BitmapFromString(8, 7, 'beNpjYPjPgIIUxASACE0QIm5lqltcUoQmmJ6eCRScP38+XFBLTxkoOB8GMAWRtQNJNEGgSoggigMAPHo7Zw=='); //Crafting Shop
18: bmp := BitmapFromString(7, 12, 'beNqbP/8/AwMENUdJzp+P4GIVjDDiTbcWBQpmBwgAEVDEQpXPQ50XIg4RBCKgCJo4UEtEeDhELxyV19YGe3uBxNMzIQgiAtQIJJER0ASgUUBxCAKyIRYB9cLZEFfhMhPoVDQz5wMAhpZNKw=='); //Dairy Churn
19: bmp := BitmapFromString(11, 11, 'beNpjYPjPgIIeX2FCE0FGX3/mAhUASUypP7/OA8XhCoBodS0Tml6gGqAsRAFQFkjOnz8fLgvRC1EDkYUgiKvwI7gJcFuAJsBdgmwLxJ0QXXA3wBVg9QVcFoKAXLiC+TCAGSBABShSAOBExfI='); //Distractions/Diversions
20: bmp := BitmapFromString(5, 11, 'beNqbP//rwkXfYvyB6KumGoQNJTXVtrCxQ7ggKTAXwsDJRVL5ISvrPwMDUATCnj9/PpALQfPBACILsRQiDtcLl4XqBQAkhE4/'); //Dungeon
21: bmp := BitmapFromString(7, 7, 'beNpjYPjPwFCWFQYko3wsgCQcAblABJSCi0O4cARRoKWnjImAitvK0yCouKQIbgKQDZHKS3CEsOGCEBEQGwBm5TFC'); //Estate Agent
22: bmp := BitmapFromString(8, 9, 'beNpjYPjPgIIijHiBCE0QIj5//nwLVT5McQ91XjRxiOB8MMAjWFxSlJ6eCTEZTRCCkLXDBSPCw9HEgSLB3l4o1gEAeBhOJQ=='); //Farming Patch
23: bmp := BitmapFromString(9, 9, 'beNqbP/8/A0OEES8QpVuLtlixLwqV3RuvDERwcQUxASCyUOXzUAdxIbJALkQEogWia7k+iAQKAqXgBgIRUByiACgFREBxuF1w64DqIeajiUNcglVq/vz5ECmIbHOUJJoUXCPQOogUUHw+AKRJSO0='); //Farming Shop
24: bmp := BitmapFromString(11, 8, 'beNpjYPzPAASMCmICQARkALkQkfbmJiCCiABJp9J0IAIyIAgii6wAGVmZ6kaEhwMRRAGyeogIRBauBpmLrAsuAjcQzoYYBecCSQiCs5HVAxHEVbgQAwD14EJB'); //Fired Up Beacon
25: bmp := BitmapFromString(10, 9, 'beNqbt+E/AwMaWhfFCEG4pObPnw9kQ0hMKUxZNClkWUwphnkbIGysUhAEkWqI0EF2AFwWyAZKQRCyM+AmQxRgMRkA0LZseQ=='); //Fishing Shop
26: bmp := BitmapFromString(10, 6, 'beNpzuvmfgQGIlA/9ByL+/L8QLgRBuBBxOEKThZPICiBaBJ1uQhBcCi4CREBlyFwGiVNANH/+fCAJkQUiiCBEHAJAugB+Vkws'); //Fishing Spot
27: bmp := BitmapFromString(10, 10, 'beNqbP/8/AwMQbdq0MStEG4jyEhyBbIggBAFFgOLzOyIhaEKiDVwNULynKgQivm1yJhABGUARiAIgCRfftrEargBk2vz5QAVAoxCyYAUQKSAAGo6QhSGILMRVQFuQpeDGQvyCYjWqLMTNQMNn5zpAXA7hAsUhspgowogXpB0A7WWJZA=='); //Food Shop
28: bmp := BitmapFromString(9, 10, 'beNpjYPjPAEXfYvybwSRcpMWKHc4AIqDs/PnzgdxmmAhEFiIOBM1gNlw9XFczTA2aac1IepEthduFLA6RgluBJo5sJqY43G3NGOJwL4AQAABgUz0='); //Fur Trader
29: bmp := BitmapFromString(9, 11, 'beNqzszfUktZSEYWQEIaFkRqE8Z+BgTxka2ePiSDioVaamAiiAMj4HsX9u04CgoBsZCmgyLuVan//cQJJIJtIKTwG4nIGdgQAbdpcHw=='); //Furnace
30: bmp := BitmapFromString(10, 10, 'beNpjYPjPAEUfsrIgCC4CRz9unYXLftVUQ5OCIIgUBCEbCJGFS21hY29GtQ4i/i3GHygOkZ0/fz5cFigOREAGUApNFq4xjIkRWS/Q8DfiHHDrgLIQtGnTRiCCuA2oAGIgRAGyFAQ1w9B8MAAJAgDG4oA+'); //Gem Shop
31: bmp := BitmapFromString(11, 12, 'beNpjYPjPgEDzYWDTpo3I4kDUVp6WFaIdYcTroQ5CQHZegiNcGVA23VrUQpVPQUwAjoAKgAiioL25CagXWRaIIObATQAqgJgQxsQIVwBEEAVAoxaFyrZYsQMtAioAIiADwgU6GKgg1Epzf6UZEO2NVwaqBKLmKEmgAiAqr60FOgAojqYAIgtEQGdMmDYbKIJLAcQjQGVYFcDdACQbInQwFRSXFCEHcllWGNAooPOAGoHOhsoCAL+9gUs=');//General Store
32: bmp := BitmapFromString(11, 12, 'beNpjYPjPgBMpiAkgc1fXMn1bx/T3H+e/f3+BDCAXU4uHOi8cYcrS2oRQK01khGYCUOTFzbWvjlQA0dPd04HsCYk2cBOQZYHiaAYCRbZNzoTI7q80AyI4F4ggRgHVAwUhskAuEDVE6ADDEIiAJiA7AyIIQQgXAgDChZrU'); //Grand Exchange
33: bmp := BitmapFromString(9, 12, 'beNpjYPjPAELTt19CRhBBuLhtdAcEwWXh4nAtWNnz589HE4Ew5oMBpkZkhGwdXD2yM4AiyO7EKo4shSaO7GusUsTqAgCWGrCh'); //Guide
34: bmp := BitmapFromString(9, 9, 'beNpjYPjPQA5iYGAEIlwi8+fPh3MhJEQErhiuAIKAXGRDILLzwQCuBqILWRCiCyKC7BJMERQEANAHSdo='); //Hairdresser
35: bmp := BitmapFromString(9, 9, 'beNpdji0KgEAUhPeGFmE32MWqgiBYNFgMJg2GPYMWr2D2MFb9YGQRYXh8zLw/Y25jxmmZ93PbVu893HctJjqcRVcSOWvFaKhjIvXgF2VeNQ3jGmQJgJ+mGT6igbWKqCGiom9ElalPQsQhGF+rwpOKYOA3ogh94fUf+sh+2w=='); //Helmet Shop
36: bmp := BitmapFromString(10, 9, 'beNqbP/8/AwMySpmsjyYCRF5RchApCMKUBSKguG+XKASxZAvDjWL1Y4EogMsCRebPnw9kABVo6SnDZYUncAA1QswBqoEogGgHigMZEEGI4RA2XDuEC9EIcRVEBKId2V64s4FciHa41HwAXTlNSA=='); //Herbalist
37: bmp := BitmapFromString(9, 10, 'beNpjYPjPwPD+Z/jHP4pABgQB2UARCANIzp8///0FEANCArlAcSACMiDq361Ug4jDtQBVAgWREUTvFjb2U1raEAQUgbOB4sgIKIXMhWiHmAknIQw8uvBINYNdAjccIQ4ARFhxmA=='); //Holiday Event
38: bmp := BitmapFromString(10, 11, 'beNpjYJg/f/6mTRv/MzAAUXtzE5ALYUNQqJUmUBDIAIoD2WVZYXBxiC4gAxPBDQGqAXKzQrQh4lamum3laXDrgMrgUhAElN2/YxbcCjwmo2mEIIhTcZmMLIvHZLhREHfCFQO5EDbQKGQPQgT/AwCyxXiQ'); //Hunter Store
39: bmp := BitmapFromString(10, 12, 'beNpjYPjPAEJaespwxvz58yFsOAIKQsQhDPyyaNoxZSEmQMiI8PD5YADkQtgQZXAuGkCTxeQiG4iMgOIQBLQUq2x7cxPc5ZiyWD0FROnpmZjBBRSEI6ggAEuzdjk='); //Hunter Training
40: bmp := BitmapFromString(7, 9, 'beNqbP/8/AwMEfdVUg7PhIqe0tLewsSNEfuY+vsIERB//KH79NhkusnGR8/z584Hk2j2SQBGg7PntpvPBAKgGKA7RBReBIKAIUP2rIxVwESAbKLi6FqQYaA5cBGgasjlAXSAbAcM+XwE='); //Jewellery Shop
41: bmp := BitmapFromString(11, 10, 'beNpjYPjPgEBhTIxAhCyCKQtEwhM4gAhNdn5HJFw2ZbI+kJtuLQqXBbKBUkBxCPqqqdYMNhCiBkhCdEFMBspCFMDVABFQFsKG2DIh0QbIBpLby8MhCiBsrCTcFmRxCILonT9/PtydyLogUhCA7BcsUgAG0Wwc'); //Kebab Seller
42: bmp := BitmapFromString(9, 9, 'beNqbP/8/A0OUj0VegiMEAbnICChloco3f/58uIKyrDC4FFAcKAtkQ9QApYAkXBdEHEIiSyHrApJE6oJoRNMFF4dIARHEGRBHIotDtIB0AQDVpFjc'); //Loom
43: bmp := BitmapFromString(8, 8, 'beNpjYPjPgIKKS4qACFOwvLYWSKanZyKLwwUjwsPhgg0ROlkh2kCRYG+v+fPnwwXTrUUjjHjnwwCmIIp2VEG4YjTB/wC6fElX'); //Mace Shop
44: bmp := BitmapFromString(8, 10, 'beNqbP/8/AwMEfdVUg7OR0e86CYgUXAGcC5SaP38+XAGEASQhCMKGq0RGQBG44LuVahAEZH+P4n4jzgGRgotDBD9kZQFJIAJyIQjI3sLGDjT/REQ4kAGRhQgCXQVx6k4PGyAXiIAMoOB8AK4+Zz8='); //Magic Shop
45: bmp := BitmapFromString(7, 9, 'beNqbP/8/AwMQPd09fdvkzAmJNhAuRAQuCBGHiCALAhGQC1EPFIQwIIJYVUIQRA2ascgW4RJEc+d8AHkKXmQ='); //Makeover Mage
46: bmp := BitmapFromString(8, 12, 'beNorTf/PwABBVVXi2QECWSHacBEI8oqSu/foQZSPxfz585HFPdR5geIWqnzI4k6l6YfPPgQqVhATQBZvuNEKNBmoBU0cKNhTFQIkgRqRxYGWTki0AZLI6oGGAG0EIqD6vARHIEI2BMgFSgG1wJ0UYcQLlAIioCDQVRCjgH4EIohngeJAJwGNBdoOFIEgiDjQEC09ZScA8ddrSg==');//Mini Obelisk
47: bmp := BitmapFromString(11, 11, 'beNplkEsNgDAQRHsCL2ABATgADTW1JrjggKAGB/CSCZN+mskm3Xn7aVN6U6VzXZpMqWvfAIi99eRM3gA6hrGphcEVgEuMCLuqFSNX0laN7mku5Q6aQoYORGXKKdpTVd7BgF/hWhi7ElcD8Z/+QwAq6wMLspcC'); //Minigame
48: bmp := BitmapFromString(9, 9, 'beNpjYPjPwPDxjyIcAblYEVYF88EAWQFWXZiycC5EO5C9LooRTRwuhVUcrgtTHG4sUBZNHIQA2t5zjw=='); //Mining Shop
49: bmp := BitmapFromString(9, 9, 'beNqbP/8/AwMEzZ8/v725qby2Fi4CROnpmUBUXFIEFIcgIBtZCxAgKwBykbVPSLRpiNCBKIgID4eLz851AIlbi9ra2QNlg7290MQhJgO1QKSA4lkh2hFGvBBxoAhQCsgAmo8mDpcCmoMmDnUzAGtcYms='); //Mining Site
50: bmp := BitmapFromString(11, 11, 'beNpdj60KwmAUQL9HMJkFm8FstRsMImJaMogYHUwWLCafwPJhNK4Mm482Dxy9yMZh3J/DvfdLqUtfbtXqWu6EOOrwfFzg/br/g3Par0PodQUh58zAYzHfLmYQLVPqOAjEZV2PhoMQTKkjsIuAlF122UgcAsQNcbYpK9yC0DZnmEzH4hxaDMHnr2PRVwN1XuFMz+bgw2bp2XZDAJ+skH9f9wHNL6hB');//Pet Shop
51: bmp := BitmapFromString(11, 9, 'beNqFj0EKgDAMBPM+PXqoPyheq//JU3XrlBKCYJlDGKakNbttcF5tWxexl6J5eqj1kKRhiI2uKJhNhLtAho892909BTJ4tnwG+PSSFER+A6E/8jx/T5cPXF54xQ=='); //Platebody Shop
52: bmp := BitmapFromString(5, 9, 'beNpLz2xvboKj9HQs3OKSIiAqr60FcoFkRHj4/PnzgSIQWQgXIgtEEC6QBCKIGohiZC5EGbJsOgDR6z5J'); //Platelegs shop
53: bmp := BitmapFromString(7, 8, 'beNoL3fCfgQGITmUdgSAIF1kEiLaGbsAUBKL58+djFUQTgZhAkSAArFBlDQ=='); //Plateskirt Shop
54: bmp := BitmapFromString(11, 11, 'beNpjYPjPgEBZJlPC+eYBSWRBuBREFoIgXDSNQFQnfapd+QqQhCtDVgCUmhn6FYKAbLgCiCxQF1D8SPN3CAKyIebADYdoR1YAMQSuBo8J+N0wf/58/L6AKACSWMNhPhhAfAphw0NyPgz8BwAKXqNr'); //POH Portal
55: bmp := BitmapFromString(9, 8, 'beNqbP/8/A0O6tWhDhA4QTUi0mZ3rAEEQcQtVPiDyUOcNtdKEIIhshBGvgpgAMgIqszLVhUgBNaLJwnVBZIHmINsFZAPFgbZAZOEuAZJANtAlaLJABDRh/nyQ4yGycJPnQwAAwgs87A=='); //Pottery Wheel
56: bmp := BitmapFromString(9, 10, 'beNpjYPjPwPDv398/v87/uHUWiJ7MawWKQBBQHFnqxc21r45UQKTObzcFst+tVAOi/ZVmQDQ716EhQgdNCsiGSM2fPx8oS6oUUByPFFAjLgOBAMjGdB5QHOJ+IGOnhw1QZKKxxnwY+A8AdDOV9Q=='); //Pub / Bar
57: bmp := BitmapFromString(11, 11, 'beNpjYPjPgIJSax6jiSCjtklPgAqAJKbU9O2XgOJwBUAk6HQTTS9QDVAWogAoCyTnz58Pl4XohaiByEIQxFX4EdwEuC1AE+AuQbYF4k6ILrgb4Aqw+gIuC0FALlzBfBjADBCgAhQpAEUguM8='); //Quest Start
58: bmp := BitmapFromString(10, 11, 'beNpjYPjPAEUs2cLCEzhYWlmBCC4IRKx+LEApiDgc4ZedP38+QgpVVnI3A9AWXLJwBJTFajKyLEQB0DS4s5GtBiIg20KVD0hC1MwHA4izIWwPdV6ICLIUHEH0oglCkIKYAFA21EoTIQgA649Yaw=='); //Rare Trees
59: bmp := BitmapFromString(11, 8, 'beNqbP/8/AwMcbVzkDEHIgpiyr45UYKpBloUgZDVoetHUNEdJwhUgq4FwgbLZAQJoauAIKN4QoQNUAFGDiSCyQFsgCiAq0djzAfKJcxg='); //Sandpit
60: bmp := BitmapFromString(9, 9, 'beNoLEPjPwABBtnb2cBJNMCI8HILQFABFikuKIAgiC1EAFwdy4bJwoyDiEASRmj9/Ph5dEUa8QJQdINAcJYmMgCK4xCFS2GUBJF1QSg=='); //Sawmill
61: bmp := BitmapFromString(8, 7, 'beNpjYPjPgI4mTJt979EDrIK2dvZAtrpDIUQEIggktfSUIeIQESBqb24CCs6fPx8oXl5bC5QCsoO9vaxMdeeDQXFJUXp6ZkR4OMR8iCCQARSBq4GIgxQAACpAS0g='); //Scimitar Shop
62: bmp := BitmapFromString(7, 10, 'beNpjYLC1sw/29vrPwABBxSVF5bW1QEEgiggPb29uAopgFUxPzyQoCGTjFwTaCHEAxBag4Pz58+GCQC4EQQSBCKgdrgwuCERAo6AiAO+SUng='); //Shield Shop
63: bmp := BitmapFromString(11, 7, 'beNpr1v/PwABEzPuckBFEEII2bdqIJoushrlZH8KdDwboyoCyYAUQWXS7ILLNIDfAZRFqYLIQBWgIWRZTAZosMwC1Zkxu'); //Shortcut
64: bmp := BitmapFromString(9, 9, 'beNrjzf/PwLCYNx+IWhkDgQjCBiKIOEQQGc0HA7guNAQUhyA8srikMO2CWIdLHOIMNHHCzgAAszxVTg=='); //Silk Trader
65: bmp := BitmapFromString(8, 8, 'beNpdTtsJACAQarFqt/poDCft6kIQCUTOFxxwSllz1NbJKQWaEVsFmnQEbXlokixTka88onR4BLw/k78OLqQLT6c='); //Silver Shop
66: bmp := BitmapFromString(11, 12, 'beNpjYPjPAEW2dvbICC4Ol/r6bTIC/cyFK8MiC1YAV4NFFqYArgarFKYhUAZM8P3PcDQr0MSBDHQrwGYCxSEIizthImgOQPgUVQFEcP78+Shhhap3PhjgCmqoLACKP84i'); //Slayer Master
67: bmp := BitmapFromString(9, 9, 'beNpjYPjPAEXrohghCC4CF/8exf1tHROQRJaFiJ+ICEeTtbWzh4sjyxaXFAGlgCSaLFCkvLYWKFVVJQ5kQxBQBIKAgkCpiPBwIAMNAWUh1gFl4RoheuGOhMhCFEDFAfiwX3k='); //Spice Shop
68: bmp := BitmapFromString(11, 11, 'beNplkDEOQEAURPcCEo1TUGkpHEGh2FYlIe7gCHrFHpVJHkNiM9lMZub/WUI4w4t9bI+1E74i2GIlQFJKSgp2p6ZA14GQdGbpcyxv+PJYZ+Ke8o2iJQqoQiDpjCE9PUcxufNQssFd6P8bV6CFKRa6Bc6IZyWqxR/uv8EbnLzdCzIvh1g='); //Spinning Wheel
69: bmp := BitmapFromString(7, 9, 'beNpjYPjPgIJm5zo0ROigiSwKlZ0/fz6mMmTBnR42EBG4IFBXc5QksghcF7JGTKMgIi1W7MiCcBGEIADoG0ru'); //Staff Shop
70: bmp := BitmapFromString(11, 12, 'beNp9kDEKg0AURPc2OUWMeI0cYElpYaxsRUgjFqZIsaVH8ACpbTxASCT3iE8GPltI4POZ/TM7f3ad+7n9OqT58dz8YZ/TRyCec0V1H2cEsG3/MIrj9TaUVQV+LW96CEEOdO8vUFwE0BFIDCWWwg1K5hQCKEwsVVZ4ZHX3lQxsAoUBm8+WJDmZgDlLwcpMx1+xLaexErBIr7AAeiMYShtjQfwVYgW2+Qogya8A');//Summoning Obelisk
71: bmp := BitmapFromString(11, 11, 'beNoTE8hLcJzfEQlE/xkYsCKggj+/zgMRUM2mTRuxKvj6bTJcDaay+fPnI6vZtrEaTQ1EAUQWrqanKgRTzYubayEKgLJAVJYVhqwGogCoF4ggaoAWIZsDMQSiAKIG08FY1WD1EbIazJCBqIEjBQBB7L1S'); //Summoning Store
72: bmp := BitmapFromString(9, 9, 'beNpjYPjPgAXde/Rg06aNaIITps2GiKenZ+ISnz9/Ppo4UATIgEipOxSiiUeEh88HA6AUEGGKQ4yCa4SYAxdvb24qr62F6AVykW0HikPcCZeFIgAn3G+P'); //Sword Shop
73: bmp := BitmapFromString(11, 9, 'beNpjYPjPAEUNEToe6rwRRiAEZMPFISgrRBsoCFEDYSCrSbcWBSqAq4EgCBcomx0gAJGFKIPLQsQhaoCM+fPnA60GCsJlgSIQcYgtaAqApkGk4AqACKgAbgXEBDSPwE2AGIKpAIiAfoQ4dT4YgAQBVtRjzg=='); //Tannery
74: bmp := BitmapFromString(13, 11, 'beNpjYPjPgAXdSZeGIKyyyMqsY/wIqoQoQ1YJNx8NQZTBVSKL4EIkKdPSU8ZEcDVANi6Hwa2Aq4F4bT4qgFuBP0wgyiBqgLrwKENRAwCSxZtO'); //Transportation
75: bmp := BitmapFromString(9, 10, 'beNpjYPjPgIKW68sCEZogXHw+GEBEGm60Su5mACKguPAEDiBKfxgAkYKIQxBECiLrfMYKTQpOYkUQjWi6kM1Eswsu5dslCnchXDHEImT3w8WBVoDEAVRGVWE='); //Vegetable Store
76: bmp := BitmapFromString(6, 10, 'beNqbP/8/AwMEpdY8BiJkrmXq1/lgABEBciEiyAqwigARnHv47EMgKeh0E6gMKALkwkWACKIYUwTOBSKgUXA2yBwA9RJYFA=='); //Water Source
77: bmp := BitmapFromString(11, 11, 'beNpjYPjPgEASHip//3ECSWRBZASUhaD58+djVQA3AZcCrCbAdUGk0BhwLlwQgtAE8ZsAtGU+DCC7AQ4o9wUBEwCrv55r'); //Windmill
78: bmp := BitmapFromString(9, 10, 'beNpLDo7yscCDeqpCgOS2yZkQBBeBMOZ3RBIjBWTTSApIYpUCov8MDECEJqUgJgAUzE4OLsgMKc2OBDKyEn2A7PKCeCDKBgDZl3R9'); //Woodcutting Stump
else
Result := False;
end;
end;

function MyFindSymbols(Symbol: Variant): TPointArray;
var
cts, b, i, ii, l, ll, Index, w, h, cR, cG, cB: Integer;
t, tp: TPoint;
p, tpa: TPointArray;
apa: T2DPointArray;
c, cBlackList: TIntegerArray;
Handle: HDC;
{$IFDEF DeformedSymbolBackup}
Acc: Extended;
{$ENDIF}
begin
SetLength(Result, 0);
{$IFDEF UseHandleNeeded}igHandleNeeded;{$ENDIF}

try
if (not LoggedIn) then
Exit;
try Handle := GetClientCanvas.Handle; except WriteLn('No handle!'); Exit; end;
cts := GetColorToleranceSpeed;

if (VarType(Symbol) = varString) then
Symbol := SymbolNameToIndex(Symbol);
if (VarType(Symbol) <> varInteger) then
Exit;

if (not GetSymbolBitmap(Symbol, b)) then
Exit;

ColorToleranceSpeed(1);
GetBitmapSize(b, w, h);
SetLength(p, 0);
SetLength(tpa, 0);
Index := Integer(Symbol);
WriteLn('Searching for '+SymbolIndexToName(Index)+' symbol.');

if (Length(ig_SymbolColors[Index][0]) = 0) then
begin
SetTargetBitmap(b);
tpa := TPAFromBox(IntToBox(0, 0, w - 1, h - 1));
c := GetColors(tpa);
SetTargetDC(Handle);
ClearSameIntegers(c);

cBlackList := [12632256, 10461087];
SetLength(ig_SymbolColors[Index][0], Length(c));
l := 0;
SetLength(ig_SymbolColors[Index][2], Length(c) * Length(c));
ll := 0;

for i := High(c) downto 0 do
begin
if (c[i] = clRed) or (c[i] = clBlack) then
Continue;
if InIntArray(cBlackList, c[i]) then
Continue;

//SetLength(ig_SymbolColors[Index][0], l + 1);
ig_SymbolColors[Index][0][l] := c[i];
Inc(l);

for ii := i - 1 downto 0 do
if (c[i] <> c[ii]) and (c[ii] <> clRed) then
if (not InIntArray(ig_SymbolColors[Index][2], iAbs(c[i] - c[ii]))) then
begin
//SetLength(ig_SymbolColors[Index][2], ll + 1);
ig_SymbolColors[Index][2][ll] := iAbs(c[i] - c[ii]);
Inc(ll);
end;
end;
SetLength(ig_SymbolColors[Index][0], l);
SetLength(ig_SymbolColors[Index][2], ll);
end;

//WriteLn(IntToStr(Length(ig_SymbolColors[Index][1])) +' - '+IntToStr(Length(ig_SymbolColors[Index][0]))+' - '+IntToStr(Length(ig_SymbolColors[Index][2])));

if (Length(ig_SymbolColors[Index][1]) < Round(Length(ig_SymbolColors[Index][0]) * 0.5)) or
(Length(ig_SymbolColors[Index][1]) = 0) then
begin
WriteLn('Getting colors from minimap.');
SetLength(p, 0);
for i := High(ig_SymbolColors[Index][0]) downto 0 do
if FindColorsTolerance(tpa, ig_SymbolColors[Index][0][i], MMX1, MMY1, MMX2, MMY2, 50) then
begin
FilterPointsPie(tpa, 0, 360, 0, 75, MMCX, MMCY);
p := CombineTPA(p, tpa);
end;

c := GetColors(p);
ClearSameIntegers(c);
cBlackList := [65536, 16711422, 16777215, 15527148, 14869218, 12961221,
13816530, 195836, 1179390, 60909, 52428, 56797, 52428];

SetLength(ig_SymbolColors[Index][1], Length(c));
l := 0;

for i := High(c) downto 0 do
begin
if InIntArray(cBlackList, c[i]) then
Continue;
if InIntArray(ig_SymbolColors[Index][1], c[i]) then
Continue;
ColorToRGB(c[i], cR, cG, cB);
if (cR <= 1) or (cR >= 254) or (cG <= 1) or (cG >= 254) or (cB <= 1) or (cB >= 254) then
begin
ig_SymbolColors[Index][1][l] := c[i];
Inc(l);
Continue;
end;
for ii := i - 1 downto 0 do
begin
if (not InIntArray(ig_SymbolColors[Index][2], iAbs(c[i] - c[ii]))) then
Continue;

ig_SymbolColors[Index][1][l] := c[i];
Inc(l);
Break;
end;
end;
SetLength(ig_SymbolColors[Index][1], l);
end;

SetLength(p, 0);
for i := 0 to High(ig_SymbolColors[Index][1]) do
if FindColorsTolerance(tpa, ig_SymbolColors[Index][1][i], MMX1, MMY1, MMX2, MMY2, 0) then
begin
FilterPointsPie(tpa, 0, 360, 0, 75, MMCX, MMCY);
if Length(tpa) < 100 then
p := CombineTPA(p, tpa)
else
WriteLn('Disposing SymbolColor: '+IntToStr(ig_SymbolColors[Index][1][i]));
end;

//apa := SplitTPAEx(p, 6, 6);
apa := TPAtoATPAEx(p, 14, 14);
SetLength(p, 0);

for i := 0 to High(apa) do
begin
if (Length(apa[i]) < 5) then
Continue;
tp := MiddleTPA(apa[i]);
tp.x := Max(10, tp.x);
tp.y := Max(10, tp.y);
if (not FindColorTolerance(t.x, t.y, 12632256, tp.x - 10, tp.y - 10, tp.x + 10, tp.y + 10, 60)) then
Continue;

if (not symbol_FindSlice(t, b, Min(3, w), Min(3, h), tp.x - 10, tp.y - 10, tp.x + 10, tp.y + 10, clRed, 50)) then
if (not symbol_FindSlice(t, b, Max(5, Min(w - 2, 7)), 2, tp.x - 10, tp.y - 10, tp.x + 10, tp.y + 10, clRed, 50)) then
if (not symbol_FindSlice(t, b, 2, Max(5, Min(h - 2, 7)), tp.x - 10, tp.y - 10, tp.x + 10, tp.y + 10, clRed, 50)) then
begin
{$IFDEF DeformedSymbolBackup}
Acc := 0.0;
if (Length(apa[i]) > 25) then
begin
FastReplaceColor(b, clRed, clBlack);
FindDeformedBitmapToleranceIn(b, t.x, t.y, tp.x - 10, tp.y - 10, tp.x + 10, tp.y + 10, 50, 0, True, Acc);
WriteLn('Found possible Symbol with accuracy: '+FloatToStr(Acc)+' - '+IntToStr(Length(apa[i])));
end;
if (Acc < 0.7) then
{$ENDIF}
Continue;
end;
SetLength(Result, Length(Result) + 1);
if (Distance(tp.x, tp.y, t.x, t.y) < 8) then
Result[High(Result)] := tp
else
Result[High(Result)] := t;
end;
finally
//RAaSTPAEx(Result, 12, 12);
for i := High(Result) downto 0 do
for ii := High(Result) downto 0 do
if (i <> ii) then
if (iAbs(Result[i].x - Result[ii].x) + iAbs(Result[i].y - Result[ii].y) < 15) then
begin
Result[i].x := (Result[i].x + Result[ii].x) shr 1;
Result[i].y := (Result[i].y + Result[ii].y) shr 1;
Swap(Result[ii], Result[High(Result)]);
SetLength(Result, Length(Result) - 1);
end;

FreeBitmap(b);
ColorToleranceSpeed(cts);
end;
end;

var
i, t: Integer;
p: TPointArray;
begin
SetupSRL;
for i := 1 to 2 do
begin
t := GetSystemTime;
p := MyFindSymbols(Symbol);
WriteLn('time:'+IntToStr(GetSystemTime - t));
for t := 0 to High(p) do
begin
WriteLn(IntToStr(p[t].x)+','+IntToStr(p[t].y));
MMouse(p[t].x, p[t].y, 0, 0);
Wait(1000);
end;
Wait(200);
end;
end.

You'll need the latest SCAR to run it.
Tell me what you think :)

-Oh, and someone needs to fix PointInTPA in WizzyPlugin..

_ChArMz

2009-05-06 10:22:18

function FindBankColor : Integer;
var
b, s : TPointArray;
c : TIntegerArray;
s2D : T2DPointArray;
sB : TBox;
i : Integer;
begin
Result := 0;

ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(14.29, 16.28); //<- the hue and sat mods may need edited

FindColorsTolerance(s, 592901, MMX1, MMY1, MMX2, MMY2, 3); //<- i need to get more colors

if Length(s) > 0 then
s2D := SplitTPA(s, 1)
else
Exit;

SetColorSpeed2Modifiers(0.14, 1.31);

for i := 0 to High(s2D) do
begin

//if ( not InRange(Length(s2D[i]), 6, 40) ) then //Needed?
//Continue;

sB := GetTPABounds(s2D[i]);

FindColorsTolerance(b, 2086386, sB.x1, sB.y1, sB.x2, sB.y2, 9);

if ( not InRange(Length(b), 5, 17) ) then
Continue;

c := GetColors(b);
ClearSameIntegers(c);

if Length(c) = 1 then
Result := c[0];

end;

WriteLn('BankColor = '+IntToStr(Result));
end;

i wrote this really fast, havent tested alot
it is really simple and works in just 0 ms :D

if i could write a fancy function that detected the black symbol circles, and halfs of them for when they are covered or more than one symbol was around it would be beast :D

EDIT: this prob wont work for every single symbol, cuz now that i read your post it seems you have already just tried colors and failed so whatever :P, thought i would script for runescape, cuz its been like a year

nielsie95

2009-05-06 10:43:28

I guess something like that could work if you'd do it for every single symbol, but I didn't feel like doing that. :p

I just made a general function which uses the bitmaps generated by another script.
Now, when there comes out a new symbol or when a symbol is updated, all you have to do is add one bitmap (instead of gathering colors from 15+ worlds).

EvilChicken!

2009-05-08 18:08:16

Hey, Niels, this looks interesting.

Few questions:
- How fast is it in average compared to SRL's current routines?
- How fast is it from second call and up?
- What are the pros&cons of using this over SRL's routines?
- Should SRL's routines be replaced with this?
- .. where is Sumilion?

nielsie95

2009-05-08 23:19:28

The speed all depends on the symbol and the place where you're searching. If you want to compare, please do :) The second call is almost always < 100ms. For symbols like bank, fish, quest, it is most of the time < 30ms. Pro's would be that it can be automaticly updated, is much more accurate and can find symbols in crowded area's. A con would be that it can be slower in some occasions.

Sumilion is having his exams in two weeks and he's not that much into SRL/RS any more.

EvilChicken!

2009-05-08 23:47:38

I took a look at both WizzyPlugin and your function.

Atleast from my point of view, the pro's of your function greatly exceed the con. If a couple extra milliseconds can lead to far better accuracy, (something which really is needed IMO) it definetly is worth it.
If someone were to replace SRL's current functions with these, wouldn't that require everyone to get 3.20c? I'm not sure if that's a con or not. Personally, I'd prefer that, as other new functions could be used in SRL aswell then.

And, I tried to compile WizzyPlugin after replacing PointInTPA, (the current version of it kinda made me smile :p) but I was missing the FastShareMem unit. What's really bothering me is that it sounds really familiar and I'm almost 100% positive I've seen it somewhere before.

If any other dev sees this, feel free to replace PointInTPA yourself in WizzyPlugin if you can, here's the fixed version:

function PointInTPA(const P: TPoint; const TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
if (TPA[i].x = P.x) and (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;


And finally; I'm really glad that one of you are still with us. :)
Hopefully Sum will return after his exams.

nielsie95

2009-05-09 00:47:38

That's exactly how I fixed it :)
FastShareMem should be in your Plugins folder.

Yes, FindTransparentBitmaps requires the latest SCAR. I guess it's not much of a con, as you said.
I hope Sumilion is coming back to, but I wouldn't count on it :( He still hops by sometimes though.

mastaraymond

2009-05-09 18:41:11

scar 15 = old FindSymbol
scar 20 = new FindSymbol

ifdefs.

Wizzup?

2009-05-09 18:55:37

From: nielsie95
Yes, FindTransparentBitmaps requires the latest SCAR. I guess it's not much of a con, as you said.


I think you mentioned you don't even need the Transparent part?

nielsie95

2009-05-09 19:12:15

No, you actually need it :p

EDIT: But you're right, it can be made compatible with scar 3.15 with a few adjustments.

nielsie95

2009-05-09 20:23:23

Moved from Developers to Members. I hope people do test it here :)

Harry

2009-05-09 20:28:21

Yay, looks nice nielsie. I will try to get around to testing it :3

Nava2

2009-05-10 07:27:06

Just use the {$DEFINE} that Fredders put into 3.20 +

Bobarkinator

2009-05-10 09:02:10

From: Nava2
Just use the {$DEFINE} that Fredders put into 3.20 +


{$DEFINE] has been in SCAR ever since I can remember…

nielsie95

2009-05-10 10:56:01

Freddy defined SCAR320_UP in SCAR versions 3.20+, which can be used to check if it's compatible.

Home

2009-05-10 15:23:19

Hie Niels, this stufflooks pretty nice :S I must have try this!
Thanks mate!

~Home

ShowerThoughts

2009-05-10 15:39:32


function PointInTPA(const P: TPoint; const TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
Result := (TPA[i].x = P.x) and (TPA[i].y = P.y);
if Result then
Exit;
end;
Shortened.(I am not sure if this does the same.)
This might skip the result checking since it has no begin, end.

nielsie95

2009-05-10 15:41:09

You're missing a begin, and it's not shortened either lol. But my way is faster ;)

ShowerThoughts

2009-05-10 15:41:57

Just tried to shorten EC!'s.

mastaraymond

2009-05-10 19:04:33

From: nielsie95
You're missing a begin, and it's not shortened either lol. But my way is faster ;)

Lies yours keeps calling high()

nielsie95

2009-05-10 20:47:03

So does Hermen's.

ShowerThoughts

2009-05-10 21:51:34

My high is faster.
It uses a special flash back time script.

nielsie95

2009-05-10 21:56:48

Oh noes, I should have known!

Anyway, still no testers?

ShowerThoughts

2009-05-10 22:02:34

From: Hermen
My high is faster.
It uses a special flash back time script.


From: nielsie95
Oh noes, I should have known!

Anyway, still no testers?


Note: if you flash back time doesn't goes faster ;).

Shuttleu

2009-05-10 22:08:55

From: nielsie95
Oh noes, I should have known!

Anyway, still no testers?


i shall test it for you and then we can see how accurate it is and fast

~shut

EDIT: Bank symbol color was 2218730
and i got
Successfully compiled (2503 ms)
SRL Compiled in 16 msec
time:0
time:0
Successfully executed

nielsie95

2009-05-11 00:32:23

I think something went wrong then =\
At the very least you should get "Searching for Bank symbol."


SRL Compiled in 15 msec
Searching for Bank symbol.
Getting SymbolColors from the MiniMap
time:47
628,95
Searching for Bank symbol.
time:0
626,95
Successfully executed

Maybe it thought you were not logged in or it failed to get the clientcanvas handle?
Could you please try it again?

Shuttleu

2009-05-11 00:40:48

ok sure

~shut

EDIT:
Successfully compiled (2480 ms)
SRL Compiled in 16 msec
Searching for Bank symbol.
Getting SymbolColors from the MiniMap
time:436
621,74
Searching for Bank symbol.
time:0
621,74
Successfully executed
Successfully compiled (2498 ms)
SRL Compiled in 16 msec
Searching for Water Source symbol.
Getting SymbolColors from the MiniMap
time:31
651,63
685,99
Searching for Water Source symbol.
time:16
651,63
685,99
Successfully executed

nielsie95

2009-05-11 00:52:54

Nice :)

I take it those values were correct? Times for the second searches were great too :)

Thank you very much for testing!

Shuttleu

2009-05-11 01:03:08

{Avalible Options

achievement diary | agility training | altar
amulet shop | anvil | apothecary
archery shop | axe shop | bank
brewery | candle shop | chainmail shop
clothes shop | combat training | cookery shop
cooking range | crafting shop | dairy churn
distractions/diversions | dungeon | estate agent
farming patch | farming shop | fired up beacon
fishing shop | fishing spot | food shop
fur trader | furnace | gem shop
general store | grand exchange | guide
hairdresser | helmet shop | herbalist
holiday event | hunter store | hunter training
jewellery shop | kebab seller | loom
mace shop | magic shop | makeover mage
mini obelisk | minigame | mining shop
mining site | pet shop | platebody shop
platelegs shop | plateskirt shop | poh portal
pottery wheel | pub / bar | quest start
rare trees | sandpit | sawmill
scimitar shop | shield shop | shortcut
silk trader | silver shop | slayer master
spice shop | spinning wheel | staff shop
summoning obelisk | summoning store | sword shop
tannery | transportation | vegetable store
water source | windmill | woodcutting stump
}
Could you add this to the top please?

~shut

EDIT:
Successfully compiled (2795 ms)
SRL Compiled in 16 msec
Searching for Cooking Range symbol.
Getting SymbolColors from the MiniMap
time:812
666,75
Searching for Cooking Range symbol.
time:31
666,75
Successfully executed
Successfully compiled (2609 ms)
SRL Compiled in 15 msec
Searching for Rare Trees symbol.
Getting SymbolColors from the MiniMap
time:858
682,76
Searching for Rare Trees symbol.
time:63
682,76
Successfully executed
Successfully compiled (2703 ms)
SRL Compiled in 15 msec
Searching for General Store symbol.
Getting SymbolColors from the MiniMap
Disposing SymbolColor: 2384482
time:2262
679,61
Searching for General Store symbol.
Disposing SymbolColor: 2384482
time:327
679,61
Successfully compiled (2608 ms)
SRL Compiled in 0 msec
Searching for Minigame symbol.
Getting SymbolColors from the MiniMap
time:94
669,101
Searching for Minigame symbol.
time:47
669,101
Successfully executed
Successfully compiled (2685 ms)
SRL Compiled in 15 msec
Searching for Dungeon symbol.
Getting SymbolColors from the MiniMap
time:94
676,50
Searching for Dungeon symbol.
time:47
676,49
Successfully executed
Successfully compiled (2547 ms)
SRL Compiled in 16 msec
Searching for Rare Trees symbol.
Getting SymbolColors from the MiniMap
time:843
687,70
642,81
Searching for Rare Trees symbol.
time:31
687,69
642,81
Successfully executed
Successfully compiled (2684 ms)
SRL Compiled in 0 msec
Searching for Fired Up Beacon symbol.
Getting SymbolColors from the MiniMap
time:936
687,63
Searching for Fired Up Beacon symbol.
time:125
687,63
Successfully executed

Successfully compiled (2719 ms)
SRL Compiled in 16 msec
Searching for Furnace symbol.
Getting SymbolColors from the MiniMap
time:796
681,84
Searching for Furnace symbol.
time:0
681,84
Successfully executed

nielsie95

2009-05-11 01:40:18

Wow, thanks :)
I'll add that list to the top :)

Did you test it in any crowded area's? What's your overall opinion? I'll see if I can speed up that first search a bit, because 2 seconds for the General Store is pretty slow :(

Shuttleu

2009-05-11 01:48:19

From: nielsie95
Wow, thanks :)
I'll add that list to the top :)

Did you test it in any crowded area's? What's your overall opinion? I'll see if I can speed up that first search a bit, because 2 seconds for the General Store is pretty slow :(


overall i think its pretty good
just one question
could you make it so it saves whatever information it gets to a file or something so it doesnt spend so long everytime you start up the script?

i will now test them in more crowded areas

~shut

EDIT:
coverd enough?
SRL Compiled in 16 msec
Searching for Bank symbol.
Getting SymbolColors from the MiniMap
time:515
633,121
Searching for Bank symbol.
time:16
633,121
Successfully executed

Successfully compiled (2657 ms)
SRL Compiled in 16 msec
Searching for Pub / Bar symbol.
Getting SymbolColors from the MiniMap
time:1155
591,85
Searching for Pub / Bar symbol.
time:63
591,85
Successfully executed

Cazax

2009-05-11 02:04:02

Searching for Farming Patch symbol.
Getting SymbolColors from the MiniMap
time:1312
613,26
Searching for Farming Patch symbol.
time:109
613,26

Searching for Fishing Spot symbol.
Getting SymbolColors from the MiniMap
time:47
617,113
608,151
Searching for Fishing Spot symbol.
Getting SymbolColors from the MiniMap
time:32
617,113
608,151

Getting SymbolColors from the MiniMap
time:312
639,106
Searching for Furnace symbol.
Getting SymbolColors from the MiniMap
time:235
639,106

Searching for General Store symbol.
Getting SymbolColors from the MiniMap
Disposing SymbolColor: 65536
time:2531
613,101
Searching for General Store symbol.
Disposing SymbolColor: 65536
time:468
613,101

Searching for Dungeon symbol.
Getting SymbolColors from the MiniMap
time:62
670,112
Searching for Dungeon symbol.
time:16
670,112

Nice function, don't look at the speed much because I was uninstalling something and it was lagging although some of them were pretty fast. I wasn't in a crowded area.

Shuttleu

2009-05-11 02:14:37

all of the ones i post now will be mostly covered symbols
SRL Compiled in 16 msec
Searching for Guide symbol.
Getting SymbolColors from the MiniMap
time:15
680,63
Searching for Guide symbol.
time:15
680,63
Successfully executed
;)
really nice function

~shut

EDIT: Only thing i can say b-e-a-utiful
SRL Compiled in 15 msec
Searching for Guide symbol.
Getting SymbolColors from the MiniMap
time:47
616,22
606,60
683,69
Searching for Guide symbol.
time:16
616,22
607,61
683,69
Successfully executed

EDIT: now i am truely amazed
Successfully compiled (2546 ms)
SRL Compiled in 0 msec
Searching for Quest Start symbol.
Getting SymbolColors from the MiniMap
Disposing SymbolColor: 14009240
time:16
676,75
Searching for Quest Start symbol.
Disposing SymbolColor: 14009240
time:15
676,75
Successfully executed

nielsie95

2009-05-11 18:43:11

Thank you both!

I tried to optimize it a bit, it should be (a lot) faster now. It should also be compatible with SCAR 3.15. I hope you guys can do some more testing?:D

Shuttleu: I can't make it save some values to a file. The part where it tries to get new colors is what's slowing it down, but those colors are not valid after a reload of the client.

marpis

2009-05-11 23:46:26

Line 148: [Error] (16904:1): Unknown identifier 'TransColor' in script

Scar 3.15b

EvilChicken!

2009-05-12 00:02:18

Marpis, you need to use SCAR 3.20c for this, I think.
Not sure if your error is related to that issue.

marpis

2009-05-12 00:24:02

From: EvilChicken!

Marpis, you need to use SCAR 3.20c for this, I think.
Not sure if your error is related to that issue.


From: nielsie95

t should also be compatible with SCAR 3.15.


:-\

nielsie95

2009-05-12 00:33:11

Oh, that should be TranspColor, sorry. I think it should compile now, even for 3.15.

marpis

2009-05-12 08:35:09

From: nielsie95
Oh, that should be TranspColor, sorry. I think it should compile now, even for 3.15.


Line 225: [Error] (16981:4): Unknown identifier 'FindTransparentBitmapTolerance' in script

BobboHobbo

2009-05-12 11:20:01

Wow, very amazing!

Image:
The one on the left was Try #2 and the right one is Try #1.

Results:
Try #1
Searching for Bank symbol.
Getting colors from minimap.
time:219
629,102
Searching for Bank symbol.
time:62
629,102


Try #2:
Searching for Bank symbol.
Getting colors from minimap.
time:203
622,102
Searching for Bank symbol.
time:31
622,102


Must say very impressive.

nielsie95

2009-05-12 16:58:12

Awesome! Thanks, Bobbo :)

marpis: Sorry, forgot about something, now it should work :p

Floor66

2009-05-12 17:19:39

Awshum! This should really be added to SRL.
Can't believe it finds crowded symbols aswell :O That's so kwl :D

EvilChicken!

2009-05-12 17:41:26

Wow, BH's pics look impressive :O

Do we need to wait for more proof, or should we just add this to SRL right away?

nielsie95

2009-05-12 17:55:53

Well, Shuttleu and Cazax had some timings of over 2 seconds, which is too slow for my liking. I made some improvements, but I'd like to see how fast it is now.

Shuttleu

2009-05-12 19:13:55

From: nielsie95
Well, Shuttleu and Cazax had some timings of over 2 seconds, which is too slow for my liking. I made some improvements, but I'd like to see how fast it is now.


my timings were for before you revamped it

i will retest them and see if they have sped up

~shut

EDIT:
Successfully compiled (2610 ms)
SRL Compiled in 32 msec
Searching for General Store symbol.
Getting colors from minimap.
Disposing SymbolColor: 1731406
time:780
682,69
Searching for General Store symbol.
Disposing SymbolColor: 1731406
time:203
681,69
Successfully executed

marpis

2009-05-12 20:04:07

From: nielsie95
Awesome! Thanks, Bobbo :)

marpis: Sorry, forgot about something, now it should work :p



yep, now it works with 3.15b too! :)
tested with dairy churn in lumby

nielsie95

2009-05-12 20:43:23

500ms for finding new colors is still a lot, but it's a lot faster than the old one :)

Thanks for testing again :)

Shuttleu

2009-05-12 20:47:10

add it! add it!

~shut

BobboHobbo

2009-05-13 10:55:24

From: Shuttleu
add it! add it!

~shut


I agree. Finding symbols when its crowded is something special. Plus some symbols are found super fast so… ADD it. xD.

Sumilion

2009-05-16 15:43:27

From: nielsie95
That's exactly how I fixed it :)
FastShareMem should be in your Plugins folder.

Yes, FindTransparentBitmaps requires the latest SCAR. I guess it's not much of a con, as you said.
I hope Sumilion is coming back to, but I wouldn't count on it :( He still hops by sometimes though.


boo

heavy stuff there, nice

n3ss3s

2009-05-16 16:01:03

Kind of irrelevant but the PointInTPA stuff caught my attention - you can do things with less or more style,


Function PointInArray(P: TPoint; TPA: TPointArray): Boolean;

Var
Bmp, C: Integer;
Box: TBox;
Begin
Box := GetTPABounds(TPA);
If Not PointInBox(P, Box) Then
Exit;
Bmp := BitmapFromString(Box.x2 - Box.x1, Box.y2 - Box.y1, '');
For C := 0 To High(TPA) Do
FastSetPixel(Bmp, TPA[c].x - Box.x1, TPA[c].y - Box.y1, 255);
If FastGetPixel(Bmp, P.x - Box.x1, P.y - Box.y1) = 255 Then
Result := True;
FreeBitmap(Bmp);
End;

nielsie95

2009-05-16 17:42:58

From: Sumilion
boo

heavy stuff there, nice


Ohai :)

n3ss3s, I prefer speed above style :p


program New;

Function PointInTPA1(P: TPoint; TPA: TPointArray): Boolean;
Var
Bmp, C: Integer;
Box: TBox;
Begin
Box := GetTPABounds(TPA);
If Not PointInBox(P, Box) Then
Exit;
Bmp := BitmapFromString(Box.x2 - Box.x1, Box.y2 - Box.y1, '');
For C := 0 To High(TPA) Do
FastSetPixel(Bmp, TPA[c].x - Box.x1, TPA[c].y - Box.y1, 255);
If FastGetPixel(Bmp, P.x - Box.x1, P.y - Box.y1) = 255 Then
Result := True;
FreeBitmap(Bmp);
End;

function PointInTPA2(p: TPoint; tpa: TPointArray): Boolean;
var
b: array of array of Boolean;
i, h: Integer;
Box: TBox;
begin
Result := False;
Box := GetTPABounds(TPA);
if (not PointInBox(P, Box)) Then
Exit;
SetLength(b, Box.x2 - Box.x1 + 1);
h := Box.y2 - Box.y1 + 1;
for i := High(b) downto 0 do
SetLength(b[i], h);

for i := High(tpa) downto 0 do
b[tpa[i].x][tpa[i].y] := True;

Result := b[p.x][p.y];
end;

function PointInTPA3(const P: TPoint; const TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := High(TPA) downto 0 do
if (TPA[i].x = P.x) and (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;

var
t: Integer;
p: TPointArray;
tp: TPoint;
begin
p := TPAFromBox(IntToBox(0, 0, 100, 100));
tp := p[High(p) div 2];

t := GetSystemTime;
WriteLn('PointInTPA1:'+BoolToStr(PointInTPA1(tp, p))+' - '+IntToStr(GetSystemTime - t));
t := GetSystemTime;
WriteLn('PointInTPA2:'+BoolToStr(PointInTPA2(tp, p))+' - '+IntToStr(GetSystemTime - t));
t := GetSystemTime;
WriteLn('PointInTPA3:'+BoolToStr(PointInTPA3(tp, p))+' - '+IntToStr(GetSystemTime - t));
end.

EvilChicken!

2009-05-17 01:56:26

I'm in a situation now where this function could be really useful for me.

Can it be committed now?
Or does it still require more testing/editing?

Wizzup?

2009-05-17 02:36:57

From: EvilChicken!
I'm in a situation now where this function could be really useful for me.

Can it be committed now?
Or does it still require more testing/editing?


You have to consider if you really want it in SRL. SRL's current FindSymbol isn't really sucky. You shouldn't change a winning team, imo. I'd prefer to see it either with compiler directives or in a misc file. Once it has had enough testing, it can be added. I fear this method can be broken more easily by JageX than Deformed bitmaps, though. (This is a great advantage of the current FindSymbol)

Shuttleu

2009-05-17 02:40:05

add it and call it FindSymbolSlice

~shut

BobboHobbo

2009-05-17 02:42:28

From: Wizzup?
You have to consider if you really want it in SRL. SRL's current FindSymbol isn't really sucky. You shouldn't change a winning team, imo. I'd prefer to see it either with compiler directives or in a misc file. Once it has had enough testing, it can be added. I fear this method can be broken more easily by JageX than Deformed bitmaps, though. (This is a great advantage of the current FindSymbol)


Make the old symbolfinding a backup?

Home

2009-05-17 02:51:19

From: BobboHobbo
Make the old symbolfinding a backup?


I agree with you mate (: Make it as backup and then there will be no losses (:


~Home

footballjds

2009-05-17 03:37:20

agreed!!!!!!!!!1

lordsaturn

2009-05-17 08:26:48

This needs to be tested some more then could be placed into SRL with the deformed bitmap finding as a backup.

marpis

2009-06-08 11:14:38

Im using this in my Faldor Yew cutter, and i got this error:
[Runtime Error] : Out Of Range in line 923 in script D:\SCAR 3.20\Scripts\Falador Yews.scar

and the line looks like this:
if (iAbs(Result.x - Result[ii].x) + iAbs(Result.y - Result[ii].y) < 15) then

Sir R. M8gic1an

2009-12-13 06:59:51

From: EvilChicken!


function PointInTPA(const P: TPoint; const TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
if (TPA[i].x = P.x) and (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;


And finally; I'm really glad that one of you are still with us. :)
Hopefully Sum will return after his exams.



function PointInTPA(const P: TPoint; const TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
if (TPA[i].x = P.x) then
if (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;

Wouldn't this be a couple of MS faster as it only checks the y coord if the x coord is the same, while yours would always check both?


Successfully compiled (224 ms)
EC took: 5289
RM took: 2356
Successfully executed
Successfully compiled (104 ms)
EC took: 2855
RM took: 1763
Successfully executed
Successfully compiled (102 ms)
EC took: 3292
RM took: 1841
Successfully executed



program New;

var
t, i: integer;
TPA: TPointArray;

function PointInTPA(P: TPoint; TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
if (TPA[i].x = P.x) and (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;

function PointInTPA2(P: TPoint; TPA: TPointArray): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(TPA) to High(TPA) do
if (TPA[i].x = P.x) then
if (TPA[i].y = P.y) then
begin
Result := True;
Exit;
end;
end;

begin
setLength(TPA, 1000);
for i:= 0 to 999 do
TPA[i] := Point(random(1000), random(1000));

t := GetSystemTime;
for i:= 0 to 100 do
PointInTPA(Point(1, 1), TPA);
writeln('EC took: '+IntToStr(GetSystemTime - t));

t := GetSystemTime;
for i:= 0 to 100 do
PointInTPA2(Point(1, 1), TPA);
writeln('RM took: '+IntToStr(GetSystemTime - t));


end.

~RM

nielsie95

2009-12-13 08:03:15

It wouldn't matter in Delphi as it supports short-circuit boolean evaluation.

Wizzup?

2009-12-13 08:24:52

From: nielsie95
It wouldn't matter in Delphi as it supports short-circuit boolean evaluation.


As far as I know every respectful language does.
http://en.wikipedia.org/wiki/Short-circuit_evaluation

marpis

2009-12-13 09:39:00

From: nielsie95
It wouldn't matter in Delphi as it supports short-circuit boolean evaluation.


Do you mean that in this situation
if Condition1 and Condition2 then

If Condition1 results false it doesn't even check Condition2?

Sir R. M8gic1an

2009-12-13 10:32:32

From: marpis
Do you mean that in this situation
if Condition1 and Condition2 then

If Condition1 results false it doesn't even check Condition2?


in scar you'd need to use and_then rather than and for short circuit evalution.

edit: actually scar doesn't accept and_then

~RM

Nava2

2009-12-13 12:03:04

From: Rasta Magician
in scar you'd need to use and_then rather than and for short circuit evalution.

edit: actually scar doesn't accept and_then

~RM


It should work the way it is, I assume thats why the scripting standards say to put the more CPU intensive things first.

Wait.. that seems backwards. :rolleyes:

Wizzup?

2009-12-13 12:29:51

From: marpis
Do you mean that in this situation
if Condition1 and Condition2 then

If Condition1 results false it doesn't even check Condition2?


I just linked a wikipedia link about it. :duh:

marpis

2009-12-13 12:41:30

From: Wizzup?
I just linked a wikipedia link about it. :duh:


I don't understand a word of that document :p
Not that good in computer english.

Naum

2009-12-13 12:59:38

From: Wizzup?
I just linked a wikipedia link about it. :duh:


From: marpis
I don't understand a word of that document :p
Not that good in computer english.


Simple.Wikipedia? :spot:
:p

Wizzup?

2009-12-13 17:37:48

From: marpis
I don't understand a word of that document :p
Not that good in computer english.


From: marpis
Do you mean that in this situation
if Condition1 and Condition2 then

If Condition1 results false it doesn't even check Condition2?


From: Wikipedia

Short-circuit evaluation or minimal evaluation denotes the semantics of some boolean operators in some programming languages in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression: when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true. In some programming languages (Lisp), the usual boolean operators are short-circuit. In others (Java, Ada), both short-circuit and standard boolean operators are available.


Hmmm… ;)

bbri06

2010-01-06 19:00:49

So, what is the status of this getting implemented? Is anything happening with a find symbol change? I think the current FindSymbol is rather terrible :(

Wizzup?

2010-07-15 06:47:01

Bump

Shuttleu

2010-07-15 08:19:25

but i'm sure my one is faster… ;) http://villavu.com/forum/showthread.php?t=57890

~shut

EDIT: 62 MS

Wizzup?

2010-07-15 11:45:13

Yes, but it breaks as soon as the colours are no longer constant. :)