Example #1
0
        public static void RecordSpell(TrinityPower power)
        {
            if (_history.Count >= SpellHistorySize)
            {
                _history.RemoveAt(0);
            }

            var skill = SkillUtils.ById(power.SNOPower);

            if (skill.IsAttackSpender)
            {
                _lastSpenderCast = DateTime.UtcNow;
            }

            if (skill.IsGeneratorOrPrimary)
            {
                _lastGeneratorCast = DateTime.UtcNow;
            }

            _history.Add(new SpellHistoryItem
            {
                Power          = power,
                UseTime        = DateTime.UtcNow,
                MyPosition     = Trinity.Player.Position,
                TargetPosition = power.TargetPosition
            });

            Logger.LogVerbose(LogCategory.Targetting, "Recorded {0}", power);

            CacheData.AbilityLastUsed[power.SNOPower] = DateTime.UtcNow;
            Trinity.LastPowerUsed = power.SNOPower;
        }
        public static bool CanRun(List <ItemSelectionType> types = null)
        {
            if (!ZetaDia.IsInGame || !ZetaDia.IsInTown)
            {
                return(false);
            }

            var kule = Town.Actors.ZultonKule;

            if (kule != null)
            {
                if (kule.IsQuestGiver)
                {
                    Logger.LogVerbose("[CubeRaresToLegendary] Cube is not unlocked yet");
                    HasUnlockedCube = false;
                    return(false);
                }
                HasUnlockedCube = true;
            }

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

            if (Trinity.Trinity.Settings.KanaisCube.RareUpgradeTypes == ItemSelectionType.Unknown)
            {
                Logger.LogVerbose("[CubeRaresToLegendary] No item types selected in settings - (Config => Items => Kanai's Cube)");
                return(false);
            }

            if (!BackpackHasMaterials && ZetaDia.Me.Inventory.NumFreeBackpackSlots < 5)
            {
                Logger.LogVerbose("[CubeRaresToLegendary] Not enough bag space");
                return(false);
            }

            var dbs = Inventory.OfType(InventoryItemType.DeathsBreath).StackQuantity();

            if (dbs < Trinity.Trinity.Settings.KanaisCube.DeathsBreathMinimum)
            {
                Logger.LogVerbose("[CubeRaresToLegendary] Not enough deaths breath - Limit is set to {0}, You currently have {1}", Trinity.Trinity.Settings.KanaisCube.DeathsBreathMinimum, dbs);
                return(false);
            }

            if (!GetBackPackRares(types).Any())
            {
                Logger.LogVerbose("[CubeRaresToLegendary] You need some rares in your backpack for this to work!");
                return(false);
            }

            if (!BackpackHasMaterials && !StashHasMaterials)
            {
                Logger.LogVerbose("[CubeRaresToLegendary] Unable to find the materials we need, maybe you don't have them!");
                return(false);
            }

            return(true);
        }
Example #3
0
 public static int SpellUseCountInTime(SNOPower power, TimeSpan time)
 {
     if (_history.Any(i => i.Power.SNOPower == power))
     {
         var spellCount = _history.Count(i => i.Power.SNOPower == power && i.TimeSinceUse <= time);
         Logger.LogVerbose(LogCategory.Targetting, "Found {0}/{1} spells in {2} time for {3} power", spellCount, _history.Count(i => i.Power.SNOPower == power), time, power);
         return(spellCount);
     }
     return(0);
 }
