예제 #1
0
        public override void Generate(Map map, GenStepParams parms)
        {
            List <NeededRoad> neededRoads = CalculateNeededRoads(map);

            if (neededRoads.Count == 0)
            {
                return;
            }
            List <DrawCommand> list = new List <DrawCommand>();

            DeepProfiler.Start("RebuildAllRegions");
            map.regionAndRoomUpdater.RebuildAllRegionsAndRooms();
            DeepProfiler.End();
            TerrainDef rockDef      = BaseGenUtility.RegionalRockTerrainDef(map.Tile, beautiful: false);
            IntVec3    centerpoint  = CellFinderLoose.TryFindCentralCell(map, 3, 10);
            RoadDef    bestRoadType = DefDatabase <RoadDef> .AllDefs.Where((RoadDef rd) => neededRoads.Count((NeededRoad nr) => nr.road == rd) >= 2).MaxByWithFallback((RoadDef rd) => rd.priority);

            DrawCommand item;

            if (bestRoadType != null)
            {
                NeededRoad neededRoad = neededRoads[neededRoads.FindIndex((NeededRoad nr) => nr.road == bestRoadType)];
                neededRoads.RemoveAt(neededRoads.FindIndex((NeededRoad nr) => nr.road == bestRoadType));
                NeededRoad neededRoad2 = neededRoads[neededRoads.FindIndex((NeededRoad nr) => nr.road == bestRoadType)];
                neededRoads.RemoveAt(neededRoads.FindIndex((NeededRoad nr) => nr.road == bestRoadType));
                RoadPathingDef pathingDef = neededRoad.road.pathingMode;
                IntVec3        intVec     = FindRoadExitCell(map, neededRoad.angle, centerpoint, ref pathingDef);
                IntVec3        end        = FindRoadExitCell(map, neededRoad2.angle, intVec, ref pathingDef);
                Action         action     = PrepDrawRoad(map, rockDef, intVec, end, neededRoad.road, pathingDef, out centerpoint);
                item = new DrawCommand
                {
                    action  = action,
                    roadDef = bestRoadType
                };
                list.Add(item);
            }
            foreach (NeededRoad item2 in neededRoads)
            {
                RoadPathingDef pathingDef2 = item2.road.pathingMode;
                IntVec3        intVec2     = FindRoadExitCell(map, item2.angle, centerpoint, ref pathingDef2);
                if (!(intVec2 == IntVec3.Invalid))
                {
                    item = new DrawCommand
                    {
                        action  = PrepDrawRoad(map, rockDef, centerpoint, intVec2, item2.road, pathingDef2),
                        roadDef = item2.road
                    };
                    list.Add(item);
                }
            }
            foreach (DrawCommand item3 in list.OrderBy((DrawCommand dc) => dc.roadDef.priority))
            {
                if (item3.action != null)
                {
                    item3.action();
                }
            }
        }
예제 #2
0
        public override void Generate(Map map)
        {
            List <GenStep_Roads.NeededRoad> neededRoads = this.CalculateNeededRoads(map);

            if (neededRoads.Count == 0)
            {
                return;
            }
            List <GenStep_Roads.DrawCommand> list = new List <GenStep_Roads.DrawCommand>();

            DeepProfiler.Start("RebuildAllRegions");
            map.regionAndRoomUpdater.RebuildAllRegionsAndRooms();
            DeepProfiler.End();
            TerrainDef rockDef      = BaseGenUtility.RegionalRockTerrainDef(map.Tile, false);
            IntVec3    intVec       = CellFinderLoose.TryFindCentralCell(map, 3, 10, null);
            RoadDef    bestRoadType = (from rd in DefDatabase <RoadDef> .AllDefs
                                       where neededRoads.Count((GenStep_Roads.NeededRoad nr) => nr.road == rd) >= 2
                                       select rd).MaxByWithFallback((RoadDef rd) => rd.priority, null);

            if (bestRoadType != null)
            {
                GenStep_Roads.NeededRoad neededRoad = neededRoads[neededRoads.FindIndex((GenStep_Roads.NeededRoad nr) => nr.road == bestRoadType)];
                neededRoads.RemoveAt(neededRoads.FindIndex((GenStep_Roads.NeededRoad nr) => nr.road == bestRoadType));
                GenStep_Roads.NeededRoad neededRoad2 = neededRoads[neededRoads.FindIndex((GenStep_Roads.NeededRoad nr) => nr.road == bestRoadType)];
                neededRoads.RemoveAt(neededRoads.FindIndex((GenStep_Roads.NeededRoad nr) => nr.road == bestRoadType));
                RoadPathingDef pathingMode = neededRoad.road.pathingMode;
                IntVec3        intVec2     = this.FindRoadExitCell(map, neededRoad.angle, intVec, ref pathingMode);
                IntVec3        end         = this.FindRoadExitCell(map, neededRoad2.angle, intVec2, ref pathingMode);
                Action         action      = this.PrepDrawRoad(map, rockDef, intVec2, end, neededRoad.road, pathingMode, out intVec);
                list.Add(new GenStep_Roads.DrawCommand
                {
                    action  = action,
                    roadDef = bestRoadType
                });
            }
            foreach (GenStep_Roads.NeededRoad current in neededRoads)
            {
                RoadPathingDef pathingMode2 = current.road.pathingMode;
                IntVec3        intVec3      = this.FindRoadExitCell(map, current.angle, intVec, ref pathingMode2);
                if (!(intVec3 == IntVec3.Invalid))
                {
                    list.Add(new GenStep_Roads.DrawCommand
                    {
                        action  = this.PrepDrawRoad(map, rockDef, intVec, intVec3, current.road, pathingMode2),
                        roadDef = current.road
                    });
                }
            }
            foreach (GenStep_Roads.DrawCommand current2 in from dc in list
                     orderby dc.roadDef.priority
                     select dc)
            {
                if (current2.action != null)
                {
                    current2.action();
                }
            }
        }
