Пример #1
0
        public static async Task <bool> EnsureSalvageWindow()
        {
            var blacksmith = TownInfo.BlacksmithSalvage;

            if (blacksmith == null)
            {
                Core.Logger.Error("[SalvageItems] Unable to find a blacksmith info for this area :(");
                return(false);
            }

            while (!UIElements.SalvageWindow.IsVisible)
            {
                var blacksmithNpc = TownInfo.Blacksmith;
                if (blacksmithNpc != null)
                {
                    Core.DBGridProvider.AddCellWeightingObstacle(blacksmithNpc.ActorId, 4);
                }

                if (!await MoveTo.Execute(blacksmith.InteractPosition))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to blacksmith interact position ({blacksmith.Name}) to salvage items :(");
                    return(false);
                }
                ;

                if (!await MoveToAndInteract.Execute(blacksmith, 10f))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to blacksmith ({blacksmith.Name}) to salvage items :(");
                    return(false);
                }
                ;
                await Coroutine.Wait(2000, () => UIElements.SalvageWindow.IsVisible);
            }
            return(true);
        }
Пример #2
0
        public static async Task <bool> Execute()
        {
            if (ZetaDia.Me.IsInCombat)
            {
                Core.Logger.Debug("[ReturnToStash] Cannot return to stash while in combat");
                return(false);
            }

            if (!ZetaDia.IsInTown && ZetaDia.Me.IsFullyValid() && !ZetaDia.Me.IsInCombat && UIElements.BackgroundScreenPCButtonRecall.IsEnabled)
            {
                StartedOutOfTown = true;
                await CommonCoroutines.UseTownPortal("[ReturnToStash] Returning to stash");

                return(true);
            }

            if (!GameUI.IsElementVisible(GameUI.StashDialogMainPage) && ZetaDia.IsInTown)
            {
                GameUI.CloseVendorWindow();

                if (TownInfo.Stash.Distance > 10f)
                {
                    if (!await MoveToAndInteract.Execute(TownInfo.Stash.GetActor()))
                    {
                        return(true);
                    }
                }
            }
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Move to Kanai's cube and transmute.
        /// </summary>
        public static async Task <bool> Execute(IEnumerable <int> transmuteGroupAnnIds, TransmuteRecipe recipe)
        {
            if (!ZetaDia.IsInGame)
            {
                return(false);
            }

            Core.Logger.Log("Transmuting...");

            if (!Core.Inventory.Currency.HasCurrency(recipe))
            {
                Core.Logger.Error($"--> Not enough currency for {recipe}");
                return(false);
            }

            if (!UIElements.TransmuteItemsDialog.IsVisible)
            {
                await MoveToAndInteract.Execute(TownInfo.KanaisCube);

                await Coroutine.Sleep(1000);
            }

            if (!UIElements.TransmuteItemsDialog.IsVisible)
            {
                Core.Logger.Log(" --> Can't transmute without the vendor window open!");
                return(false);
            }

            Core.Logger.Log("Zip Zap!");
            InventoryManager.TransmuteItems(transmuteGroupAnnIds.ToArray(), recipe);
            await Coroutine.Sleep(Randomizer.Fudge(500));

            UIElement.FromHash(TransmuteButtonHash)?.Click();
            return(true);
        }
Пример #4
0
        private async Task <bool> Interacting()
        {
            //if (_interactionCoroutine.State == InteractionCoroutine.States.NotStarted)
            //{
            //    var portalGizmo = BountyHelpers.GetPortalNearMarkerPosition(_markerPosition);
            //    if (portalGizmo == null)
            //    {
            //        Core.Logger.Debug("[Bounty] No portal nearby, keep exploring .");
            //        State = States.SearchingForDestinationWorld;
            //        return false;
            //    }
            //    _interactionCoroutine.DiaObject = portalGizmo;
            //}

            Core.Logger.Debug("[InteractWithGizmo] Starting interaction subroutine.");

            if (await _interactionCoroutine.GetCoroutine())
            {
                ActorFinder.InteractWhitelist.Remove(_actorId);
                if (_interactionCoroutine.State == InteractionCoroutine.States.TimedOut)
                {
                    Core.Logger.Error("[InteractWithGizmo] Interaction timed out.");
                    State = States.Failed;
                    return(false);
                }

                if (_useAll)
                {
                    var nextGizmo = ActorFinder.FindGizmo(_actorId, gizmo => gizmo.IsInteractableQuestObject());
                    if (nextGizmo != null)
                    {
                        Core.Logger.Warn("Found another actor that needs some interaction. Dist={0}", nextGizmo.Distance);
                        State = States.Searching;
                        return(false);
                    }
                }

                var actor = ActorFinder.FindGizmo(_actorId);
                if (actor == null)
                {
                    Core.Logger.Log($"No Gizmo Found.");
                    State = States.Failed;
                    return(false);
                }

                if (await(MoveToAndInteract.Execute(actor)))
                {
                    State = States.Completed;
                    _interactionCoroutine = null;
                    return(false);
                }
            }
            return(false);
        }
Пример #5
0
        public static async Task <bool> TakeReturnPortal()
        {
            if (!ZetaDia.IsInTown)
            {
                return(false);
            }

            var portalRef = TownInfo.ReturnPortal;
            var actor     = portalRef?.GetActor();

            if (actor == null || !actor.IsFullyValid())
            {
                Core.Logger.Debug("Couldn't find a return portal");
                return(false);
            }

            Core.Logger.Log("Found a hearth portal, lets use it.");

            if (!await MoveToAndInteract.Execute(actor, 2f, 10))
            {
                Core.Logger.Log("Failed to move to return portal :(");
                return(false);
            }

            Core.PlayerMover.MoveStop();

            if (actor.IsFullyValid() && !actor.Interact())
            {
                Core.Logger.Debug("Failed to interact with return portal.");
            }

            await Coroutine.Sleep(1000);

            if (ZetaDia.IsInTown && !ZetaDia.Globals.IsLoadingWorld)
            {
                Core.Logger.Log("Trying again to use return portal.");
                var gizmo = ZetaDia.Actors.GetActorsOfType <DiaGizmo>().FirstOrDefault(g => g.ActorInfo.GizmoType == GizmoType.HearthPortal);
                if (gizmo != null)
                {
                    await CommonCoroutines.MoveAndStop(gizmo.Position, 2f, "Portal Position");

                    await Coroutine.Sleep(1000);

                    gizmo.Interact();
                    gizmo.Interact();
                }
            }

            await Coroutine.Wait(5000, () => !ZetaDia.Globals.IsLoadingWorld);

            return(true);
        }
Пример #6
0
        public static async Task <bool> TakeItemsFromStash(List <ACDItem> stashCandidates)
        {
            if (!ZetaDia.IsInGame ||
                !ZetaDia.IsInTown)
            {
                return(false);
            }

            if (TownInfo.Stash.Distance > 3f)
            {
                await MoveToAndInteract.Execute(TownInfo.Stash);
            }

            var stash = TownInfo.Stash?.GetActor();

            if (stash == null)
            {
                Core.Logger.Log("[TakeItemsFromStash] Unable to find Stash");
                return(false);
            }

            if (!UIElements.StashWindow.IsVisible &&
                TownInfo.Stash.Distance <= 10f)
            {
                Core.Logger.Log("[TakeItemsFromStash] Stash window not open, interacting");
                stash.Interact();
            }

            foreach (var item in stashCandidates)
            {
                try
                {
                    if (!item.IsValid)
                    {
                        Core.Logger.Verbose("[TakeItemsFromStash] An ACDItem was invalid, unable to remove it from stash.");
                        continue;
                    }

                    Core.Logger.Verbose($"[TakeItemsFromStash] QuickWithdrawing: {item.InternalName} Id={item.ActorSnoId} AnnId={item.AnnId} Name={item.Name} Quality={item.ItemQualityLevel} IsAncient={item.Stats.IsAncient}");
                    InventoryManager.QuickWithdraw(item);
                }
                catch (Exception ex)
                {
                    Core.Logger.Error(ex.ToString());
                }
            }

            await Coroutine.Yield();

            return(true);
        }
Пример #7
0
        //public static async Task<bool> Execute(List<ACDItem> stashCandidates)
        //{
        //    if (!ZetaDia.IsInGame || !ZetaDia.IsInTown)
        //        return false;

        //    if (TownInfo.Stash.Distance > 3f)
        //    {
        //        await MoveToAndInteract.Execute(TownInfo.Stash);
        //    }

        //    var stash = TownInfo.Stash?.GetActor();
        //    if (stash == null)
        //    {
        //        Core.Logger.Log("[PutItemsInStash] Unable to find Stash");
        //        return false;
        //    }

        //    if (!UIElements.StashWindow.IsVisible && TownInfo.Stash.Distance <= 10f)
        //    {
        //        Core.Logger.Log("[PutItemsInStash] Stash window not open, interacting");
        //        stash.Interact();
        //    }

        //    foreach (var item in stashCandidates)
        //    {
        //        try
        //        {
        //            if (!item.IsValid || item.IsDisposed)
        //            {
        //                Core.Logger.Verbose("[PutItemsInStash] An ACDItem was invalid, unable to put it in stash.");
        //                continue;
        //            }

        //            Core.Logger.Log($"[PutItemsInStash] Adding {item.Name} ({item.ActorSnoId}) to stash. StackSize={item.ItemStackQuantity} AnnId={item.AnnId} InternalName={item.InternalName} Id={item.ActorSnoId} Quality={item.ItemQualityLevel} AncientRank={item.AncientRank}");
        //            InventoryManager.QuickStash(item);
        //        }
        //        catch (Exception ex)
        //        {
        //            Core.Logger.Error(ex.ToString());
        //        }
        //    }

        //    await Coroutine.Sleep(1000);
        //    Core.Logger.Log("[PutItemsInStash] Finished!");
        //    return true;
        //}

        public static async Task <bool> Execute(List <int> annIds)
        {
            if (!ZetaDia.IsInGame || !ZetaDia.IsInTown)
            {
                return(false);
            }

            if (TownInfo.Stash.Distance > 3f)
            {
                await MoveToAndInteract.Execute(TownInfo.Stash);
            }

            var stash = TownInfo.Stash?.GetActor();

            if (stash == null)
            {
                Core.Logger.Log("[PutItemsInStash] Unable to find Stash");
                return(false);
            }

            if (!UIElements.StashWindow.IsVisible && TownInfo.Stash.Distance <= 10f)
            {
                Core.Logger.Log("[PutItemsInStash] Stash window not open, interacting");
                stash.Interact();
            }

            foreach (var item in InventoryManager.Backpack.Where(i => annIds.Contains(i.AnnId)))
            {
                try
                {
                    if (!item.IsValid || item.IsDisposed)
                    {
                        Core.Logger.Verbose("[PutItemsInStash] An ACDItem was invalid, unable to put it in stash.");
                        continue;
                    }

                    Core.Logger.Log($"[PutItemsInStash] Adding {item.Name} ({item.ActorSnoId}) to stash. StackSize={item.ItemStackQuantity} AnnId={item.AnnId} InternalName={item.InternalName} Id={item.ActorSnoId} Quality={item.ItemQualityLevel} AncientRank={item.AncientRank}");
                    InventoryManager.QuickStash(item);
                }
                catch (Exception ex)
                {
                    Core.Logger.Error(ex.ToString());
                }
            }

            await Coroutine.Sleep(1000);

            return(true);
        }
Пример #8
0
        public static async Task <bool> Execute()
        {
            if (!ZetaDia.IsInTown)
            {
                Core.Logger.Verbose("[IdentifyItems] Need to be in town to identify items");
                return(false);
            }

            if (Core.Settings.Items.KeepLegendaryUnid)
            {
                Core.Logger.Verbose("[IdentifyItems] Town run setting 'Keep Legendary Unidentified' - Skipping ID");
                return(false);
            }

            var timeout = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30));

            var bookActor = TownInfo.BookOfCain;

            if (bookActor == null)
            {
                Core.Logger.Log($"[IdentifyItems] TownInfo.BookOfCain not found Act={ZetaDia.CurrentAct} WorldSnoId={ZetaDia.Globals.WorldSnoId}");
                return(false);
            }

            while (Core.Inventory.Backpack.Any(i => i.IsUnidentified))
            {
                if (DateTime.UtcNow > timeout)
                {
                    break;
                }

                Core.Logger.Log("Identifying Items");

                if (!Core.Grids.CanRayCast(ZetaDia.Me.Position, bookActor.Position))
                {
                    await MoveTo.Execute(TownInfo.NearestSafeSpot);
                }

                await MoveToAndInteract.Execute(bookActor);

                await Coroutine.Wait(8000, () => ZetaDia.Me.LoopingAnimationEndTime <= 0);
            }
            return(false);
        }
