コード例 #1
0
        private static void ReconfigureStationAccess()
        {
            var pathList      = new List <BuildingInfo.PathInfo>();
            var connectList   = new List <Vector3[]>();
            var singleGap     = 16;
            var directionList = new List <string>();

            //for (int i = 0; i < m_Info.m_paths.Length; i++)
            //{
            //    var thePath = m_Info.m_paths[i];
            //    if (thePath.m_netInfo == null || thePath.m_nodes == null || thePath.m_nodes.Count() < 2)
            //        continue;
            //    if (thePath.m_netInfo.IsUndergroundMetroStationTrack())
            //    {
            //        var xDirection = (thePath.m_nodes.First().x - thePath.m_nodes.Last().x);
            //        var zDirection = (thePath.m_nodes.First().z - thePath.m_nodes.Last().z);
            //        var direction = $"{xDirection},{zDirection}";
            //        var antiDirection = $"{-xDirection},{-zDirection}";
            //        if (directionList.Contains(direction))
            //        {
            //            continue;
            //        }
            //        if (directionList.Contains(antiDirection))
            //        {
            //            thePath.m_nodes = thePath.m_nodes.Reverse().ToArray();
            //        }
            //        else
            //        {
            //            directionList.Add(direction);
            //        }
            //    }
            //}

            for (int i = 0; i < m_Info.m_paths.Length; i++)
            {
                var thePath = m_Info.m_paths[i];
                if (thePath.m_netInfo == null || thePath.m_nodes == null || thePath.m_nodes.Count() < 2)
                {
                    continue;
                }
                if (thePath.m_netInfo.IsUndergroundSmallStationTrack() && !IsPathGenerated(thePath))
                {
                    var xCoeff = -(thePath.m_nodes.First().x - thePath.m_nodes.Last().x) / Vector3.Distance(thePath.m_nodes.First(), thePath.m_nodes.Last());
                    var zCoeff = (thePath.m_nodes.First().z - thePath.m_nodes.Last().z) / Vector3.Distance(thePath.m_nodes.First(), thePath.m_nodes.Last());

                    var multiplier       = 1;
                    var nearestTrackNode = m_Info.m_paths.Where(p => p.m_netInfo.IsUndergroundMetroStationTrack()).SelectMany(p => p.m_nodes).Where(n => n.y == thePath.m_nodes.First().y).OrderBy(n => Vector3.Distance(n, thePath.m_nodes.First())).FirstOrDefault();
                    if (Vector3.Distance(nearestTrackNode, thePath.m_nodes.First()) <= 2 * singleGap)
                    {
                        multiplier = -1;
                    }
                    var aNewPath = thePath.ShallowClone();
                    var nodeList = new List <Vector3>();
                    nodeList.Add(new Vector3()
                    {
                        x = thePath.m_nodes.First().x + multiplier * zCoeff * singleGap,
                        y = thePath.m_nodes.First().y,
                        z = thePath.m_nodes.First().z + multiplier * xCoeff * singleGap
                    });
                    nodeList.Add(new Vector3()
                    {
                        x = thePath.m_nodes.Last().x + multiplier * zCoeff * singleGap,
                        y = thePath.m_nodes.Last().y,
                        z = thePath.m_nodes.Last().z + multiplier * xCoeff * singleGap
                    });
                    aNewPath.m_nodes = nodeList.ToArray();
                    MarkPathGenerated(aNewPath);
                    pathList.Add(aNewPath);
                }
                pathList.Add(thePath);
            }

            var aPath = pathList.FirstOrDefault(p => IsPedestrianPath(p));

            if (aPath == null)
            {
                aPath = new BuildingInfo.PathInfo();
            }

            for (int i = 0; i < pathList.Count; i++)
            {
                if (pathList[i].m_netInfo != null && pathList[i].m_netInfo.IsUndergroundMetroStationTrack())
                {
                    TrackPath = pathList[i];
                    var middleBend = GetMiddle(TrackPath, true);
                    var middle     = GetMiddle(TrackPath, false);
                    BendVector = middleBend - middle;

                    //var trackNodes = new List<Vector3>();
                    //for (var j = 0; j < trackPath.m_nodes.Count(); j++)
                    //{
                    //    trackNodes.Add(new Vector3()
                    //    {
                    //        x = trackPath.m_nodes[j].x - bendVector.x,
                    //        y = trackPath.m_nodes[j].y,
                    //        z = trackPath.m_nodes[j].z - bendVector.z
                    //    });
                    //}
                    //trackPath.m_nodes = trackNodes.ToArray();
                    NewPath = aPath.ShallowClone();
                    NewPath.AssignNetInfo(SpecialNetInfo);
                    MarkPathGenerated(NewPath);

                    xCoeff = -(TrackPath.m_nodes[0].x - TrackPath.m_nodes.Last().x) / Vector3.Distance(TrackPath.m_nodes[0], TrackPath.m_nodes.Last());
                    zCoeff = (TrackPath.m_nodes[0].z - TrackPath.m_nodes.Last().z) / Vector3.Distance(TrackPath.m_nodes[0], TrackPath.m_nodes.Last());
                    var stationLength = Vector3.Distance(TrackPath.m_nodes[0], TrackPath.m_nodes.Last());
                    StairsLengthX = (((0.12f * m_BendStrength) + 1) * (stationLength * StairCoeff)) * -xCoeff;
                    StairsLengthZ = (((0.12f * m_BendStrength) + 1) * (stationLength * StairCoeff)) * zCoeff;
                    var interpolant = 0.6f;
                    Crossing = Vector3.Lerp(TrackPath.m_nodes.First(), TrackPath.m_nodes.Last(), interpolant);
                    if (TrackPath.m_netInfo.IsUndergroundIslandPlatformStationTrack())
                    {
                        pathList.AddRange(SetStationPaths(0));
                    }
                    //else if (TrackPath.m_netInfo.IsUndergroundSideIslandPlatformMetroStationTrack())
                    //{
                    //    pathList.AddRange(SetStationPaths(-14, 0, 14));
                    //}
                    else if (TrackPath.m_netInfo.IsUndergroundSmallStationTrack())
                    {
                        pathList.AddRange(SetStationPaths(5));
                    }
                    else if (TrackPath.m_netInfo.IsUndergroundPlatformLargeMetroStationTrack())
                    {
                        pathList.AddRange(SetStationPaths(-11, 11));
                    }
                    else if (TrackPath.m_netInfo.IsUndergroundDualIslandPlatformMetroStationTrack())
                    {
                        pathList.AddRange(SetStationPaths(-8.8f, -5.5f, 5.5f, 8.8f));
                    }
                    else if (TrackPath.m_netInfo.IsUndergroundSidePlatformMetroStationTrack())
                    {
                        pathList.AddRange(SetStationPaths(-7, 7));
                    }

                    if (!connectList.Contains(NewPath.m_nodes))
                    {
                        connectList.Add(NewPath.m_nodes);
                    }
                }
            }
            if (/*m_SuperInfo == null &&*/ m_Info.m_paths.Count() >= 2)
            {
                CheckPedestrianConnections();
            }
            pathList = CleanPaths(pathList);
            var lowestHighPaths = m_Info.m_paths.Where(p => IsPedestrianPath(p) && p.m_nodes.Any(n => n.y > -4) && p.m_nodes.Any(nd => nd.y <= -4)).ToList();

            if (lowestHighPaths.Count == 0)
            {
                lowestHighPaths.Add(m_Info.m_paths.Where(p => IsPedestrianPath(p))
                                    .OrderByDescending(p => p.m_nodes[0].y)
                                    .FirstOrDefault());
            }
            var connectPoints = new List <Vector3>();

            if (lowestHighPaths != null && lowestHighPaths.Count > 0)
            {
                foreach (BuildingInfo.PathInfo p in lowestHighPaths)
                {
                    if (p != null && p.m_nodes != null && p.m_nodes.Count() > 0)
                    {
                        connectPoints.Add(p.m_nodes.OrderByDescending(n => n.y).ThenBy(n => n.z).LastOrDefault());
                    }
                }
            }
            var currentVector = connectPoints.FirstOrDefault();

            if (connectPoints != null && connectPoints.Count > 0)
            {
                var pool      = new List <Vector3[]>();
                var pivotPath = pathList.FirstOrDefault(p => p.m_nodes.Any(n => n == connectPoints.FirstOrDefault()));
                pool.AddRange(connectList);

                for (var i = 0; i < connectList.Count; i++)
                {
                    var closestVector = pool.SelectMany(n => n).OrderBy(n => (currentVector.x - n.x) + (100 * (connectPoints.FirstOrDefault().y - n.y)) + (currentVector.z - n.z)).LastOrDefault();

                    var closestPath = pathList.FirstOrDefault(p => p.m_nodes.Any(n => n == closestVector));
                    BuildingInfo.PathInfo branch = null;
                    if (currentVector == connectPoints.FirstOrDefault())
                    {
                        branch = ChainPath(pivotPath, closestVector, Array.IndexOf(pivotPath.m_nodes, connectPoints.FirstOrDefault()));
                    }
                    else
                    {
                        branch = ChainPath(closestPath, currentVector, Array.IndexOf(closestPath.m_nodes, closestVector));
                    }
                    branch.AssignNetInfo(SpecialNetInfo);
                    branch.m_forbidLaneConnection = new[] { true, true };
                    pathList.Add(branch);
                    var nodeArrayToLose = pool.FirstOrDefault(na => na.Any(n => n == closestVector));
                    if (nodeArrayToLose != null)
                    {
                        currentVector = nodeArrayToLose.OrderBy(n => Vector3.Distance(closestVector, n)).LastOrDefault();
                        pool.Remove(nodeArrayToLose);
                    }
                }

                if (connectPoints.Count > 1)
                {
                    for (var i = 1; i < connectPoints.Count(); i++)
                    {
                        Vector3 node          = connectPoints[i];
                        Vector3 closestVector = connectList.SelectMany(n => n).OrderBy(n => (node.x - n.x) + (100 * (node.y - n.y)) + (node.z - n.z)).FirstOrDefault();
                        var     closestPath   = pathList.FirstOrDefault(p => p.m_nodes.Any(n => n == closestVector));
                        var     branch        = ChainPath(closestPath, node, Array.IndexOf(closestPath.m_nodes, closestVector));
                        branch.AssignNetInfo(SpecialNetInfo);
                        branch.m_forbidLaneConnection = new[] { true, true };
                        pathList.Add(branch);
                    }
                }
            }

            m_Info.m_paths = CleanPaths(pathList).ToArray();
        }
