diff --git a/NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs b/NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs index 1a75fbb..2cf56c0 100644 --- a/NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs +++ b/NHSE.Core/Structures/Acres/Terrain/TerrainManager.cs @@ -24,7 +24,7 @@ public TerrainManager(TerrainTile[] tiles) Tiles = tiles; } - private static int GetIndex(int x, int y) => (MapHeight * x) + y; + public static int GetIndex(int x, int y) => (MapHeight * x) + y; public TerrainTile GetTile(int x, int y) => this[GetIndex(x, y)]; @@ -43,6 +43,8 @@ public TerrainTile GetAcreTile(int acreIndex, int tileIndex) return GetTile(acre.X, acre.Y, x, y); } + public static int GetAcre(int x, int y) => (x / GridWidth) + ((y / GridHeight) * AcreWidth); + public TerrainTile this[int index] { get => Tiles[index]; diff --git a/NHSE.Sprites/TerrainSprite.cs b/NHSE.Sprites/TerrainSprite.cs index 2d13287..e55b574 100644 --- a/NHSE.Sprites/TerrainSprite.cs +++ b/NHSE.Sprites/TerrainSprite.cs @@ -54,7 +54,14 @@ public static Bitmap CreateMap(TerrainManager mgr) return bmp; } - public static Image CreateMap(TerrainManager mgr, int scale, int acreIndex = -1) + public static Bitmap CreateMap(TerrainManager mgr, int scale, int x, int y) + { + var img = CreateMap(mgr); + var map = ImageUtil.ResizeImage(img, img.Width * scale, img.Height * scale); + return DrawReticle(map, x, y, scale); + } + + public static Bitmap CreateMap(TerrainManager mgr, int scale, int acreIndex = -1) { var img = CreateMap(mgr); var map = ImageUtil.ResizeImage(img, img.Width * scale, img.Height * scale); @@ -62,15 +69,21 @@ public static Image CreateMap(TerrainManager mgr, int scale, int acreIndex = -1) if (acreIndex < 0) return img; + var acre = mgr.Acres[acreIndex]; + var x = acre.X * TerrainManager.GridWidth; + var y = acre.Y * TerrainManager.GridHeight; + + return DrawReticle(map, x, y, scale); + } + + private static Bitmap DrawReticle(Bitmap map, int x, int y, int scale) + { using var gfx = Graphics.FromImage(map); using var pen = new Pen(Color.Red); - var acre = mgr.Acres[acreIndex]; - var x = acre.X * TerrainManager.GridWidth * scale; - var y = acre.Y * TerrainManager.GridHeight * scale; int w = TerrainManager.GridWidth * scale; int h = TerrainManager.GridHeight * scale; - gfx.DrawRectangle(pen, x, y, w, h); + gfx.DrawRectangle(pen, x * scale, y * scale, w, h); return map; } } diff --git a/NHSE.WinForms/Subforms/TerrainEditor.Designer.cs b/NHSE.WinForms/Subforms/TerrainEditor.Designer.cs index 2f8dd84..d5deb00 100644 --- a/NHSE.WinForms/Subforms/TerrainEditor.Designer.cs +++ b/NHSE.WinForms/Subforms/TerrainEditor.Designer.cs @@ -52,6 +52,7 @@ private void InitializeComponent() this.PB_Map = new System.Windows.Forms.PictureBox(); this.CM_Picture = new System.Windows.Forms.ContextMenuStrip(this.components); this.Menu_SavePNG = new System.Windows.Forms.ToolStripMenuItem(); + this.CHK_SnapToAcre = new System.Windows.Forms.CheckBox(); this.CM_Click.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.PB_Map)).BeginInit(); this.CM_Picture.SuspendLayout(); @@ -100,7 +101,7 @@ private void InitializeComponent() // this.CB_Acre.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.CB_Acre.FormattingEnabled = true; - this.CB_Acre.Location = new System.Drawing.Point(978, 588); + this.CB_Acre.Location = new System.Drawing.Point(978, 598); this.CB_Acre.Name = "CB_Acre"; this.CB_Acre.Size = new System.Drawing.Size(49, 21); this.CB_Acre.TabIndex = 10; @@ -109,7 +110,7 @@ private void InitializeComponent() // L_Acre // this.L_Acre.AutoSize = true; - this.L_Acre.Location = new System.Drawing.Point(940, 591); + this.L_Acre.Location = new System.Drawing.Point(940, 601); this.L_Acre.Name = "L_Acre"; this.L_Acre.Size = new System.Drawing.Size(32, 13); this.L_Acre.TabIndex = 11; @@ -117,7 +118,7 @@ private void InitializeComponent() // // B_ZeroElevation // - this.B_ZeroElevation.Location = new System.Drawing.Point(820, 276); + this.B_ZeroElevation.Location = new System.Drawing.Point(820, 262); this.B_ZeroElevation.Name = "B_ZeroElevation"; this.B_ZeroElevation.Size = new System.Drawing.Size(112, 40); this.B_ZeroElevation.TabIndex = 12; @@ -127,7 +128,7 @@ private void InitializeComponent() // // B_ClearAll // - this.B_ClearAll.Location = new System.Drawing.Point(937, 276); + this.B_ClearAll.Location = new System.Drawing.Point(937, 262); this.B_ClearAll.Name = "B_ClearAll"; this.B_ClearAll.Size = new System.Drawing.Size(112, 40); this.B_ClearAll.TabIndex = 13; @@ -137,7 +138,7 @@ private void InitializeComponent() // // B_DumpAcre // - this.B_DumpAcre.Location = new System.Drawing.Point(820, 662); + this.B_DumpAcre.Location = new System.Drawing.Point(820, 672); this.B_DumpAcre.Name = "B_DumpAcre"; this.B_DumpAcre.Size = new System.Drawing.Size(112, 40); this.B_DumpAcre.TabIndex = 14; @@ -147,7 +148,7 @@ private void InitializeComponent() // // B_DumpAllAcres // - this.B_DumpAllAcres.Location = new System.Drawing.Point(820, 708); + this.B_DumpAllAcres.Location = new System.Drawing.Point(820, 718); this.B_DumpAllAcres.Name = "B_DumpAllAcres"; this.B_DumpAllAcres.Size = new System.Drawing.Size(112, 40); this.B_DumpAllAcres.TabIndex = 15; @@ -157,7 +158,7 @@ private void InitializeComponent() // // B_ImportAllAcres // - this.B_ImportAllAcres.Location = new System.Drawing.Point(937, 708); + this.B_ImportAllAcres.Location = new System.Drawing.Point(937, 718); this.B_ImportAllAcres.Name = "B_ImportAllAcres"; this.B_ImportAllAcres.Size = new System.Drawing.Size(112, 40); this.B_ImportAllAcres.TabIndex = 17; @@ -167,7 +168,7 @@ private void InitializeComponent() // // B_ImportAcre // - this.B_ImportAcre.Location = new System.Drawing.Point(937, 662); + this.B_ImportAcre.Location = new System.Drawing.Point(937, 672); this.B_ImportAcre.Name = "B_ImportAcre"; this.B_ImportAcre.Size = new System.Drawing.Size(112, 40); this.B_ImportAcre.TabIndex = 16; @@ -207,7 +208,7 @@ private void InitializeComponent() // // B_Up // - this.B_Up.Location = new System.Drawing.Point(868, 551); + this.B_Up.Location = new System.Drawing.Point(868, 561); this.B_Up.Name = "B_Up"; this.B_Up.Size = new System.Drawing.Size(32, 32); this.B_Up.TabIndex = 18; @@ -217,7 +218,7 @@ private void InitializeComponent() // // B_Left // - this.B_Left.Location = new System.Drawing.Point(838, 581); + this.B_Left.Location = new System.Drawing.Point(838, 591); this.B_Left.Name = "B_Left"; this.B_Left.Size = new System.Drawing.Size(32, 32); this.B_Left.TabIndex = 19; @@ -227,7 +228,7 @@ private void InitializeComponent() // // B_Right // - this.B_Right.Location = new System.Drawing.Point(898, 581); + this.B_Right.Location = new System.Drawing.Point(898, 591); this.B_Right.Name = "B_Right"; this.B_Right.Size = new System.Drawing.Size(32, 32); this.B_Right.TabIndex = 20; @@ -237,7 +238,7 @@ private void InitializeComponent() // // B_Down // - this.B_Down.Location = new System.Drawing.Point(868, 611); + this.B_Down.Location = new System.Drawing.Point(868, 621); this.B_Down.Name = "B_Down"; this.B_Down.Size = new System.Drawing.Size(32, 32); this.B_Down.TabIndex = 22; @@ -249,12 +250,13 @@ private void InitializeComponent() // this.PB_Map.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.PB_Map.ContextMenuStrip = this.CM_Picture; - this.PB_Map.Location = new System.Drawing.Point(821, 338); + this.PB_Map.Location = new System.Drawing.Point(821, 348); this.PB_Map.Name = "PB_Map"; this.PB_Map.Size = new System.Drawing.Size(226, 194); this.PB_Map.TabIndex = 23; this.PB_Map.TabStop = false; this.PB_Map.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PB_Map_MouseDown); + this.PB_Map.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PB_Map_MouseMove); // // CM_Picture // @@ -267,15 +269,28 @@ private void InitializeComponent() // Menu_SavePNG // this.Menu_SavePNG.Name = "Menu_SavePNG"; - this.Menu_SavePNG.Size = new System.Drawing.Size(155, 22); + this.Menu_SavePNG.Size = new System.Drawing.Size(100, 22); this.Menu_SavePNG.Text = "Save .png"; this.Menu_SavePNG.Click += new System.EventHandler(this.Menu_SavePNG_Click); // + // CHK_SnapToAcre + // + this.CHK_SnapToAcre.AutoSize = true; + this.CHK_SnapToAcre.Checked = true; + this.CHK_SnapToAcre.CheckState = System.Windows.Forms.CheckState.Checked; + this.CHK_SnapToAcre.Location = new System.Drawing.Point(820, 325); + this.CHK_SnapToAcre.Name = "CHK_SnapToAcre"; + this.CHK_SnapToAcre.Size = new System.Drawing.Size(167, 17); + this.CHK_SnapToAcre.TabIndex = 24; + this.CHK_SnapToAcre.Text = "Snap to nearest Acre on Click"; + this.CHK_SnapToAcre.UseVisualStyleBackColor = true; + // // TerrainEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1061, 822); + this.Controls.Add(this.CHK_SnapToAcre); this.Controls.Add(this.PB_Map); this.Controls.Add(this.B_Down); this.Controls.Add(this.B_Right); @@ -333,5 +348,6 @@ private void InitializeComponent() private System.Windows.Forms.PictureBox PB_Map; private System.Windows.Forms.ContextMenuStrip CM_Picture; private System.Windows.Forms.ToolStripMenuItem Menu_SavePNG; + private System.Windows.Forms.CheckBox CHK_SnapToAcre; } } \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/TerrainEditor.cs b/NHSE.WinForms/Subforms/TerrainEditor.cs index 4480429..1727781 100644 --- a/NHSE.WinForms/Subforms/TerrainEditor.cs +++ b/NHSE.WinForms/Subforms/TerrainEditor.cs @@ -14,7 +14,11 @@ public partial class TerrainEditor : Form private readonly Button[] Grid; private readonly TerrainManager Terrain; + private const int GridWidth = TerrainManager.GridWidth; + private const int GridHeight = TerrainManager.GridHeight; + private const int SquareSize = 50; + private const int MapScale = 2; public TerrainEditor(MainSave sav) { @@ -32,19 +36,47 @@ public TerrainEditor(MainSave sav) ReloadMap(); } - private int AcreIndex => CB_Acre.SelectedIndex; - private void ChangeAcre(object sender, EventArgs e) => LoadGrid(AcreIndex); - private void ReloadMap() => PB_Map.Image = TerrainSprite.CreateMap(Terrain, 2, AcreIndex); + private int X; + private int Y; - private void LoadGrid(int index) + private int AcreIndex => CB_Acre.SelectedIndex; + + private void ChangeAcre(object sender, EventArgs e) => ChangeViewToAcre(AcreIndex); + + private void ChangeViewToAcre(int acre) { - for (int i = 0; i < TerrainManager.AcreSize; i++) + X = (acre % TerrainManager.AcreWidth) * GridWidth; + Y = (acre / TerrainManager.AcreWidth) * GridHeight; + + LoadGrid(X, Y); + UpdateArrowVisibility(acre); + } + + private void ReloadMap() => PB_Map.Image = TerrainSprite.CreateMap(Terrain, MapScale, X, Y); + + private void LoadGrid(int topX, int topY) + { + for (int x = 0; x < GridWidth; x++) { - var b = Grid[i]; - var tile = Terrain.GetAcreTile(index, i); - RefreshTile(b, tile); + for (int y = 0; y < GridHeight; y++) + { + var i = (y * GridWidth) + x; + var rx = topX + x; + var ry = topY + y; + var ri = TerrainManager.GetIndex(rx, ry); + var b = Grid[i]; + if (ri >= Terrain.Tiles.Length) + { + b.Visible = false; + } + else + { + b.Visible = true; + var tile = Terrain.GetTile(rx, ry); + RefreshTile(b, tile); + } + } } - UpdateArrowVisibility(index); ReloadMap(); } @@ -178,7 +210,7 @@ private void B_ZeroElevation_Click(object sender, EventArgs e) return; foreach (var t in Terrain.Tiles) t.Elevation = 0; - LoadGrid(AcreIndex); + LoadGrid(X=0, Y=0); System.Media.SystemSounds.Asterisk.Play(); } @@ -188,7 +220,7 @@ private void B_ClearAll_Click(object sender, EventArgs e) return; foreach (var t in Terrain.Tiles) t.Clear(); - LoadGrid(AcreIndex); + LoadGrid(X=0, Y=0); System.Media.SystemSounds.Asterisk.Play(); } @@ -245,7 +277,7 @@ private void B_ImportAcre_Click(object sender, EventArgs e) var data = File.ReadAllBytes(path); Terrain.ImportAcre(AcreIndex, data); - LoadGrid(AcreIndex); + ChangeViewToAcre(AcreIndex); System.Media.SystemSounds.Asterisk.Play(); } @@ -271,7 +303,7 @@ private void B_ImportAllAcres_Click(object sender, EventArgs e) var data = File.ReadAllBytes(path); Terrain.ImportAllAcres(data); - LoadGrid(AcreIndex); + ChangeViewToAcre(AcreIndex); System.Media.SystemSounds.Asterisk.Play(); } @@ -297,16 +329,51 @@ private void Menu_SavePNG_Click(object sender, EventArgs e) bmp.Save(sfd.FileName, ImageFormat.Png); } - private void PB_Map_MouseDown(object sender, MouseEventArgs e) + private void PB_Map_MouseDown(object sender, MouseEventArgs e) => ClickMapAt(e, true); + + private void ClickMapAt(MouseEventArgs e, bool skipLagCheck) { - var x = e.X / (2 * TerrainManager.GridWidth); - var y = e.Y / (2 * TerrainManager.GridHeight); + const int maxX = ((TerrainManager.AcreWidth - 1) * GridWidth); + const int maxY = ((TerrainManager.AcreHeight - 1) * GridHeight); - var index = (y * TerrainManager.AcreWidth) + x; - var clamp = Math.Max(0, Math.Min((TerrainManager.AcreHeight * TerrainManager.AcreWidth) - 1, index)); + int center = CHK_SnapToAcre.Checked ? 0 : GridWidth / 2; + var x = Math.Max(0, Math.Min((e.X / MapScale) - center, maxX)); + var y = Math.Max(0, Math.Min((e.Y / MapScale) - center, maxY)); - if (AcreIndex != clamp) - CB_Acre.SelectedIndex = clamp; + var acre = TerrainManager.GetAcre(x, y); + bool sameAcre = AcreIndex == acre; + if (!skipLagCheck) + { + if (CHK_SnapToAcre.Checked) + { + if (sameAcre) + return; + } + else + { + const int delta = 0; // disabled = 0 + var dx = Math.Abs(X - x); + var dy = Math.Abs(Y - y); + if (dx <= delta && dy <= delta && !sameAcre) + return; + } + } + + if (!CHK_SnapToAcre.Checked) + { + LoadGrid(X = x, Y = y); + return; + } + + if (!sameAcre) + CB_Acre.SelectedIndex = acre; + } + + private void PB_Map_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) + return; + ClickMapAt(e, false); } } }