Example #4
0
            internal void UpdateFastChangingData()
            {
                ACDGuid                      = _me.ACDGuid;
                RActorGuid                   = _me.RActorGuid;
                LastUpdated                  = DateTime.UtcNow;
                IsInTown                     = DataDictionary.TownLevelAreaIds.Contains(LevelAreaId);
                IsInRift                     = DataDictionary.RiftWorldIds.Contains(WorldID);
                IsDead                       = _me.IsDead;
                IsIncapacitated              = (_me.IsFeared || _me.IsStunned || _me.IsFrozen || _me.IsBlind);
                IsRooted                     = _me.IsRooted;
                CurrentHealthPct             = _me.HitpointsCurrentPct;
                PrimaryResource              = _me.CurrentPrimaryResource;
                PrimaryResourcePct           = PrimaryResource / PrimaryResourceMax;
                PrimaryResourceMissing       = PrimaryResourceMax - PrimaryResource;
                SecondaryResource            = _me.CurrentSecondaryResource;
                SecondaryResourcePct         = SecondaryResource / SecondaryResourceMax;
                SecondaryResourceMissing     = SecondaryResourceMax - SecondaryResource;
                Position                     = _me.Position;
                Rotation                     = _me.Movement.Rotation;
                DirectionVector              = _me.Movement.DirectionVector;
                MovementSpeed                = _me.Movement.SpeedXY;
                IsMoving                     = _me.Movement.IsMoving;
                IsInCombat                   = _me.IsInCombat;
                MaxBloodShards               = 500 + ZetaDia.Me.CommonData.GetAttribute <int>(ActorAttributeType.HighestSoloRiftLevel) * 10;
                IsMaxCriticalChance          = _me.CritPercentBonusUncapped > 0;
                IsJailed                     = _me.HasDebuff(SNOPower.MonsterAffix_JailerCast);
                IsFrozen                     = _me.IsFrozen;
                ParticipatingInTieredLootRun = _me.IsParticipatingInTieredLootRun;
                TieredLootRunlevel           = _me.InTieredLootRunLevel;

                CurrentHealth = _me.HitpointsCurrent;

                HealthHistory.Add(CurrentHealth);
                while (HealthHistory.Count > 5)
                {
                    HealthHistory.RemoveAt(0);
                }

                var averageHealth = HealthHistory.Average();

                IsTakingDamage = averageHealth > CurrentHealth;
                if (IsTakingDamage)
                {
                    Logger.LogVerbose(LogCategory.Avoidance, "Taking Damage 5TickAvg={0} Current={1}", averageHealth, CurrentHealth);
                }

                // For WD Angry Chicken
                IsHidden = _me.IsHidden;
            }
        public static bool CanRun()
        {
            if (!ZetaDia.IsInGame || !ZetaDia.IsInTown)
            {
                return(false);
            }

            if (!LastCanRunResult && DateTime.UtcNow.Subtract(LastCanRunCheck).TotalSeconds < 5)
            {
                return(LastCanRunResult);
            }

            Inventory.Materials.Update();

            _highest = Inventory.Materials.HighestCountMaterial(Inventory.MaterialConversionTypes);

            var settingsTypes = Trinity.Trinity.Settings.KanaisCube.GetCraftingMaterialTypes();

            if (!settingsTypes.Any())
            {
                Logger.LogVerbose("[CubeItemsToMaterials] No materials have been selected in settings", _highest.Type, _highest.TotalStackQuantity);
            }

            Logger.LogVerbose("[CubeItemsToMaterials] Selected {0} as the material with highest count - {1}", _highest.Type, _highest.TotalStackQuantity);

            var _validTypes = settingsTypes.Where(t => t != _highest.Type);

            _materials = Inventory.Materials.OfTypes(_validTypes);

            bool result = false;

            foreach (var material in _materials)
            {
                if (ConvertMaterials.CanRun(_highest.Type, material.Key, true, true))
                {
                    Logger.LogVerbose("[CubeItemsToMaterials] YES - {0} -> {1}", _highest.Type, material.Key);
                    result = true;
                }
                else
                {
                    Logger.LogVerbose("[CubeItemsToMaterials] NO - {0} -> {1}", _highest.Type, material.Key);
                }
            }

            LastCanRunCheck  = DateTime.UtcNow;
            LastCanRunResult = result;
            return(result);
        }
        public static async Task <bool> Execute(List <ItemSelectionType> types = null)
        {
            if (!CanRun())
            {
                return(true);
            }

            Logger.LogVerbose("[CubeItemsToMaterials] Getting Materials from Stash");

            if (!Inventory.Materials.HasStackQuantityOfTypes(Inventory.MaterialConversionTypes, InventorySlot.BackpackItems, 100) && !await TakeItemsFromStash.Execute(Inventory.RareUpgradeIds, 5000))
            {
                return(true);
            }

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

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

            if (_highest.Type == InventoryItemType.None)
            {
                Logger.Log("[CubeItemsToMaterials] Error: Highest material count is unknown.");
                return(true);
            }

            foreach (var material in _materials)
            {
                if (!await ConvertMaterials.Execute(_highest.Type, material.Key))
                {
                    Logger.Log("[Cube] Failed! Finished!");
                    return(true);
                }

                await Coroutine.Sleep(100);

                await Coroutine.Yield();
            }

            Logger.LogVerbose("[Cube] CubeItemsToMaterials Finished!");
            return(true);
        }
