using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Windows.Forms; using NHSE.Core; using NHSE.Sprites; namespace NHSE.WinForms { public partial class TerrainEditor : Form { private readonly MainSave SAV; private readonly Button[] Grid; private readonly TerrainManager Terrain; private int GridWidth => Terrain.GridWidth; private int GridHeight => Terrain.GridHeight; private const int SquareSize = 50; private const int MapScale = 2; public TerrainEditor(MainSave sav) { InitializeComponent(); this.TranslateInterface(GameInfo.CurrentLanguage); SAV = sav; Terrain = new TerrainManager(SAV.GetTerrain()); Grid = GenerateGrid(GridWidth, GridHeight); foreach (var acre in MapGrid.Acres) CB_Acre.Items.Add(acre.Name); PG_Tile.SelectedObject = new TerrainTile(); CB_Acre.SelectedIndex = 0; ReloadMap(); } private int X; private int Y; private int AcreIndex => CB_Acre.SelectedIndex; private void ChangeAcre(object sender, EventArgs e) => ChangeViewToAcre(AcreIndex); private void ChangeViewToAcre(int acre) { Terrain.GetViewAnchorCoordinates(acre, out X, out Y); 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++) { for (int y = 0; y < GridHeight; y++) { var controlIndex = (y * GridWidth) + x; var b = Grid[controlIndex]; var rx = topX + x; var ry = topY + y; var tile = Terrain.GetTile(rx, ry); RefreshTile(b, tile); } } ReloadMap(); } private void UpdateArrowVisibility(int index) { B_Up.Enabled = index >= MapGrid.AcreWidth; B_Down.Enabled = index < MapGrid.AcreWidth * (MapGrid.AcreHeight - 1); B_Left.Enabled = index % MapGrid.AcreWidth != 0; B_Right.Enabled = index % MapGrid.AcreWidth != MapGrid.AcreWidth - 1; } private Button[] GenerateGrid(int w, int h) { var grid = new Button[w * h]; int i = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { var item = CreateGridItem(index: i, x, y); FLP_Tile.Controls.Add(item); grid[i++] = item; } var last = grid[i - 1]; FLP_Tile.SetFlowBreak(last, true); } return grid; } private Button CreateGridItem(int index, int x, int y) { var button = new Button { Name = index.ToString(), Text = $"{index:000} ({x},{y})", Size = new Size(SquareSize, SquareSize), Padding = Padding.Empty, Margin = Padding.Empty, ContextMenuStrip = CM_Click, FlatStyle = FlatStyle.Flat, }; button.Click += (sender, args) => { var tile = GetTile(index); switch (ModifierKeys) { default: ViewTile(tile); return; case Keys.Shift: SetTile(tile, button); return; case Keys.Alt: DeleteTile(tile, button); return; } }; return button; } private void ViewTile(TerrainTile tile) { var pgt = (TerrainTile)PG_Tile.SelectedObject; pgt.CopyFrom(tile); PG_Tile.SelectedObject = pgt; } private void SetTile(TerrainTile tile, Control obj) { var pgt = (TerrainTile)PG_Tile.SelectedObject; tile.CopyFrom(pgt); RefreshTile(obj, tile); ReloadMap(); } private void DeleteTile(TerrainTile tile, Control obj) { tile.Clear(); RefreshTile(obj, tile); ReloadMap(); } private void B_Cancel_Click(object sender, EventArgs e) => Close(); private void B_Save_Click(object sender, EventArgs e) { SAV.SetTerrain(Terrain.Tiles); Close(); } private void Menu_View_Click(object sender, EventArgs e) { GetTile(sender, out var tile, out _); ViewTile(tile); } private void Menu_Set_Click(object sender, EventArgs e) { GetTile(sender, out var tile, out var obj); SetTile(tile, obj); } private void Menu_Reset_Click(object sender, EventArgs e) { GetTile(sender, out var tile, out var obj); DeleteTile(tile, obj); } private void GetTile(object sender, out TerrainTile tile, out Button obj) { obj = WinFormsUtil.GetUnderlyingControl