Ejemplo n.º 1
0
        /// <summary>
        /// Constructor for single object name, or for object path
        /// </summary>
        /// <remarks>
        /// Unity object naming is unrestricted. In particular:
        /// - Names can be repeated.
        /// - Names can include the path separator character '/'.
        /// - Names can be empty.
        /// Consequently, a PathName is not guaranteed to uniquely identify a GameObject
        /// Paths are relative to a specified GameObject, so the name
        /// argument must begin and end with GameObject names.
        /// - name = "" matches "" which is a root GameObject
        /// - name = "/" matches "" which is a child of ""
        /// - name = "/" also matches "/" which is a root GameObject
        /// </remarks>
        public PathName(string name, PathStep.Step type = PathStep.Step.Path)
        {
            var step = new PathStep(name, type);

            path = new List <PathStep>();
            path.Add(step);
        }
Ejemplo n.º 2
0
 public PathStep(T data, float gScore = 0, float hScore = 0, PathStep <T> parent = null)
 {
     this.data   = data;
     this.gCost  = gScore;
     this.hCost  = hScore;
     this.parent = parent;
 }
Ejemplo n.º 3
0
        public bool MoveMob(
            Point3d targetPosition)
        {
            bool success = false;

            if (path == null)
            {
                PathComputer pathComputer = new PathComputer();

                success =
                    pathComputer.BlockingPathRequest(
                        moveRequest.Room.runtime_nav_mesh,
                        moveRequest.Room.room_key,
                        new Point3d(mob.Position),
                        new Point3d(targetPosition));

                if (success)
                {
                    RoomKey  roomKey            = moveRequest.Room.room_key;
                    PathStep lastPathStep       = pathComputer.FinalPath[pathComputer.FinalPath.Count - 1];
                    PathStep secondLastPathStep = pathComputer.FinalPath[pathComputer.FinalPath.Count - 2];
                    Vector3d lastPathHeading    = lastPathStep.StepPoint - secondLastPathStep.StepPoint;
                    float    targetAngle        = MathConstants.GetAngleForVector(lastPathHeading);

                    path =
                        new EntityPath()
                    {
                        entity_id = mob.ID,
                        path      = pathComputer.FinalPath
                    };

                    // Post an event that we moved
                    output_game_events.Add(
                        new GameEvent_MobMoved()
                    {
                        mob_id     = mob.ID,
                        room_x     = roomKey.x,
                        room_y     = roomKey.y,
                        room_z     = roomKey.z,
                        from_x     = mob.Position.x,
                        from_y     = mob.Position.y,
                        from_z     = mob.Position.z,
                        from_angle = mob.Angle,
                        to_x       = targetPosition.x,
                        to_y       = targetPosition.y,
                        to_z       = targetPosition.z,
                        to_angle   = targetAngle
                    });

                    // Update the mob position and facing
                    mob.Position = targetPosition;
                    mob.Angle    = targetAngle;

                    // TODO: Update the mob energy based on the distance traveled
                }
            }

            return(success);
        }
Ejemplo n.º 4
0
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return(false);
        }

        PathStep <T> other = (PathStep <T>)obj;

        return(data.Equals(other.data));
    }
Ejemplo n.º 5
0
        /* Inserts step into list at its sorted position. list is sorted by ascending fScore's.
         */
        void InsertPathStep(PathStep <Cell> step, List <PathStep <Cell> > list)
        {
            int i = 0;

            for (; i < list.Count; ++i)
            {
                if (step.fCost <= list[i].fCost)
                {
                    break;
                }
            }
            list.Insert(i, step);
        }