Example #7
0
        private static void ModifyTownRun(GroupComposite original)
        {
            var firstChild = original.Children.FirstOrDefault() as GroupComposite;

            if (firstChild == null)
            {
                Logger.LogVerbose("Unexpected Composite or no vendor composite found in original town run");
                return;
            }

            if (firstChild.Children.Count != 9)
            {
                return;
            }

            firstChild.InsertChild(3, new ActionRunCoroutine(async ret => await VendorHook.ExecutePreVendor()));
            // 2= Identify
            // 5= Stash
            firstChild.InsertChild(8, new ActionRunCoroutine(async ret => await VendorHook.ExecutePostVendor()));
        }
        /// <summary>
        /// A list of conversion candidates from backpack
        /// </summary>
        public static List <ACDItem> GetBackPackRares(IEnumerable <ItemSelectionType> types = null)
        {
            if (types == null)
            {
                types = Trinity.Trinity.Settings.KanaisCube.GetRareUpgradeSettings();
            }

            var rares = ZetaDia.Me.Inventory.Backpack.Where(i =>
            {
                if (Inventory.InvalidItemDynamicIds.Contains(i.DynamicId))
                {
                    return(false);
                }

                if (i.ItemBaseType != ItemBaseType.Armor && i.ItemBaseType != ItemBaseType.Weapon && i.ItemBaseType != ItemBaseType.Jewelry)
                {
                    return(false);
                }

                // Both ItemQualityLevel and ItemLinkColor are unreliable, together maybe we have a chance.
                if (i.GetItemQuality() != ItemQuality.Rare4 || i.ItemQualityLevel == ItemQuality.Legendary)
                {
                    return(false);
                }

                if (i.ItemStackQuantity != 0 || !i.IsValid || i.IsDisposed)
                {
                    Logger.LogVerbose("Skipping Item - Invalid {0} Disposed={1} IsValid={2} InvalidStackQuantity={3}",
                                      i.InternalName, i.IsDisposed, i.IsValid, i.ItemStackQuantity != 0);

                    return(false);
                }

                return(types == null || types.Contains(i.GetItemSelectionType()));
            }).ToList();

            Logger.Log(LogCategory.Behavior, "[CubeRaresToLegendary] {0} Valid Rares in Backpack", rares.Count);
            return(rares);
        }
Example #9
0
        /// <summary>
        ///  Do not remove nav server logging. We need to be able to identify the cause of stuck issues users report
        ///  and to do that we need to be able to differentiate between bugs in trinity and navigation server problems.
        /// </summary>
        public static void NavServerReport(bool silent = false, MoveResult moveResult = default(MoveResult), [System.Runtime.CompilerServices.CallerMemberName] string caller = "")
        {
            if (Navigator.SearchGridProvider.Width == 0 || Navigator.SearchGridProvider.SearchArea.Length == 0)
            {
                if (silent)
                {
                    Logger.LogVerbose("Waiting for Navigation Server... ({0})", caller);
                }
                else
                {
                    Logger.Log("Waiting for Navigation Server... ({0})", caller);
                }
            }

            else if (moveResult == MoveResult.PathGenerating)
            {
                Logger.LogVerbose("Navigation Path is Generating... ({0})", caller);
            }

            else if (moveResult == MoveResult.PathGenerationFailed)
            {
                Logger.LogVerbose("Navigation Path Failed to Generate... ({0})", caller);
            }
        }
Example #10
0
        public void AddRule(string propertyName, RuleType ruleType)
        {
            var propertiesWithDuplicatesAllowed = new HashSet <ItemProperty>
            {
                ItemProperty.ElementalDamage,
                ItemProperty.SkillDamage
            };

            Func <ItemProperty, bool> allowedToAdd = p => Rules.All(r => r.ItemProperty != p) || propertiesWithDuplicatesAllowed.Contains(p);

            ItemProperty property;

            Logger.Log("Attempting to Add {0} Type={1}", propertyName, ruleType);

            if (Enum.TryParse(propertyName, out property) && property != ItemProperty.Unknown && allowedToAdd(property))
            {
                var statRange = GetItemStatRange(property);
                if (statRange != null)
                {
                    Logger.LogVerbose(string.Format("Stats Min = {0} Max = {1} Step = {2}",
                                                    statRange.AbsMin.ToString(), statRange.AbsMax.ToString(), statRange.AbsStep.ToString()));
                }

                Rules.Add(new LRule
                {
                    Id              = (int)property,
                    ItemStatRange   = statRange,
                    TrinityItemType = TrinityItemType,
                    RuleType        = ruleType,
                    Value           = LRule.GetDefaultValue(property)
                });

                OnPropertyChanged("Rules");
                OnPropertyChanged(ruleType + "Rules");
            }
        }
        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);
        }
