From c25cd262d4f34aedee6c9abe079d6aa8a18551ed Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 2 May 2020 00:20:44 -0700 Subject: [PATCH] Add automatic delete/set of extension tiles from root Setting a root tile: will fill in the extension tiles Deleting a root tile: will delete all extension tiles (it assumes extension tiles are valid) Add checkbox to prevent overwriting tiles that aren't none (eg if you set a 4x4 and it'd overlap with a 2x2, the program would play a sound indicating that the requested operation was disallowed). Closes #136 -- multi-select with the current drawing setup isn't really feasible. Bulk set/delete addresses the underlying request. --- .../Acres/Terrain/FieldItemLayer.cs | 81 +++++++++++++++++++ .../Structures/Item/FieldItem/FieldItem.cs | 10 +++ NHSE.Core/Structures/Item/ItemSize.cs | 5 +- .../Subforms/Map/FieldItemEditor.Designer.cs | 15 ++++ NHSE.WinForms/Subforms/Map/FieldItemEditor.cs | 45 ++++++++--- 5 files changed, 141 insertions(+), 15 deletions(-) diff --git a/NHSE.Core/Structures/Acres/Terrain/FieldItemLayer.cs b/NHSE.Core/Structures/Acres/Terrain/FieldItemLayer.cs index f963bcc..02a28ac 100644 --- a/NHSE.Core/Structures/Acres/Terrain/FieldItemLayer.cs +++ b/NHSE.Core/Structures/Acres/Terrain/FieldItemLayer.cs @@ -121,5 +121,86 @@ public int RemoveAll(int xmin, int ymin, int width, int height, Func RemoveAll(xmin, ymin, width, height, _ => true); public int RemoveAllPlacedItems(int xmin, int ymin, int width, int height) => RemoveAll(xmin, ymin, width, height, z => z.DisplayItemId != FieldItem.NONE && !FieldItemList.Items.ContainsKey(z.DisplayItemId)); + + public void DeleteExtensionTiles(FieldItem tile, in int x, in int y) + { + var type = ItemInfo.GetItemSize(tile); + var w = type.GetWidth(); + var h = type.GetHeight(); + + if ((tile.Rotation & 1) == 1) + { + var tmp = w; + w = h; + h = tmp; + } + + for (int ix = 0; ix < w; ix++) + { + for (int iy = 0; iy < h; iy++) + { + if (iy == 0 && ix == 0) + continue; + var t = GetTile(x + ix, y + iy); + t.Delete(); + } + } + } + + public void SetExtensionTiles(FieldItem tile, in int x, in int y) + { + var type = ItemInfo.GetItemSize(tile); + var w = type.GetWidth(); + var h = type.GetHeight(); + + if ((tile.Rotation & 1) == 1) + { + var tmp = w; + w = h; + h = tmp; + } + + for (byte ix = 0; ix < w; ix++) + { + for (byte iy = 0; iy < h; iy++) + { + if (iy == 0 && ix == 0) + continue; + var t = GetTile(x + ix, y + iy); + t.SetAsExtension(tile, ix, iy); + } + } + } + + + /// + /// Checks if writing the at the specified and coordinates will overlap with any existing tiles. + /// + /// True if any tile will be overwritten, false if nothing is there. + public bool IsOccupied(FieldItem tile, in int x, in int y) + { + var type = ItemInfo.GetItemSize(tile); + var w = type.GetWidth(); + var h = type.GetHeight(); + + if ((tile.Rotation & 1) == 1) + { + var tmp = w; + w = h; + h = tmp; + } + + for (byte ix = 0; ix < w; ix++) + { + for (byte iy = 0; iy < h; iy++) + { + var t = GetTile(x + ix, y + iy); + if (!t.IsNone) + return true; + } + } + + return false; + } } } diff --git a/NHSE.Core/Structures/Item/FieldItem/FieldItem.cs b/NHSE.Core/Structures/Item/FieldItem/FieldItem.cs index 7b17169..df1f74f 100644 --- a/NHSE.Core/Structures/Item/FieldItem/FieldItem.cs +++ b/NHSE.Core/Structures/Item/FieldItem/FieldItem.cs @@ -76,5 +76,15 @@ public void CopyFrom(IHeldItem item) public static FieldItem[] GetArray(byte[] data) => data.GetArray(SIZE); public static byte[] SetArray(IReadOnlyList data) => data.SetArray(SIZE); + + public void SetAsExtension(FieldItem tile, byte x, byte y) + { + ItemType = EXTENSION; + Rotation = 0; + E03 = 0; + ExtensionX = x; + ExtensionY = y; + ExtensionItemId = tile.ItemId; + } } } diff --git a/NHSE.Core/Structures/Item/ItemSize.cs b/NHSE.Core/Structures/Item/ItemSize.cs index c0e838a..977aecd 100644 --- a/NHSE.Core/Structures/Item/ItemSize.cs +++ b/NHSE.Core/Structures/Item/ItemSize.cs @@ -79,10 +79,9 @@ public static class ItemSizeExtensions {ItemSizeType.S_4_0x4_0_Rug , new ItemSize( 8, 8)}, // 4x4(ラグ) {ItemSizeType.S_5_0x4_0_Rug , new ItemSize(10, 8)}, // 5x4(ラグ) {ItemSizeType.S_5_0x5_0_Rug , new ItemSize(10, 10)}, // 5x5(ラグ) - }; - public static int GetWidth(this ItemSizeType s) => Dictionary.TryGetValue(s, out var val) ? val.Width : 1; - public static int GetHeight(this ItemSizeType s) => Dictionary.TryGetValue(s, out var val) ? val.Height : 1; + public static int GetWidth(this ItemSizeType s) => Dictionary.TryGetValue(s, out var val) ? val.Width : 2; + public static int GetHeight(this ItemSizeType s) => Dictionary.TryGetValue(s, out var val) ? val.Height : 2; } } diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs index 652cb95..0a3726b 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs @@ -66,6 +66,7 @@ private void InitializeComponent() this.GB_Remove = new System.Windows.Forms.GroupBox(); this.B_RemovePlacedItems = new System.Windows.Forms.Button(); this.TR_Transparency = new System.Windows.Forms.TrackBar(); + this.CHK_NoOverwrite = new System.Windows.Forms.CheckBox(); this.CM_Click.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.PB_Map)).BeginInit(); this.CM_Picture.SuspendLayout(); @@ -433,11 +434,24 @@ private void InitializeComponent() this.TR_Transparency.Value = 90; this.TR_Transparency.Scroll += new System.EventHandler(this.TR_Transparency_Scroll); // + // CHK_NoOverwrite + // + this.CHK_NoOverwrite.AutoSize = true; + this.CHK_NoOverwrite.Checked = true; + this.CHK_NoOverwrite.CheckState = System.Windows.Forms.CheckState.Checked; + this.CHK_NoOverwrite.Location = new System.Drawing.Point(534, 416); + this.CHK_NoOverwrite.Name = "CHK_NoOverwrite"; + this.CHK_NoOverwrite.Size = new System.Drawing.Size(173, 17); + this.CHK_NoOverwrite.TabIndex = 37; + this.CHK_NoOverwrite.Text = "Prevent Writing Occupied Tiles"; + this.CHK_NoOverwrite.UseVisualStyleBackColor = true; + // // FieldItemEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(981, 537); + this.Controls.Add(this.CHK_NoOverwrite); this.Controls.Add(this.TR_Transparency); this.Controls.Add(this.GB_Remove); this.Controls.Add(this.PB_Acre); @@ -515,5 +529,6 @@ private void InitializeComponent() private System.Windows.Forms.GroupBox GB_Remove; private System.Windows.Forms.Button B_RemovePlacedItems; private System.Windows.Forms.TrackBar TR_Transparency; + private System.Windows.Forms.CheckBox CHK_NoOverwrite; } } \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs index dd8ea5f..75bd34f 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs @@ -112,22 +112,22 @@ private void UpdateArrowVisibility() private void PB_Acre_MouseClick(object sender, MouseEventArgs e) { - var tile = GetTile(Layer, e); + var tile = GetTile(Layer, e, out var x, out var y); switch (ModifierKeys) { default: ViewTile(tile); return; - case Keys.Shift: SetTile(tile); return; - case Keys.Alt: DeleteTile(tile); return; + case Keys.Shift: SetTile(tile, x, y); return; + case Keys.Alt: DeleteTile(tile, x, y); return; } } private int HoverX; private int HoverY; - private FieldItem GetTile(FieldItemLayer layer, MouseEventArgs e) + private FieldItem GetTile(FieldItemLayer layer, MouseEventArgs e, out int x, out int y) { SetHoveredItem(e); - return layer.GetTile(X + HoverX, Y + HoverY); + return layer.GetTile(x = X + HoverX, y = Y + HoverY); } private void SetHoveredItem(MouseEventArgs e) @@ -139,7 +139,7 @@ private void SetHoveredItem(MouseEventArgs e) private void PB_Acre_MouseMove(object sender, MouseEventArgs e) { var oldTile = Layer.GetTile(X + HoverX, Y + HoverY); - var tile = GetTile(Layer, e); + var tile = GetTile(Layer, e, out _, out _); if (tile == oldTile) return; var str = GameInfo.Strings; @@ -154,17 +154,34 @@ private void ViewTile(FieldItem tile) PG_Tile.SelectedObject = pgt; } - private void SetTile(FieldItem tile) + private void SetTile(FieldItem tile, int x, int y) { var pgt = (FieldItem)PG_Tile.SelectedObject; + if (CHK_NoOverwrite.Checked && Layer.IsOccupied(pgt, x, y)) + { + System.Media.SystemSounds.Asterisk.Play(); + return; + } + + // Clean up original placed data + if (tile.IsRoot) + Layer.DeleteExtensionTiles(tile, x, y); + + // Set new placed data + if (pgt.IsRoot) + Layer.SetExtensionTiles(pgt, x, y); tile.CopyFrom(pgt); + ReloadGrid(Layer, X, Y); ReloadMap(); } - private void DeleteTile(FieldItem tile) + private void DeleteTile(FieldItem tile, int x, int y) { + if (tile.IsRoot) + Layer.DeleteExtensionTiles(tile, x, y); tile.Delete(); + ReloadGrid(Layer, X, Y); ReloadMap(); } @@ -186,14 +203,18 @@ private void Menu_View_Click(object sender, EventArgs e) private void Menu_Set_Click(object sender, EventArgs e) { - var tile = Layer.GetTile(X + HoverX, Y + HoverY); - SetTile(tile); + int x = X + HoverX; + int y = Y + HoverY; + var tile = Layer.GetTile(x, y); + SetTile(tile, x, y); } private void Menu_Reset_Click(object sender, EventArgs e) { - var tile = Layer.GetTile(X + HoverX, Y + HoverY); - DeleteTile(tile); + int x = X + HoverX; + int y = Y + HoverY; + var tile = Layer.GetTile(x, y); + DeleteTile(tile, x, y); } private void B_Up_Click(object sender, EventArgs e)