Пример #1
0
 private void Awake()
 {
     aiPos      = GetComponent <Transform>();
     aiBody     = GetComponent <Rigidbody2D>();
     pathFinder = FindObjectOfType <PathFinder>();
     spawner    = FindObjectOfType <Spawner>();
     truckNode  = pathFinder.GetClosestNode(new Vector3(aiPos.position.x, aiPos.position.y, 0));
 }
Пример #2
0
 public PathFinder.Node FindEnd(PathFinder.Node start)
 {
     for (PathFinder.Node i = start; i != null; i = i.next)
     {
         if (i.next == null)
         {
             return(i);
         }
     }
     return(start);
 }
Пример #3
0
 public PathFinder.Node FindEnd(PathFinder.Node start)
 {
     for (PathFinder.Node node = start; node != null; node = node.next)
     {
         if (node.next == null)
         {
             return(node);
         }
     }
     return(start);
 }
Пример #4
0
    private PathFinder.Node FindPathReversed(List <PathFinder.Point> startList, List <PathFinder.Point> endList, int depth = 2147483647)
    {
        if (this.visited != null)
        {
            Array.Clear(this.visited, 0, this.visited.Length);
        }
        else
        {
            this.visited = new bool[this.costmap.GetLength(0), this.costmap.GetLength(1)];
        }
        int num     = 0;
        int length  = this.costmap.GetLength(0) - 1;
        int num1    = 0;
        int length1 = this.costmap.GetLength(1) - 1;
        IntrusiveMinHeap <PathFinder.Node> intrusiveMinHeap = new IntrusiveMinHeap <PathFinder.Node>();

        foreach (PathFinder.Point point in startList)
        {
            int num2 = this.costmap[point.y, point.x];
            int num3 = this.Heuristic(point, endList);
            intrusiveMinHeap.Add(new PathFinder.Node(point, num2, num3, null));
            this.visited[point.y, point.x] = true;
        }
        while (!intrusiveMinHeap.Empty)
        {
            int num4 = depth;
            depth = num4 - 1;
            if (num4 <= 0)
            {
                break;
            }
            PathFinder.Node node = intrusiveMinHeap.Pop();
            if (node.heuristic == 0)
            {
                return(node);
            }
            for (int i = 0; i < (int)this.neighbors.Length; i++)
            {
                PathFinder.Point point1 = node.point + this.neighbors[i];
                if (point1.x >= num && point1.x <= length && point1.y >= num1 && point1.y <= length1 && !this.visited[point1.y, point1.x])
                {
                    this.visited[point1.y, point1.x] = true;
                    int num5 = this.costmap[point1.y, point1.x];
                    if (num5 != 2147483647)
                    {
                        int num6 = node.cost + num5;
                        int num7 = this.Heuristic(point1, endList);
                        intrusiveMinHeap.Add(new PathFinder.Node(point1, num6, num7, node));
                    }
                }
            }
        }
        return(null);
    }
Пример #5
0
    private void FollowPath(PathFinder.Node goalNode)
    {
        if (currentNode != goalNode)
        {
            aiBody.velocity = (currentNode.parent.pos - (Vector2)aiPos.position).normalized * speed;
        }

        distance = pathFinder.DistanceManhattan(aiPos.position, currentNode.parent.pos);
        if (distance <= 0.1f)
        {
            currentNode = currentNode.parent;
        }
    }