コード例 #2
0
        private static List <BuildingInfo.PathInfo> SetStationPaths(params float[] connectorHalfWidths)
        {
            var retval = new List <BuildingInfo.PathInfo>();

            if (connectorHalfWidths != null)
            {
                var newNodes = new List <Vector3>();
                var connectorHalfWidthList = new List <float>();
                connectorHalfWidthList.AddRange(connectorHalfWidths);
                connectorHalfWidthList.Sort();
                var offset        = connectorHalfWidthList[0];
                var forbiddenList = new List <bool>();

                for (int i = 0; i < connectorHalfWidthList.Count(); i++)
                {
                    if (i == 0)
                    {
                        newNodes.Add(new Vector3()
                        {
                            x = Crossing.x + (connectorHalfWidthList[0] * zCoeff) - (3 * xCoeff),
                            y = TrackPath.m_nodes.Last().y + 8,
                            z = Crossing.z + (connectorHalfWidthList[0] * xCoeff) + (3 * zCoeff)
                        });
                        newNodes[0] = new Vector3(newNodes[0].x - BendVector.x, newNodes[0].y, newNodes[0].z + BendVector.z);
                    }
                    else
                    {
                        offset -= connectorHalfWidthList[i];
                        newNodes.Add(new Vector3()
                        {
                            x = newNodes[i - 1].x + (Math.Abs(offset) * zCoeff),
                            y = TrackPath.m_nodes.Last().y + 8,
                            z = newNodes[i - 1].z + (Math.Abs(offset) * xCoeff)
                        });
                        offset = connectorHalfWidthList[i];
                    }
                    forbiddenList.Add(true);
                }


                var averagedNodeList = new List <Vector3>();
                var stairNodes       = new List <Vector3>();
                if (newNodes.Count() == 1)
                {
                    averagedNodeList.Add(newNodes.First());
                    stairNodes.Add(new Vector3()
                    {
                        x = newNodes[0].x + StairsLengthX,
                        y = TrackPath.m_nodes.Last().y,
                        z = newNodes[0].z + StairsLengthZ,
                    });
                }
                else
                {
                    var mergeOnLast = false;
                    for (int i = 0; i < newNodes.Count(); i++)
                    {
                        if (i > 0)
                        {
                            if (mergeOnLast)
                            {
                                mergeOnLast = false;
                            }
                            else if (Vector3.Distance(newNodes[i], newNodes[i - 1]) < 4)
                            {
                                averagedNodeList.Add(((newNodes[i] + newNodes[i - 1]) / 2));
                                mergeOnLast = true;
                            }
                            else
                            {
                                averagedNodeList.Add(newNodes[i - 1]);
                                if (i == newNodes.Count() - 1)
                                {
                                    averagedNodeList.Add(newNodes[i]);
                                }
                            }
                        }

                        stairNodes.Add(new Vector3()
                        {
                            x = newNodes[i].x + StairsLengthX,
                            y = TrackPath.m_nodes.Last().y,
                            z = newNodes[i].z + StairsLengthZ,
                        });
                    }
                }

                NewPath.m_nodes = averagedNodeList.ToArray();
                NewPath.m_forbidLaneConnection = forbiddenList.ToArray();
                NewPath.AssignNetInfo(m_SpecialNetInfo);

                retval.Add(NewPath);

                for (var i = 0; i < stairNodes.Count(); i++)
                {
                    var closestIndex    = averagedNodeList.IndexOf(averagedNodeList.OrderBy(n => Vector3.Distance(n, stairNodes[i])).FirstOrDefault());
                    var branchPathStair = ChainPath(NewPath, stairNodes[i], closestIndex);
                    branchPathStair.m_forbidLaneConnection = new[] { true, false };
                    branchPathStair.AssignNetInfo(m_SpecialNetInfo);
                    retval.Add(branchPathStair);
                }
            }
            return(retval);
        }