Пример #9
0
        private static async Task <bool> MoveToCube()
        {
            if (GameUI.KanaisCubeWindow.IsVisible)
            {
                return(true);
            }

            if (TownInfo.KanaisCube.Distance < 10f)
            {
                return(true);
            }

            if (TownInfo.KanaisCube.Distance > 350f || TownInfo.KanaisCube.Position == Vector3.Zero)
            {
                return(false);
            }

            return(await MoveToAndInteract.Execute(TownInfo.KanaisCube));
        }
Пример #10
0
        public static async Task <bool> Execute(List <ItemSelectionType> types = null)
        {
            if (!CanRun())
            {
                return(true);
            }

            Core.Logger.Verbose("[CubeItemsToMaterials] Time to Convert some junk into delicious crafting materials.");

            if (!await MoveToAndInteract.Execute(TownInfo.KanaisCube))
            {
                Core.Logger.Log("[CubeItemsToMaterials] Failed to move to the cube, quite unfortunate.");
                return(true);
            }

            // * Never create more of the material you have most of.
            // * Always use the material you have most of to create others.
            // * Only allow creation of a material if it has been selected in settings.

            var settingsTypes = Core.Settings.KanaisCube.GetCraftingMaterialTypes();
            var allTypes      = GetAllConversionTypes();
            var orderedTypes  = OrderByAmount(allTypes);
            var highestCount  = orderedTypes.First();
            var allowedTypes  = settingsTypes.Select(GetCurrencyType);
            var otherTypes    = orderedTypes.Skip(1).Where(t => allowedTypes.Contains(t)).ToList();

            foreach (var toType in otherTypes)
            {
                if (!await ConvertMaterials.Execute(highestCount, toType))
                {
                    Core.Logger.Log("[Cube] Failed! Finished!");
                    return(true);
                }
                await Coroutine.Sleep(100);

                await Coroutine.Yield();
            }

            Core.Logger.Verbose("[Cube] CubeItemsToMaterials Finished!");
            return(true);
        }
