Exemplo n.º 1
0
        public bool IsOnEdge(ExplorationNode n, SceneExitDirections direction)
        {
            switch (direction)
            {
            case SceneExitDirections.North:
                return(n.TopLeft.X == NorthWest.X);

            case SceneExitDirections.East:
                return(n.BottomLeft.Y == NorthEast.Y);

            case SceneExitDirections.South:
                return(n.BottomRight.X == SouthEast.X);

            case SceneExitDirections.West:
                return(n.TopRight.Y == SouthWest.Y);
            }
            return(false);
        }
Exemplo n.º 2
0
        public static double PriorityDistanceFormula(ExplorationNode n)
        {
            var directionMultiplier = IsInPriorityDirection(n.NavigableCenter, 30) ? 4.5 : 1;
            var sceneConnectionDirectionMultiplier = IsInSceneConnectionDirection(n.NavigableCenter, 30) ? 1.25 : 1;
            var nodeInPrioritySceneMultiplier      = n.Priority ? 2.25 : 0;
            var baseDistanceFactor = 50 / n.NavigableCenter.Distance(AdvDia.MyPosition) * 10;
            var canRayWalk         = Core.Grids.CanRayWalk(AdvDia.MyPosition, n.NavigableCenter) ? 1.75 : 1;

            var edgeMultiplier      = 1d;
            var visitedMultiplier   = 1d;
            var exitSceneMultiplier = 1d;
            var exploredPercent     = ExplorationGrid.Instance.WalkableNodes.Count(x => x.Scene.HasBeenVisited) /
                                      ExplorationGrid.Instance.WalkableNodes.Count();

            // for now.. restrict this group of checks from effecting bounties.
            if (Core.Rift.IsInRift)
            {
                var isInExitScene = n.Scene.Name.Contains("Exit");
                exitSceneMultiplier = isInExitScene ? 100 / n.Distance : 1;
                visitedMultiplier   = n.Scene.HasBeenVisited && !isInExitScene ? 0.01f : 1f;

                // Ignore dead end scenes.
                if (n.Scene.ExitPositions.Count <= 1 && !isInExitScene)
                {
                    return(0);
                }

                if (!Core.Grids.CanRayWalk(Core.Player.Position, n.NavigableCenter))
                {
                    return(0);
                }

                // Lower weight for scenes near the edge of an open style map.
                edgeMultiplier = (n.Scene.Name.Contains("Border") || n.Scene.Name.Contains("Edge")) && n.Distance <100 &&
                                                                                                                   exploredPercent> 0.85
                    ? 2.5
                    : 1;
            }

            return(baseDistanceFactor * exitSceneMultiplier *
                   directionMultiplier * sceneConnectionDirectionMultiplier
                   * (n.UnvisitedWeight + nodeInPrioritySceneMultiplier) * visitedMultiplier * edgeMultiplier *
                   canRayWalk);
        }
Exemplo n.º 3
0
        private void CreateGrid(Scene.NavMesh mesh)
        {
            if (GridCreated)
            {
                return;
            }

            Cells = new List <WorldSceneCell>();

            foreach (var navCell in mesh.Zone.NavZoneDef.NavCells)
            {
                Cells.Add(new WorldSceneCell(navCell, Min));
            }
            if (SubScene != null)
            {
                foreach (var navCell in SubScene.Cells)
                {
                    Cells.Add(navCell);
                }
                if (SubScene.SubScene != null)
                {
                    foreach (var navCell in SubScene.SubScene.Cells)
                    {
                        Cells.Add(navCell);
                    }
                }
            }

            var navBoxSize      = ExplorationData.ExplorationNodeBoxSize;
            var searchBeginning = navBoxSize / 2;

            for (var x = Min.X + searchBeginning; x <= Max.X; x = x + navBoxSize)
            {
                for (var y = Min.Y + searchBeginning; y <= Max.Y; y = y + navBoxSize)
                {
                    var navNode = new ExplorationNode(new Vector2(x, y), _boxSize, _boxTolerance, this);
                    Nodes.Add(navNode);
                }
            }

            GridCreated     = true;
            GridCreatedTime = DateTime.UtcNow;
        }