Ejemplo n.º 6
0
 private void SelectRowForStep(PathStep step)
 {
     Invoke(new Action(() =>
     {
         foreach (DataGridViewRow r in dataGridView1.Rows)
         {
             if (r.DataBoundItem == step)
             {
                 dataGridView1.CurrentCell = r.Cells[0];
             }
         }
     }));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Constructor for object path
        /// </summary>
        /// <param name="rootObject">Path ends when root object is reached</param>
        public PathName(GameObject gameObject, GameObject rootObject = null)
        {
            path = new List <PathStep>();
            Transform parent = gameObject.transform;

            while (parent && parent != rootObject?.transform)
            {
                var step = new PathStep(parent.name, PathStep.Step.Name);
                path.Add(step);
                parent = parent.parent;
            }
            path.Reverse();
        }
Ejemplo n.º 8
0
    public List <PathStep> GetPathsGraph(Vector2Int from)
    {
        List <PathStep> pathsGraph = new List <PathStep>();
        PathStep        start      = new PathStep {
            pos = from, reach = new List <PathStep>()
        };

        pathsGraph.Add(start);

        BuildPathsGraphFrom(ref start, ref pathsGraph, new Vector2Int(-1, -1));

        return(pathsGraph);
    }
        /// <summary>
        /// A* algorithm that traverses the graph to find shortest path between set vertices
        /// </summary>
        /// <param name="graph"> <see cref="Graph"/> instance. </param>
        /// <param name="startVertex"> The start <see cref="Vertex"/> of path to calculate minimum distance for. </param>
        /// <param name="endVertex"> The end <see cref="Vertex"/> of path to calculate minimum distance for. </param>
        /// <returns> The shortest (minimum cost) path from starting point to ending point. </returns>
        public Pathway <T> FindPath(IAdjacencyMatrix <T> graph, Vertex <T> start, Vertex <T> target)
        {
            /// System.Collections.Generic.SortedList by default does not allow duplicate items.
            /// Since items are keyed by TotalCost there can be duplicate entries per key.
            var priorityComparer = Comparer <int> .Create((x, y) => (x <= y)? -1 : 1);

            var opened  = new PriorityQueue <int, Vertex <T> >(priorityComparer);
            var visited = new PriorityQueue <int, Vertex <T> >(priorityComparer);
            var path    = new Dictionary <Vertex <T>, PathStep <T> >();

            // Resets the AStar algorithm with the newly specified start node and goal node.
            var current           = start;
            int estimatedDistance = _distanceMesureable.MesureDistance(start, target);

            path[start] = new PathStep <T>(start, null, 0, estimatedDistance);
            opened.Enqueue(path[start].TotalCost, start);

            // Continue searching until either failure or the goal node has been found.
            AlgorithmState state = AlgorithmState.Searching;

            while (state == AlgorithmState.Searching)
            {
                current = GetNext(opened, visited);

                if (current == null)
                {
                    state = AlgorithmState.PathDoesNotExist;
                    break;
                }

                // Remove from the open list and place on the closed list
                // since this node is now being searched.
                visited.Enqueue(path[current].TotalCost, current);

                // Found the goal, stop searching.
                if (current.Equals(target))
                {
                    state = AlgorithmState.PathFound;
                    break;
                }

                ExtendOpened(opened, visited, current, target, path);
            }

            ICollection <Vertex <T> > vertices = ReconstructPath(current, path);
            int totalDistance = current != null && path.ContainsKey(current) ? path[current].MovementCost : 0;

            return(new Pathway <T>(vertices, totalDistance, state));
        }
Ejemplo n.º 10
0
    //this is main function of pathStep, which spawn inumerable objects around if there are no walls in the vicinity
    //the spawned objects will go on doing the same thing until one of their location is next to the player
    //along with each object is a string that show how to get to the starting point to its position
    IEnumerable SmallStep()
    {
        if (this.transform.position == pathManager.Destination())
        {
            pathManager.WayIsFound(theWay);
            iFindTheWay = true;
        }
        wallCheckUp    = Physics2D.Linecast(this.transform.position, new Vector3(this.transform.position.x, this.transform.position.y + 1, 0), wall);
        wallCheckDown  = Physics2D.Linecast(this.transform.position, new Vector3(this.transform.position.x, this.transform.position.y - 1, 0), wall);
        wallCheckLeft  = Physics2D.Linecast(this.transform.position, new Vector3(this.transform.position.x - 1, this.transform.position.y, 0), wall);
        wallCheckRight = Physics2D.Linecast(this.transform.position, new Vector3(this.transform.position.x + 1, this.transform.position.y, 0), wall);

        if (wallCheckLeft.collider == null)
        {
            stepLeft        = Instantiate(step, new Vector3(this.transform.position.x - 1, this.transform.position.y, 0), Quaternion.Euler(new Vector3(0, 0, 0)), pathManager.transform) as PathStep;
            stepLeft.theWay = this.theWay + "a;";
            stepLeft.gameObject.SetActive(true);
            theWay = rememberTheWay;
        }
        if (wallCheckUp.collider == null)
        {
            //stepUp = new PathStep();
            stepUp        = Instantiate(step, new Vector3(this.transform.position.x, this.transform.position.y + 1, 0), Quaternion.Euler(new Vector3(0, 0, 0)), pathManager.transform) as PathStep;
            stepUp.theWay = this.theWay + "w;";
            stepUp.gameObject.SetActive(true);
            theWay = rememberTheWay;
        }
        if (wallCheckDown.collider == null)
        {
            //stepDown = new PathStep();
            stepDown        = Instantiate(step, new Vector3(this.transform.position.x, this.transform.position.y - 1, 0), Quaternion.Euler(new Vector3(0, 0, 0)), pathManager.transform) as PathStep;
            stepDown.theWay = this.theWay + "s;";
            stepDown.gameObject.SetActive(true);
            theWay = rememberTheWay;
        }

        if (wallCheckRight.collider == null)
        {
            // stepRight = new PathStep();
            stepRight        = Instantiate(step, new Vector3(this.transform.position.x + 1, this.transform.position.y, 0), Quaternion.Euler(new Vector3(0, 0, 0)), pathManager.transform) as PathStep;
            stepRight.theWay = this.theWay + "d;";
            stepRight.gameObject.SetActive(true);
            theWay = rememberTheWay;
        }
        return(null);
    }
Ejemplo n.º 11
0
    public List <DijkstraStep> GetSubGraph(Vector2Int from, List <PathStep> graph)
    {
        // SubGraph and a copy to keep track of processed elements
        List <DijkstraStep> subGraph    = new List <DijkstraStep>();
        List <DijkstraStep> unprocessed = new List <DijkstraStep>();

        // Subgraphes initialization
        foreach (PathStep step in graph)
        {
            DijkstraStep ds = new DijkstraStep {
                pathStep = step, weight = (step.pos == from) ? 0 : int.MaxValue, prev = null
            };
            subGraph.Add(ds);
            unprocessed.Add(ds);
        }

        // Computes subgraph values: shorter distances, previous element
        while (unprocessed.Count > 0)
        {
            DijkstraStep current = new DijkstraStep {
                pathStep = null, prev = null, weight = int.MaxValue
            };
            foreach (DijkstraStep ds in unprocessed)
            {
                if (ds.weight < current.weight)
                {
                    current = ds;
                }
            }

            foreach (PathStep next in current.pathStep.reach)
            {
                DijkstraStep dijkstraNext = subGraph.Find(n => n.pathStep == next);
                if (dijkstraNext.weight > current.weight + PathStep.Distance(current.pathStep, dijkstraNext.pathStep))
                {
                    dijkstraNext.weight = current.weight + PathStep.Distance(current.pathStep, dijkstraNext.pathStep);
                    dijkstraNext.prev   = current;
                }
            }

            unprocessed.Remove(current);
        }

        return(subGraph);
    }
Ejemplo n.º 12
0
 private void AddPathSteps(char[][] maze, PathStep currentStep)
 {
     // checks for all possible moves of the currentStep
     foreach (var move in _possibleMoves)
     {
         var nextX = currentStep.X + move[0];
         var nextY = currentStep.Y + move[1];
         if (IsValidPathStep(maze, currentStep.Y, nextX, nextY))
         {
             // adds the next step to _pathQueue while retaining the currentStep as part of the next step and set as visited
             var nextStep = new PathStep {
                 X = nextX, Y = nextY, PreviousStep = currentStep
             };
             _pathQueue.Enqueue(nextStep);
             _visitedPaths[nextY, nextX] = true;
         }
     }
 }
Ejemplo n.º 13
0
        private char[][] GetSolvedMaze(char[][] maze, PathStep currentStep)
        {
            _totalMazeSteps = 0;

            // loops through all previous steps totaling all maze steps
            // and adding @ symbol to designate the completed path through the maze.
            do
            {
                _totalMazeSteps++;
                currentStep = currentStep.PreviousStep;
                if (maze[currentStep.Y][currentStep.X] != 'A')
                {
                    maze[currentStep.Y][currentStep.X] = '@';
                }
            } while (currentStep.PreviousStep != null);

            return(maze);
        }
Ejemplo n.º 14
0
        private static object SlowGetMemberValue(PathStep step, object instance)
        {
            switch (step.StepType)
            {
            case PathStepType.Member:
            {
                FieldInfo field = step.Member as FieldInfo;
                if (field != null)
                {
                    if (field.IsLiteral)
                    {
                        return(field.GetRawConstantValue());
                    }
                    return(field.GetValue(instance));
                }

                PropertyInfo prop = step.Member as PropertyInfo;
                if (prop != null)
                {
                    return(prop.GetValue(instance, null));
                }

                MethodInfo method = step.Member as MethodInfo;
                if (method != null)
                {
                    return(method.Invoke(instance, null));
                }

                throw new NotSupportedException(step.Member.GetType().GetNiceName());
            }

            case PathStepType.WeakListElement:
                return(WeakListGetItem.Invoke(instance, new object[] { step.ElementIndex }));

            case PathStepType.ArrayElement:
                return((instance as Array).GetValue(step.ElementIndex));

            case PathStepType.StrongListElement:
                return(step.StrongListGetItemMethod.Invoke(instance, new object[] { step.ElementIndex }));

            default:
                throw new NotImplementedException(step.StepType.ToString());
            }
        }
Ejemplo n.º 15
0
    private void BuildPathsGraphFrom(ref PathStep from, ref List <PathStep> pathsGraph, Vector2Int previousPos)
    {
        List <Vector2Int> reachablePositions = FindReachExcluding(from.pos, previousPos);

        foreach (Vector2Int position in reachablePositions)
        {
            PathStep nextStep = pathsGraph.Find(p => p.pos == position);

            if (nextStep == null)
            {
                nextStep = new PathStep {
                    pos = position, reach = new List <PathStep>()
                };
                pathsGraph.Add(nextStep);
                BuildPathsGraphFrom(ref nextStep, ref pathsGraph, from.pos);
            }

            from.reach.Add(nextStep);
        }
    }
 private void ExtendOpened(
     PriorityQueue <int, Vertex <T> > opened,
     PriorityQueue <int, Vertex <T> > visited,
     Vertex <T> current,
     Vertex <T> target,
     Dictionary <Vertex <T>, PathStep <T> > path)
 {
     foreach (var neighbor in current.Neighbors)
     {
         // If the child has already been visited (closed list) or is on
         // the open list to be searched then do not modify its movement cost
         // or estimated cost since they have already been set previously.
         if (!visited.ContainsValue(neighbor) && !opened.ContainsValue(neighbor))
         {
             // Each child needs to have its movement cost set and estimated cost.
             int estimatedDistance = _distanceMesureable.MesureDistance(neighbor, target);
             path[neighbor] = new PathStep <T>(neighbor, current, path[current].MovementCost, estimatedDistance);
             opened.Enqueue(path[neighbor].TotalCost, neighbor);
         }
     }
 }
Ejemplo n.º 17
0
        private char[][] GetMazeSolution(char[][] maze)
        {
            _pathQueue.Enqueue(new PathStep {
                X = _startingStep[0], Y = _startingStep[1]
            });

            while (_pathQueue.Count > 0)
            {
                PathStep currentStep = _pathQueue.Dequeue();

                if (currentStep.X == _endStep[0] && currentStep.Y == _endStep[1])
                {
                    // returns array that represents the solved maze
                    return(GetSolvedMaze(maze, currentStep));
                }

                AddPathSteps(maze, currentStep);
            }

            return(maze);
        }
Ejemplo n.º 18
0
        private static void SlowSetMemberValue(PathStep step, object instance, object value)
        {
            switch (step.StepType)
            {
            case PathStepType.Member:
            {
                FieldInfo field = step.Member as FieldInfo;
                if (field != null)
                {
                    field.SetValue(instance, value);
                    break;
                }

                PropertyInfo prop = step.Member as PropertyInfo;
                if (prop != null)
                {
                    prop.SetValue(instance, value, null);
                    break;
                }

                throw new NotSupportedException(step.Member.GetType().GetNiceName());
            }

            case PathStepType.WeakListElement:
                WeakListSetItem.Invoke(instance, new object[] { step.ElementIndex, value });
                break;

            case PathStepType.ArrayElement:
                (instance as Array).SetValue(value, step.ElementIndex);
                break;

            case PathStepType.StrongListElement:
                var setItemMethod = typeof(IList <>).MakeGenericType(step.ElementType).GetMethod("set_Item");
                setItemMethod.Invoke(instance, new object[] { step.ElementIndex, value });
                break;

            default:
                throw new NotImplementedException(step.StepType.ToString());
            }
        }
Ejemplo n.º 19
0
    public List <Vector2Int> FindShorterPathFromTo(Vector2Int from, Vector2Int to, List <PathStep> graph)
    {
        // Find from and end postitions in graph
        PathStep start = null, end = null;

        if (graph != null)
        {
            start = graph.Find(step => step.pos == from);
            end   = graph.Find(step => step.pos == to);
        }

        if (graph == null || start == null || end == null)
        {
            Debug.Log("No path!");
            return(null);
        }

        // Output initialization
        List <Vector2Int> path = new List <Vector2Int>();

        // Build Subgraph
        List <DijkstraStep> subGraph = GetSubGraph(from, graph);

        // Retrieves shorter path step by step, from end to start
        DijkstraStep shortestPathStep = subGraph.Find(s => s.pathStep == end);

        while (shortestPathStep.pathStep != start)
        {
            path.Add(shortestPathStep.pathStep.pos);
            shortestPathStep = shortestPathStep.prev;
        }
        path.Add(start.pos);

        // Revert path so it's from start to end
        path.Reverse();

        return(path);
    }
Ejemplo n.º 20
0
    public static bool GetPath(Vec2I StartPos, Vec2I EndPos, int maxDistance, out Vec2I[] path)
    {
        if (StartPos == EndPos)
        {
            path    = new Vec2I[1];
            path[0] = EndPos;
            return(true);
        }

        path = null;

        if (Vec2I.Max(StartPos, EndPos) > maxDistance)
        {
            return(false);
        }
        if (Heatmap.GetNode(EndPos) == null)
        {
            return(false);
        }

        HeatmapNode startNode = Heatmap.GetNode(StartPos);

        if (startNode == null)
        {
            return(false);
        }

        //init arrays
        int arraySize = maxDistance * 2 + 1;

        bool[,] closedCheck   = new bool[arraySize, arraySize];
        bool[,] openCheck     = new bool[arraySize, arraySize];
        Vec2I[,] parent       = new Vec2I[arraySize, arraySize];
        PathStep[,] openArray = new PathStep[arraySize, arraySize];

        //set start point
        BinaryHeap <PathStep> openList = new BinaryHeap <PathStep>(arraySize * arraySize);

        openList.Add(new PathStep(startNode, Heuristic(StartPos, EndPos)));
        openCheck[maxDistance, maxDistance] = true;
        parent[maxDistance, maxDistance]    = StartPos;

        bool found = false;

        while (openList.ItemCount > 0)
        {
            //get top of heap
            PathStep current = openList.RemoveFirst();
            int      cx      = current.node.gridPos.x - StartPos.x + maxDistance;
            int      cy      = current.node.gridPos.y - StartPos.y + maxDistance;
            closedCheck[cx, cy] = true;

            foreach (HeatmapNode neighbor in current.node.neighbors)
            {
                //calculate array position
                int nx = neighbor.gridPos.x - StartPos.x + maxDistance;
                int ny = neighbor.gridPos.y - StartPos.y + maxDistance;

                //cull disallowed
                if (Vec2I.Max(neighbor.gridPos, StartPos) > maxDistance)
                {
                    continue;
                }
                if (closedCheck[nx, ny])
                {
                    continue;
                }
                if (!CanTravel(current.node, neighbor))
                {
                    continue;
                }

                //found target
                if (neighbor.gridPos == EndPos)
                {
                    parent[nx, ny] = current.node.gridPos;
                    found          = true;
                    goto finalize;
                }

                //calculate cost
                int travelCost = current.travelCost + TravelCostAstar(current.node, neighbor);
                int heuristic  = Heuristic(neighbor.gridPos, EndPos);
                int fullCost   = travelCost + heuristic;

                //check if we can update parent to better
                if (openCheck[nx, ny])
                {
                    if (openArray[nx, ny].fullCost > fullCost)
                    {
                        openArray[nx, ny].travelCost = travelCost;
                        openArray[nx, ny].heuristic  = heuristic;
                        openArray[nx, ny].fullCost   = fullCost;
                        parent[nx, ny] = current.node.gridPos;
                        openList.UpdateItem(openArray[nx, ny]);
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }

                //priority sorted by heap
                PathStep step = new PathStep(neighbor, travelCost, heuristic);
                openList.Add(step);
                openArray[nx, ny] = step;
                openCheck[nx, ny] = true;
                parent[nx, ny]    = current.node.gridPos;
            }
        }

finalize:
        if (found)
        {
            SingleLinkedList <Vec2I> list = new SingleLinkedList <Vec2I>();

            Vec2I current = EndPos;
            while (current != StartPos)
            {
                list.InsertFront(current);
                current = parent[current.x - StartPos.x + maxDistance, current.y - StartPos.y + maxDistance];
            }
            list.InsertFront(current); //adds the starting point to the path
            path = list.ToArray();
            return(true);
        }

        return(false);
    }
Ejemplo n.º 21
0
    public override void IterateOpenSet()
    {
        //Track how many iterations have taken place to find this pathway
        OpenSetIterations++;

        //Once the openset has been exhausted its time to complete the pathway
        if (OpenSet.Count <= 0)
        {
            //Get the completed pathway
            List <Node> Pathway = GridManager.Instance.GetCompletedPathway(PathStart, PathEnd);

            //If the path is empty, then no pathway was able to be found between the target nodes
            if (Pathway == null)
            {
                //Print a failure message and reset the grid
                Log.Print("Unable to find a valid pathway using Dijkstras algorithm.");
                FindingPathway = false;
                GridManager.Instance.HideAllParentIndicators();
                return;
            }

            //Announce the pathway has been found
            Log.Print("Dijkstras pathfinding completed after " + OpenSetIterations + " iterations.");

            //Hide all the neighbour indicators
            GridManager.Instance.HideAllParentIndicators();

            //Change the type of all nodes in the pathway to display it in the game
            foreach (Node PathStep in Pathway)
            {
                PathStep.SetType(NodeType.Pathway);
            }

            //Complete the process
            FindingPathway = false;
            return;
        }

        //Find the new current node, then iterate through all its neighbours
        Node Current = GridManager.Instance.FindCheapestNode(OpenSet);

        OpenSet.Remove(Current);
        foreach (Node Neighbour in GridManager.Instance.GetTraversableNeighbours(Current))
        {
            //Ignore nodes not listed in the open set
            if (!OpenSet.Contains(Neighbour))
            {
                continue;
            }

            //check if its cheaper to travel over this neighbour
            float NeighbourCost = Current.FScore + GridManager.FindHeuristic(Current, Neighbour);
            if (NeighbourCost < Neighbour.FScore)
            {
                //update this neighbour as the best way to travel
                Neighbour.FScore = NeighbourCost;
                Neighbour.Parent = Current;
                Neighbour.ToggleParentIndicator(true);
                Neighbour.PointIndicator(Neighbour.GetDirection(Current));
            }
        }
    }
Ejemplo n.º 22
0
 private static bool AreEqual(PathStep first, PathStep second)
 {
     return(first.Equals(second)); // PathStep is a struct
 }
Ejemplo n.º 23
0
    //AI Algorithm to create a path between and around impassible objects using OccupiedGrid as a reference
    //and then converting it to world space thanks to GridDimension
    //Takes a point (x and y) for start and destination
    //point is declared in PathStep.cs, along with the constructor for PathStep
    //Called by GuardBrain.cs
    //Realistically, you almost never need to do this and you could just use Unity's Navmesh tools to do this in like 2 lines of code.
    //This is also extremely resource intensive and the game will noticably hitch everytime you call this function.
    //But because Unity2d is basically incomplete, we have no choice
    public List <point> GeneratePath(point start, point destination)
    {
        //Create a queue of points for GuardBrain to test for navigation
        Queue <PathStep> unVisited = new Queue <PathStep>();
        //When points are processed by unVisited, it gets added to visited
        List <point> Visited = new List <point>();

        //Start by Enqueuing (Putting into the end of the queue) the start position
        unVisited.Enqueue(new PathStep(start, null));
        //When every point on the path has been checked, Unvisited will be equal to 0 and and leave the while loop
        while (unVisited.Count > 0)
        {
            //Start by removing the first item from unVisited and putting into a temp PathStep.
            //This increments the while and lets us work with its value easier
            PathStep thisStep = unVisited.Dequeue();
            //Check if the point we're testing is our destination. If it is, finalize the path and pass it along to GuardBrain
            if (thisStep.position.Equals(destination))
            {
                //Create a list of the points used to reach the destination.
                //Because we used a queue starting from the start, when things get put into this list, they'll start from the destination instead
                List <point> path = new List <point>();
                //Create a holder for our last step
                PathStep cur = thisStep;
                //add the first item to our path
                path.Add(cur.position);
                //Each PathStep also holds the data for the step it took before that.
                //This allows us to work our way backwards through where we've been to figure out where we need to go
                //This while loop keeps checking the previous step until it gets to a PathStep that doesn't have a previous step
                //This is the first step, and it means our path is built.
                while (cur.previous != null)
                {
                    //switch which PathStep we're working with
                    cur = cur.previous;
                    //Add it to the path
                    path.Add(cur.position);
                }
                //Once we have all our points, we can reverse the path so the start is now first and the AI can go through them properly.
                path.Reverse();
                //Send the path to the object that caled this function.
                return(path);
            }
            //Until we have our destination, we need to try the squares above, below, to the right, and to the left of this
            //try-catch lets you do something that may crash the game, and when it would crash, simply doesn't do it and runs whatever is in catch instead
            //In this case, we're doing it to prevent an ArrayOutOfBounds if we try to check a point that doesn't exist (Like if we're on the top row and try to check the row above us)
            try
            {
                //x-1 would be the step to the left of our current one, for example.
                if (!OccupiedGrid[thisStep.position.x - 1, thisStep.position.y])
                {
                    //If the grid space isn't occupied, it checks to make usre we haven't already checed that space, and if we haven't...
                    if (!Visited.Contains(new point(thisStep.position.x - 1, thisStep.position.y)))
                    {
                        //...it enqueues it for unVisited.
                        unVisited.Enqueue(new PathStep(new point(thisStep.position.x - 1, thisStep.position.y), thisStep));
                    }
                }
            }catch { }
            try
            {
                if (!OccupiedGrid[thisStep.position.x + 1, thisStep.position.y])
                {
                    if (!Visited.Contains(new point(thisStep.position.x + 1, thisStep.position.y)))
                    {
                        unVisited.Enqueue(new PathStep(new point(thisStep.position.x + 1, thisStep.position.y), thisStep));
                    }
                }
            }
            catch { }
            try
            {
                if (!OccupiedGrid[thisStep.position.x, thisStep.position.y - 1])
                {
                    if (!Visited.Contains(new point(thisStep.position.x, thisStep.position.y - 1)))
                    {
                        unVisited.Enqueue(new PathStep(new point(thisStep.position.x, thisStep.position.y - 1), thisStep));
                    }
                }
            }
            catch { }
            try
            {
                if (!OccupiedGrid[thisStep.position.x, thisStep.position.y + 1])
                {
                    if (!Visited.Contains(new point(thisStep.position.x, thisStep.position.y + 1)))
                    {
                        unVisited.Enqueue(new PathStep(new point(thisStep.position.x, thisStep.position.y + 1), thisStep));
                    }
                }
            }
            catch { }
        }
        //If no path could be found, return null to avoid crashing anything
        return(null);
    }
Ejemplo n.º 24
0
        void CreatePath(Cell origin, Cell destination)
        {
            List <PathStep <Cell> >    openSteps   = new List <PathStep <Cell> >();
            HashSet <PathStep <Cell> > closedSteps = new HashSet <PathStep <Cell> >();

            openSteps.Add(new PathStep <Cell>(origin));

            do
            {
                // Pop the next step in openSteps
                PathStep <Cell> curStep = openSteps.First();
                Cell            curCell = curStep.data;
                openSteps.RemoveAt(0);

                closedSteps.Add(curStep);

                // Destination reached, carve the path.
                if (curStep.data.Equals(destination))
                {
                    do
                    {
                        if (curStep.parent != null)
                        {
                            curCell = curStep.data;
                            curCell.Empty();
                        }
                        curStep = curStep.parent;
                    } while (curStep != null);
                    return;
                }

                List <Cell> adjacentCells = GetAdjacentCells(curCell);

                // Perform A* search to find shortest path.
                foreach (Cell adjCell in adjacentCells)
                {
                    PathStep <Cell> step     = new PathStep <Cell>(adjCell);
                    Cell            stepCell = step.data;

                    // Only proceed if the nextStep is not already in the closedSteps.
                    if (!closedSteps.Contains(step))
                    {
                        float moveCost = GetCostForStep(curCell, stepCell);
                        step.parent = curStep;
                        step.gCost  = curStep.gCost + moveCost;

                        // Check if the nextStep is already in the openSteps
                        int stepIndex = openSteps.IndexOf(step);

                        // nextStep is not in openSteps, so add it.
                        if (stepIndex == -1)
                        {
                            step.hCost = GetCostForStep(stepCell, destination);
                            InsertPathStep(step, openSteps);
                        }
                        // nextStep is already in openSteps, so update its score.
                        else
                        {
                            // If the current path gives nextStep a better gScore than its existing
                            // gScore, remove the existing and insert step.
                            if (curStep.gCost + moveCost < openSteps[stepIndex].gCost)
                            {
                                step.hCost = openSteps[stepIndex].hCost;
                                openSteps.RemoveAt(stepIndex);
                                InsertPathStep(step, openSteps);
                            }
                        }
                    }
                }
            } while (openSteps.Count > 0);
        }
Ejemplo n.º 25
0
        private void UpdateAIPropVisibility(
            MobUpdateContext context)
        {
            Mob     ownerMob = context.mob;
            NavMesh navMesh  = context.moveRequest.Room.runtime_nav_mesh;

            foreach (EntityProp prop in ai_props)
            {
                Point3d oldPropPosition = prop.GetPosition();

                // Find the player associated with the player id
                MobUpdateContext otherMobContext = context.moveRequest.MobContexts.Find(m => m.mob.ID == prop.target_object_id);
                Mob otherMob = otherMobContext.mob;

                // Can the mob see the other mob at their current location
                bool canSee = CanMobSeePoint(navMesh, ownerMob, otherMob.Position);

                TypedFlags <EntityProp.ePropVisibilityFlags> oldVisibilityFlags =
                    new TypedFlags <EntityProp.ePropVisibilityFlags>(prop.visibilityFlags);

                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.canSee, canSee);
                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.caughtGlimpse, canSee);

                if (canSee)
                {
                    // If so, we get to pull the entity properties
                    prop.RefeshEntityProperties(ownerMob, otherMob);
                    prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.seenAtLeastOnce, true);
                }
                else
                {
                    EntityPath entityPath = otherMobContext.path;

                    if (entityPath != null)
                    {
                        // Find the last place we saw the player along their path, if at all
                        for (int pathStepIndex = entityPath.path.Count - 1; pathStepIndex >= 0; pathStepIndex--)
                        {
                            PathStep pathStep = entityPath.path[pathStepIndex];

                            if (CanMobSeePoint(navMesh, ownerMob, pathStep.StepPoint))
                            {
                                prop.position_x = pathStep.StepPoint.x;
                                prop.position_y = pathStep.StepPoint.y;
                                prop.position_z = pathStep.StepPoint.z;
                                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.caughtGlimpse, true);
                                prop.visibilityFlags.Set(EntityProp.ePropVisibilityFlags.seenAtLeastOnce, true);
                                break;
                            }
                        }
                    }
                }

                // Post an event if we just spotted another mob that we've never seen before
                if (!oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) &&
                    !oldVisibilityFlags.Test(EntityProp.ePropVisibilityFlags.seenAtLeastOnce) &&
                    (prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.canSee) ||
                     prop.visibilityFlags.Test(EntityProp.ePropVisibilityFlags.caughtGlimpse)))
                {
                    context.output_game_events.Add(
                        new GameEvent_MobAIPropSpotted()
                    {
                        mob_id         = ownerMob.ID,
                        spotted_mob_id = prop.target_object_id,
                        x = prop.position_x,
                        y = prop.position_y,
                        z = prop.position_z
                    });
                }
            }
        }
