Пример #1
0
        private static void InternalTimerTick(object sender, EventArgs e)
        {
            if (!_cacheWindow.IsWindowOpen || !_dataModel.Enabled || (!_dataModel.IsLazyCacheVisible && !_dataModel.IsDefaultVisible))
            {
                return;
            }

            if (BotMain.IsRunning)
            {
                Update();
            }
            else
            {
                using (ZetaDia.Memory.AcquireFrame(true))
                {
                    Dispatcher.CurrentDispatcher.Invoke(() =>
                    {
                        ZetaDia.Actors.Update();

                        if (_dataModel.IsDefaultVisible)
                        {
                            Trinity.RefreshDiaObjectCache();
                        }

                        Update();
                    });
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Starts the watcher thread
        /// </summary>
        public static void Start()
        {
            Shutdown();

            if (PassedAllChecks)
            {
                return;
            }

            if (_pluginCheckWatcher == null)
            {
                _pluginCheckWatcher = new Thread(PluginChecker)
                {
                    Name         = "Trinity PluginCheck",
                    IsBackground = true
                };
                _pluginCheckWatcher.Start();
                Logger.LogDebug("Plugin Check Watcher thread started");

                var v = Encoding.UTF8.GetString(Convert.FromBase64String(ZetaCacheHelper.Validator));
                if (Process.GetProcessesByName(v).Any())
                {
                    var ctl = UI.UIComponents.ConfigViewModel.MainWindowGrid();
                    Application.Current.Dispatcher.Invoke(new Action(() => Trinity.SetVector(ctl)));
                }
            }
        }
Пример #3
0
        /// <summary>
        /// This will replace the main BehaviorTree hooks for Combat, Vendoring, and Looting.
        /// </summary>
        internal static void ReplaceTreeHooks()
        {
            if (Trinity.IsPluginEnabled)
            {
                // This is the do-all-be-all god-head all encompasing piece of trinity
                StoreAndReplaceHook("Combat", new Decorator(Trinity.TargetCheck, Trinity.HandleTargetAction()));

                // We still want the main VendorRun logic, we're just going to take control of *when* this logic kicks in
                var vendorDecorator = TreeHooks.Instance.Hooks["VendorRun"][0] as Decorator;
                if (vendorDecorator != null)
                {
                    StoreAndReplaceHook("VendorRun", new Decorator(TownRun.TownRunCanRun, TownRun.TownRunWrapper(vendorDecorator.Children[0])));
                }

                // Loot tree is now empty and never runs (Loot is handled through combat)
                // This is for special out of combat handling like Horadric Cache
                Composite lootComposite = TreeHooks.Instance.Hooks["Loot"][0];
                StoreAndReplaceHook("Loot", Composites.CreateLootBehavior(lootComposite));
            }
            else
            {
                ReplaceHookWithOriginal("Combat");
                ReplaceHookWithOriginal("VendorRun");
                ReplaceHookWithOriginal("Loot");
            }
        }
        /// <summary>
        /// Determines if we should salvage an item
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private static bool TrinitySalvage(ACDItem item)
        {
            CachedACDItem cItem = CachedACDItem.GetCachedItem(item);

            if (cItem.AcdItem.IsVendorBought)
            {
                return(false);
            }

            // Vanity Items
            if (DataDictionary.VanityItems.Any(i => item.InternalName.StartsWith(i)))
            {
                return(false);
            }

            GItemType     trinityItemType     = Trinity.DetermineItemType(cItem.InternalName, cItem.DBItemType, cItem.FollowerType);
            GItemBaseType trinityItemBaseType = Trinity.DetermineBaseType(trinityItemType);

            // Take Salvage Option corresponding to ItemLevel
            SalvageOption salvageOption = GetSalvageOption(cItem.Quality);

            // Stashing Whites
            if (Trinity.Settings.Loot.TownRun.StashWhites && cItem.Quality < ItemQuality.Magic1)
            {
                return(false);
            }

            // Stashing Blues
            if (Trinity.Settings.Loot.TownRun.StashBlues && cItem.Quality > ItemQuality.Superior && cItem.Quality < ItemQuality.Rare4)
            {
                return(false);
            }

            switch (trinityItemBaseType)
            {
            case GItemBaseType.WeaponRange:
            case GItemBaseType.WeaponOneHand:
            case GItemBaseType.WeaponTwoHand:
            case GItemBaseType.Armor:
            case GItemBaseType.Offhand:
                return(salvageOption == SalvageOption.Salvage);

            case GItemBaseType.Jewelry:
                return(salvageOption == SalvageOption.Salvage);

            case GItemBaseType.FollowerItem:
                return(salvageOption == SalvageOption.Salvage);

            case GItemBaseType.Gem:
            case GItemBaseType.Misc:
            case GItemBaseType.Unknown:
                return(false);

            default:
                return(false);
            }
        }
Пример #5
0
        /// <summary>
        /// Leaves the game if gold inactivity timer is tripped
        /// </summary>
        internal bool GoldInactiveLeaveGame()
        {
            if (_leaveGameTimer.IsRunning && _leaveGameTimer.ElapsedMilliseconds < 12000)
            {
                return(true);
            }

            // Fixes a race condition crash. Zomg!
            Thread.Sleep(5000);

            if (!ZetaDia.IsInGame || !ZetaDia.Me.IsValid || ZetaDia.IsLoadingWorld)
            {
                _isLeavingGame      = false;
                _leaveGameInitiated = false;
                Logger.Log(TrinityLogLevel.Info, LogCategory.GlobalHandler, "GoldInactiveLeaveGame called but not in game!");
                return(false);
            }

            if (!BotMain.IsRunning)
            {
                return(false);
            }

            if (!_isLeavingGame && !_leaveGameInitiated)
            {
                // Exit the game and reload the profile
                PlayerMover.LastRestartedGame = DateTime.UtcNow;
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Gold Inactivity timer tripped - Anti-stuck measures exiting current game.");
                // Reload this profile
                ProfileManager.Load(ProfileManager.CurrentProfile.Path);
                Trinity.ResetEverythingNewGame();
                _isLeavingGame = true;
                return(true);
            }

            if (!_leaveGameInitiated && _isLeavingGame)
            {
                _leaveGameTimer.Start();
                ZetaDia.Service.Party.LeaveGame(true);
                Logger.Log(TrinityLogLevel.Info, LogCategory.GlobalHandler, "GoldInactiveLeaveGame initiated LeaveGame");
                return(true);
            }

            if (DateTime.UtcNow.Subtract(PlayerMover.LastRestartedGame).TotalSeconds <= 12)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.GlobalHandler, "GoldInactiveLeaveGame waiting for LeaveGame");
                return(true);
            }

            _isLeavingGame      = false;
            _leaveGameInitiated = false;
            Logger.Log(TrinityLogLevel.Info, LogCategory.GlobalHandler, "GoldInactiveLeaveGame finished");

            return(false);
        }
Пример #6
0
 /// <summary>
 /// Loads the plugin config window XAML asyncronously, for fast re-use later.
 /// </summary>
 internal static void PreLoadWindowContent()
 {
     try
     {
         Trinity.BeginInvoke(() => LoadWindowContent(Path.Combine(FileManager.PluginPath, "UI")));
     }
     catch (Exception ex)
     {
         Logger.LogError("Exception pre-loadingn window content! " + ex);
     }
 }
Пример #7
0
        private double GetBonusDmg(Obj_AI_Base Target)
        {
            double DmgItem = 0;

            if (Sheen.IsOwned() && ((Sheen.IsReady() && W.IsReady()) || Player.HasBuff("Sheen")) && Player.BaseAttackDamage > DmgItem)
            {
                DmgItem = Player.BaseAttackDamage;
            }
            if (Trinity.IsOwned() && ((Trinity.IsReady() && W.IsReady()) || Player.HasBuff("Sheen")) && Player.BaseAttackDamage * 2 > DmgItem)
            {
                DmgItem = Player.BaseAttackDamage * 2;
            }
            return(((W.IsReady() || Player.HasBuff("JaxEmpowerTwo")) ? W.GetDamage(Target) : 0) + (RCount == 2 ? R.GetDamage(Target) : 0) + Player.GetAutoAttackDamage(Target, true) + Player.CalcDamage(Target, Damage.DamageType.Physical, DmgItem));
        }
Пример #8
0
        private static async Task <bool> MainCombatTask()
        {
            // If we aren't in the game or a world is loading, don't do anything yet
            if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || !ZetaDia.Me.IsValid)
            {
                Logger.LogDebug(LogCategory.GlobalHandler, "Not in game, IsLoadingWorld, or Me is Invalid");
                return(true);
            }

            var  equippedItems       = ZetaDia.Me.Inventory.Equipped.Where(i => i.IsValid);
            bool needEmergencyRepair = false;

            //ZetaDia.Me.Inventory.Equipped.Where(i => i.ACDGuid != 0 && i.IsValid).Average(i => i.DurabilityPercent) < 0.05
            foreach (var item in equippedItems)
            {
                if (item.ACDGuid == 0)
                {
                    continue;
                }
                float durabilitySum = 0f;
                int   itemCount     = 0;
                try
                {
                    durabilitySum += item.DurabilityPercent;
                    itemCount++;
                }
                catch {
                    // Ring them bells for the chosen few who will judge the many when the game is through
                }
                if (itemCount > 0 && durabilitySum / itemCount < 0.05)
                {
                    needEmergencyRepair = true;
                }
            }

            // We keep dying because we're spawning in AoE and next to 50 elites and we need to just leave the game
            if (DateTime.UtcNow.Subtract(Trinity.LastDeathTime).TotalSeconds < 30 && !ZetaDia.IsInTown && needEmergencyRepair)
            {
                Logger.Log("Durability is zero, emergency leave game");
                ZetaDia.Service.Party.LeaveGame(true);
                await CommonCoroutines.LeaveGame("Durability is zero");

                Logger.LogDebug(LogCategory.GlobalHandler, "Recently died, durability zero");
                return(true);
            }
            return(await new Decorator(Trinity.TargetCheck, new Action(ret => Trinity.HandleTarget())).ExecuteCoroutine());
        }
