Esempio n. 1
0
        public void UpdateMonsterFlags(TrinityActor actor, AvoidanceLayer layer)
        {
            if (actor.ActorType != ActorType.Monster)
            {
                return;
            }

            foreach (var node in TrinityGrid.Instance.GetNodesInRadius(actor.Position, actor.CollisionRadius * MonsterWeightRadiusFactor))
            {
                node.Weight += 2;

                if (actor.IsHostile)
                {
                    node.HostileMonsterCount++;
                }

                node.AddNodeFlags(AvoidanceFlags.Monster);
                layer.Add(node);

                if (node.Center.Distance(actor.Position.ToVector2()) < actor.CollisionRadius)
                {
                    node.AddNodeFlags(AvoidanceFlags.NavigationBlocking);
                }
            }
        }
Esempio n. 2
0
        public void UpdateKiteFromFlags(TrinityActor actor, AvoidanceLayer layer)
        {
            if (TrinityCombat.Routines.Current == null)
            {
                s_logger.Debug($"[{nameof(UpdateKiteFromFlags)}] UpdateKiteFromFlags failed to update becasue no routine is selected");
                return;
            }

            var kiteMode     = TrinityCombat.Routines.Current.KiteMode;
            var kiteDistance = TrinityCombat.Routines.Current.KiteDistance;

            if (kiteMode == KiteMode.Never)
            {
                return;
            }

            if (actor.ActorType != ActorType.Monster || actor.IsQuestMonster || actor.IsNpc)
            {
                return;
            }

            var kiteFromBoss   = kiteMode == KiteMode.Bosses && actor.IsBoss;
            var kiteFromElites = kiteMode == KiteMode.Elites && actor.IsElite;
            var kiteAlways     = kiteMode == KiteMode.Always;
            var isKiting       = kiteFromBoss || kiteFromElites || kiteAlways;
            var weight         = 1;

            if (!isKiting)
            {
                return;
            }

            foreach (var node in TrinityGrid.Instance.GetNodesInRadius(actor.Position, actor.CollisionRadius + kiteDistance))
            {
                if (!node.IsWalkable)
                {
                    continue;
                }

                node.Weight = weight;
                node.AddNodeFlags(AvoidanceFlags.KiteFrom);
                layer.Add(node);
            }
        }