Пример #11
0
        public static async Task <bool> MoveToStash()
        {
            var stash = TownInfo.Stash;

            if (stash == null)
            {
                Core.Logger.Error("[StashItems] Unable to find a stash info for this area :(");
                return(false);
            }

            if (!UIElements.StashWindow.IsVisible)
            {
                if (!await MoveToAndInteract.Execute(stash))
                {
                    Core.Logger.Error($"[StashItems] Failed to move to stash ({stash.Name}) to salvage items :(");
                    return(false);
                }
                await Coroutine.Yield();
            }
            return(true);
        }
Пример #12
0
        private async Task <bool> Looting()
        {
            DisablePulse();
            var loots = ZetaDia.Actors.GetActorsOfType <DiaObject>(true).OrderBy(x => x.Distance).Where(x => x.IsFullyValid() && KeywardenDataFactory.KeyIds.Contains(x.ActorSnoId)).ToList();

            if (!loots.Any())
            {
                StatusText = "[Keywarden] No Loot!";
                Core.Logger.Log("[Keywarden] No Loot!");
                State = States.Completed;
                return(false);
            }
            foreach (var loot in loots)
            {
                if (await MoveToAndInteract.Execute(loot, 0, 5))
                {
                    return(true);
                }
                await Coroutine.Sleep(1000);
            }
            State = States.Completed;
            return(false);
        }