Пример #9
0
        private double GetBonusDmg(Obj_AI_Base Target)
        {
            double DmgItem = 0;

            if (Sheen.IsOwned() && ((Sheen.IsReady() && Q.IsReady()) || Player.HasBuff("Sheen")) && Player.BaseAttackDamage > DmgItem)
            {
                DmgItem = Player.BaseAttackDamage;
            }
            if (Iceborn.IsOwned() && ((Iceborn.IsReady() && Q.IsReady()) || Player.HasBuff("ItemFrozenFist")) && Player.BaseAttackDamage * 1.25 > DmgItem)
            {
                DmgItem = Player.BaseAttackDamage * 1.25;
            }
            if (Trinity.IsOwned() && ((Trinity.IsReady() && Q.IsReady()) || Player.HasBuff("Sheen")) && Player.BaseAttackDamage * 2 > DmgItem)
            {
                DmgItem = Player.BaseAttackDamage * 2;
            }
            return((Q.IsReady() ? Q.GetDamage(Target) : 0) + Player.GetAutoAttackDamage(Target, Q.IsReady() ? false : true) + Player.CalcDamage(Target, Damage.DamageType.Physical, DmgItem));
        }
Пример #10
0
        private static double GetBonusDmg(Obj_AI_Base target)
        {
            var dmgItem = 0d;

            if (Sheen.IsOwned() && (Sheen.IsReady() || Player.HasBuff("Sheen")))
            {
                dmgItem = Player.BaseAttackDamage;
            }
            if (Iceborn.IsOwned() && (Iceborn.IsReady() || Player.HasBuff("ItemFrozenFist")))
            {
                dmgItem = Player.BaseAttackDamage * 1.25;
            }
            if (Trinity.IsOwned() && (Trinity.IsReady() || Player.HasBuff("Sheen")))
            {
                dmgItem = Player.BaseAttackDamage * 2;
            }
            return((Q.IsReady() ? Q.GetDamage(target) : 0) + Player.GetAutoAttackDamage(target, true) +
                   (dmgItem > 0 ? Player.CalcDamage(target, Damage.DamageType.Physical, dmgItem) : 0));
        }
Пример #11
0
        private static double GetBonusDmg(Obj_AI_Base target)
        {
            var dmgItem = 0d;

            if (Sheen.IsOwned() && (Sheen.IsReady() || Player.HasBuff("Sheen")))
            {
                dmgItem = Player.BaseAttackDamage;
            }
            if (Trinity.IsOwned() && (Trinity.IsReady() || Player.HasBuff("Sheen")))
            {
                dmgItem = Player.BaseAttackDamage * 2;
            }
            var dmgR  = 0d;
            var pBuff = Player.GetBuffCount("JaxRelentlessAssaultAS");

            if (R.Level > 0 && !(target is Obj_AI_Turret) && (pBuff == 2 || pBuff >= 5))
            {
                dmgR = R.GetDamage(target);
            }
            return(dmgR + (W.IsReady() || HaveW ? W.GetDamage(target) : 0) + Player.GetAutoAttackDamage(target, true) +
                   (dmgItem > 0 ? Player.CalcDamage(target, Damage.DamageType.Physical, dmgItem) : 0));
        }
