From 33b9e7f17029e8f88b7e791ec35a7e1aebc74cd0 Mon Sep 17 00:00:00 2001 From: Kurt Date: Tue, 28 Apr 2020 21:08:57 -0700 Subject: [PATCH] Show terrain map behind field item view Adds a transparency slider to have the field items fade so you can see the underlying terrain tile. Not really optimized (allocates every time), but it should be fine for now. Make the None item transparent, so that the entire map bleeds through (clear clarity). --- NHSE.Sprites/Field/FieldItemSprite.cs | 2 +- NHSE.Sprites/Field/FieldItemSpriteDrawer.cs | 9 +++-- NHSE.Sprites/Field/TerrainSprite.cs | 18 ++++++++++ NHSE.Sprites/Util/ImageUtil.cs | 9 +++++ .../Subforms/Map/FieldItemEditor.Designer.cs | 16 +++++++++ NHSE.WinForms/Subforms/Map/FieldItemEditor.cs | 35 +++++++++++++++---- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/NHSE.Sprites/Field/FieldItemSprite.cs b/NHSE.Sprites/Field/FieldItemSprite.cs index 9123208..10c665c 100644 --- a/NHSE.Sprites/Field/FieldItemSprite.cs +++ b/NHSE.Sprites/Field/FieldItemSprite.cs @@ -57,7 +57,7 @@ public static Color GetItemColor(FieldItem item) { var kind = ItemInfo.GetItemKind(item); if (kind == ItemKind.Unknown) - return item.DisplayItemId == FieldItem.NONE ? Color.LimeGreen : Color.DarkGreen; + return item.DisplayItemId == FieldItem.NONE ? Color.Transparent : Color.DarkGreen; return Colors[(int)kind]; } diff --git a/NHSE.Sprites/Field/FieldItemSpriteDrawer.cs b/NHSE.Sprites/Field/FieldItemSpriteDrawer.cs index 5598653..d23c0d5 100644 --- a/NHSE.Sprites/Field/FieldItemSpriteDrawer.cs +++ b/NHSE.Sprites/Field/FieldItemSpriteDrawer.cs @@ -60,7 +60,7 @@ private static void LoadPixelsFromLayer(FieldItemLayer layer, int x0, int y0, in } // non-allocation image generator - public static Bitmap GetBitmapLayerAcre(FieldItemLayer layer, int x0, int y0, int scale, int[] acre1, int[] acreScale, Bitmap dest) + public static Bitmap GetBitmapLayerAcre(FieldItemLayer layer, int x0, int y0, int scale, int[] acre1, int[] acreScale, Bitmap dest, int transparency = -1) { var w = layer.GridWidth; var h = layer.GridHeight; @@ -69,6 +69,9 @@ public static Bitmap GetBitmapLayerAcre(FieldItemLayer layer, int x0, int y0, in h *= scale; ImageUtil.ScalePixelImage(acre1, acreScale, w, h, scale); + if (transparency >> 24 != 0xFF) + ImageUtil.SetAllTransparencyTo(acreScale, transparency); + // draw symbols over special items now? DrawDirectionals(acreScale, layer, w, x0, y0, scale); @@ -185,9 +188,11 @@ public static Bitmap GetBitmapLayer(FieldItemLayer layer, int x, int y, int scal return DrawViewReticle(map, layer, x, y, scale); } - public static Bitmap GetBitmapLayer(FieldItemLayer layer, int x, int y, int[] data, Bitmap dest) + public static Bitmap GetBitmapLayer(FieldItemLayer layer, int x, int y, int[] data, Bitmap dest, int transparency = -1) { LoadBitmapLayer(layer.Tiles, data, layer.MapWidth, layer.MapHeight); + if (transparency >> 24 != 0xFF) + ImageUtil.SetAllTransparencyTo(data, transparency); ImageUtil.SetBitmapData(dest, data); return DrawViewReticle(dest, layer, x, y); } diff --git a/NHSE.Sprites/Field/TerrainSprite.cs b/NHSE.Sprites/Field/TerrainSprite.cs index c41b91e..451acc7 100644 --- a/NHSE.Sprites/Field/TerrainSprite.cs +++ b/NHSE.Sprites/Field/TerrainSprite.cs @@ -142,5 +142,23 @@ private static void GetBuildingCoordinate(MapGrid g, ushort bx, ushort by, int s x = (int) (((bx / 2f) - buildingShift) * scale); y = (int) (((by / 2f) - buildingShift) * scale); } + + public static Image GetAcre(in int topX, in int topY, TerrainManager terrain, int acreScale) + { + int[] data = new int[16 * 16]; + int index = 0; + for (int y = 0; y < 16; y++) + { + var yi = y + topY; + for (int x = 0; x < 16; x++, index++) + { + var tile = terrain.GetTile(x + topX, yi); + data[index] = GetTileColor(tile).ToArgb(); + } + } + + var final = ImageUtil.ScalePixelImage(data, acreScale, 16, 16, out int fw, out int fh); + return ImageUtil.GetBitmap(final, fw, fh); + } } } diff --git a/NHSE.Sprites/Util/ImageUtil.cs b/NHSE.Sprites/Util/ImageUtil.cs index a34b32c..26772fd 100644 --- a/NHSE.Sprites/Util/ImageUtil.cs +++ b/NHSE.Sprites/Util/ImageUtil.cs @@ -108,5 +108,14 @@ public static void ScalePixelImage(int[] data, int[] scaled, int fW, int fH, int Array.Copy(scaled, baseIndex, scaled, baseIndex + (y1 * fW), fW); } } + + /// + /// Sets a bitwise and of the requested transparency; this is assuming the pixel value is 0xFF_xx_xx_xx. Single operation laziness! + /// + public static void SetAllTransparencyTo(int[] data, int trans) + { + for (int i = 0; i < data.Length; i++) + data[i] &= trans; + } } } diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs index f8930ae..652cb95 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs @@ -65,12 +65,14 @@ private void InitializeComponent() this.B_RemoveObjects = new System.Windows.Forms.Button(); 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.CM_Click.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.PB_Map)).BeginInit(); this.CM_Picture.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.NUD_Layer)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PB_Acre)).BeginInit(); this.GB_Remove.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.TR_Transparency)).BeginInit(); this.SuspendLayout(); // // B_Cancel @@ -420,11 +422,23 @@ private void InitializeComponent() this.B_RemovePlacedItems.UseVisualStyleBackColor = true; this.B_RemovePlacedItems.Click += new System.EventHandler(this.B_RemovePlacedItems_Click); // + // TR_Transparency + // + this.TR_Transparency.Location = new System.Drawing.Point(535, 250); + this.TR_Transparency.Maximum = 100; + this.TR_Transparency.Name = "TR_Transparency"; + this.TR_Transparency.Size = new System.Drawing.Size(226, 45); + this.TR_Transparency.TabIndex = 36; + this.TR_Transparency.TickFrequency = 10; + this.TR_Transparency.Value = 90; + this.TR_Transparency.Scroll += new System.EventHandler(this.TR_Transparency_Scroll); + // // 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.TR_Transparency); this.Controls.Add(this.GB_Remove); this.Controls.Add(this.PB_Acre); this.Controls.Add(this.L_Layer); @@ -458,6 +472,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.NUD_Layer)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.PB_Acre)).EndInit(); this.GB_Remove.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.TR_Transparency)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -499,5 +514,6 @@ private void InitializeComponent() private System.Windows.Forms.Button B_RemoveObjects; private System.Windows.Forms.GroupBox GB_Remove; private System.Windows.Forms.Button B_RemovePlacedItems; + private System.Windows.Forms.TrackBar TR_Transparency; } } \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs index e1c77a1..3f366a7 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs @@ -24,6 +24,8 @@ public partial class FieldItemEditor : Form private readonly int[] Map; private readonly Bitmap MapReticle; + private readonly TerrainManager Terrain; + private int X; private int Y; @@ -43,6 +45,9 @@ public FieldItemEditor(MainSave sav) Map = new int[l1.MapWidth * l1.MapHeight * MapScale * MapScale]; MapReticle = new Bitmap(l1.MapWidth * MapScale, l1.MapHeight * MapScale); + Terrain = new TerrainManager(sav.GetTerrain()); + PB_Map.BackgroundImage = TerrainSprite.CreateMap(Terrain, 2); + foreach (var acre in MapGrid.Acres) CB_Acre.Items.Add(acre.Name); @@ -65,19 +70,29 @@ private void ChangeViewToAcre(int acre) private void ReloadMap() { - PB_Map.Image = FieldItemSpriteDrawer.GetBitmapLayer(Layer, X, Y, Map, MapReticle); + var transparency = TR_Transparency.Value / 100d; + var t = ((int)(0xFF * transparency) << 24) | 0x00FF_FFFF; + PB_Map.Image = FieldItemSpriteDrawer.GetBitmapLayer(Layer, X, Y, Map, MapReticle, t); } private void LoadGrid(int topX, int topY) { ReloadGrid(Layer, topX, topY); + ReloadBackground(topX, topY); UpdateArrowVisibility(); ReloadMap(); } + private void ReloadBackground(int topX, int topY) + { + PB_Acre.BackgroundImage = TerrainSprite.GetAcre(topX/2, topY/2, Terrain, AcreScale * 2); + } + private void ReloadGrid(FieldItemLayer layer, int topX, int topY) { - PB_Acre.Image = FieldItemSpriteDrawer.GetBitmapLayerAcre(layer, topX, topY, AcreScale, Scale1, ScaleX, ScaleAcre); + var transparency = TR_Transparency.Value / 100d; + var t = ((int) (0xFF * transparency) << 24) | 0x00FF_FFFF; + PB_Acre.Image = FieldItemSpriteDrawer.GetBitmapLayerAcre(layer, topX, topY, AcreScale, Scale1, ScaleX, ScaleAcre, t); } private void UpdateArrowVisibility() @@ -179,7 +194,7 @@ private void B_Up_Click(object sender, EventArgs e) if (ModifierKeys != Keys.Shift) { if (Y != 0) - LoadGrid(X, --Y); + LoadGrid(X, Y -= 2); return; } @@ -191,7 +206,7 @@ private void B_Left_Click(object sender, EventArgs e) if (ModifierKeys != Keys.Shift) { if (X != 0) - LoadGrid(--X, Y); + LoadGrid(X -= 2, Y); return; } @@ -202,8 +217,8 @@ private void B_Right_Click(object sender, EventArgs e) { if (ModifierKeys != Keys.Shift) { - if (X != Layer.MapWidth - 1) - LoadGrid(++X, Y); + if (X != Layer.MapWidth - 2) + LoadGrid(X += 2, Y); return; } @@ -340,6 +355,8 @@ private void ClickMapAt(MouseEventArgs e, bool skipLagCheck) int mY = e.Y; bool centerReticle = CHK_SnapToAcre.Checked; GetViewAnchorCoordinates(mX, mY, out var x, out var y, centerReticle); + x &= 0xFFFE; + y &= 0xFFFE; var acre = layer.GetAcre(x, y); bool sameAcre = AcreIndex == acre; @@ -431,5 +448,11 @@ private void Remove(Control sender, Func removal) private void B_RemovePlacedItems_Click(object sender, EventArgs e) => Remove(B_RemovePlacedItems, Layer.RemoveAllPlacedItems); private void PG_Tile_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) => PG_Tile.SelectedObject = PG_Tile.SelectedObject; + + private void TR_Transparency_Scroll(object sender, EventArgs e) + { + ReloadGrid(Layer, X, Y); + ReloadMap(); + } } }