marpis
2009-11-04 08:28:56
As we all know, ChooseOptionMultiEx is currently horribly slow and doesn't even find all capital letters (don't know why)
I solved the problem by making this function use Bitmap masks instead of Text TPA.
Pros
+ Very fast
+ All letters work (at least Withdraw-X was found immediately)
Cons
- Didn't make it search for any specific colour. In the old function you could only search cyan text etc, in this one the whole text has to be the same color.
Example: You can't use ['Attack Goblin'] Because Attack and Goblin and in different colours.
The searching priority is a bit different than current. This one first searches through all the options for Text[0], and then it searches through all the options for Text[1] etc etc, while the current one first checks if we have any of the texts[0..?] in the very first option, then it goes to the 2nd optionslot etc etc.
This wouldn't even break that many scripts because I think everyone just uses WaitOption and WaitOptionMulti.
EDIT: Espect a new version of this with colors support :)
EDIT2: So, here comes the monster, obey:
Works like a dream to me
I solved the problem by making this function use Bitmap masks instead of Text TPA.
Pros
+ Very fast
+ All letters work (at least Withdraw-X was found immediately)
Cons
- Didn't make it search for any specific colour. In the old function you could only search cyan text etc, in this one the whole text has to be the same color.
Example: You can't use ['Attack Goblin'] Because Attack and Goblin and in different colours.
The searching priority is a bit different than current. This one first searches through all the options for Text[0], and then it searches through all the options for Text[1] etc etc, while the current one first checks if we have any of the texts[0..?] in the very first option, then it goes to the 2nd optionslot etc etc.
This wouldn't even break that many scripts because I think everyone just uses WaitOption and WaitOptionMulti.
function ChooseOptionMultiEx2(Texts: TStringArray; Action: fnct_ActionOptions): Boolean;
var
B: TBox;
TPA: TPointArray;
aTPA: T2DPointArray;
I, H, TextMask, X, Y: Integer;
begin
Result := False;
GetClientDimensions(B.X2, B.Y2);
B.X1 := 0;
B.Y1 := 0;
FindColorsTolerance(TPA, 4016722, B.X1, B.Y1, B.X2, B.Y2, 0);
If Length(TPA) < 10 Then
Exit;
B.X2 := 0;
B.Y2 := 0;
aTPA := SplitTPAEx(TPA, 20, 20);
SortATPASize(aTPA, True);
B := GetTPABounds(aTPA[0]);
H := High(Texts);
for I := 0 to H do
begin
TextMask := CreateBitmapMaskFromText(Texts[I], UpChars);
Result := FindBitmapMaskTolerance(TextMask, X, Y, B.X1, B.Y1, B.X2, B.Y2, 0, 0);
FreeBitmap(TextMask);
if Result then
begin
case Action of
ClickLeft: MouseBox(B.X1 + 5, Y + 3, B.X2 - 5, Y + 8, 1);
Move: MouseBox(B.X1 + 5, Y + 3, B.X2 - 5, Y + 8, 3);
end;
Exit;
end;
end;
end;
EDIT: Espect a new version of this with colors support :)
EDIT2: So, here comes the monster, obey:
function ChooseOptionMultiEx2(Texts: TStringArray; TextType: String; Action: fnct_ActionOptions): Boolean;
var
B: TBox;
TPA: TPointArray;
aTPA: T2DPointArray;
Colors, GoodColors: TIntegerArray;
I, H, II, HH, III, J, TextMask, X, Y, XX, YY, CorrectWords: Integer;
TSA: TStringArray;
SmallBoxes: TBoxArray;
begin
Result := False;
GetClientDimensions(B.X2, B.Y2);
B.X1 := 0;
B.Y1 := 0;
FindColorsTolerance(TPA, 4016722, B.X1, B.Y1, B.X2, B.Y2, 0);
If Length(TPA) < 10 Then
Exit;
B.X2 := 0;
B.Y2 := 0;
aTPA := SplitTPAEx(TPA, 20, 20);
SortATPASize(aTPA, True);
B := GetTPABounds(aTPA[0]);
TPA := [];
Colors := [13034990, 4231423, 2070783, 65535, 16776960, 9812166];
TextType := LowerCase(TextType);
case TextType of
'action',
'player': GoodColors := [Colors[0], Colors[5]];
'item' : GoodColors := [Colors[1], Colors[2]];
'npc' : GoodColors := [Colors[3]];
'object': GoodColors := [Colors[4]];
else
GoodColors := Colors;
end;
SetLength(SmallBoxes, (B.Y2 - B.Y1)/15);
for I := 0 to High(SmallBoxes) do
begin
SmallBoxes[I].X1 := B.X1;
SmallBoxes[I].Y1 := B.Y1 + I * 16 - 3;
SmallBoxes[I].X2 := B.X2;
SmallBoxes[I].Y2 := B.Y1 + (I + 1) * 16 + 3;
end;
H := High(Texts);
HH := High(SmallBoxes);
for I := 0 to H do
begin
TSA := SRL_Explode(Texts[I], ' ');
for II := 0 to HH do
begin
//DrawBox(SmallBoxes[II]);
CorrectWords := 0;
for J := 0 to High(TSA) do
begin
TextMask := CreateBitmapMaskFromText(TSA[J], UpChars);
if FindBitmapMaskTolerance(TextMask, X, Y, SmallBoxes[II].X1, SmallBoxes[II].Y1, SmallBoxes[II].X2, SmallBoxes[II].Y2, 0, 0) then
begin
for III := 0 to High(GoodColors) do
begin
Result := FindColorTolerance(XX, YY, GoodColors[III], SmallBoxes[II].X1, SmallBoxes[II].Y1, SmallBoxes[II].X2, SmallBoxes[II].Y2, 3);
if Result then
begin
Inc(CorrectWords);
Break;
end;
end;
end else
Break;
end;
FreeBitmap(TextMask);
if (CorrectWords < Length(TSA)) then
Continue;
case Action of
ClickLeft: MouseBox(SmallBoxes[II].X1 + 5, SmallBoxes[II].Y1 + 3, SmallBoxes[II].X2 - 5, SmallBoxes[II].Y2 - 3, 1);
Move: MouseBox(SmallBoxes[II].X1, SmallBoxes[II].Y1, SmallBoxes[II].X2, SmallBoxes[II].Y2, 3);
end;
Exit;
end;
end;
end;
Works like a dream to me