This repository was archived by the owner on Jan 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathHuntBase.cs
More file actions
486 lines (441 loc) · 23.5 KB
/
HuntBase.cs
File metadata and controls
486 lines (441 loc) · 23.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using Buddy.Coroutines;
using Clio.Utilities;
using ff14bot;
using ff14bot.AClasses;
using ff14bot.Behavior;
using ff14bot.Enums;
using ff14bot.Helpers;
using ff14bot.Managers;
using ff14bot.Navigation;
using ff14bot.Objects;
using ff14bot.Pathing.Service_Navigation;
using LlamaLibrary.Helpers;
using LlamaLibrary.Memory;
using TreeSharp;
using Action = TreeSharp.Action;
namespace LlamaLibrary
{
public class HuntBase : BotBase
{
private static readonly List<uint> Blacklist = new List<uint>();
private static List<BagSlot> _playerItems;
public static float PostCombatDelay = 0f;
internal static bool Bool0;
public static readonly InventoryBagId[] PlayerInventoryBagIds =
{
InventoryBagId.Bag1,
InventoryBagId.Bag2,
InventoryBagId.Bag3,
InventoryBagId.Bag4
};
private Composite _root;
public HuntBase()
{
OffsetManager.Init();
}
public override string Name => @"Daily Hunts";
public override PulseFlags PulseFlags => PulseFlags.All;
public override bool IsAutonomous => true;
public override bool RequiresProfile => false;
public override Composite Root => _root;
public override bool WantButton { get; } = false;
internal static bool InFight => GameObjectManager.Attackers.Any();
internal static BattleCharacter FirstAttacker => GameObjectManager.Attackers.FirstOrDefault();
private async Task<bool> Run()
{
Navigator.PlayerMover = new SlideMover();
Navigator.NavigationProvider = new ServiceNavigationProvider();
ff14bot.Settings.CharacterSettings.Instance.UseMount = true;
_playerItems = InventoryManager.GetBagsByInventoryBagId(PlayerInventoryBagIds).Select(i => i.FilledSlots).SelectMany(x => x).AsParallel().ToList();
var hadOld = await GetHuntBills();
await CompleteHunts();
if (hadOld)
{
await GetHuntBills();
await CompleteHunts();
}
if (WorldManager.CanTeleport())
{
WorldManager.TeleportById(Core.Me.HomePoint.Id);
await Coroutine.Sleep(5000);
if (CommonBehaviors.IsLoading) await Coroutine.Wait(-1, () => !CommonBehaviors.IsLoading);
}
TreeRoot.Stop($"Stop Requested");
return true;
}
public override void Start()
{
_root = new ActionRunCoroutine(r => Run());
}
public override void Stop()
{
_root = null;
}
public async Task<bool> GetHuntBills()
{
var statues = HuntHelper.GetDailyStatus();
foreach ((var orderType, var huntOrderStatus) in statues)
{
var orderTypeObj = HuntHelper.GetMobHuntOrderType((int) orderType);
switch (huntOrderStatus)
{
case HuntOrderStatus.OnlyFatesLeft:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Only Fates left for today's dailies so done");
break;
case HuntOrderStatus.OnlyFatesLeftOld:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Only Fates left for old dailies so should yeet them and get new ones");
HuntHelper.DiscardMobHuntType(orderType);
await HuntHelper.GetHuntsByOrderType(orderType);
break;
case HuntOrderStatus.NotAccepted:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Have not accepted today's hunts");
await HuntHelper.GetHuntsByOrderType(orderType);
break;
case HuntOrderStatus.NotAcceptedOld:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Not Accepted and last accepted were old and so should get new ones");
await HuntHelper.GetHuntsByOrderType(orderType);
break;
case HuntOrderStatus.Complete:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Finished today's dailies");
break;
case HuntOrderStatus.CompleteOld:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Finished old dailies");
await HuntHelper.GetHuntsByOrderType(orderType);
break;
case HuntOrderStatus.Unfinished:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Unfinished current dailies");
break;
case HuntOrderStatus.UnFinishedOld:
Log($"{orderTypeObj.Item.CurrentLocaleName} - Unfinished old dailies");
break;
default:
throw new ArgumentOutOfRangeException();
}
}
return statues.Any(i => i.Item2 == HuntOrderStatus.UnFinishedOld);
}
public async Task CompleteHunts()
{
int[] dailyOrderTypes = {0, 1, 2, 3, 6, 7, 8, 10, 11, 12};
const int flytoHunt = 418;
int[] umbra = {107, 247};
var hunts = new List<DailyHuntOrder>();
foreach (var dailyOrderType in dailyOrderTypes)
{
hunts.AddRange(HuntHelper.GetAcceptedDailyHunts(dailyOrderType).Where(i => !i.IsFinished));
}
foreach (var hunt in hunts.OrderBy(i => i.MapId).ThenBy(j => j.Location.X))
{
Log($"{hunt}");
while (Core.Me.InCombat)
{
var target = GameObjectManager.Attackers.FirstOrDefault(i => i.InCombat && i.IsAlive);
if (target != default(BattleCharacter) && target.IsValid && target.IsAlive)
{
await Navigation.GetTo(WorldManager.ZoneId, target.Location);
await KillMob(target);
}
}
/*
if (WorldManager.ZoneId == 401 && hunt.MapId == 401)
{
var AE = WorldManager.AetheryteIdsForZone(hunt.MapId).OrderBy(i => i.Item2.DistanceSqr(hunt.Location)).First();
WorldManager.TeleportById(AE.Item1);
await Coroutine.Wait(20000, () => WorldManager.ZoneId == AE.Item1);
await Coroutine.Sleep(2000);
}
if (WorldManager.ZoneId == 402 && hunt.MapId == 402)
{
var AE = WorldManager.AetheryteIdsForZone(hunt.MapId).OrderBy(i => i.Item2.DistanceSqr(hunt.Location)).First();
WorldManager.TeleportById(AE.Item1);
await Coroutine.Wait(20000, () => WorldManager.ZoneId == AE.Item1);
await Coroutine.Sleep(2000);
}*/
if (hunt.HuntTarget == flytoHunt)
{
var AE = WorldManager.AetheryteIdsForZone(hunt.MapId).OrderBy(i => i.Item2.DistanceSqr(hunt.Location)).First();
WorldManager.TeleportById(AE.Item1);
await Coroutine.Wait(20000, () => WorldManager.ZoneId == AE.Item1);
await Coroutine.Sleep(2000);
await Navigation.FlightorMove(new Vector3(196.902f, -163.4457f, 113.3596f));
//
Navigator.PlayerMover.MoveTowards(new Vector3(208.712f, -165.4754f, 128.228f));
await Coroutine.Wait(10000, () => CommonBehaviors.IsLoading);
Navigator.Stop();
await Coroutine.Sleep(1000);
if (CommonBehaviors.IsLoading) await Coroutine.Wait(-1, () => !CommonBehaviors.IsLoading);
while (!hunt.IsFinished)
{
if (await FindAndKillMob(hunt.NpcID))
{
Log("Killed one");
await Coroutine.Sleep(1000);
if (!Core.Me.InCombat) await Coroutine.Sleep(3000);
}
else
{
Log("None found, sleeping 10 sec.");
await Coroutine.Sleep(10000);
}
}
}
else if (umbra.Contains(hunt.HuntTarget))
{
await Navigation.GetToIslesOfUmbra();
if (await Navigation.GetTo(hunt.MapId, hunt.Location))
{
while (!hunt.IsFinished)
{
if (await FindAndKillMob(hunt.NpcID))
{
Log("Killed one");
await Coroutine.Sleep(1000);
if (!Core.Me.InCombat) await Coroutine.Sleep(3000);
}
else
{
Log("None found, sleeping 10 sec.");
await Coroutine.Sleep(10000);
}
}
}
}
else if (hunt.MapId >= 399)
{
await Lisbeth.TravelToZones(hunt.MapId, hunt.Location);
if (Core.Me.Location.Distance2DSqr(hunt.Location) <= 10f)
{
while (!hunt.IsFinished)
{
if (await FindAndKillMob(hunt.NpcID))
{
Log("Killed one");
await Coroutine.Sleep(1000);
if (!Core.Me.InCombat) await Coroutine.Sleep(3000);
}
else
{
Log("None found, sleeping 10 sec.");
await Coroutine.Sleep(10000);
}
}
}
}
else if (await Lisbeth.TravelToZones(hunt.MapId, hunt.Location))
{
while (!hunt.IsFinished)
{
if (await FindAndKillMob(hunt.NpcID))
{
Log("Killed one");
await Coroutine.Sleep(1000);
if (!Core.Me.InCombat) await Coroutine.Sleep(3000);
}
else
{
Log("None found, sleeping max 10 sec.");
await Coroutine.Wait(10000, () => FindMob(hunt.NpcID));
}
}
}
else if (await Navigation.GetTo(hunt.MapId, hunt.Location))
{
while (!hunt.IsFinished)
{
if (await FindAndKillMob(hunt.NpcID))
{
Log("Killed one");
await Coroutine.Sleep(1000);
if (!Core.Me.InCombat) await Coroutine.Sleep(3000);
}
else
{
Log("None found, sleeping max 10 sec.");
await Coroutine.Wait(10000, () => FindMob(hunt.NpcID));
}
}
}
Log($"Done: {hunt}");
var newPlayerItems = InventoryManager.GetBagsByInventoryBagId(PlayerInventoryBagIds).Select(i => i.FilledSlots).SelectMany(x => x).AsParallel().ToList();
var newitems = newPlayerItems.Except(_playerItems, new BagSlotComparer());
Log("New loot");
Log($"{string.Join(",", newitems)}");
Blacklist.Clear();
await Coroutine.Sleep(1000);
}
/*foreach (var orderType in dailyOrderTypes)
{
var dailies = HuntHelper.GetAcceptedDailyHunts(orderType).OrderBy(i=> i.MapId).ThenBy(j => j.Location.X);
if (dailies.Any(i => !i.IsFinished))
{
foreach (var hunt in dailies.Where(i => !i.IsFinished))
{
}
}*/
while (Core.Me.InCombat)
{
var target = GameObjectManager.Attackers.FirstOrDefault(i => i.InCombat);
if (target != default(BattleCharacter) && target.IsValid && target.IsAlive)
{
await Navigation.GetTo(WorldManager.ZoneId, target.Location);
await KillMob(target);
}
}
}
public static bool FindMob(uint npcId)
{
uint[] fateExmpt = {252, 339};
var mob = GameObjectManager.GetObjectsOfType<BattleCharacter>(true).Where(i => i.NpcId == npcId && i.IsValid && i.IsAlive && !(i.IsFate && !fateExmpt.Contains(npcId)) && !Blacklist.Contains(i.ObjectId)).OrderBy(r => r.Distance()).FirstOrDefault();
if (FirstAttacker != null && (Core.Me.InCombat && GameObjectManager.Attackers.FirstOrDefault() != null && FirstAttacker.IsAlive)) return true;
if (mob == default(BattleCharacter))
{
LogCritical($"Couldn't find mob with NPCID {npcId}");
return false;
}
else
{
return true;
}
}
public static async Task<bool> FindAndKillMob(uint npcId)
{
uint[] fateExmpt = {252, 339};
while (FirstAttacker != null && (Core.Me.InCombat && GameObjectManager.Attackers.FirstOrDefault() != null && FirstAttacker.IsAlive))
{
var target = GameObjectManager.Attackers.FirstOrDefault();
if (target != default(BattleCharacter) && target.IsValid && target.IsAlive)
{
await Navigation.GetTo(WorldManager.ZoneId, target.Location);
Bool0 = false;
await KillMob(target);
}
}
var mob = GameObjectManager.GetObjectsOfType<BattleCharacter>(true).Where(i => i.NpcId == npcId && i.IsValid && i.IsAlive && !(i.IsFate && !fateExmpt.Contains(npcId)) && !Blacklist.Contains(i.ObjectId)).OrderBy(r => r.Distance()).FirstOrDefault();
if (mob == default(BattleCharacter))
{
LogCritical($"Couldn't find mob with NPCID {npcId}");
return false;
}
else
{
LogSucess($"Found mob {mob}");
if (!await Navigation.GetTo(WorldManager.ZoneId, mob.Location))
{
LogCritical("Can't get to, blacklisting mob");
Blacklist.Add(mob.ObjectId);
return false;
}
await KillMob(mob);
LogSucess($"Did we kill it? {!(mob.IsValid && mob.IsAlive)}");
Navigator.PlayerMover.MoveStop();
return true;
}
}
public static async Task KillMob(BattleCharacter mob)
{
if (!mob.IsValid || !mob.IsAlive) return;
var test = new Poi(mob, PoiType.Kill);
Poi.Current = test;
while (mob.IsValid && mob.IsAlive && Poi.Current != null && Poi.Current.Unit != null)
{
//("Looping combat");
if (!await CombatCoroutine().ExecuteCoroutine())
{
LogCritical("Looping combat Composite False");
break;
}
GameObjectManager.Update();
await Coroutine.Yield();
if (mob.IsValid && mob.IsAlive && Poi.Current != null && Poi.Current.Unit != null)
{
LogCritical($"Looping combat {mob} {Poi.Current} {mob.IsValid && mob.IsAlive && Poi.Current != null && Poi.Current.Unit != null} ");
await Coroutine.Sleep(500);
LogCritical($"Looping combat {mob.IsValid && mob.IsAlive && Poi.Current != null && Poi.Current.Unit != null} ");
}
else
{
LogCritical("Combat Done");
break;
}
await Coroutine.Yield();
}
}
private static Composite CombatCoroutine()
{
return new PrioritySelector(new Decorator(object0 => !InFight && !Core.Me.IsDead, new PrioritySelector(new HookExecutor("Rest", "", new ActionAlwaysFail()), new HookExecutor("PreCombatBuff", "", new ActionAlwaysFail()))),
new Decorator(object0 => Core.Me.IsDead || Poi.Current == null || Poi.Current.BattleCharacter == null, new Action(delegate { Poi.Clear("Invalid Combat Poi"); })),
new Decorator(object0 => !Poi.Current.Unit.IsValid || Poi.Current.BattleCharacter.IsDead || Poi.Current.Unit.IsFateGone,
new Action(delegate
{
Poi.Clear("Targeted unit is dead, clearing Poi and carrying on!");
return RunStatus.Failure;
})),
new Decorator(object0 => Poi.Current != null && Poi.Current.Unit != null && Poi.Current.Unit.IsValid && Poi.Current.Unit.Pointer != Core.Me.PrimaryTargetPtr && Poi.Current.Unit.Distance() < 30f,
new Action(delegate { Poi.Current.Unit.Target(); })),
new Decorator(object0 => Core.Me.PrimaryTargetPtr == IntPtr.Zero,
new Action(delegate
{
Poi.Clear("Targeted unit is zero, clearing Poi and carrying on!");
return RunStatus.Failure;
})),
new HookExecutor("PreCombatLogic"),
new Decorator(object0 => Core.Me.PrimaryTargetPtr != IntPtr.Zero,
new PrioritySelector(new Decorator(object0 => Core.Player.IsMounted &&
Core.Target.Location.Distance2D(Core.Player.Location) < Core.Me.CombatReach + RoutineManager.Current.PullRange,
new Action(delegate
{
ActionManager.Dismount();
Navigator.Stop();
})),
new Decorator(object0 => !Core.Me.InCombat || !Core.Me.InCombat && !Poi.Current.BattleCharacter.InCombat,
new HookExecutor("Pull", "Run when pulling a mob to kill.", RoutineManager.Current.PullBehavior)),
new Decorator(object0 => Core.Me.InCombat,
new PrioritySelector(new Decorator(object0 => PostCombatDelay > 0f && !Bool0,
new Action(delegate
{
Bool0 = true;
return RunStatus.Failure;
})),
new Decorator(object0 => !Poi.Current.BattleCharacter.InCombat &&
Poi.Current.TimeSet + TimeSpan.FromSeconds(10.0) < DateTime.Now,
new Action(delegate
{
Poi
.Clear("I'm in combat, but POI isn't and it has been atleast 10 seconds. Clearing POI and picking up a new target.");
})),
new Decorator(object0 => Poi.Current.BattleCharacter.IsDead,
new Action(delegate { Poi.Clear("I'm in combat, but POI is dead. Clearing POI and picking up a new target."); })),
new HookExecutor("RoutineCombat", "Executes the current routine's Combat behavior", BrainBehavior.CombatLogic))))),
new Action(object0 => RunStatus.Success));
}
private void Log(string text)
{
var msg = "[" + Name + "] " + text;
Logging.Write(Colors.Pink, msg);
}
public static void LogCritical(string text)
{
Logging.Write(Colors.OrangeRed, text);
}
public static void LogSucess(string text)
{
Logging.Write(Colors.Green, text);
}
private class BagSlotComparer : IEqualityComparer<BagSlot>
{
public bool Equals(BagSlot x, BagSlot y)
{
return y != null && (x != null && x.TrueItemId == y.TrueItemId);
}
public int GetHashCode(BagSlot obj)
{
return obj.Item.GetHashCode();
}
}
}
}