SHOW:
|
|
- or go back to the newest paste.
1 | using System; | |
2 | using System.Collections.Generic; | |
3 | using System.Linq; | |
4 | using System.Text; | |
5 | using System.Threading; | |
6 | ||
7 | using D3; | |
8 | using rndWalker.Common; | |
9 | ||
10 | namespace rndWalker.Bots | |
11 | { | |
12 | public abstract class Bot | |
13 | { | |
14 | abstract public void Execute(); | |
15 | ||
16 | // 0002FA62: 00000001(00000000) # {c:ffffffff}Salvage{/c} = 0x1D19D9E | |
17 | // C3024CC: 48BA183D534400AD Root.NormalLayer.vendor_dialog_mainPage.salvage_dialog.salvage_button (Visible: True) | |
18 | ||
19 | protected void closeInventory() | |
20 | { | |
21 | // 303EF3AC: 368FF8C552241695 Root.NormalLayer.inventory_dialog_mainPage.inventory_button_exit (Visible: True) | |
22 | var btn = UIElement.Get(0x368FF8C552241695); | |
23 | if (btn.Visible) | |
24 | btn.Click(); | |
25 | } | |
26 | ||
27 | protected bool needsRepair() | |
28 | { | |
29 | // 1EFC3224: BD8B3C3679D4F4D9 Root.NormalLayer.DurabilityIndicator (Visible: True) | |
30 | var indicator = UIElement.Get(0xBD8B3C3679D4F4D9); | |
31 | return (indicator != default(UIElement) && indicator.Visible); | |
32 | } | |
33 | ||
34 | /// <summary> | |
35 | /// will wait up to 60 seconds for the game to start. does nothing if already ingame | |
36 | /// </summary> | |
37 | protected void startGame() | |
38 | { | |
39 | ||
40 | ||
41 | while (Game.Ingame) | |
42 | { | |
43 | ExitGame(); | |
44 | Thread.Sleep(5000); | |
45 | } | |
46 | ||
47 | UIElement okButton = UIElement.Get(0xB4433DA3F648A992); | |
48 | if (okButton != default(UIElement) && okButton.Visible) | |
49 | { | |
50 | okButton.Click(); | |
51 | } | |
52 | ||
53 | // 27DFC2E4: 51A3923949DC80B7 Root.NormalLayer.BattleNetCampaign_main.LayoutRoot.Menu.PlayGameButton (Visible: True) | |
54 | // it's both the resume and the start game button | |
55 | while (Game.Ingame == false) | |
56 | { | |
57 | UIElement resumeGame = UIElement.Get(0x51A3923949DC80B7); | |
58 | if (resumeGame != null) | |
59 | { | |
60 | resumeGame.Click(); | |
61 | ||
62 | for (int i = 0; i < 20 && Game.Ingame == false; ++i) | |
63 | { | |
64 | okButton = UIElement.Get(0xB4433DA3F648A992); | |
65 | if (okButton != default(UIElement) && okButton.Visible) | |
66 | { | |
67 | okButton.Click(); | |
68 | } | |
69 | Thread.Sleep(1000); | |
70 | } | |
71 | } | |
72 | ||
73 | ||
74 | ||
75 | } | |
76 | ||
77 | Thread.Sleep(2000); | |
78 | ||
79 | } | |
80 | ||
81 | /// <summary> | |
82 | /// clicks the revive button once per second. does not handle the popups yet | |
83 | /// </summary> | |
84 | protected void revive() | |
85 | { | |
86 | // 20DDD3F4: BFAAF48BA9316742 Root.NormalLayer.deathmenu_dialog.dialog_main.button_revive_at_checkpoint (Visible: True) | |
87 | var btn = UIElement.Get(0xBFAAF48BA9316742); | |
88 | while (btn != default(UIElement) && btn.Visible) | |
89 | { | |
90 | btn.Click(); | |
91 | Thread.Sleep(1000); | |
92 | } | |
93 | } | |
94 | ||
95 | /// <summary> | |
96 | /// buy window needs to be open. repair tab needs not be selected though | |
97 | /// </summary> | |
98 | protected void repairAll() | |
99 | { | |
100 | // 1EFC12BC: 80F5D06A035848A5 Root.NormalLayer.shop_dialog_mainPage.repair_dialog.RepairAll (Visible: True) | |
101 | var btn = UIElement.Get(0x80F5D06A035848A5); | |
102 | if (btn != default(UIElement)) | |
103 | { | |
104 | btn.Click(); | |
105 | } | |
106 | } | |
107 | ||
108 | /// <summary> | |
109 | /// skips conversation pc with npc | |
110 | /// </summary> | |
111 | protected void skipConversation() | |
112 | { | |
113 | // 1F05DE84: 942F41B6B5346714 Root.NormalLayer.conversation_dialog_main.button_close (Visible: True) | |
114 | var advKey = UIElement.Get(0x942F41B6B5346714); | |
115 | while (advKey.Visible) | |
116 | { | |
117 | advKey.Click(); | |
118 | Thread.Sleep(45); | |
119 | } | |
120 | } | |
121 | ||
122 | /*// <summary> | |
123 | /// dont use! buggy | |
124 | /// </summary> | |
125 | protected void skipNpcConversation() { | |
126 | // 2D3E702C: C06278A08ADCF3AA Root.NormalLayer.playinghotkeys_dialog_backgroundScreen.playinghotkeys_conversation_advance (Visible: True) | |
127 | var advKey = UIElement.Get(0xC06278A08ADCF3AA); | |
128 | while (advKey.Visible) { | |
129 | advKey.Click(); | |
130 | Thread.Sleep(45); | |
131 | } | |
132 | }*/ | |
133 | ||
134 | /// <summary> | |
135 | /// changes quest to the one with the given index. may be slow so try to give the button hash in advance | |
136 | /// </summary> | |
137 | /// <param name="_listIndex"></param> | |
138 | protected void changeQuest(uint _listIndex) | |
139 | { | |
140 | ||
141 | changeQuest(_listIndex, 0); | |
142 | } | |
143 | ||
144 | protected void changeQuest(uint _listIndex, ulong _btn) | |
145 | { | |
146 | if (Game.Ingame) | |
147 | { | |
148 | ExitGame(); | |
149 | while (Game.Ingame) | |
150 | { | |
151 | Thread.Sleep(687); | |
152 | } | |
153 | } | |
154 | // 23E844FC: C4A9CC94C0A929B Root.NormalLayer.BattleNetCampaign_main.LayoutRoot.Menu.ChangeQuestButton (Visible: True) | |
155 | UIElement changeQuest = UIElement.Get(0xC4A9CC94C0A929B); | |
156 | changeQuest.Click(); | |
157 | Thread.Sleep(469); | |
158 | ||
159 | var button = default(UIElement); | |
160 | ||
161 | if (_btn == 0) | |
162 | { | |
163 | - | button = UIElement.Get().Where(x => x.Name.EndsWith(string.Format("_item{0}", _listIndex))).FirstOrDefault(); |
163 | + | button = rndWalker._elements.Where(x => x.Name.EndsWith(string.Format("_item{0}", _listIndex))).FirstOrDefault(); |
164 | } | |
165 | else | |
166 | { | |
167 | button = UIElement.Get(_btn); | |
168 | } | |
169 | button.Click(); | |
170 | Thread.Sleep(478); | |
171 | ||
172 | ||
173 | // 2BBDBAC4: 1AE2209980AAEA69 Root.NormalLayer.BattleNetQuestSelection_main.LayoutRoot.OverlayContainer.SelectQuestButton | |
174 | UIElement.Get(0x1AE2209980AAEA69).Click(); // select quest | |
175 | Thread.Sleep(730); | |
176 | ||
177 | // 2440DBEC: B4433DA3F648A992 Root.TopLayer.BattleNetModalNotifications_main.ModalNotification.Buttons.ButtonList.OkButton (Visible: True) | |
178 | var ok = UIElement.Get(0xB4433DA3F648A992); | |
179 | if (ok != null && ok.Visible) | |
180 | { // unfortunately this is always true... | |
181 | ok.Click(); | |
182 | } | |
183 | ||
184 | Thread.Sleep(1000); | |
185 | } | |
186 | ||
187 | public static void ExitGame() | |
188 | { | |
189 | UIElement ui = UIElement.Get(0x5DB09161C4D6B4C6); | |
190 | ||
191 | if (ui != null) | |
192 | { | |
193 | ui.Click(); | |
194 | } | |
195 | } | |
196 | ||
197 | protected void SkipSequence() | |
198 | { | |
199 | UIElement skipSequence = UIElement.Get(0x2289FE26DA955A81); | |
200 | UIElement confirmButton = UIElement.Get(0x891D21408238D18E); | |
201 | ||
202 | for (int i = 0; i < 10 && skipSequence.Visible == false; i++) | |
203 | { | |
204 | Thread.Sleep(500); | |
205 | } | |
206 | ||
207 | if (skipSequence.Visible == false) | |
208 | { | |
209 | throw new Exception("Skip Sequence UIElement is not visible!"); | |
210 | } | |
211 | ||
212 | skipSequence.Click(); | |
213 | ||
214 | for (int i = 0; i < 10 && confirmButton.Visible == false; i++) | |
215 | { | |
216 | Thread.Sleep(500); | |
217 | } | |
218 | ||
219 | if (skipSequence.Visible == false) | |
220 | { | |
221 | throw new Exception("Confirm Button UIElement is not visible!"); | |
222 | } | |
223 | ||
224 | confirmButton.Click(); | |
225 | ||
226 | for (int i = 0; i < 10 && confirmButton.Visible == true; i++) | |
227 | { | |
228 | Thread.Sleep(500); | |
229 | } | |
230 | ||
231 | if (confirmButton.Visible == true) | |
232 | { | |
233 | throw new Exception("Confirm Button UIElement is still visible!"); | |
234 | } | |
235 | ||
236 | // Wait out sequence post effect.. | |
237 | Thread.Sleep(5500); | |
238 | } | |
239 | ||
240 | protected bool walk(float _x, float _y) | |
241 | { | |
242 | return walk(_x, _y, false, 0); | |
243 | } | |
244 | ||
245 | /// <summary> | |
246 | /// walk to given (x,y) position. | |
247 | /// </summary> | |
248 | /// <param name="_x">X</param> | |
249 | /// <param name="_y">Y</param> | |
250 | /// <param name="_waitTillThere">whether to wait until toon is there</param> | |
251 | /// <returns></returns> | |
252 | protected bool walk(float _x, float _y, bool _waitTillThere) | |
253 | { | |
254 | return walk(_x, _y, _waitTillThere, 3); | |
255 | } | |
256 | ||
257 | protected bool walk(float _x, float _y, bool _waitTillThere, uint _countOut) | |
258 | { | |
259 | Me.UsePower(SNOPowerId.Walk, _x, _y, Me.Z); | |
260 | uint count = 0; | |
261 | if (_waitTillThere) | |
262 | { | |
263 | while (GetDistance(_x, _y) > 10) | |
264 | { | |
265 | if (Me.Mode != UnitMode.Running) | |
266 | { | |
267 | Me.UsePower(SNOPowerId.Walk, _x, _y, Me.Z); | |
268 | if (count++ >= _countOut) | |
269 | { | |
270 | return false; | |
271 | } | |
272 | } | |
273 | Thread.Sleep(100); | |
274 | } | |
275 | } | |
276 | return true; | |
277 | } | |
278 | ||
279 | protected void interact(Unit _u, bool _walkThere) | |
280 | { | |
281 | if (_u.Type == UnitType.Gizmo | |
282 | || _u.Type == UnitType.Monster | |
283 | || _u.Type == UnitType.Item) | |
284 | { | |
285 | if (_walkThere) | |
286 | { | |
287 | walk(_u.X, _u.Y, true); | |
288 | Thread.Sleep(300); | |
289 | } | |
290 | Me.UsePower(_u.Type == UnitType.Monster ? SNOPowerId.Axe_Operate_NPC : SNOPowerId.Axe_Operate_Gizmo, _u); | |
291 | if (_walkThere) | |
292 | { | |
293 | Thread.Sleep(700); | |
294 | } | |
295 | } | |
296 | } | |
297 | ||
298 | protected void interact(string _name, bool _walkThere) | |
299 | { | |
300 | var unit = Unit.Get().Where(x => x.Name.Contains(_name)).FirstOrDefault(); | |
301 | interact(unit, _walkThere); | |
302 | Thread.Sleep(213); | |
303 | } | |
304 | ||
305 | protected void clickUI(string _name, bool _visible) | |
306 | { | |
307 | - | var e = UIElement.Get().FirstOrDefault(x => x.Name.Contains(_name)); |
307 | + | var e = rndWalker._elements.FirstOrDefault(x => x.Name.Contains(_name)); |
308 | e.Click(); | |
309 | } | |
310 | ||
311 | /// <summary> | |
312 | /// waypoint menu needs to be open. if unsure use 'interact("Waypoint");' before this | |
313 | /// </summary> | |
314 | /// <param name="_listpos"></param> | |
315 | protected void useWaypoint(uint _listpos) | |
316 | { | |
317 | clickUI(string.Format("{0}.wrapper.button", _listpos), true); | |
318 | } | |
319 | ||
320 | protected bool GoTown() | |
321 | { | |
322 | if (Me.InTown == true) { return true; } | |
323 | ||
324 | if (Me.UsePower(SNOPowerId.UseStoneOfRecall) == true) | |
325 | { | |
326 | Thread.Sleep(550); | |
327 | ||
328 | while (Me.Mode == UnitMode.Casting | |
329 | || Me.Mode == UnitMode.Warping) | |
330 | { | |
331 | Thread.Sleep(250); | |
332 | } | |
333 | ||
334 | if (Me.InTown == true) | |
335 | { | |
336 | return true; | |
337 | } | |
338 | } | |
339 | return false; | |
340 | } | |
341 | ||
342 | protected bool TakePortal() | |
343 | { | |
344 | if (Me.InTown == false) { return false; } | |
345 | ||
346 | Unit[] units = Unit.Get(); | |
347 | ||
348 | var unit = (from u in units where u.Type == UnitType.Gizmo && u.ActorId == SNOActorId.hearthPortal select u).FirstOrDefault(); | |
349 | ||
350 | if (unit == default(Unit)) | |
351 | { | |
352 | return false; | |
353 | } | |
354 | ||
355 | for (int i = 0; i < 3; i++) | |
356 | { | |
357 | Me.UsePower(SNOPowerId.Axe_Operate_Gizmo, unit); | |
358 | Thread.Sleep(500); | |
359 | ||
360 | if (Me.InTown == false) | |
361 | { | |
362 | break; | |
363 | } | |
364 | } | |
365 | ||
366 | return Me.InTown == false; | |
367 | } | |
368 | ||
369 | ||
370 | protected Unit[] waitForMobs(uint _timeout) | |
371 | { | |
372 | var mobs = Unit.Get().Where(x => x.Type == UnitType.Monster && ((uint)x.MonsterType == 0 || (uint)x.MonsterType == 4) && x.Mode != UnitMode.Warping && x.Life > 0 | |
373 | && x.GetAttributeInteger(UnitAttribute.Is_NPC) == 0 && x.GetAttributeInteger(UnitAttribute.Is_Helper) == 0 | |
374 | && x.GetAttributeInteger(UnitAttribute.Invulnerable) == 0).ToArray(); | |
375 | uint count = 0; | |
376 | while (mobs.Length <= 0 && count < 2 * _timeout) | |
377 | { | |
378 | Thread.Sleep(500); | |
379 | mobs = Unit.Get().Where(x => x.Type == UnitType.Monster && ((uint)x.MonsterType == 0 || (uint)x.MonsterType == 4) && x.Mode != UnitMode.Warping && x.Life > 0 | |
380 | && x.GetAttributeInteger(UnitAttribute.Is_NPC) == 0 && x.GetAttributeInteger(UnitAttribute.Is_Helper) == 0 | |
381 | && x.GetAttributeInteger(UnitAttribute.Invulnerable) == 0).ToArray(); | |
382 | ++count; | |
383 | } | |
384 | return mobs; | |
385 | } | |
386 | ||
387 | /// <summary> | |
388 | /// buggy? | |
389 | /// </summary> | |
390 | /// <param name="_name"></param> | |
391 | /// <param name="_timeout"></param> | |
392 | /// <returns></returns> | |
393 | protected Unit waitForUnit(string _name, uint _timeout) | |
394 | { | |
395 | var portal = Unit.Get().Where(x =>/* x.Type == UnitType.Gizmo && */x.Name.Contains(_name)).ToArray(); | |
396 | ||
397 | uint count = 0; | |
398 | while (portal.Length <= 0 && count < 2 * _timeout) | |
399 | { | |
400 | Thread.Sleep(500); | |
401 | portal = Unit.Get().Where(x =>/* x.Type == UnitType.Gizmo && */x.Name.Contains(_name)).ToArray(); | |
402 | ++count; | |
403 | ||
404 | } | |
405 | return portal.FirstOrDefault(); | |
406 | } | |
407 | ||
408 | protected void waitForArea(uint _lvlArea) | |
409 | { | |
410 | while ((uint)Me.LevelArea != _lvlArea) | |
411 | { | |
412 | Thread.Sleep(567); | |
413 | } | |
414 | } | |
415 | ||
416 | protected void killThese(Unit[] _units) | |
417 | { | |
418 | _units = _units.OrderBy(u1 => GetDistance(u1.X, u1.Y, Me.X, Me.Y)).ToArray(); | |
419 | for (uint i = 0; i < _units.Length; ++i) | |
420 | { | |
421 | if (_units[i].Valid && _units[i].Life > 0) | |
422 | { | |
423 | Attack.AttackUnit(_units[i]); | |
424 | Thread.Sleep(154); | |
425 | } | |
426 | } | |
427 | } | |
428 | ||
429 | protected void killAll() | |
430 | { | |
431 | var mobs = waitForMobs(0); | |
432 | while (mobs.Length > 0) | |
433 | { | |
434 | killThese(mobs); | |
435 | mobs = waitForMobs(0); | |
436 | } | |
437 | } | |
438 | ||
439 | public static float GetDistance(float x, float y) | |
440 | { | |
441 | return GetDistance(x, y, Me.X, Me.Y); | |
442 | } | |
443 | ||
444 | public static float GetDistance(float x, float y, float x2, float y2) | |
445 | { | |
446 | return (float)Math.Sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); | |
447 | } | |
448 | ||
449 | private bool CheckWaypoint(string WPName, out string WPTarget) | |
450 | { | |
451 | WPTarget = ""; | |
452 | ||
453 | Game.Print("Checking Waypoint Availability"); | |
454 | ||
455 | - | var warps = UIElement.Get().Where(u => u.Name.Contains("waypoints_dialog") && u.Name.EndsWith("wrapper.text")); // Return all the waypoint text entries. |
455 | + | var warps = rndWalker._elements.Where(u => u.Name.Contains("waypoints_dialog") && u.Name.EndsWith("wrapper.text")); // Return all the waypoint text entries. |
456 | ||
457 | foreach (UIElement u in warps) | |
458 | { | |
459 | ||
460 | if (u.Text.ToLower().Contains(WPName.ToLower())) // Let's see if we can find a waypoint that matches the text we were given. | |
461 | { | |
462 | WPTarget = u.Name.Replace("wrapper.text", "wrapper.button"); // Fill out the name of the UIElement we need to click on. | |
463 | return true; | |
464 | } | |
465 | } | |
466 | ||
467 | return false; | |
468 | } | |
469 | ||
470 | private bool WarpTo(string warp_target) | |
471 | { | |
472 | ||
473 | Game.Print("Running WarpTo"); | |
474 | ||
475 | string warp_button = ""; | |
476 | ||
477 | if (!CheckWaypoint(warp_target, out warp_button)) //Check to see if we can actually warp there... | |
478 | return false; | |
479 | ||
480 | if (warp_button == "") // We didn't find it, return. | |
481 | return false; | |
482 | Game.Print("Okay, clicking the button..."); | |
483 | ||
484 | clickUI(warp_button, true); // Clicky wait for level change... | |
485 | ||
486 | uint _lvlArea = (uint)Me.LevelArea; | |
487 | ||
488 | Game.Print("Waiting for level change..."); | |
489 | while ((uint)Me.LevelArea == _lvlArea) | |
490 | { | |
491 | Thread.Sleep(400); | |
492 | } | |
493 | ||
494 | Game.Print("Done!"); | |
495 | return true; | |
496 | ||
497 | } | |
498 | ||
499 | ||
500 | public bool TakeWaypointTo(string warp_target) | |
501 | { | |
502 | var Waypoint = Unit.Get().Where(u => u.Name.ToLower().Contains("waypoint")).FirstOrDefault(); | |
503 | ||
504 | if (!Waypoint.Name.ToLower().Contains("waypoint")) | |
505 | { | |
506 | Game.Print("Unable to locate Waypoint!"); | |
507 | return false; | |
508 | } | |
509 | ||
510 | interact(Waypoint, true); | |
511 | Thread.Sleep(500); | |
512 | ||
513 | ||
514 | bool WarpAction = WarpTo(warp_target); | |
515 | return WarpAction; | |
516 | } | |
517 | } | |
518 | } |