Esempio n. 1
0
        public void AddLink(PathLink pLink)
        {
            List <PathLink> newLinks = links == null ? new List <PathLink>():new List <PathLink>(links);

            newLinks.Add(pLink);
            links = newLinks.ToArray();
        }
Esempio n. 2
0
        public override void MakePreparations(Living living)
        {
            ComponentSelectable entityData = living.GetExactComponent <ComponentSelectable>();
            Point2D             start      = entityData.MapLocation;

            if (start != this.Destination)
            {
                List <PathLink>   pth;
                ComponentMovement movementComponent = living.GetExactComponent <ComponentMovement>();

                //Handle reroute
                if (movementComponent.QueuedMovement.Count > 0)
                {
                    //Get a path to the nearest/next tile so that path finding and the screen location sync up.
                    PathLink previous = movementComponent.QueuedMovement.Peek();
                    movementComponent.QueuedMovement.Clear();
                    movementComponent.QueuedMovement.Enqueue(previous);
                    pth = MainPathFinder.GetRoute(living.Dimension, previous.Destination, this.Destination);
                }
                //No reroute
                else
                {
                    pth = MainPathFinder.GetRoute(living.Dimension, start, this.Destination);
                }

                MagicalLifeAPI.Util.Extensions.EnqueueCollection(movementComponent.QueuedMovement, pth);
                ClientSendRecieve.Send <RouteCreatedMessage>(new RouteCreatedMessage(pth, living.ID, living.Dimension));
            }
        }
Esempio n. 3
0
        protected override void StartJob(Living living)
        {
            Point2D start = living.MapLocation;

            if (start != this.Destination)
            {
                List <PathLink> pth;

                //Handle reroute
                if (living.QueuedMovement.Count > 0)
                {
                    //Get a path to the nearest/next tile so that path finding and the screen location sync up.
                    PathLink previous = living.QueuedMovement.Peek();
                    living.QueuedMovement.Clear();
                    living.QueuedMovement.Enqueue(previous);
                    pth = MainPathFinder.GetRoute(living.Dimension, previous.Destination, this.Destination);
                }
                //No reroute
                else
                {
                    pth = MainPathFinder.GetRoute(living.Dimension, living.MapLocation, this.Destination);
                }

                MagicalLifeAPI.Util.Extensions.EnqueueCollection(living.QueuedMovement, pth);
                ClientSendRecieve.Send <RouteCreatedMessage>(new RouteCreatedMessage(pth, living.ID, living.Dimension));
            }
        }
Esempio n. 4
0
        private void Move(Selectable selectable, Microsoft.Xna.Framework.Point target)
        {
            if (World.Dimensions[RenderingPipe.Dimension][target.X, target.Y].IsWalkable)
            {
                switch (selectable)
                {
                case Living living:

                    Microsoft.Xna.Framework.Point start = selectable.MapLocation;
                    if (start != target)
                    {
                        List <PathLink> pth;

                        //Handle reroute
                        if (living.QueuedMovement.Count > 0)
                        {
                            //Get a path to the nearest/next tile so that path finding and the screen location sync up.
                            PathLink previous = living.QueuedMovement.Peek();
                            living.QueuedMovement.Clear();
                            living.QueuedMovement.Enqueue(previous);
                            pth = MainPathFinder.GetRoute(RenderingPipe.Dimension, previous.Destination, target);
                        }
                        //No reroute
                        else
                        {
                            pth = MainPathFinder.GetRoute(RenderingPipe.Dimension, living.MapLocation, target);
                        }

                        Extensions.EnqueueCollection(living.QueuedMovement, pth);
                        ClientSendRecieve.Send <RouteCreatedMessage>(new RouteCreatedMessage(pth, living.ID, living.Dimension));
                    }
                    break;
                }
            }
        }
Esempio n. 5
0
 public SolutionNode(SolutionNode parent, PathLink link, PathNode destination)
     : this(link.destinationNode)
 {
     this.parent       = parent;
     distanceTravelled = parent.distanceTravelled + link.getCost();
     distanceLeft      = (pathNode.position - destination.position).Length;
 }
Esempio n. 6
0
    public void InitNodeLink(PathNode node, int type)
    {
        int startX = (int)Mathf.Max(0, node.x - 1);
        int endX   = (int)Mathf.Max(m_gridZ - 1, node.x + 1);
        int startY = (int)Mathf.Max(0, node.y - 1);
        int endY   = (int)Mathf.Max(m_gridX - 1, node.y + 1);

        foreach (PathLink link in node.links)
        {
            link.Destroy();
        }
        node.links.Clear();

        for (int i = startX; i < endX; i++)
        {
            for (int j = startY; j < endY; j++)
            {
                PathNode test = GetNode(i, j);
                if (test == node || !test.walkable)
                {
                    continue;
                }
                if (type != 2 && i != node.x && j != node.y)
                {
                    PathNode test2 = GetNode((int)node.x, j);
                    if (!test2.walkable)
                    {
                        continue;
                    }
                    test2 = GetNode(i, (int)node.y);
                    if (!test2.walkable)
                    {
                        continue;
                    }
                }
                float cost = m_straightCost;
                if (!((node.x == test.x) || (node.y == test.y)))
                {
                    if (type == 1)
                    {
                        continue;
                    }
                    if (type == 2 && (node.x - test.x) * (node.y - test.y) == 1)
                    {
                        continue;
                    }
                    if (type == 2)
                    {
                        cost = m_straightCost;
                    }
                    else
                    {
                        cost = m_diagCost;
                    }
                }
                PathLink link = new PathLink(test, cost);
                node.links.Add(link);
            }
        }
    }
Esempio n. 7
0
        public void RemoveLink(PathLink pLink)
        {
            List <PathLink> newLinks = links == null ? new List <PathLink>() : new List <PathLink>(links);

            newLinks.Remove(pLink);
            links = newLinks.ToArray();
        }
Esempio n. 8
0
 protected Project(FileInfo path)
 {
     if (path == null)
     {
         throw new ArgumentNullException("path");
     }
     Path = new PathLink(path);
 }
Esempio n. 9
0
    public static Path CreatePath(PathLink _Link)
    {
        Path p = new Path();

        p.m_Weight = _Link.Weight;
        while (_Link != null)
        {
            p.m_Steps.Insert(0, _Link.Tile);
            _Link = _Link.PreviousLink;
        }
        return(p);
    }