Пример #13
0
        public static async Task <bool> Execute(bool dontStashCraftingMaterials = false)
        {
            if (!ZetaDia.IsInTown)
            {
                Core.Logger.Verbose("[StashItems] Need to be in town to stash items");
                return(false);
            }

            var stashItems = Core.Inventory.Backpack.Where(ShouldStash).Where(i => AllowedToStash(dontStashCraftingMaterials, i)).ToList();

            if (!stashItems.Any())
            {
                Core.Logger.Verbose($"[StashItems] Nothing to stash");
                return(false);
            }

            Core.Logger.Verbose($"[StashItems] Now to stash {stashItems.Count} items");
            stashItems.ForEach(i => Core.Logger.Debug($"[StashItems] Stashing: {i.Name} ({i.ActorSnoId}) InternalName={i.InternalName} Ancient={i.IsAncient} Ann={i.AnnId}"));

            GameUI.CloseVendorWindow();

            await MoveToStash();

            if (!UIElements.StashWindow.IsVisible)
            {
                var stash = ZetaDia.Actors.GetActorsOfType <GizmoPlayerSharedStash>().FirstOrDefault();
                if (stash == null)
                {
                    return(false);
                }

                if (!await MoveTo.Execute(stash.Position))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to stash interact position ({stash.Name}) to stash items :(");
                    return(false);
                }
                ;
                Navigator.PlayerMover.MoveTowards(stash.Position);
                if (!await MoveToAndInteract.Execute(stash, 5f))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to stash ({stash.Name}) to stash items :(");
                    return(false);
                }
                ;
                await Coroutine.Yield();

                stash.Interact();
            }

            if (UIElements.StashWindow.IsVisible)
            {
                if (Core.Settings.Items.BuyStashTabs && StashPagesAvailableToPurchase)
                {
                    Core.Logger.Error("[StashItems] Attempting to buy stash pages");
                    InventoryManager.BuySharedStashSlots();
                }

                await StackRamaladnisGift();
                await StackCraftingMaterials();

                var isStashFull = false;

                // Get items again to make sure they are valid and current this tick
                var freshItems = Core.Inventory.Backpack.Where(ShouldStash).Where(i => AllowedToStash(dontStashCraftingMaterials, i)).ToList();
                if (!freshItems.Any())
                {
                    Core.Logger.Verbose($"[StashItems] No items to stash");
                }
                else
                {
                    foreach (var item in freshItems)
                    {
                        try
                        {
                            item.OnUpdated(); // make sure wrong col/row/location is not cached after a move.

                            var page = GetBestStashLocation(item, out var col, out var row);
                            if (page == -1)
                            {
                                Core.Logger.Verbose($"[StashItems] No place to put item, stash is probably full ({item.Name} [{col},{row}] Page={page})");
                                HandleFullStash();
                                isStashFull = true;
                                continue;
                            }

                            if (page != InventoryManager.CurrentStashPage)
                            {
                                Core.Logger.Verbose($"[StashItems] Changing to stash page: {page}");
                                InventoryManager.SwitchStashPage(page);
                                await Coroutine.Yield();
                            }

                            Core.Logger.Debug($"[StashItems] Stashing: {item.Name} ({item.ActorSnoId}) [{item.InventoryColumn},{item.InventoryRow} {item.InventorySlot}] Quality={item.ItemQualityLevel} IsAncient={item.IsAncient} InternalName={item.InternalName} StashPage={page}");
                            InventoryManager.MoveItem(item.AnnId, Core.Player.MyDynamicID, InventorySlot.SharedStash, col, row);
                            await Coroutine.Yield();

                            Core.Actors.Update();

                            await Coroutine.Wait(5000, () => !item.IsValid || item.InventoryRow == row && item.InventoryColumn == col);

                            ItemEvents.FireItemStashed(item);
                        }
                        catch (Exception ex)
                        {
                            Core.Logger.Log($"Exception Stashing Item: {ex}");
                        }
                    }
                }

                await Coroutine.Yield();

                await RepairItems.Execute();

                if (isStashFull)
                {
                    return(false);
                }

                return(true);
            }

            Core.Logger.Error($"[StashItems] Failed to stash items");
            return(false);
        }