Example #12
0
        // thanks to Main for the super fast can-stand-at code
        internal static Vector3 MainFindSafeZone(Vector3 origin, bool shouldKite = false, bool isStuck = false, IEnumerable <TrinityCacheObject> monsterList = null, bool avoidDeath = false, float minDistance = 0f)
        {
            const float gridSquareSize = 5f;
            var         dhMaxDistance  = Math.Max(Trinity.Settings.Combat.DemonHunter.KiteMaxDistance, Trinity.Settings.Combat.DemonHunter.KiteLimit + 5);
            float       maxDistance    = Trinity.Player.ActorClass == ActorClass.DemonHunter ? dhMaxDistance : 100f;
            const int   maxWeight      = 100;

            double gridSquareRadius = Math.Sqrt((Math.Pow(gridSquareSize / 2, 2) + Math.Pow(gridSquareSize / 2, 2)));

            GridPoint bestPoint = new GridPoint(Vector3.Zero, 0, 0);

            if (MainGridProvider.Width == 0)
            {
                // Do not remove nav server logging, we need to differentiate between legitmate trinity issues and nav server issues.
                // In this case, if MainGridProvider is empty, then the bot cannot kite.
                Logger.Log("NavServer Issue: MainGridProvider is empty, unable to avoidance/kite position");
                return(Vector3.Zero);
            }

            int totalNodes       = 0;
            int nodesCantStand   = 0;
            int nodesZDiff       = 0;
            int nodesGT45Raycast = 0;
            int nodesAvoidance   = 0;
            int nodesMonsters    = 0;
            int nodesObjects     = 0;
            int pathFailures     = 0;
            int navRaycast       = 0;
            int pointsFound      = 0;

            int worldId = Trinity.Player.WorldID;

            Stopwatch[] timers = Enumerable.Range(0, 12).Select(i => new Stopwatch()).ToArray();

            Vector2 minWorld;

            minWorld.X = origin.X - maxDistance;
            minWorld.Y = origin.Y - maxDistance;

            //Point minPoint = WorldToGrid(minWorld);
            Point minPoint = MainGridProvider.WorldToGrid(minWorld);

            minPoint.X = Math.Max(minPoint.X, 0);
            minPoint.Y = Math.Max(minPoint.Y, 0);

            Vector2 maxWorld;

            maxWorld.X = origin.X + maxDistance;
            maxWorld.Y = origin.Y + maxDistance;

            // MainGridProvider will be empty/clear we start receiving navServer data
            //Point maxPoint = WorldToGrid(maxWorld);
            Point maxPoint = MainGridProvider.WorldToGrid(maxWorld);

            maxPoint.X = Math.Min(maxPoint.X, MainGridProvider.Width - 1);
            maxPoint.Y = Math.Min(maxPoint.Y, MainGridProvider.Height - 1);

            Point originPos = MainGridProvider.WorldToGrid(origin.ToVector2());

            //var monsters = monsterList.ToList();

            using (new PerformanceLogger("MainFindSafeZoneLoop"))
            {
                for (int y = minPoint.Y; y <= maxPoint.Y; y++)
                {
                    int searchAreaBasis = y * MainGridProvider.Width;
                    for (int x = minPoint.X; x <= maxPoint.X; x++)
                    {
                        totalNodes++;

                        timers[0].Start();

                        int dx = originPos.X - x;
                        int dy = originPos.Y - y;

                        // Ignore out of range
                        if (dx * dx + dy * dy > (maxDistance / 2.5f) * (maxDistance / 2.5f))
                        {
                            continue;
                        }

                        // extremely efficient CanStandAt
                        if (!MainGridProvider.SearchArea[searchAreaBasis + x])
                        {
                            nodesCantStand++;
                            continue;
                        }

                        Vector2 xy  = MainGridProvider.GridToWorld(new Point(x, y));
                        Vector3 xyz = Vector3.Zero;

                        if (Trinity.Settings.Combat.Misc.UseNavMeshTargeting)
                        {
                            xyz = new Vector3(xy.X, xy.Y, MainGridProvider.GetHeight(xy));
                        }
                        else
                        {
                            xyz = new Vector3(xy.X, xy.Y, origin.Z + 4);
                        }

                        GridPoint gridPoint = new GridPoint(xyz, 0, origin.Distance(xyz));

                        timers[0].Stop();

                        if (isStuck && gridPoint.Distance > (PlayerMover.TotalAntiStuckAttempts + 2) * 5)
                        {
                            continue;
                        }

                        /*
                         * Check if a square is occupied already
                         */
                        // Avoidance
                        timers[2].Start();
                        if (CacheData.TimeBoundAvoidance.Any(aoe => xyz.Distance2D(aoe.Position) <= gridSquareRadius))
                        {
                            nodesAvoidance++;
                            continue;
                        }
                        timers[2].Stop();

                        if (monsterList != null && monsterList.Any(m => xyz.Distance(m.Position) - m.Radius - 2 <= minDistance))
                        {
                            nodesMonsters++;
                            continue;
                        }

                        // Monsters
                        if (shouldKite)
                        {
                            timers[3].Start();
                            double checkRadius = gridSquareRadius;

                            if (CombatBase.KiteDistance > 0)
                            {
                                checkRadius = gridSquareSize + 10f;
                            }

                            // Any monster standing in this GridPoint
                            if (CacheData.MonsterObstacles.Any(monster => monster.Position.Distance2D(xyz) - monster.Radius <= checkRadius))
                            {
                                nodesMonsters++;
                                continue;
                            }



                            timers[3].Stop();
                        }

                        timers[4].Start();
                        if (isStuck && UsedStuckSpots.Any(p => Vector3.Distance(p.Position, gridPoint.Position) <= gridSquareRadius))
                        {
                            continue;
                        }
                        timers[4].Stop();

                        // set base weight
                        if (!isStuck && !avoidDeath)
                        {
                            // e.g. ((100 - 15) / 100) * 100) = 85
                            // e.g. ((100 - 35) / 100) * 100) = 65
                            // e.g. ((100 - 75) / 100) * 100) = 25
                            gridPoint.Weight = ((maxDistance - gridPoint.Distance) / maxDistance) * maxWeight;

                            // Low weight for close range grid points
                            if (shouldKite && gridPoint.Distance < CombatBase.KiteDistance)
                            {
                                gridPoint.Weight = (int)gridPoint.Distance;
                            }
                        }
                        else
                        {
                            gridPoint.Weight = gridPoint.Distance;
                        }

                        // Boss Areas
                        timers[5].Start();
                        if (UnSafeZone.UnsafeKiteAreas.Any(a => a.WorldId == Trinity.Player.WorldID && a.Position.Distance2DSqr(gridPoint.Position) <= (a.Radius * a.Radius)))
                        {
                            continue;
                        }
                        timers[5].Stop();

                        if (shouldKite)
                        {
                            /*
                             * We want to down-weight any grid points where monsters are closer to it than we are
                             */
                            timers[7].Start();
                            foreach (CacheObstacleObject monster in CacheData.MonsterObstacles)
                            {
                                float distFromPointToMonster = gridPoint.Position.Distance2D(monster.Position);
                                float distFromPointToOrigin  = gridPoint.Position.Distance2D(origin);

                                // No Kite Distance Setting
                                if (CombatBase.KiteDistance <= 0)
                                {
                                    // higher weight closer to monster
                                    if (distFromPointToMonster < distFromPointToOrigin)
                                    {
                                        gridPoint.Weight += distFromPointToOrigin;
                                    }
                                    else if (distFromPointToMonster > distFromPointToOrigin)
                                    {
                                        gridPoint.Weight -= distFromPointToMonster;
                                    }
                                }
                                else // Kite Distance is Set
                                {
                                    // higher weight further from monster
                                    if (distFromPointToMonster < distFromPointToOrigin)
                                    {
                                        gridPoint.Weight -= distFromPointToOrigin;
                                    }
                                    else if (distFromPointToMonster > distFromPointToOrigin)
                                    {
                                        gridPoint.Weight += distFromPointToMonster;
                                    }
                                    if (PositionCache.Cache.Any(cachePoint => gridPoint.Position.Distance2D(cachePoint.Position) <= gridSquareRadius))
                                    {
                                        gridPoint.Weight += distFromPointToOrigin; // always <= max distance, 0-150ish
                                    }
                                }
                            }
                            timers[7].Stop();

                            timers[8].Start();
                            foreach (CacheObstacleObject avoidance in CacheData.TimeBoundAvoidance)
                            {
                                float distSqrFromPointToAvoidance = gridPoint.Position.Distance2DSqr(avoidance.Position);

                                // position is inside avoidance
                                if (distSqrFromPointToAvoidance < (avoidance.Radius * avoidance.Radius))
                                {
                                    continue;
                                }

                                float distSqrFromPointToOrigin = gridPoint.Position.Distance2DSqr(origin);
                                if (distSqrFromPointToAvoidance < distSqrFromPointToOrigin)
                                {
                                    gridPoint.Weight -= distSqrFromPointToOrigin;
                                }
                                else if (distSqrFromPointToAvoidance > distSqrFromPointToOrigin)
                                {
                                    gridPoint.Weight += distSqrFromPointToAvoidance;
                                }
                            }
                            timers[8].Stop();
                        }
                        else if (isStuck)
                        {
                            // give weight to points nearer to our destination
                            gridPoint.Weight *= (maxDistance - PlayerMover.LastMoveToTarget.Distance2D(gridPoint.Position)) / maxDistance * maxWeight;
                        }
                        else if (!avoidDeath) // melee avoidance use only
                        {
                            timers[9].Start();
                            var monsterCount = Trinity.ObjectCache.Count(u => u.IsUnit && u.Position.Distance2D(gridPoint.Position) <= 2.5f);
                            if (monsterCount > 0)
                            {
                                gridPoint.Weight *= monsterCount;
                            }
                            timers[9].Stop();
                        }

                        pointsFound++;

                        if (gridPoint.Weight > bestPoint.Weight && gridPoint.Distance > 1)
                        {
                            bestPoint = gridPoint;
                        }
                    }
                }
            }


            if (isStuck)
            {
                UsedStuckSpots.Add(bestPoint);
            }

            string times = "";

            for (int t = 0; t < timers.Length; t++)
            {
                if (timers[t].IsRunning)
                {
                    timers[t].Stop();
                }
                times += string.Format("{0}/{1:0.0} ", t, timers[t].ElapsedMilliseconds);
            }

            Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance, "Kiting grid found {0}, distance: {1:0}, weight: {2:0}", bestPoint.Position, bestPoint.Distance, bestPoint.Weight);
            Logger.Log(TrinityLogLevel.Debug, LogCategory.Avoidance,
                       "Kiting grid stats Total={0} CantStand={1} ZDiff {2} GT45Raycast {3} Avoidance {4} Monsters {5} Obstacles {14} pathFailures {6} navRaycast {7} "
                       + "pointsFound {8} shouldKite={9} isStuck={10} avoidDeath={11} monsters={12} timers={13}",
                       totalNodes,
                       nodesCantStand,
                       nodesZDiff,
                       nodesGT45Raycast,
                       nodesAvoidance,
                       nodesMonsters,
                       pathFailures,
                       navRaycast,
                       pointsFound,
                       shouldKite,
                       isStuck,
                       avoidDeath,
                       monsterList == null ? 0 : monsterList.Count(),
                       times,
                       nodesObjects
                       );

            if (double.IsNaN(bestPoint.Position.X))
            {
                Logger.LogVerbose("Somethign went wrong, NaN value for MainFindSafeZone result");
                return(Vector3.Zero);
            }

            return(bestPoint.Position);
        }
