Here is the code that freezes my game client when it gets to it: Code: using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Clio.Utilities; using DestinyPlugin.Utilities; using ff14bot; using ff14bot.BotBases; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using ff14bot.Objects; using NeoGaia.ConnectionHandler; namespace DestinyPlugin.Logic { internal class Patrol : LogicBase { #region BaseClass Implementation protected override bool NeedToStart { get { return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" && !FatesAreAvailable() && PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null; } } protected override async Task<bool> Start() { Logger.Log("No Fates within the current settings are available. Starting to Patrol now."); var target = FindTarget(); if (Poi.Current.Type != PoiType.Kill) { Poi.Clear("Clearing Poi so we can find and kill a new target."); Poi.Current = new Poi(target, PoiType.Kill); } if (Poi.Current.BattleCharacter != null) { if (Poi.Current.BattleCharacter.ObjectId != target.ObjectId) { Poi.Current = new Poi(target, PoiType.Kill); } } while (Core.Me.Distance(target.Location) > RoutineManager.Current.PullRange + target.CombatReach + Core.Me.CombatReach) { Navigator.MoveTo(target.Location); await CarefulSleep.Sleep(500); } if (Core.Me.Distance(target.Location) < 15f) { target.Target(); } return true; } #endregion #region Helpers private static bool FatesAreAvailable() { var activeFates = FateManager.ActiveFates.Where( x => x.Level >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) && x.Level <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) && !FatebotSettings.Instance.BlackListedFates.Contains(x.Name) ).ToList(); var monsterSlayingFates = new List<FateData>(); var bossFates = new List<FateData>(); var escortFates = new List<FateData>(); if (Settings.Instance.MonsterSlayingEnabled) { monsterSlayingFates = activeFates.Where(x => x.IsValid && x.Icon == FateIconType.Battle).ToList(); } if (Settings.Instance.BossEnabled) { bossFates = activeFates.Where( x => x.IsValid && x.Icon == FateIconType.Boss && x.Progress >= Settings.Instance.BossPercentRequired).ToList(); } if (Settings.Instance.EscortEnabled) { escortFates = activeFates.Where( x => x.IsValid && (x.Icon == FateIconType.ProtectNPC || x.Icon == FateIconType.ProtectNPC2)) .ToList(); } var availableFates = monsterSlayingFates.Union(bossFates.Union(escortFates)); return availableFates.Any(); } private static BattleCharacter FindTarget() { return GameObjectManager.GetObjectsOfType<BattleCharacter>() .Where(x => !Settings.Instance.BlackListMobNames.Contains(x.EnglishName) && x.CanAttack && !x.IsDead && x.IsTargetable && x.IsVisible && !x.TappedByOther && x.FateId == 0 && x.ClassLevel >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) && x.ClassLevel <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) && x.MaxHealth < (Core.Player.MaxHealth*5)) .OrderBy(x => Core.Me.Distance(x.Location)) .FirstOrDefault(); } private static bool PatrolTargetAvailable { get { var target = FindTarget(); return target != null; } } #endregion } } Any help figuring out why it's freezing my client would be greatly appreciated.
I thought Code: return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" && !FatesAreAvailable() && PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null; needs to be Code: return Core.Me.IsAlive && Settings.Instance.Patrol && (BotManager.Current.EnglishName == "Fate Bot") && !FatesAreAvailable() && PatrolTargetAvailable && !Core.Me.InCombat && (Core.Me.CurrentTarget == null); to contain the comparison operators in the same statement with the logical operators. EDIT: Never mind, the compiler can parse and order them automatically these days.
So, I just removed the movement code and am just letting FateBot handle moving to the new Poi.... This seems to be working: Code: using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Clio.Utilities; using DestinyPlugin.Utilities; using ff14bot; using ff14bot.BotBases; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using ff14bot.Objects; using NeoGaia.ConnectionHandler; namespace DestinyPlugin.Logic { internal class Patrol : LogicBase { #region BaseClass Implementation protected override bool NeedToStart { get { return Core.Me.IsAlive && Settings.Instance.Patrol && BotManager.Current.EnglishName == "Fate Bot" && !FatesAreAvailable() && PatrolTargetAvailable && !Core.Me.InCombat && Core.Me.CurrentTarget == null; } } protected override async Task<bool> Start() { Logger.Log("No Fates within the current settings are available. Starting to Patrol now."); var target = FindTarget(); await CarefulSleep.Sleep(100); if (Poi.Current.Type != PoiType.Kill) { Poi.Clear("Clearing Poi so we can find and kill a new target."); Poi.Current = new Poi(target, PoiType.Kill); } if (Poi.Current.BattleCharacter != null) { if (Poi.Current.BattleCharacter.ObjectId != target.ObjectId) { Poi.Current = new Poi(target, PoiType.Kill); } } if (Core.Me.Distance(target.Location) < 15f) { target.Target(); } else { return false; } return true; } #endregion #region Helpers private static bool FatesAreAvailable() { var activeFates = FateManager.ActiveFates.Where( x => x.Level >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) && x.Level <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) && !FatebotSettings.Instance.BlackListedFates.Contains(x.Name) ).ToList(); var monsterSlayingFates = new List<FateData>(); var bossFates = new List<FateData>(); var escortFates = new List<FateData>(); if (Settings.Instance.MonsterSlayingEnabled) { monsterSlayingFates = activeFates.Where(x => x.IsValid && x.Icon == FateIconType.Battle).ToList(); } if (Settings.Instance.BossEnabled) { bossFates = activeFates.Where( x => x.IsValid && x.Icon == FateIconType.Boss && x.Progress >= Settings.Instance.BossPercentRequired).ToList(); } if (Settings.Instance.EscortEnabled) { escortFates = activeFates.Where( x => x.IsValid && (x.Icon == FateIconType.ProtectNPC || x.Icon == FateIconType.ProtectNPC2)) .ToList(); } var availableFates = monsterSlayingFates.Union(bossFates.Union(escortFates)); return availableFates.Any(); } private static BattleCharacter FindTarget() { return GameObjectManager.GetObjectsOfType<BattleCharacter>() .Where(x => !Settings.Instance.BlackListMobNames.Contains(x.EnglishName) && x.CanAttack && !x.IsDead && x.IsTargetable && x.IsVisible && !x.TappedByOther && x.FateId == 0 && x.ClassLevel >= (Core.Me.ClassLevel - Settings.Instance.MinLevel) && x.ClassLevel <= (Core.Me.ClassLevel + Settings.Instance.MaxLevel) && x.MaxHealth < (Core.Player.MaxHealth*5)) .OrderBy(x => Core.Me.Distance(x.Location)) .FirstOrDefault(); } private static bool PatrolTargetAvailable { get { var target = FindTarget(); return target != null; } } #endregion } }
If you remove the loop that pauses the function while moving to the target, doesn't that now cause it to stop targeting any mobs that are outside the '15' range? Or will the Fatebot bypass that portion and target them anyway due to the PoiType.Kill command?
Basically, right now, on the first tick, I will find a target and set it as my Poi. If I'm also within the 15 yalm range, then I'll target the mob, and that will cause the Patrol Logic to stop being pulsed because the decorator won't be true anymore because of the Core.Me.CurrentTarget == null portion of the NeedToStart boolean. If I'm more than 15 yalm away, then the Start method will keep getting run on each tick, and because it will already have a PoiType.Kill, it will bypass those checks and go right to the range check. If it's not within the 15 yalm range, it will just return false which tells the CoRoutine that it didn't finish successfully and it needs to keep it at this status. Setting the Poi will make FateBot handle the movement to the mob, and once I'm in range to target it, FateBot just handles the rest.
Code: while (Core.Me.Distance(target.Location) > RoutineManager.Current.PullRange + target.CombatReach + Core.Me.CombatReach) { Navigator.MoveTo(target.Location); await CarefulSleep.Sleep(500); } Seems troublesome, and u should handle it as u already did above ( return tick when out of range).
What are you doing poking around the RB forums!! =) Thanks for the input. You're correct in that part being bad. Once I removed that code, my client stopped freezing. Glad to see you over in RB's neck of the woods. I know the 6 month ban hurt a lot of WoW player's, but it's brought a lot of new life to RB!
await CarefulSleep.Sleep(500); What ever this is its probably bad. If your using a while loop your pretty much have to have a coroutine.yield in it as the last statement. Edit: Yea. Whatever this "CarefulSleep" is needs to replaced. If you need to sleep for a specifc amount of time then you should be using await Coroutine.Sleep(1000); If you want to sleep until a condition becomes true/false then you should be using await Coroutine.Wait(Timeout.Infinite, () => HousingMyChocobo.IsOpen); or await Coroutine.Wait(5000, () => HousingMyChocobo.IsOpen); If you are doing work inside a while loop: while(dosomething) { dostuff(); await Coroutine.Yield(); }
In the official Destiny V2 plugin, CarefulSleep is a function which calls Coroutine.Yield until the supplied millisecond count has expired: Code: private static async Task<bool> CarefulSleep(uint ms) { var stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds < ms && CanTeleport) { await Coroutine.Yield(); } stopwatch.Stop(); return CanTeleport; } I'm not sure what has changed in the new unreleased Destiny code, but that function does not cause any crashing issues and seems to currently work with Destiny.
The CarefulSleep method works beautifully and does exactly what I want it to do. Mastahg is correct that we don't need that method and that there are built in ways to do it which he has provided examples of. Regardless, I've fixed the issue I was having and thank everyone for their input on the topic. Feel free to lock this thread now as there's no more responses needed.