Exemplo n.º 4
0
        public NavigationNode(Vector3 center, float boxSize, ExplorationNode node, WorldSceneCell cell)
        {
            if (node != null)
            {
                _explorationNode = node;
                _scene           = node.Scene;
            }

            if (cell != null)
            {
                NodeFlags = (NodeFlags)cell.NavCellFlags;
            }

            var halfSize = (float)boxSize / 2;

            Center            = center.ToVector2();
            TopLeft           = Center + new Vector2(-(halfSize), -(halfSize));
            BottomLeft        = Center + new Vector2(-(halfSize), halfSize);
            TopRight          = Center + new Vector2(halfSize, -(halfSize));
            BottomRight       = Center + new Vector2(halfSize, halfSize);
            NavigableCenter   = center;
            NavigableCenter2D = Center;
        }
Exemplo n.º 5
0
        public static ExplorationNode NearestWeightedUnvisitedNode(HashSet <int> levelAreaIds, List <string> ignoreScenes = null)
        {
            var             dynamicWorldId = AdvDia.CurrentWorldDynamicId;
            var             myPosition     = AdvDia.MyPosition;
            ExplorationNode node           = null;

            using (new PerformanceLogger("NearestUnvisitedNodeLocation", true))
            {
                var nearestNode = ExplorationGrid.Instance.GetNearestWalkableNodeToPosition(myPosition);

                if (Core.Rift.IsInRift && !Core.BlockedCheck.IsBlocked && !Core.StuckHandler.IsStuck)
                {
                    //Core.Logger.Warn("in rift");
                    // In rift prefer the highest weight nodes because we dont need to explore everything, just need to find the exit.

                    var closestUnvisitedNodes = ExplorationGrid.Instance.WalkableNodes
                                                .Where(n => !n.IsIgnored && !n.IsVisited && !n.IsBlacklisted && n.HasEnoughNavigableCells &&
                                                       n.DynamicWorldId == dynamicWorldId && levelAreaIds.Contains(n.LevelAreaId))
                                                .OrderByDescending(n => n.Priority)
                                                .ThenByDescending(PriorityDistanceFormula);

                    var closestUnvisitedNode = closestUnvisitedNodes.FirstOrDefault();
                    if (closestUnvisitedNode != null)
                    {
                        var weight = PriorityDistanceFormula(closestUnvisitedNode);
                        Core.Logger.Debug(LogCategory.Exploration, $"Explore: Best Rift Weighted Node: [{closestUnvisitedNode.NavigableCenter.X},{closestUnvisitedNode.NavigableCenter.Y},{closestUnvisitedNode.NavigableCenter.Z}] Dist:{closestUnvisitedNode.Distance} Weight: {weight} {(closestUnvisitedNode.Priority ? "(Priority)" : "")} ");
                        return(closestUnvisitedNode);
                    }
                }

                // Try for nodes nearby walkable nodes first
                for (var i = 3; i <= 4; i++)
                {
                    var closestUnvisitedNodes = ExplorationGrid.Instance.GetNeighbors(nearestNode, i)
                                                .Where(n => !n.IsIgnored && !n.IsVisited && !n.IsBlacklisted && n.HasEnoughNavigableCells &&
                                                       n.DynamicWorldId == dynamicWorldId && levelAreaIds.Contains(n.LevelAreaId) &&
                                                       Core.Grids.CanRayWalk(myPosition, n.NavigableCenter))
                                                .OrderByDescending(n => n.Priority)
                                                .ThenBy(PriorityDistanceFormula);

                    var closestUnvisitedNode = closestUnvisitedNodes.FirstOrDefault();
                    if (closestUnvisitedNode != null)
                    {
                        Core.Logger.Debug(LogCategory.Exploration, $"Explore: Selected Nearby Node: [{closestUnvisitedNode.NavigableCenter.X},{closestUnvisitedNode.NavigableCenter.Y},{closestUnvisitedNode.NavigableCenter.Z}] Dist:{closestUnvisitedNode.Distance} {(closestUnvisitedNode.Priority ? "(Priority)" : "")} ");
                        return(closestUnvisitedNode);
                    }
                }

                // Try any nearby nodes
                for (var i = 3; i <= 6; i++)
                {
                    var closestUnvisitedNode = ExplorationGrid.Instance.GetNeighbors(nearestNode, i)
                                               .Where(n => !n.IsIgnored && !n.IsVisited && !n.IsBlacklisted && n.HasEnoughNavigableCells &&
                                                      n.DynamicWorldId == dynamicWorldId && levelAreaIds.Contains(n.LevelAreaId))
                                               .OrderBy(PriorityDistanceFormula)
                                               .FirstOrDefault();

                    if (closestUnvisitedNode != null)
                    {
                        Core.Logger.Debug(LogCategory.Exploration, $"Explore: Selected Nearby Node: [{closestUnvisitedNode.NavigableCenter.X},{closestUnvisitedNode.NavigableCenter.Y},{closestUnvisitedNode.NavigableCenter.Z}] Dist:{closestUnvisitedNode.Distance} {(closestUnvisitedNode.Priority ? "(Priority)" : "")} ");
                        return(closestUnvisitedNode);
                    }
                }

                // Try any univisted node by distance.
                node = ExplorationGrid.Instance.WalkableNodes.Where(n =>
                                                                    !n.IsIgnored &&
                                                                    !n.IsVisited &&
                                                                    !n.IsBlacklisted &&
                                                                                                                   //n.DynamicWorldId == dynamicWorldId &&
                                                                    n.NavigableCenter.DistanceSqr(myPosition) > 20 //&& levelAreaIds.Contains(n.LevelAreaId)
                                                                    )
                       .OrderByDescending(PriorityDistanceFormula)
                       .FirstOrDefault();

                if (node != null)
                {
                    Core.Logger.Debug(LogCategory.Exploration, $"Explore: Selected Nearby Node: [{node.NavigableCenter.X},{node.NavigableCenter.Y},{node.NavigableCenter.Z}] Dist:{node.Distance} {(node.Priority ? "(Priority)" : "")} ");
                    return(node);
                }

                if (ExplorationGrid.Instance.NearestNode != null && !levelAreaIds.Contains(ZetaDia.CurrentLevelAreaSnoId))
                {
                    Core.Logger.Debug("[ExplorationLogic] Adventurer is trying to find nodes that are not in this LevelArea. DefinedIds='{0}' CurrentId='{0}'. Marking current area's nodes as valid.", string.Join(", ", levelAreaIds), ZetaDia.CurrentLevelAreaSnoId);
                    levelAreaIds.Add(ZetaDia.CurrentLevelAreaSnoId);

                    // Ignore level area match
                    node = ExplorationGrid.Instance.WalkableNodes
                           .Where(n =>
                                  !n.IsIgnored &&
                                  !n.IsVisited &&
                                  !n.IsBlacklisted &&
                                  n.DynamicWorldId == dynamicWorldId &&
                                  n.NavigableCenter.DistanceSqr(myPosition) > 100)
                           .OrderByDescending(PriorityDistanceFormula)
                           .FirstOrDefault();
                }

                if (node == null)
                {
                    var allNodes       = ExplorationGrid.Instance.WalkableNodes.Count(n => levelAreaIds.Contains(n.LevelAreaId));
                    var unvisitedNodes = ExplorationGrid.Instance.WalkableNodes.Count(n => !n.IsVisited && levelAreaIds.Contains(n.LevelAreaId));

                    Core.Logger.Log("[ExplorationLogic] Couldn't find any unvisited nodes. Current AdvDia.LevelAreaSnoIdId: {0}, " +
                                    "ZetaDia.CurrentLevelAreaSnoId: {3}, Total Nodes: {1} Unvisited Nodes: {2} Searching In [{4}] HasNavServerData={5}",
                                    AdvDia.CurrentLevelAreaId, allNodes, unvisitedNodes,
                                    ZetaDia.CurrentLevelAreaSnoId, string.Join(", ", levelAreaIds),
                                    AdvDia.MainGridProvider.Width != 0);

                    //Core.Scenes.Reset();
                }

                return(node);
            }
        }