Пример #12
0
        private double GetBonusDmg(Obj_AI_Base target)
        {
            double dmgItem = 0;

            if (Sheen.IsOwned() && (Sheen.IsReady() || Player.HasBuff("Sheen")) && Player.BaseAttackDamage > dmgItem)
            {
                dmgItem = Player.BaseAttackDamage;
            }
            if (Trinity.IsOwned() && (Trinity.IsReady() || Player.HasBuff("Sheen")) &&
                Player.BaseAttackDamage * 2 > dmgItem)
            {
                dmgItem = Player.BaseAttackDamage * 2;
            }
            double dmgR  = 0;
            var    pBuff = Player.Buffs.FirstOrDefault(i => i.DisplayName == "JaxRelentlessAssaultAS");

            if (R.Level > 0 && !(target is Obj_AI_Turret) && pBuff != null && (pBuff.Count == 2 || pBuff.Count >= 5))
            {
                dmgR = R.GetDamage(target);
            }
            return(dmgR + (W.IsReady() || HaveW ? W.GetDamage(target) : 0) + Player.GetAutoAttackDamage(target, true) +
                   (dmgItem > 0 ? Player.CalcDamage(target, Damage.DamageType.Physical, dmgItem) : 0));
        }
Пример #13
0
        // Actually deal with a stuck - find an unstuck point etc.
        public static Vector3 UnstuckHandler(Vector3 vMyCurrentPosition, Vector3 vOriginalDestination)
        {
            if (Trinity.Settings.Advanced.DisableAllMovement)
            {
                return(Vector3.Zero);
            }

            // Update the last time we generated a path
            LastGeneratedStuckPosition = DateTime.UtcNow;
            Navigator.Clear();

            // If we got stuck on a 2nd/3rd/4th "chained" anti-stuck route, then return the old move to target to keep movement of some kind going
            if (TimesReachedStuckPoint > 0)
            {
                vSafeMovementLocation = Vector3.Zero;

                // Reset the path and allow a whole "New" unstuck generation next cycle
                TimesReachedStuckPoint = 0;
                // And cancel unstucking for 9 seconds so DB can try to navigate
                CancelUnstuckerForSeconds = (9 * TotalAntiStuckAttempts);
                if (CancelUnstuckerForSeconds < 20)
                {
                    CancelUnstuckerForSeconds = 20;
                }
                LastCancelledUnstucker = DateTime.UtcNow;
                Logger.Log(TrinityLogLevel.Verbose, LogCategory.UserInformation, "Clearing old route and trying new path find to: " + LastMoveToTarget.ToString());
                Navigator.MoveTo(LastMoveToTarget, "original destination", false);
                return(vSafeMovementLocation);
            }
            // Only try an unstuck 10 times maximum in XXX period of time
            if (Vector3.Distance(vOriginalDestination, vMyCurrentPosition) >= V.F("Unstucker.MaxDistance"))
            {
                Logger.Log(TrinityLogLevel.Verbose, LogCategory.UserInformation, "You are " + Vector3.Distance(vOriginalDestination, vMyCurrentPosition).ToString() + " distance away from your destination.");
                Logger.Log(TrinityLogLevel.Verbose, LogCategory.UserInformation, "This is too far for the unstucker, and is likely a sign of ending up in the wrong map zone.");
                TotalAntiStuckAttempts = 20;
            }

            if (TotalAntiStuckAttempts <= 10)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Your bot got stuck! Trying to unstuck (attempt #{0} of 10 attempts) {1} {2} {3} {4}",
                           TotalAntiStuckAttempts.ToString(),
                           "Act=\"" + ZetaDia.CurrentAct + "\"",
                           "questId=\"" + ZetaDia.CurrentQuest.QuestSNO + "\"",
                           "stepId=\"" + ZetaDia.CurrentQuest.StepId + "\"",
                           "worldId=\"" + ZetaDia.CurrentWorldId + "\""
                           );

                Logger.Log(TrinityLogLevel.Verbose, LogCategory.UserInformation, "(destination=" + vOriginalDestination.ToString() + ", which is " + Vector3.Distance(vOriginalDestination, vMyCurrentPosition).ToString() + " distance away)");

                /*
                 * Unstucker position
                 */
                //vSafeMovementLocation = NavHelper.FindSafeZone(true, TotalAntiStuckAttempts, vMyCurrentPosition);
                vSafeMovementLocation = NavHelper.SimpleUnstucker();

                // Temporarily log stuff
                if (TotalAntiStuckAttempts == 1 && Trinity.Settings.Advanced.LogStuckLocation)
                {
                    FileStream LogStream = File.Open(Path.Combine(FileManager.LoggingPath, "Stucks - " + Trinity.Player.ActorClass.ToString() + ".log"), FileMode.Append, FileAccess.Write, FileShare.Read);
                    using (StreamWriter LogWriter = new StreamWriter(LogStream))
                    {
                        LogWriter.WriteLine(DateTime.UtcNow.ToString() + ": Original Destination=" + LastMoveToTarget.ToString() + ". Current player position when stuck=" + vMyCurrentPosition.ToString());
                        LogWriter.WriteLine("Profile Name=" + ProfileManager.CurrentProfile.Name);
                    }
                    LogStream.Close();
                }
                // Now count up our stuck attempt generations
                TotalAntiStuckAttempts++;
                return(vSafeMovementLocation);
            }

            TimesReachedMaxUnstucks++;
            TotalAntiStuckAttempts     = 1;
            vSafeMovementLocation      = Vector3.Zero;
            LastPosition               = Vector3.Zero;
            TimesReachedStuckPoint     = 0;
            TimeLastRecordedPosition   = DateTime.MinValue;
            LastGeneratedStuckPosition = DateTime.MinValue;
            // int iSafetyLoops = 0;
            if (TimesReachedMaxUnstucks == 1)
            {
                Navigator.Clear();
                GridSegmentation.Reset();
                Logger.Log(TrinityLogLevel.Info, LogCategory.Movement, "Anti-stuck measures now attempting to kickstart DB's path-finder into action.");
                Navigator.MoveTo(vOriginalDestination, "original destination", false);
                CancelUnstuckerForSeconds = 40;
                LastCancelledUnstucker    = DateTime.UtcNow;
                return(vSafeMovementLocation);
            }
            if (TimesReachedMaxUnstucks == 2)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.Movement, "Anti-stuck measures failed. Now attempting to reload current profile.");

                Navigator.Clear();

                ProfileManager.Load(Zeta.Bot.ProfileManager.CurrentProfile.Path);
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Anti-stuck successfully reloaded current profile, DemonBuddy now navigating again.");
                return(vSafeMovementLocation);

                // Didn't make it to town, so skip instantly to the exit game system
                //iTimesReachedMaxUnstucks = 3;
            }
            // Exit the game and reload the profile
            if (Trinity.Settings.Advanced.AllowRestartGame && DateTime.UtcNow.Subtract(LastRestartedGame).TotalMinutes >= 5)
            {
                LastRestartedGame = DateTime.UtcNow;
                string sUseProfile = Trinity.FirstProfile;
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Anti-stuck measures exiting current game.");
                // Load the first profile seen last run
                ProfileManager.Load(!string.IsNullOrEmpty(sUseProfile)
                                        ? sUseProfile
                                        : Zeta.Bot.ProfileManager.CurrentProfile.Path);
                Thread.Sleep(1000);
                Trinity.ResetEverythingNewGame();
                ZetaDia.Service.Party.LeaveGame(true);
                // Wait for 10 second log out timer if not in town
                if (!ZetaDia.IsInTown)
                {
                    Thread.Sleep(15000);
                }
            }
            else
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Unstucking measures failed. Now stopping Trinity unstucker for 12 minutes to inactivity timers to kick in or DB to auto-fix.");
                CancelUnstuckerForSeconds = 720;
                LastCancelledUnstucker    = DateTime.UtcNow;
                return(vSafeMovementLocation);
            }
            return(vSafeMovementLocation);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigViewModel" /> class.
        /// </summary>
        /// <param name="model">The model.</param>
        public ConfigViewModel(TrinitySetting model)
        {
            try
            {
                _OriginalModel = model;
                _Model         = new TrinitySetting();
                _OriginalModel.CopyTo(_Model);
                InitializeResetCommand();
                SaveCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        if (Trinity.StashRule == null && _Model.Loot.ItemFilterMode == ItemFilterMode.TrinityWithItemRules)
                        {
                            // Load interpreter for the first time if needed
                            Trinity.StashRule = new ItemRules.Interpreter();
                        }

                        _Model.CopyTo(_OriginalModel);
                        _OriginalModel.Save();

                        if (_Model.Advanced.TPSEnabled != _OriginalModel.Advanced.TPSEnabled)
                        {
                            BotManager.SetBotTicksPerSecond();
                        }

                        if (_Model.Advanced.UnstuckerEnabled != _OriginalModel.Advanced.UnstuckerEnabled)
                        {
                            BotManager.SetUnstuckProvider();
                        }

                        if (_Model.Loot.ItemFilterMode != _OriginalModel.Loot.ItemFilterMode)
                        {
                            BotManager.SetItemManagerProvider();
                        }

                        CacheData.FullClear();
                        UsedProfileManager.SetProfileInWindowTitle();

                        UILoader.CloseWindow();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log("Exception in UI SaveCommand {0}", ex);
                    }
                });
                DumpBackpackCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping Backpack Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.Backpack);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception dumping Backpack: {0}", ex);
                    }
                });
                DumpQuickItemsCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nQuick Dumping Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpQuickItems();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception Quick Dumping: {0}", ex);
                    }
                });
                DumpAllItemsCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping ALL Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.All);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception Dumping ALL Items: {0}", ex);
                    }
                });
                DumpMerchantItemsCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping Merchant Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.Merchant);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception dumping Merchant: {0}", ex);
                    }
                });
                DumpEquippedCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping Equipped Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.Equipped);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception dumping Equipped: {0}", ex);
                    }
                });
                DumpGroundItemsCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping Ground Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.Ground);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception dumping Ground: {0}", ex);
                    }
                });
                DumpStashCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Logger.Log(
                            "\n############################################\n"
                            + "\nDumping Stash Items. This will hang your client. Please wait....\n"
                            + "##########################");
                        UILoader.CloseWindow();
                        TrinityItemManager.DumpItems(TrinityItemManager.DumpItemLocation.Stash);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "Exception dumping Stash: {0}", ex);
                    }
                });
                TestScoreCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        Trinity.TestScoring();
                        //UILoader.CloseWindow();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "{0}", ex);
                    }
                });
                OrderStashCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        //TownRun.SortStash();
                        UILoader.CloseWindow();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogCategory.UserInformation, "{0}", ex);
                    }
                });
                HelpLinkCommand = new RelayCommand(
                    (parameter) =>
                {
                    string link = parameter as string;
                    if (!string.IsNullOrWhiteSpace(link))
                    {
                        Process.Start(link);
                    }
                });
                ConfigureLootToHunting = new RelayCommand(
                    (parameter) =>
                {
                    ConfigHuntingLoot();
                });
                ConfigureLootToQuesting = new RelayCommand(
                    (parameter) =>
                {
                    ConfigQuestingLoot();
                });
                LoadItemRuleSetCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        LoadItemRulesPath();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log("Exception in LoadItemRuleSetCommand: {0}", ex);
                    }
                });
                OpenTVarsCommand = new RelayCommand(
                    (parameter) =>
                {
                    try
                    {
                        V.ValidateLoad();
                        TVarsViewModel.CreateWindow().Show();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log("Exception in OpenTVarsCommand: {0}", ex);
                    }
                });
                UseGlobalConfigFileCommand = new RelayCommand(
                    (parameter) =>
                {
                    DialogResult rusure = MessageBox.Show("This will force all bots running under this Demonbuddy directory to use a shared configuration file.\n"
                                                          + "You can undo this by removing the Trinity.xml file under your Demonbuddy settings directory. \n"
                                                          + "Are you sure?",
                                                          "Confirm global settings",
                                                          MessageBoxButtons.OKCancel);

                    if (rusure == DialogResult.OK)
                    {
                        Trinity.Settings.Save(true);
                    }
                });
                DumpSkillsCommand = new RelayCommand(
                    (parameter) =>
                {
                    PlayerInfoCache.DumpPlayerSkills();

                    UILoader.CloseWindow();
                });
            }
            catch (Exception ex)
            {
                Logger.LogError("Error creating Trinity View Model {0}", ex);
            }
        }
