Unit BestUOAntimacroUtil;

interface

type 
 TDigit = record
  Name : String;
  Coord : Array of TPoint;
 end;
 
 
var
 Digits : Array[0..9] of TDigit;
 
implementation

procedure InitDigits;
var
 i, k : Integer;
begin
{$Region '0'}
 {
  ***
  * *
  * *
  * *
  ***  
  }
 Digits[0].Name := '0';
 SetLength(Digits[0].Coord, 12);
 with Digits[0] do 
  begin 
  for i := 0 to 2 do
   begin
    Coord[i].X := i * 15;
    Coord[i].Y := 0;
   end;
  Coord[3].X := 0;
  Coord[3].Y := 15;
  Coord[4].X := 30;
  Coord[4].Y := 15;
  Coord[5].X := 0;
  Coord[5].Y := 30;
  Coord[6].X := 30;
  Coord[6].Y := 30;
  Coord[7].X := 0;
  Coord[7].Y := 45;
  Coord[8].X := 30;
  Coord[8].Y := 45;
  Coord[9].X := 0;
  Coord[9].Y := 60;
  Coord[10].X := 15;
  Coord[10].Y := 60;
  Coord[11].X := 30;
  Coord[11].Y := 60; 
 end;
{$EndRegion}

{$Region '1'}
 {
  *
  *
  *
  *
  *  
  }
 Digits[1].Name := '1';
 SetLength(Digits[1].Coord, 5);
 with Digits[1] do 
  begin
   for i := 0 to 4 do
    begin
	 Coord[i].X := 0;
	 Coord[i].Y := i * 15;
	end;
  end;
{$EndRegion}

{$Region '2'}
 {
  ***
    *
  ***
  *
  ***  
  }
 Digits[2].Name := '2';
 SetLength(Digits[2].Coord, 11);
 with Digits[2] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 30;
   Coord[3].Y := 15;
   k := 0;
   for i := 4 to 6 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[7].X := 0;
   Coord[7].Y := 45;
   k := 0;
   for i := 8 to 10 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '3'}
 {
  ***
    *
  ***
    *
  ***  
  }
 Digits[3].Name := '3';
 SetLength(Digits[3].Coord, 11);
 with Digits[3] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 30;
   Coord[3].Y := 15;
   k := 0;
   for i := 4 to 6 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[7].X := 30;
   Coord[7].Y := 45;
   k := 0;
   for i := 8 to 10 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '4'}
 {
  * *
  * *
  ***
    *
    *  
  }
 Digits[4].Name := '4';
 SetLength(Digits[4].Coord, 9);
 with Digits[4] do 
  begin
   Coord[0].X := 0;
   Coord[0].Y := 0;
   Coord[1].X := 30;
   Coord[1].Y := 0;
   Coord[2].X := 0;
   Coord[2].Y := 15;
   Coord[3].X := 30;
   Coord[3].Y := 15;
   k := 0;
   for i := 4 to 6 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[7].X := 30;
   Coord[7].Y := 45;
   Coord[8].X := 30;
   Coord[8].Y := 60;   
  end;
{$EndRegion}

{$Region '5'}
 {
  ***
  *
  ***
    *
  ***  
  }
 Digits[5].Name := '5';
 SetLength(Digits[5].Coord, 11);
 with Digits[5] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 0;
   Coord[3].Y := 15;
   k := 0;
   for i := 4 to 6 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[7].X := 30;
   Coord[7].Y := 45;
   k := 0;
   for i := 8 to 10 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '6'}
 {
  ***
  *
  ***
  * *
  ***  
  }
 Digits[6].Name := '6';
 SetLength(Digits[6].Coord, 12);
 with Digits[6] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 0;
   Coord[3].Y := 15;
   k := 0;
   for i := 4 to 6 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[7].X := 0;
   Coord[7].Y := 45;
   Coord[8].X := 30;
   Coord[8].Y := 45;
   k := 0;
   for i := 9 to 11 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '7'}
 {
  ***
    *
    *
    *
    *  
  }
 Digits[7].Name := '7';
 SetLength(Digits[7].Coord, 7);
 with Digits[7] do 
  begin
   for i := 0 to 1 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   k := 0
   for i := 2 to 6 do
    begin
	 Coord[i].X := 30;
	 Coord[i].Y := k * 15;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '8'}
 {
  ***
  * *
  ***
  * *
  ***  
  }
 Digits[8].Name := '8';
 SetLength(Digits[8].Coord, 13);
 with Digits[8] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 0;
   Coord[3].Y := 15;
   Coord[4].X := 30;
   Coord[4].Y := 15;
   k := 0;
   for i := 5 to 7 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;
   Coord[8].X := 0;
   Coord[8].Y := 45;
   Coord[9].X := 30;
   Coord[9].Y := 45;
   k := 0;
   for i := 10 to 12 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}