Ejemplo n.º 26
0
    public override void IterateOpenSet()
    {
        //Track how many times the open set has been iterated over
        OpenSetIterations++;

        //If the open set is empty, then no pathway could be found
        if (OpenSet.Count <= 0)
        {
            //Print a failure message and reset the grid
            Log.Print("Unable to find a valid pathway using Theta* algorithm, after a total " + OpenSetIterations + " iterations.");
            FindingPathway = false;
            GridManager.Instance.HideAllParentIndicators();
            return;
        }

        //Grab the node from open set with the lowest FScore value, move it from the OpenSet to the ClosedSet
        Node Current = GridManager.Instance.FindCheapestNode(OpenSet);

        OpenSet.Remove(Current);
        ClosedSet.Add(Current);

        //If the Current node is the EndNode, then the pathway has been found
        if (Current == PathEnd)
        {
            //Announce the pathway has been found
            Log.Print("Theta* pathfinding complete after " + OpenSetIterations + " iterations.");

            //Hide all nodes parent indicators
            GridManager.Instance.HideAllParentIndicators();

            //Get the completed pathway
            List <Node> FinalPathway = GridManager.Instance.GetCompletedPathway(PathStart, PathEnd);

            //Change all pathway node types so the completed pathway is displayed
            foreach (Node PathStep in FinalPathway)
            {
                PathStep.SetType(NodeType.Pathway);
            }

            //Finalize the pathfinding process
            FindingPathway = false;
            return;
        }

        //Go through all the current nodes neighbours
        foreach (Node Neighbour in GridManager.Instance.GetTraversableNeighbours(Current))
        {
            //Ignore neighbours in the closed list
            if (ClosedSet.Contains(Neighbour))
            {
                continue;
            }

            if (!OpenSet.Contains(Neighbour))
            {
                Neighbour.GScore = Mathf.Infinity;
                Neighbour.Parent = null;
            }

            UpdateNode(Current, Neighbour);
        }
    }