Пример #6
0
    private PathFinder.Node FindPathReversed(
        List <PathFinder.Point> startList,
        List <PathFinder.Point> endList,
        int depth = 2147483647)
    {
        if (this.visited == null)
        {
            this.visited = new bool[this.costmap.GetLength(0), this.costmap.GetLength(1)];
        }
        else
        {
            Array.Clear((Array)this.visited, 0, this.visited.Length);
        }
        int num1 = 0;
        int num2 = this.costmap.GetLength(0) - 1;
        int num3 = 0;
        int num4 = this.costmap.GetLength(1) - 1;
        IntrusiveMinHeap <PathFinder.Node> intrusiveMinHeap = (IntrusiveMinHeap <PathFinder.Node>)null;

        foreach (PathFinder.Point start in startList)
        {
            int cost      = this.costmap[start.y, start.x];
            int heuristic = this.Heuristic(start, endList);
            ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Add(new PathFinder.Node(start, cost, heuristic, (PathFinder.Node)null));
            this.visited[start.y, start.x] = true;
        }
        while (!((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).get_Empty() && depth-- > 0)
        {
            PathFinder.Node next = ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Pop();
            if (next.heuristic == 0)
            {
                return(next);
            }
            for (int index = 0; index < this.neighbors.Length; ++index)
            {
                PathFinder.Point point = next.point + this.neighbors[index];
                if (point.x >= num1 && point.x <= num2 && (point.y >= num3 && point.y <= num4) && !this.visited[point.y, point.x])
                {
                    this.visited[point.y, point.x] = true;
                    int num5 = this.costmap[point.y, point.x];
                    if (num5 != int.MaxValue)
                    {
                        int cost      = next.cost + num5;
                        int heuristic = this.Heuristic(point, endList);
                        ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Add(new PathFinder.Node(point, cost, heuristic, next));
                    }
                }
            }
        }
        return((PathFinder.Node)null);
    }
Пример #7
0
    public void SpawnEntities(Vector2Int mapSize)
    {
        //spawn player on the most top left node
        PathFinder.Node spawnNode = pathFinder.GetClosestNode(new Vector3Int(0, mapSize.y, 0));
        playerStartpos = spawnNode.pos;
        Instantiate(prefabPlayer, playerStartpos, Quaternion.identity);

        //spawn AI on the most down right node
        spawnNode  = pathFinder.GetClosestNode(new Vector3Int(mapSize.x, -1, 0));
        aiStartPos = spawnNode.pos;
        Instantiate(prefabIa, aiStartPos, Quaternion.identity);

        //spawn boxes
        for (int i = 0; i < maxBoxes; i++)
        {
            int        spawnX   = Random.Range(0, mapSize.x);
            int        spawnY   = Random.Range(0, mapSize.y);
            Vector3Int spawnPos = new Vector3Int(spawnX, spawnY, 0);
            bool       canSpawn = true;


            //block spawn in player and AI position
            spawnNode = pathFinder.GetClosestNode(spawnPos);
            if (spawnNode.pos == playerStartpos ||
                spawnNode.pos == aiStartPos)
            {
                canSpawn = false;
            }

            //block spawn in other boxes position
            foreach (Vector2 boxPos in boxesPos)
            {
                if (spawnNode.pos == boxPos)
                {
                    canSpawn = false;
                    break;
                }
            }

            if (canSpawn)
            {
                boxesPos.Add(spawnNode.pos);
                Instantiate(prefabBox, boxesPos[i], Quaternion.identity);
            }
            else
            {
                i--;
            }
        }
    }
Пример #8
0
    public PathFinder.Node FindClosestWalkable(PathFinder.Point start, int depth = 2147483647)
    {
        if (this.visited != null)
        {
            Array.Clear(this.visited, 0, this.visited.Length);
        }
        else
        {
            this.visited = new bool[this.costmap.GetLength(0), this.costmap.GetLength(1)];
        }
        int num     = 0;
        int length  = this.costmap.GetLength(0) - 1;
        int num1    = 0;
        int length1 = this.costmap.GetLength(1) - 1;
        IntrusiveMinHeap <PathFinder.Node> intrusiveMinHeap = new IntrusiveMinHeap <PathFinder.Node>();
        int num2 = 1;
        int num3 = this.Heuristic(start);

        intrusiveMinHeap.Add(new PathFinder.Node(start, num2, num3, null));
        this.visited[start.y, start.x] = true;
        while (!intrusiveMinHeap.Empty)
        {
            int num4 = depth;
            depth = num4 - 1;
            if (num4 <= 0)
            {
                break;
            }
            PathFinder.Node node = intrusiveMinHeap.Pop();
            if (node.heuristic == 0)
            {
                return(node);
            }
            for (int i = 0; i < (int)this.neighbors.Length; i++)
            {
                PathFinder.Point point = node.point + this.neighbors[i];
                if (point.x >= num && point.x <= length && point.y >= num1 && point.y <= length1 && !this.visited[point.y, point.x])
                {
                    this.visited[point.y, point.x] = true;
                    int num5 = node.cost + 1;
                    int num6 = this.Heuristic(point);
                    intrusiveMinHeap.Add(new PathFinder.Node(point, num5, num6, node));
                }
            }
        }
        return(null);
    }
Пример #9
0
 public PathFinder.Node Reverse(PathFinder.Node start)
 {
     PathFinder.Node node1 = (PathFinder.Node)null;
     PathFinder.Node node2 = (PathFinder.Node)null;
     for (PathFinder.Node node3 = start; node3 != null; node3 = node3.next)
     {
         if (node1 != null)
         {
             node1.next = node2;
         }
         node2 = node1;
         node1 = node3;
     }
     if (node1 != null)
     {
         node1.next = node2;
     }
     return(node1);
 }
Пример #10
0
 public PathFinder.Node Reverse(PathFinder.Node start)
 {
     PathFinder.Node node  = null;
     PathFinder.Node node1 = null;
     for (PathFinder.Node i = start; i != null; i = i.next)
     {
         if (node != null)
         {
             node.next = node1;
         }
         node1 = node;
         node  = i;
     }
     if (node != null)
     {
         node.next = node1;
     }
     return(node);
 }
Пример #11
0
    public PathFinder.Node FindClosestWalkable(PathFinder.Point start, int depth = 2147483647)
    {
        if (this.visited == null)
        {
            this.visited = new bool[this.costmap.GetLength(0), this.costmap.GetLength(1)];
        }
        else
        {
            Array.Clear((Array)this.visited, 0, this.visited.Length);
        }
        int num1 = 0;
        int num2 = this.costmap.GetLength(0) - 1;
        int num3 = 0;
        int num4 = this.costmap.GetLength(1) - 1;
        IntrusiveMinHeap <PathFinder.Node> intrusiveMinHeap = (IntrusiveMinHeap <PathFinder.Node>)null;
        int cost1      = 1;
        int heuristic1 = this.Heuristic(start);

        ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Add(new PathFinder.Node(start, cost1, heuristic1, (PathFinder.Node)null));
        this.visited[start.y, start.x] = true;
        while (!((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).get_Empty() && depth-- > 0)
        {
            PathFinder.Node next = ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Pop();
            if (next.heuristic == 0)
            {
                return(next);
            }
            for (int index = 0; index < this.neighbors.Length; ++index)
            {
                PathFinder.Point point = next.point + this.neighbors[index];
                if (point.x >= num1 && point.x <= num2 && (point.y >= num3 && point.y <= num4) && !this.visited[point.y, point.x])
                {
                    this.visited[point.y, point.x] = true;
                    int cost2      = next.cost + 1;
                    int heuristic2 = this.Heuristic(point);
                    ((IntrusiveMinHeap <PathFinder.Node>) ref intrusiveMinHeap).Add(new PathFinder.Node(point, cost2, heuristic2, next));
                }
            }
        }
        return((PathFinder.Node)null);
    }
Пример #12
0
    private void Update()
    {
        switch (state)
        {
        case AIstate.IDLE:
            break;

        case AIstate.SEARCH_BOX_PATH:

            CheckAi();
            boxPos    = spawner.ReturnRandomBoxPos();
            goalNode  = pathFinder.GetClosestNode(new Vector3(boxPos.x, boxPos.y, 0));
            startNode = pathFinder.GetClosestNode(new Vector3(aiPos.position.x, aiPos.position.y, 0));
            pathFinder.FindPath(goalNode, startNode);
            currentNode = startNode;
            state       = AIstate.FOLLOW_PATH;
            break;

        case AIstate.SEARCH_TRUCK_PATH:

            CheckAi();
            goalNode  = truckNode;
            startNode = pathFinder.GetClosestNode(new Vector3(aiPos.position.x, aiPos.position.y, 0));
            pathFinder.FindPath(goalNode, startNode);
            currentNode = startNode;
            state       = AIstate.FOLLOW_PATH;
            break;

        case AIstate.FOLLOW_PATH:

            CheckAi();
            FollowPath(goalNode);
            break;

        default:
            throw new ArgumentOutOfRangeException();
        }
    }
Пример #13
0
    public override void Process(uint seed)
    {
        List <PathList>     pathLists   = new List <PathList>();
        TerrainHeightMap    heightMap   = TerrainMeta.HeightMap;
        TerrainTopologyMap  topologyMap = TerrainMeta.TopologyMap;
        List <MonumentInfo> monuments   = TerrainMeta.Path.Monuments;

        if (monuments.Count == 0)
        {
            return;
        }
        int num = Mathf.NextPowerOfTwo((int)((float)((float)World.Size) / 10f));

        int[,] numArray = new int[num, num];
        float single = 5f;

        for (int i = 0; i < num; i++)
        {
            float single1 = ((float)i + 0.5f) / (float)num;
            for (int j = 0; j < num; j++)
            {
                float single2  = ((float)j + 0.5f) / (float)num;
                int   num1     = SeedRandom.Range(ref seed, 100, 500);
                float slope    = heightMap.GetSlope(single2, single1);
                int   topology = topologyMap.GetTopology(single2, single1, single);
                int   num2     = 2295686;
                int   num3     = 49152;
                if (slope > 20f || (topology & num2) != 0)
                {
                    numArray[i, j] = 2147483647;
                }
                else if ((topology & num3) == 0)
                {
                    numArray[i, j] = 1 + (int)(slope * slope * 10f) + num1;
                }
                else
                {
                    numArray[i, j] = 2500;
                }
            }
        }
        PathFinder pathFinder = new PathFinder(numArray, true);
        List <GenerateRoadLayout.PathSegment> pathSegments = new List <GenerateRoadLayout.PathSegment>();
        List <GenerateRoadLayout.PathNode>    pathNodes    = new List <GenerateRoadLayout.PathNode>();
        List <GenerateRoadLayout.PathNode>    pathNodes1   = new List <GenerateRoadLayout.PathNode>();
        List <PathFinder.Point> points  = new List <PathFinder.Point>();
        List <PathFinder.Point> points1 = new List <PathFinder.Point>();
        List <PathFinder.Point> points2 = new List <PathFinder.Point>();

        foreach (MonumentInfo monument in monuments)
        {
            bool count = pathNodes.Count == 0;
            foreach (TerrainPathConnect target in monument.GetTargets(InfrastructureType.Road))
            {
                PathFinder.Node node = pathFinder.FindClosestWalkable(target.GetPoint(num), 100000);
                if (node == null)
                {
                    continue;
                }
                GenerateRoadLayout.PathNode pathNode = new GenerateRoadLayout.PathNode()
                {
                    monument = monument,
                    target   = target,
                    node     = node
                };
                if (!count)
                {
                    pathNodes1.Add(pathNode);
                }
                else
                {
                    pathNodes.Add(pathNode);
                }
            }
        }
        while (pathNodes1.Count != 0)
        {
            points1.Clear();
            points2.Clear();
            points1.AddRange(
                from x in pathNodes
                select x.node.point);
            points1.AddRange(points);
            points2.AddRange(
                from x in pathNodes1
                select x.node.point);
            PathFinder.Node node1 = pathFinder.FindPathUndirected(points1, points2, 100000);
            if (node1 != null)
            {
                GenerateRoadLayout.PathSegment pathSegment = new GenerateRoadLayout.PathSegment();
                for (PathFinder.Node k = node1; k != null; k = k.next)
                {
                    if (k == node1)
                    {
                        pathSegment.start = k;
                    }
                    if (k.next == null)
                    {
                        pathSegment.end = k;
                    }
                }
                pathSegments.Add(pathSegment);
                GenerateRoadLayout.PathNode pathNode1 = pathNodes1.Find((GenerateRoadLayout.PathNode x) => {
                    if (x.node.point == pathSegment.start.point)
                    {
                        return(true);
                    }
                    return(x.node.point == pathSegment.end.point);
                });
                pathNodes.AddRange(
                    from x in pathNodes1
                    where x.monument == pathNode1.monument
                    select x);
                pathNodes1.RemoveAll((GenerateRoadLayout.PathNode x) => x.monument == pathNode1.monument);
                int num4 = 1;
                for (PathFinder.Node l = node1; l != null; l = l.next)
                {
                    if (num4 % 8 == 0)
                    {
                        points.Add(l.point);
                    }
                    num4++;
                }
            }
            else
            {
                GenerateRoadLayout.PathNode item = pathNodes1[0];
                pathNodes.AddRange(
                    from x in pathNodes1
                    where x.monument == item.monument
                    select x);
                pathNodes1.RemoveAll((GenerateRoadLayout.PathNode x) => x.monument == item.monument);
            }
        }
        foreach (GenerateRoadLayout.PathNode pathNode2 in pathNodes)
        {
            GenerateRoadLayout.PathSegment pathSegment1 = pathSegments.Find((GenerateRoadLayout.PathSegment x) => {
                if (x.start.point == pathNode2.node.point)
                {
                    return(true);
                }
                return(x.end.point == pathNode2.node.point);
            });
            if (pathSegment1 == null)
            {
                continue;
            }
            if (pathSegment1.start.point != pathNode2.node.point)
            {
                if (pathSegment1.end.point != pathNode2.node.point)
                {
                    continue;
                }
                pathSegment1.end.next = pathNode2.node;
                pathSegment1.end      = pathFinder.FindEnd(pathNode2.node);
                pathSegment1.target   = pathNode2.target;
            }
            else
            {
                PathFinder.Node node2 = pathNode2.node;
                PathFinder.Node node3 = pathFinder.Reverse(pathNode2.node);
                node2.next          = pathSegment1.start;
                pathSegment1.start  = node3;
                pathSegment1.origin = pathNode2.target;
            }
        }
        List <Vector3> vector3s = new List <Vector3>();

        foreach (GenerateRoadLayout.PathSegment pathSegment2 in pathSegments)
        {
            bool flag  = false;
            bool flag1 = false;
            for (PathFinder.Node m = pathSegment2.start; m != null; m = m.next)
            {
                float single3 = ((float)m.point.x + 0.5f) / (float)num;
                float single4 = ((float)m.point.y + 0.5f) / (float)num;
                if (pathSegment2.start == m && pathSegment2.origin != null)
                {
                    flag    = true;
                    single3 = TerrainMeta.NormalizeX(pathSegment2.origin.transform.position.x);
                    single4 = TerrainMeta.NormalizeZ(pathSegment2.origin.transform.position.z);
                }
                else if (pathSegment2.end == m && pathSegment2.target != null)
                {
                    flag1   = true;
                    single3 = TerrainMeta.NormalizeX(pathSegment2.target.transform.position.x);
                    single4 = TerrainMeta.NormalizeZ(pathSegment2.target.transform.position.z);
                }
                float single5 = TerrainMeta.DenormalizeX(single3);
                float single6 = TerrainMeta.DenormalizeZ(single4);
                float single7 = Mathf.Max(heightMap.GetHeight(single3, single4), 1f);
                vector3s.Add(new Vector3(single5, single7, single6));
            }
            if (vector3s.Count == 0)
            {
                continue;
            }
            if (vector3s.Count >= 2)
            {
                PathList pathList = new PathList(string.Concat("Road ", pathLists.Count), vector3s.ToArray())
                {
                    Width         = 10f,
                    InnerPadding  = 1f,
                    OuterPadding  = 1f,
                    InnerFade     = 1f,
                    OuterFade     = 8f,
                    RandomScale   = 0.75f,
                    MeshOffset    = 0f,
                    TerrainOffset = -0.5f,
                    Topology      = 2048,
                    Splat         = 128,
                    Start         = flag,
                    End           = flag1
                };
                pathLists.Add(pathList);
            }
            vector3s.Clear();
        }
        foreach (PathList pathList1 in pathLists)
        {
            pathList1.Path.Smoothen(2);
        }
        TerrainMeta.Path.Roads.AddRange(pathLists);
    }
Пример #14
0
    public override void Process(uint seed)
    {
        if (World.Networked)
        {
            TerrainMeta.Path.Roads.Clear();
            TerrainMeta.Path.Roads.AddRange(World.GetPaths("Road"));
            return;
        }
        List <PathList> list = new List <PathList>();

        int[,] array = TerrainPath.CreateRoadCostmap(ref seed);
        PathFinder              pathFinder = new PathFinder(array);
        int                     length     = array.GetLength(0);
        List <PathSegment>      list2      = new List <PathSegment>();
        List <PathNode>         list3      = new List <PathNode>();
        List <PathNode>         list4      = new List <PathNode>();
        List <PathNode>         list5      = new List <PathNode>();
        List <PathFinder.Point> list6      = new List <PathFinder.Point>();
        List <PathFinder.Point> list7      = new List <PathFinder.Point>();
        List <PathFinder.Point> list8      = new List <PathFinder.Point>();

        foreach (PathList road in TerrainMeta.Path.Roads)
        {
            if (road.ProcgenStartNode == null || road.ProcgenEndNode == null)
            {
                continue;
            }
            int num = 1;
            for (PathFinder.Node node4 = road.ProcgenStartNode; node4 != null; node4 = node4.next)
            {
                if (num % 8 == 0)
                {
                    list6.Add(node4.point);
                }
                num++;
            }
        }
        foreach (MonumentInfo monument in TerrainMeta.Path.Monuments)
        {
            if (monument.Type == MonumentType.Roadside)
            {
                continue;
            }
            TerrainPathConnect[] componentsInChildren = monument.GetComponentsInChildren <TerrainPathConnect>(true);
            foreach (TerrainPathConnect terrainPathConnect in componentsInChildren)
            {
                if (terrainPathConnect.Type == RoadType)
                {
                    PathFinder.Point pathFinderPoint = terrainPathConnect.GetPathFinderPoint(length);
                    PathFinder.Node  node5           = pathFinder.FindClosestWalkable(pathFinderPoint, 100000);
                    if (node5 != null)
                    {
                        PathNode pathNode = new PathNode();
                        pathNode.monument = monument;
                        pathNode.target   = terrainPathConnect;
                        pathNode.node     = node5;
                        list4.Add(pathNode);
                    }
                }
            }
        }
        while (list4.Count != 0 || list5.Count != 0)
        {
            if (list4.Count == 0)
            {
                PathNode node3 = list5[0];
                list4.AddRange(list5.Where((PathNode x) => x.monument == node3.monument));
                list5.RemoveAll((PathNode x) => x.monument == node3.monument);
                pathFinder.PushPoint      = node3.monument.GetPathFinderPoint(length);
                pathFinder.PushRadius     = node3.monument.GetPathFinderRadius(length);
                pathFinder.PushDistance   = 40;
                pathFinder.PushMultiplier = 1;
            }
            list8.Clear();
            list8.AddRange(list4.Select((PathNode x) => x.node.point));
            list7.Clear();
            list7.AddRange(list3.Select((PathNode x) => x.node.point));
            list7.AddRange(list5.Select((PathNode x) => x.node.point));
            list7.AddRange(list6);
            PathFinder.Node node6 = pathFinder.FindPathUndirected(list7, list8, 100000);
            if (node6 == null)
            {
                PathNode node2 = list4[0];
                list5.AddRange(list4.Where((PathNode x) => x.monument == node2.monument));
                list4.RemoveAll((PathNode x) => x.monument == node2.monument);
                list5.Remove(node2);
                list3.Add(node2);
                continue;
            }
            PathSegment segment = new PathSegment();
            for (PathFinder.Node node7 = node6; node7 != null; node7 = node7.next)
            {
                if (node7 == node6)
                {
                    segment.start = node7;
                }
                if (node7.next == null)
                {
                    segment.end = node7;
                }
            }
            list2.Add(segment);
            PathNode node = list4.Find((PathNode x) => x.node.point == segment.start.point || x.node.point == segment.end.point);
            list5.AddRange(list4.Where((PathNode x) => x.monument == node.monument));
            list4.RemoveAll((PathNode x) => x.monument == node.monument);
            list5.Remove(node);
            list3.Add(node);
            PathNode pathNode2 = list5.Find((PathNode x) => x.node.point == segment.start.point || x.node.point == segment.end.point);
            if (pathNode2 != null)
            {
                list5.Remove(pathNode2);
                list3.Add(pathNode2);
            }
            int num2 = 1;
            for (PathFinder.Node node8 = node6; node8 != null; node8 = node8.next)
            {
                if (num2 % 8 == 0)
                {
                    list6.Add(node8.point);
                }
                num2++;
            }
        }
        foreach (PathNode target in list3)
        {
            PathSegment pathSegment = list2.Find((PathSegment x) => x.start.point == target.node.point || x.end.point == target.node.point);
            if (pathSegment != null)
            {
                if (pathSegment.start.point == target.node.point)
                {
                    PathFinder.Node node9 = target.node;
                    PathFinder.Node start = pathFinder.Reverse(target.node);
                    node9.next         = pathSegment.start;
                    pathSegment.start  = start;
                    pathSegment.origin = target.target;
                }
                else if (pathSegment.end.point == target.node.point)
                {
                    pathSegment.end.next = target.node;
                    pathSegment.end      = pathFinder.FindEnd(target.node);
                    pathSegment.target   = target.target;
                }
            }
        }
        List <Vector3> list9 = new List <Vector3>();

        foreach (PathSegment item in list2)
        {
            bool start2 = false;
            bool end    = false;
            for (PathFinder.Node node10 = item.start; node10 != null; node10 = node10.next)
            {
                float normX = ((float)node10.point.x + 0.5f) / (float)length;
                float normZ = ((float)node10.point.y + 0.5f) / (float)length;
                if (item.start == node10 && item.origin != null)
                {
                    start2 = true;
                    normX  = TerrainMeta.NormalizeX(item.origin.transform.position.x);
                    normZ  = TerrainMeta.NormalizeZ(item.origin.transform.position.z);
                }
                else if (item.end == node10 && item.target != null)
                {
                    end   = true;
                    normX = TerrainMeta.NormalizeX(item.target.transform.position.x);
                    normZ = TerrainMeta.NormalizeZ(item.target.transform.position.z);
                }
                float x2 = TerrainMeta.DenormalizeX(normX);
                float z  = TerrainMeta.DenormalizeZ(normZ);
                float y  = Mathf.Max(TerrainMeta.HeightMap.GetHeight(normX, normZ), 1f);
                list9.Add(new Vector3(x2, y, z));
            }
            if (list9.Count != 0)
            {
                if (list9.Count >= 2)
                {
                    int      number   = TerrainMeta.Path.Roads.Count + list.Count;
                    PathList pathList = CreateSegment(number, list9.ToArray());
                    pathList.Start            = start2;
                    pathList.End              = end;
                    pathList.ProcgenStartNode = item.start;
                    pathList.ProcgenEndNode   = item.end;
                    list.Add(pathList);
                }
                list9.Clear();
            }
        }
        foreach (PathList item2 in list)
        {
            item2.Path.Smoothen(4);
            item2.Path.RecalculateTangents();
            item2.AdjustPlacementMap(item2.Width * 2f);
        }
        TerrainMeta.Path.Roads.AddRange(list);
    }
Пример #15
0
    public override void Process(uint seed)
    {
        if (World.Networked || World.Size < MinWorldSize)
        {
            return;
        }
        int[,] array = TerrainPath.CreateRoadCostmap(ref seed);
        PathFinder      pathFinder = new PathFinder(array);
        int             length     = array.GetLength(0);
        int             num        = length / 4;
        int             num2       = 4;
        int             stepcount  = num / num2;
        int             num3       = length / 2;
        int             pos_x      = num;
        int             pos_x2     = length - num;
        int             pos_y      = num;
        int             pos_y2     = length - num;
        int             num4       = 0;
        int             dir_x      = -num2;
        int             dir_x2     = num2;
        int             dir_y      = -num2;
        int             dir_y2     = num2;
        List <RingNode> list       = ((World.Size >= 5000) ? new List <RingNode>
        {
            new RingNode(num3, pos_y2, num4, dir_y, stepcount),
            new RingNode(pos_x2, pos_y2, dir_x, dir_y, stepcount),
            new RingNode(pos_x2, num3, dir_x, num4, stepcount),
            new RingNode(pos_x2, pos_y, dir_x, dir_y2, stepcount),
            new RingNode(num3, pos_y, num4, dir_y2, stepcount),
            new RingNode(pos_x, pos_y, dir_x2, dir_y2, stepcount),
            new RingNode(pos_x, num3, dir_x2, num4, stepcount),
            new RingNode(pos_x, pos_y2, dir_x2, dir_y, stepcount)
        } : new List <RingNode>
        {
            new RingNode(pos_x2, pos_y2, dir_x, dir_y, stepcount),
            new RingNode(pos_x2, pos_y, dir_x, dir_y2, stepcount),
            new RingNode(pos_x, pos_y, dir_x2, dir_y2, stepcount),
            new RingNode(pos_x, pos_y2, dir_x2, dir_y, stepcount)
        });

        for (int i = 0; i < list.Count; i++)
        {
            RingNode ringNode = list[i];
            RingNode next     = list[(i + 1) % list.Count];
            RingNode prev     = list[(i - 1 + list.Count) % list.Count];
            ringNode.next = next;
            ringNode.prev = prev;
            while (!pathFinder.IsWalkable(ringNode.position))
            {
                if (ringNode.attempts <= 0)
                {
                    return;
                }
                ringNode.position += ringNode.direction;
                ringNode.attempts--;
            }
        }
        foreach (RingNode item in list)
        {
            item.path = pathFinder.FindPath(item.position, item.next.position, 250000);
        }
        bool flag = false;

        while (!flag)
        {
            flag = true;
            PathFinder.Point point = new PathFinder.Point(0, 0);
            foreach (RingNode item2 in list)
            {
                point += item2.position;
            }
            point /= list.Count;
            float    num5      = float.MinValue;
            RingNode ringNode2 = null;
            foreach (RingNode item3 in list)
            {
                if (item3.path == null)
                {
                    float num6 = new Vector2(item3.position.x - point.x, item3.position.y - point.y).magnitude;
                    if (item3.prev.path == null)
                    {
                        num6 *= 1.5f;
                    }
                    if (num6 > num5)
                    {
                        num5      = num6;
                        ringNode2 = item3;
                    }
                }
            }
            if (ringNode2 == null)
            {
                continue;
            }
            do
            {
                if (ringNode2.attempts <= 0)
                {
                    return;
                }
                ringNode2.position += ringNode2.direction;
                ringNode2.attempts--;
            }while (!pathFinder.IsWalkable(ringNode2.position));
            ringNode2.path      = pathFinder.FindPath(ringNode2.position, ringNode2.next.position, 250000);
            ringNode2.prev.path = pathFinder.FindPath(ringNode2.prev.position, ringNode2.position, 250000);
            flag = false;
        }
        if (!flag)
        {
            return;
        }
        for (int j = 0; j < list.Count; j++)
        {
            RingNode ringNode3 = list[j];
            RingNode ringNode4 = list[(j + 1) % list.Count];
            for (PathFinder.Node node = ringNode3.path; node != null; node = node.next)
            {
                for (PathFinder.Node node2 = ringNode4.path; node2 != null; node2 = node2.next)
                {
                    if (Mathf.Abs(node.point.x - node2.point.x) <= 1 && Mathf.Abs(node.point.y - node2.point.y) <= 1)
                    {
                        node.next      = null;
                        ringNode4.path = node2;
                        break;
                    }
                }
            }
        }
        PathFinder.Node node3 = null;
        PathFinder.Node node4 = null;
        foreach (RingNode item4 in list)
        {
            if (node3 == null)
            {
                node3 = item4.path;
                node4 = item4.path;
            }
            else
            {
                node4.next = item4.path;
            }
            while (node4.next != null)
            {
                node4 = node4.next;
            }
        }
        node4.next = new PathFinder.Node(node3.point, node3.cost, node3.heuristic);
        List <Vector3> list2 = new List <Vector3>();

        for (PathFinder.Node node5 = node3; node5 != null; node5 = node5.next)
        {
            float normX = ((float)node5.point.x + 0.5f) / (float)length;
            float normZ = ((float)node5.point.y + 0.5f) / (float)length;
            float x     = TerrainMeta.DenormalizeX(normX);
            float z     = TerrainMeta.DenormalizeZ(normZ);
            float y     = Mathf.Max(TerrainMeta.HeightMap.GetHeight(normX, normZ), 1f);
            list2.Add(new Vector3(x, y, z));
        }
        if (list2.Count >= 2)
        {
            int      count    = TerrainMeta.Path.Roads.Count;
            PathList pathList = new PathList("Road " + count, list2.ToArray());
            pathList.Width            = 12f;
            pathList.InnerPadding     = 1f;
            pathList.OuterPadding     = 1f;
            pathList.InnerFade        = 1f;
            pathList.OuterFade        = 8f;
            pathList.RandomScale      = 0.75f;
            pathList.MeshOffset       = 0f;
            pathList.TerrainOffset    = -0.125f;
            pathList.Topology         = 2048;
            pathList.Splat            = 128;
            pathList.Start            = false;
            pathList.End              = false;
            pathList.ProcgenStartNode = node3;
            pathList.ProcgenEndNode   = node4;
            pathList.Path.Smoothen(4);
            pathList.Path.RecalculateTangents();
            pathList.AdjustPlacementMap(24f);
            TerrainMeta.Path.Roads.Add(pathList);
        }
    }
Пример #16
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");
        }
    }