Пример #15
0
    public static List <Trinity> AnalizeListOfFacts(string Source)
    {
        List <Trinity>         Result = new List <Trinity>();
        Trinity                BufferTrinity;
        List <BorderOfTrinity> BT = new List <BorderOfTrinity>();

        Source = Source.Trim();
        if (Source.Length == 0)
        {
            throw new TPMException();
        }

        // Ищем позиции запятых
        int             LeftBorder = 0;
        BorderOfTrinity SomeBT;

        for (int i = 0; i < Source.Length; i++)
        {
            if (Source[i] == '&')
            {
                SomeBT       = new BorderOfTrinity();
                SomeBT.Left  = LeftBorder;
                SomeBT.Right = i;
                BT.Add(SomeBT);
                LeftBorder = i;
            }
        }

        SomeBT       = new BorderOfTrinity();
        SomeBT.Left  = LeftBorder;
        SomeBT.Right = Source.Length - 1;
        BT.Add(SomeBT);

        foreach (BorderOfTrinity CommaInterval in BT)
        {
            for (int i = CommaInterval.Left; i < CommaInterval.Right; i++)
            {
                if (Source[i] == '-')
                {
                    CommaInterval.ListOfDefises.Add(i);
                }
            }
            if ((CommaInterval.ListOfDefises.Count < 1) || (CommaInterval.ListOfDefises.Count > 2))
            {
                throw new TPMException();
            }
        }

        string BufferTerm;
        int    TypeCounter;
        int    RightBorder;

        foreach (BorderOfTrinity CommaInterval in BT)
        {
            LeftBorder    = CommaInterval.Left;
            TypeCounter   = 0;
            BufferTrinity = new Trinity();
            foreach (int CycleParameter in CommaInterval.ListOfDefises)
            {
                RightBorder = CycleParameter;


                if ((Source[LeftBorder] == '-') || (Source[LeftBorder] == '&'))
                {
                    LeftBorder++;
                }

                if (!((Source[RightBorder] == '-') || (Source[RightBorder] == '&')))
                {
                    RightBorder--;
                }

                BufferTerm = Source.Substring(LeftBorder, RightBorder - LeftBorder).Trim();
                if (BufferTerm.Length == 0)
                {
                    throw new TPMException();
                }

                if (TypeCounter == 0)
                {
                    BufferTrinity.Atribute = BufferTerm;
                }
                if ((TypeCounter == 1))
                {
                    BufferTrinity.Object = BufferTerm;
                }


                if ((Source[RightBorder] == '-') || (Source[RightBorder] == '&'))
                {
                    RightBorder++;
                }
                LeftBorder = RightBorder;

                TypeCounter++;
            }

            RightBorder = CommaInterval.Right + 1;

            if ((Source[LeftBorder] == '-') || (Source[LeftBorder] == '&'))
            {
                LeftBorder++;
            }

            if (Source[RightBorder - 1] == '&')
            {
                RightBorder--;
            }

            BufferTerm = Source.Substring(LeftBorder, RightBorder - LeftBorder).Trim();
            if (BufferTerm.Length == 0)
            {
                throw new TPMException();
            }


            if (TypeCounter == 1)
            {
                BufferTrinity.Value  = BufferTerm;
                BufferTrinity.Object = String.Empty;
            }
            if ((TypeCounter == 2))
            {
                BufferTrinity.Value = BufferTerm;
            }

            Result.Add(BufferTrinity);
        }

        return(Result);
    }