Ejemplo n.º 27
0
        private AssertionContext ProcessPathPartWithWildcardForArId(AssertionContext contextObj, PathStep pathStep)
        {
            DesignByContract.Check.Require(pathStep.Attribute == "//*", "anyAttribute value must be //*.");

            Locatable locatable = contextObj.Data as Locatable;
            if (locatable != null)
            {

                ArchetypedPathProcessor archetypePathProcessor = new ArchetypedPathProcessor(locatable);
                string archetypePathWithWildcardKey = null;
                if (!string.IsNullOrEmpty(pathStep.ArchetypeNodeId))
                    archetypePathWithWildcardKey = pathStep.Attribute + "[" + pathStep.ArchetypeNodeId + "]";
                else if (!string.IsNullOrEmpty(pathStep.NodePattern))
                    archetypePathWithWildcardKey = pathStep.Attribute + "[{/" + pathStep.NodePattern + "/}]";
                else
                    throw new NotSupportedException(pathStep.Value+" path not supported");
                object obj = null;
                if (!archetypePathProcessor.PathExists(archetypePathWithWildcardKey))
                    return null;

                if (archetypePathProcessor.PathUnique(archetypePathWithWildcardKey))
                    obj = archetypePathProcessor.ItemAtPath(archetypePathWithWildcardKey);
                else
                    obj = archetypePathProcessor.ItemsAtPath(archetypePathWithWildcardKey);

                if (obj == null)
                    throw new ApplicationException("obj must not be null.");

                return new AssertionContext(obj, contextObj);
            }

            AssumedTypes.IList ilist = contextObj.Data as AssumedTypes.IList;
            if (ilist == null)
                throw new ApplicationException("only support either locatable or ilist");
            AssumedTypes.List<object> results = new OpenEhr.AssumedTypes.List<object>();
            foreach (Locatable locatableItem in ilist)
            {
                AssertionContext assertionContext = new AssertionContext(locatableItem, contextObj);
                AssertionContext result = ProcessPathPartWithWildcardForArId(assertionContext, pathStep);
                if (result != null && result.Data != null)
                    results.Add(result.Data);
            }

            if (results.Count > 0)
                return new AssertionContext(results, contextObj);

            return null;
        }
