Пример #1
0
 /// <summary>
 /// Adds highlights and shadows to the solid stone color in the texture
 /// </summary>
 private static void AddBevelToSolidStone(ThreadableTexture tex)
 {
     for (int x = 0; x < tex.width; x++)
     {
         for (int y = 0; y < tex.height; y++)
         {
             var isStone = tex.GetPixel(x, y) == solidStoneColor;
             if (isStone)
             {
                 var colorBelow   = y > 0 ? tex.GetPixel(x, y - 1) : Color.clear;
                 var isStoneBelow = colorBelow == solidStoneColor || colorBelow == solidStoneHighlightColor || colorBelow == solidStoneShadowColor;
                 var isStoneAbove = y < tex.height - 1 && tex.GetPixel(x, y + 1) == solidStoneColor;
                 if (!isStoneAbove)
                 {
                     tex.SetPixel(x, y, solidStoneHighlightColor);
                 }
                 else if (!isStoneBelow)
                 {
                     tex.SetPixel(x, y, solidStoneShadowColor);
                 }
             }
         }
     }
 }
Пример #2
0
        private void DoThreadWork()
        {
            QueuedPreviewRequest request = null;

            try {
                while (queuedRequests.Count > 0 || WaitHandle.WaitAny(new WaitHandle[] { workHandle, disposeHandle }) == 0)
                {
                    Exception rejectException = null;
                    if (queuedRequests.Count > 0)
                    {
                        var req = queuedRequests.Dequeue();
                        request = req;
                        Texture2D texture = null;
                        int       width = 0, height = 0;
                        WaitForExecutionInMainThread(() => {
                            // textures must be instantiated in the main thread
                            texture = new Texture2D(req.MapSize, req.MapSize, TextureFormat.RGB24, false);
                            width   = texture.width;
                            height  = texture.height;
                        });
                        ThreadableTexture placeholderTex = null;
                        try {
                            if (texture == null)
                            {
                                throw new Exception("Could not create required texture.");
                            }
                            placeholderTex = new ThreadableTexture(width, height);
                            GeneratePreviewForSeed(req.Seed, req.MapTile, req.MapSize, req.RevealCaves, placeholderTex);
                        } catch (Exception e) {
                            MapRerollController.Instance.Logger.Error("Failed to generate map preview: " + e);
                            rejectException = e;
                            texture         = null;
                        }
                        if (texture != null && placeholderTex != null)
                        {
                            WaitForExecutionInMainThread(() => {
                                // upload in main thread
                                placeholderTex.CopyToTexture(texture);
                                texture.Apply();
                            });
                        }
                        WaitForExecutionInMainThread(() => {
                            if (texture == null)
                            {
                                req.Promise.Reject(rejectException);
                            }
                            else
                            {
                                req.Promise.Resolve(texture);
                            }
                        });
                    }
                }
                workHandle.Close();
                mainThreadHandle.Close();
                mainThreadHandle = disposeHandle = workHandle = null;
            } catch (Exception e) {
                MapRerollController.Instance.Logger.Error("Exception in preview generator thread: " + e);
                if (request != null)
                {
                    request.Promise.Reject(e);
                }
            }
        }
Пример #3
0
        private static void GeneratePreviewForSeed(string seed, int mapTile, int mapSize, bool revealCaves, ThreadableTexture texture)
        {
            var prevSeed = Find.World.info.seedString;

            try {
                MapRerollController.HasCavesOverride.HasCaves        = Find.World.HasCaves(mapTile);
                MapRerollController.HasCavesOverride.OverrideEnabled = true;
                Find.World.info.seedString = seed;

                MapRerollController.RandStateStackCheckingPaused = true;
                var grids = GenerateMapGrids(mapTile, mapSize, revealCaves);
                DeepProfiler.Start("generateMapPreviewTexture");
                const string terrainGenStepName = "Terrain";
                var          terrainGenStepDef  = DefDatabase <GenStepDef> .GetNamedSilentFail(terrainGenStepName);

                if (terrainGenStepDef == null)
                {
                    throw new Exception("Named GenStepDef not found: " + terrainGenStepName);
                }
                var terrainGenstep         = terrainGenStepDef.genStep;
                var riverMaker             = ReflectionCache.GenStepTerrain_GenerateRiver.Invoke(terrainGenstep, new object[] { grids.Map });
                var beachTerrainAtDelegate = (BeachMakerBeachTerrainAt)Delegate.CreateDelegate(typeof(BeachMakerBeachTerrainAt), null, ReflectionCache.BeachMaker_BeachTerrainAt);
                var riverTerrainAtDelegate = riverMaker == null ? null
                                        : (RiverMakerTerrainAt)Delegate.CreateDelegate(typeof(RiverMakerTerrainAt), riverMaker, ReflectionCache.RiverMaker_TerrainAt);
                ReflectionCache.BeachMaker_Init.Invoke(null, new object[] { grids.Map });

                var mapBounds = CellRect.WholeMap(grids.Map);
                foreach (var cell in mapBounds)
                {
                    const float rockCutoff = .7f;
                    var         terrainDef = TerrainFrom(cell, grids.Map, grids.ElevationGrid[cell], grids.FertilityGrid[cell], riverTerrainAtDelegate, beachTerrainAtDelegate, false);
                    if (!terrainColors.TryGetValue(terrainDef.defName, out Color pixelColor))
                    {
                        pixelColor = missingTerrainColor;
                    }
                    if (grids.ElevationGrid[cell] > rockCutoff && !terrainDef.IsRiver)
                    {
                        pixelColor = solidStoneColor;
                        if (grids.CavesGrid[cell] > 0)
                        {
                            pixelColor = caveColor;
                        }
                    }
                    texture.SetPixel(cell.x, cell.z, pixelColor);
                }

                AddBevelToSolidStone(texture);

                foreach (var terrainPatchMaker in grids.Map.Biome.terrainPatchMakers)
                {
                    terrainPatchMaker.Cleanup();
                }
            } catch (Exception e) {
                MapRerollController.Instance.Logger.ReportException(e, null, false, "preview generation");
            } finally {
                RockNoises.Reset();
                DeepProfiler.End();
                Find.World.info.seedString = prevSeed;
                MapRerollController.RandStateStackCheckingPaused     = false;
                MapRerollController.HasCavesOverride.OverrideEnabled = false;
                try {
                    ReflectionCache.BeachMaker_Cleanup.Invoke(null, null);
                } catch (Exception e) {
                    MapRerollController.Instance.Logger.ReportException(e, null, false, "BeachMaker preview cleanup");
                }
            }
        }