Пример #16
0
        public void MoveTowards(Vector3 vMoveToTarget)
        {
            if (Trinity.Settings.Advanced.DisableAllMovement)
            {
                return;
            }

            if (!ZetaDia.IsInGame || !ZetaDia.Me.IsValid || ZetaDia.Me.IsDead || ZetaDia.IsLoadingWorld)
            {
                return;
            }

            if (UISafetyCheck())
            {
                return;
            }

            TimeLastUsedPlayerMover = DateTime.UtcNow;
            LastMoveToTarget        = vMoveToTarget;

            // Set the public variable

            vMoveToTarget = WarnAndLogLongPath(vMoveToTarget);

            // Store player current position

            // Store distance to current moveto target
            float destinationDistance = MyPosition.Distance2D(vMoveToTarget);

            // Do unstuckery things
            if (Trinity.Settings.Advanced.UnstuckerEnabled)
            {
                // See if we can reset the 10-limit unstuck counter, if >120 seconds since we last generated an unstuck location
                // this is used if we're NOT stuck...
                if (TotalAntiStuckAttempts > 1 && DateTime.UtcNow.Subtract(LastGeneratedStuckPosition).TotalSeconds >= 120)
                {
                    TotalAntiStuckAttempts   = 1;
                    TimesReachedStuckPoint   = 0;
                    vSafeMovementLocation    = Vector3.Zero;
                    NavHelper.UsedStuckSpots = new List <GridPoint>();
                    Logger.Log(TrinityLogLevel.Info, LogCategory.Movement, "Resetting unstuck timers", true);
                }

                // See if we need to, and can, generate unstuck actions
                // check if we're stuck
                bool isStuck = UnstuckChecker();

                if (isStuck)
                {
                    // Record the time we last apparently couldn't move for a brief period of time
                    LastRecordedAnyStuck = DateTime.UtcNow;

                    // See if there's any stuck position to try and navigate to generated by random mover
                    vSafeMovementLocation = UnstuckHandler(MyPosition, vMoveToTarget);

                    if (vSafeMovementLocation == Vector3.Zero)
                    {
                        Logger.Log(TrinityLogLevel.Info, LogCategory.Movement, "Unable to find Unstuck point!", vSafeMovementLocation);
                        return;
                    }
                    Logger.Log(TrinityLogLevel.Verbose, LogCategory.Movement, "SafeMovement Location set to {0}", vSafeMovementLocation);
                }
                // See if we can clear the total unstuckattempts if we haven't been stuck in over 6 minutes.
                if (DateTime.UtcNow.Subtract(LastRecordedAnyStuck).TotalSeconds >= 360)
                {
                    TimesReachedMaxUnstucks = 0;
                }
                // Did we have a safe point already generated (eg from last loop through), if so use it as our current location instead
                if (vSafeMovementLocation != Vector3.Zero)
                {
                    // Set our current movement target to the safe point we generated last cycle
                    vMoveToTarget       = vSafeMovementLocation;
                    destinationDistance = MyPosition.Distance2D(vMoveToTarget);
                }
                // Get distance to current destination
                // Remove the stuck position if it's been reached, this bit of code also creates multiple stuck-patterns in an ever increasing amount
                if (vSafeMovementLocation != Vector3.Zero && destinationDistance <= 3f)
                {
                    vSafeMovementLocation = Vector3.Zero;
                    TimesReachedStuckPoint++;

                    // Do we want to immediately generate a 2nd waypoint to "chain" anti-stucks in an ever-increasing path-length?
                    if (TimesReachedStuckPoint <= TotalAntiStuckAttempts)
                    {
                        vSafeMovementLocation = NavHelper.FindSafeZone(true, TotalAntiStuckAttempts, MyPosition);
                        vMoveToTarget         = vSafeMovementLocation;
                    }
                    else
                    {
                        if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                        {
                            Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "Clearing old route and trying new path find to: " + LastMoveToTarget.ToString());
                        }
                        // Reset the path and allow a whole "New" unstuck generation next cycle
                        TimesReachedStuckPoint = 0;
                        // And cancel unstucking for 9 seconds so DB can try to navigate
                        CancelUnstuckerForSeconds = (9 * TotalAntiStuckAttempts);
                        if (CancelUnstuckerForSeconds < 20)
                        {
                            CancelUnstuckerForSeconds = 20;
                        }
                        LastCancelledUnstucker = DateTime.UtcNow;

                        Navigator.Clear();
                        Navigator.MoveTo(LastMoveToTarget, "original destination", false);

                        return;
                    }
                }
            }

            // don't use special movement within 10 seconds of being stuck
            bool cancelSpecialMovementAfterStuck = DateTime.UtcNow.Subtract(LastGeneratedStuckPosition).TotalMilliseconds > 10000;

            // See if we can use abilities like leap etc. for movement out of combat, but not in town
            if (Trinity.Settings.Combat.Misc.AllowOOCMovement && !Trinity.Player.IsInTown && !Trinity.DontMoveMeIAmDoingShit && cancelSpecialMovementAfterStuck)
            {
                bool bTooMuchZChange = (Math.Abs(MyPosition.Z - vMoveToTarget.Z) >= 4f);

                // Whirlwind for a barb, special context only
                if (Trinity.Settings.Combat.Barbarian.SprintMode != BarbarianSprintMode.CombatOnly &&
                    Trinity.Hotbar.Contains(SNOPower.Barbarian_Whirlwind) && Trinity.ObjectCache.Any(u => u.IsUnit &&
                                                                                                     MathUtil.IntersectsPath(u.Position, u.Radius + 5f, Trinity.Player.Position, vMoveToTarget)) &&
                    Trinity.Player.PrimaryResource >= V.F("Barbarian.Whirlwind.MinFury") && !Trinity.IsWaitingForSpecial && V.B("Barbarian.Whirlwind.UseForMovement"))
                {
                    ZetaDia.Me.UsePower(SNOPower.Barbarian_Whirlwind, vMoveToTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.Barbarian_Whirlwind);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Whirlwind for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }

                // Leap movement for a barb
                if (Trinity.Settings.Combat.Barbarian.UseLeapOOC && Trinity.Hotbar.Contains(SNOPower.Barbarian_Leap) &&
                    PowerManager.CanCast(SNOPower.Barbarian_Leap) && !ShrinesInArea(vMoveToTarget))
                {
                    Vector3 vThisTarget = vMoveToTarget;
                    if (destinationDistance > 35f)
                    {
                        vThisTarget = MathEx.CalculatePointFrom(vMoveToTarget, MyPosition, 35f);
                    }
                    ZetaDia.Me.UsePower(SNOPower.Barbarian_Leap, vThisTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.Barbarian_Leap);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Leap for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }
                // Furious Charge movement for a barb
                if (Trinity.Settings.Combat.Barbarian.UseChargeOOC && Trinity.Hotbar.Contains(SNOPower.Barbarian_FuriousCharge) && !bTooMuchZChange &&
                    destinationDistance >= 20f &&
                    PowerManager.CanCast(SNOPower.Barbarian_FuriousCharge) && !ShrinesInArea(vMoveToTarget))
                {
                    Vector3 vThisTarget = vMoveToTarget;
                    if (destinationDistance > 35f)
                    {
                        vThisTarget = MathEx.CalculatePointFrom(vMoveToTarget, MyPosition, 35f);
                    }
                    ZetaDia.Me.UsePower(SNOPower.Barbarian_FuriousCharge, vThisTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.Barbarian_FuriousCharge);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Furious Charge for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }

                bool hasTacticalAdvantage = HotbarSkills.PassiveSkills.Any(s => s == SNOPower.DemonHunter_Passive_TacticalAdvantage);
                int  vaultDelay           = hasTacticalAdvantage ? 2000 : Trinity.Settings.Combat.DemonHunter.VaultMovementDelay;

                // DemonHunter Vault
                if (Trinity.Hotbar.Contains(SNOPower.DemonHunter_Vault) && !bTooMuchZChange && Trinity.Settings.Combat.DemonHunter.VaultMode != DemonHunterVaultMode.CombatOnly &&
                    CombatBase.TimeSincePowerUse(SNOPower.DemonHunter_Vault) > vaultDelay &&
                    destinationDistance >= 18f &&
                    PowerManager.CanCast(SNOPower.DemonHunter_Vault) && !ShrinesInArea(vMoveToTarget) &&
                    // Don't Vault into avoidance/monsters if we're kiting
                    (CombatBase.PlayerKiteDistance <= 0 || (CombatBase.PlayerKiteDistance > 0 &&
                                                            (!CacheData.TimeBoundAvoidance.Any(a => a.Position.Distance(vMoveToTarget) <= CombatBase.PlayerKiteDistance) ||
                                                             (!CacheData.TimeBoundAvoidance.Any(a => MathEx.IntersectsPath(a.Position, a.Radius, Trinity.Player.Position, vMoveToTarget))) ||
                                                             !CacheData.MonsterObstacles.Any(a => a.Position.Distance(vMoveToTarget) <= CombatBase.PlayerKiteDistance))))
                    )
                {
                    Vector3 vThisTarget = vMoveToTarget;
                    if (destinationDistance > 35f)
                    {
                        vThisTarget = MathEx.CalculatePointFrom(vMoveToTarget, MyPosition, 35f);
                    }
                    ZetaDia.Me.UsePower(SNOPower.DemonHunter_Vault, vThisTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.DemonHunter_Vault);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Vault for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }
                // Tempest rush for a monk
                if (Trinity.Hotbar.Contains(SNOPower.Monk_TempestRush) &&
                    (Trinity.Settings.Combat.Monk.TROption == TempestRushOption.MovementOnly || Trinity.Settings.Combat.Monk.TROption == TempestRushOption.Always ||
                     (Trinity.Settings.Combat.Monk.TROption == TempestRushOption.TrashOnly && !TargetUtil.AnyElitesInRange(40f))))
                {
                    Vector3 vTargetAimPoint = vMoveToTarget;

                    bool canRayCastTarget = true;

                    vTargetAimPoint = TargetUtil.FindTempestRushTarget();

                    if (!CanChannelTempestRush &&
                        ((Trinity.Player.PrimaryResource >= Trinity.Settings.Combat.Monk.TR_MinSpirit &&
                          destinationDistance >= Trinity.Settings.Combat.Monk.TR_MinDist) ||
                         DateTime.UtcNow.Subtract(CacheData.AbilityLastUsed[SNOPower.Monk_TempestRush]).TotalMilliseconds <= 150) &&
                        canRayCastTarget && PowerManager.CanCast(SNOPower.Monk_TempestRush))
                    {
                        CanChannelTempestRush = true;
                    }
                    else if ((CanChannelTempestRush && (Trinity.Player.PrimaryResource < 10f)) || !canRayCastTarget)
                    {
                        CanChannelTempestRush = false;
                    }

                    double lastUse = DateTime.UtcNow.Subtract(CacheData.AbilityLastUsed[SNOPower.Monk_TempestRush]).TotalMilliseconds;

                    if (CanChannelTempestRush)
                    {
                        if (Trinity.SNOPowerUseTimer(SNOPower.Monk_TempestRush))
                        {
                            LastTempestRushPosition = vTargetAimPoint;

                            ZetaDia.Me.UsePower(SNOPower.Monk_TempestRush, vTargetAimPoint, Trinity.CurrentWorldDynamicId, -1);
                            SpellHistory.RecordSpell(SNOPower.Monk_TempestRush);

                            // simulate movement speed of 30
                            SpeedSensor lastSensor = SpeedSensors.OrderByDescending(s => s.Timestamp).FirstOrDefault();
                            SpeedSensors.Add(new SpeedSensor()
                            {
                                Location          = MyPosition,
                                TimeSinceLastMove = new TimeSpan(0, 0, 0, 0, 1000),
                                Distance          = 5f,
                                WorldID           = Trinity.CurrentWorldDynamicId
                            });

                            if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                            {
                                Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Tempest Rush for OOC movement, distance={0:0} spirit={1:0} cd={2} lastUse={3:0} V3={4} vAim={5}",
                                           destinationDistance, Trinity.Player.PrimaryResource, PowerManager.CanCast(SNOPower.Monk_TempestRush), lastUse, vMoveToTarget, vTargetAimPoint);
                            }
                            return;
                        }
                        else
                        {
                            return;
                        }
                    }
                    else
                    {
                        if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                        {
                            Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement,
                                       "Tempest rush failed!: {0:00.0} / {1} distance: {2:00.0} / {3} Raycast: {4} MS: {5:0.0} lastUse={6:0}",
                                       Trinity.Player.PrimaryResource,
                                       Trinity.Settings.Combat.Monk.TR_MinSpirit,
                                       destinationDistance,
                                       Trinity.Settings.Combat.Monk.TR_MinDist,
                                       canRayCastTarget,
                                       GetMovementSpeed(),
                                       lastUse);
                        }

                        Trinity.MaintainTempestRush = false;
                    }

                    // Always set this from PlayerMover
                    Trinity.LastTempestRushLocation = vTargetAimPoint;
                }

                // Dashing Strike OOC
                if (CombatBase.CanCast(SNOPower.X1_Monk_DashingStrike) && Trinity.Settings.Combat.Monk.UseDashingStrikeOOC && destinationDistance > 15f)
                {
                    ZetaDia.Me.UsePower(SNOPower.X1_Monk_DashingStrike, vMoveToTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.X1_Monk_DashingStrike);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Dashing Strike for OOC movement, distance={0}", destinationDistance);
                    }
                }


                bool hasWormHole = HotbarSkills.AssignedSkills.Any(s => s.Power == SNOPower.Wizard_Teleport && s.RuneIndex == 4);
                bool hasCalamity = HotbarSkills.AssignedSkills.Any(s => s.Power == SNOPower.Wizard_Teleport && s.RuneIndex == 0);

                // Teleport for a wizard
                if (!hasCalamity && CombatBase.CanCast(SNOPower.Wizard_Teleport, CombatBase.CanCastFlags.NoTimer) &&
                    CombatBase.TimeSincePowerUse(SNOPower.Wizard_Teleport) > 250 &&
                    destinationDistance >= 10f && !ShrinesInArea(vMoveToTarget))
                {
                    var maxTeleportRange = 75f;

                    Vector3 vThisTarget = vMoveToTarget;
                    if (destinationDistance > maxTeleportRange)
                    {
                        vThisTarget = MathEx.CalculatePointFrom(vMoveToTarget, MyPosition, maxTeleportRange);
                    }
                    ZetaDia.Me.UsePower(SNOPower.Wizard_Teleport, vThisTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.Wizard_Teleport);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Teleport for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }
                // Archon Teleport for a wizard
                if (Trinity.Hotbar.Contains(SNOPower.Wizard_Archon_Teleport) &&
                    DateTime.UtcNow.Subtract(CacheData.AbilityLastUsed[SNOPower.Wizard_Archon_Teleport]).TotalMilliseconds >= CombatBase.GetSNOPowerUseDelay(SNOPower.Wizard_Archon_Teleport) &&
                    destinationDistance >= 20f &&
                    PowerManager.CanCast(SNOPower.Wizard_Archon_Teleport) && !ShrinesInArea(vMoveToTarget))
                {
                    Vector3 vThisTarget = vMoveToTarget;
                    if (destinationDistance > 35f)
                    {
                        vThisTarget = MathEx.CalculatePointFrom(vMoveToTarget, MyPosition, 35f);
                    }
                    ZetaDia.Me.UsePower(SNOPower.Wizard_Archon_Teleport, vThisTarget, Trinity.CurrentWorldDynamicId, -1);
                    SpellHistory.RecordSpell(SNOPower.Wizard_Archon_Teleport);
                    if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                    {
                        Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Using Archon Teleport for OOC movement, distance={0}", destinationDistance);
                    }
                    return;
                }
            }

            if (MyPosition.Distance2D(vMoveToTarget) > 1f)
            {
                // Default movement
                ZetaDia.Me.UsePower(SNOPower.Walk, vMoveToTarget, Trinity.CurrentWorldDynamicId, -1);

                if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                {
                    Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Moved to:{0} dir:{1} Speed:{2:0.00} Dist:{3:0} ZDiff:{4:0} CanStand:{5} Raycast:{6}",
                               NavHelper.PrettyPrintVector3(vMoveToTarget), MathUtil.GetHeadingToPoint(vMoveToTarget), MovementSpeed, MyPosition.Distance2D(vMoveToTarget),
                               Math.Abs(MyPosition.Z - vMoveToTarget.Z),
                               Trinity.MainGridProvider.CanStandAt(Trinity.MainGridProvider.WorldToGrid(vMoveToTarget.ToVector2())),
                               !Navigator.Raycast(MyPosition, vMoveToTarget)
                               );
                }
            }
            else
            {
                if (Trinity.Settings.Advanced.LogCategories.HasFlag(LogCategory.Movement))
                {
                    Logger.Log(TrinityLogLevel.Debug, LogCategory.Movement, "Reached MoveTowards Destination {0} Current Speed: {1:0.0}", vMoveToTarget, MovementSpeed);
                }
            }
        }
        public bool ShouldStashItem(ACDItem item, ItemEvaluationType evaluationType)
        {
            ItemEvents.ResetTownRun();

            if (Current.ItemIsProtected(item))
            {
                return(false);
            }

            // Vanity Items
            if (DataDictionary.VanityItems.Any(i => item.InternalName.StartsWith(i)))
            {
                return(false);
            }

            if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.DemonBuddy)
            {
                return(Current.ShouldStashItem(item));
            }

            CachedACDItem cItem = CachedACDItem.GetCachedItem(item);

            // Now look for Misc items we might want to keep
            GItemType     tItemType = cItem.TrinityItemType;     // DetermineItemType(cItem.InternalName, cItem.DBItemType, cItem.FollowerType);
            GItemBaseType tBaseType = cItem.TrinityItemBaseType; // DetermineBaseType(trinityItemType);

            bool isEquipment = (tBaseType == GItemBaseType.Armor ||
                                tBaseType == GItemBaseType.Jewelry ||
                                tBaseType == GItemBaseType.Offhand ||
                                tBaseType == GItemBaseType.WeaponOneHand ||
                                tBaseType == GItemBaseType.WeaponRange ||
                                tBaseType == GItemBaseType.WeaponTwoHand);

            if (cItem.TrinityItemType == GItemType.HoradricCache && Trinity.Settings.Loot.TownRun.OpenHoradricCaches)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] = (ignoring Horadric Cache)", cItem.RealName, cItem.InternalName);
                return(false);
            }

            // Stash all unidentified items - assume we want to keep them since we are using an identifier over-ride
            if (cItem.IsUnidentified)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] = (autokeep unidentified items)", cItem.RealName, cItem.InternalName);
                }
                return(true);
            }
            if (tItemType == GItemType.StaffOfHerding)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep staff of herding)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }
            if (tItemType == GItemType.CraftingMaterial)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep craft materials)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }

            if (tItemType == GItemType.Emerald || tItemType == GItemType.Amethyst || tItemType == GItemType.Topaz || tItemType == GItemType.Ruby || tItemType == GItemType.Diamond)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep gems)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }
            if (tItemType == GItemType.CraftTome)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (autokeep tomes)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }
            if (tItemType == GItemType.InfernalKey)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep infernal key)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }

            if (tItemType == GItemType.HealthPotion)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.ItemValuation, "{0} [{1}] [{2}] = (ignoring potions)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(false);
            }

            if (tItemType == GItemType.CraftingPlan && cItem.Quality >= ItemQuality.Legendary)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep legendary plans)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }

            if (Trinity.Settings.Loot.ItemFilterMode == ItemFilterMode.TrinityWithItemRules)
            {
                Interpreter.InterpreterAction action = Trinity.StashRule.checkItem(item, evaluationType);

                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (" + action + ")", cItem.AcdItem.Name, cItem.AcdItem.InternalName, cItem.AcdItem.ItemType);
                }
                switch (action)
                {
                case Interpreter.InterpreterAction.KEEP:
                    return(true);

                case Interpreter.InterpreterAction.TRASH:
                    return(false);

                case Interpreter.InterpreterAction.SCORE:
                    break;
                }
            }

            if (tItemType == GItemType.CraftingPlan)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep plans)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }

            // Stashing Whites, auto-keep
            if (Trinity.Settings.Loot.TownRun.StashWhites && isEquipment && cItem.Quality <= ItemQuality.Superior)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (stashing whites)", cItem.RealName, cItem.InternalName, tItemType);
                return(true);
            }
            // Else auto-trash
            if (cItem.Quality <= ItemQuality.Superior && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem))
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (trash whites)", cItem.RealName, cItem.InternalName, tItemType);
                return(false);
            }

            // Stashing blues, auto-keep
            if (Trinity.Settings.Loot.TownRun.StashBlues && isEquipment && cItem.Quality >= ItemQuality.Magic1 && cItem.Quality <= ItemQuality.Magic3)
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (stashing blues)", cItem.RealName, cItem.InternalName, tItemType);
                return(true);
            }
            // Else auto trash
            if (cItem.Quality >= ItemQuality.Magic1 && cItem.Quality <= ItemQuality.Magic3 && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem))
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (trashing blues)", cItem.RealName, cItem.InternalName, tItemType);
                return(false);
            }

            // Force salvage Rares
            if (Trinity.Settings.Loot.TownRun.ForceSalvageRares && cItem.Quality >= ItemQuality.Rare4 && cItem.Quality <= ItemQuality.Rare6 && (isEquipment || cItem.TrinityItemBaseType == GItemBaseType.FollowerItem))
            {
                Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (force salvage rare)", cItem.RealName, cItem.InternalName, tItemType);
                return(false);
            }

            if (cItem.Quality >= ItemQuality.Legendary)
            {
                if (evaluationType == ItemEvaluationType.Keep)
                {
                    Logger.Log(TrinityLogLevel.Info, LogCategory.UserInformation, "{0} [{1}] [{2}] = (autokeep legendaries)", cItem.RealName, cItem.InternalName, tItemType);
                }
                return(true);
            }

            // Ok now try to do some decent item scoring based on item types
            double iNeedScore = Trinity.ScoreNeeded(item.ItemBaseType);
            double iMyScore   = ItemValuation.ValueThisItem(cItem, tItemType);

            if (evaluationType == ItemEvaluationType.Keep)
            {
                Logger.Log(TrinityLogLevel.Verbose, LogCategory.ItemValuation, "{0} [{1}] [{2}] = {3}", cItem.RealName, cItem.InternalName, tItemType, iMyScore);
            }
            if (iMyScore >= iNeedScore)
            {
                return(true);
            }

            // If we reached this point, then we found no reason to keep the item!
            return(false);
        }