예제 #3
0
        private IntVec3 FindRoadExitCell(Map map, float angle, IntVec3 crossroads, ref RoadPathingDef pathingDef)
        {
            Predicate <IntVec3> tileValidator = delegate(IntVec3 pos)
            {
                foreach (IntVec3 current in GenRadial.RadialCellsAround(pos, 8f, true))
                {
                    if (current.InBounds(map) && current.GetTerrain(map).HasTag("Water"))
                    {
                        return(false);
                    }
                }
                return(true);
            };
            float validAngleSpan;

            for (validAngleSpan = 10f; validAngleSpan < 90f; validAngleSpan += 10f)
            {
                Predicate <IntVec3> angleValidator = (IntVec3 pos) => GenGeo.AngleDifferenceBetween((pos - map.Center).AngleFlat, angle) < validAngleSpan;
                IntVec3             result;
                if (CellFinder.TryFindRandomEdgeCellWith((IntVec3 x) => angleValidator(x) && tileValidator(x) && map.reachability.CanReach(crossroads, x, PathEndMode.OnCell, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false)), map, 0f, out result))
                {
                    return(result);
                }
            }
            if (pathingDef == RoadPathingDefOf.Avoid)
            {
                pathingDef = RoadPathingDefOf.Bulldoze;
            }
            float validAngleSpan2;

            for (validAngleSpan2 = 10f; validAngleSpan2 < 90f; validAngleSpan2 += 10f)
            {
                Predicate <IntVec3> angleValidator = (IntVec3 pos) => GenGeo.AngleDifferenceBetween((pos - map.Center).AngleFlat, angle) < validAngleSpan2;
                IntVec3             result;
                if (CellFinder.TryFindRandomEdgeCellWith((IntVec3 x) => angleValidator(x) && tileValidator(x) && map.reachability.CanReach(crossroads, x, PathEndMode.OnCell, TraverseParms.For(TraverseMode.PassAllDestroyableThings, Danger.Deadly, false)), map, 0f, out result))
                {
                    return(result);
                }
            }
            Log.Error(string.Format("Can't find exit from map from {0} to angle {1}", crossroads, angle));
            return(IntVec3.Invalid);
        }
예제 #4
0
        private void ApplyDistanceField(DistanceElement[,] distance, Map map, TerrainDef rockDef, RoadDef roadDef, RoadPathingDef pathingDef)
        {
            int num = 0;

            while (true)
            {
                int     num2 = num;
                IntVec3 size = map.Size;
                if (num2 >= size.x)
                {
                    break;
                }
                int num3 = 0;
                while (true)
                {
                    int     num4  = num3;
                    IntVec3 size2 = map.Size;
                    if (num4 >= size2.z)
                    {
                        break;
                    }
                    DistanceElement distanceElement = distance[num, num3];
                    if (distanceElement.touched)
                    {
                        float b = Mathf.Abs(distanceElement.fromRoad + Rand.Value - 0.5f);
                        for (int i = 0; i < roadDef.roadGenSteps.Count; i++)
                        {
                            RoadDefGenStep roadDefGenStep = roadDef.roadGenSteps[i];
                            float          x    = Mathf.LerpUnclamped(distanceElement.fromRoad, b, roadDefGenStep.antialiasingMultiplier);
                            float          num5 = roadDefGenStep.chancePerPositionCurve.Evaluate(x);
                            if (!(num5 <= 0f) && (roadDefGenStep.periodicSpacing == 0 || !(distanceElement.alongPath / (float)roadDefGenStep.periodicSpacing % 1f * (float)roadDefGenStep.periodicSpacing >= 1f)))
                            {
                                IntVec3 position = new IntVec3(num, 0, num3);
                                if (Rand.Value < num5)
                                {
                                    roadDefGenStep.Place(map, position, rockDef, distanceElement.origin, distance);
                                }
                            }
                        }
                    }
                    num3++;
                }
                num++;
            }
        }
