Beispiel #1
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());
        }
Beispiel #2
0
        private async Task <bool> ReloadProfile(bool restart)
        {
            var path = Path.GetDirectoryName(ProfileManager.CurrentProfile.Path);

            if (path != null)
            {
                CurrentProfile = ProfileManager.CurrentProfile.Path;
                Core.Logger.Log($"Reloading profile {CurrentProfile} {QuestInfo()} Restart#={QuestStepReloadLoops}");
                var profilePath = Path.Combine(path, CurrentProfile);
                ProfileManager.Load(profilePath);
                Navigator.Clear();
                CountReloads();
                LastProfileReload = DateTime.UtcNow;

                if (restart)
                {
                    await CommonCoroutines.LeaveGame("ReloadProfileTag");
                }

                return(true);
            }
            return(false);
        }
Beispiel #3
0
        public static async Task <bool> Execute()
        {
            if (!ZetaDia.IsInGame || ZetaDia.Globals.IsLoadingWorld || !ZetaDia.Me.IsValid)
            {
                return(false);
            }

            if (Core.IsOutOfGame)
            {
                return(false);
            }

            var isDead = ZetaDia.Me.IsDead;

            if (_isDead != isDead)
            {
                if (isDead)
                {
                    _deathCounter            = LastDeathTime.Subtract(DateTime.UtcNow).TotalSeconds > 60 ? 0 : _deathCounter + 1;
                    _deathNeedRepairCounter  = LastDeathTime.Subtract(DateTime.UtcNow).TotalSeconds < 60 && EquipmentNeedsEmergencyRepair(5) ? _deathNeedRepairCounter + 1 : 0;
                    LastDeathTime            = DateTime.UtcNow;
                    _resButtonsVisibleStart  = DateTime.MinValue;
                    _resurrectButtonsVisible = false;
                    _deathLocation           = ZetaDia.Me.Position;
                    DeathsThisSession++;
                    DeathsThisSession++;

                    Core.Logger.Log("[Death] You died lol! RecentDeaths={0} RecentDeathsNeedingRepair={1}", _deathCounter, _deathNeedRepairCounter);
                }
                else
                {
                    Core.Logger.Log("[Death] No Longer Dead");

                    //if (Core.Settings.Combat.Misc.FleeInGhostMode)
                    //{
                    await MoveWhileGhosted();

                    //}

                    if (EquipmentNeedsEmergencyRepair(5))
                    {
                        BrainBehavior.ForceTownrun("[Death] Item Durability - Need to Repair");
                    }
                }
                _isDead = isDead;
            }

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

            var reviveAtCorpseButton     = UIElement.FromHash(0xE3CBD66296A39588);
            var reviveAtCheckPointButton = UIElement.FromHash(0xBFAAF48BA9316742);
            var acceptRessurectionButton = UIElement.FromHash(0x712D458486D6F062);
            var reviveInTownButton       = UIElement.FromHash(0x7A2AF9C0F3045ADA);
            var needRepair            = EquipmentNeedsEmergencyRepair(5);
            var checkpointButtonReady = reviveAtCheckPointButton.IsVisible && reviveAtCheckPointButton.IsEnabled;
            var corpseButtonReady     = reviveAtCorpseButton.IsVisible && reviveAtCorpseButton.IsEnabled;
            var townButtonReady       = reviveInTownButton.IsVisible && reviveInTownButton.IsEnabled;
            var isInRift                  = GameData.RiftWorldIds.Contains(ZetaDia.Globals.WorldSnoId);
            var isInGreaterRift           = isInRift && ZetaDia.Storage.CurrentRiftType == RiftType.Greater;
            var noMoreCorpseRevives       = !isInGreaterRift && ZetaDia.Me.CommonData.CorpseResurrectionCharges == 0;
            var waitingForCorpseResurrect = ZetaDia.Globals.GameTick < ZetaDia.Me.CommonData.CorpseResurrectionAllowedGameTime;
            var deathCount                = ZetaDia.Me.CommonData.DeathCount;
            var corpseResurrectDisabled   = ZetaDia.Me.CommonData.CorpseResurrectionDisabled > 0;

            if (reviveAtCheckPointButton.IsVisible)
            {
                _resButtonsVisibleStart = DateTime.UtcNow;
            }

            var resurrectButtonsVisible = _resButtonsVisibleStart != DateTime.MinValue;

            if (resurrectButtonsVisible != _resurrectButtonsVisible)
            {
                if (resurrectButtonsVisible)
                {
                    Core.Logger.Verbose("[Death] Buttons are now visible");
                    var maxWaitTime = ZetaDia.Me.IsParticipatingInTieredLootRun ? Math.Min(deathCount * 5, 30) - 2 : 4;
                    _corpseReviveAvailableTime = new DateTime(_resButtonsVisibleStart.Ticks).Add(TimeSpan.FromSeconds(maxWaitTime));
                }
                _resurrectButtonsVisible = resurrectButtonsVisible;
            }

            var remainingTimeSecs = (_corpseReviveAvailableTime - DateTime.UtcNow).TotalSeconds;
            var resLimit          = isInGreaterRift ? 16 : 10;

            if (_deathCounter > resLimit && !ZetaDia.IsInTown && needRepair)
            {
                Core.Logger.Log("Durability is zero and {0} deaths within 60s of each other - emergency leave game", deathCount);
                ZetaDia.Service.Party.LeaveGame(true);
                await CommonCoroutines.LeaveGame("Durability is zero");

                _deathCounter = 0;
                return(true);
            }

            if (acceptRessurectionButton.IsVisible && acceptRessurectionButton.IsEnabled)
            {
                acceptRessurectionButton.Click();
            }
            else if (IsBeingRevived())
            {
                Core.Logger.Log("[Death] Waiting while being resurrected");
            }
            else if (ZetaDia.Me.IsInBossEncounter && !Core.Rift.IsInRift && IsAlivePlayerNearby)
            {
                Core.Logger.Log("[Death] Waiting because of boss fight");
            }
            else if (corpseButtonReady && !needRepair && !waitingForCorpseResurrect && !noMoreCorpseRevives && !corpseResurrectDisabled)
            {
                while (reviveAtCorpseButton.IsVisible && ZetaDia.Me.IsDead)
                {
                    Core.Logger.Log("[Death] Reviving at corpse");
                    reviveAtCorpseButton.Click();
                    await Coroutine.Sleep(1000);
                }
            }
            else if (townButtonReady && needRepair && _deathNeedRepairCounter > 4)
            {
                Core.Logger.Log("[Death] We've failed few times to resurrect at checkpoint to repair , now resurrecting in town.");
                reviveInTownButton.Click();
            }
            else if (checkpointButtonReady)
            {
                Core.Logger.Log("[Death] Reviving at checkpoint (NeedRepair={0})", needRepair);
                reviveAtCheckPointButton.Click();
            }
            else if (!corpseButtonReady && !checkpointButtonReady && townButtonReady && DateTime.UtcNow.Subtract(LastDeathTime).TotalSeconds > 45)
            {
                Core.Logger.Log("[Death] Reviving in town");
                reviveInTownButton.Click();
            }
            else
            {
                Core.Logger.Verbose("[Death] Waiting...");
            }

            await Coroutine.Sleep(250);

            return(true);
        }
        private async Task <bool> UpgradeGemsTask(bool force = false)
        {
            if (VendorDialog.IsVisible && (GameUI.IsElementVisible(UpgradeGemButton) && UpgradeGemButton.IsEnabled) || GameUI.IsElementVisible(UpgradeButton))
            {
                bool hasUpgradeableGems = ZetaDia.Actors.GetActorsOfType <ACDItem>()
                                          .Where(item => item.ItemType == ItemType.LegendaryGem).Any(item => GetUpgradeChance(item) > 0.00f);

                if (!hasUpgradeableGems)
                {
                    Logger.Error("No valid gems found to upgrade! Leaving game...");
                    await CommonCoroutines.UseTownPortal("Unable to upgrade gem - leaving game");

                    await Coroutine.Sleep(100);

                    await Coroutine.Yield();

                    await CommonCoroutines.LeaveGame("Unable to upgrade gem");

                    _isDone = true;
                    await Coroutine.Sleep(100);

                    await Coroutine.Yield();

                    return(true);
                }
                float minimumGemChance = force ? 0f : QuestToolsSettings.Instance.MinimumGemChance;

                List <ACDItem> gems = ZetaDia.Actors.GetActorsOfType <ACDItem>()
                                      .Where(item => item.ItemType == ItemType.LegendaryGem && GetUpgradeChance(item) > 0.00f && GetUpgradeChance(item) >= minimumGemChance)
                                      .OrderByDescending(item => GetUpgradeChance(item))
                                      .ThenByDescending(item => item.JewelRank).ToList();

                if (gems.Count == 0 && !_isGemsOnly) //No gems that can be upgraded - upgrade keystone
                {
                    return(false);
                }

                if (gems.Count == 0 && _isGemsOnly)
                {
                    gems = ZetaDia.Actors.GetActorsOfType <ACDItem>()
                           .Where(item => item.ItemType == ItemType.LegendaryGem)
                           .Where(item => !IsMaxLevelGem(item) && GetUpgradeChance(item) > 0.00f)
                           .OrderByDescending(item => GetUpgradeChance(item))
                           .ThenByDescending(item => item.JewelRank).ToList();
                }



                _isGemsOnly = true;

                int    selectedGemId         = int.MaxValue;
                string selectedGemPreference = "";
                foreach (string gemName in QuestToolsSettings.Instance.GemPriority)
                {
                    selectedGemId = DataDictionary.LegendaryGems.FirstOrDefault(kv => kv.Value == gemName).Key;

                    // Map to known gem type or dynamic priority
                    if (selectedGemId == int.MaxValue)
                    {
                        Logger.Error("Invalid Gem Name: {0}", gemName);
                        continue;
                    }

                    // Equipped Gems
                    if (selectedGemId == 0)
                    {
                        selectedGemPreference = gemName;
                        if (gems.Any(IsGemEquipped))
                        {
                            gems = gems.Where(item => item.InventorySlot == InventorySlot.Socket).ToList();
                            break;
                        }
                    }

                    // Lowest Rank
                    if (selectedGemId == 1)
                    {
                        selectedGemPreference = gemName;
                        gems = gems.OrderBy(item => item.JewelRank).ToList();
                        break;
                    }

                    // Highest Rank
                    if (selectedGemId == 2)
                    {
                        selectedGemPreference = gemName;
                        gems = gems.OrderByDescending(item => item.JewelRank).ToList();
                        break;
                    }

                    // Selected gem
                    if (gems.Any(i => i.ActorSNO == selectedGemId))
                    {
                        selectedGemPreference = gemName;
                        if (gems.Any(i => i.ActorSNO == selectedGemId))
                        {
                            gems = gems.Where(i => i.ActorSNO == selectedGemId).Take(1).ToList();
                            break;
                        }
                    }

                    // No gem found... skip!
                }

                if (selectedGemId < 10)
                {
                    Logger.Log("Using gem priority of {0}", selectedGemPreference);
                }

                var bestGem = gems.FirstOrDefault();

                if (bestGem != null && await CommonCoroutines.AttemptUpgradeGem(bestGem))
                {
                    await Coroutine.Sleep(250);

                    GameUI.SafeClickElement(VendorCloseButton, "Vendor Window Close Button");
                    await Coroutine.Yield();

                    return(true);
                }
                else
                {
                    /*
                     * Demonbuddy MAY randomly fail to upgrade the selected gem. This is a workaround, in case we get stuck...
                     */

                    var randomGems = ZetaDia.Actors.GetActorsOfType <ACDItem>()
                                     .Where(item => item.ItemType == ItemType.LegendaryGem)
                                     .OrderBy(item => item.JewelRank).ToList();

                    Random random = new Random(DateTime.UtcNow.Millisecond);
                    int    i      = random.Next(0, randomGems.Count - 1);

                    var randomGem = randomGems.ElementAtOrDefault(i);
                    if (randomGem == null)
                    {
                        Logger.Error("Error: No gems found");
                        return(false);
                    }

                    Logger.Error("Gem Upgrade failed! Upgrading random Gem {0} ({1}) - {2:##.##}% {3} ", randomGem.Name, randomGem.JewelRank, GetUpgradeChance(randomGem) * 100, IsGemEquipped(randomGem) ? "Equipped" : string.Empty);

                    if (!await CommonCoroutines.AttemptUpgradeGem(randomGem))
                    {
                        Logger.Error("Random gem upgrade also failed. Something... seriously... wrong... ");
                    }

                    return(true);
                }
            }

            return(false);
        }