Пример #14
0
        public static async Task <bool> Execute()
        {
            if (DateTime.UtcNow < CooldownExpires)
            {
                Logger.LogVerbose("[UseCraftingRecipes] On cooldown after behavior timeout");
                return(true);
            }

            LastStartTime = DateTime.UtcNow;

            while (true)
            {
                await Coroutine.Yield();

                if (!ZetaDia.IsInTown)
                {
                    break;
                }

                // No Plans
                if (!Inventory.OfType(InventoryItemType.BlackSmithPlan, InventoryItemType.JewelerPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] No Jeweler or Blacksmith Plans");
                    break;
                }

                // Timeout
                if (DateTime.UtcNow.Subtract(LastStartTime).TotalSeconds > TimeoutSeconds)
                {
                    Logger.LogVerbose("[UseCraftingRecipes] {0} Second Timeout", TimeoutSeconds);
                    CooldownExpires = DateTime.UtcNow.AddSeconds(60);
                    break;
                }

                // Use all the blacksmith plans
                while (GameUI.IsBlackSmithWindowOpen && Inventory.Backpack.OfType(InventoryItemType.BlackSmithPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] Using Blacksmith Plans");

                    ZetaDia.Me.Inventory.UseItem(Inventory.Backpack.OfType(InventoryItemType.BlackSmithPlan).First().DynamicId);
                    await Coroutine.Sleep(25);
                }

                // Move to Blacksmith.
                if (!GameUI.IsBlackSmithWindowOpen && Inventory.Backpack.OfType(InventoryItemType.BlackSmithPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] Moving to Blacksmith");

                    if (!await MoveToAndInteract.Execute(Town.Locations.BlackSmith, Town.ActorIds.BlackSmith))
                    {
                        Logger.LogVerbose("[UseCraftingRecipes] Failed to move to Blacksmith");
                        return(true);
                    }

                    continue;
                }

                // Use all the Jeweller plans
                while (GameUI.IsJewelerWindowOpen && Inventory.Backpack.OfType(InventoryItemType.JewelerPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] Using Jeweler Plans");

                    ZetaDia.Me.Inventory.UseItem(Inventory.Backpack.OfType(InventoryItemType.JewelerPlan).First().DynamicId);
                    await Coroutine.Sleep(25);
                }

                // Move to Jeweller.
                if (!GameUI.IsJewelerWindowOpen && Inventory.Backpack.OfType(InventoryItemType.JewelerPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] Moving to Jeweler");

                    if (!await MoveToAndInteract.Execute(Town.Locations.Jeweler, Town.ActorIds.Jeweler))
                    {
                        Logger.LogVerbose("[UseCraftingRecipes] Failed to move to Jeweler");
                        return(true);
                    }

                    continue;
                }

                // Move to Stash
                if (Inventory.Stash.OfType(InventoryItemType.BlackSmithPlan, InventoryItemType.JewelerPlan).Any())
                {
                    Logger.LogVerbose("[UseCraftingRecipes] Getting Plans from Stash");

                    var plans   = Inventory.OfType(InventoryItemType.BlackSmithPlan, InventoryItemType.JewelerPlan);
                    var amount  = Math.Min(ZetaDia.Me.Inventory.NumFreeBackpackSlots, plans.Count);
                    var planIds = plans.Select(i => i.ActorSNO).Distinct();
                    if (!await TakeItemsFromStash.Execute(planIds, amount))
                    {
                        Logger.LogVerbose("[UseCraftingRecipes] Failed to get items from Stash");
                        return(true);
                    }
                }
            }

            Logger.Log("[UseCraftingRecipes] Finished!");
            return(true);
        }
Пример #15
0
        /// <summary>
        /// Moves items from the Stash to the Backpack
        /// </summary>
        /// <param name="itemIds">list of items to withdraw</param>
        /// <param name="maxAmount">amount to withdraw up to (including counts already in backpack)</param>
        /// <returns></returns>
        public static async Task <bool> Execute(IEnumerable <int> itemIds, int maxAmount)
        {
            if (!ZetaDia.IsInGame || !ZetaDia.IsInTown)
            {
                return(true);
            }

            if (TownInfo.Stash.Distance > 20f)
            {
                await MoveTo.Execute(TownInfo.Stash.InteractPosition);
            }

            var stash = TownInfo.Stash?.GetActor();

            if (stash == null)
            {
                Core.Logger.Log("[TakeItemsFromStash] Unable to find Stash");
                return(false);
            }

            if (!UIElements.StashWindow.IsVisible && TownInfo.Stash.Distance <= 10f)
            {
                await MoveToAndInteract.Execute(TownInfo.Stash);
            }

            if (!UIElements.StashWindow.IsVisible && TownInfo.Stash.Distance <= 10f)
            {
                Core.Logger.Log("[TakeItemsFromStash] Stash window not open, interacting");
                stash.Interact();
            }

            var itemIdsHashSet  = new HashSet <int>(itemIds);
            var amountWithdrawn = itemIdsHashSet.ToDictionary(k => k, v => (long)0);
            var overageTaken    = itemIdsHashSet.ToDictionary(k => k, v => false);
            var lastStackTaken  = itemIdsHashSet.ToDictionary(k => k, v => default(ACDItem));

            foreach (var item in InventoryManager.Backpack.Where(i => i.ACDId != 0 && i.IsValid && itemIdsHashSet.Contains(i.ActorSnoId)).ToList())
            {
                amountWithdrawn[item.ActorSnoId] += item.ItemStackQuantity;
                lastStackTaken[item.ActorSnoId]   = item;
            }

            foreach (var item in InventoryManager.StashItems.Where(i => i.ACDId != 0 && i.IsValid && itemIdsHashSet.Contains(i.ActorSnoId)).ToList())
            {
                try
                {
                    if (!item.IsValid || item.IsDisposed)
                    {
                        continue;
                    }

                    var stackSize       = Math.Max(1, item.ItemStackQuantity);
                    var numTakenAlready = amountWithdrawn[item.ActorSnoId];

                    // We have enough of this material already
                    var alreadyTakenEnough = numTakenAlready >= maxAmount;
                    if (alreadyTakenEnough)
                    {
                        continue;
                    }

                    // We have enough of everything already.
                    if (amountWithdrawn.All(i => i.Value >= maxAmount))
                    {
                        break;
                    }

                    // Only take up to the required amount.
                    var willBeOverMax = numTakenAlready + stackSize > maxAmount;
                    if (!willBeOverMax || !overageTaken[item.ActorSnoId])
                    {
                        var lastItem            = lastStackTaken[item.ActorSnoId];
                        var amountRequiredToMax = maxAmount - numTakenAlready;

                        if (willBeOverMax && lastItem != null && lastItem.IsValid && !lastItem.IsDisposed && stackSize > amountRequiredToMax)
                        {
                            // Tried InventoryManager.SplitStack but it didnt work, reverting to moving onto existing stacks.

                            var amountToSplit = stackSize - lastItem.ItemStackQuantity;
                            Core.Logger.Log($"[TakeItemsFromStash] Merging Stash Stack {item.Name} ({item.ActorSnoId}) onto Backpack Stack. StackSize={amountToSplit} WithdrawnAlready={numTakenAlready} InternalName={item.InternalName} Id={item.ActorSnoId} Quality={item.ItemQualityLevel} AncientRank={item.AncientRank}");

                            InventoryManager.MoveItem(item.AnnId, ZetaDia.Me.CommonData.AnnId, InventorySlot.BackpackItems, lastItem.InventoryColumn, lastItem.InventoryRow);

                            amountWithdrawn[item.ActorSnoId] += amountToSplit;
                            overageTaken[item.ActorSnoId]     = true;
                        }
                        else
                        {
                            if (item.IsValid && !item.IsDisposed)
                            {
                                Core.Logger.Log($"[TakeItemsFromStash] Removing {item.Name} ({item.ActorSnoId}) from stash. StackSize={stackSize} WithdrawnAlready={numTakenAlready} InternalName={item.InternalName} Id={item.ActorSnoId} AnnId={item.AnnId} Quality={item.ItemQualityLevel} AncientRank={item.AncientRank}");

                                // Quick withdraw broken?
                                //InventoryManager.QuickWithdraw(item);

                                var newPosition = TrinityCombat.Loot.FindBackpackSlot(item.IsTwoSquareItem);
                                InventoryManager.MoveItem(item.AnnId, ZetaDia.Me.CommonData.AnnId, InventorySlot.BackpackItems, (int)newPosition.X, (int)newPosition.Y);

                                amountWithdrawn[item.ActorSnoId] += stackSize;
                                lastStackTaken[item.ActorSnoId]   = item;
                            }
                        }

                        await Coroutine.Sleep(25);

                        await Coroutine.Yield();
                    }
                }
                catch (Exception ex)
                {
                    Core.Logger.Error(ex.ToString());
                }
            }

            await Coroutine.Sleep(1000);

            return(true);
        }