Example #13
0
        public static TrinityPower GetPower()
        {
            TrinityPower power;

            if (UseDestructiblePower)
            {
                return(DestroyObjectPower);
            }

            if (UseOOCBuff)
            {
                // Call of The Ancients
                if (CanUseCallOfTheAncients && Sets.ImmortalKingsCall.IsFullyEquipped)
                {
                    return(PowerCallOfTheAncients);
                }

                // Sprint OOC
                if (CanUseSprintOOC)
                {
                    return(PowerSprint);
                }
            }
            else
            {
                if (QueuedPower != null && !Player.IsIncapacitated && PowerManager.CanCast(QueuedPower.SNOPower) && !Player.IsCastingOrLoading)
                {
                    Logger.LogVerbose(LogCategory.Behavior, "Casting Queued Power {0}", QueuedPower);
                    var next = QueuedPower;
                    QueuedPower.MaxFailedCastReTryAttempts = 5;
                    QueuedPower.WaitBeforeUseDelay         = 750;
                    QueuedPower = null;
                    return(next);
                }
            }

            // Ignore Pain when near Frozen
            if ((ZetaDia.Me.IsFrozen || ZetaDia.Me.IsRooted || Trinity.ObjectCache.Any(o => o.AvoidanceType == AvoidanceType.IceBall)) && CanCastIgnorePain)
            {
                Logger.Log("Used Ignore Pain to prevent Frozen");
                return(PowerIgnorePain);
            }

            if (!UseOOCBuff)
            {
                // Refresh Frenzy
                if (CanCast(SNOPower.Barbarian_Frenzy) && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) > 3000 && TimeSincePowerUse(SNOPower.Barbarian_Frenzy) < 4000)
                {
                    return(PowerFrenzy);
                }

                // Refresh Bash - Punish
                if (CanCast(SNOPower.Barbarian_Bash) && TimeSincePowerUse(SNOPower.Barbarian_Bash) > 4000 && TimeSincePowerUse(SNOPower.Barbarian_Bash) < 5000)
                {
                    return(PowerBash);
                }
            }

            // Ignore Pain when low on health
            if (CanCastIgnorePain)
            {
                return(PowerIgnorePain);
            }

            // WOTB
            if (CanUseWrathOfTheBerserker)
            {
                return(PowerWrathOfTheBerserker);
            }

            // Call of the Ancients
            if (CanUseCallOfTheAncients)
            {
                return(PowerCallOfTheAncients);
            }

            // Leap with Earth Set.
            if (CanUseLeap && Sets.MightOfTheEarth.IsThirdBonusActive)
            {
                return(PowerLeap);
            }

            // Earthquake
            if (CanUseEarthquake)
            {
                return(PowerEarthquake);
            }

            // Avalanche
            if (CanUseAvalanche)
            {
                return(PowerAvalanche);
            }

            // War Cry
            if (CanUseWarCry)
            {
                return(PowerWarCry);
            }

            // Battle Rage
            if (CanUseBattleRage)
            {
                return(PowerBattleRage);
            }

            // Rend
            if (CanUseRend)
            {
                return(PowerRend);
            }

            // Overpower
            if (CanUseOverPower)
            {
                return(PowerOverpower);
            }

            // Threatening Shout
            if (CanUseThreatingShout)
            {
                return(PowerThreateningShout);
            }

            // Ground Stomp
            if (CanUseGroundStomp)
            {
                return(PowerGroundStomp);
            }

            // Revenge
            if (CanUseRevenge)
            {
                return(PowerRevenge);
            }

            // Ancient Spear
            if (CanUseAncientSpear)
            {
                return(PowerAncientSpear);
            }

            // Sprint
            if (CanUseSprint)
            {
                return(PowerSprint);
            }

            // Furious Charge
            if (CanUseFuriousCharge)
            {
                return(PowerFuriousCharge);
            }

            // Leap
            if (CanUseLeap)
            {
                return(PowerLeap);
            }

            // Seismic Slam
            if (CanUseSeismicSlam)
            {
                return(PowerSeismicSlam);
            }

            // Bash to 3 stacks (Punish)
            if (CanUseBashTo3)
            {
                return(PowerBash);
            }

            // Frenzy to 5 stacks (Maniac)
            if (CanUseFrenzyTo5)
            {
                return(PowerFrenzy);
            }

            // HOTA Elites
            if (CanUseHammerOfTheAncientsElitesOnly)
            {
                return(PowerHammerOfTheAncients);
            }

            // Whirlwind
            if (CanUseWhirlwind)
            {
                return(PowerWhirlwind);
            }

            // Hammer of the Ancients
            if (CanUseHammerOfTheAncients)
            {
                return(PowerHammerOfTheAncients);
            }

            // Weapon Throw
            if (CanUseWeaponThrow)
            {
                return(PowerWeaponThrow);
            }

            // Frenzy Fury Generator
            if (CanUseFrenzy)
            {
                return(PowerFrenzy);
            }

            // Bash Fury Generator
            if (CanUseBash)
            {
                return(PowerBash);
            }

            // Cleave Fury Generator
            if (CanUseCleave)
            {
                return(PowerCleave);
            }

            // Default Attacks
            return(DefaultPower);

            return(power);
        }