private void WriteMapData(World world) { string dataXmlPath = Path.Combine(options.OutputDirectory, "MapData.xml"); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.Indent = true; xmlWriterSettings.IndentChars = "\t"; using (XmlWriter writer = XmlWriter.Create(dataXmlPath, xmlWriterSettings)) { writer.WriteStartElement("World"); writer.WriteAttributeString("Name", world.Name); writer.WriteAttributeString("Size", string.Format("{0},{1}", world.Size.Width, world.Size.Height)); writer.WriteAttributeString("Bounds", string.Format("{0},{1},{2},{3}", world.leftWorld, world.topWorld, world.rightWorld, world.bottomWorld)); writer.WriteAttributeString("Spawn", string.Format("{0},{1}", world.Spawn.X, world.Spawn.Y)); writer.WriteAttributeString("Spawn_X", string.Format("{0}", world.Spawn.X)); writer.WriteAttributeString("Spawn_Y", string.Format("{0}", world.Spawn.Y)); writer.WriteStartElement("Npcs"); foreach (Npc npc in world.npc) { if (npc == null) { continue; } writer.WriteStartElement("Npc"); writer.WriteAttributeString("Name", npc.Name); writer.WriteAttributeString("Location", string.Format("{0},{1}", npc.Position.X, npc.Position.Y)); writer.WriteAttributeString("Location_X", npc.Position.X.ToString()); writer.WriteAttributeString("Location_Y", npc.Position.Y.ToString()); writer.WriteAttributeString("Home", string.Format("{0},{1}", npc.HomePosition.X, npc.HomePosition.Y)); writer.WriteAttributeString("Homeless", npc.IsHomeless.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("Chests"); foreach (Chest chest in world.chest) { if (chest == null) { continue; } writer.WriteStartElement("Chest"); writer.WriteAttributeString("Location", string.Format("{0},{1}", chest.Position.X, chest.Position.Y)); writer.WriteAttributeString("Location_X", chest.Position.X.ToString()); writer.WriteAttributeString("Location_Y", chest.Position.Y.ToString()); foreach (Item item in chest.Items) { if (item == null) { continue; } writer.WriteStartElement("Item"); if (!IsNameValid(item.Name)) { writer.WriteAttributeString("Name", "Invalid"); } else { writer.WriteAttributeString("Name", item.Name); } writer.WriteAttributeString("Count", item.Count.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("Signs"); foreach (Sign sign in world.sign) { if (sign == null) { continue; } writer.WriteStartElement("Sign"); writer.WriteAttributeString("Location", string.Format("{0},{1}", sign.Position.X, sign.Position.Y)); writer.WriteAttributeString("Location_X", sign.Position.X.ToString()); writer.WriteAttributeString("Location_Y", sign.Position.Y.ToString()); writer.WriteCData(sign.Text); writer.WriteEndElement(); } writer.WriteEndElement(); Dictionary<TileType, List<System.Drawing.Point>> mapObjects = FindMapObjects(world); foreach (var entry in mapObjects) { TileTypeInfo tileTypeInfo = TileTypeInfo.GetTileTypeInfo(entry.Key); writer.WriteStartElement(entry.Key.ToString() + "s"); writer.WriteAttributeString("Name", tileTypeInfo.Name); foreach (System.Drawing.Point location in entry.Value) { writer.WriteStartElement(entry.Key.ToString()); writer.WriteAttributeString("Location", string.Format("{0},{1}", location.X, location.Y)); writer.WriteAttributeString("Location_X", location.X.ToString()); writer.WriteAttributeString("Location_Y", location.Y.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); } }
private void DrawTiles(World world, System.Drawing.Rectangle region, bool foreground, Graphics g, TextureSet textures) { int height = 16; int width = 16; bool solidOnly = !foreground; int frameOverlap = 4; int frameOverlapTimes2 = frameOverlap * 2; int startX = region.Left - frameOverlap; int startY = region.Top - frameOverlap; int endX = region.Right + frameOverlapTimes2; int endY = region.Bottom + frameOverlapTimes2; if (startX < 0) { startX = 0; } if (startY < 0) { startY = 0; } if (endX >= world.Size.Width) { endX = world.Size.Width - 1; } if (endY >= world.Size.Height) { endY = world.Size.Height - 1; } for (int y = startY; y < endY; y++) { for (int x = startX; x < endX; x++) { if (world.tile[x, y].Active && (World.tileSolid[world.tile[x, y].Type] == solidOnly)) { int num9 = 0; // Pot if (world.tile[x, y].Type == 78) { num9 = 2; } // Red candle, blue candle. if ((world.tile[x, y].Type == 33) || (world.tile[x, y].Type == 49)) { num9 = -4; } // Flowers, torches, trees, fungus, red candle, blue candle, grass, mushrooms. if ((((world.tile[x, y].Type == 3) || (world.tile[x, y].Type == 4)) || ((world.tile[x, y].Type == 5) || (world.tile[x, y].Type == 24))) || (((world.tile[x, y].Type == 33) || (world.tile[x, y].Type == 49)) || ((world.tile[x, y].Type == 61) || (world.tile[x, y].Type == 71)))) { height = 20; // Chairs, table, anvil, forge, workbench, sappling, chest, demon forge, sunflowers, corrupted thorns, thorns, ?, hell forge } else if (((((world.tile[x, y].Type == 15) || (world.tile[x, y].Type == 14)) || ((world.tile[x, y].Type == 16) || (world.tile[x, y].Type == 17))) || (((world.tile[x, y].Type == 18) || (world.tile[x, y].Type == 20)) || ((world.tile[x, y].Type == 21) || (world.tile[x, y].Type == 26)))) || (((world.tile[x, y].Type == 27) || (world.tile[x, y].Type == 32)) || (((world.tile[x, y].Type == 69) || (world.tile[x, y].Type == 72)) || (world.tile[x, y].Type == 77) || (world.tile[x, y].Type == 80)))) { height = 18; } else { height = 16; } // Torch, tree if ((world.tile[x, y].Type == 4) || (world.tile[x, y].Type == 5)) { width = 20; } else { width = 16; } // Grass, grass. if ((world.tile[x, y].Type == 73) || (world.tile[x, y].Type == 74)) { num9 -= 12; height = 32; } // Draw tree tops and branches. if (((world.tile[x, y].Type == 5) && (world.tile[x, y].FrameY >= 198)) && (world.tile[x, y].FrameX >= 22)) { int num11 = 0; if (world.tile[x, y].FrameX == 22) { if (world.tile[x, y].FrameY == 220) { num11 = 1; } else if (world.tile[x, y].FrameY == 242) { num11 = 2; } int num14 = 0; int num15 = 80; int num16 = 80; int num17 = 0x20; for (int k = y; k < (y + 100); k++) { if (world.tile[x, k].Type == 2) { num14 = 0; break; } if (world.tile[x, k].Type == 0x17) { num14 = 1; break; } if (world.tile[x, k].Type == 60) { num14 = 2; num15 = 0x72; num16 = 0x60; num17 = 0x30; break; } } g.DrawImage(textures.treeTopTexture[num14], (x - region.Left) * 16 - num17, (y - region.Top) * 16 - num16 + 16, new RectangleF(num11 * (num15 + 2), 0, num15, num16), GraphicsUnit.Pixel); } else if (world.tile[x, y].FrameX == 44) { if (world.tile[x, y].FrameY == 220) { num11 = 1; } else if (world.tile[x, y].FrameY == 242) { num11 = 2; } int num19 = 0; for (int m = y; m < (y + 100); m++) { if (world.tile[x, m].Type == 2) { num19 = 0; break; } if (world.tile[x, m].Type == 0x17) { num19 = 1; break; } if (world.tile[x, m].Type == 60) { num19 = 2; break; } } g.DrawImage(textures.treeBranchTexture[num19], (x - region.Left) * 16 - 24, (y - region.Top) * 16 - 12, new RectangleF(0, num11 * 42, 40, 40), GraphicsUnit.Pixel); } else if (world.tile[x, y].FrameX == 66) { if (world.tile[x, y].FrameY == 220) { num11 = 1; } else if (world.tile[x, y].FrameY == 242) { num11 = 2; } int num21 = 0; for (int n = y; n < (y + 100); n++) { if (world.tile[x, n].Type == 2) { num21 = 0; break; } if (world.tile[x, n].Type == 0x17) { num21 = 1; break; } if (world.tile[x, n].Type == 60) { num21 = 2; break; } } g.DrawImage(textures.treeBranchTexture[num21], (x - region.Left) * 16, (y - region.Top) * 16 - 12, new RectangleF(42, num11 * 42, 40, 40), GraphicsUnit.Pixel); } } // Drawn mushroom tops. if ((world.tile[x, y].Type == 72) && (world.tile[x, y].FrameX >= 36)) { int num12 = 0; if (world.tile[x, y].FrameY == 18) { num12 = 1; } else if (world.tile[x, y].FrameY == 36) { num12 = 2; } g.DrawImage(textures.shroomCapTexture, (x - region.Left) * 16 - 22, (y - region.Top) * 16 - 26, new RectangleF(num12 * 62, 0, 60, 42), GraphicsUnit.Pixel); } // Draw liquids behind solids. if (solidOnly && (x > 1 && y > 1 && x < world.Size.Width - 2 && y < world.Size.Height - 2) && (((world.tile[x - 1, y].Liquid > 0) || (world.tile[x + 1, y].Liquid > 0)) || ((world.tile[x, y - 1].Liquid > 0) || (world.tile[x, y + 1].Liquid > 0)))) { int liquidLevel = 0; bool liquidToLeft = false; bool liquidToRight = false; bool liquidAbove = false; bool liquidBelow = false; bool hasLava = false; bool hasWater = false; if (world.tile[x - 1, y].Liquid > 0) { liquidToLeft = true; if (world.tile[x - 1, y].Liquid > liquidLevel) { liquidLevel = world.tile[x - 1, y].Liquid; } if (world.tile[x - 1, y].Lava) { hasLava = true; } else { hasWater = true; } } if (world.tile[x + 1, y].Liquid > 0) { liquidToRight = true; liquidLevel = world.tile[x + 1, y].Liquid; if (world.tile[x + 1, y].Lava) { hasLava = true; } else { hasWater = true; } } if (world.tile[x, y - 1].Liquid > 0) { liquidAbove = true; if (world.tile[x, y - 1].Lava) { hasLava = true; } else { hasWater = true; } } if (world.tile[x, y + 1].Liquid > 0) { if (world.tile[x, y + 1].Lava) { hasLava = true; } else { hasWater = true; } if (world.tile[x, y + 1].Liquid > 240) { liquidBelow = true; } } if (!hasWater || !hasLava) { float num15 = 0f; Vector2 vector = new Vector2((float) (x * 16), (float) (y * 16)); Microsoft.Xna.Framework.Rectangle rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16 - 4); if (liquidBelow && (liquidToLeft || liquidToRight)) { liquidToLeft = true; liquidToRight = true; } if ((!liquidAbove || (!liquidToLeft && !liquidToRight)) && (!liquidBelow || !liquidAbove)) { if (liquidAbove) { rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 4); } else if ((liquidBelow && !liquidToLeft) && !liquidToRight) { vector = new Vector2((float) (x * 16), (float) ((y * 16) + 12)); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 4); } else { num15 = 256 - liquidLevel; num15 /= 32f; if (liquidToLeft && liquidToRight) { vector = new Vector2((float) (x * 16), (float) ((y * 16) + (((int) num15) * 2))); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16 - (((int) num15) * 2) - 4); } else if (liquidToLeft) { vector = new Vector2((float) (x * 16), (float) ((y * 16) + (((int) num15) * 2))); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 4, 16 - (((int) num15) * 2) - 4); } else { vector = new Vector2((float) (x * 16), (float) ((y * 16) + (((int) num15) * 2))); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 4, 16 - (((int) num15) * 2) - 4); } } } float intensity = 0.5f; int liquidTextureIndex = hasWater ? 0 : 1; if (liquidTextureIndex == 1) { intensity *= 1.6f; } if ((y < world.worldSurface) || (intensity > 1f)) { intensity = 1f; } ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix33 = intensity; ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(colorMatrix); int waterWidth = 16; int waterHeight = 16 - ((int) vector.Y - (y * 16)); g.DrawImage(textures.liquidTexture[liquidTextureIndex], new System.Drawing.Rectangle((int) (vector.X - region.Left * 16), (int) (vector.Y - region.Top * 16), waterWidth, waterHeight), rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height, GraphicsUnit.Pixel, imageAttributes); } } g.DrawImage(textures.tileTexture[world.tile[x, y].Type], (x - region.Left) * 16 - (width - 16) / 2, (y - region.Top) * 16 + num9, new RectangleF(world.tile[x, y].FrameX, world.tile[x, y].FrameY, width, height), GraphicsUnit.Pixel); } } } }
private Dictionary<TileType, List<System.Drawing.Point>> FindMapObjects(World world) { Dictionary<TileType, List<System.Drawing.Point>> mapObjects = new Dictionary<TileType, List<System.Drawing.Point>>(); mapObjects.Add(TileType.HeartContainer, new List<System.Drawing.Point>()); mapObjects.Add(TileType.Anvil, new List<System.Drawing.Point>()); mapObjects.Add(TileType.Forge, new List<System.Drawing.Point>()); mapObjects.Add(TileType.Workbench, new List<System.Drawing.Point>()); mapObjects.Add(TileType.Alter, new List<System.Drawing.Point>()); mapObjects.Add(TileType.ShadowOrb, new List<System.Drawing.Point>()); mapObjects.Add(TileType.HellForge, new List<System.Drawing.Point>()); for (int x = 0; x < world.Size.Width; ++x) { for (int y = 0; y < world.Size.Height; ++y) { // Only record the top left coordinate. if (world.tile[x, y].FrameX != 0 || world.tile[x, y].FrameY != 0) { continue; } TileType tileType = (TileType) world.tile[x, y].Type; if (mapObjects.ContainsKey(tileType)) { mapObjects[tileType].Add(new System.Drawing.Point(x, y)); } } } return mapObjects; }
private void CreateBlockImages(World world, int blockX, int blockY, int blockWidth, int blockHeight, float zoomLevel) { // Caluclate the first and last tiles int firstTileX = blockX * blockWidth; int firstTileY = blockY * blockHeight; int lastTileX = firstTileX + blockWidth; int lastTileY = firstTileY + blockHeight; if (lastTileX > world.Size.Width) { lastTileX = world.Size.Width; } if (lastTileY > world.Size.Height) { lastTileY = world.Size.Height; } // The region that should be drawn. System.Drawing.Rectangle region = System.Drawing.Rectangle.FromLTRB(firstTileX, firstTileY, lastTileX, lastTileY); int layerIndex = 0; foreach (MapGeneratorLayerOptions layer in options.Layers) { using (Image blockImage = CreateBlockImage(world, region, zoomLevel, layer)) { // Construct the path to the target file. string path = string.Format("{0}\\Zoom {1}\\Layer {2}\\{3}", options.OutputDirectory, zoomLevel, layerIndex, blockX); Directory.CreateDirectory(path); string blockFile = string.Format("{0}\\{1}.png", path, blockY); blockImage.Save(blockFile, ImageFormat.Png); } ++layerIndex; } }
public void Generate(MapGeneratorProgressHandler progressHandler) { LoadTextures(); progressHandler.SubTaskName = "Loading world"; World world = new World(options.WorldPath); progressHandler.WriteLine(" World Name: {0}", world.Name); progressHandler.WriteLine(" World Version: {0}", world.worldVersion); progressHandler.WriteLine(" World Size: ({0}, {1})", world.Size.Width, world.Size.Height); progressHandler.WriteLine(" World Bounds: ({0}, {1}, {2}, {3})", world.leftWorld, world.topWorld, world.rightWorld, world.bottomWorld); Directory.CreateDirectory(options.OutputDirectory); if (options.WriteMapData) { progressHandler.WriteLine("Writing map data..."); WriteMapData(world); } progressHandler.TaskCount = options.ZoomLevels.Count; progressHandler.TasksCompleted = 0; ParallelOptions parallelOptions = new ParallelOptions(); if (options.ParallelizeGeneration) { parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount; } else { parallelOptions.MaxDegreeOfParallelism = 1; } foreach (float zoomLevel in options.ZoomLevels.OrderBy(z => z)) { if (progressHandler.Cancel) { return; } int blockWidth = (int) (options.BlockSize.Width / zoomLevel); int blockHeight = (int) (options.BlockSize.Height / zoomLevel); int xBlocks = (int) Math.Ceiling(world.Size.Width / (float) blockWidth); int yBlocks = (int) Math.Ceiling(world.Size.Height / (float) blockHeight); string taskName = string.Format("Generating Zoom Level {0} ({1}x{2})...", zoomLevel, xBlocks, yBlocks); progressHandler.SubTaskName = taskName; progressHandler.SubTasksCompleted = 0; progressHandler.SubTaskCount = xBlocks * yBlocks; Parallel.For(0, xBlocks, parallelOptions, i => { for (int j = 0; j < yBlocks; ++j) { if (progressHandler.Cancel) { return; } progressHandler.WriteLine(string.Format(" Writing Block {0},{1}", i, j)); CreateBlockImages(world, i, j, blockWidth, blockHeight, zoomLevel); ++progressHandler.SubTasksCompleted; } }); ++progressHandler.TasksCompleted; } WriteMapHtml(); progressHandler.WriteLine("Done"); }
private Image CreateBlockImage(World world, System.Drawing.Rectangle region, float zoomLevel, MapGeneratorLayerOptions layer) { Image blockImage = new Bitmap(16 * options.BlockSize.Width, 16 * options.BlockSize.Height, PixelFormat.Format32bppArgb); TextureSet textures = null; lock (availableTextureSetLock) { if (availableTextureSet.Count == 0) { System.Diagnostics.Trace.WriteLine("Creating new texture set for thread: " + Thread.CurrentThread.ManagedThreadId); textures = this.textures.Copy(); } else { textures = availableTextureSet.Dequeue(); } } using (Graphics g = Graphics.FromImage(blockImage)) { g.Clip = new Region(new RectangleF(0, 0, region.Width * 16 * zoomLevel, region.Height * 16 * zoomLevel)); g.ScaleTransform(zoomLevel, zoomLevel); g.PixelOffsetMode = PixelOffsetMode.Half; g.CompositingMode = CompositingMode.SourceOver; g.InterpolationMode = InterpolationMode.NearestNeighbor; g.CompositingQuality = CompositingQuality.HighSpeed; if (layer.DrawBackground) { DrawSky(world, region, g); } if (layer.DrawBackgroundWater) { DrawWater(world, region, true, g, textures); } if (layer.DrawBackground) { DrawBackground(world, region, g, textures); } if (layer.DrawWalls) { DrawWalls(world, region, g, textures); } if (layer.DrawBackgroundTiles) { DrawTiles(world, region, false, g, textures); } if (layer.DrawForegroundTiles) { DrawTiles(world, region, true, g, textures); } if (layer.DrawForegroundWater) { DrawWater(world, region, false, g, textures); } } lock (availableTextureSetLock) { availableTextureSet.Enqueue(textures); } return blockImage; }
protected void DrawWater(World world, System.Drawing.Rectangle region, bool background, Graphics g, TextureSet textures) { for (int y = region.Top; y < region.Bottom; y++) { for (int x = region.Left; x < region.Right; x++) { if (y == 0) { continue; } // Skip if the tile contains no liquid. if (world.tile[x, y].Liquid <= 0) { continue; } // What is the liquid level of the tile? float liquidLevel = 256 - world.tile[x, y].Liquid; liquidLevel /= 32f; int liquidTextureIndex = 0; if (world.tile[x, y].Lava) { liquidTextureIndex = 1; } float intensity = 0.5f; if (background) { intensity = 1f; } Vector2 vector = new Vector2((float) (x * 16), (float) ((y * 16) + (((int) liquidLevel) * 2))); Microsoft.Xna.Framework.Rectangle rectangle = new Microsoft.Xna.Framework.Rectangle(0, 0, 16, 16 - (((int) liquidLevel) * 2)); if ((world.tile[x, y + 1].Liquid < 245) && ((!world.tile[x, y + 1].Active || !World.tileSolid[world.tile[x, y + 1].Type]) || World.tileSolidTop[world.tile[x, y + 1].Type])) { float num10 = 256 - world.tile[x, y + 1].Liquid; num10 /= 32f; intensity = (0.5f * (8f - liquidLevel)) / 4f; if (intensity > 0.55) { intensity = 0.55f; } if (intensity < 0.35) { intensity = 0.35f; } float num11 = liquidLevel / 2f; if (world.tile[x, y + 1].Liquid < 200) { if (background) { continue; } if ((world.tile[x, y - 1].Liquid > 0) && (world.tile[x, y - 1].Liquid > 0)) { rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16); intensity = 0.5f; } else if (world.tile[x, y - 1].Liquid > 0) { vector = new Vector2((float) (x * 16), (float) ((y * 16) + 4)); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 12); intensity = 0.5f; } else if (world.tile[x, y + 1].Liquid > 0) { vector = new Vector2((float) (x * 16), (float) (((y * 16) + (((int) liquidLevel) * 2)) + (((int) num10) * 2))); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16 - (((int) liquidLevel) * 2)); } else { vector = new Vector2((float) ((x * 16) + ((int) num11)), (float) (((y * 16) + (((int) num11) * 2)) + (((int) num10) * 2))); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16 - (((int) num11) * 2), 16 - (((int) num11) * 2)); } } else { intensity = 0.5f; rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, (16 - (((int) liquidLevel) * 2)) + (((int) num10) * 2)); } } else if (world.tile[x, y - 1].Liquid > 32) { rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, rectangle.Width, rectangle.Height - 4); } else if (((liquidLevel < 1f) && world.tile[x, y - 1].Active) && (World.tileSolid[world.tile[x, y - 1].Type] && !World.tileSolidTop[world.tile[x, y - 1].Type])) { vector = new Vector2((float) (x * 16), (float) (y * 16)); rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16 - 4); } else { bool flag = true; for (int k = y + 1; k < (y + 6); k++) { if ((world.tile[x, k].Active && World.tileSolid[world.tile[x, k].Type]) && !World.tileSolidTop[world.tile[x, k].Type]) { break; } if (world.tile[x, k].Liquid < 200) { flag = false; break; } } if (!flag) { intensity = 0.5f; rectangle = new Microsoft.Xna.Framework.Rectangle(0, 4, 16, 16 - 4); } else if (world.tile[x, y - 1].Liquid > 0) { rectangle = new Microsoft.Xna.Framework.Rectangle(0, 2, rectangle.Width, rectangle.Height - 2); } } if (world.tile[x, y].Lava) { intensity *= 1.6f; } if (intensity > 1f) { intensity = 1f; } ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix33 = intensity; ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(colorMatrix); int waterWidth = 16; int waterHeight = 16 - ((int) vector.Y - (y * 16)); g.DrawImage(textures.liquidTexture[liquidTextureIndex], new System.Drawing.Rectangle((int) (vector.X - region.Left * 16), (int) (vector.Y - region.Top * 16), waterWidth, waterHeight), rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, GraphicsUnit.Pixel, imageAttributes); } } }
protected void DrawWalls(World world, System.Drawing.Rectangle region, Graphics g, TextureSet textures) { for (int y = region.Top; y < region.Bottom; y++) { for (int x = region.Left; x < region.Right; x++) { if (world.tile[x, y].Wall > 0) { System.Drawing.RectangleF rectangle3 = new System.Drawing.RectangleF(world.tile[x, y].WallFrameX * 2, world.tile[x, y].WallFrameY * 2, 32, 32); g.DrawImage(textures.wallTexture[world.tile[x, y].Wall], new System.Drawing.RectangleF((x - region.Left) * 16 - 8, (y - region.Top) * 16 - 8, 32, 32), rectangle3, GraphicsUnit.Pixel); } } } }
protected void DrawSky(World world, System.Drawing.Rectangle region, Graphics g) { float regionWidth = region.Width * 16; float regionHeight = region.Height * 16; // Draw the sky. int skyEnd = (int) world.worldSurface + 1; if (region.Top <= skyEnd) { float skyStart = region.Top / (float) skyEnd; float skyHeight = 0; float destinationHeight = 0; if (region.Bottom <= skyEnd) { skyHeight = region.Height / (float) skyEnd; destinationHeight = region.Height; } else { skyHeight = 1.0f - skyStart; destinationHeight = skyEnd - region.Top; } System.Drawing.Color firstColor = skyStartColor.Lerp(skyEndColor, skyStart); System.Drawing.Color secondColor = skyStartColor.Lerp(skyEndColor, skyStart + skyHeight); destinationHeight *= 16; using (Brush brush = new LinearGradientBrush(new PointF(0, 0), new PointF(0, destinationHeight), firstColor, secondColor)) { g.FillRectangle(brush, new RectangleF(0, 0, regionWidth, destinationHeight)); } } }
protected void DrawBackground(World world, System.Drawing.Rectangle region, Graphics g, TextureSet textures) { float regionWidth = region.Width * 16; float regionHeight = region.Height * 16; int skyEnd = (int) world.worldSurface + 1; // Draw the Dirt Sky Blend if (region.Top < skyEnd && skyEnd <= region.Bottom) { float destinationTop = (skyEnd - region.Top - 1) * 16; // How many across need to be rendered. int instances = (int) Math.Ceiling(regionWidth / textures.backgroundTexture[1].Width) + 1; int offset = ((region.Left % 6) + 3) * 16; for (int i = 0; i < instances; ++i) { g.DrawImage(textures.backgroundTexture[1], new PointF(i * textures.backgroundTexture[1].Width - offset, destinationTop)); } } int rockStart = (int) world.rockLayer + 38; // Draw the Dirt Background if (skyEnd < region.Bottom || region.Top <= rockStart) { int minBlockY = region.Top; float startOffsetY = 0.0f; if (skyEnd > region.Top) { minBlockY = skyEnd; startOffsetY = (skyEnd - region.Top) * 16; } int maxBlockY = (int) ((rockStart < region.Bottom) ? rockStart : region.Bottom); int blockCount = maxBlockY - minBlockY; int dirtBackgroundTextureWidth = textures.backgroundTexture[2].Width; int dirtBackgroundTextureHeight = textures.backgroundTexture[2].Height; // How many vertical repeats. int instancesToDrawY = (int) Math.Ceiling(blockCount * 16.0f / dirtBackgroundTextureHeight) + 1; int instancesToDrawX = (int) Math.Ceiling((regionWidth / dirtBackgroundTextureWidth)) + 1; int offsetX = (((region.Left) % (dirtBackgroundTextureWidth / 16)) + 3) * 16; int offsetY = ((minBlockY - (int) skyEnd) % (dirtBackgroundTextureHeight / 16)) * 16; for (int i = 0; i < instancesToDrawX; ++i) { for (int j = 0; j < instancesToDrawY; ++j) { g.DrawImage(textures.backgroundTexture[2], new PointF(i * dirtBackgroundTextureWidth - offsetX, startOffsetY + j * dirtBackgroundTextureHeight - offsetY)); } } } // Draw the Dirt Rock Blend if (region.Top < rockStart && rockStart <= region.Bottom) { float destinationTop = (rockStart - region.Top - 1) * 16; // How many across need to be rendered. int instances = (int) Math.Ceiling(regionWidth / textures.backgroundTexture[4].Width) + 1; int offset = ((region.Left % 6) + 3) * 16; for (int i = 0; i < instances; ++i) { g.DrawImage(textures.backgroundTexture[4], new PointF(i * textures.backgroundTexture[4].Width - offset, destinationTop)); } } int hellStart = world.Size.Height - 230; // Draw the Rock Background if (region.Bottom > rockStart || region.Top < hellStart) { int minBlockY = region.Top; float startOffsetY = 0.0f; if (rockStart > region.Top) { minBlockY = rockStart; startOffsetY = (rockStart - region.Top) * 16; } int maxBlockY = (hellStart < region.Bottom) ? hellStart : region.Bottom; int blockCount = maxBlockY - minBlockY; int rockBackgroundTextureWidth = textures.backgroundTexture[3].Width; int rockBackgroundTextureHeight = textures.backgroundTexture[3].Height; // How many vertical repeats. int instancesToDrawY = (int) Math.Ceiling(blockCount * 16.0f / rockBackgroundTextureHeight) + 1; int instancesToDrawX = (int) Math.Ceiling((regionWidth / rockBackgroundTextureWidth)) + 1; int offsetX = (((region.Left) % (rockBackgroundTextureWidth / 16)) + 3) * 16; int offsetY = ((minBlockY - (int) rockStart - 1) % (rockBackgroundTextureHeight / 16)) * 16 + 8; for (int i = 0; i < instancesToDrawX; ++i) { for (int j = 0; j < instancesToDrawY; ++j) { g.DrawImage(textures.backgroundTexture[3], new PointF(i * rockBackgroundTextureWidth - offsetX, startOffsetY + j * rockBackgroundTextureHeight - offsetY)); } } } // Draw the Rock Hell Blend if (region.Top < hellStart && hellStart <= region.Bottom) { float destinationTop = (hellStart - region.Top - 1) * 16 + 24; // How many across need to be rendered. int instances = (int) Math.Ceiling(regionWidth / textures.backgroundTexture[6].Width) + 1; int offset = ((region.Left % 6) + 3) * 16; for (int i = 0; i < instances; ++i) { g.DrawImage(textures.backgroundTexture[6], new PointF(i * textures.backgroundTexture[6].Width - offset, destinationTop)); } } // Draw the Hell Background if (region.Bottom > hellStart) { int minBlockY = region.Top; float startOffsetY = 0.0f; if (hellStart > region.Top) { minBlockY = hellStart; startOffsetY = (hellStart - region.Top) * 16; } int maxBlockY = region.Bottom; int blockCount = maxBlockY - minBlockY; int rockBackgroundTextureWidth = textures.backgroundTexture[5].Width; int rockBackgroundTextureHeight = textures.backgroundTexture[5].Height; // How many vertical repeats. int instancesToDrawY = (int) Math.Ceiling(blockCount * 16.0f / rockBackgroundTextureHeight) + 1; int instancesToDrawX = (int) Math.Ceiling((regionWidth / rockBackgroundTextureWidth)) + 1; int offsetX = (((region.Left) % (rockBackgroundTextureWidth / 16)) + 3) * 16; int offsetY = ((minBlockY - (int) hellStart - 1) % (rockBackgroundTextureHeight / 16)) * 16 - 16; for (int i = 0; i < instancesToDrawX; ++i) { for (int j = 0; j < instancesToDrawY; ++j) { g.DrawImage(textures.backgroundTexture[5], new PointF(i * rockBackgroundTextureWidth - offsetX, startOffsetY + j * rockBackgroundTextureHeight - offsetY)); } } } }