using System; using System.Drawing; using System.IO; using System.Windows.Forms; using pk3DS.Core.CTR; namespace pk3DS.WinForms; public partial class MapPermView : Form { public MapPermView() { InitializeComponent(); MapMatrixes = Directory.GetFiles("mapMatrix"); MapGRs = Directory.GetFiles("mapGR"); } private readonly string[] MapMatrixes; private readonly string[] MapGRs; private int mapScale = -1; public int DrawMap = -1; public void SetMap(int Map) { DrawMap = Map; PB_Map.Image = CHK_AutoDraw.Checked ? GetMapImage(sliceArea: true) : null; } public Bitmap GetMapImage(bool crop = false, bool entity = true, bool sliceArea = false) { // Load MM byte[][] MM = Mini.UnpackMini(File.ReadAllBytes(MapMatrixes[DrawMap]), "MM"); var mm = OWSE.mm = new MapMatrix(MM); // Unknown if (ModifierKeys == Keys.Control) Clipboard.SetText(mm.Unk2String()); // Load GR TileMaps for (int i = 0; i < mm.EntryList.Length; i++) { if (mm.EntryList[i] == 0xFFFF) // Mystery Zone continue; byte[][] GR = Mini.UnpackMini(File.ReadAllBytes(MapGRs[mm.EntryList[i]]), "GR"); mm.Entries[i] = new MapMatrix.Entry(GR[0]) { coll = new MapMatrix.Collision(GR[2]) }; } mapScale = Math.Max(1, (int)NUD_Scale.Value); Bitmap img = mm.Preview(mapScale, (int)NUD_Flavor.Value); baseImage = (Bitmap)img.Clone(); if (sliceArea && mapScale > 3) { int area = 40 * mapScale; for (int x = 0; x < img.Width; x++) { for (int y = 0; y < img.Height; y++) { if (x % area == 0 || y % area == 0) img.SetPixel(x, y, Color.FromArgb(0x10, 0xFF, 0, 0)); } } } if (entity && mapScale == 8) img = OverlayEntities(img); if (crop) img = WinFormsUtil.TrimBitmap(img); return img; } internal static Bitmap baseImage; private Bitmap OverlayEntities(Bitmap img) { const float opacity = 0.66f; // Overlay every... overworld entity foreach (var e in OWSE.CurrentZone.Entities.Furniture) { int x = e.X; int y = e.Y; for (int sx = 0; sx < e.WX; sx++) // Stretch X { for (int sy = 0; sy < e.WY; sy++) // Stretch Y { try { WinFormsUtil.LayerImage(img, Properties.Resources.F, (x + sx) * mapScale, (y + sy) * mapScale, opacity); } catch { } } } } foreach (var e in OWSE.CurrentZone.Entities.NPCs) { int x = e.X; int y = e.Y; try { WinFormsUtil.LayerImage(img, Properties.Resources.N, x * mapScale, y * mapScale, opacity); } catch { } } foreach (var e in OWSE.CurrentZone.Entities.Warps) { int x = (int)e.PX; // shifted warps look weird int y = (int)e.PY; // shifted warps look weird for (int sx = 0; sx < e.Width; sx++) // Stretch X { for (int sy = 0; sy < e.Height; sy++) // Stretch Y { try { WinFormsUtil.LayerImage(img, Properties.Resources.W, (x + sx) * mapScale, (y + sy) * mapScale, opacity); } catch { } } } } foreach (var e in OWSE.CurrentZone.Entities.Triggers1) { int x = e.X; int y = e.Y; for (int sx = 0; sx < e.Width; sx++) // Stretch X { for (int sy = 0; sy < e.Height; sy++) // Stretch Y { try { WinFormsUtil.LayerImage(img, Properties.Resources.T1, (x + sx) * mapScale, (y + sy) * mapScale, opacity); } catch { } } } } foreach (var e in OWSE.CurrentZone.Entities.Triggers2) { int x = e.X; int y = e.Y; for (int sx = 0; sx < e.Width; sx++) // Stretch X { for (int sy = 0; sy < e.Height; sy++) // Stretch Y { try { WinFormsUtil.LayerImage(img, Properties.Resources.T2, (x + sx) * mapScale, (y + sy) * mapScale, opacity); } catch { } } } } // Overlay Map Data // Flyto { int x = (int)OWSE.CurrentZone.ZD.PX2; int y = (int)OWSE.CurrentZone.ZD.PY2; for (int sx = 0; sx < 1; sx++) // Stretch X { for (int sy = 0; sy < 1; sy++) // Stretch Y { try { WinFormsUtil.LayerImage(img, Properties.Resources.FLY, (x + sx) * mapScale, (y + sy) * mapScale, opacity / 2); } catch { } } } } // Unknown //{ // using(var g = Graphics.FromImage(img)) // foreach (var l in OWSE.mm.LoadLines) // try { g.DrawLine(new Pen(Color.Red, 4), l.p2 * mapScale, l.p1 * mapScale, l.p4 * mapScale, l.p3 * mapScale); } // catch {} //} return img; } // UI private void HoverMap(object sender, MouseEventArgs e) { if (mapScale < 0) return; if (PB_Map.Image == null) return; int X = e.X / mapScale; int Y = e.Y / mapScale; int entryX = X / 40; int entryY = Y / 40; int entry = (entryY * (PB_Map.Image.Width / 40 / mapScale)) + entryX; int epX = X % 40; int epY = Y % 40; int tile = (epY * 40) + epX; try { var tileVal = OWSE.mm.Entries[entry] == null ? "No Tile" : OWSE.mm.Entries[entry].Tiles[tile].ToString("X8"); L_MapCoord.Text = string.Format("V:0x{3}{2}X:{0,3} Y:{1,3}", X, Y, Environment.NewLine, tileVal); } catch { } } private void B_Redraw_Click(object sender, EventArgs e) { if (DrawMap != -1) PB_Map.Image = GetMapImage(sliceArea: true); } private void MapPermView_FormClosing(object sender, FormClosingEventArgs e) { CHK_AutoDraw.Checked = false; Hide(); e.Cancel = true; } private void FocusPanel(object sender, EventArgs e) { if (ContainsFocus) PAN_MAP.Focus(); } private void DclickMap(object sender, EventArgs e) { DialogResult dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy image to Clipboard?", "Yes: Map & Overworlds" + Environment.NewLine + "No: Map Only"); if (dr == DialogResult.No) // Map Only Clipboard.SetImage(WinFormsUtil.TrimBitmap(baseImage)); if (dr == DialogResult.Yes) Clipboard.SetImage(PB_Map.Image); } }