Пример #16
0
        public static async Task <bool> Execute()
        {
            if (!ZetaDia.IsInTown)
            {
                Core.Logger.Verbose("[SalvageItems] Need to be in town to salvage items");
                return(false);
            }

            var salvageItems = Core.Inventory.Backpack.Where(ShouldSalvage).ToList();

            if (!salvageItems.Any())
            {
                Core.Logger.Verbose("[SalvageItems] Nothing to salvage");
                return(false);
            }

            Core.Logger.Verbose("[SalvageItems] Starting salvage for {0} items", salvageItems.Count);
            salvageItems.ForEach(i => Core.Logger.Debug($"[SalvageItems] Salvaging: {i.Name} ({i.ActorSnoId}) InternalName={i.InternalName} Ancient={i.IsAncient} Ann={i.AnnId}"));

            GameUI.CloseVendorWindow();

            var blacksmith = TownInfo.BlacksmithSalvage;

            if (blacksmith == null)
            {
                Core.Logger.Error("[SalvageItems] Unable to find a blacksmith info for this area :(");
                return(false);
            }

            if (!UIElements.SalvageWindow.IsVisible)
            {
                var blacksmithNpc = TownInfo.Blacksmith;
                if (blacksmithNpc != null)
                {
                    Core.DBGridProvider.AddCellWeightingObstacle(blacksmithNpc.ActorId, 4);
                }

                if (!await MoveTo.Execute(blacksmith.InteractPosition))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to blacksmith interact position ({blacksmith.Name}) to salvage items :(");
                    return(false);
                }
                ;

                if (!await MoveToAndInteract.Execute(blacksmith, 10f))
                {
                    Core.Logger.Error($"[SalvageItems] Failed to move to blacksmith ({blacksmith.Name}) to salvage items :(");
                    return(false);
                }
                ;
                await Coroutine.Sleep(Rnd.Next(750, 1250));
            }

            if (UIElements.SalvageWindow.IsVisible)
            {
                if (ZetaDia.Me.Level >= 70 && UIElements.SalvageAllWrapper.IsVisible)
                {
                    var items = Core.Inventory.Backpack.Where(i => Combat.TrinityCombat.Loot.ShouldSalvage(i)).ToList();

                    var normals = items.Where(i => NormalQualityLevels.Contains(i.ItemQualityLevel)).ToList();
                    if (normals.Count > 0)
                    {
                        Core.Logger.Verbose($"[SalvageItems] Bulk Salvaging {normals.Count} Normal");
                        if (InventoryManager.SalvageItemsOfRarity(SalvageRarity.Normal))
                        {
                            normals.ForEach(ItemEvents.FireItemSalvaged);
                        }
                    }

                    var magic = items.Where(i => MagicQualityLevels.Contains(i.ItemQualityLevel)).ToList();
                    if (magic.Count > 0)
                    {
                        Core.Logger.Verbose($"[SalvageItems] Bulk Salvaging {magic.Count} Magic");
                        if (InventoryManager.SalvageItemsOfRarity(SalvageRarity.Magic))
                        {
                            magic.ForEach(ItemEvents.FireItemSalvaged);
                        }
                    }

                    var rares = items.Where(i => RareQualityLevels.Contains(i.ItemQualityLevel)).ToList();
                    if (rares.Count > 0)
                    {
                        Core.Logger.Verbose($"[SalvageItems] Bulk Salvaging {rares.Count} Rare");
                        if (InventoryManager.SalvageItemsOfRarity(SalvageRarity.Rare))
                        {
                            rares.ForEach(ItemEvents.FireItemSalvaged);
                        }
                    }
                }

                await Coroutine.Sleep(500);

                await Coroutine.Yield();

                var timeout = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30));
                while (DateTime.UtcNow < timeout)
                {
                    if (!UIElements.SalvageWindow.IsVisible)
                    {
                        break;
                    }

                    await Coroutine.Sleep(Rnd.Next(200, 300));

                    Core.Actors.Update();

                    var freshItems = Core.Inventory.Backpack.Where(i => ShouldSalvage(i) && !Core.Inventory.InvalidAnnIds.Contains(i.AnnId)).ToList();
                    if (!freshItems.Any())
                    {
                        break;
                    }

                    var item = freshItems.First();

                    if (ZetaDia.Actors.GetACDByAnnId(item.AnnId) == null)
                    {
                        Core.Logger.Log("AnnId doesn't exist, skipping salvage");
                        Core.Inventory.InvalidAnnIds.Add(item.AnnId);
                        continue;
                    }

                    if (!Core.Actors.IsAnnIdValid(item.AnnId))
                    {
                        Core.Logger.Log("AnnId test failed, skipping salvage to prevent disconnect");
                        Core.Inventory.InvalidAnnIds.Add(item.AnnId);
                        continue;
                    }

                    Core.Logger.Log($"Salvaging: {item.Name} ({item.ActorSnoId}) Ancient={item.IsAncient}");
                    InventoryManager.SalvageItem(item.AnnId);
                    Core.Inventory.InvalidAnnIds.Add(item.AnnId);
                    ItemEvents.FireItemSalvaged(item);
                }

                await Coroutine.Sleep(Rnd.Next(750, 1250));

                await RepairItems.Execute();

                return(true);
            }

            Core.Logger.Error($"[SalvageItems] Failed to salvage items");
            return(false);
        }