예제 #5
0
 private void DrawCurveSegment(DistanceElement[,] distance, List <IntVec3> path, int pathStartIndex, int pathEndIndex, RoadPathingDef pathing, Map map, int centerpointIndex, ref IntVec3 centerpoint)
 {
     if (pathStartIndex == pathEndIndex)
     {
         Log.ErrorOnce("Zero-length segment drawn in road routine", 78187971);
     }
     else
     {
         GenMath.BezierCubicControls bcc = GenerateBezierControls(path, pathStartIndex, pathEndIndex);
         List <Vector3> list             = new List <Vector3>();
         int            num = (pathEndIndex - pathStartIndex) * 4;
         for (int i = 0; i <= num; i++)
         {
             list.Add(GenMath.BezierCubicEvaluate((float)i / (float)num, bcc));
         }
         int num2 = 0;
         for (int j = pathStartIndex; j <= pathEndIndex; j++)
         {
             if (j > 0 && j < path.Count && path[j].InBounds(map) && path[j].GetTerrain(map).IsWater)
             {
                 num2++;
             }
         }
         if (pathStartIndex + 1 < pathEndIndex)
         {
             for (int k = 0; k < list.Count; k++)
             {
                 IntVec3 intVec = list[k].ToIntVec3();
                 bool    flag   = intVec.InBounds(map) && intVec.Impassable(map);
                 int     num3   = 0;
                 for (int l = 0; l < GenAdj.CardinalDirections.Length; l++)
                 {
                     if (flag)
                     {
                         break;
                     }
                     IntVec3 c = intVec + GenAdj.CardinalDirections[l];
                     if (c.InBounds(map))
                     {
                         flag |= (pathing == RoadPathingDefOf.Avoid && c.Impassable(map));
                         if (c.GetTerrain(map).IsWater)
                         {
                             num3++;
                         }
                         if (flag)
                         {
                             break;
                         }
                     }
                 }
                 if (flag || (float)num3 > (float)num2 * 1.5f + 2f)
                 {
                     DrawCurveSegment(distance, path, pathStartIndex, (pathStartIndex + pathEndIndex) / 2, pathing, map, centerpointIndex, ref centerpoint);
                     DrawCurveSegment(distance, path, (pathStartIndex + pathEndIndex) / 2, pathEndIndex, pathing, map, centerpointIndex, ref centerpoint);
                     return;
                 }
             }
         }
         for (int m = 0; m < list.Count; m++)
         {
             Vector3 vector  = list[m];
             float   x       = vector.x;
             Vector3 vector2 = list[m];
             FillDistanceField(distance, x, vector2.z, GenMath.LerpDouble(0f, (float)(list.Count - 1), (float)pathStartIndex, (float)pathEndIndex, (float)m), 10f, map);
         }
         if (centerpointIndex >= pathStartIndex && centerpointIndex < pathEndIndex)
         {
             centerpointIndex = Mathf.Clamp(Mathf.RoundToInt(GenMath.LerpDouble((float)pathStartIndex, (float)pathEndIndex, 0f, (float)list.Count, (float)centerpointIndex)), 0, list.Count - 1);
             centerpoint      = list[centerpointIndex].ToIntVec3();
         }
     }
 }
예제 #6
0
        private Action PrepDrawRoad(Map map, TerrainDef rockDef, IntVec3 start, IntVec3 end, RoadDef roadDef, RoadPathingDef pathingDef, out IntVec3 centerpoint)
        {
            centerpoint = IntVec3.Invalid;
            PawnPath pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.NoPassClosedDoorsOrWater));

            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.NoPassClosedDoors));
            }
            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.PassAllDestroyableThingsNotWater));
            }
            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.PassAllDestroyableThings));
            }
            if (pawnPath == PawnPath.NotFound)
            {
                return(null);
            }
            List <IntVec3> list = RefinePath(pawnPath.NodesReversed, map);

            pawnPath.ReleaseToPool();
            IntVec3 size  = map.Size;
            int     x     = size.x;
            IntVec3 size2 = map.Size;

            DistanceElement[,] distance = new DistanceElement[x, size2.z];
            for (int i = 0; i < distance.GetLength(0); i++)
            {
                for (int j = 0; j < distance.GetLength(1); j++)
                {
                    distance[i, j].origin = IntVec3.Invalid;
                }
            }
            int count            = list.Count;
            int centerpointIndex = Mathf.RoundToInt(Rand.Range(0.3f, 0.7f) * (float)count);
            int num = Mathf.Max(1, GenMath.RoundRandom((float)count / (float)roadDef.tilesPerSegment));

            for (int k = 0; k < num; k++)
            {
                int pathStartIndex = Mathf.RoundToInt((float)(count - 1) / (float)num * (float)k);
                int pathEndIndex   = Mathf.RoundToInt((float)(count - 1) / (float)num * (float)(k + 1));
                DrawCurveSegment(distance, list, pathStartIndex, pathEndIndex, pathingDef, map, centerpointIndex, ref centerpoint);
            }
            return(delegate
            {
                ApplyDistanceField(distance, map, rockDef, roadDef, pathingDef);
            });
        }
