@@ -16,10 +16,70 @@ Record responsible to handle the {ref}`GrandExchangeChat` interface.
1616 TRSGrandExchangeChat = record
1717 Bounds, Header: TBox;
1818 Scroll: TRSScrollBar;
19+ Slots: TRSSlotInterface;
20+ Items: TRSItemInterface;
1921 end;
2022
2123function TRSGrandExchangeChat.IsOpen(): Boolean; forward;
2224
25+ (*
26+ ## GrandExchangeChat.Grid
27+ ```pascal
28+ property TRSGrandExchangeChat.Grid: TBoxArray;
29+ ```
30+ Returns the {ref}`GrandExchangeChat` search grid.
31+
32+ Example:
33+ ```pascal
34+ {$I WaspLib/osrs.simba}
35+ begin
36+ while True do
37+ ShowOnTarget(GrandExchangeChat.Grid);
38+ end.
39+ ```
40+ ```{figure} ../../images/gec_grid.gif
41+ ```
42+ *)
43+ property TRSGrandExchangeChat.Grid: TBoxArray;
44+ var
45+ b, tmp: TBox;
46+ tpa: TPointArray;
47+ boxes: TBoxArray;
48+ weights: TIntegerArray;
49+ i: Integer;
50+ begin
51+ with Self.Scroll.Area do
52+ b := [X1+2, Y1, X2, Y2];
53+
54+ boxes := b.Partition(1, 3);
55+ for i := 0 to High(boxes) do
56+ begin
57+ b := boxes[i];
58+ tpa := Target.FindColor($555555, 0, b);
59+ if tpa = [] then
60+ begin
61+ if i = 0 then Exit;
62+ Continue;
63+ end;
64+ tpa += Target.FindColor(RSColors.ITEM_BORDER, 8.5, b);
65+
66+ if tpa = [] then Continue;
67+
68+ for tpa in tpa.Cluster(300, 1.5) do
69+ begin
70+ tmp := tpa.Bounds();
71+ if tmp.Height < 8 then Continue;
72+
73+ tmp.X1 := b.X1;
74+ tmp.X2 := b.X2;
75+ weights += tmp.X1 + tmp.Y2 * 100;
76+ Result += tmp;
77+ end;
78+ end;
79+
80+ Result := Result.Sort(weights, False);
81+ end;
82+
2383(*
2484## GrandExchangeChat.SetupInterface
2585```pascal
43103 Self.Scroll.Area.Y2 := Self.Bounds.Y2 - 9;
44104
45105 Self.Scroll.Setup();
106+
107+ Self.Slots.Setup('GrandExchangeChat.Slots', [], @Self.Grid);
108+ Self.Items.Setup('GrandExchangeChat.Items', @Self.Slots, [0, 1], @Self.IsOpen);
46109end;
47110
48111(*
@@ -157,72 +220,151 @@ begin
157220 Result := search = Self.SearchText;
158221end;
159222
223+ (*
224+ ## GrandExchangeChat.Find
225+ ```pascal
226+ function TRSGrandExchangeChat.Find(item: TRSItem; out bounds: TBox): Boolean;
227+ ```
228+ Returns true if the specified `item` text is found on the
229+ {ref}`GrandExchangeChat.Grid`.
230+
231+ `bounds` will return the grid box where the item text was found.
232+
233+ Example:
234+ ```pascal
235+ {$I WaspLib/osrs.simba}
236+ var
237+ b: TBox;
238+ begin
239+ if GrandExchangeChat.Find('Abyssal whip', b) then
240+ ShowOnTarget(b);
241+ end.
242+ ```
243+ ```{figure} ../../images/gec_Find.png
244+ ```
245+ *)
246+ function TRSGrandExchangeChat.Find(item: TRSItem; out bounds: TBox): Boolean;
247+ var
248+ str: String;
249+ begin
250+ item := item.ToLower();
251+ for bounds in Self.Grid do
252+ begin
253+ str := OCR.RecognizeLines(bounds, RSFonts.PLAIN_12, [RSColors.TEXT_BLACK], 0).Join(' ').ToLower();
254+ if item = str then
255+ Exit(True);
256+ end;
257+ end;
160258
161259(*
162- ## GrandExchangeChat.Grid
260+ ## GrandExchangeChat.Contains
163261```pascal
164- property TRSGrandExchangeChat.Grid: TBoxArray ;
262+ function TRSGrandExchangeChat.Contains(item: TRSItem): Boolean ;
165263```
166- Returns the {ref}`GrandExchangeChat` search grid.
264+ Returns true if the specified `item` text is found on the
265+ {ref}`GrandExchangeChat.Grid`.
167266
168267Example:
169268```pascal
269+ WriteLn GrandExchangeChat.Contains('Abyssal whip');
270+ ```
271+ *)
272+ function TRSGrandExchangeChat.Contains(item: TRSItem): Boolean;
273+ var
274+ bounds: TBox;
275+ begin
276+ Result := Self.Find(item, bounds);
277+ end;
170278
279+ (*
280+ ## GrandExchangeChat.Click
281+ ```pascal
282+ function TRSGrandExchangeChat.Click(item: TRSItem): Boolean;
171283```
172- ```{figure} ../../images/gec_grid.png
284+ Attempts to click the specified `item` on the {ref}`GrandExchangeChat.Grid`.
285+
286+ Example:
287+ ```pascal
288+ WriteLn GrandExchangeChat.Click('Abyssal whip');
173289```
290+ *)
291+ function TRSGrandExchangeChat.Click(item: TRSItem): Boolean;
292+ var
293+ bounds: TBox;
294+ begin
295+ if Self.Find(item, bounds) then
296+ begin
297+ Mouse.Click(bounds, EMouseButton.LEFT);
298+ Result := SleepUntil(Self.IsOpen(), 200, 2400);
299+ end;
300+ end;
174301
302+
303+ (*
304+ ## GrandExchangeChat.FindScroll
305+ ```pascal
306+ function TRSGrandExchangeChat.FindScroll(item: TRSItem): Integer;
307+ ```
308+ Attempts to find the scroll level the specified `item` is found on the
309+ {ref}`GrandExchangeChat.Grid`.
310+
311+ Example:
312+ ```pascal
313+ WriteLn GrandExchangeChat.FindScroll('Bandos tassets');
314+ ```
175315*)
176- property TRSGrandExchangeChat.Grid: TBoxArray ;
316+ function TRSGrandExchangeChat.FindScroll(item: TRSItem): Integer ;
177317var
178- b, tmp, offset: TBox;
179- tpa: TPointArray;
180- atpa: T2DPointArray;
181- i, h, newH: Integer;
318+ next: Integer;
319+ down: Boolean;
182320begin
183- with Self.Scroll.Area do
184- b := [X1+40, Y1+8, X1+160, Y1+80];
185- tpa := Target.FindColor($0, 0, b);
186- if tpa = [] then Exit;
187-
188- //remove small chars, like "'"
189- tpa := tpa.Cluster(1.5, 1.5).ExcludeSize(5, EComparator.__LE__).Merge();
190- atpa := tpa.Cluster(12, 8);
191-
192- //for i := 0 to High(atpa) do
193- //begin
194- // b := atpa[i].Bounds;
195- // newH := b.Height;
196- // if newH > h then
197- // begin
198- // tmp := b;
199- // h := newH;
200- // end;
201- //end;
202- //
203- //if h < 20 then
204- // b := [Self.Scroll.Area.X1+2, tmp.Y1-10, Self.Scroll.Area.X1+162, tmp.Y2+8]
205- //else
206- // b := [Self.Scroll.Area.X1+2, tmp.Y1-4, Self.Scroll.Area.X1+162, tmp.Y2+6];
207- //
208- //Result += b;
209- //offset := b;
210- //
211- //h := b.Height;
212- //
213- //repeat
214- // offset := offset.Offset([0,-h]);
215- // b := offset.Clip(Self.Scroll.Area);
216- // if b.Height >= 28 then
217- // Result += offset;
218- //until offset.Y1 < Self.Scroll.Area.Y1;
219- //
220- //repeat
221- // offset := offset.Offset([0,h]);
222- // b := offset.Clip(Self.Scroll.Area);
223- // if b.Height >= 32 then
224- // Result += offset;
225- //until offset.Y2 > Self.Scroll.Area.Y2;
321+ if not Self.Scroll.CanScroll() then Exit(-1);
322+
323+ Result := Self.Scroll.GetLevel();
324+ down := (Result > 0) or RandomBoolean(0.5);
325+
326+ if Self.Contains(item) then Exit;
327+
328+ repeat
329+ if down then next := Result - 5
330+ else next := Result + 5;
331+
332+ Result := Self.Scroll.SetLevel(next);
333+ if Self.Contains(item) then Exit;
334+
335+ if not Self.IsOpen() then Exit(-1); //failsafe
336+ until not InRange(Result, 1, 99);
337+
338+ down := not down;
339+ repeat
340+ if down then next := Result - 5
341+ else next := Result + 5;
342+
343+ Result := Self.Scroll.SetLevel(next);
344+ if Self.Contains(item) then Exit;
345+
346+ if not Self.IsOpen() then Exit(-1);
347+ until not InRange(Result, 1, 99);
348+
349+ Result := -1;
350+ end;
351+
352+ (*
353+ ## GrandExchangeChat.ScrollTo
354+ ```pascal
355+ function TRSGrandExchangeChat.ScrollTo(item: TRSItem): Boolean;
356+ ```
357+ Attempts to scroll until the specified `item` is found on the
358+ {ref}`GrandExchangeChat.Grid`.
359+
360+ Example:
361+ ```pascal
362+ WriteLn GrandExchangeChat.ScrollTo('Bandos tassets');
363+ ```
364+ *)
365+ function TRSGrandExchangeChat.ScrollTo(item: TRSItem): Boolean;
366+ begin
367+ Result := Self.FindScroll(item) > -1;
226368end;
227369
228370
0 commit comments