Пример #17
0
        public static async Task <bool> Execute()
        {
            if (!ZetaDia.IsInTown)
            {
                IsDumpingShards = false;
            }

            try
            {
                while (CanRun() && (!StillSavingShards || IsDumpingShards))
                {
                    IsDumpingShards = true;
                    if ((TownInfo.Kadala.Distance > 8f || !UIElements.VendorWindow.IsVisible) && !await MoveToAndInteract.Execute(TownInfo.Kadala))
                    {
                        Core.Logger.Log("[Gamble] Failed to move to Kadala, quite unfortunate.");
                        break;
                    }

                    if (CanBuyItems)
                    {
                        await BuyItem();
                    }
                    else
                    {
                        GameUI.CloseVendorWindow();
                    }

                    if (TrinityCombat.Loot.IsBackpackFull)
                    {
                        BrainBehavior.ForceTownrun();
                    }

                    await Coroutine.Yield();
                }
            }
            catch (Exception ex)
            {
                Core.Logger.Error("Exception in Gamble.Execute, {0}", ex);

                if (ex is CoroutineStoppedException)
                {
                    throw;
                }
            }

            GameUI.CloseVendorWindow();

            return(true);
        }
Пример #18
0
        /// <summary>
        /// Convert rares into legendaries with Kanai's cube
        /// </summary>
        /// <param name="types">restrict the rares that can be selected by ItemType</param>
        public static async Task <bool> Execute(List <ItemSelectionType> types = null)
        {
            while (CanRun(types))
            {
                if (!ZetaDia.IsInTown)
                {
                    break;
                }

                //Core.Logger.Log("[CubeRaresToLegendary] CubeRaresToLegendary Started! Wooo!");

                var backpackGuids = new HashSet <int>(InventoryManager.Backpack.Select(i => i.ACDId));

                if (HasMaterialsRequired)
                {
                    if (TownInfo.KanaisCube.Distance > 10f || !GameUI.KanaisCubeWindow.IsVisible)
                    {
                        if (!await MoveToAndInteract.Execute(TownInfo.KanaisCube))
                        {
                            Core.Logger.Log("Failed to move to the cube, quite unfortunate.");
                            break;
                        }
                        continue;
                    }

                    //Core.Logger.Log("[CubeRaresToLegendary] Ready to go, Lets transmute!");

                    var item             = GetBackPackRares(types).First();
                    var itemName         = item.Name;
                    var itemAnnId        = item.AnnId;
                    var itemInternalName = item.InternalName;
                    await Transmute.Execute(item, TransmuteRecipe.UpgradeRareItem);

                    await Coroutine.Sleep(1500);

                    var newItem = InventoryManager.Backpack.FirstOrDefault(i => !backpackGuids.Contains(i.ACDId));
                    if (newItem != null)
                    {
                        var newLegendaryItem = Legendary.GetItemByACD(newItem);
                        var newTrinityItem   = Core.Actors.ItemByAnnId(newItem.AnnId);
                        ItemEvents.FireItemCubed(newTrinityItem);

                        if (newTrinityItem.IsPrimalAncient)
                        {
                            Core.Logger.Warn($"[CubeRaresToLegendary] Upgraded Rare '{itemName}' ---> '{newLegendaryItem.Name}' ({newItem.ActorSnoId}) PRIMAL!~");
                        }
                        else
                        {
                            Core.Logger.Log($"[CubeRaresToLegendary] Upgraded Rare '{itemName}' ---> '{newLegendaryItem.Name}' ({newItem.ActorSnoId})");
                        }
                    }
                    else
                    {
                        Core.Logger.Log("[CubeRaresToLegendary] Failed to upgrade Item '{0}' {1} DynId={2} HasBackpackMaterials={3}",
                                        itemName, itemInternalName, itemAnnId, HasMaterialsRequired);
                    }

                    Core.Inventory.InvalidAnnIds.Add(itemAnnId);
                }
                else
                {
                    Core.Logger.Log("[CubeRaresToLegendary] Oh no! Out of materials!");
                    return(true);
                }

                await Coroutine.Sleep(500);

                await Coroutine.Yield();
            }

            return(true);
        }
