public void Bind(Map m, TileSet ts, TileSetRenderer tsr, IPalette p, IPalette pp) { Map = m; TileSet = ts; TileSetRenderer = tsr; Palette = p; PlayerPalette = pp; playerPalettes = null; Chunks.Clear(); currentTool = null; }
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, Palette p, Palette pp) { Map = m; TileSet = ts; TileSetRenderer = tsr; Palette = p; PlayerPalette = pp; playerPalettes = null; Chunks.Clear(); currentTool = null; }
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, IPalette p, IPalette pp) { Map = m; if (m != null) Actors = m.ActorDefinitions.ToDictionary(n => n.Key, n => new ActorReference(n.Value.Value, n.Value.ToDictionary())); TileSet = ts; TileSetRenderer = tsr; Palette = p; PlayerPalette = pp; playerPalettes = null; Chunks.Clear(); currentTool = null; }
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, IPalette p, IPalette pp) { Map = m; if (m != null) { Actors = m.ActorDefinitions.ToDictionary(n => n.Key, n => new ActorReference(n.Value.Value, n.Value.ToDictionary())); } TileSet = ts; TileSetRenderer = tsr; Palette = p; PlayerPalette = pp; playerPalettes = null; Chunks.Clear(); currentTool = null; }
// this code is insanely stupid, and mostly my fault -- chrisf void PrepareMapResources(ModData modData, Map map) { Program.Rules = map.Rules; tileset = Program.Rules.TileSets[map.Tileset]; tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize); var shadowIndex = new int[] { 3, 4 }; var palette = new ImmutablePalette(GlobalFileSystem.Open(tileset.Palette), shadowIndex); // required for desert terrain in RA var playerPalette = tileset.PlayerPalette ?? tileset.Palette; var shadowedPalette = new ImmutablePalette(GlobalFileSystem.Open(playerPalette), shadowIndex); surface1.Bind(map, tileset, tilesetRenderer, palette, shadowedPalette); // construct the palette of tiles var palettes = new[] { tilePalette, actorPalette, resourcePalette }; foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); } var templateOrder = tileset.EditorTemplateOrder ?? new string[] { }; foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => templateOrder.IndexOf(t.Key))) { var category = tc.Key ?? "(Uncategorized)"; var categoryHeader = new Label { BackColor = SystemColors.Highlight, ForeColor = SystemColors.HighlightText, Text = category, AutoSize = false, Height = 24, TextAlign = ContentAlignment.MiddleLeft, Width = tilePalette.ClientSize.Width, }; // hook this manually, anchoring inside FlowLayoutPanel is flaky. tilePalette.Resize += (_, e) => categoryHeader.Width = tilePalette.ClientSize.Width; if (tilePalette.Controls.Count > 0) { tilePalette.SetFlowBreak( tilePalette.Controls[tilePalette.Controls.Count - 1], true); } tilePalette.Controls.Add(categoryHeader); foreach (var t in tc) { try { var bitmap = tilesetRenderer.RenderTemplate((ushort)t.Key, palette); var ibox = new PictureBox { Image = bitmap, Width = bitmap.Width / 2, Height = bitmap.Height / 2, SizeMode = PictureBoxSizeMode.StretchImage }; var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key }; ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate)); var template = t.Value; tilePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{1}:{0} ({2}x{3})".F(template.Images[0], template.Id, template.Size.X, template.Size.Y)); } catch { } } } var actorTemplates = new List <ActorTemplate>(); foreach (var a in Program.Rules.Actors.Keys) { try { var info = Program.Rules.Actors[a]; if (!info.Traits.Contains <ILegacyEditorRenderInfo>()) { continue; } var etf = info.Traits.GetOrDefault <EditorTilesetFilterInfo>(); if (etf != null && etf.ExcludeTilesets != null && etf.ExcludeTilesets.Contains(tileset.Id)) { continue; } if (etf != null && etf.RequireTilesets != null && !etf.RequireTilesets.Contains(tileset.Id)) { continue; } var templatePalette = shadowedPalette; var rsi = info.Traits.GetOrDefault <ILegacyEditorRenderInfo>(); // exception for desert buildings if (rsi != null && rsi.EditorPalette != null && rsi.EditorPalette.Contains("terrain")) { templatePalette = palette; } var race = Program.Rules.Actors["world"].Traits.WithInterface <CountryInfo>().First().Race; var sequenceProvider = Program.Rules.Sequences[tileset.Id]; var template = RenderUtils.RenderActor(info, sequenceProvider, tileset, templatePalette, race); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ActorTool(template)); actorPalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}".F(info.Name)); actorTemplates.Add(template); } catch { } } surface1.BindActorTemplates(actorTemplates); var resourceTemplates = new List <ResourceTemplate>(); foreach (var a in Program.Rules.Actors["world"].Traits.WithInterface <ResourceTypeInfo>()) { try { var template = RenderUtils.RenderResourceType(a, tileset, shadowedPalette); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ResourceTool(template)); resourcePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}:{1}cr".F(template.Info.Name, template.Info.ValuePerUnit)); resourceTemplates.Add(template); } catch { } } surface1.BindResourceTemplates(resourceTemplates); foreach (var p in palettes) { p.Visible = true; p.ResumeLayout(); } miniMapBox.Image = Minimap.RenderMapPreview(tileset, surface1.Map, true); propertiesToolStripMenuItem.Enabled = true; toolStripMenuItemProperties.Enabled = true; resizeToolStripMenuItem.Enabled = true; toolStripMenuItemResize.Enabled = true; saveToolStripMenuItem.Enabled = true; toolStripMenuItemSave.Enabled = true; saveAsToolStripMenuItem.Enabled = true; miniMapToPng.Enabled = true; PopulateActorOwnerChooser(); }
// this code is insanely stupid, and mostly my fault -- chrisf void PrepareMapResources(ModData modData, Map map) { Program.Rules = map.Rules; tileset = Program.Rules.TileSets[map.Tileset]; tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize); var shadowIndex = new int[] { 3, 4 }; var palette = new Palette(GlobalFileSystem.Open(tileset.Palette), shadowIndex); // required for desert terrain in RA var playerPalette = tileset.PlayerPalette ?? tileset.Palette; var shadowedPalette = new Palette(GlobalFileSystem.Open(playerPalette), shadowIndex); surface1.Bind(map, tileset, tilesetRenderer, palette, shadowedPalette); // construct the palette of tiles var palettes = new[] { tilePalette, actorPalette, resourcePalette }; foreach (var p in palettes) { p.Visible = false; p.SuspendLayout(); } var templateOrder = tileset.EditorTemplateOrder ?? new string[] { }; foreach (var tc in tileset.Templates.GroupBy(t => t.Value.Category).OrderBy(t => templateOrder.ToList().IndexOf(t.Key))) { var category = tc.Key ?? "(Uncategorized)"; var categoryHeader = new Label { BackColor = SystemColors.Highlight, ForeColor = SystemColors.HighlightText, Text = category, AutoSize = false, Height = 24, TextAlign = ContentAlignment.MiddleLeft, Width = tilePalette.ClientSize.Width, }; // hook this manually, anchoring inside FlowLayoutPanel is flaky. tilePalette.Resize += (_, e) => categoryHeader.Width = tilePalette.ClientSize.Width; if (tilePalette.Controls.Count > 0) tilePalette.SetFlowBreak( tilePalette.Controls[tilePalette.Controls.Count - 1], true); tilePalette.Controls.Add(categoryHeader); foreach (var t in tc) { try { var bitmap = tilesetRenderer.RenderTemplate((ushort)t.Key, palette); var ibox = new PictureBox { Image = bitmap, Width = bitmap.Width / 2, Height = bitmap.Height / 2, SizeMode = PictureBoxSizeMode.StretchImage }; var brushTemplate = new BrushTemplate { Bitmap = bitmap, N = t.Key }; ibox.Click += (_, e) => surface1.SetTool(new BrushTool(brushTemplate)); var template = t.Value; tilePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{1}:{0} ({2}x{3})".F(template.Image, template.Id, template.Size.X, template.Size.Y)); } catch { } } } var actorTemplates = new List<ActorTemplate>(); foreach (var a in Program.Rules.Actors.Keys) { try { var info = Program.Rules.Actors[a]; if (!info.Traits.Contains<RenderSimpleInfo>()) continue; var etf = info.Traits.GetOrDefault<EditorTilesetFilterInfo>(); if (etf != null && etf.ExcludeTilesets != null && etf.ExcludeTilesets.Contains(tileset.Id)) continue; if (etf != null && etf.RequireTilesets != null && !etf.RequireTilesets.Contains(tileset.Id)) continue; var templatePalette = shadowedPalette; var rsi = info.Traits.GetOrDefault<RenderSimpleInfo>(); // exception for desert buildings if (rsi != null && rsi.Palette != null && rsi.Palette.Contains("terrain")) templatePalette = palette; var template = RenderUtils.RenderActor(info, tileset, templatePalette); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ActorTool(template)); actorPalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}".F(info.Name)); actorTemplates.Add(template); } catch { } } surface1.BindActorTemplates(actorTemplates); var resourceTemplates = new List<ResourceTemplate>(); foreach (var a in Program.Rules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()) { try { var template = RenderUtils.RenderResourceType(a, tileset.Extensions, shadowedPalette); var ibox = new PictureBox { Image = template.Bitmap, Width = 32, Height = 32, SizeMode = PictureBoxSizeMode.Zoom, BorderStyle = BorderStyle.FixedSingle }; ibox.Click += (_, e) => surface1.SetTool(new ResourceTool(template)); resourcePalette.Controls.Add(ibox); tt.SetToolTip(ibox, "{0}:{1}cr".F(template.Info.Name, template.Info.ValuePerUnit)); resourceTemplates.Add(template); } catch { } } surface1.BindResourceTemplates(resourceTemplates); foreach (var p in palettes) { p.Visible = true; p.ResumeLayout(); } miniMapBox.Image = Minimap.RenderMapPreview(tileset, surface1.Map, true); propertiesToolStripMenuItem.Enabled = true; toolStripMenuItemProperties.Enabled = true; resizeToolStripMenuItem.Enabled = true; toolStripMenuItemResize.Enabled = true; saveToolStripMenuItem.Enabled = true; toolStripMenuItemSave.Enabled = true; saveAsToolStripMenuItem.Enabled = true; miniMapToPng.Enabled = true; PopulateActorOwnerChooser(); }
public const int ChunkSize = 8; // 8x8 chunks ==> 192x192 bitmaps. Bitmap RenderChunk(int u, int v) { var bitmap = new Bitmap(ChunkSize * TileSetRenderer.TileSize.Width, ChunkSize * TileSetRenderer.TileSize.Height); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { int *p = (int *)data.Scan0.ToPointer(); var stride = data.Stride >> 2; for (var i = 0; i < ChunkSize; i++) { for (var j = 0; j < ChunkSize; j++) { var tr = Map.MapTiles.Value[u * ChunkSize + i, v *ChunkSize + j]; var tile = TileSetRenderer.Data(tr.Type); var index = (tr.Index < tile.Count) ? tr.Index : (byte)0; var rawImage = tile[index]; for (var x = 0; x < TileSetRenderer.TileSize.Width; x++) { for (var y = 0; y < TileSetRenderer.TileSize.Height; y++) { p[(j * TileSetRenderer.TileSize.Width + y) * stride + i * TileSetRenderer.TileSize.Width + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize.Width * y]).ToArgb(); } } if (Map.MapResources.Value[u * ChunkSize + i, v *ChunkSize + j].Type != 0) { var resourceImage = ResourceTemplates[Map.MapResources.Value[u * ChunkSize + i, v *ChunkSize + j].Type].Bitmap; var srcdata = resourceImage.LockBits(resourceImage.Bounds(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int *q = (int *)srcdata.Scan0.ToPointer(); var srcstride = srcdata.Stride >> 2; for (var x = 0; x < TileSetRenderer.TileSize.Width; x++) { for (var y = 0; y < TileSetRenderer.TileSize.Height; y++) { var c = q[y * srcstride + x]; if ((c & 0xff000000) != 0) /* quick & dirty, i cbf doing real alpha */ { p[(j * TileSetRenderer.TileSize.Width + y) * stride + i * TileSetRenderer.TileSize.Width + x] = c; } } } resourceImage.UnlockBits(srcdata); } } } } bitmap.UnlockBits(data); if (ShowGrid) { using (var g = SGraphics.FromImage(bitmap)) { var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); ControlPaint.DrawGrid(g, rect, new Size(2, Game.CellSize), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(Game.CellSize, 2), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(Game.CellSize, Game.CellSize), Color.Red); } } return(bitmap); }
public const int ChunkSize = 8; // 8x8 chunks ==> 192x192 bitmaps. Bitmap RenderChunk(int u, int v) { var bitmap = new Bitmap(ChunkSize * TileSetRenderer.TileSize, ChunkSize * TileSetRenderer.TileSize); var data = bitmap.LockBits(bitmap.Bounds(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); unsafe { var p = (int *)data.Scan0.ToPointer(); var stride = data.Stride >> 2; for (var i = 0; i < ChunkSize; i++) { for (var j = 0; j < ChunkSize; j++) { var ui = u * ChunkSize + i; var vj = v * ChunkSize + j; var uv = new MPos(ui, vj); if (uv.U >= Map.MapSize.X || uv.V >= Map.MapSize.Y) { for (var x = 0; x < TileSetRenderer.TileSize; x++) { for (var y = 0; y < TileSetRenderer.TileSize; y++) { p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = 0; } } continue; } var tr = Map.MapTiles.Value[uv]; var tile = TileSetRenderer.Data(tr.Type); if (tile == null) { continue; } var index = (tr.Index < tile.Length) ? tr.Index : (byte)0; var rawImage = tile[index]; for (var x = 0; x < TileSetRenderer.TileSize; x++) { for (var y = 0; y < TileSetRenderer.TileSize; y++) { p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = Palette.GetColor(rawImage[x + TileSetRenderer.TileSize * y]).ToArgb(); } } if (Map.MapResources.Value[uv].Type != 0) { var resourceImage = ResourceTemplates[Map.MapResources.Value[uv].Type].Bitmap; var srcdata = resourceImage.LockBits(resourceImage.Bounds(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var q = (int *)srcdata.Scan0.ToPointer(); var srcstride = srcdata.Stride >> 2; for (var x = 0; x < TileSetRenderer.TileSize; x++) { for (var y = 0; y < TileSetRenderer.TileSize; y++) { var c = q[y * srcstride + x]; if ((c & 0xff000000) != 0) /* quick & dirty, i cbf doing real alpha */ { p[(j * TileSetRenderer.TileSize + y) * stride + i * TileSetRenderer.TileSize + x] = c; } } } resourceImage.UnlockBits(srcdata); } } } } bitmap.UnlockBits(data); if (ShowGrid) { using (var g = SGraphics.FromImage(bitmap)) { var ts = Game.ModData.Manifest.TileSize; var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); ControlPaint.DrawGrid(g, rect, new Size(2, ts.Height), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(ts.Width, 2), Color.DarkRed); ControlPaint.DrawGrid(g, rect, new Size(ts.Width, ts.Height), Color.Red); } } return(bitmap); }