예제 #7
0
        private Action PrepDrawRoad(Map map, TerrainDef rockDef, IntVec3 start, IntVec3 end, RoadDef roadDef, RoadPathingDef pathingDef)
        {
            IntVec3 centerpoint;

            return(PrepDrawRoad(map, rockDef, start, end, roadDef, pathingDef, out centerpoint));
        }
예제 #8
0
        private Action PrepDrawRoad(Map map, TerrainDef rockDef, IntVec3 start, IntVec3 end, RoadDef roadDef, RoadPathingDef pathingDef)
        {
            IntVec3 intVec = default(IntVec3);

            return(this.PrepDrawRoad(map, rockDef, start, end, roadDef, pathingDef, out intVec));
        }
예제 #9
0
 private void ApplyDistanceField(DistanceElement[,] distance, Map map, TerrainDef rockDef, RoadDef roadDef, RoadPathingDef pathingDef)
 {
     for (int i = 0; i < map.Size.x; i++)
     {
         for (int j = 0; j < map.Size.z; j++)
         {
             DistanceElement distanceElement = distance[i, j];
             if (!distanceElement.touched)
             {
                 continue;
             }
             float b = Mathf.Abs(distanceElement.fromRoad + Rand.Value - 0.5f);
             for (int k = 0; k < roadDef.roadGenSteps.Count; k++)
             {
                 RoadDefGenStep roadDefGenStep = roadDef.roadGenSteps[k];
                 float          x   = Mathf.LerpUnclamped(distanceElement.fromRoad, b, roadDefGenStep.antialiasingMultiplier);
                 float          num = roadDefGenStep.chancePerPositionCurve.Evaluate(x);
                 if (!(num <= 0f) && (roadDefGenStep.periodicSpacing == 0 || !(distanceElement.alongPath / (float)roadDefGenStep.periodicSpacing % 1f * (float)roadDefGenStep.periodicSpacing >= 1f)))
                 {
                     IntVec3 position = new IntVec3(i, 0, j);
                     if (Rand.Value < num)
                     {
                         roadDefGenStep.Place(map, position, rockDef, distanceElement.origin, distance);
                     }
                 }
             }
         }
     }
 }
예제 #10
0
        private Action PrepDrawRoad(Map map, TerrainDef rockDef, IntVec3 start, IntVec3 end, RoadDef roadDef, RoadPathingDef pathingDef, out IntVec3 centerpoint)
        {
            centerpoint = IntVec3.Invalid;
            PawnPath pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.NoPassClosedDoorsOrWater, Danger.Deadly, false), PathEndMode.OnCell);

            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), PathEndMode.OnCell);
            }
            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.PassAllDestroyableThingsNotWater, Danger.Deadly, false), PathEndMode.OnCell);
            }
            if (pawnPath == PawnPath.NotFound)
            {
                pawnPath = map.pathFinder.FindPath(start, end, TraverseParms.For(TraverseMode.PassAllDestroyableThings, Danger.Deadly, false), PathEndMode.OnCell);
            }
            if (pawnPath == PawnPath.NotFound)
            {
                return(null);
            }
            List <IntVec3> list = this.RefinePath(pawnPath.NodesReversed, map);

            pawnPath.ReleaseToPool();
            GenStep_Roads.DistanceElement[,] distance = new GenStep_Roads.DistanceElement[map.Size.x, map.Size.z];
            int count            = list.Count;
            int centerpointIndex = Mathf.RoundToInt(Rand.Range(0.3f, 0.7f) * (float)count);
            int num = Mathf.Max(1, GenMath.RoundRandom((float)count / (float)roadDef.tilesPerSegment));

            for (int i = 0; i < num; i++)
            {
                int pathStartIndex = Mathf.RoundToInt((float)(count - 1) / (float)num * (float)i);
                int pathEndIndex   = Mathf.RoundToInt((float)(count - 1) / (float)num * (float)(i + 1));
                this.DrawCurveSegment(distance, list, pathStartIndex, pathEndIndex, pathingDef, map, centerpointIndex, ref centerpoint);
            }
            return(delegate
            {
                this.ApplyDistanceField(distance, map, rockDef, roadDef, pathingDef);
            });
        }