Esempio n. 3
0
        public void UpdateGrid()
        {
            TrinityGrid.Instance.IsUpdatingNodes = true;

            using (new PerformanceLogger("UpdateGrid"))
            {
                HighestNodeWeight = 0;

                if (TrinityGrid.Instance.NearestNode == null ||
                    TrinityGrid.Instance.NearestNode.DynamicWorldId != ZetaDia.Globals.WorldId)
                {
                    s_logger.Debug($"[{nameof(UpdateGrid)}] No Player Nearest Node or WorldId Mismatch");
                    Core.Scenes.Reset();
                    Core.Scenes.Update();
                    return;
                }

                var safeNodes             = new AvoidanceLayer();
                var kiteNodes             = new AvoidanceLayer();
                var avoidanceNodes        = new AvoidanceLayer();
                var monsterNodes          = new AvoidanceLayer();
                var obstacleNodes         = new AvoidanceLayer();
                var activeAvoidanceSnoIds = new HashSet <SNOActor>();
                var kiteFromNodes         = new AvoidanceLayer();

                var nodePool = TrinityGrid.Instance
                               .GetNodesInRadius(Core.Player.Position, node => node.IsWalkable, MaxDistance)
                               .Select(n => n.Reset()).ToList();

                //var allNodes = Grid.GetNodesInRadius(Core.Player.Position, node => node != null, MaxDistance).ToList();
                var nearestNodes = TrinityGrid.Instance
                                   .GetNodesInRadius(Core.Player.Position, node => node != null &&
                                                     node.NodeFlags.HasFlag(NodeFlags.AllowWalk), Settings.AvoiderLocalRadius)
                                   .ToList();

                var weightSettings = Settings.WeightingOptions;

                try
                {
                    if (!ZetaDia.IsInGame || ZetaDia.Globals.IsLoadingWorld)
                    {
                        return;
                    }

                    if (!nodePool.Any())
                    {
                        return;
                    }

                    foreach (var obj in Core.Targets)
                    {
                        if (obj.IsMe)
                        {
                            continue;
                        }

                        UpdateGizmoFlags(obj);
                        UpdateGlobeFlags(obj);
                        UpdateMonsterFlags(obj, monsterNodes);
                        UpdateKiteFromFlags(obj, kiteFromNodes);
                        UpdateProjectileBlockers(obj);
                    }

                    foreach (var door in Core.Actors.Actors.Where(a => a.Type == TrinityObjectType.Door))
                    {
                        UpdateDoorFlags(door);
                    }

                    //foreach (var obstacle in CacheData.NavigationObstacles)
                    //{
                    //    UpdateObstacleFlags(obstacle, obstacleNodes);
                    //}

                    //UpdateBacktrackFlags();

                    foreach (var avoidance in Core.Avoidance.CurrentAvoidances)
                    {
                        try
                        {
                            if (!avoidance.Settings.IsEnabled || avoidance.IsImmune)
                            {
                                continue;
                            }

                            var handler = avoidance.Definition.Handler;
                            if (handler == null)
                            {
                                s_logger.Error($"[{nameof(UpdateGrid)}] Avoidance: {avoidance.Definition.Name} has no handler");
                                continue;
                            }

                            if (avoidance.IsAllowed && !avoidance.IsExpired)
                            {
                                handler.UpdateNodes(TrinityGrid.Instance, avoidance);

                                avoidance.Actors.ForEach(a =>
                                {
                                    activeAvoidanceSnoIds.Add(a.ActorSnoId);
                                    Core.DBGridProvider.AddCellWeightingObstacle(a.ActorSnoId, a.CollisionRadius);
                                    //Core.Logger.Warn(LogCategory.Avoidance, $"Avoidance Flagged {a} for {avoidance.Definition.Name}, handler={avoidance.Definition.Handler.GetType().Name}");
                                });
                            }
                            else
                            {
                                //Core.Logger.Warn(LogCategory.Avoidance, $"Avoidance {avoidance.Definition.Name} is not allowed. Enabled={avoidance.Settings.IsEnabled} IsAllowed={avoidance.IsAllowed} PlayerHealth={Core.Player.CurrentHealthPct * 100} SettingsHealth={avoidance.Settings.HealthPct} ");
                            }
                        }
                        catch (Exception ex)
                        {
                            s_logger.Error($"[{nameof(UpdateGrid)}] Exception in AvoidanceHandler updating nodes. Name={avoidance.Definition?.Name} Handler={avoidance.Definition?.Handler?.GetType()}", ex);
                        }
                    }

                    AvoidanceCentroid = avoidanceNodes.GetCentroid();
                    MonsterCentroid   = monsterNodes.GetCentroid();

                    foreach (var node in nodePool)
                    {
                        if (weightSettings.HasFlag(WeightingOptions.Backtrack) && node.AvoidanceFlags.HasFlag(AvoidanceFlags.Backtrack))
                        {
                            node.Weight--;
                        }

                        if (weightSettings.HasFlag(WeightingOptions.AvoidanceCentroid) && node.NavigableCenter.Distance(AvoidanceCentroid) < 15f)
                        {
                            node.Weight += 2;
                        }

                        if (weightSettings.HasFlag(WeightingOptions.MonsterCentroid) && node.NavigableCenter.Distance(MonsterCentroid) > 15f)
                        {
                            node.Weight--;
                        }

                        // Disabled for performance - 12ms @80yd
                        //if (Grid.IsInKiteDirection(node.NavigableCenter, 70))
                        //{
                        //    node.AddNodeFlags(AvoidanceFlags.Kite);
                        //    node.Weight--;
                        //    kiteNodes.Add(node);
                        //}
                        //else
                        //{
                        //    node.Weight++;
                        //}

                        var anyAdjacentUnsafe = node.AdjacentNodes.Any(n =>
                                                                       !n.NodeFlags.HasFlag(NodeFlags.AllowWalk) ||
                                                                       n.AvoidanceFlags.HasFlag(AvoidanceFlags.Avoidance) ||
                                                                       n.AvoidanceFlags.HasFlag(AvoidanceFlags.Monster) ||
                                                                       n.AvoidanceFlags.HasFlag(AvoidanceFlags.KiteFrom));

                        if (!anyAdjacentUnsafe)
                        {
                            if (weightSettings.HasFlag(WeightingOptions.AdjacentSafe))
                            {
                                node.Weight--;
                            }

                            node.AddNodeFlags(AvoidanceFlags.AdjacentSafe);
                            safeNodes.Add(node);
                        }

                        if (node.Weight > HighestNodeWeight)
                        {
                            HighestNodeWeight = node.Weight;
                            HighestNode       = node;
                        }
                    }
                }
                catch (Exception ex)
                {
                    s_logger.Error($"[{nameof(UpdateGrid)}] Exception in UpdateGrid", ex);

                    if (ex is CoroutineStoppedException)
                    {
                        throw;
                    }
                }

                //AllNodes = allNodes;
                CurrentNodes          = nodePool; //.OrderBy(n => n.Weight).ThenByDescending(n => n.Distance).ToList();
                SafeNodesByWeight     = safeNodes.Nodes.OrderBy(n => n.Weight).ThenByDescending(n => n.Distance);
                SafeNodesByDistance   = safeNodes.Nodes.OrderBy(n => n.Distance);
                SafeNodeLayer         = safeNodes;
                KiteNodeLayer         = kiteNodes;
                KiteFromLayer         = kiteFromNodes;
                AvoidanceNodeLayer    = avoidanceNodes;
                MonsterNodeLayer      = monsterNodes;
                NearbyNodes           = nearestNodes;
                ObstacleNodeLayer     = obstacleNodes;
                ActiveAvoidanceSnoIds = activeAvoidanceSnoIds;
            }

            TrinityGrid.Instance.IsUpdatingNodes = true;
        }