Пример #17
0
    public override void Process(uint seed)
    {
        List <PathList>     pathListList = new List <PathList>();
        TerrainHeightMap    heightMap    = TerrainMeta.HeightMap;
        TerrainTopologyMap  topologyMap  = TerrainMeta.TopologyMap;
        List <MonumentInfo> monuments    = TerrainMeta.Path.Monuments;

        if (monuments.Count == 0)
        {
            return;
        }
        int res = Mathf.NextPowerOfTwo((int)((double)World.Size / 10.0));

        int[,] costmap = new int[res, res];
        float radius = 5f;

        for (int index1 = 0; index1 < res; ++index1)
        {
            float normZ = ((float)index1 + 0.5f) / (float)res;
            for (int index2 = 0; index2 < res; ++index2)
            {
                float normX    = ((float)index2 + 0.5f) / (float)res;
                int   num1     = SeedRandom.Range(ref seed, 100, 500);
                float slope    = heightMap.GetSlope(normX, normZ);
                int   topology = topologyMap.GetTopology(normX, normZ, radius);
                int   num2     = 2295686;
                int   num3     = 49152;
                costmap[index1, index2] = (double)slope > 20.0 || (topology & num2) != 0 ? int.MaxValue : ((topology & num3) == 0 ? 1 + (int)((double)slope * (double)slope * 10.0) + num1 : 2500);
            }
        }
        PathFinder pathFinder = new PathFinder(costmap, true);
        List <GenerateRoadLayout.PathSegment> pathSegmentList = new List <GenerateRoadLayout.PathSegment>();
        List <GenerateRoadLayout.PathNode>    source1         = new List <GenerateRoadLayout.PathNode>();
        List <GenerateRoadLayout.PathNode>    source2         = new List <GenerateRoadLayout.PathNode>();
        List <PathFinder.Point> pointList = new List <PathFinder.Point>();
        List <PathFinder.Point> startList = new List <PathFinder.Point>();
        List <PathFinder.Point> endList   = new List <PathFinder.Point>();

        foreach (MonumentInfo monumentInfo in monuments)
        {
            bool flag = source1.Count == 0;
            foreach (TerrainPathConnect target in monumentInfo.GetTargets(InfrastructureType.Road))
            {
                PathFinder.Point point           = target.GetPoint(res);
                PathFinder.Node  closestWalkable = pathFinder.FindClosestWalkable(point, 100000);
                if (closestWalkable != null)
                {
                    GenerateRoadLayout.PathNode pathNode = new GenerateRoadLayout.PathNode();
                    pathNode.monument = monumentInfo;
                    pathNode.target   = target;
                    pathNode.node     = closestWalkable;
                    if (flag)
                    {
                        source1.Add(pathNode);
                    }
                    else
                    {
                        source2.Add(pathNode);
                    }
                }
            }
        }
        while (source2.Count != 0)
        {
            startList.Clear();
            endList.Clear();
            startList.AddRange(source1.Select <GenerateRoadLayout.PathNode, PathFinder.Point>((Func <GenerateRoadLayout.PathNode, PathFinder.Point>)(x => x.node.point)));
            startList.AddRange((IEnumerable <PathFinder.Point>)pointList);
            endList.AddRange(source2.Select <GenerateRoadLayout.PathNode, PathFinder.Point>((Func <GenerateRoadLayout.PathNode, PathFinder.Point>)(x => x.node.point)));
            PathFinder.Node pathUndirected = pathFinder.FindPathUndirected(startList, endList, 100000);
            if (pathUndirected == null)
            {
                GenerateRoadLayout.PathNode copy = source2[0];
                source1.AddRange(source2.Where <GenerateRoadLayout.PathNode>((Func <GenerateRoadLayout.PathNode, bool>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument))));
                source2.RemoveAll((Predicate <GenerateRoadLayout.PathNode>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument)));
            }
            else
            {
                GenerateRoadLayout.PathSegment segment = new GenerateRoadLayout.PathSegment();
                for (PathFinder.Node node = pathUndirected; node != null; node = node.next)
                {
                    if (node == pathUndirected)
                    {
                        segment.start = node;
                    }
                    if (node.next == null)
                    {
                        segment.end = node;
                    }
                }
                pathSegmentList.Add(segment);
                GenerateRoadLayout.PathNode copy = source2.Find((Predicate <GenerateRoadLayout.PathNode>)(x =>
                {
                    if (!(x.node.point == segment.start.point))
                    {
                        return(x.node.point == segment.end.point);
                    }
                    return(true);
                }));
                source1.AddRange(source2.Where <GenerateRoadLayout.PathNode>((Func <GenerateRoadLayout.PathNode, bool>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument))));
                source2.RemoveAll((Predicate <GenerateRoadLayout.PathNode>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument)));
                int num = 1;
                for (PathFinder.Node node = pathUndirected; node != null; node = node.next)
                {
                    if (num % 8 == 0)
                    {
                        pointList.Add(node.point);
                    }
                    ++num;
                }
            }
        }
        foreach (GenerateRoadLayout.PathNode pathNode in source1)
        {
            GenerateRoadLayout.PathNode    target      = pathNode;
            GenerateRoadLayout.PathSegment pathSegment = pathSegmentList.Find((Predicate <GenerateRoadLayout.PathSegment>)(x =>
            {
                if (!(x.start.point == target.node.point))
                {
                    return(x.end.point == target.node.point);
                }
                return(true);
            }));
            if (pathSegment != null)
            {
                if (pathSegment.start.point == target.node.point)
                {
                    PathFinder.Node node1 = target.node;
                    PathFinder.Node node2 = pathFinder.Reverse(target.node);
                    PathFinder.Node start = pathSegment.start;
                    node1.next         = start;
                    pathSegment.start  = node2;
                    pathSegment.origin = target.target;
                }
                else if (pathSegment.end.point == target.node.point)
                {
                    pathSegment.end.next = target.node;
                    pathSegment.end      = pathFinder.FindEnd(target.node);
                    pathSegment.target   = target.target;
                }
            }
        }
        List <Vector3> vector3List = new List <Vector3>();

        foreach (GenerateRoadLayout.PathSegment pathSegment in pathSegmentList)
        {
            bool flag1 = false;
            bool flag2 = false;
            for (PathFinder.Node node = pathSegment.start; node != null; node = node.next)
            {
                float normX = ((float)node.point.x + 0.5f) / (float)res;
                float normZ = ((float)node.point.y + 0.5f) / (float)res;
                if (pathSegment.start == node && Object.op_Inequality((Object)pathSegment.origin, (Object)null))
                {
                    flag1 = true;
                    normX = TerrainMeta.NormalizeX((float)((Component)pathSegment.origin).get_transform().get_position().x);
                    normZ = TerrainMeta.NormalizeZ((float)((Component)pathSegment.origin).get_transform().get_position().z);
                }
                else if (pathSegment.end == node && Object.op_Inequality((Object)pathSegment.target, (Object)null))
                {
                    flag2 = true;
                    normX = TerrainMeta.NormalizeX((float)((Component)pathSegment.target).get_transform().get_position().x);
                    normZ = TerrainMeta.NormalizeZ((float)((Component)pathSegment.target).get_transform().get_position().z);
                }
                float num1 = TerrainMeta.DenormalizeX(normX);
                float num2 = TerrainMeta.DenormalizeZ(normZ);
                float num3 = Mathf.Max(heightMap.GetHeight(normX, normZ), 1f);
                vector3List.Add(new Vector3(num1, num3, num2));
            }
            if (vector3List.Count != 0)
            {
                if (vector3List.Count >= 2)
                {
                    pathListList.Add(new PathList("Road " + (object)pathListList.Count, vector3List.ToArray())
                    {
                        Width         = 10f,
                        InnerPadding  = 1f,
                        OuterPadding  = 1f,
                        InnerFade     = 1f,
                        OuterFade     = 8f,
                        RandomScale   = 0.75f,
                        MeshOffset    = -0.0f,
                        TerrainOffset = -0.5f,
                        Topology      = 2048,
                        Splat         = 128,
                        Start         = flag1,
                        End           = flag2
                    });
                }
                vector3List.Clear();
            }
        }
        foreach (PathList pathList in pathListList)
        {
            pathList.Path.Smoothen(2);
        }
        TerrainMeta.Path.Roads.AddRange((IEnumerable <PathList>)pathListList);
    }
    public override void Process(uint seed)
    {
        if (World.Networked)
        {
            TerrainMeta.Path.Powerlines.Clear();
            TerrainMeta.Path.Powerlines.AddRange(World.GetPaths("Powerline"));
            return;
        }
        List <PathList>     list      = new List <PathList>();
        List <MonumentInfo> monuments = TerrainMeta.Path.Monuments;

        int[,] array = TerrainPath.CreatePowerlineCostmap(ref seed);
        PathFinder              pathFinder = new PathFinder(array);
        int                     length     = array.GetLength(0);
        List <PathSegment>      list2      = new List <PathSegment>();
        List <PathNode>         list3      = new List <PathNode>();
        List <PathNode>         list4      = 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>();

        foreach (PathList road in TerrainMeta.Path.Roads)
        {
            if (road.ProcgenStartNode == null || road.ProcgenEndNode == null || !road.IsExtraWide)
            {
                continue;
            }
            int num = 1;
            for (PathFinder.Node node = road.ProcgenStartNode; node != null; node = node.next)
            {
                if (num % 8 == 0)
                {
                    list5.Add(node.point);
                }
                num++;
            }
        }
        foreach (MonumentInfo item in monuments)
        {
            TerrainPathConnect[] componentsInChildren = item.GetComponentsInChildren <TerrainPathConnect>(true);
            foreach (TerrainPathConnect terrainPathConnect in componentsInChildren)
            {
                if (terrainPathConnect.Type == InfrastructureType.Power)
                {
                    PathFinder.Point pathFinderPoint = terrainPathConnect.GetPathFinderPoint(length);
                    PathFinder.Node  node2           = pathFinder.FindClosestWalkable(pathFinderPoint, 100000);
                    if (node2 != null)
                    {
                        PathNode pathNode = new PathNode();
                        pathNode.monument = item;
                        pathNode.node     = node2;
                        list4.Add(pathNode);
                    }
                }
            }
        }
        while (list4.Count != 0)
        {
            list7.Clear();
            list7.AddRange(list4.Select((PathNode x) => x.node.point));
            list6.Clear();
            list6.AddRange(list3.Select((PathNode x) => x.node.point));
            list6.AddRange(list5);
            PathFinder.Node node3 = pathFinder.FindPathUndirected(list6, list7, 100000);
            if (node3 == null)
            {
                PathNode copy2 = list4[0];
                list3.AddRange(list4.Where((PathNode x) => x.monument == copy2.monument));
                list4.RemoveAll((PathNode x) => x.monument == copy2.monument);
                continue;
            }
            PathSegment segment = new PathSegment();
            for (PathFinder.Node node4 = node3; node4 != null; node4 = node4.next)
            {
                if (node4 == node3)
                {
                    segment.start = node4;
                }
                if (node4.next == null)
                {
                    segment.end = node4;
                }
            }
            list2.Add(segment);
            PathNode copy = list4.Find((PathNode x) => x.node.point == segment.start.point || x.node.point == segment.end.point);
            list3.AddRange(list4.Where((PathNode x) => x.monument == copy.monument));
            list4.RemoveAll((PathNode x) => x.monument == copy.monument);
            int num2 = 1;
            for (PathFinder.Node node5 = node3; node5 != null; node5 = node5.next)
            {
                if (num2 % 8 == 0)
                {
                    list5.Add(node5.point);
                }
                num2++;
            }
        }
        List <Vector3> list8 = new List <Vector3>();

        foreach (PathSegment item2 in list2)
        {
            for (PathFinder.Node node6 = item2.start; node6 != null; node6 = node6.next)
            {
                float num3   = ((float)node6.point.x + 0.5f) / (float)length;
                float num4   = ((float)node6.point.y + 0.5f) / (float)length;
                float height = TerrainMeta.HeightMap.GetHeight01(num3, num4);
                list8.Add(TerrainMeta.Denormalize(new Vector3(num3, height, num4)));
            }
            if (list8.Count != 0)
            {
                if (list8.Count >= 8)
                {
                    int      num5     = TerrainMeta.Path.Powerlines.Count + list.Count;
                    PathList pathList = new PathList("Powerline " + num5, list8.ToArray());
                    pathList.Start            = true;
                    pathList.End              = true;
                    pathList.ProcgenStartNode = item2.start;
                    pathList.ProcgenEndNode   = item2.end;
                    list.Add(pathList);
                }
                list8.Clear();
            }
        }
        foreach (PathList item3 in list)
        {
            item3.Path.RecalculateTangents();
        }
        TerrainMeta.Path.Powerlines.AddRange(list);
    }