Esempio n. 10
0
        private void ConnectNodes(PointTileNode pA, PointTileNode pB)
        {
            PathLink l = pB.GetLinkTo(pA);

            if (l == null)
            {
                l          = new PathLink(pA, pB);
                l.distance = 1f;
                pA.AddLink(l);
                pB.AddLink(l);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Moves the entity as far along on its path as possible.
        /// </summary>
        /// <param name="entity"></param>
        public static void MoveEntity(Living entity)
        {
            ProtoQueue <PathLink> path = entity.QueuedMovement;

            while (entity.Movement.GetValue() > 0 && path.Count > 0)
            {
                PathLink section = path.Peek();

                Tile sourceTile      = World.Data.World.Dimensions[entity.Dimension][section.Origin.X, section.Origin.Y];
                Tile destinationTile = World.Data.World.Dimensions[entity.Dimension][section.Destination.X, section.Destination.Y];
                Move(entity, sourceTile, destinationTile);
            }
        }
Esempio n. 12
0
        private void AddNode(SampleNode pA, SampleNode pB)
        {
            PathLink l = pB.GetLinkTo(pA);

            if (l == null)
            {
                l = new PathLink(pA, pB);
            }

            l.distance = 1f;
            pA.links.Add(l);
            pB.links.Add(l);
        }
Esempio n. 13
0
        /// <summary>
        /// Moves the entity as far along on its path as possible.
        /// </summary>
        /// <param name="entity"></param>
        public static void MoveEntity(ref Living entity)
        {
            Queue <PathLink> path = entity.QueuedMovement;

            //MasterLog.DebugWriteLine("Creature movement speed: " + entity.Movement.GetValue().ToString());
            while (entity.Movement.GetValue() > 0 && path.Count > 0)
            {
                PathLink section = path.Peek();

                Tile sourceTile      = World.World.MainWorld.Tiles[section.Origin.X, section.Origin.Y];
                Tile destinationTile = World.World.MainWorld.Tiles[section.Destination.X, section.Destination.Y];
                Move(ref entity, sourceTile, destinationTile);
            }
        }
        /// <summary>
        /// Moves the entity as far along on its path as possible.
        /// </summary>
        /// <param name="entity"></param>
        public static void MoveEntity(ref Living entity)
        {
            ProtoQueue <PathLink> path = entity.QueuedMovement;

            //MasterLog.DebugWriteLine("Creature movement speed: " + entity.Movement.GetValue().ToString());
            while (entity.Movement.GetValue() > 0 && path.Count > 0)
            {
                PathLink section = path.Peek();//Should use a normal list, and pull from [0], queue pulls in the wrong order

                Tile sourceTile      = World.Data.World.Dimensions[entity.Dimension][section.Origin.X, section.Origin.Y];
                Tile destinationTile = World.Data.World.Dimensions[entity.Dimension][section.Destination.X, section.Destination.Y];
                Move(ref entity, sourceTile, destinationTile);
            }
            //MasterLog.DebugWriteLine("Tile location: " + entity.MapLocation.ToString());
        }
Esempio n. 15
0
    public void ConnectPoints()
    {
        List <GameObject> points = GetPoints();

        for (int i = 0; i < points.Count - 1; i++)
        {
            GameObject pointA = points[i];
            GameObject pointB = points[i + 1];

            GameObject newlink = new GameObject();
            Image      img     = newlink.AddComponent <Image>() as Image;
            PathLink   pl      = newlink.AddComponent <PathLink>() as PathLink;
            newlink.transform.SetParent(linkParent.transform, false);
            pl.pointA = pointA;
            pl.pointB = pointB;
        }
    }
Esempio n. 16
0
        private void ConnectNodes(TileNode pA, TileNode pB)
        {
            if ((pA.type == TileType.FLOOR || pA.type == TileType.DOOR) &&
                (pB.type == TileType.FLOOR || pB.type == TileType.DOOR))
            {
                PathLink l = pB.GetLinkTo(pA);

                if (l == null)
                {
                    l = new PathLink(pA, pB);
                }

                l.distance = 1f;
                pA.links.Add(l);
                pB.links.Add(l);
            }
        }
Esempio n. 17
0
        private void Move(HasComponents selectable, Point2D target)
        {
            if (World.Dimensions[RenderInfo.Dimension][target.X, target.Y].IsWalkable)
            {
                switch (selectable)
                {
                case Living living:
                    ComponentSelectable positionData = living.GetExactComponent <ComponentSelectable>();
                    Point2D             start        = positionData.MapLocation;
                    if (start != target)
                    {
                        List <PathLink>   pth;
                        ComponentMovement movementComponent = living.GetExactComponent <ComponentMovement>();

                        //Handle reroute
                        if (movementComponent.QueuedMovement.Count > 0)
                        {
                            //Get a path to the nearest/next tile so that path finding and the screen location sync up.
                            PathLink previous = movementComponent.QueuedMovement.Peek();
                            movementComponent.QueuedMovement.Clear();
                            movementComponent.QueuedMovement.Enqueue(previous);
                            pth = MainPathFinder.GetRoute(RenderInfo.Dimension, previous.Destination, target);
                        }
                        //No reroute
                        else
                        {
                            pth = MainPathFinder.GetRoute(RenderInfo.Dimension, positionData.MapLocation, target);
                        }

                        Extensions.EnqueueCollection(movementComponent.QueuedMovement, pth);
                    }
                    break;

                default:
                    break;
                }
            }
        }
Esempio n. 18
0
        private void ConnectNodes(TileNode pA, TileNode pB)
        {
            if ((pA.type == TileType.FLOOR || pA.type == TileType.DOOR) &&
                    (pB.type == TileType.FLOOR || pB.type == TileType.DOOR)) {
                PathLink l = pB.GetLinkTo(pA);

                if (l == null) {
                    l = new PathLink(pA, pB);
                }

                l.distance = 1f;
                pA.links.Add(l);
                pB.links.Add(l);
            }
        }
Esempio n. 19
0
        private void TryQueueNewTile(PointTileNode pNewNode, PathLink pLink, AStarStack pNodesToVisit, PointTileNode pGoal)
        {
            PointTileNode previousNode = pLink.GetOtherNode(pNewNode);
            float linkDistance = pLink.distance;
            float newPathCost = previousNode.pathCostHere + pNewNode.baseCost + linkDistance;

            if (pNewNode.linkLeadingHere == null || (pNewNode.pathCostHere > newPathCost)) {
                pNewNode.distanceToGoal = pNewNode.DistanceTo(pGoal) * 2f;
                pNewNode.pathCostHere = newPathCost;
                pNewNode.linkLeadingHere = pLink;
                pNodesToVisit.Push(pNewNode);
            }
        }
Esempio n. 20
0
 public void AddLink(PathLink pLink)
 {
     links.Add(pLink);
 }
Esempio n. 21
0
 public void RemoveLink(PathLink pLink)
 {
     links.Remove(pLink);
 }
Esempio n. 22
0
    public override void Process(uint seed)
    {
        if (World.Cached)
        {
            TerrainMeta.Path.DungeonRoot = HierarchyUtil.GetRoot("Dungeon");
            return;
        }
        if (World.Networked)
        {
            World.Spawn("Dungeon");
            TerrainMeta.Path.DungeonRoot = HierarchyUtil.GetRoot("Dungeon");
            return;
        }
        Prefab <DungeonCell>[] array = Prefab.Load <DungeonCell>("assets/bundled/prefabs/autospawn/" + TunnelFolder);
        if (array == null || array.Length == 0)
        {
            return;
        }
        Prefab <DungeonCell>[] array2 = Prefab.Load <DungeonCell>("assets/bundled/prefabs/autospawn/" + StationFolder);
        if (array2 == null || array2.Length == 0)
        {
            return;
        }
        Prefab <DungeonCell>[] array3 = Prefab.Load <DungeonCell>("assets/bundled/prefabs/autospawn/" + TransitionFolder);
        if (array3 == null)
        {
            return;
        }
        Prefab <DungeonLink>[] array4 = Prefab.Load <DungeonLink>("assets/bundled/prefabs/autospawn/" + LinkFolder);
        if (array4 == null)
        {
            return;
        }
        array4 = array4.OrderByDescending((Prefab <DungeonLink> x) => x.Component.Priority).ToArray();
        List <DungeonInfo> list = (TerrainMeta.Path ? TerrainMeta.Path.DungeonEntrances : null);
        WorldSpaceGrid <Prefab <DungeonCell> > worldSpaceGrid = new WorldSpaceGrid <Prefab <DungeonCell> >(TerrainMeta.Size.x * 2f, CellSize);

        int[,] array5 = new int[worldSpaceGrid.CellCount, worldSpaceGrid.CellCount];
        _003C_003Ec__DisplayClass17_0 _003C_003Ec__DisplayClass17_ = default(_003C_003Ec__DisplayClass17_0);

        _003C_003Ec__DisplayClass17_.hashmap    = new DungeonConnectionHash[worldSpaceGrid.CellCount, worldSpaceGrid.CellCount];
        _003C_003Ec__DisplayClass17_.pathFinder = new PathFinder(array5, false);
        int cellCount = worldSpaceGrid.CellCount;
        int num       = 0;
        int num2      = worldSpaceGrid.CellCount - 1;

        for (int i = 0; i < cellCount; i++)
        {
            for (int j = 0; j < cellCount; j++)
            {
                array5[j, i] = 1;
            }
        }
        List <PathSegment> list2 = new List <PathSegment>();
        List <PathLink>    list3 = new List <PathLink>();
        List <PathNode>    list4 = new List <PathNode>();

        _003C_003Ec__DisplayClass17_.unconnectedNodeList = new List <PathNode>();
        _003C_003Ec__DisplayClass17_.secondaryNodeList   = new List <PathNode>();
        List <PathFinder.Point>       list5 = new List <PathFinder.Point>();
        List <PathFinder.Point>       list6 = new List <PathFinder.Point>();
        List <PathFinder.Point>       list7 = new List <PathFinder.Point>();
        _003C_003Ec__DisplayClass17_1 _003C_003Ec__DisplayClass17_2 = default(_003C_003Ec__DisplayClass17_1);
        _003C_003Ec__DisplayClass17_3 _003C_003Ec__DisplayClass17_3 = default(_003C_003Ec__DisplayClass17_3);

        foreach (DungeonInfo item in list)
        {
            _003C_003Ec__DisplayClass17_2.entrance = item;
            TerrainPathConnect[] componentsInChildren = _003C_003Ec__DisplayClass17_2.entrance.GetComponentsInChildren <TerrainPathConnect>(true);
            foreach (TerrainPathConnect terrainPathConnect in componentsInChildren)
            {
                _003C_003Ec__DisplayClass17_2 CS_0024_003C_003E8__locals0 = new _003C_003Ec__DisplayClass17_2();
                CS_0024_003C_003E8__locals0._003C_003E4__this = this;
                if (terrainPathConnect.Type != ConnectionType)
                {
                    continue;
                }
                Vector2i cellPos = worldSpaceGrid.WorldToGridCoords(terrainPathConnect.transform.position);
                if (array5[cellPos.x, cellPos.y] == int.MaxValue)
                {
                    continue;
                }
                CS_0024_003C_003E8__locals0.stationNode = _003C_003Ec__DisplayClass17_.pathFinder.FindClosestWalkable(new PathFinder.Point(cellPos.x, cellPos.y), 1);
                if (CS_0024_003C_003E8__locals0.stationNode == null)
                {
                    continue;
                }
                Prefab <DungeonCell> prefab  = ((cellPos.x > num) ? worldSpaceGrid[cellPos.x - 1, cellPos.y] : null);
                Prefab <DungeonCell> prefab2 = ((cellPos.x < num2) ? worldSpaceGrid[cellPos.x + 1, cellPos.y] : null);
                Prefab <DungeonCell> prefab3 = ((cellPos.y > num) ? worldSpaceGrid[cellPos.x, cellPos.y - 1] : null);
                Prefab <DungeonCell> prefab4 = ((cellPos.y < num2) ? worldSpaceGrid[cellPos.x, cellPos.y + 1] : null);
                Prefab <DungeonCell> prefab5 = null;
                float num3 = float.MaxValue;
                ArrayEx.Shuffle(array2, ref seed);
                Prefab <DungeonCell>[] array6 = array2;
                foreach (Prefab <DungeonCell> prefab6 in array6)
                {
                    if ((prefab != null && prefab6.Component.West != prefab.Component.East) || (prefab2 != null && prefab6.Component.East != prefab2.Component.West) || (prefab3 != null && prefab6.Component.South != prefab3.Component.North) || (prefab4 != null && prefab6.Component.North != prefab4.Component.South))
                    {
                        continue;
                    }
                    DungeonLinkBlockVolume componentInChildren  = prefab6.Object.GetComponentInChildren <DungeonLinkBlockVolume>();
                    DungeonLinkBlockVolume componentInChildren2 = _003C_003Ec__DisplayClass17_2.entrance.GetComponentInChildren <DungeonLinkBlockVolume>();
                    OBB bounds  = componentInChildren.GetBounds(worldSpaceGrid.GridToWorldCoords(cellPos), Quaternion.identity);
                    OBB bounds2 = componentInChildren2.GetBounds(_003C_003Ec__DisplayClass17_2.entrance.transform.position, Quaternion.identity);
                    if (!bounds.Intersects2D(bounds2))
                    {
                        DungeonLink componentInChildren3 = prefab6.Object.GetComponentInChildren <DungeonLink>();
                        Vector3     vector = worldSpaceGrid.GridToWorldCoords(new Vector2i(cellPos.x, cellPos.y)) + componentInChildren3.UpSocket.localPosition;
                        float       num4   = (terrainPathConnect.transform.position - vector).Magnitude2D();
                        if (!(num3 < num4))
                        {
                            prefab5 = prefab6;
                            num3    = num4;
                        }
                    }
                }
                if (prefab5 != null)
                {
                    worldSpaceGrid[cellPos.x, cellPos.y]       = prefab5;
                    array5[cellPos.x, cellPos.y]               = int.MaxValue;
                    _003C_003Ec__DisplayClass17_3.isStartPoint = _003C_003Ec__DisplayClass17_.secondaryNodeList.Count == 0;
                    _003C_003Ec__DisplayClass17_.secondaryNodeList.RemoveAll((PathNode x) => x.node.point == CS_0024_003C_003E8__locals0.stationNode.point);
                    _003C_003Ec__DisplayClass17_.unconnectedNodeList.RemoveAll((PathNode x) => x.node.point == CS_0024_003C_003E8__locals0.stationNode.point);
                    if (prefab5.Component.West != 0)
                    {
                        CS_0024_003C_003E8__locals0._003CProcess_003Eg__AddNode_007C1(cellPos.x - 1, cellPos.y, ref _003C_003Ec__DisplayClass17_, ref _003C_003Ec__DisplayClass17_2, ref _003C_003Ec__DisplayClass17_3);
                    }
                    if (prefab5.Component.East != 0)
                    {
                        CS_0024_003C_003E8__locals0._003CProcess_003Eg__AddNode_007C1(cellPos.x + 1, cellPos.y, ref _003C_003Ec__DisplayClass17_, ref _003C_003Ec__DisplayClass17_2, ref _003C_003Ec__DisplayClass17_3);
                    }
                    if (prefab5.Component.South != 0)
                    {
                        CS_0024_003C_003E8__locals0._003CProcess_003Eg__AddNode_007C1(cellPos.x, cellPos.y - 1, ref _003C_003Ec__DisplayClass17_, ref _003C_003Ec__DisplayClass17_2, ref _003C_003Ec__DisplayClass17_3);
                    }
                    if (prefab5.Component.North != 0)
                    {
                        CS_0024_003C_003E8__locals0._003CProcess_003Eg__AddNode_007C1(cellPos.x, cellPos.y + 1, ref _003C_003Ec__DisplayClass17_, ref _003C_003Ec__DisplayClass17_2, ref _003C_003Ec__DisplayClass17_3);
                    }
                    PathLink    pathLink             = new PathLink();
                    DungeonLink componentInChildren4 = _003C_003Ec__DisplayClass17_2.entrance.gameObject.GetComponentInChildren <DungeonLink>();
                    Vector3     position             = _003C_003Ec__DisplayClass17_2.entrance.transform.position;
                    Vector3     eulerAngles          = _003C_003Ec__DisplayClass17_2.entrance.transform.rotation.eulerAngles;
                    DungeonLink componentInChildren5 = prefab5.Object.GetComponentInChildren <DungeonLink>();
                    Vector3     position2            = worldSpaceGrid.GridToWorldCoords(new Vector2i(cellPos.x, cellPos.y));
                    Vector3     zero = Vector3.zero;
                    pathLink.downwards                 = new PathLinkSide();
                    pathLink.downwards.origin          = new PathLinkSegment();
                    pathLink.downwards.origin.position = position;
                    pathLink.downwards.origin.rotation = Quaternion.Euler(eulerAngles);
                    pathLink.downwards.origin.scale    = Vector3.one;
                    pathLink.downwards.origin.link     = componentInChildren4;
                    pathLink.downwards.segments        = new List <PathLinkSegment>();
                    pathLink.upwards                 = new PathLinkSide();
                    pathLink.upwards.origin          = new PathLinkSegment();
                    pathLink.upwards.origin.position = position2;
                    pathLink.upwards.origin.rotation = Quaternion.Euler(zero);
                    pathLink.upwards.origin.scale    = Vector3.one;
                    pathLink.upwards.origin.link     = componentInChildren5;
                    pathLink.upwards.segments        = new List <PathLinkSegment>();
                    list3.Add(pathLink);
                }
            }
        }
        while (_003C_003Ec__DisplayClass17_.unconnectedNodeList.Count != 0 || _003C_003Ec__DisplayClass17_.secondaryNodeList.Count != 0)
        {
            if (_003C_003Ec__DisplayClass17_.unconnectedNodeList.Count == 0)
            {
                PathNode node3 = _003C_003Ec__DisplayClass17_.secondaryNodeList[0];
                _003C_003Ec__DisplayClass17_.unconnectedNodeList.AddRange(_003C_003Ec__DisplayClass17_.secondaryNodeList.Where((PathNode x) => x.monument == node3.monument));
                _003C_003Ec__DisplayClass17_.secondaryNodeList.RemoveAll((PathNode x) => x.monument == node3.monument);
                Vector2i vector2i = worldSpaceGrid.WorldToGridCoords(node3.monument.transform.position);
                _003C_003Ec__DisplayClass17_.pathFinder.PushPoint      = new PathFinder.Point(vector2i.x, vector2i.y);
                _003C_003Ec__DisplayClass17_.pathFinder.PushRadius     = 2;
                _003C_003Ec__DisplayClass17_.pathFinder.PushDistance   = 2;
                _003C_003Ec__DisplayClass17_.pathFinder.PushMultiplier = 4;
            }
            list7.Clear();
            list7.AddRange(_003C_003Ec__DisplayClass17_.unconnectedNodeList.Select((PathNode x) => x.node.point));
            list6.Clear();
            list6.AddRange(list4.Select((PathNode x) => x.node.point));
            list6.AddRange(_003C_003Ec__DisplayClass17_.secondaryNodeList.Select((PathNode x) => x.node.point));
            list6.AddRange(list5);
            PathFinder.Node node4 = _003C_003Ec__DisplayClass17_.pathFinder.FindPathUndirected(list6, list7, 100000);
            if (node4 == null)
            {
                PathNode node2 = _003C_003Ec__DisplayClass17_.unconnectedNodeList[0];
                _003C_003Ec__DisplayClass17_.secondaryNodeList.AddRange(_003C_003Ec__DisplayClass17_.unconnectedNodeList.Where((PathNode x) => x.monument == node2.monument));
                _003C_003Ec__DisplayClass17_.unconnectedNodeList.RemoveAll((PathNode x) => x.monument == node2.monument);
                _003C_003Ec__DisplayClass17_.secondaryNodeList.Remove(node2);
                list4.Add(node2);
                continue;
            }
            PathSegment segment = new PathSegment();
            for (PathFinder.Node node5 = node4; node5 != null; node5 = node5.next)
            {
                if (node5 == node4)
                {
                    segment.start = node5;
                }
                if (node5.next == null)
                {
                    segment.end = node5;
                }
            }
            list2.Add(segment);
            PathNode node = _003C_003Ec__DisplayClass17_.unconnectedNodeList.Find((PathNode x) => x.node.point == segment.start.point || x.node.point == segment.end.point);
            _003C_003Ec__DisplayClass17_.secondaryNodeList.AddRange(_003C_003Ec__DisplayClass17_.unconnectedNodeList.Where((PathNode x) => x.monument == node.monument));
            _003C_003Ec__DisplayClass17_.unconnectedNodeList.RemoveAll((PathNode x) => x.monument == node.monument);
            _003C_003Ec__DisplayClass17_.secondaryNodeList.Remove(node);
            list4.Add(node);
            PathNode pathNode = _003C_003Ec__DisplayClass17_.secondaryNodeList.Find((PathNode x) => x.node.point == segment.start.point || x.node.point == segment.end.point);
            if (pathNode != null)
            {
                _003C_003Ec__DisplayClass17_.secondaryNodeList.Remove(pathNode);
                list4.Add(pathNode);
            }
            for (PathFinder.Node node6 = node4; node6 != null; node6 = node6.next)
            {
                if (node6 != node4 && node6.next != null)
                {
                    list5.Add(node6.point);
                }
            }
        }
        foreach (PathSegment item2 in list2)
        {
            PathFinder.Node node7 = item2.start;
            while (node7 != null && node7.next != null)
            {
                DungeonConnectionHash dungeonConnectionHash  = _003C_003Ec__DisplayClass17_.hashmap[node7.point.x, node7.point.y];
                DungeonConnectionHash dungeonConnectionHash2 = _003C_003Ec__DisplayClass17_.hashmap[node7.next.point.x, node7.next.point.y];
                if (node7.point.x > node7.next.point.x)
                {
                    dungeonConnectionHash.West  = true;
                    dungeonConnectionHash2.East = true;
                }
                if (node7.point.x < node7.next.point.x)
                {
                    dungeonConnectionHash.East  = true;
                    dungeonConnectionHash2.West = true;
                }
                if (node7.point.y > node7.next.point.y)
                {
                    dungeonConnectionHash.South  = true;
                    dungeonConnectionHash2.North = true;
                }
                if (node7.point.y < node7.next.point.y)
                {
                    dungeonConnectionHash.North  = true;
                    dungeonConnectionHash2.South = true;
                }
                _003C_003Ec__DisplayClass17_.hashmap[node7.point.x, node7.point.y]           = dungeonConnectionHash;
                _003C_003Ec__DisplayClass17_.hashmap[node7.next.point.x, node7.next.point.y] = dungeonConnectionHash2;
                node7 = node7.next;
            }
        }
        for (int m = 0; m < worldSpaceGrid.CellCount; m++)
        {
            for (int n = 0; n < worldSpaceGrid.CellCount; n++)
            {
                if (array5[m, n] == int.MaxValue)
                {
                    continue;
                }
                DungeonConnectionHash dungeonConnectionHash3 = _003C_003Ec__DisplayClass17_.hashmap[m, n];
                if (dungeonConnectionHash3.Value == 0)
                {
                    continue;
                }
                ArrayEx.Shuffle(array, ref seed);
                Prefab <DungeonCell>[] array6 = array;
                foreach (Prefab <DungeonCell> prefab7 in array6)
                {
                    Prefab <DungeonCell> prefab8 = ((m > num) ? worldSpaceGrid[m - 1, n] : null);
                    if (((prefab8 != null) ? ((prefab7.Component.West == prefab8.Component.East) ? 1 : 0) : (dungeonConnectionHash3.West ? ((int)prefab7.Component.West) : ((prefab7.Component.West == DungeonConnectionType.None) ? 1 : 0))) == 0)
                    {
                        continue;
                    }
                    Prefab <DungeonCell> prefab9 = ((m < num2) ? worldSpaceGrid[m + 1, n] : null);
                    if (((prefab9 != null) ? ((prefab7.Component.East == prefab9.Component.West) ? 1 : 0) : (dungeonConnectionHash3.East ? ((int)prefab7.Component.East) : ((prefab7.Component.East == DungeonConnectionType.None) ? 1 : 0))) == 0)
                    {
                        continue;
                    }
                    Prefab <DungeonCell> prefab10 = ((n > num) ? worldSpaceGrid[m, n - 1] : null);
                    if (((prefab10 != null) ? ((prefab7.Component.South == prefab10.Component.North) ? 1 : 0) : (dungeonConnectionHash3.South ? ((int)prefab7.Component.South) : ((prefab7.Component.South == DungeonConnectionType.None) ? 1 : 0))) == 0)
                    {
                        continue;
                    }
                    Prefab <DungeonCell> prefab11 = ((n < num2) ? worldSpaceGrid[m, n + 1] : null);
                    if (((prefab11 != null) ? ((prefab7.Component.North == prefab11.Component.South) ? 1 : 0) : (dungeonConnectionHash3.North ? ((int)prefab7.Component.North) : ((prefab7.Component.North == DungeonConnectionType.None) ? 1 : 0))) != 0 && (prefab7.Component.West == DungeonConnectionType.None || prefab8 == null || !prefab7.Component.ShouldAvoid(prefab8.ID)) && (prefab7.Component.East == DungeonConnectionType.None || prefab9 == null || !prefab7.Component.ShouldAvoid(prefab9.ID)) && (prefab7.Component.South == DungeonConnectionType.None || prefab10 == null || !prefab7.Component.ShouldAvoid(prefab10.ID)) && (prefab7.Component.North == DungeonConnectionType.None || prefab11 == null || !prefab7.Component.ShouldAvoid(prefab11.ID)))
                    {
                        worldSpaceGrid[m, n] = prefab7;
                        bool num5 = prefab8 == null || prefab7.Component.WestVariant == prefab8.Component.EastVariant;
                        bool flag = prefab10 == null || prefab7.Component.SouthVariant == prefab10.Component.NorthVariant;
                        if (num5 && flag)
                        {
                            break;
                        }
                    }
                }
            }
        }
        Vector3 zero2   = Vector3.zero;
        Vector3 zero3   = Vector3.zero;
        Vector3 vector2 = Vector3.up * 10f;
        Vector3 vector3 = Vector3.up * (LinkTransition + 1f);

        do
        {
            zero3 = zero2;
            for (int num6 = 0; num6 < worldSpaceGrid.CellCount; num6++)
            {
                for (int num7 = 0; num7 < worldSpaceGrid.CellCount; num7++)
                {
                    Prefab <DungeonCell> prefab12 = worldSpaceGrid[num6, num7];
                    if (prefab12 != null)
                    {
                        Vector2i cellPos2 = new Vector2i(num6, num7);
                        Vector3  vector4  = worldSpaceGrid.GridToWorldCoords(cellPos2);
                        while (!prefab12.CheckEnvironmentVolumesInsideTerrain(zero2 + vector4 + vector2, Quaternion.identity, Vector3.one, EnvironmentType.Underground) || prefab12.CheckEnvironmentVolumes(zero2 + vector4 + vector3, Quaternion.identity, Vector3.one, EnvironmentType.Underground | EnvironmentType.Building) || prefab12.CheckEnvironmentVolumes(zero2 + vector4, Quaternion.identity, Vector3.one, EnvironmentType.Underground | EnvironmentType.Building))
                        {
                            zero2.y -= 9f;
                        }
                    }
                }
            }
        }while (zero2 != zero3);
        foreach (PathLink item3 in list3)
        {
            item3.upwards.origin.position += zero2;
        }
        for (int num8 = 0; num8 < worldSpaceGrid.CellCount; num8++)
        {
            for (int num9 = 0; num9 < worldSpaceGrid.CellCount; num9++)
            {
                Prefab <DungeonCell> prefab13 = worldSpaceGrid[num8, num9];
                if (prefab13 != null)
                {
                    Vector2i cellPos3 = new Vector2i(num8, num9);
                    Vector3  vector5  = worldSpaceGrid.GridToWorldCoords(cellPos3);
                    World.AddPrefab("Dungeon", prefab13, zero2 + vector5, Quaternion.identity, Vector3.one);
                }
            }
        }
        for (int num10 = 0; num10 < worldSpaceGrid.CellCount - 1; num10++)
        {
            for (int num11 = 0; num11 < worldSpaceGrid.CellCount - 1; num11++)
            {
                Prefab <DungeonCell>   prefab14 = worldSpaceGrid[num10, num11];
                Prefab <DungeonCell>   prefab15 = worldSpaceGrid[num10 + 1, num11];
                Prefab <DungeonCell>   prefab16 = worldSpaceGrid[num10, num11 + 1];
                Prefab <DungeonCell>[] array6;
                if (prefab14 != null && prefab15 != null && prefab14.Component.EastVariant != prefab15.Component.WestVariant)
                {
                    ArrayEx.Shuffle(array3, ref seed);
                    array6 = array3;
                    foreach (Prefab <DungeonCell> prefab17 in array6)
                    {
                        if (prefab17.Component.West == prefab14.Component.East && prefab17.Component.East == prefab15.Component.West && prefab17.Component.WestVariant == prefab14.Component.EastVariant && prefab17.Component.EastVariant == prefab15.Component.WestVariant)
                        {
                            Vector2i cellPos4 = new Vector2i(num10, num11);
                            Vector3  vector6  = worldSpaceGrid.GridToWorldCoords(cellPos4) + new Vector3(worldSpaceGrid.CellSizeHalf, 0f, 0f);
                            World.AddPrefab("Dungeon", prefab17, zero2 + vector6, Quaternion.identity, Vector3.one);
                            break;
                        }
                    }
                }
                if (prefab14 == null || prefab16 == null || prefab14.Component.NorthVariant == prefab16.Component.SouthVariant)
                {
                    continue;
                }
                ArrayEx.Shuffle(array3, ref seed);
                array6 = array3;
                foreach (Prefab <DungeonCell> prefab18 in array6)
                {
                    if (prefab18.Component.South == prefab14.Component.North && prefab18.Component.North == prefab16.Component.South && prefab18.Component.SouthVariant == prefab14.Component.NorthVariant && prefab18.Component.NorthVariant == prefab16.Component.SouthVariant)
                    {
                        Vector2i cellPos5 = new Vector2i(num10, num11);
                        Vector3  vector7  = worldSpaceGrid.GridToWorldCoords(cellPos5) + new Vector3(0f, 0f, worldSpaceGrid.CellSizeHalf);
                        World.AddPrefab("Dungeon", prefab18, zero2 + vector7, Quaternion.identity, Vector3.one);
                        break;
                    }
                }
            }
        }
        foreach (PathLink item4 in list3)
        {
            Vector3   vector8 = item4.upwards.origin.position + item4.upwards.origin.rotation * Vector3.Scale(item4.upwards.origin.upSocket.localPosition, item4.upwards.origin.scale);
            Vector3   vector9 = item4.downwards.origin.position + item4.downwards.origin.rotation * Vector3.Scale(item4.downwards.origin.downSocket.localPosition, item4.downwards.origin.scale) - vector8;
            Vector3[] array7  = new Vector3[2]
            {
                new Vector3(0f, 1f, 0f),
                new Vector3(1f, 1f, 1f)
            };
            for (int k = 0; k < array7.Length; k++)
            {
                Vector3 b     = array7[k];
                int     num12 = 0;
                int     num13 = 0;
                while (vector9.magnitude > 1f && (num12 < 8 || num13 < 8))
                {
                    bool flag2 = num12 > 2 && num13 > 2;
                    bool flag3 = num12 > 4 && num13 > 4;
                    Prefab <DungeonLink> prefab19      = null;
                    Vector3                vector10    = Vector3.zero;
                    int                    num14       = int.MinValue;
                    Vector3                position3   = Vector3.zero;
                    Quaternion             rotation    = Quaternion.identity;
                    PathLinkSegment        prevSegment = item4.downwards.prevSegment;
                    Vector3                vector11    = prevSegment.position + prevSegment.rotation * Vector3.Scale(prevSegment.scale, prevSegment.downSocket.localPosition);
                    Quaternion             quaternion  = prevSegment.rotation * prevSegment.downSocket.localRotation;
                    Prefab <DungeonLink>[] array8      = array4;
                    foreach (Prefab <DungeonLink> prefab20 in array8)
                    {
                        float       num15     = SeedRandom.Value(ref seed);
                        DungeonLink component = prefab20.Component;
                        if (prevSegment.downType != component.UpType)
                        {
                            continue;
                        }
                        switch (component.DownType)
                        {
                        case DungeonLinkType.Elevator:
                            if (flag2 || b.x != 0f || b.z != 0f)
                            {
                                continue;
                            }
                            break;

                        case DungeonLinkType.Transition:
                            if (b.x != 0f || b.z != 0f)
                            {
                                continue;
                            }
                            break;
                        }
                        int num16 = ((!flag2) ? component.Priority : 0);
                        if (num14 > num16)
                        {
                            continue;
                        }
                        Quaternion      quaternion2  = quaternion * Quaternion.Inverse(component.UpSocket.localRotation);
                        Quaternion      quaternion3  = quaternion2 * component.DownSocket.localRotation;
                        PathLinkSegment prevSegment2 = item4.upwards.prevSegment;
                        Quaternion      quaternion4  = prevSegment2.rotation * prevSegment2.upSocket.localRotation;
                        if (component.Rotation > 0)
                        {
                            if (Quaternion.Angle(quaternion4, quaternion3) > (float)component.Rotation)
                            {
                                continue;
                            }
                            Quaternion quaternion5 = quaternion4 * Quaternion.Inverse(quaternion3);
                            quaternion2 *= quaternion5;
                            quaternion3 *= quaternion5;
                        }
                        Vector3 vector12   = vector11 - quaternion2 * component.UpSocket.localPosition;
                        Vector3 vector13   = quaternion2 * (component.DownSocket.localPosition - component.UpSocket.localPosition);
                        Vector3 a          = vector9 + vector10;
                        Vector3 a2         = vector9 + vector13;
                        float   magnitude  = a.magnitude;
                        float   magnitude2 = a2.magnitude;
                        Vector3 vector14   = Vector3.Scale(a, b);
                        Vector3 vector15   = Vector3.Scale(a2, b);
                        float   magnitude3 = vector14.magnitude;
                        float   magnitude4 = vector15.magnitude;
                        if (vector10 != Vector3.zero)
                        {
                            if (magnitude3 < magnitude4 || (magnitude3 == magnitude4 && magnitude < magnitude2) || (magnitude3 == magnitude4 && magnitude == magnitude2 && num15 < 0.5f))
                            {
                                continue;
                            }
                        }
                        else if (magnitude3 <= magnitude4)
                        {
                            continue;
                        }
                        if (Mathf.Abs(vector15.x) - Mathf.Abs(vector14.x) > 0.01f || (Mathf.Abs(vector15.x) > 0.01f && a.x * a2.x < 0f) || Mathf.Abs(vector15.y) - Mathf.Abs(vector14.y) > 0.01f || (Mathf.Abs(vector15.y) > 0.01f && a.y * a2.y < 0f) || Mathf.Abs(vector15.z) - Mathf.Abs(vector14.z) > 0.01f || (Mathf.Abs(vector15.z) > 0.01f && a.z * a2.z < 0f) || (flag2 && b.x == 0f && b.z == 0f && component.DownType == DungeonLinkType.Default && ((Mathf.Abs(a2.x) > 0.01f && Mathf.Abs(a2.x) < LinkRadius * 2f - 0.1f) || (Mathf.Abs(a2.z) > 0.01f && Mathf.Abs(a2.z) < LinkRadius * 2f - 0.1f))))
                        {
                            continue;
                        }
                        num14 = num16;
                        if (b.x == 0f && b.z == 0f)
                        {
                            if (!flag2 && Mathf.Abs(a2.y) < LinkTransition - 0.1f)
                            {
                                continue;
                            }
                        }
                        else if ((!flag2 && magnitude4 > 0.01f && (Mathf.Abs(a2.x) < LinkRadius * 2f - 0.1f || Mathf.Abs(a2.z) < LinkRadius * 2f - 0.1f)) || (!flag3 && magnitude4 > 0.01f && (Mathf.Abs(a2.x) < LinkRadius * 1f - 0.1f || Mathf.Abs(a2.z) < LinkRadius * 1f - 0.1f)))
                        {
                            continue;
                        }
                        if (!flag2 || !(magnitude4 < 0.01f) || !(magnitude2 < 0.01f) || !(Quaternion.Angle(quaternion4, quaternion3) > 10f))
                        {
                            prefab19  = prefab20;
                            vector10  = vector13;
                            num14     = num16;
                            position3 = vector12;
                            rotation  = quaternion2;
                        }
                    }
                    if (vector10 != Vector3.zero)
                    {
                        PathLinkSegment pathLinkSegment = new PathLinkSegment();
                        pathLinkSegment.position = position3;
                        pathLinkSegment.rotation = rotation;
                        pathLinkSegment.scale    = Vector3.one;
                        pathLinkSegment.prefab   = prefab19;
                        pathLinkSegment.link     = prefab19.Component;
                        item4.downwards.segments.Add(pathLinkSegment);
                        vector9 += vector10;
                    }
                    else
                    {
                        num13++;
                    }
                    if (b.x > 0f || b.z > 0f)
                    {
                        Prefab <DungeonLink> prefab21 = null;
                        Vector3         vector16      = Vector3.zero;
                        int             num17         = int.MinValue;
                        Vector3         position4     = Vector3.zero;
                        Quaternion      rotation2     = Quaternion.identity;
                        PathLinkSegment prevSegment3  = item4.upwards.prevSegment;
                        Vector3         vector17      = prevSegment3.position + prevSegment3.rotation * Vector3.Scale(prevSegment3.scale, prevSegment3.upSocket.localPosition);
                        Quaternion      quaternion6   = prevSegment3.rotation * prevSegment3.upSocket.localRotation;
                        array8 = array4;
                        foreach (Prefab <DungeonLink> prefab22 in array8)
                        {
                            float       num18      = SeedRandom.Value(ref seed);
                            DungeonLink component2 = prefab22.Component;
                            if (prevSegment3.upType != component2.DownType)
                            {
                                continue;
                            }
                            switch (component2.DownType)
                            {
                            case DungeonLinkType.Elevator:
                                if (flag2 || b.x != 0f || b.z != 0f)
                                {
                                    continue;
                                }
                                break;

                            case DungeonLinkType.Transition:
                                if (b.x != 0f || b.z != 0f)
                                {
                                    continue;
                                }
                                break;
                            }
                            int num19 = ((!flag2) ? component2.Priority : 0);
                            if (num17 > num19)
                            {
                                continue;
                            }
                            Quaternion      quaternion7  = quaternion6 * Quaternion.Inverse(component2.DownSocket.localRotation);
                            Quaternion      quaternion8  = quaternion7 * component2.UpSocket.localRotation;
                            PathLinkSegment prevSegment4 = item4.downwards.prevSegment;
                            Quaternion      quaternion9  = prevSegment4.rotation * prevSegment4.downSocket.localRotation;
                            if (component2.Rotation > 0)
                            {
                                if (Quaternion.Angle(quaternion9, quaternion8) > (float)component2.Rotation)
                                {
                                    continue;
                                }
                                Quaternion quaternion10 = quaternion9 * Quaternion.Inverse(quaternion8);
                                quaternion7 *= quaternion10;
                                quaternion8 *= quaternion10;
                            }
                            Vector3 vector18   = vector17 - quaternion7 * component2.DownSocket.localPosition;
                            Vector3 vector19   = quaternion7 * (component2.UpSocket.localPosition - component2.DownSocket.localPosition);
                            Vector3 a3         = vector9 - vector16;
                            Vector3 a4         = vector9 - vector19;
                            float   magnitude5 = a3.magnitude;
                            float   magnitude6 = a4.magnitude;
                            Vector3 vector20   = Vector3.Scale(a3, b);
                            Vector3 vector21   = Vector3.Scale(a4, b);
                            float   magnitude7 = vector20.magnitude;
                            float   magnitude8 = vector21.magnitude;
                            if (vector16 != Vector3.zero)
                            {
                                if (magnitude7 < magnitude8 || (magnitude7 == magnitude8 && magnitude5 < magnitude6) || (magnitude7 == magnitude8 && magnitude5 == magnitude6 && num18 < 0.5f))
                                {
                                    continue;
                                }
                            }
                            else if (magnitude7 <= magnitude8)
                            {
                                continue;
                            }
                            if (Mathf.Abs(vector21.x) - Mathf.Abs(vector20.x) > 0.01f || (Mathf.Abs(vector21.x) > 0.01f && a3.x * a4.x < 0f) || Mathf.Abs(vector21.y) - Mathf.Abs(vector20.y) > 0.01f || (Mathf.Abs(vector21.y) > 0.01f && a3.y * a4.y < 0f) || Mathf.Abs(vector21.z) - Mathf.Abs(vector20.z) > 0.01f || (Mathf.Abs(vector21.z) > 0.01f && a3.z * a4.z < 0f) || (flag2 && b.x == 0f && b.z == 0f && component2.UpType == DungeonLinkType.Default && ((Mathf.Abs(a4.x) > 0.01f && Mathf.Abs(a4.x) < LinkRadius * 2f - 0.1f) || (Mathf.Abs(a4.z) > 0.01f && Mathf.Abs(a4.z) < LinkRadius * 2f - 0.1f))))
                            {
                                continue;
                            }
                            num17 = num19;
                            if (b.x == 0f && b.z == 0f)
                            {
                                if (!flag2 && Mathf.Abs(a4.y) < LinkTransition - 0.1f)
                                {
                                    continue;
                                }
                            }
                            else if ((!flag2 && magnitude8 > 0.01f && (Mathf.Abs(a4.x) < LinkRadius * 2f - 0.1f || Mathf.Abs(a4.z) < LinkRadius * 2f - 0.1f)) || (!flag3 && magnitude8 > 0.01f && (Mathf.Abs(a4.x) < LinkRadius * 1f - 0.1f || Mathf.Abs(a4.z) < LinkRadius * 1f - 0.1f)))
                            {
                                continue;
                            }
                            if (!flag2 || !(magnitude8 < 0.01f) || !(magnitude6 < 0.01f) || !(Quaternion.Angle(quaternion9, quaternion8) > 10f))
                            {
                                prefab21  = prefab22;
                                vector16  = vector19;
                                num17     = num19;
                                position4 = vector18;
                                rotation2 = quaternion7;
                            }
                        }
                        if (vector16 != Vector3.zero)
                        {
                            PathLinkSegment pathLinkSegment2 = new PathLinkSegment();
                            pathLinkSegment2.position = position4;
                            pathLinkSegment2.rotation = rotation2;
                            pathLinkSegment2.scale    = Vector3.one;
                            pathLinkSegment2.prefab   = prefab21;
                            pathLinkSegment2.link     = prefab21.Component;
                            item4.upwards.segments.Add(pathLinkSegment2);
                            vector9 -= vector16;
                        }
                        else
                        {
                            num12++;
                        }
                    }
                    else
                    {
                        num12++;
                    }
                }
            }
        }
        foreach (PathLink item5 in list3)
        {
            foreach (PathLinkSegment segment2 in item5.downwards.segments)
            {
                World.AddPrefab("Dungeon", segment2.prefab, segment2.position, segment2.rotation, segment2.scale);
            }
            foreach (PathLinkSegment segment3 in item5.upwards.segments)
            {
                World.AddPrefab("Dungeon", segment3.prefab, segment3.position, segment3.rotation, segment3.scale);
            }
        }
        if ((bool)TerrainMeta.Path)
        {
            TerrainMeta.Path.DungeonRoot = HierarchyUtil.GetRoot("Dungeon");
        }
    }
Esempio n. 23
0
 private void ConnectNodes(PointTileNode pA, PointTileNode pB)
 {
     PathLink l = pB.GetLinkTo(pA);
     if (l == null) {
         l = new PathLink(pA, pB);
         l.distance = 1f;
         pA.AddLink(l);
         pB.AddLink(l);
     }
 }
Esempio n. 24
0
    /// <summary>
    /// Search a path with Dijkstra algorithm.
    /// The open list is optimized with PathLink class and not Path class. This way, we do not duplicate a whole path when we extend it,
    /// we create PathLink insted and use it as LinkedList to simulate a path.
    /// </summary>
    /// <param name="_Start">Tile to start from</param>
    /// <param name="_End">Tile to reach</param>
    /// <param name="_ChronoInfos">Struct with times value to evaluate performance</param>
    /// <param name="_MaxSeconds">Max time allowed to search a solution. If value is negative, no time limit applied</param>
    /// <returns>the shortest path from start tile to end tile if it exists, null otherwise</returns>
    public static Path SearchDisjktraPathFromTo_LinkOpti(Tile _Start, Tile _End, out ChronoInfos _ChronoInfos, float _TimeLimit)
    {
        StartChrono();

        if (_Start == null || !_Start.IsAccessible || _End == null || !_End.IsAccessible)
        {
            _ChronoInfos = ChronoInfos.InfosNone;
            return(null);
        }

        List <PathLink> openList = new List <PathLink>(100)
        {
            new PathLink(_Start)
        };
        HashSet <Tile>            closeHashSet   = new HashSet <Tile>();
        CustomComparer <PathLink> customComparer = new CustomComparer <PathLink>(false);

        while (openList.Count > 0)
        {
            // Stop search if the chrono reached the time limit.
            // It avoids to get infinite loop or too long to find a solution. Mainly usefull to debug
            if (_TimeLimit > 0 && chrono.Elapsed.TotalSeconds > _TimeLimit)
            {
                _ChronoInfos = StopChrono(_Start, _End, false);
                return(null);
            }

            // Take the last (and so the shortest) path to extend
            PathLink pathToExtend = openList.Last();
            Tile     tileToExtend = pathToExtend.Tile;

            // If the end is reach, return solution
            if (tileToExtend == _End)
            {
                _ChronoInfos = StopChrono(_Start, _End, true);
                return(Path.CreatePath(pathToExtend));
            }

            // Remove the current path from open list
            removeFromOpenChrono -= chrono.ElapsedMilliseconds;
            openList.RemoveAt(openList.Count - 1);
            removeFromOpenChrono += chrono.ElapsedMilliseconds;

            // If the last tile was already reached, skip process to next path to extend
            if (closeHashSet.Contains(tileToExtend))
            {
                continue;
            }
            closeHashSet.Add(tileToExtend);

            foreachNeighborsChrono -= chrono.ElapsedMilliseconds;
            // Loop on  neighbors of last tile
            for (int i = 0; i < tileToExtend.Neighbors.Count; i++)
            {
                Tile neighbor = tileToExtend.Neighbors[i];
                // If neighbor is wall or already reached, skip process to next neighbor

                searchInCloseListChrono -= chrono.ElapsedMilliseconds;
                bool existInCloseList = closeHashSet.Contains(neighbor);
                searchInCloseListChrono += chrono.ElapsedMilliseconds;

                if (!neighbor.IsAccessible || existInCloseList)
                {
                    continue;
                }


                // Extend pathlink with the path to extend and the current neighbor
                extendPathChrono -= chrono.ElapsedMilliseconds;
                //PathLink extendedPath = new PathLink(pathToExtend, neighbor);
                PathLink extendedPath = pathToExtend.MakeExtensionWith(neighbor);
                extendPathChrono += chrono.ElapsedMilliseconds;

                // Search index to insert extended path in open list
                searchInsertionChrono -= chrono.ElapsedMilliseconds;
                int indexInsertion = openList.BinarySearch(extendedPath, customComparer);
                if (indexInsertion < 0)
                {
                    indexInsertion = ~indexInsertion;
                }
                searchInsertionChrono += chrono.ElapsedMilliseconds;

                // Insert the extended path in open list
                insertToOpenListChrono -= chrono.ElapsedMilliseconds;
                openList.Insert(indexInsertion, extendedPath);
                insertToOpenListChrono += chrono.ElapsedMilliseconds;
            }
            foreachNeighborsChrono += chrono.ElapsedMilliseconds;
        }

        _ChronoInfos = StopChrono(_Start, _End, false);
        return(null);
    }
        FindOptimalLinksToCrossovers(
            IntVector2 p,
            int[] candidateWaypoints = null,
            IReadOnlyDictionary <DoubleLineSegment2, IntLineSegment2[]> candidateBarriersByDestinationSegment = null
            )
        {
            Interlocked.Increment(ref FindOptimalLinksToCrossoversInvocationCount);
            //var links = new List<PathLink>(128);
            //links.Resize(crossoverPoints.Count);
            //return (new PathLink[0], 0, new PathLink[waypoints.Length], links);

            int visibleWaypointLinksLength;

            PathLink[] optimalLinkToWaypoints;
            var        visibleWaypointLinks = FindVisibleWaypointLinks(p, candidateWaypoints, out visibleWaypointLinksLength, out optimalLinkToWaypoints);

            // Cost from p to other crossoverPoints...
            var optimalLinkToCrossovers = new ExposedArrayList <PathLink>(Math.Max(128, crossoverPoints.Count));

            optimalLinkToCrossovers.size = crossoverPoints.Count;

            void ProcessCpi(int cpi, IntLineSegment2[] candidateBarriers)
            {
                // for bench
                optimalLinkToCrossovers[cpi] = new PathLink {
                    PriorIndex = PathLink.ErrorInvalidIndex,
                    TotalCost  = float.PositiveInfinity
                };
                return;

                Interlocked.Increment(ref ProcessCpiInvocationCount);
                bool isDirectPath;

                if (p == crossoverPoints[cpi])
                {
                    isDirectPath = true; // degenerate segment
                }
                else if (candidateBarriers == null)
                {
                    //               Console.WriteLine($"Try intersect {cpi}: {p} to {crossoverPoints[cpi]}");
                    var isDirectPath1 = !landPolyNode.FindContourAndChildHoleBarriersBvh().Intersects(new IntLineSegment2(p, crossoverPoints[cpi]));
                    //               var isDirectPath2 = landPolyNode.SegmentInLandPolygonNonrecursive(p, crossoverPoints[cpi]);
                    //               Console.WriteLine($" => res {isDirectPath1} vs {isDirectPath2}");
                    isDirectPath = isDirectPath1;
                }
                else
                {
                    // below is equivalent to (and shaved off 22% execution time relative to):
                    // isDirectPath = candidateBarriers.None(new ILS2(p, crossoverPoints[cpi]).Intersects)
                    isDirectPath = true;
                    //var seg = new IntLineSegment2(p, crossoverPoints[cpi]);
                    for (var bi = 0; bi < candidateBarriers.Length && isDirectPath; bi++)
                    {
                        Interlocked.Increment(ref ProcessCpiInvocation_CandidateBarrierIntersectCount);

                        if (IntLineSegment2.Intersects(
                                p.X, p.Y, crossoverPoints[cpi].X, crossoverPoints[cpi].Y,
                                candidateBarriers[bi].X1, candidateBarriers[bi].Y1, candidateBarriers[bi].X2, candidateBarriers[bi].Y2))
                        {
                            isDirectPath = false;
                        }
                        //if (seg.Intersects(ref candidateBarriers[bi])) isDirectPath = false;
                    }
                }

                if (isDirectPath)
                {
                    Interlocked.Increment(ref ProcessCpiInvocation_DirectCount);
                    var totalCost = p.To(crossoverPoints[cpi]).Norm2F();
                    Trace.Assert(!float.IsNaN(totalCost));
                    optimalLinkToCrossovers[cpi] = new PathLink {
                        PriorIndex = PathLink.DirectPathIndex,
                        TotalCost  = totalCost
                    };
                }
                else
                {
                    Interlocked.Increment(ref ProcessCpiInvocation_IndirectCount);
                    var otherOptimalLinkByWaypointIndex = optimalLinkToWaypointsByCrossoverPointIndex[cpi];

                    //--
                    // Below is equivalent to (and shaved off 14% execution time relative to):
                    // visibleWaypointLinks.MinBy(cpwl => cpwl.TotalCost + otherOptimalLinkByWaypointIndex[cpwl.PriorIndex].TotalCost);
                    var optimalLinkToOtherCrossoverPointIndex = -1;
                    var optimalLinkToOtherCrossoverPointCost  = float.PositiveInfinity;
                    for (var vwli = 0; vwli < visibleWaypointLinksLength; vwli++)
                    {
                        ref var vwl  = ref visibleWaypointLinks[vwli];
                        var     cost = vwl.TotalCost + otherOptimalLinkByWaypointIndex[vwl.PriorIndex].TotalCost;
                        if (cost < optimalLinkToOtherCrossoverPointCost)
                        {
                            optimalLinkToOtherCrossoverPointIndex = vwli;
                            optimalLinkToOtherCrossoverPointCost  = cost;
                        }
                    }

                    if (optimalLinkToOtherCrossoverPointIndex == -1)
                    {
                        // Todo: This shouldn't happen!
                        optimalLinkToCrossovers[cpi] = new PathLink {
                            PriorIndex = PathLink.ErrorInvalidIndex,
                            TotalCost  = float.PositiveInfinity
                        };
                    }
                    else
                    {
                        ref var optimalLinkToOtherCrossoverPoint = ref visibleWaypointLinks[optimalLinkToOtherCrossoverPointIndex];

                        //--
                        var optimalLinkFromOtherCrossoverPoint = otherOptimalLinkByWaypointIndex[optimalLinkToOtherCrossoverPoint.PriorIndex];
                        var totalCost = optimalLinkToOtherCrossoverPoint.TotalCost + optimalLinkFromOtherCrossoverPoint.TotalCost;
                        Trace.Assert(!float.IsNaN(totalCost));
                        optimalLinkToCrossovers[cpi] = new PathLink {
                            PriorIndex = optimalLinkToOtherCrossoverPoint.PriorIndex,
                            TotalCost  = totalCost
                        };
                    }
                }
Esempio n. 26
0
 public void RemoveLink(PathLink pLink)
 {
     _links.Remove(pLink);
 }
Esempio n. 27
0
 public void AddLink(PathLink pLink)
 {
     List<PathLink> newLinks = links == null ? new List<PathLink>() : new List<PathLink>(links);
     newLinks.Add(pLink);
     links = newLinks;
 }
Esempio n. 28
0
 public void RemoveLink(PathLink pLink)
 {
     List<PathLink> newLinks = links == null ? new List<PathLink>() : new List<PathLink>(links);
     newLinks.Remove(pLink);
     links = newLinks;
 }
Esempio n. 29
0
 public void AddLink(PathLink pLink)
 {
     _links.Add(pLink);
 }