1616 TRSMake = record
1717 Items: array of TRSMakeItem;
1818 QuantityButtons: TBoxArray;
19+ SelectedQuantity: Integer;
1920 {%codetools on}
20- _IsOpenHelper, _QuantityHelper, _ItemsHelper: TBox;
21+ _IsOpenHelper, _ItemsHelper: TBox;
2122 {%codetools on}
22- const QUANTITY_ALL: Integer = 0;
2323 const TEXT_COLOR: TColor = $203040;
2424 end;
2525
@@ -36,22 +36,14 @@ procedure TRSMake.SetupInterface();
3636begin
3737 with Chat.Bounds do
3838 begin
39- Self._IsOpenHelper.X1 := X1 + 40 ;
39+ Self._IsOpenHelper.X1 := X1 + 10 ;
4040 Self._IsOpenHelper.Y1 := Y1 + 12;
41- Self._IsOpenHelper.X2 := X1 + 300 ;
41+ Self._IsOpenHelper.X2 := X2 - 10 ;
4242 Self._IsOpenHelper.Y2 := Y1 + 34;
43- end;
4443
45- with Chat.Bounds do
46- begin
47- Self._QuantityHelper.X1 := X2 - 193;
48- Self._QuantityHelper.Y1 := Y1 + 15;
49- Self._QuantityHelper.X2 := X2 - 19;
50- Self._QuantityHelper.Y2 := Y1 + 44;
51- end;
44+ Self.QuantityButtons := TBoxArray.Create([X2-228, Y1+15], 6, 1, 29, 29, [6,0]).Reversed();
45+ Self.QuantityButtons[0].X2 += 5;
5246
53- with Chat.Bounds do
54- begin
5547 Self._ItemsHelper.X1 := X1 + 8;
5648 Self._ItemsHelper.Y1 := Y1 + 51;
5749 Self._ItemsHelper.X2 := X2 - 8;
@@ -95,10 +87,333 @@ begin
9587end;
9688
9789
90+ (*
91+ ## Make.GetItemBoxes
92+ ```pascal
93+ function TRSMake.GetItemBoxes(): TBoxArray;
94+ ```
95+ Returns the available item boxes.
96+
97+ Example:
98+ ```pascal
99+ ShowOnClient(Make.GetItemBoxes());
100+ ```
101+ *)
102+ function TRSMake.GetItemBoxes(): TBoxArray;
103+ var
104+ tpa: TPointArray;
105+ b: TBox;
106+ begin
107+ tpa := Target.FindColor($080707, 5, Self._ItemsHelper);
108+ for tpa in tpa.Cluster(1.5) do
109+ begin
110+ b := tpa.Bounds();
111+ if (b.Height = 72) and (b.Width = 93) then
112+ Result += b;
113+ end;
114+ end;
115+
116+
117+ (*
118+ ## Make.HasHint
119+ ```pascal
120+ function TRSMake.HasHint(): Boolean;
121+ ```
122+ Returns true if a hint tooltip is visible.
123+
124+ Example:
125+ ```pascal
126+ if Make.HasHint() then
127+ ShowOnClient(Make.GetHintBox());
128+ ```
129+ *)
130+ function TRSMake.HasHint(): Boolean;
131+ begin
132+ Result := Target.HasColor($A0FFFF, 0, 1, Chat.Bounds);
133+ end;
134+
135+ (*
136+ ## Make.WaitHint
137+ ```pascal
138+ function TRSMake.WaitHint(time: Integer = 600; interval: Integer = -1): Boolean;
139+ ```
140+ Returns true if a hint tooltip is visible within `time` milliseconds.
141+
142+ Example:
143+ ```pascal
144+ if Make.WaitHint() then
145+ ShowOnClient(Make.GetHintBox());
146+ ```
147+ *)
148+ function TRSMake.WaitHint(time: Integer = 600; interval: Integer = -1): Boolean;
149+ begin
150+ if interval < 0 then interval := RandomMode(100, 50, 1500);
151+ Result := SleepUntil(Self.HasHint(), interval, time);
152+ end;
153+
154+ (*
155+ ## Make.GetHintBox
156+ ```pascal
157+ function TRSMake.GetHintBox(): TBox;
158+ ```
159+ Returns the hint tooltip bounds.
160+
161+ Example:
162+ ```pascal
163+ ShowOnClient(Make.GetHintBox());
164+ ```
165+ *)
166+ function TRSMake.GetHintBox(): TBox;
167+ var
168+ tpa: TPointArray;
169+ begin
170+ tpa := Target.FindColor($A0FFFF, 0, Chat.Bounds);
171+ if tpa <> [] then Result := tpa.Bounds();
172+ end;
173+
174+ (*
175+ ## Make.ReadHint
176+ ```pascal
177+ function TRSMake.ReadHint(): String;
178+ ```
179+ Returns the hint tooltip text.
180+
181+ Example:
182+ ```pascal
183+ WriteLn Make.ReadHint();
184+ ```
185+ *)
186+ function TRSMake.ReadHint(): String;
187+ begin
188+ Result := OCR.Recognize(Self.GetHintBox(), RSFonts.PLAIN_12, [$0], 0);
189+ end;
190+
191+ (*
192+ ## Make.CloseHint
193+ ```pascal
194+ function TRSMake.CloseHint(): Boolean;
195+ ```
196+ Attempts to close a hint tooltip.
197+
198+ Example:
199+ ```pascal
200+ WriteLn Make.CloseHint();
201+ ```
202+ *)
203+ function TRSMake.CloseHint(): Boolean;
204+ var
205+ tpa: TPointArray;
206+ b: TBox;
207+ begin
208+ tpa := TPointArray.CreateFromBox(Chat.Bounds, True);
209+ for b in Self.GetItemBoxes() do
210+ tpa := tpa.ExcludeBox(b.Expand(1));
211+
212+ tpa := tpa.SortFrom(Mouse.Position());
213+ Mouse.Move(tpa[RandomLeft(0, High(tpa))]);
214+ Result := SleepUntil(not Self.HasHint(), RandomMode(100, 50, 1500), 600);
215+ end;
216+
217+
218+
219+ (*
220+ ## Make.IndexOfQuantity
221+ ```pascal
222+ function TRSMake.IndexOfQuantity(amount: Integer): Integer;
223+ ```
224+ Finds the index of a quantity button by the specified `amount`.
225+ If the `amount` we are looking for, the custom quantity button is returned,
226+ otherwise the result is `-1`.
227+
228+ Example:
229+ ```pascal
230+ WriteLn Make.IndexOfQuantity(Make.QUANTITY_ALL);
231+ ```
232+ *)
233+ function TRSMake.IndexOfQuantity(amount: Integer): Integer;
234+ var
235+ hintPt: TPoint;
236+ i, value: Integer;
237+ quantity: ERSItemQuantity;
238+ begin
239+ if amount <= 0 then Exit(0);
240+
241+ if Self.HasHint() then
242+ begin
243+ hintPt := Self.GetHintBox().TopRight;
244+ if (hintPt.Y <= Self.QuantityButtons[5].Y2) and (hintPt.X >= Self.QuantityButtons[5].X1) then
245+
246+ if not Self.CloseHint() then
247+ raise GetDebugLn('Make', 'Failed to close the tooltip which is covering the quanitty buttons');
248+ end;
249+
250+ quantity := ERSItemQuantity.Integer2Quantity(amount);
251+
252+ if quantity = ERSItemQuantity.CUSTOM then
253+ begin
254+ if amount = OCR.RecognizeNumber(Self.QuantityButtons[2], RSFonts.PLAIN_11, [Self.TEXT_COLOR, RSColors.TEXT_WHITE], 0) then
255+ Exit(2);
256+ Exit(1);
257+ end;
258+
259+ for i := 1 to High(Self.QuantityButtons) do
260+ if amount = OCR.RecognizeNumber(Self.QuantityButtons[i], RSFonts.PLAIN_11, [Self.TEXT_COLOR, RSColors.TEXT_WHITE], 0) then
261+ Exit(i);
262+ Result := -1;
263+ end;
264+
265+ (*
266+ ## Make.IndexOfQuantity
267+ ```pascal
268+ function TRSMake.IndexOfQuantity(amount: Integer): Integer;
269+ ```
270+ Finds the index of a quantity button by the specified `amount`.
271+ If the `amount` we are looking for, the custom quantity button is returned,
272+ otherwise the result is `-1`.
273+
274+ Example:
275+ ```pascal
276+ WriteLn Make.IndexOfQuantity(Make.QUANTITY_ALL);
277+ ```
278+ *)
279+ function TRSMake.IsQuantitySelected(idx: Integer): Boolean;
280+ begin
281+ Result := Target.HasColor(RSColors.TEXT_WHITE, 0, 1, Self.QuantityButtons[idx]);
282+ end;
283+
284+
285+ (*
286+ ## Make.SetQuantity
287+ ```pascal
288+ function TRSMake.SetQuantity(amount: Integer): Boolean;
289+ ```
290+ Attempts to set a quantity.
291+
292+ Example:
293+ ```pascal
294+ WriteLn Make.SetQuantity(Make.QUANTITY_ALL);
295+ ```
296+ *)
297+ function TRSMake.SetQuantity(amount: Integer): Boolean;
298+ var
299+ idx: Integer;
300+ done: Boolean;
301+ begin
302+ idx := Self.IndexOfQuantity(amount);
303+ if idx < 0 then
304+ raise GetDebugLn('Make', 'Quantity button for "' + ToStr(amount) + '" is not available.');
305+
306+ if Self.IsQuantitySelected(idx) then Exit(True);
307+
308+ Mouse.Click(Self.QuantityButtons[idx], EMouseButton.LEFT);
309+ Result := SleepUntil(
310+ (done := Self.IsQuantitySelected(idx)) or
311+ Chat.FindQuery('Enter amount', True), RandomMode(100, 50, 1500), 600
312+ );
313+ if done then Exit;
314+
315+ Result := Chat.AnswerQuery('Enter amount', ToStr(amount), 600);
316+ end;
317+
318+
319+ (*
320+ ## Make._SelectHelper
321+ ```pascal
322+ function TRSMake._SelectHelper(index: Integer; boxes: TBoxArray; keyboardProbability: Single): Boolean;
323+ ```
324+ Internal helper method that handles selecting an item with or without the keyboard.
325+ You probably will never need to use this directly.
326+ *)
327+ function TRSMake._SelectHelper(index: Integer; boxes: TBoxArray; keyboardProbability: Single): Boolean;
328+ var
329+ t: UInt64;
330+ begin
331+ if High(boxes) < index then Exit;
332+
333+ if keyboardProbability = -1 then
334+ keyboardProbability := Biometrics.RandomDouble(0.5);
335+
336+ if not RandomBoolean(keyboardProbability) then
337+ begin
338+ Mouse.Click(boxes[index], EMouseButton.LEFT);
339+ Exit(SleepUntil(not Self.IsOpen(), RandomMode(100, 50, 1500), 2000));
340+ end;
341+
342+ boxes[index].Y1 := boxes[index].Y2 + 1;
343+ boxes[index].Y2 += 15;
344+
345+ if OCR.Locate(boxes[index], 'Space', [Self.TEXT_COLOR], 0, RSFonts.PLAIN_11) < 0.95 then
346+ Keyboard.PressKey(EKeyCode.SPACE)
347+ else
348+ Keyboard.PressKey(EKeyCode(Ord(EKeyCode.NUM_1) + index));
349+
350+ Result := SleepUntil(not Self.IsOpen(), RandomMode(100, 50, 1500), 2000);
351+ end;
352+
353+ (*
354+ ## Make.Select
355+ ```pascal
356+ function TRSMake.Select(index, quantity: Integer; keyboardProbability: Single = -1): Boolean;
357+ function TRSMake.Select(item: String; quantity: Integer; keyboardProbability: Single = -1): Boolean; overload;
358+ ```
359+ Select a `index` or an `item` of the available item buttons available.
360+ If you are selecting an `item` you need to use the tooltip text.
361+
362+ Example:
363+ ```pascal
364+ WriteLn Make.Select('Maple longbow', QUANTITY_ALL);
365+ ```
366+ *)
367+ function TRSMake.Select(index, quantity: Integer; keyboardProbability: Single = -1): Boolean;
368+ var
369+ boxes: TBoxArray;
370+ begin
371+ if not Self.IsOpen() then Exit;
372+ if not Self.SetQuantity(quantity) then Exit;
373+ boxes := Self.GetItemBoxes();
374+ if index <= High(boxes) then
375+ Result := Self._SelectHelper(index, boxes, keyboardProbability);
376+ end;
377+
378+ function TRSMake.Select(item: String; quantity: Integer; keyboardProbability: Single = -1): Boolean; overload;
379+ var
380+ boxes: TBoxArray;
381+ i: Integer;
382+ begin
383+ if not Self.IsOpen() then Exit;
384+ boxes := Self.GetItemBoxes();
385+
386+ for i := 0 to High(Self.Items) do
387+ begin
388+ if Self.Items[i].Item <> item then Continue;
389+
390+ if Self.Items[i].Quantity <> quantity then
391+ begin
392+ if not Self.SetQuantity(quantity) then Exit;
393+ Self.Items[i].Quantity := quantity;
394+ end;
395+
396+ Exit(Self._SelectHelper(Self.Items[i].Index, boxes, keyboardProbability));
397+ end;
398+
399+ if not Self.SetQuantity(quantity) then Exit;
400+
401+ for i := 0 to High(boxes) do
402+ begin
403+ Mouse.Move(boxes[i]);
404+ if not Self.WaitHint(4000) then Continue;
405+
406+ if SameText(Self.ReadHint(), item) then
407+ begin
408+ Self.Items += [item, i, quantity];
409+ Exit(Self._SelectHelper(i, boxes, keyboardProbability));
410+ end;
411+ end;
412+ end;
413+
98414var
99415(*
100- (Make variable)=
101- ## var Make
416+ ## Make variable
102417Global {ref}`TRSMake` variable.
103418*)
104419 Make: TRSMake;
0 commit comments