{$Region '9'}
 {
  ***
  * *
  ***
    *
  ***  
  }
 Digits[9].Name := '9';
 SetLength(Digits[9].Coord, 12);
 with Digits[9] do 
  begin
   for i := 0 to 2 do
    begin
	 Coord[i].X := i * 15;
	 Coord[i].Y := 0;
	end;
   Coord[3].X := 0;
   Coord[3].Y := 15;
   Coord[4].X := 30;
   Coord[4].Y := 15;
   k := 0;
   for i := 5 to 7 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 30;
	 Inc(k);
	end;   
   Coord[8].X := 30;
   Coord[8].Y := 45;
   k := 0;
   for i := 9 to 11 do
    begin	 
	 Coord[i].X := k * 15;
	 Coord[i].Y := 60;
	 Inc(k);
	end;
  end;
{$EndRegion}
end;

function ArrCompairor(APoints : Array of TPoint) : String;
var
 i, k : Integer;
 CurrMatch : Integer;
 ZPoint : TPoint;
begin 
 InitDigits;
 Result := 'Not Found...';
 if Length(APoints) > 0 then
  begin
   ZPoint.X := APoints[0].X;
   ZPoint.Y := APoints[0].Y;
   for i := 0 to Length(APoints)-1 do
    begin
     APoints[i].X := APoints[i].X - ZPoint.X;
	 APoints[i].Y := APoints[i].Y - ZPoint.Y;
    end;
  end;	
 for i := 0 to 9 do
  if Length(APoints) = Length(Digits[i].Coord) then
   begin
    CurrMatch := i;
    for k := 0 to Length(Digits[i].Coord)-1 do
	 begin
	  
      if (APoints[k].X <> Digits[i].Coord[k].X) then//or (APoints[k].Y <> Digits[i].Coord[k].Y) then
	   begin
	    CurrMatch := -1;
	    Continue;
	   end;	  
	  end;
	  if CurrMatch > -1 then break;
	end;
  if CurrMatch > -1 then
   Result := Digits[CurrMatch].Name;      
end;

procedure ParseAntimacroGump;
var
 AGumpInfo : TGumpInfo;
 i, k, l, m : Integer;
 APoints : Array of TPoint;
 s : String;
 Ends : Array[0..3] of Byte;
begin 
 //if GetGumpsCount > 0 then
  //for i := 0 to GetGumpsCount -1 do
   //if GetGumpSerial(i) = $9FDEE9 then
 if IsGump then GetGumpInfo(GetGumpsCount-1, AGumpInfo); 
 m := 0;
 for i := 0 to Length(AGumpInfo.GumpPics)-2 do
  begin
   k := AGumpInfo.GumpPics[i+1].X - AGumpInfo.GumpPics[i].X;
   if (k > 0) and (k <> 15) and (k <> 30) then
    begin	 
     Ends[m] := i;
	 Inc(m);
	end;
  end;
 SetLength(APoints, Ends[0]+1);
 for l := 0 to Ends[0] do
   begin
	APoints[l].X := AGumpInfo.GumpPics[l].X;
	APoints[l].Y := AGumpInfo.GumpPics[l].Y;
   end;
 s := ArrCompairor(APoints);
 SetLength(APoints, 0);
 m := 0;
 SetLength(APoints, Ends[1] - Ends[0]);
 for l := Ends[0]+1 to Ends[1] do
   begin
	APoints[m].X := AGumpInfo.GumpPics[l].X;
	APoints[m].Y := AGumpInfo.GumpPics[l].Y;
	Inc(m);
   end;
 s := s + ArrCompairor(APoints);
 SetLength(APoints, 0); 
 SetLength(APoints, (Length(AGumpInfo.GumpPics)-1 - Ends[1])); 
 m := 0;
 for l := Ends[1]+1 to Length(AGumpInfo.GumpPics)-1 do
   begin
	APoints[m].X := AGumpInfo.GumpPics[l].X;
	APoints[m].Y := AGumpInfo.GumpPics[l].Y;
	Inc(m);
   end;
 s := s + ArrCompairor(APoints);
 AddToSystemJournal(s); 
 NumGumpTextEntry(GetGumpsCount-1, AGumpInfo.TextEntries[0].return_value, s);
 CheckLag(60000); 
 Wait(RandomRange(2, 6)*1000); //задержка для меньшего палива :)
 NumGumpButton(GetGumpsCount-1, AGumpInfo.GumpButtons[0].return_value);  
end;

procedure EvAntiMacroUtil(Serial, GumpID, X, Y : Cardinal);
begin 
 if IsGump then 
  ParseAntiMacroGump; 
end;

end.