Пример #19
0
        public async static Task <bool> Execute()
        {
            if (!ZetaDia.IsInTown)
            {
                Core.Logger.Verbose("[SellItems] Need to be in town to sell items");
                return(false);
            }

            var sellItems = Core.Inventory.Backpack.Where(ShouldSell).ToList();

            if (!sellItems.Any())
            {
                await RepairItems.Execute();

                Core.Logger.Verbose("[SellItems] Nothing to sell");
                return(false);
            }

            Core.Logger.Verbose("[SellItems] Now to sell {0} items", sellItems.Count);
            sellItems.ForEach(i => Core.Logger.Debug($"[SellItems] Selling: {i.Name} ({i.ActorSnoId}) InternalName={i.InternalName} Ancient={i.IsAncient} Ann={i.AnnId}"));

            await Coroutine.Sleep(Randomizer.Fudge(150));

            GameUI.CloseVendorWindow();

            var merchant = TownInfo.NearestMerchant;

            if (merchant == null)
            {
                Core.Logger.Error("[SellItems] Unable to find merchant info for this area :(");
                return(false);
            }

            if (!UIElements.VendorWindow.IsVisible)
            {
                if (!await MoveToAndInteract.Execute(merchant))
                {
                    Core.Logger.Error($"[SellItems] Failed to move to merchant ({merchant.Name}) to sell items :(");
                    return(false);
                }
                await Coroutine.Sleep(Randomizer.Fudge(1000));
            }

            if (UIElements.VendorWindow.IsVisible)
            {
                await Coroutine.Sleep(Randomizer.Fudge(1500));

                var freshItems = Core.Inventory.Backpack.Where(ShouldSell);
                foreach (var item in freshItems)
                {
                    if (InventoryManager.CanSellItem(item.ToAcdItem()))
                    {
                        if (!item.IsValid || item.IsUnidentified)
                        {
                            Core.Logger.Verbose($"[SellItems] Invalid Items Detected: IsValid={item.IsValid} IsUnidentified={item.IsUnidentified}");
                            continue;
                        }

                        await Coroutine.Sleep(Randomizer.Fudge(100));

                        Core.Logger.Verbose($"[SellItems] Selling: {item.Name} ({item.ActorSnoId}) Quality={item.ItemQualityLevel} IsAncient={item.IsAncient} Name={item.InternalName}");
                        InventoryManager.SellItem(item.ToAcdItem());
                        ItemEvents.FireItemSold(item);
                        Core.Inventory.InvalidAnnIds.Add(item.AnnId);
                    }
                }

                await Coroutine.Sleep(Randomizer.Fudge(1000));

                await RepairItems.Execute();

                return(true);
            }

            Core.Logger.Error($"[SellItems] Failed to sell items");
            return(false);
        }
Пример #20
0
        public static async Task <bool> Execute()
        {
            if (!ZetaDia.IsInTown)
            {
                Core.Logger.Verbose("[RepairItems] Need to be in town to Repair items");
                return(false);
            }

            if (!EquipmentNeedsRepair())
            {
                return(false);
            }

            var coinage         = ZetaDia.Storage.PlayerDataManager.ActivePlayerData.Coinage;
            var shouldRepairAll = coinage > InventoryManager.GetRepairCost(true);

            if (!shouldRepairAll)
            {
                if (coinage < InventoryManager.GetRepairCost(false))
                {
                    Core.Logger.Verbose("[RepairItems] Can't afford to repair");
                    return(false);
                }
            }

            if (UIElements.VendorWindow.IsVisible)
            {
                await Coroutine.Yield();

                Core.Logger.Verbose("[RepairItems] Repairing equipment while at this vendor");
                Repair(shouldRepairAll);
                return(true);
            }

            var smith       = TownInfo.Blacksmith;
            var merchant    = TownInfo.NearestMerchant;
            var repairActor = (Randomizer.Boolean ? merchant : smith) ?? (smith ?? merchant);

            if (repairActor == null)
            {
                Core.Logger.Error("[RepairItems] Failed to find somewhere to repair :(");
                return(false);
            }
            ;

            if (!await MoveToAndInteract.Execute(repairActor))
            {
                Core.Logger.Error($"[RepairItems] Failed to move to Vendor {repairActor.Name} for repair :( ");
                return(false);
            }
            ;

            if (repairActor.Distance <= 10f)
            {
                Navigator.PlayerMover.MoveStop();
                await Coroutine.Yield();
            }

            if (GameUI.IsBlackSmithWindowOpen || UIElements.VendorWindow.IsVisible)
            {
                await Coroutine.Yield();

                Core.Logger.Verbose($"[RepairItems] Repairing Equipment at {repairActor.Name} :)");
                Repair(shouldRepairAll);
                return(true);
            }

            repairActor.GetActor().Interact();
            await Coroutine.Sleep(1000);

            if (GameUI.IsBlackSmithWindowOpen || UIElements.VendorWindow.IsVisible)
            {
                await Coroutine.Yield();

                Core.Logger.Verbose($"[RepairItems] Repairing Equipment at {repairActor.Name} :) (Attempt Two)");
                Repair(shouldRepairAll);
                return(true);
            }

            Core.Logger.Error($"[RepairItems] Failed to repair at {repairActor.Name} :(");
            return(false);
        }