Ejemplo n.º 28
0
        private AssertionContext ProcessPathPartWithAttrObject(AssertionContext attributeObjContext, PathStep pathStep)
        {
            DesignByContract.Check.Require(attributeObjContext != null && attributeObjContext.Data != null,
                    "attributeObjContext and attributeObjContext.Data must not be null.");

            AssertionContext tempContext = attributeObjContext;

            if (pathStep.Predicates != null)
            {
                foreach (PredicateExpr predicate in pathStep.Predicates)
                {
                    AssertionContext predicateObj = predicate.Evaluate(tempContext);

                    if (predicateObj == null)
                        return null;

                    tempContext = predicateObj;
                }
            }

            return tempContext;
        }
Ejemplo n.º 29
0
    //optimized A* pathfinding
    public static bool GetPath(Vec2I StartPoint, Vec2I EndPoint, int maxDistance, out Vec2I[] path)
    {
        if (StartPoint == EndPoint)
        {
            path    = new Vec2I[1];
            path[0] = EndPoint;
            return(true);
        }

        path = null;

        if (AxMath.RogueDistance(StartPoint, EndPoint) > maxDistance)
        {
            return(false);
        }
        if (GetHeat(StartPoint).x == -1)
        {
            return(false);
        }
        if (GetHeat(EndPoint).x == -1)
        {
            return(false);
        }

        //init arrays
        int arraySize = maxDistance * 2 + 1;

        bool[,] closedCheck   = new bool[arraySize, arraySize];
        bool[,] openCheck     = new bool[arraySize, arraySize];
        Vec2I[,] parents      = new Vec2I[arraySize, arraySize];
        PathStep[,] openArray = new PathStep[arraySize, arraySize];

        //set start point
        BinaryHeap <PathStep> openList = new BinaryHeap <PathStep>(arraySize * arraySize);

        openList.Add(new PathStep(StartPoint, AxMath.WeightedDistance(StartPoint, EndPoint)));
        openCheck[maxDistance, maxDistance] = true;
        parents[maxDistance, maxDistance]   = StartPoint;

        bool found = false;

        while (openList.ItemCount > 0)
        {
            //get top of heap
            PathStep current = openList.RemoveFirst();
            closedCheck[current.position.x - StartPoint.x + maxDistance, current.position.y - StartPoint.y + maxDistance] = true;

            foreach (Vec2I neighbor in current.position.neighbors)
            {
                //calculate array position
                int arrayX = neighbor.x - StartPoint.x + maxDistance;
                int arrayY = neighbor.y - StartPoint.y + maxDistance;

                //cull disallowed
                if (AxMath.RogueDistance(neighbor, StartPoint) > maxDistance)
                {
                    continue;
                }
                if (closedCheck[arrayX, arrayY])
                {
                    continue;
                }

                //found target
                if (neighbor == EndPoint)
                {
                    parents[arrayX, arrayY] = current.position;
                    found = true;
                    goto finalize;
                }

                if (!CanPath(neighbor))
                {
                    continue;
                }

                //calculate cost
                int travelCost = current.travelCost + AxMath.WeightedDistance(current.position, neighbor);
                int heuristic  = AxMath.WeightedDistance(neighbor, EndPoint);
                int fullCost   = travelCost + heuristic;

                //check if we can update parent to better
                if (openCheck[arrayX, arrayY])
                {
                    if (openArray[arrayX, arrayY].travelCost > travelCost)
                    {
                        openArray[arrayX, arrayY].travelCost = travelCost;
                        openArray[arrayX, arrayY].heuristic  = heuristic;
                        openArray[arrayX, arrayY].fullCost   = fullCost;
                        parents[arrayX, arrayY] = current.position;
                        openList.UpdateItem(openArray[arrayX, arrayY]);
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }

                //priority sorted by heap
                PathStep step = new PathStep(neighbor, travelCost, heuristic);
                openList.Add(step);
                openCheck[arrayX, arrayY] = true;
                openArray[arrayX, arrayY] = step;
                parents[arrayX, arrayY]   = current.position;
            }
        }

finalize:
        if (found)
        {
            SingleLinkedList <Vec2I> list = new SingleLinkedList <Vec2I>();

            Vec2I current = EndPoint;
            while (current != StartPoint)
            {
                list.InsertFront(current);
                current = parents[current.x - StartPoint.x + maxDistance, current.y - StartPoint.y + maxDistance];
            }
            //list.InsertFront(current); //adds the starting point to the path
            path = list.ToArray();
            return(true);
        }

        return(false);
    }
Ejemplo n.º 30
0
    public override void IterateOpenSet()
    {
        //Track how many iterations have taken place to find this pathway so far
        OpenSetIterations++;

        //If the open set is empty, then no pathway was able to be found
        if (OpenSet.Count <= 0)
        {
            //Print a failure message and reset the grid
            Log.Print("Unable to find a valid pathway using A* algorithm.");
            FindingPathway = false;
            GridManager.Instance.HideAllParentIndicators();
            return;
        }

        //Get the cheapest node currently being stored in the open set
        Node Current = GridManager.Instance.FindCheapestNode(OpenSet);

        OpenSet.Remove(Current);

        //When Current matches the end node, the pathway is ready to be reconstructed
        if (Current == PathEnd)
        {
            //Announce the pathway has been found and how long it took to find
            Log.Print("A* pathfinding completed after " + OpenSetIterations + " iterations.");

            //Hide all parent indicators
            GridManager.Instance.HideAllParentIndicators();

            //Grab and display the final pathway
            List <Node> Pathway = GridManager.Instance.GetCompletedPathway(PathStart, PathEnd);
            foreach (Node PathStep in Pathway)
            {
                PathStep.SetType(NodeType.Pathway);
            }

            //Finalize the process
            FindingPathway = false;
            return;
        }

        //Remove the current node from the open set, then iterate over its neighbours
        OpenSet.Remove(Current);
        foreach (Node Neighbour in GridManager.Instance.GetTraversableNeighbours(Current))
        {
            if (Current.GScore < Neighbour.GScore)
            {
                //Update this as the preferred way to travel
                Neighbour.Parent = Current;
                Neighbour.ToggleParentIndicator(true);
                Neighbour.PointIndicator(Neighbour.GetDirection(Current));

                //Update neighbours score values
                Neighbour.GScore = Current.GScore;
                Neighbour.FScore = Neighbour.GScore + GridManager.FindHeuristic(Neighbour, PathEnd);

                //Add neighbour to open set if its not there already
                if (!OpenSet.Contains(Neighbour))
                {
                    OpenSet.Add(Neighbour);
                }
            }
        }
    }
Ejemplo n.º 31
0
    public PathStep previous; //The PathStep that was used before this
    // Use this for initialization

    public PathStep(point position, PathStep previous)
    {
        this.position = position;
        this.previous = previous;
    }
Ejemplo n.º 32
0
    //same as previous, but take into account movement cost of cells
    public static void FillPlayerBreath(ref BreathArea breath, ref List <ThingController> monstersList, bool cullByTrueDistance = false)
    {
        int   maxDistance = breath.maxDistance;
        int   arraySize   = breath.size;
        Vec2I StartPoint  = breath.position;

        breath.Invalidate();
        monstersList.Clear();

        if (GetHeat(StartPoint).x == -1)
        {
            return;
        }

        //init arrays
        bool[,] closedCheck   = new bool[arraySize, arraySize];
        bool[,] openCheck     = new bool[arraySize, arraySize];
        PathStep[,] openArray = new PathStep[arraySize, arraySize];

        //set start point
        BinaryHeap <PathStep> openList = new BinaryHeap <PathStep>(arraySize * arraySize);

        openList.Add(new PathStep(StartPoint, 0));
        openCheck[maxDistance, maxDistance] = true;

        breath.exist[maxDistance, maxDistance]     = true;
        breath.steps[maxDistance, maxDistance]     = 0;
        breath.distance[maxDistance, maxDistance]  = 0;
        breath.direction[maxDistance, maxDistance] = 0;

        List <ThingController> monsters = new List <ThingController>();

        int maxStepDistance = maxDistance * 10;

        while (openList.ItemCount > 0)
        {
            //get top of heap
            PathStep current         = openList.RemoveFirst();
            int      ax              = current.position.x - StartPoint.x + maxDistance;
            int      ay              = current.position.y - StartPoint.y + maxDistance;
            int      currentDistance = breath.distance[ax, ay];
            int      currentSteps    = breath.steps[ax, ay];
            closedCheck[ax, ay] = true;

            TheGrid.GetNearbyMonsters(current.position, 0).Perform((n) => { monsters.Add(n.Data); });

            if (cullByTrueDistance)
            {
                if (currentDistance >= maxStepDistance)
                {
                    continue;
                }
            }

            Vector3 currentHeat = GetHeat(current.position);

            //no propagation through solids
            if (currentHeat.x >= 1f)
            {
                if (current.position != StartPoint)
                {
                    continue;
                }
            }

            for (int i = 1; i < 9; i++)
            {
                Vec2I neighbor = current.position + Vec2I.directions[i];

                //calculate array position
                int arrayX = neighbor.x - StartPoint.x + maxDistance;
                int arrayY = neighbor.y - StartPoint.y + maxDistance;

                //cull disallowed
                if (AxMath.RogueDistance(neighbor, StartPoint) > maxDistance)
                {
                    continue;
                }
                if (openCheck[arrayX, arrayY])
                {
                    continue;
                }
                if (closedCheck[arrayX, arrayY])
                {
                    continue;
                }

                if (!CanPath(neighbor))
                {
                    continue;
                }

                if (HasLedge(current.position, neighbor, false))
                {
                    continue;
                }

                //calculate cost
                int travelCost = current.travelCost + GetTravelCost(neighbor);
                int heuristic  = AxMath.WeightedDistance(neighbor, StartPoint);
                int fullCost   = travelCost + heuristic;

                //reverse direction to point towards the source of breath
                int p = i + 4;
                if (p > 8)
                {
                    p -= 8;
                }

                //check if we can update parent to better
                if (openCheck[arrayX, arrayY])
                {
                    if (openArray[arrayX, arrayY].travelCost > travelCost)
                    {
                        openArray[arrayX, arrayY].travelCost = travelCost;
                        openArray[arrayX, arrayY].heuristic  = heuristic;
                        openArray[arrayX, arrayY].fullCost   = fullCost;
                        breath.direction[arrayX, arrayY]     = p;
                        breath.distance[arrayX, arrayY]      = currentDistance + StepDistance(i);
                        breath.steps[arrayX, arrayY]         = currentSteps + 1;
                        openList.UpdateItem(openArray[arrayX, arrayY]);
                        continue;
                    }
                    else
                    {
                        continue;
                    }
                }

                //priority sorted by heap
                PathStep step = new PathStep(neighbor, travelCost, heuristic);
                openList.Add(step);
                openArray[arrayX, arrayY] = step;
                openCheck[arrayX, arrayY] = true;

                breath.exist[arrayX, arrayY]     = true;
                breath.direction[arrayX, arrayY] = p;
                breath.distance[arrayX, arrayY]  = currentDistance + StepDistance(i);
                breath.steps[arrayX, arrayY]     = currentSteps + 1;
            }
        }

        monstersList = monsters;
    }
Ejemplo n.º 33
0
        private AssertionContext ProcessPathPartWithAllProperties(AssertionContext rootObjContext, PathStep pathStep)
        {
            DesignByContract.Check.Require(rootObjContext != null && rootObjContext.Data != null,
               "attributeObjContext and attributeObjContext.Data must not be null.");

            object rootObj = rootObjContext.Data;

            AssumedTypes.List<object> objList = new OpenEhr.AssumedTypes.List<object>();

            // go through all properties
            System.Reflection.PropertyInfo[] allProperties = rootObj.GetType().GetProperties(System.Reflection.BindingFlags.Public
                | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.DeclaredOnly
                | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance);
            foreach (System.Reflection.PropertyInfo property in allProperties)
            {
                object propertyValue = property.GetValue(rootObj, null);
                if (propertyValue != null)
                {
                    AssertionContext propertyContext = new AssertionContext(propertyValue, rootObjContext);
                    AssertionContext tempContext = ProcessPathPartWithAttrObject(propertyContext, pathStep);
                    if (tempContext != null && tempContext.Data != null)
                    {
                        objList.Add(tempContext.Data);
                    }
                }
            }

            if (objList.Count == 0)
                return null;
            if (objList.Count == 1)
                return new AssertionContext(objList[0], rootObjContext);

            return new AssertionContext(objList, rootObjContext);
        }