public void ShouldGenerateVisualizationOfSimpleLightMap() { MapData map = TileDemoMap.Create(); var(floorLights, _) = LightTracer.Trace( map, new LightRange(DarkLevels: 10, LightLevels: 10), new LightDefinition[] { new(new Position(1, 1), Brightness: 20, Radius: 20), new(new Position(map.Width - 2, map.Height - 2), Brightness: 20, Radius: 20), new(new Position(map.Width - 2, 1), Brightness: 20, Radius: 20), new(new Position(1, map.Height - 2), Brightness: 20, Radius: 20), });
public void ShowFloorVsCeilingLighting() { void SaveImage(IFastImage image, string description) => image.Save(Path.Combine(_dirInfo.FullName, $"{description}.png")); var random = new Random(Seed); var board = new CellBoard(new(128, 128)) .Fill(random, probabilityAlive: 0.5) .MakeBorderAlive(thickness: 3) .GenerateStandardCave(); var(largestComponent, dimensions) = ConnectedAreaAnalyzer .FindForegroundAreas(board.Dimensions, p => board[p] == CellType.Dead) .OrderByDescending(component => component.Area) .First() .TrimExcess(border: 1); var interior = largestComponent.DetermineInteriorEdgeDistance(Neighborhood.VonNeumann); // Place some lights var lightRange = new LightRange(DarkLevels: 15, LightLevels: 5); var lights = CaveThingPlacement.RandomlyPlaceLights( interior.Where(pair => pair.Value == 2).Select(pair => pair.Key).ToList(), random, lightRange, percentAreaToCover: 0.05, varyHeight: true) .ToArray(); var(floorLighting, ceilingLight) = LightTracer.Trace(dimensions, p => !largestComponent.Contains(p), lightRange, lights); using var floorImg = LightMapVisualizer.Render(floorLighting, lights, largestComponent, scale: 5); using var ceilingImg = LightMapVisualizer.Render(ceilingLight, lights, largestComponent, scale: 5); SaveImage(floorImg, "Floor"); SaveImage(ceilingImg, "Ceiling"); }
public static MapData Create(int seed, string texturePrefix, TextureQueue textureQueue) { var random = new Random(seed); var caveBoard = new CellBoard(new Size(128, 128)) .Fill(random, probabilityAlive: 0.5) .MakeBorderAlive(thickness: 3) .GenerateStandardCave(); var(caveArea, size) = ConnectedAreaAnalyzer .FindForegroundAreas(caveBoard.Dimensions, p => caveBoard[p] == CellType.Dead) .OrderByDescending(a => a.Area) .First() .TrimExcess(border: 1); var interior = caveArea.DetermineInteriorEdgeDistance(Neighborhood.VonNeumann); var alternateFloor = new CellBoard(new Size(size.Width + 1, size.Height + 1)) .Fill(random, probabilityAlive: 0.5) .RunGenerations(6); var alternateCeiling = new CellBoard(new Size(size.Width + 1, size.Height + 1)) .Fill(random, probabilityAlive: 0.5) .RunGenerations(6); var lightRange = new LightRange(DarkLevels: 15, LightLevels: 5); var lights = CaveThingPlacement.RandomlyPlaceLights( interior.Where(pair => pair.Value == 2).Select(pair => pair.Key).ToList(), random, lightRange, percentAreaToCover: 0.05, varyHeight: true) .ToArray(); var(floorLighting, ceilingLighting) = LightTracer.Trace(size, p => !caveArea.Contains(p), lightRange, lights); var(planeMap, sectors, tiles) = CreateGeometry( size, caveArea, alternateFloor, alternateCeiling, floorLighting, ceilingLighting, textureQueue, texturePrefix); var playerPosition = caveArea.First(); var things = lights.Select(light => new Thing( Type: light.Height == LightHeight.Ceiling ? "CeilingCrystal" : "FloorCrystal", X: light.Center.X + 0.5, Y: light.Center.Y + 0.5, Z: 0, Angle: 0, Ambush: false, Skill1: true, Skill2: true, Skill3: true, Skill4: true)).ToList(); things.Add(new Thing( Type: Actor.Player1Start.ClassName, X: playerPosition.X + 0.5, Y: playerPosition.Y + 0.5, Z: 0, Angle: 0, Ambush: false, Skill1: true, Skill2: true, Skill3: true, Skill4: true)); return(new MapData( NameSpace: "Wolf3D", TileSize: 64, Name: "Procedural Cave", Width: size.Width, Height: size.Height, Tiles: tiles, Sectors: sectors, Zones: ImmutableArray.Create(new Zone()), Planes: ImmutableArray.Create(new Plane(Depth: 64)), PlaneMaps: ImmutableArray.Create(planeMap), Things: things.ToImmutableArray(), Triggers: ImmutableArray <Trigger> .Empty)); }