Пример #19
0
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;

            if (nextNode == null)
            {
                nextNode = GetComponent <PathFinder>().Next();
            }

            if (nextNode != null)
            {
                List <Point> soldierCollisions = new List <Point>();

                // Collision with moving units
                foreach (var body in Swarm)
                {
                    if (body != this)
                    {
                        if (body.Transform.Grid == nextNode.Position)
                        {
                            soldierCollisions.Add(body.Transform.Grid);
                            GetComponent <PathFinder>().RecreatePath(soldierCollisions);
                            nextNode = GetComponent <PathFinder>().Next();
                            break;
                        }
                    }
                }

                if (nextNode != null)
                {
                    var nodeWorldPos = Grid.GridToWorld(nextNode.Position);
                    // HACK: Make this work properly with other speeds...
                    float speed = 4f;
                    if (Transform.World.X < nodeWorldPos.X)
                    {
                        Transform.World.X += speed;
                        GetComponent <Component.Transform>().World.Rotation = MathHelper.ToRadians(0);
                    }
                    if (Transform.World.X > nodeWorldPos.X)
                    {
                        Transform.World.X -= speed;
                        GetComponent <Component.Transform>().World.Rotation = MathHelper.ToRadians(180);
                    }
                    if (Transform.World.Y < nodeWorldPos.Y)
                    {
                        Transform.World.Y += speed;
                        GetComponent <Component.Transform>().World.Rotation = MathHelper.ToRadians(90);
                    }
                    if (Transform.World.Y > nodeWorldPos.Y)
                    {
                        Transform.World.Y -= speed;
                        GetComponent <Component.Transform>().World.Rotation = MathHelper.ToRadians(270);
                    }
                    if (Transform.World == nodeWorldPos)
                    {
                        if (currentStep < numberOfSteps)
                        {
                            currentStep++;
                            //lastLastNode = lastNode;
                            //lastNode = nextNode;
                            nextNode = GetComponent <PathFinder>().Next();
                        }
                        else
                        {
                            GetComponent <PathFinder>().Stop();
                        }
                        foreach (var entity in EntityManager.Entities)
                        {
                            if (entity is Soldier)
                            {
                                if (entity.GetComponent <Component.Collision>().Rectangle.Intersects(this.GetComponent <Component.Collision>().Rectangle))
                                {
                                    if (AttackedThisTurn == false)
                                    {
                                        if (Utility.AttackTest(this.GetComponent <Component.Stat>(), entity, Utility.CalculateHitChance(this.GetComponent <Component.Stat>(), this.Transform.World.Position, entity)))
                                        {
                                            AttackedThisTurn = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    public override void Process(uint seed)
    {
        List <PathList>     pathListList = new List <PathList>();
        TerrainHeightMap    heightMap    = TerrainMeta.HeightMap;
        TerrainTopologyMap  topologyMap  = TerrainMeta.TopologyMap;
        List <MonumentInfo> monuments    = TerrainMeta.Path.Monuments;

        if (monuments.Count == 0)
        {
            return;
        }
        int res = Mathf.NextPowerOfTwo((int)((double)World.Size / 10.0));

        int[,] costmap = new int[res, res];
        float radius = 5f;

        for (int index1 = 0; index1 < res; ++index1)
        {
            float normZ = ((float)index1 + 0.5f) / (float)res;
            for (int index2 = 0; index2 < res; ++index2)
            {
                float normX    = ((float)index2 + 0.5f) / (float)res;
                float slope    = heightMap.GetSlope(normX, normZ);
                int   topology = topologyMap.GetTopology(normX, normZ, radius);
                int   num1     = 2295174;
                int   num2     = 55296;
                int   num3     = 512;
                costmap[index1, index2] = (topology & num1) == 0 ? ((topology & num2) == 0 ? ((topology & num3) == 0 ? 1 + (int)((double)slope * (double)slope * 10.0) : 1000) : 2500) : int.MaxValue;
            }
        }
        PathFinder pathFinder = new PathFinder(costmap, true);
        List <GeneratePowerlineLayout.PathSegment> pathSegmentList = new List <GeneratePowerlineLayout.PathSegment>();
        List <GeneratePowerlineLayout.PathNode>    source1         = new List <GeneratePowerlineLayout.PathNode>();
        List <GeneratePowerlineLayout.PathNode>    source2         = new List <GeneratePowerlineLayout.PathNode>();
        List <PathFinder.Point> pointList = new List <PathFinder.Point>();
        List <PathFinder.Point> startList = new List <PathFinder.Point>();
        List <PathFinder.Point> endList   = new List <PathFinder.Point>();

        foreach (MonumentInfo monumentInfo in monuments)
        {
            bool flag = source1.Count == 0;
            foreach (TerrainPathConnect target in monumentInfo.GetTargets(InfrastructureType.Power))
            {
                PathFinder.Point point           = target.GetPoint(res);
                PathFinder.Node  closestWalkable = pathFinder.FindClosestWalkable(point, 100000);
                if (closestWalkable != null)
                {
                    GeneratePowerlineLayout.PathNode pathNode = new GeneratePowerlineLayout.PathNode();
                    pathNode.monument = monumentInfo;
                    pathNode.node     = closestWalkable;
                    if (flag)
                    {
                        source1.Add(pathNode);
                    }
                    else
                    {
                        source2.Add(pathNode);
                    }
                }
            }
        }
        while (source2.Count != 0)
        {
            startList.Clear();
            endList.Clear();
            startList.AddRange(source1.Select <GeneratePowerlineLayout.PathNode, PathFinder.Point>((Func <GeneratePowerlineLayout.PathNode, PathFinder.Point>)(x => x.node.point)));
            startList.AddRange((IEnumerable <PathFinder.Point>)pointList);
            endList.AddRange(source2.Select <GeneratePowerlineLayout.PathNode, PathFinder.Point>((Func <GeneratePowerlineLayout.PathNode, PathFinder.Point>)(x => x.node.point)));
            PathFinder.Node pathUndirected = pathFinder.FindPathUndirected(startList, endList, 100000);
            if (pathUndirected == null)
            {
                GeneratePowerlineLayout.PathNode copy = source2[0];
                source1.AddRange(source2.Where <GeneratePowerlineLayout.PathNode>((Func <GeneratePowerlineLayout.PathNode, bool>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument))));
                source2.RemoveAll((Predicate <GeneratePowerlineLayout.PathNode>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument)));
            }
            else
            {
                GeneratePowerlineLayout.PathSegment segment = new GeneratePowerlineLayout.PathSegment();
                for (PathFinder.Node node = pathUndirected; node != null; node = node.next)
                {
                    if (node == pathUndirected)
                    {
                        segment.start = node;
                    }
                    if (node.next == null)
                    {
                        segment.end = node;
                    }
                }
                pathSegmentList.Add(segment);
                GeneratePowerlineLayout.PathNode copy = source2.Find((Predicate <GeneratePowerlineLayout.PathNode>)(x =>
                {
                    if (!(x.node.point == segment.start.point))
                    {
                        return(x.node.point == segment.end.point);
                    }
                    return(true);
                }));
                source1.AddRange(source2.Where <GeneratePowerlineLayout.PathNode>((Func <GeneratePowerlineLayout.PathNode, bool>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument))));
                source2.RemoveAll((Predicate <GeneratePowerlineLayout.PathNode>)(x => Object.op_Equality((Object)x.monument, (Object)copy.monument)));
                int num = 1;
                for (PathFinder.Node node = pathUndirected; node != null; node = node.next)
                {
                    if (num % 8 == 0)
                    {
                        pointList.Add(node.point);
                    }
                    ++num;
                }
            }
        }
        List <Vector3> vector3List = new List <Vector3>();

        foreach (GeneratePowerlineLayout.PathSegment pathSegment in pathSegmentList)
        {
            for (PathFinder.Node node = pathSegment.start; node != null; node = node.next)
            {
                float normX    = ((float)node.point.x + 0.5f) / (float)res;
                float normZ    = ((float)node.point.y + 0.5f) / (float)res;
                float height01 = heightMap.GetHeight01(normX, normZ);
                vector3List.Add(TerrainMeta.Denormalize(new Vector3(normX, height01, normZ)));
            }
            if (vector3List.Count != 0)
            {
                if (vector3List.Count >= 8)
                {
                    pathListList.Add(new PathList("Powerline " + (object)pathListList.Count, vector3List.ToArray())
                    {
                        Start = true,
                        End   = true
                    });
                }
                vector3List.Clear();
            }
        }
        TerrainMeta.Path.Powerlines.AddRange((IEnumerable <PathList>)pathListList);
    }
Пример #21
0
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            float elapsed = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;

            if (nextNode == null)
            {
                nextNode = GetComponent <PathFinder>().Next();
            }

            if (nextNode != null)
            {
                List <Point> soldierCollisions = new List <Point>();

                // Collision with units at a standstill
                //foreach (var soldier in Squad)
                //{
                //    if (soldier != this)
                //    {
                //        if (!soldier.GetComponent<PathFinder>().IsMoving)
                //        {
                //            soldierCollisions.Add(soldier.Transform.Grid);
                //        }
                //        if (soldier.Transform.Grid == nextNode.Position)
                //        {
                //            GetComponent<PathFinder>().RecreatePath(soldierCollisions);
                //            nextNode = GetComponent<PathFinder>().Next();
                //            break;
                //        }
                //    }

                //}

                // Collision with moving units
                //foreach (var soldier in Squad)
                //{
                //    if (soldier != this)
                //    {
                //        var pathFinder = soldier.GetComponent<PathFinder>();
                //        var position = nextNode.Position;
                //        if (soldier.Transform.Grid == position)
                //        {
                //            soldierCollisions.Add(soldier.Transform.Grid);
                //            GetComponent<PathFinder>().RecreatePath(soldierCollisions);
                //            nextNode = GetComponent<PathFinder>().Next();
                //            break;
                //        }
                //    }
                //}

                if (nextNode != null)
                {
                    var nodeWorldPos = Grid.GridToWorld(nextNode.Position);
                    // HACK: Make this work properly with other speeds...
                    float speed = 4f;
                    if (Transform.World.X < nodeWorldPos.X)
                    {
                        Transform.World.X += speed;
                    }
                    if (Transform.World.X > nodeWorldPos.X)
                    {
                        Transform.World.X -= speed;
                    }
                    if (Transform.World.Y < nodeWorldPos.Y)
                    {
                        Transform.World.Y += speed;
                    }
                    if (Transform.World.Y > nodeWorldPos.Y)
                    {
                        Transform.World.Y -= speed;
                    }

                    if (Transform.World == nodeWorldPos)
                    {
                        //if (AP < NumberOfActionPoints)
                        //{
                        //AP++;
                        lastLastNode = lastNode;
                        lastNode     = nextNode;
                        nextNode     = GetComponent <PathFinder>().Next();
                        //}

                        /*else
                         * {
                         *  GetComponent<PathFinder>().Stop();
                         * }*/
                    }
                }
            }
            if (Fired == true)
            {
                fireTimer += gameTime.ElapsedGameTime.Milliseconds;
                if (fireTimer > timeSpentFired)
                {
                    fireTimer = 0;
                    Fired     = false;
                }
            }
        }
Пример #22
0
    public override void Process(uint seed)
    {
        List <PathList>     pathLists   = new List <PathList>();
        TerrainHeightMap    heightMap   = TerrainMeta.HeightMap;
        TerrainTopologyMap  topologyMap = TerrainMeta.TopologyMap;
        List <MonumentInfo> monuments   = TerrainMeta.Path.Monuments;

        if (monuments.Count == 0)
        {
            return;
        }
        int num = Mathf.NextPowerOfTwo((int)((float)((float)World.Size) / 10f));

        int[,] numArray = new int[num, num];
        float single = 5f;

        for (int i = 0; i < num; i++)
        {
            float single1 = ((float)i + 0.5f) / (float)num;
            for (int j = 0; j < num; j++)
            {
                float single2  = ((float)j + 0.5f) / (float)num;
                float slope    = heightMap.GetSlope(single2, single1);
                int   topology = topologyMap.GetTopology(single2, single1, single);
                int   num1     = 2295174;
                int   num2     = 55296;
                int   num3     = 512;
                if ((topology & num1) != 0)
                {
                    numArray[i, j] = 2147483647;
                }
                else if ((topology & num2) != 0)
                {
                    numArray[i, j] = 2500;
                }
                else if ((topology & num3) == 0)
                {
                    numArray[i, j] = 1 + (int)(slope * slope * 10f);
                }
                else
                {
                    numArray[i, j] = 1000;
                }
            }
        }
        PathFinder pathFinder = new PathFinder(numArray, true);
        List <GeneratePowerlineLayout.PathSegment> pathSegments = new List <GeneratePowerlineLayout.PathSegment>();
        List <GeneratePowerlineLayout.PathNode>    pathNodes    = new List <GeneratePowerlineLayout.PathNode>();
        List <GeneratePowerlineLayout.PathNode>    pathNodes1   = new List <GeneratePowerlineLayout.PathNode>();
        List <PathFinder.Point> points  = new List <PathFinder.Point>();
        List <PathFinder.Point> points1 = new List <PathFinder.Point>();
        List <PathFinder.Point> points2 = new List <PathFinder.Point>();

        foreach (MonumentInfo monument in monuments)
        {
            bool count = pathNodes.Count == 0;
            foreach (TerrainPathConnect target in monument.GetTargets(InfrastructureType.Power))
            {
                PathFinder.Point point = target.GetPoint(num);
                PathFinder.Node  node  = pathFinder.FindClosestWalkable(point, 100000);
                if (node == null)
                {
                    continue;
                }
                GeneratePowerlineLayout.PathNode pathNode = new GeneratePowerlineLayout.PathNode()
                {
                    monument = monument,
                    node     = node
                };
                if (!count)
                {
                    pathNodes1.Add(pathNode);
                }
                else
                {
                    pathNodes.Add(pathNode);
                }
            }
        }
        while (pathNodes1.Count != 0)
        {
            points1.Clear();
            points2.Clear();
            points1.AddRange(
                from x in pathNodes
                select x.node.point);
            points1.AddRange(points);
            points2.AddRange(
                from x in pathNodes1
                select x.node.point);
            PathFinder.Node node1 = pathFinder.FindPathUndirected(points1, points2, 100000);
            if (node1 != null)
            {
                GeneratePowerlineLayout.PathSegment pathSegment = new GeneratePowerlineLayout.PathSegment();
                for (PathFinder.Node k = node1; k != null; k = k.next)
                {
                    if (k == node1)
                    {
                        pathSegment.start = k;
                    }
                    if (k.next == null)
                    {
                        pathSegment.end = k;
                    }
                }
                pathSegments.Add(pathSegment);
                GeneratePowerlineLayout.PathNode pathNode1 = pathNodes1.Find((GeneratePowerlineLayout.PathNode x) => {
                    if (x.node.point == pathSegment.start.point)
                    {
                        return(true);
                    }
                    return(x.node.point == pathSegment.end.point);
                });
                pathNodes.AddRange(
                    from x in pathNodes1
                    where x.monument == pathNode1.monument
                    select x);
                pathNodes1.RemoveAll((GeneratePowerlineLayout.PathNode x) => x.monument == pathNode1.monument);
                int num4 = 1;
                for (PathFinder.Node l = node1; l != null; l = l.next)
                {
                    if (num4 % 8 == 0)
                    {
                        points.Add(l.point);
                    }
                    num4++;
                }
            }
            else
            {
                GeneratePowerlineLayout.PathNode item = pathNodes1[0];
                pathNodes.AddRange(
                    from x in pathNodes1
                    where x.monument == item.monument
                    select x);
                pathNodes1.RemoveAll((GeneratePowerlineLayout.PathNode x) => x.monument == item.monument);
            }
        }
        List <Vector3> vector3s = new List <Vector3>();

        foreach (GeneratePowerlineLayout.PathSegment pathSegment1 in pathSegments)
        {
            for (PathFinder.Node m = pathSegment1.start; m != null; m = m.next)
            {
                float single3  = ((float)m.point.x + 0.5f) / (float)num;
                float single4  = ((float)m.point.y + 0.5f) / (float)num;
                float height01 = heightMap.GetHeight01(single3, single4);
                vector3s.Add(TerrainMeta.Denormalize(new Vector3(single3, height01, single4)));
            }
            if (vector3s.Count == 0)
            {
                continue;
            }
            if (vector3s.Count >= 8)
            {
                PathList pathList = new PathList(string.Concat("Powerline ", pathLists.Count), vector3s.ToArray())
                {
                    Start = true,
                    End   = true
                };
                pathLists.Add(pathList);
            }
            vector3s.Clear();
        }
        TerrainMeta.Path.Powerlines.AddRange(pathLists);
    }