C&C Remastered Map Editor
Initial commit of C&C Remastered Map Editor code
This commit is contained in:
parent
1f6350fe6e
commit
e37e174be1
289 changed files with 80922 additions and 7 deletions
502
CnCTDRAMapEditor/Tools/BuildingTool.cs
Normal file
502
CnCTDRAMapEditor/Tools/BuildingTool.cs
Normal file
|
@ -0,0 +1,502 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Render;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class BuildingTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox buildingTypeComboBox;
|
||||
private readonly MapPanel buildingTypeMapPanel;
|
||||
private readonly ObjectProperties objectProperties;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private readonly Building mockBuilding;
|
||||
|
||||
private Building selectedBuilding;
|
||||
private ObjectPropertiesPopup selectedObjectProperties;
|
||||
private Point selectedBuildingPivot;
|
||||
|
||||
private BuildingType selectedBuildingType;
|
||||
private BuildingType SelectedBuildingType
|
||||
{
|
||||
get => selectedBuildingType;
|
||||
set
|
||||
{
|
||||
if (selectedBuildingType != value)
|
||||
{
|
||||
if (placementMode && (selectedBuildingType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedBuildingType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
selectedBuildingType = value;
|
||||
buildingTypeComboBox.SelectedValue = selectedBuildingType;
|
||||
|
||||
if (placementMode && (selectedBuildingType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedBuildingType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
mockBuilding.Type = selectedBuildingType;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BuildingTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox buildingTypeComboBox, MapPanel buildingTypeMapPanel, ObjectProperties objectProperties, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
mockBuilding = new Building()
|
||||
{
|
||||
Type = buildingTypeComboBox.Types.First() as BuildingType,
|
||||
House = map.Houses.First().Type,
|
||||
Strength = 256,
|
||||
Direction = map.DirectionTypes.Where(d => d.Equals(FacingType.North)).First()
|
||||
};
|
||||
mockBuilding.PropertyChanged += MockBuilding_PropertyChanged;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseDoubleClick += MapPanel_MouseDoubleClick;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += UnitTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += UnitTool_KeyUp;
|
||||
|
||||
this.buildingTypeComboBox = buildingTypeComboBox;
|
||||
this.buildingTypeComboBox.SelectedIndexChanged += UnitTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.buildingTypeMapPanel = buildingTypeMapPanel;
|
||||
this.buildingTypeMapPanel.BackColor = Color.White;
|
||||
this.buildingTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
this.objectProperties = objectProperties;
|
||||
this.objectProperties.Object = mockBuilding;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedBuildingType = mockBuilding.Type;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Control.ModifierKeys != Keys.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.Metrics.GetCell(navigationWidget.MouseCell, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Building building)
|
||||
{
|
||||
selectedBuilding = null;
|
||||
selectedBuildingPivot = Point.Empty;
|
||||
|
||||
selectedObjectProperties?.Close();
|
||||
selectedObjectProperties = new ObjectPropertiesPopup(objectProperties.Plugin, building);
|
||||
selectedObjectProperties.Closed += (cs, ce) =>
|
||||
{
|
||||
navigationWidget.Refresh();
|
||||
};
|
||||
|
||||
building.PropertyChanged += SelectedBuilding_PropertyChanged;
|
||||
|
||||
selectedObjectProperties.Show(mapPanel, mapPanel.PointToClient(Control.MousePosition));
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MockBuilding_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if ((mockBuilding.Type == null) || !mockBuilding.Type.HasTurret)
|
||||
{
|
||||
mockBuilding.Direction = map.DirectionTypes.Where(d => d.Equals(FacingType.North)).First();
|
||||
}
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
|
||||
private void SelectedBuilding_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
mapPanel.Invalidate(map, sender as Building);
|
||||
}
|
||||
|
||||
private void UnitTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedBuildingType = buildingTypeComboBox.SelectedValue as BuildingType;
|
||||
}
|
||||
|
||||
private void UnitTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void UnitTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddBuilding(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveBuilding(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SelectBuilding(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
PickBuilding(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (selectedBuilding != null)
|
||||
{
|
||||
selectedBuilding = null;
|
||||
selectedBuildingPivot = Point.Empty;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedBuildingType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(e.OldCell, SelectedBuildingType.OverlapBounds.Size));
|
||||
mapPanel.Invalidate(map, new Rectangle(e.NewCell, SelectedBuildingType.OverlapBounds.Size));
|
||||
}
|
||||
}
|
||||
else if (selectedBuilding != null)
|
||||
{
|
||||
var oldLocation = map.Technos[selectedBuilding].Value;
|
||||
var newLocation = new Point(Math.Max(0, e.NewCell.X - selectedBuildingPivot.X), Math.Max(0, e.NewCell.Y - selectedBuildingPivot.Y));
|
||||
mapPanel.Invalidate(map, selectedBuilding);
|
||||
map.Buildings.Remove(selectedBuilding);
|
||||
if (map.Technos.CanAdd(newLocation, selectedBuilding, selectedBuilding.Type.BaseOccupyMask) &&
|
||||
map.Buildings.Add(newLocation, selectedBuilding))
|
||||
{
|
||||
mapPanel.Invalidate(map, selectedBuilding);
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Buildings.Add(oldLocation, selectedBuilding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddBuilding(Point location)
|
||||
{
|
||||
if (SelectedBuildingType != null)
|
||||
{
|
||||
var building = mockBuilding.Clone();
|
||||
if (map.Technos.CanAdd(location, building, building.Type.BaseOccupyMask) && map.Buildings.Add(location, building))
|
||||
{
|
||||
if (building.BasePriority >= 0)
|
||||
{
|
||||
foreach (var baseBuilding in map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0))
|
||||
{
|
||||
if ((building != baseBuilding) && (baseBuilding.BasePriority >= building.BasePriority))
|
||||
{
|
||||
baseBuilding.BasePriority++;
|
||||
}
|
||||
}
|
||||
|
||||
var baseBuildings = map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0).OrderBy(x => x.BasePriority).ToArray();
|
||||
for (var i = 0; i < baseBuildings.Length; ++i)
|
||||
{
|
||||
baseBuildings[i].BasePriority = i;
|
||||
}
|
||||
|
||||
foreach (var baseBuilding in map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0))
|
||||
{
|
||||
mapPanel.Invalidate(map, baseBuilding);
|
||||
}
|
||||
}
|
||||
|
||||
mapPanel.Invalidate(map, building);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveBuilding(Point location)
|
||||
{
|
||||
if (map.Technos[location] is Building building)
|
||||
{
|
||||
mapPanel.Invalidate(map, building);
|
||||
map.Buildings.Remove(building);
|
||||
|
||||
if (building.BasePriority >= 0)
|
||||
{
|
||||
var baseBuildings = map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0).OrderBy(x => x.BasePriority).ToArray();
|
||||
for (var i = 0; i < baseBuildings.Length; ++i)
|
||||
{
|
||||
baseBuildings[i].BasePriority = i;
|
||||
}
|
||||
|
||||
foreach (var baseBuilding in map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0))
|
||||
{
|
||||
mapPanel.Invalidate(map, baseBuilding);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedBuildingType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, SelectedBuildingType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedBuildingType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, SelectedBuildingType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickBuilding(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Building building)
|
||||
{
|
||||
SelectedBuildingType = building.Type;
|
||||
mockBuilding.House = building.House;
|
||||
mockBuilding.Strength = building.Strength;
|
||||
mockBuilding.Direction = building.Direction;
|
||||
mockBuilding.Trigger = building.Trigger;
|
||||
mockBuilding.BasePriority = building.BasePriority;
|
||||
mockBuilding.IsPrebuilt = building.IsPrebuilt;
|
||||
mockBuilding.Sellable = building.Sellable;
|
||||
mockBuilding.Rebuild = building.Rebuild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectBuilding(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
selectedBuilding = map.Technos[cell] as Building;
|
||||
selectedBuildingPivot = (selectedBuilding != null) ? (location - (Size)map.Technos[selectedBuilding].Value) : Point.Empty;
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
if (mockBuilding.Type != null)
|
||||
{
|
||||
var render = MapRenderer.Render(plugin.GameType, map.Theater, new Point(0, 0), Globals.TileSize, Globals.TileScale, mockBuilding);
|
||||
if (!render.Item1.IsEmpty)
|
||||
{
|
||||
var buildingPreview = new Bitmap(render.Item1.Width, render.Item1.Height);
|
||||
using (var g = Graphics.FromImage(buildingPreview))
|
||||
{
|
||||
render.Item2(g);
|
||||
}
|
||||
buildingTypeMapPanel.MapImage = buildingPreview;
|
||||
}
|
||||
else
|
||||
{
|
||||
buildingTypeMapPanel.MapImage = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buildingTypeMapPanel.MapImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place building, Right-Click to remove building";
|
||||
}
|
||||
else if (selectedBuilding != null)
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to move building";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click drag to move building, Double-Click update building properties, Right-Click to pick building";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedBuildingType != null)
|
||||
{
|
||||
var building = mockBuilding.Clone();
|
||||
building.Tint = Color.FromArgb(128, Color.White);
|
||||
if (previewMap.Technos.CanAdd(location, building, building.Type.BaseOccupyMask) && previewMap.Buildings.Add(location, building))
|
||||
{
|
||||
mapPanel.Invalidate(previewMap, building);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var buildingPen = new Pen(Color.Green, 4.0f);
|
||||
var occupyPen = new Pen(Color.Red, 2.0f);
|
||||
foreach (var (topLeft, building) in map.Buildings.OfType<Building>())
|
||||
{
|
||||
var bounds = new Rectangle(
|
||||
new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight),
|
||||
new Size(building.Type.Size.Width * Globals.TileWidth, building.Type.Size.Height * Globals.TileHeight)
|
||||
);
|
||||
graphics.DrawRectangle(buildingPen, bounds);
|
||||
|
||||
for (var y = 0; y < building.Type.BaseOccupyMask.GetLength(0); ++y)
|
||||
{
|
||||
for (var x = 0; x < building.Type.BaseOccupyMask.GetLength(1); ++x)
|
||||
{
|
||||
if (building.Type.BaseOccupyMask[y, x])
|
||||
{
|
||||
var occupyBounds = new Rectangle(
|
||||
new Point((topLeft.X + x) * Globals.TileWidth, (topLeft.Y + y) * Globals.TileHeight),
|
||||
Globals.TileSize
|
||||
);
|
||||
graphics.DrawRectangle(occupyPen, occupyBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseDoubleClick -= MapPanel_MouseDoubleClick;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= UnitTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= UnitTool_KeyUp;
|
||||
|
||||
buildingTypeComboBox.SelectedIndexChanged -= UnitTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
268
CnCTDRAMapEditor/Tools/CellTriggersTool.cs
Normal file
268
CnCTDRAMapEditor/Tools/CellTriggersTool.cs
Normal file
|
@ -0,0 +1,268 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class CellTriggersTool : ViewTool
|
||||
{
|
||||
private readonly ComboBox triggerCombo;
|
||||
|
||||
private readonly Dictionary<int, CellTrigger> undoCellTriggers = new Dictionary<int, CellTrigger>();
|
||||
private readonly Dictionary<int, CellTrigger> redoCellTriggers = new Dictionary<int, CellTrigger>();
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
public CellTriggersTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, ComboBox triggerCombo, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += WaypointsTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += WaypointsTool_KeyUp;
|
||||
|
||||
this.triggerCombo = triggerCombo;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SetCellTrigger(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveCellTrigger(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
|
||||
{
|
||||
PickCellTrigger(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if ((undoCellTriggers.Count > 0) || (redoCellTriggers.Count > 0))
|
||||
{
|
||||
CommitChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void WaypointsTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void WaypointsTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (Control.MouseButtons == MouseButtons.Left)
|
||||
{
|
||||
SetCellTrigger(e.NewCell);
|
||||
}
|
||||
else if (Control.MouseButtons == MouseButtons.Right)
|
||||
{
|
||||
RemoveCellTrigger(e.NewCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCellTrigger(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.CellTriggers[cell] == null)
|
||||
{
|
||||
if (!undoCellTriggers.ContainsKey(cell))
|
||||
{
|
||||
undoCellTriggers[cell] = map.CellTriggers[cell];
|
||||
}
|
||||
|
||||
var cellTrigger = new CellTrigger { Trigger = triggerCombo.SelectedItem as string };
|
||||
map.CellTriggers[cell] = cellTrigger;
|
||||
redoCellTriggers[cell] = cellTrigger;
|
||||
|
||||
mapPanel.Invalidate();
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveCellTrigger(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var cellTrigger = map.CellTriggers[cell];
|
||||
if (cellTrigger != null)
|
||||
{
|
||||
if (!undoCellTriggers.ContainsKey(cell))
|
||||
{
|
||||
undoCellTriggers[cell] = map.CellTriggers[cell];
|
||||
}
|
||||
|
||||
map.CellTriggers[cell] = null;
|
||||
redoCellTriggers[cell] = null;
|
||||
|
||||
mapPanel.Invalidate();
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickCellTrigger(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var cellTrigger = map.CellTriggers[cell];
|
||||
if (cellTrigger != null)
|
||||
{
|
||||
triggerCombo.SelectedItem = cellTrigger.Trigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CommitChange()
|
||||
{
|
||||
var undoCellTriggers2 = new Dictionary<int, CellTrigger>(undoCellTriggers);
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in undoCellTriggers2)
|
||||
{
|
||||
e.Map.CellTriggers[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate();
|
||||
}
|
||||
|
||||
var redoCellTriggers2 = new Dictionary<int, CellTrigger>(redoCellTriggers);
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in redoCellTriggers2)
|
||||
{
|
||||
e.Map.CellTriggers[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate();
|
||||
}
|
||||
|
||||
undoCellTriggers.Clear();
|
||||
redoCellTriggers.Clear();
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to set cell trigger, Right-Click to clear cell trigger";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick cell trigger";
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= WaypointsTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= WaypointsTool_KeyUp;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
123
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.Designer.cs
generated
Normal file
123
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,123 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class CellTriggersToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.triggerCombo = new System.Windows.Forms.ComboBox();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel4
|
||||
//
|
||||
this.tableLayoutPanel4.AutoSize = true;
|
||||
this.tableLayoutPanel4.ColumnCount = 2;
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.Controls.Add(this.label1, 0, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.triggerCombo, 1, 0);
|
||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||
this.tableLayoutPanel4.RowCount = 2;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(218, 118);
|
||||
this.tableLayoutPanel4.TabIndex = 3;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(4, 0);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(58, 38);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Trigger";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// triggerCombo
|
||||
//
|
||||
this.triggerCombo.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.triggerCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.triggerCombo.FormattingEnabled = true;
|
||||
this.triggerCombo.Location = new System.Drawing.Point(70, 5);
|
||||
this.triggerCombo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.triggerCombo.Name = "triggerCombo";
|
||||
this.triggerCombo.Size = new System.Drawing.Size(144, 28);
|
||||
this.triggerCombo.TabIndex = 1;
|
||||
//
|
||||
// CellTriggersToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.ClientSize = new System.Drawing.Size(218, 118);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel4);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(210, 91);
|
||||
this.Name = "CellTriggersToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Cell Triggers";
|
||||
this.tableLayoutPanel4.ResumeLayout(false);
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.ComboBox triggerCombo;
|
||||
}
|
||||
}
|
39
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.cs
Normal file
39
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class CellTriggersToolDialog : Form
|
||||
{
|
||||
public ComboBox TriggerCombo => triggerCombo;
|
||||
|
||||
public CellTriggersToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
120
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.resx
Normal file
120
CnCTDRAMapEditor/Tools/Dialogs/CellTriggersToolDialog.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
121
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.Designer.cs
generated
Normal file
121
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class GenericToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TemplateToolDialog));
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.genericTypeMapPanel = new MobiusEditor.Controls.MapPanel();
|
||||
this.genericTypeComboBox = new MobiusEditor.Controls.TypeComboBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 1;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.genericTypeMapPanel, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.genericTypeComboBox, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(274, 254);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// templateTypeMapPanel
|
||||
//
|
||||
this.genericTypeMapPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.genericTypeMapPanel.Location = new System.Drawing.Point(3, 30);
|
||||
this.genericTypeMapPanel.MaxZoom = 8;
|
||||
this.genericTypeMapPanel.MinZoom = 1;
|
||||
this.genericTypeMapPanel.Name = "templateTypeMapPanel";
|
||||
this.genericTypeMapPanel.Quality = 1;
|
||||
this.genericTypeMapPanel.Size = new System.Drawing.Size(268, 221);
|
||||
this.genericTypeMapPanel.TabIndex = 3;
|
||||
this.genericTypeMapPanel.Zoom = 1;
|
||||
//
|
||||
// templateTypeComboBox
|
||||
//
|
||||
this.genericTypeComboBox.DisplayMember = "Name";
|
||||
this.genericTypeComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.genericTypeComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
|
||||
this.genericTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.genericTypeComboBox.FormattingEnabled = true;
|
||||
this.genericTypeComboBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.genericTypeComboBox.MissingThumbnail = ((System.Drawing.Image)(resources.GetObject("templateTypeComboBox.MissingThumbnail")));
|
||||
this.genericTypeComboBox.Name = "templateTypeComboBox";
|
||||
this.genericTypeComboBox.Size = new System.Drawing.Size(268, 21);
|
||||
this.genericTypeComboBox.TabIndex = 2;
|
||||
this.genericTypeComboBox.ValueMember = "Type";
|
||||
//
|
||||
// TemplateToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(274, 254);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(290, 293);
|
||||
this.Name = "TemplateToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Map";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.TypeComboBox genericTypeComboBox;
|
||||
private Controls.MapPanel genericTypeMapPanel;
|
||||
}
|
||||
}
|
49
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.cs
Normal file
49
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class GenericToolDialog : Form
|
||||
{
|
||||
public TypeComboBox GenericTypeComboBox => genericTypeComboBox;
|
||||
|
||||
public MapPanel GenericTypeMapPanel => genericTypeMapPanel;
|
||||
|
||||
public GenericToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
165
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.resx
Normal file
165
CnCTDRAMapEditor/Tools/Dialogs/GenericToolDialog.resx
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="templateTypeComboBox.MissingThumbnail" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
fwDWYGmBKz70PQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
144
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.Designer.cs
generated
Normal file
144
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,144 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class ObjectToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ObjectToolDialog));
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.objectTypeMapPanel = new MobiusEditor.Controls.MapPanel();
|
||||
this.objectTypeComboBox = new MobiusEditor.Controls.TypeComboBox();
|
||||
this.objectProperties = new MobiusEditor.Controls.ObjectProperties();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 1;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.objectTypeMapPanel, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.objectTypeComboBox, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.objectProperties, 0, 2);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(365, 582);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// objectTypeMapPanel
|
||||
//
|
||||
this.objectTypeMapPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.objectTypeMapPanel.Location = new System.Drawing.Point(4, 35);
|
||||
this.objectTypeMapPanel.MapImage = null;
|
||||
this.objectTypeMapPanel.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.objectTypeMapPanel.MaxZoom = 8;
|
||||
this.objectTypeMapPanel.MinZoom = 1;
|
||||
this.objectTypeMapPanel.Name = "objectTypeMapPanel";
|
||||
this.objectTypeMapPanel.Quality = 1;
|
||||
this.objectTypeMapPanel.Size = new System.Drawing.Size(357, 272);
|
||||
this.objectTypeMapPanel.TabIndex = 3;
|
||||
this.objectTypeMapPanel.Zoom = 1;
|
||||
this.objectTypeMapPanel.ZoomStep = 1;
|
||||
//
|
||||
// objectTypeComboBox
|
||||
//
|
||||
this.objectTypeComboBox.DisplayMember = "Name";
|
||||
this.objectTypeComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.objectTypeComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
|
||||
this.objectTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.objectTypeComboBox.FormattingEnabled = true;
|
||||
this.objectTypeComboBox.Location = new System.Drawing.Point(4, 4);
|
||||
this.objectTypeComboBox.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.objectTypeComboBox.MissingThumbnail = ((System.Drawing.Image)(resources.GetObject("objectTypeComboBox.MissingThumbnail")));
|
||||
this.objectTypeComboBox.Name = "objectTypeComboBox";
|
||||
this.objectTypeComboBox.Size = new System.Drawing.Size(357, 23);
|
||||
this.objectTypeComboBox.TabIndex = 2;
|
||||
this.objectTypeComboBox.ValueMember = "Type";
|
||||
//
|
||||
// objectProperties
|
||||
//
|
||||
this.objectProperties.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.objectProperties.Location = new System.Drawing.Point(5, 316);
|
||||
this.objectProperties.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
|
||||
this.objectProperties.Name = "objectProperties";
|
||||
this.objectProperties.Object = null;
|
||||
this.objectProperties.Size = new System.Drawing.Size(355, 261);
|
||||
this.objectProperties.TabIndex = 4;
|
||||
//
|
||||
// ObjectToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(365, 582);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(381, 528);
|
||||
this.Name = "ObjectToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Map";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.TypeComboBox objectTypeComboBox;
|
||||
private Controls.MapPanel objectTypeMapPanel;
|
||||
private Controls.ObjectProperties objectProperties;
|
||||
}
|
||||
}
|
58
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.cs
Normal file
58
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Interface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class ObjectToolDialog : Form
|
||||
{
|
||||
public TypeComboBox ObjectTypeComboBox => objectTypeComboBox;
|
||||
|
||||
public MapPanel ObjectTypeMapPanel => objectTypeMapPanel;
|
||||
|
||||
public ObjectProperties ObjectProperties => objectProperties;
|
||||
|
||||
public ObjectToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
public ObjectToolDialog(IGamePlugin plugin)
|
||||
: this()
|
||||
{
|
||||
objectProperties.Initialize(plugin, true);
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
165
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.resx
Normal file
165
CnCTDRAMapEditor/Tools/Dialogs/ObjectToolDialog.resx
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="objectTypeComboBox.MissingThumbnail" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
fwDWYGmBKz70PQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
179
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.Designer.cs
generated
Normal file
179
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,179 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class ResourcesToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.totalResourcesLbl = new System.Windows.Forms.Label();
|
||||
this.gemsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.resourceBrushSizeNud = new System.Windows.Forms.NumericUpDown();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel6.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.resourceBrushSizeNud)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel6
|
||||
//
|
||||
this.tableLayoutPanel6.ColumnCount = 2;
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.Controls.Add(this.label10, 0, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.totalResourcesLbl, 1, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.gemsCheckBox, 0, 3);
|
||||
this.tableLayoutPanel6.Controls.Add(this.resourceBrushSizeNud, 1, 2);
|
||||
this.tableLayoutPanel6.Controls.Add(this.label1, 0, 2);
|
||||
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
|
||||
this.tableLayoutPanel6.RowCount = 4;
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel6.Size = new System.Drawing.Size(196, 67);
|
||||
this.tableLayoutPanel6.TabIndex = 1;
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(3, 0);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(88, 13);
|
||||
this.label10.TabIndex = 0;
|
||||
this.label10.Text = "Total Resources:";
|
||||
//
|
||||
// totalResourcesLbl
|
||||
//
|
||||
this.totalResourcesLbl.AutoSize = true;
|
||||
this.totalResourcesLbl.Location = new System.Drawing.Point(97, 0);
|
||||
this.totalResourcesLbl.Name = "totalResourcesLbl";
|
||||
this.totalResourcesLbl.Size = new System.Drawing.Size(13, 13);
|
||||
this.totalResourcesLbl.TabIndex = 1;
|
||||
this.totalResourcesLbl.Text = "0";
|
||||
//
|
||||
// gemsCheckBox
|
||||
//
|
||||
this.gemsCheckBox.AutoSize = true;
|
||||
this.tableLayoutPanel6.SetColumnSpan(this.gemsCheckBox, 2);
|
||||
this.gemsCheckBox.Location = new System.Drawing.Point(3, 42);
|
||||
this.gemsCheckBox.Name = "gemsCheckBox";
|
||||
this.gemsCheckBox.Size = new System.Drawing.Size(53, 17);
|
||||
this.gemsCheckBox.TabIndex = 2;
|
||||
this.gemsCheckBox.Text = "Gems";
|
||||
this.gemsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// resourceBrushSizeNud
|
||||
//
|
||||
this.resourceBrushSizeNud.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.resourceBrushSizeNud.Increment = new decimal(new int[] {
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.resourceBrushSizeNud.Location = new System.Drawing.Point(97, 16);
|
||||
this.resourceBrushSizeNud.Maximum = new decimal(new int[] {
|
||||
9,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.resourceBrushSizeNud.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.resourceBrushSizeNud.Name = "resourceBrushSizeNud";
|
||||
this.resourceBrushSizeNud.Size = new System.Drawing.Size(99, 20);
|
||||
this.resourceBrushSizeNud.TabIndex = 3;
|
||||
this.resourceBrushSizeNud.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(3, 13);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(88, 26);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = "Brush Size";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// ResourcesToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(196, 67);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel6);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(212, 106);
|
||||
this.Name = "ResourcesToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Resources";
|
||||
this.tableLayoutPanel6.ResumeLayout(false);
|
||||
this.tableLayoutPanel6.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.resourceBrushSizeNud)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.Label totalResourcesLbl;
|
||||
private System.Windows.Forms.CheckBox gemsCheckBox;
|
||||
private System.Windows.Forms.NumericUpDown resourceBrushSizeNud;
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
43
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.cs
Normal file
43
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class ResourcesToolDialog : Form
|
||||
{
|
||||
public Label TotalResourcesLbl => totalResourcesLbl;
|
||||
|
||||
public NumericUpDown ResourceBrushSizeNud => resourceBrushSizeNud;
|
||||
|
||||
public CheckBox GemsCheckBox => gemsCheckBox;
|
||||
|
||||
public ResourcesToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
120
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.resx
Normal file
120
CnCTDRAMapEditor/Tools/Dialogs/ResourcesToolDialog.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
130
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.Designer.cs
generated
Normal file
130
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class TemplateToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.templateTypeListView = new System.Windows.Forms.ListView();
|
||||
this.templateTypeMapPanel = new MobiusEditor.Controls.MapPanel();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer1.Location = new System.Drawing.Point(2, 2);
|
||||
this.splitContainer1.Name = "splitContainer1";
|
||||
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
this.splitContainer1.Panel1.Controls.Add(this.templateTypeListView);
|
||||
//
|
||||
// splitContainer1.Panel2
|
||||
//
|
||||
this.splitContainer1.Panel2.Controls.Add(this.templateTypeMapPanel);
|
||||
this.splitContainer1.Size = new System.Drawing.Size(270, 545);
|
||||
this.splitContainer1.SplitterDistance = 275;
|
||||
this.splitContainer1.TabIndex = 7;
|
||||
//
|
||||
// templateTypeListView
|
||||
//
|
||||
this.templateTypeListView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.templateTypeListView.HideSelection = false;
|
||||
this.templateTypeListView.Location = new System.Drawing.Point(0, 0);
|
||||
this.templateTypeListView.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.templateTypeListView.MultiSelect = false;
|
||||
this.templateTypeListView.Name = "templateTypeListView";
|
||||
this.templateTypeListView.Size = new System.Drawing.Size(270, 275);
|
||||
this.templateTypeListView.TabIndex = 7;
|
||||
this.templateTypeListView.UseCompatibleStateImageBehavior = false;
|
||||
//
|
||||
// templateTypeMapPanel
|
||||
//
|
||||
this.templateTypeMapPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.templateTypeMapPanel.Location = new System.Drawing.Point(0, 0);
|
||||
this.templateTypeMapPanel.MapImage = null;
|
||||
this.templateTypeMapPanel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.templateTypeMapPanel.MaxZoom = 8;
|
||||
this.templateTypeMapPanel.MinZoom = 1;
|
||||
this.templateTypeMapPanel.Name = "templateTypeMapPanel";
|
||||
this.templateTypeMapPanel.Quality = 1;
|
||||
this.templateTypeMapPanel.Size = new System.Drawing.Size(270, 266);
|
||||
this.templateTypeMapPanel.TabIndex = 6;
|
||||
this.templateTypeMapPanel.Zoom = 1;
|
||||
this.templateTypeMapPanel.ZoomStep = 1;
|
||||
//
|
||||
// TemplateToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(274, 549);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.splitContainer1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(288, 287);
|
||||
this.Name = "TemplateToolDialog";
|
||||
this.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Map";
|
||||
this.splitContainer1.Panel1.ResumeLayout(false);
|
||||
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
||||
this.splitContainer1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||
private System.Windows.Forms.ListView templateTypeListView;
|
||||
private Controls.MapPanel templateTypeMapPanel;
|
||||
}
|
||||
}
|
49
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.cs
Normal file
49
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class TemplateToolDialog : Form
|
||||
{
|
||||
public ListView TemplateTypeListView => templateTypeListView;
|
||||
|
||||
public MapPanel TemplateTypeMapPanel => templateTypeMapPanel;
|
||||
|
||||
public TemplateToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
120
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.resx
Normal file
120
CnCTDRAMapEditor/Tools/Dialogs/TemplateToolDialog.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
147
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.Designer.cs
generated
Normal file
147
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class TerrainToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TerrainToolDialog));
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.terrainTypeMapPanel = new MobiusEditor.Controls.MapPanel();
|
||||
this.terrainTypeComboBox = new MobiusEditor.Controls.TypeComboBox();
|
||||
this.terrainProperties = new MobiusEditor.Controls.TerrainProperties();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.AutoSize = true;
|
||||
this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.tableLayoutPanel1.ColumnCount = 1;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.terrainTypeMapPanel, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.terrainTypeComboBox, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.terrainProperties, 0, 3);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 4;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(411, 466);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// terrainTypeMapPanel
|
||||
//
|
||||
this.terrainTypeMapPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.terrainTypeMapPanel.Location = new System.Drawing.Point(4, 42);
|
||||
this.terrainTypeMapPanel.MapImage = null;
|
||||
this.terrainTypeMapPanel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.terrainTypeMapPanel.MaxZoom = 8;
|
||||
this.terrainTypeMapPanel.MinZoom = 1;
|
||||
this.terrainTypeMapPanel.Name = "terrainTypeMapPanel";
|
||||
this.terrainTypeMapPanel.Quality = 1;
|
||||
this.terrainTypeMapPanel.Size = new System.Drawing.Size(403, 370);
|
||||
this.terrainTypeMapPanel.TabIndex = 3;
|
||||
this.terrainTypeMapPanel.Zoom = 1;
|
||||
this.terrainTypeMapPanel.ZoomStep = 1;
|
||||
//
|
||||
// terrainTypeComboBox
|
||||
//
|
||||
this.terrainTypeComboBox.DisplayMember = "Name";
|
||||
this.terrainTypeComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.terrainTypeComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
|
||||
this.terrainTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.terrainTypeComboBox.FormattingEnabled = true;
|
||||
this.terrainTypeComboBox.Location = new System.Drawing.Point(4, 5);
|
||||
this.terrainTypeComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.terrainTypeComboBox.MissingThumbnail = ((System.Drawing.Image)(resources.GetObject("terrainTypeComboBox.MissingThumbnail")));
|
||||
this.terrainTypeComboBox.Name = "terrainTypeComboBox";
|
||||
this.terrainTypeComboBox.Size = new System.Drawing.Size(403, 27);
|
||||
this.terrainTypeComboBox.TabIndex = 2;
|
||||
this.terrainTypeComboBox.ValueMember = "Type";
|
||||
//
|
||||
// terrainProperties
|
||||
//
|
||||
this.terrainProperties.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.terrainProperties.Location = new System.Drawing.Point(4, 422);
|
||||
this.terrainProperties.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.terrainProperties.Name = "terrainProperties";
|
||||
this.terrainProperties.Size = new System.Drawing.Size(403, 38);
|
||||
this.terrainProperties.TabIndex = 4;
|
||||
this.terrainProperties.Terrain = null;
|
||||
//
|
||||
// TerrainToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.ClientSize = new System.Drawing.Size(411, 466);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(424, 421);
|
||||
this.Name = "TerrainToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Terrain";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.TypeComboBox terrainTypeComboBox;
|
||||
private Controls.MapPanel terrainTypeMapPanel;
|
||||
private Controls.TerrainProperties terrainProperties;
|
||||
}
|
||||
}
|
58
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.cs
Normal file
58
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Interface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class TerrainToolDialog : Form
|
||||
{
|
||||
public TypeComboBox TerrainTypeComboBox => terrainTypeComboBox;
|
||||
|
||||
public MapPanel TerrainTypeMapPanel => terrainTypeMapPanel;
|
||||
|
||||
public TerrainProperties TerrainProperties => terrainProperties;
|
||||
|
||||
public TerrainToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
public TerrainToolDialog(IGamePlugin plugin)
|
||||
: this()
|
||||
{
|
||||
terrainProperties.Initialize(plugin, true);
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
165
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.resx
Normal file
165
CnCTDRAMapEditor/Tools/Dialogs/TerrainToolDialog.resx
Normal file
|
@ -0,0 +1,165 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="terrainTypeComboBox.MissingThumbnail" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
fwDWYGmBKz70PQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
125
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.Designer.cs
generated
Normal file
125
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.Designer.cs
generated
Normal file
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
partial class WaypointsToolDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.waypointCombo = new System.Windows.Forms.ComboBox();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel4
|
||||
//
|
||||
this.tableLayoutPanel4.AutoSize = true;
|
||||
this.tableLayoutPanel4.ColumnCount = 2;
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.Controls.Add(this.label1, 0, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.waypointCombo, 1, 0);
|
||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||
this.tableLayoutPanel4.RowCount = 2;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(218, 118);
|
||||
this.tableLayoutPanel4.TabIndex = 3;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(4, 0);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(75, 38);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Waypoint";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// waypointCombo
|
||||
//
|
||||
this.waypointCombo.DisplayMember = "Name";
|
||||
this.waypointCombo.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.waypointCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.waypointCombo.FormattingEnabled = true;
|
||||
this.waypointCombo.Location = new System.Drawing.Point(87, 5);
|
||||
this.waypointCombo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.waypointCombo.Name = "waypointCombo";
|
||||
this.waypointCombo.Size = new System.Drawing.Size(127, 28);
|
||||
this.waypointCombo.TabIndex = 1;
|
||||
this.waypointCombo.ValueMember = "Type";
|
||||
//
|
||||
// WaypointsToolDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.ClientSize = new System.Drawing.Size(218, 118);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.tableLayoutPanel4);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(210, 91);
|
||||
this.Name = "WaypointsToolDialog";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Waypoints";
|
||||
this.tableLayoutPanel4.ResumeLayout(false);
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.ComboBox waypointCombo;
|
||||
}
|
||||
}
|
39
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.cs
Normal file
39
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools.Dialogs
|
||||
{
|
||||
public partial class WaypointsToolDialog : Form
|
||||
{
|
||||
public ComboBox WaypointCombo => waypointCombo;
|
||||
|
||||
public WaypointsToolDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Location = Properties.Settings.Default.ToolDialogPosition;
|
||||
}
|
||||
|
||||
protected override void OnMove(EventArgs e)
|
||||
{
|
||||
base.OnMove(e);
|
||||
|
||||
Properties.Settings.Default.ToolDialogPosition = Location;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
}
|
||||
}
|
120
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.resx
Normal file
120
CnCTDRAMapEditor/Tools/Dialogs/WaypointsToolDialog.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
539
CnCTDRAMapEditor/Tools/InfantryTool.cs
Normal file
539
CnCTDRAMapEditor/Tools/InfantryTool.cs
Normal file
|
@ -0,0 +1,539 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Render;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class InfantryTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox infantryTypeComboBox;
|
||||
private readonly MapPanel infantryTypeMapPanel;
|
||||
private readonly ObjectProperties objectProperties;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private readonly Infantry mockInfantry;
|
||||
|
||||
private Infantry selectedInfantry;
|
||||
private ObjectPropertiesPopup selectedObjectProperties;
|
||||
|
||||
private InfantryType selectedInfantryType;
|
||||
private InfantryType SelectedInfantryType
|
||||
{
|
||||
get => selectedInfantryType;
|
||||
set
|
||||
{
|
||||
if (selectedInfantryType != value)
|
||||
{
|
||||
if (placementMode && (selectedInfantryType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
selectedInfantryType = value;
|
||||
infantryTypeComboBox.SelectedValue = selectedInfantryType;
|
||||
|
||||
if (placementMode && (selectedInfantryType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
mockInfantry.Type = selectedInfantryType;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public InfantryTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox infantryTypeComboBox, MapPanel infantryTypeMapPanel, ObjectProperties objectProperties, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
mockInfantry = new Infantry(null)
|
||||
{
|
||||
Type = infantryTypeComboBox.Types.First() as InfantryType,
|
||||
House = map.Houses.First().Type,
|
||||
Strength = 256,
|
||||
Direction = map.DirectionTypes.Where(d => d.Equals(FacingType.South)).First(),
|
||||
Mission = map.MissionTypes.Where(m => m.Equals("Guard")).FirstOrDefault() ?? map.MissionTypes.First()
|
||||
};
|
||||
mockInfantry.PropertyChanged += MockInfantry_PropertyChanged;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseDoubleClick += MapPanel_MouseDoubleClick;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += InfantryTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += InfantryTool_KeyUp;
|
||||
|
||||
this.infantryTypeComboBox = infantryTypeComboBox;
|
||||
this.infantryTypeComboBox.SelectedIndexChanged += InfantryTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.infantryTypeMapPanel = infantryTypeMapPanel;
|
||||
this.infantryTypeMapPanel.BackColor = Color.White;
|
||||
this.infantryTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
this.objectProperties = objectProperties;
|
||||
this.objectProperties.Object = mockInfantry;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedInfantryType = this.infantryTypeComboBox.Types.First() as InfantryType;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Control.ModifierKeys != Keys.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.Metrics.GetCell(navigationWidget.MouseCell, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is InfantryGroup infantryGroup)
|
||||
{
|
||||
var i = InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>().First();
|
||||
if (infantryGroup.Infantry[i] is Infantry infantry)
|
||||
{
|
||||
selectedInfantry = null;
|
||||
|
||||
selectedObjectProperties?.Close();
|
||||
selectedObjectProperties = new ObjectPropertiesPopup(objectProperties.Plugin, infantry);
|
||||
selectedObjectProperties.Closed += (cs, ce) =>
|
||||
{
|
||||
navigationWidget.Refresh();
|
||||
};
|
||||
|
||||
infantry.PropertyChanged += SelectedInfantry_PropertyChanged;
|
||||
|
||||
selectedObjectProperties.Show(mapPanel, mapPanel.PointToClient(Control.MousePosition));
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MockInfantry_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
RefreshMapPanel();
|
||||
}
|
||||
|
||||
private void SelectedInfantry_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
mapPanel.Invalidate(map, (sender as Infantry).InfantryGroup);
|
||||
}
|
||||
|
||||
private void InfantryTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedInfantryType = infantryTypeComboBox.SelectedValue as InfantryType;
|
||||
}
|
||||
|
||||
private void InfantryTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void InfantryTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
|
||||
if (placementMode)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
else if (selectedInfantry != null)
|
||||
{
|
||||
var oldLocation = map.Technos[selectedInfantry.InfantryGroup].Value;
|
||||
var oldStop = Array.IndexOf(selectedInfantry.InfantryGroup.Infantry, selectedInfantry);
|
||||
|
||||
InfantryGroup infantryGroup = null;
|
||||
var techno = map.Technos[navigationWidget.MouseCell];
|
||||
if (techno == null)
|
||||
{
|
||||
infantryGroup = new InfantryGroup();
|
||||
map.Technos.Add(navigationWidget.MouseCell, infantryGroup);
|
||||
}
|
||||
else if (techno is InfantryGroup)
|
||||
{
|
||||
infantryGroup = techno as InfantryGroup;
|
||||
}
|
||||
|
||||
if (infantryGroup != null)
|
||||
{
|
||||
foreach (var i in InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>())
|
||||
{
|
||||
if (infantryGroup.Infantry[i] == null)
|
||||
{
|
||||
selectedInfantry.InfantryGroup.Infantry[oldStop] = null;
|
||||
infantryGroup.Infantry[i] = selectedInfantry;
|
||||
|
||||
if (infantryGroup != selectedInfantry.InfantryGroup)
|
||||
{
|
||||
mapPanel.Invalidate(map, selectedInfantry.InfantryGroup);
|
||||
if (selectedInfantry.InfantryGroup.Infantry.All(x => x == null))
|
||||
{
|
||||
map.Technos.Remove(selectedInfantry.InfantryGroup);
|
||||
}
|
||||
}
|
||||
selectedInfantry.InfantryGroup = infantryGroup;
|
||||
|
||||
mapPanel.Invalidate(map, infantryGroup);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
|
||||
if (infantryGroup == selectedInfantry.InfantryGroup)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddInfantry(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveInfantry(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SelectInfantry(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
PickInfantry(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (selectedInfantry != null)
|
||||
{
|
||||
selectedInfantry = null;
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedInfantryType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.OldCell, new Size(1, 1)), 1, 1));
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.NewCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddInfantry(Point location)
|
||||
{
|
||||
if (SelectedInfantryType != null)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
InfantryGroup infantryGroup = null;
|
||||
|
||||
var techno = map.Technos[cell];
|
||||
if (techno == null)
|
||||
{
|
||||
infantryGroup = new InfantryGroup();
|
||||
map.Technos.Add(cell, infantryGroup);
|
||||
}
|
||||
else if (techno is InfantryGroup)
|
||||
{
|
||||
infantryGroup = techno as InfantryGroup;
|
||||
}
|
||||
|
||||
if (infantryGroup != null)
|
||||
{
|
||||
foreach (var i in InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>())
|
||||
{
|
||||
if (infantryGroup.Infantry[i] == null)
|
||||
{
|
||||
var infantry = mockInfantry.Clone();
|
||||
infantryGroup.Infantry[i] = infantry;
|
||||
infantry.InfantryGroup = infantryGroup;
|
||||
mapPanel.Invalidate(map, infantryGroup);
|
||||
plugin.Dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveInfantry(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is InfantryGroup infantryGroup)
|
||||
{
|
||||
foreach (var i in InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>())
|
||||
{
|
||||
if (infantryGroup.Infantry[i] != null)
|
||||
{
|
||||
infantryGroup.Infantry[i] = null;
|
||||
mapPanel.Invalidate(map, infantryGroup);
|
||||
plugin.Dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (infantryGroup.Infantry.All(i => i == null))
|
||||
{
|
||||
map.Technos.Remove(infantryGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedInfantryType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedInfantryType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickInfantry(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is InfantryGroup infantryGroup)
|
||||
{
|
||||
var i = InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>().First();
|
||||
if (infantryGroup.Infantry[i] is Infantry infantry)
|
||||
{
|
||||
SelectedInfantryType = infantry.Type;
|
||||
mockInfantry.House = infantry.House;
|
||||
mockInfantry.Strength = infantry.Strength;
|
||||
mockInfantry.Direction = infantry.Direction;
|
||||
mockInfantry.Mission = infantry.Mission;
|
||||
mockInfantry.Trigger = infantry.Trigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectInfantry(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
selectedInfantry = null;
|
||||
if (map.Technos[cell] is InfantryGroup infantryGroup)
|
||||
{
|
||||
var i = InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>().First();
|
||||
if (infantryGroup.Infantry[i] is Infantry infantry)
|
||||
{
|
||||
selectedInfantry = infantry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
if (mockInfantry.Type != null)
|
||||
{
|
||||
var infantryPreview = new Bitmap(Globals.TileWidth, Globals.TileHeight);
|
||||
using (var g = Graphics.FromImage(infantryPreview))
|
||||
{
|
||||
MapRenderer.Render(map.Theater, Point.Empty, Globals.TileSize, mockInfantry, InfantryStoppingType.Center).Item2(g);
|
||||
}
|
||||
infantryTypeMapPanel.MapImage = infantryPreview;
|
||||
}
|
||||
else
|
||||
{
|
||||
infantryTypeMapPanel.MapImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place infantry, Right-Click to remove infantry";
|
||||
}
|
||||
else if (selectedInfantry != null)
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to move infantry";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click drag to move infantry, Double-Click update infantry properties, Right-Click to pick infantry";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedInfantryType != null)
|
||||
{
|
||||
if (previewMap.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
InfantryGroup infantryGroup = null;
|
||||
|
||||
var techno = previewMap.Technos[cell];
|
||||
if (techno == null)
|
||||
{
|
||||
infantryGroup = new InfantryGroup();
|
||||
previewMap.Technos.Add(cell, infantryGroup);
|
||||
}
|
||||
else if (techno is InfantryGroup)
|
||||
{
|
||||
infantryGroup = techno as InfantryGroup;
|
||||
}
|
||||
|
||||
if (infantryGroup != null)
|
||||
{
|
||||
foreach (var i in InfantryGroup.ClosestStoppingTypes(navigationWidget.MouseSubPixel).Cast<int>())
|
||||
{
|
||||
if (infantryGroup.Infantry[i] == null)
|
||||
{
|
||||
var infantry = mockInfantry.Clone();
|
||||
infantry.Tint = Color.FromArgb(128, Color.White);
|
||||
infantryGroup.Infantry[i] = infantry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var infantryPen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (topLeft, _) in map.Technos.OfType<InfantryGroup>())
|
||||
{
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(infantryPen, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseDoubleClick -= MapPanel_MouseDoubleClick;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= InfantryTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= InfantryTool_KeyUp;
|
||||
|
||||
infantryTypeComboBox.SelectedIndexChanged -= InfantryTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
341
CnCTDRAMapEditor/Tools/OverlaysTool.cs
Normal file
341
CnCTDRAMapEditor/Tools/OverlaysTool.cs
Normal file
|
@ -0,0 +1,341 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class OverlaysTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox overlayTypeComboBox;
|
||||
private readonly MapPanel overlayTypeMapPanel;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private OverlayType selectedOverlayType;
|
||||
private OverlayType SelectedOverlayType
|
||||
{
|
||||
get => selectedOverlayType;
|
||||
set
|
||||
{
|
||||
if (selectedOverlayType != value)
|
||||
{
|
||||
if (placementMode && (selectedOverlayType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
selectedOverlayType = value;
|
||||
overlayTypeComboBox.SelectedValue = selectedOverlayType;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OverlaysTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox overlayTypeComboBox, MapPanel overlayTypeMapPanel, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += OverlaysTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += OverlaysTool_KeyUp;
|
||||
|
||||
this.overlayTypeComboBox = overlayTypeComboBox;
|
||||
this.overlayTypeComboBox.SelectedIndexChanged += OverlayTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.overlayTypeMapPanel = overlayTypeMapPanel;
|
||||
this.overlayTypeMapPanel.BackColor = Color.White;
|
||||
this.overlayTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedOverlayType = this.overlayTypeComboBox.Types.First() as OverlayType;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void OverlayTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedOverlayType = overlayTypeComboBox.SelectedValue as OverlayType;
|
||||
}
|
||||
|
||||
private void OverlaysTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void OverlaysTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddOverlay(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveOverlay(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
|
||||
{
|
||||
PickOverlay(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedOverlayType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(e.OldCell, new Size(1, 1)));
|
||||
mapPanel.Invalidate(map, new Rectangle(e.NewCell, new Size(1, 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddOverlay(Point location)
|
||||
{
|
||||
if ((location.Y == 0) || (location.Y == (map.Metrics.Height - 1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.Overlay[location] == null)
|
||||
{
|
||||
if (SelectedOverlayType != null)
|
||||
{
|
||||
var overlay = new Overlay
|
||||
{
|
||||
Type = SelectedOverlayType,
|
||||
Icon = 0
|
||||
};
|
||||
map.Overlay[location] = overlay;
|
||||
mapPanel.Invalidate(map, location);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Overlay[location] = null;
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Overlay[location] = overlay;
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveOverlay(Point location)
|
||||
{
|
||||
if ((map.Overlay[location] is Overlay overlay) && overlay.Type.IsPlaceable)
|
||||
{
|
||||
map.Overlay[location] = null;
|
||||
mapPanel.Invalidate(map, location);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Overlay[location] = overlay;
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Overlay[location] = null;
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedOverlayType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedOverlayType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickOverlay(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var overlay = map.Overlay[cell];
|
||||
if ((overlay != null) && !overlay.Type.IsWall)
|
||||
{
|
||||
SelectedOverlayType = overlay.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
overlayTypeMapPanel.MapImage = SelectedOverlayType?.Thumbnail;
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place overlay, Right-Click to remove overlay";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick overlay";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedOverlayType != null)
|
||||
{
|
||||
if (previewMap.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (previewMap.Overlay[cell] == null)
|
||||
{
|
||||
previewMap.Overlay[cell] = new Overlay
|
||||
{
|
||||
Type = SelectedOverlayType,
|
||||
Icon = 0,
|
||||
Tint = Color.FromArgb(128, Color.White)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var overlayPen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (cell, overlay) in previewMap.Overlay.Where(x => x.Value.Type.IsPlaceable))
|
||||
{
|
||||
previewMap.Metrics.GetLocation(cell, out Point topLeft);
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(overlayPen, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
overlayTypeComboBox.SelectedIndexChanged -= OverlayTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= OverlaysTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= OverlaysTool_KeyUp;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
364
CnCTDRAMapEditor/Tools/ResourcesTool.cs
Normal file
364
CnCTDRAMapEditor/Tools/ResourcesTool.cs
Normal file
|
@ -0,0 +1,364 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class ResourcesTool : ViewTool
|
||||
{
|
||||
private readonly Label totalResourcesLbl;
|
||||
private readonly NumericUpDown brushSizeNud;
|
||||
private readonly CheckBox gemsCheckBox;
|
||||
|
||||
private bool placementMode;
|
||||
private bool additivePlacement;
|
||||
|
||||
private readonly Dictionary<int, Overlay> undoOverlays = new Dictionary<int, Overlay>();
|
||||
private readonly Dictionary<int, Overlay> redoOverlays = new Dictionary<int, Overlay>();
|
||||
|
||||
public ResourcesTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, Label totalResourcesLbl, NumericUpDown brushSizeNud, CheckBox gemsCheckBox, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
(this.mapPanel as Control).KeyDown += ResourceTool_KeyDown;
|
||||
|
||||
this.totalResourcesLbl = totalResourcesLbl;
|
||||
this.brushSizeNud = brushSizeNud;
|
||||
this.gemsCheckBox = gemsCheckBox;
|
||||
|
||||
this.brushSizeNud.ValueChanged += BrushSizeNud_ValueChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
navigationWidget.MouseoverSize = new Size((int)brushSizeNud.Value, (int)brushSizeNud.Value);
|
||||
|
||||
url.Undone += Url_UndoRedo;
|
||||
url.Redone += Url_UndoRedo;
|
||||
|
||||
Update();
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void Url_UndoRedo(object sender, EventArgs e)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
private void BrushSizeNud_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
navigationWidget.MouseoverSize = new Size((int)brushSizeNud.Value, (int)brushSizeNud.Value);
|
||||
}
|
||||
|
||||
private void ResourceTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.OemOpenBrackets)
|
||||
{
|
||||
brushSizeNud.DownButton();
|
||||
mapPanel.Invalidate();
|
||||
}
|
||||
else if (e.KeyCode == Keys.OemCloseBrackets)
|
||||
{
|
||||
brushSizeNud.UpButton();
|
||||
mapPanel.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
EnterPlacementMode(true);
|
||||
AddResource(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
EnterPlacementMode(false);
|
||||
RemoveResource(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (((e.Button == MouseButtons.Left) && additivePlacement) ||
|
||||
((e.Button == MouseButtons.Right) && !additivePlacement))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
if ((undoOverlays.Count > 0) || (redoOverlays.Count > 0))
|
||||
{
|
||||
CommitChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (additivePlacement)
|
||||
{
|
||||
AddResource(e.NewCell);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveResource(e.NewCell);
|
||||
}
|
||||
}
|
||||
|
||||
if (brushSizeNud.Value > 1)
|
||||
{
|
||||
foreach (var cell in new Point[] { e.OldCell, e.NewCell })
|
||||
{
|
||||
mapPanel.Invalidate(mapPanel.MapToClient(new Rectangle(
|
||||
new Point(cell.X - ((int)brushSizeNud.Value / 2), cell.Y - ((int)brushSizeNud.Value / 2)),
|
||||
new Size((int)brushSizeNud.Value, (int)brushSizeNud.Value)
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddResource(Point location)
|
||||
{
|
||||
Rectangle rectangle = new Rectangle(location, new Size(1, 1));
|
||||
rectangle.Inflate(navigationWidget.MouseoverSize.Width / 2, navigationWidget.MouseoverSize.Height / 2);
|
||||
foreach (var subLocation in rectangle.Points())
|
||||
{
|
||||
if ((subLocation.Y == 0) || (subLocation.Y == (map.Metrics.Height - 1)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map.Metrics.GetCell(subLocation, out int cell))
|
||||
{
|
||||
if (map.Overlay[cell] == null)
|
||||
{
|
||||
var resourceType = gemsCheckBox.Checked ?
|
||||
map.OverlayTypes.Where(t => t.IsGem).FirstOrDefault() :
|
||||
map.OverlayTypes.Where(t => t.IsTiberiumOrGold).FirstOrDefault();
|
||||
if (resourceType != null)
|
||||
{
|
||||
if (!undoOverlays.ContainsKey(cell))
|
||||
{
|
||||
undoOverlays[cell] = map.Overlay[cell];
|
||||
}
|
||||
|
||||
var overlay = new Overlay { Type = resourceType, Icon = 0 };
|
||||
map.Overlay[cell] = overlay;
|
||||
redoOverlays[cell] = overlay;
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectangle.Inflate(1, 1);
|
||||
mapPanel.Invalidate(map, rectangle);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void RemoveResource(Point location)
|
||||
{
|
||||
Rectangle rectangle = new Rectangle(location, new Size(1, 1));
|
||||
rectangle.Inflate(navigationWidget.MouseoverSize.Width / 2, navigationWidget.MouseoverSize.Height / 2);
|
||||
foreach (var subLocation in rectangle.Points())
|
||||
{
|
||||
if (map.Metrics.GetCell(subLocation, out int cell))
|
||||
{
|
||||
if (map.Overlay[cell]?.Type.IsResource ?? false)
|
||||
{
|
||||
if (!undoOverlays.ContainsKey(cell))
|
||||
{
|
||||
undoOverlays[cell] = map.Overlay[cell];
|
||||
}
|
||||
|
||||
map.Overlay[cell] = null;
|
||||
redoOverlays[cell] = null;
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rectangle.Inflate(1, 1);
|
||||
mapPanel.Invalidate(map, rectangle);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
private void EnterPlacementMode(bool additive)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
additivePlacement = additive;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void CommitChange()
|
||||
{
|
||||
var undoOverlays2 = new Dictionary<int, Overlay>(undoOverlays);
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in undoOverlays2)
|
||||
{
|
||||
e.Map.Overlay[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate(e.Map, undoOverlays2.Keys.Select(k =>
|
||||
{
|
||||
e.Map.Metrics.GetLocation(k, out Point location);
|
||||
var rectangle = new Rectangle(location, new Size(1, 1));
|
||||
rectangle.Inflate(1, 1);
|
||||
return rectangle;
|
||||
}));
|
||||
}
|
||||
|
||||
var redoOverlays2 = new Dictionary<int, Overlay>(redoOverlays);
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in redoOverlays2)
|
||||
{
|
||||
e.Map.Overlay[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate(e.Map, redoOverlays2.Keys.Select(k =>
|
||||
{
|
||||
e.Map.Metrics.GetLocation(k, out Point location);
|
||||
var rectangle = new Rectangle(location, new Size(1, 1));
|
||||
rectangle.Inflate(1, 1);
|
||||
return rectangle;
|
||||
}));
|
||||
}
|
||||
|
||||
undoOverlays.Clear();
|
||||
redoOverlays.Clear();
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
totalResourcesLbl.Text = map.TotalResources.ToString();
|
||||
|
||||
if (map.OverlayTypes.Any(t => t.IsGem))
|
||||
{
|
||||
gemsCheckBox.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gemsCheckBox.Visible = false;
|
||||
gemsCheckBox.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (additivePlacement)
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to add resources";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to remove resources";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Left-Click drag to add resources, Right-Click drag to remove resources";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var resourcePen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (cell, overlay) in map.Overlay)
|
||||
{
|
||||
if (overlay.Type.IsResource)
|
||||
{
|
||||
map.Metrics.GetLocation(cell, out Point topLeft);
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(resourcePen, bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
(mapPanel as Control).KeyDown -= ResourceTool_KeyDown;
|
||||
|
||||
brushSizeNud.ValueChanged -= BrushSizeNud_ValueChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
|
||||
url.Undone -= Url_UndoRedo;
|
||||
url.Redone -= Url_UndoRedo;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
337
CnCTDRAMapEditor/Tools/SmudgeTool.cs
Normal file
337
CnCTDRAMapEditor/Tools/SmudgeTool.cs
Normal file
|
@ -0,0 +1,337 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class SmudgeTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox smudgeTypeComboBox;
|
||||
private readonly MapPanel smudgeTypeMapPanel;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private SmudgeType selectedSmudgeType;
|
||||
private SmudgeType SelectedSmudgeType
|
||||
{
|
||||
get => selectedSmudgeType;
|
||||
set
|
||||
{
|
||||
if (selectedSmudgeType != value)
|
||||
{
|
||||
if (placementMode && (selectedSmudgeType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
selectedSmudgeType = value;
|
||||
smudgeTypeComboBox.SelectedValue = selectedSmudgeType;
|
||||
|
||||
if (placementMode && (selectedSmudgeType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SmudgeTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox smudgeTypeComboBox, MapPanel smudgeTypeMapPanel, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += SmudgeTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += SmudgeTool_KeyUp;
|
||||
|
||||
this.smudgeTypeComboBox = smudgeTypeComboBox;
|
||||
this.smudgeTypeComboBox.SelectedIndexChanged += SmudgeTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.smudgeTypeMapPanel = smudgeTypeMapPanel;
|
||||
this.smudgeTypeMapPanel.BackColor = Color.White;
|
||||
this.smudgeTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedSmudgeType = smudgeTypeComboBox.Types.First() as SmudgeType;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void SmudgeTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedSmudgeType = smudgeTypeComboBox.SelectedValue as SmudgeType;
|
||||
}
|
||||
|
||||
private void SmudgeTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void SmudgeTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddSmudge(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveSmudge(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
|
||||
{
|
||||
PickSmudge(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedSmudgeType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, e.OldCell);
|
||||
mapPanel.Invalidate(map, e.NewCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSmudge(Point location)
|
||||
{
|
||||
if (map.Smudge[location] == null)
|
||||
{
|
||||
if (SelectedSmudgeType != null)
|
||||
{
|
||||
var smudge = new Smudge
|
||||
{
|
||||
Type = SelectedSmudgeType,
|
||||
Icon = 0,
|
||||
Data = 0
|
||||
};
|
||||
map.Smudge[location] = smudge;
|
||||
mapPanel.Invalidate(map, location);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Smudge[location] = null;
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Smudge[location] = smudge;
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveSmudge(Point location)
|
||||
{
|
||||
if ((map.Smudge[location] is Smudge smudge) && ((smudge.Type.Flag & SmudgeTypeFlag.Bib) == SmudgeTypeFlag.None))
|
||||
{
|
||||
map.Smudge[location] = null;
|
||||
mapPanel.Invalidate(map, location);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Smudge[location] = smudge;
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Smudge[location] = null;
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedSmudgeType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedSmudgeType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickSmudge(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var smudge = map.Smudge[cell];
|
||||
if (smudge != null)
|
||||
{
|
||||
SelectedSmudgeType = smudge.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
smudgeTypeMapPanel.MapImage = SelectedSmudgeType?.Thumbnail;
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place smudge, Right-Click to remove smudge";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick smudge";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedSmudgeType != null)
|
||||
{
|
||||
if (previewMap.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (previewMap.Smudge[cell] == null)
|
||||
{
|
||||
previewMap.Smudge[cell] = new Smudge { Type = SelectedSmudgeType, Data = 0, Tint = Color.FromArgb(128, Color.White) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var smudgePen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (cell, smudge) in previewMap.Smudge.Where(x => (x.Value.Type.Flag & SmudgeTypeFlag.Bib) == SmudgeTypeFlag.None))
|
||||
{
|
||||
previewMap.Metrics.GetLocation(cell, out Point topLeft);
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(smudgePen, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
smudgeTypeComboBox.SelectedIndexChanged -= SmudgeTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= SmudgeTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= SmudgeTool_KeyUp;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
1008
CnCTDRAMapEditor/Tools/TemplateTool.cs
Normal file
1008
CnCTDRAMapEditor/Tools/TemplateTool.cs
Normal file
File diff suppressed because it is too large
Load diff
455
CnCTDRAMapEditor/Tools/TerrainTool.cs
Normal file
455
CnCTDRAMapEditor/Tools/TerrainTool.cs
Normal file
|
@ -0,0 +1,455 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class TerrainTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox terrainTypeComboBox;
|
||||
private readonly MapPanel terrainTypeMapPanel;
|
||||
private readonly TerrainProperties terrainProperties;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private readonly Terrain mockTerrain;
|
||||
|
||||
private Terrain selectedTerrain;
|
||||
private Point selectedTerrainPivot;
|
||||
|
||||
private TerrainType selectedTerrainType;
|
||||
private TerrainPropertiesPopup selectedTerrainProperties;
|
||||
private TerrainType SelectedTerrainType
|
||||
{
|
||||
get => selectedTerrainType;
|
||||
set
|
||||
{
|
||||
if (selectedTerrainType != value)
|
||||
{
|
||||
if (placementMode && (selectedTerrainType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedTerrainType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
selectedTerrainType = value;
|
||||
terrainTypeComboBox.SelectedValue = selectedTerrainType;
|
||||
|
||||
if (placementMode && (selectedTerrainType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedTerrainType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
mockTerrain.Type = selectedTerrainType;
|
||||
mockTerrain.Icon = selectedTerrainType.IsTransformable ? 22 : 0;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox terrainTypeComboBox, MapPanel terrainTypeMapPanel, TerrainProperties terrainProperties, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
mockTerrain = new Terrain();
|
||||
mockTerrain.PropertyChanged += MockTerrain_PropertyChanged;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseDoubleClick += MapPanel_MouseDoubleClick;
|
||||
(this.mapPanel as Control).KeyDown += TerrainTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += TerrainTool_KeyUp;
|
||||
|
||||
this.terrainTypeComboBox = terrainTypeComboBox;
|
||||
this.terrainTypeComboBox.SelectedIndexChanged += TerrainTypeCombo_SelectedIndexChanged;
|
||||
|
||||
this.terrainTypeMapPanel = terrainTypeMapPanel;
|
||||
this.terrainTypeMapPanel.BackColor = Color.White;
|
||||
this.terrainTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
this.terrainProperties = terrainProperties;
|
||||
this.terrainProperties.Terrain = mockTerrain;
|
||||
this.terrainProperties.Visible = plugin.GameType == GameType.TiberianDawn;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedTerrainType = terrainTypeComboBox.Types.First() as TerrainType;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Control.ModifierKeys != Keys.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.Metrics.GetCell(navigationWidget.MouseCell, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Terrain terrain)
|
||||
{
|
||||
selectedTerrain = null;
|
||||
|
||||
selectedTerrainProperties?.Close();
|
||||
selectedTerrainProperties = new TerrainPropertiesPopup(terrainProperties.Plugin, terrain);
|
||||
selectedTerrainProperties.Closed += (cs, ce) =>
|
||||
{
|
||||
navigationWidget.Refresh();
|
||||
};
|
||||
|
||||
selectedTerrainProperties.Show(mapPanel, mapPanel.PointToClient(Control.MousePosition));
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MockTerrain_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
RefreshMapPanel();
|
||||
}
|
||||
|
||||
private void TerrainTypeCombo_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedTerrainType = terrainTypeComboBox.SelectedValue as TerrainType;
|
||||
}
|
||||
|
||||
private void TerrainTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void TerrainTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddTerrain(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveTerrain(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SelectTerrain(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
PickTerrain(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (selectedTerrain != null)
|
||||
{
|
||||
selectedTerrain = null;
|
||||
selectedTerrainPivot = Point.Empty;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedTerrainType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(e.OldCell, SelectedTerrainType.OverlapBounds.Size));
|
||||
mapPanel.Invalidate(map, new Rectangle(e.NewCell, SelectedTerrainType.OverlapBounds.Size));
|
||||
}
|
||||
}
|
||||
else if (selectedTerrain != null)
|
||||
{
|
||||
var oldLocation = map.Technos[selectedTerrain].Value;
|
||||
var newLocation = new Point(Math.Max(0, e.NewCell.X - selectedTerrainPivot.X), Math.Max(0, e.NewCell.Y - selectedTerrainPivot.Y));
|
||||
mapPanel.Invalidate(map, selectedTerrain);
|
||||
map.Technos.Remove(selectedTerrain);
|
||||
if (map.Technos.Add(newLocation, selectedTerrain))
|
||||
{
|
||||
mapPanel.Invalidate(map, selectedTerrain);
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Technos.Add(oldLocation, selectedTerrain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddTerrain(Point location)
|
||||
{
|
||||
if (!map.Metrics.Contains(location))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedTerrainType != null)
|
||||
{
|
||||
var terrain = mockTerrain.Clone();
|
||||
if (map.Technos.Add(location, terrain))
|
||||
{
|
||||
mapPanel.Invalidate(map, terrain);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Technos.Remove(terrain);
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Technos.Add(location, terrain);
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveTerrain(Point location)
|
||||
{
|
||||
if (map.Technos[location] is Terrain terrain)
|
||||
{
|
||||
mapPanel.Invalidate(map, terrain);
|
||||
map.Technos.Remove(location);
|
||||
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.Map.Technos.Add(location, terrain);
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
}
|
||||
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
e.MapPanel.Invalidate(e.Map, location);
|
||||
e.Map.Technos.Remove(terrain);
|
||||
}
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedTerrainType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedTerrainType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedTerrainType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, new Rectangle(navigationWidget.MouseCell, selectedTerrainType.OverlapBounds.Size));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickTerrain(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Terrain terrain)
|
||||
{
|
||||
SelectedTerrainType = terrain.Type;
|
||||
mockTerrain.Trigger = terrain.Trigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectTerrain(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
selectedTerrain = map.Technos[cell] as Terrain;
|
||||
selectedTerrainPivot = (selectedTerrain != null) ? (location - (Size)map.Technos[selectedTerrain].Value) : Point.Empty;
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
terrainTypeMapPanel.MapImage = mockTerrain.Type.Thumbnail;
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place terrain, Right-Click to remove terrain";
|
||||
}
|
||||
else if (selectedTerrain != null)
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to move terrain";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click drag to move terrain, Double-Click update terrain properties, Right-Click to pick terrain";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedTerrainType != null)
|
||||
{
|
||||
if (previewMap.Metrics.Contains(location))
|
||||
{
|
||||
var terrain = new Terrain
|
||||
{
|
||||
Type = SelectedTerrainType,
|
||||
Icon = SelectedTerrainType.IsTransformable ? 22 : 0,
|
||||
Tint = Color.FromArgb(128, Color.White)
|
||||
};
|
||||
previewMap.Technos.Add(location, terrain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var terrainPen = new Pen(Color.Green, 4.0f);
|
||||
var occupyPen = new Pen(Color.Red, 2.0f);
|
||||
foreach (var (topLeft, terrain) in previewMap.Technos.OfType<Terrain>())
|
||||
{
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), terrain.Type.RenderSize);
|
||||
graphics.DrawRectangle(terrainPen, bounds);
|
||||
|
||||
for (var y = 0; y < terrain.Type.OccupyMask.GetLength(0); ++y)
|
||||
{
|
||||
for (var x = 0; x < terrain.Type.OccupyMask.GetLength(1); ++x)
|
||||
{
|
||||
if (terrain.Type.OccupyMask[y, x])
|
||||
{
|
||||
var occupyBounds = new Rectangle(
|
||||
new Point((topLeft.X + x) * Globals.TileWidth, (topLeft.Y + y) * Globals.TileHeight),
|
||||
Globals.TileSize
|
||||
);
|
||||
graphics.DrawRectangle(occupyPen, occupyBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
selectedTerrainProperties?.Close();
|
||||
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseDoubleClick -= MapPanel_MouseDoubleClick;
|
||||
(mapPanel as Control).KeyDown -= TerrainTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= TerrainTool_KeyUp;
|
||||
|
||||
terrainTypeComboBox.SelectedIndexChanged -= TerrainTypeCombo_SelectedIndexChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
426
CnCTDRAMapEditor/Tools/UnitTool.cs
Normal file
426
CnCTDRAMapEditor/Tools/UnitTool.cs
Normal file
|
@ -0,0 +1,426 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Render;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class UnitTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox unitTypeComboBox;
|
||||
private readonly MapPanel unitTypeMapPanel;
|
||||
private readonly ObjectProperties objectProperties;
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private readonly Unit mockUnit;
|
||||
|
||||
private Unit selectedUnit;
|
||||
private ObjectPropertiesPopup selectedObjectProperties;
|
||||
|
||||
private UnitType selectedUnitType;
|
||||
private UnitType SelectedUnitType
|
||||
{
|
||||
get => selectedUnitType;
|
||||
set
|
||||
{
|
||||
if (selectedUnitType != value)
|
||||
{
|
||||
if (placementMode && (selectedUnitType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
selectedUnitType = value;
|
||||
unitTypeComboBox.SelectedValue = selectedUnitType;
|
||||
|
||||
if (placementMode && (selectedUnitType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
mockUnit.Type = selectedUnitType;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UnitTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox unitTypeComboBox, MapPanel unitTypeMapPanel, ObjectProperties objectProperties, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
mockUnit = new Unit()
|
||||
{
|
||||
Type = unitTypeComboBox.Types.First() as UnitType,
|
||||
House = map.Houses.First().Type,
|
||||
Strength = 256,
|
||||
Direction = map.DirectionTypes.Where(d => d.Equals(FacingType.North)).First(),
|
||||
Mission = map.MissionTypes.Where(m => m.Equals("Guard")).FirstOrDefault() ?? map.MissionTypes.First()
|
||||
};
|
||||
mockUnit.PropertyChanged += MockUnit_PropertyChanged;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseDoubleClick += MapPanel_MouseDoubleClick;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += UnitTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += UnitTool_KeyUp;
|
||||
|
||||
this.unitTypeComboBox = unitTypeComboBox;
|
||||
this.unitTypeComboBox.SelectedIndexChanged += UnitTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.unitTypeMapPanel = unitTypeMapPanel;
|
||||
this.unitTypeMapPanel.BackColor = Color.White;
|
||||
this.unitTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
this.objectProperties = objectProperties;
|
||||
this.objectProperties.Object = mockUnit;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedUnitType = mockUnit.Type;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Control.ModifierKeys != Keys.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.Metrics.GetCell(navigationWidget.MouseCell, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Unit unit)
|
||||
{
|
||||
selectedUnit = null;
|
||||
|
||||
selectedObjectProperties?.Close();
|
||||
selectedObjectProperties = new ObjectPropertiesPopup(objectProperties.Plugin, unit);
|
||||
selectedObjectProperties.Closed += (cs, ce) =>
|
||||
{
|
||||
navigationWidget.Refresh();
|
||||
};
|
||||
|
||||
unit.PropertyChanged += SelectedUnit_PropertyChanged;
|
||||
|
||||
selectedObjectProperties.Show(mapPanel, mapPanel.PointToClient(Control.MousePosition));
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MockUnit_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
RefreshMapPanel();
|
||||
}
|
||||
|
||||
private void SelectedUnit_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
mapPanel.Invalidate(map, sender as Unit);
|
||||
}
|
||||
|
||||
private void UnitTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedUnitType = unitTypeComboBox.SelectedValue as UnitType;
|
||||
}
|
||||
|
||||
private void UnitTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void UnitTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddUnit(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveUnit(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SelectUnit(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
PickUnit(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (selectedUnit != null)
|
||||
{
|
||||
selectedUnit = null;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (SelectedUnitType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.OldCell, new Size(1, 1)), 1, 1));
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.NewCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
}
|
||||
else if (selectedUnit != null)
|
||||
{
|
||||
var oldLocation = map.Technos[selectedUnit].Value;
|
||||
mapPanel.Invalidate(map, selectedUnit);
|
||||
map.Technos.Remove(selectedUnit);
|
||||
if (map.Technos.Add(e.NewCell, selectedUnit))
|
||||
{
|
||||
mapPanel.Invalidate(map, selectedUnit);
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Technos.Add(oldLocation, selectedUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddUnit(Point location)
|
||||
{
|
||||
if (SelectedUnitType != null)
|
||||
{
|
||||
var unit = mockUnit.Clone();
|
||||
if (map.Technos.Add(location, unit))
|
||||
{
|
||||
mapPanel.Invalidate(map, unit);
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveUnit(Point location)
|
||||
{
|
||||
if (map.Technos[location] is Unit unit)
|
||||
{
|
||||
mapPanel.Invalidate(map, unit);
|
||||
map.Technos.Remove(unit);
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedUnitType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedUnitType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickUnit(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (map.Technos[cell] is Unit unit)
|
||||
{
|
||||
SelectedUnitType = unit.Type;
|
||||
mockUnit.House = unit.House;
|
||||
mockUnit.Strength = unit.Strength;
|
||||
mockUnit.Direction = unit.Direction;
|
||||
mockUnit.Mission = unit.Mission;
|
||||
mockUnit.Trigger = unit.Trigger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectUnit(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
selectedUnit = map.Technos[cell] as Unit;
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
if (mockUnit.Type != null)
|
||||
{
|
||||
var unitPreview = new Bitmap(Globals.TileWidth * 3, Globals.TileHeight * 3);
|
||||
using (var g = Graphics.FromImage(unitPreview))
|
||||
{
|
||||
MapRenderer.Render(plugin.GameType, map.Theater, new Point(1, 1), Globals.TileSize, mockUnit).Item2(g);
|
||||
}
|
||||
unitTypeMapPanel.MapImage = unitPreview;
|
||||
}
|
||||
else
|
||||
{
|
||||
unitTypeMapPanel.MapImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to place unit, Right-Click to remove unit";
|
||||
}
|
||||
else if (selectedUnit != null)
|
||||
{
|
||||
statusLbl.Text = "Drag mouse to move unit";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click drag to move unit, Double-Click update unit properties, Right-Click to pick unit";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedUnitType != null)
|
||||
{
|
||||
var unit = mockUnit.Clone();
|
||||
unit.Tint = Color.FromArgb(128, Color.White);
|
||||
if (previewMap.Technos.Add(location, unit))
|
||||
{
|
||||
mapPanel.Invalidate(previewMap, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var unitPen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (topLeft, _) in map.Technos.OfType<Unit>())
|
||||
{
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(unitPen, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
selectedObjectProperties?.Close();
|
||||
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseDoubleClick -= MapPanel_MouseDoubleClick;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= UnitTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= UnitTool_KeyUp;
|
||||
|
||||
unitTypeComboBox.SelectedIndexChanged -= UnitTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
315
CnCTDRAMapEditor/Tools/ViewTool.cs
Normal file
315
CnCTDRAMapEditor/Tools/ViewTool.cs
Normal file
|
@ -0,0 +1,315 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Render;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public abstract class ViewTool : ITool
|
||||
{
|
||||
protected readonly IGamePlugin plugin;
|
||||
protected readonly Map map;
|
||||
|
||||
protected readonly MapPanel mapPanel;
|
||||
protected readonly ToolStripStatusLabel statusLbl;
|
||||
protected readonly UndoRedoList<UndoRedoEventArgs> url;
|
||||
protected readonly NavigationWidget navigationWidget;
|
||||
|
||||
protected virtual Map RenderMap => map;
|
||||
|
||||
private MapLayerFlag layers;
|
||||
public MapLayerFlag Layers
|
||||
{
|
||||
get => layers;
|
||||
set
|
||||
{
|
||||
if (layers != value)
|
||||
{
|
||||
layers = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ViewTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
{
|
||||
this.layers = layers;
|
||||
this.plugin = plugin;
|
||||
this.url = url;
|
||||
|
||||
this.mapPanel = mapPanel;
|
||||
this.mapPanel.PreRender += MapPanel_PreRender;
|
||||
this.mapPanel.PostRender += MapPanel_PostRender;
|
||||
|
||||
this.statusLbl = statusLbl;
|
||||
|
||||
map = plugin.Map;
|
||||
map.BasicSection.PropertyChanged += BasicSection_PropertyChanged;
|
||||
|
||||
navigationWidget = new NavigationWidget(mapPanel, map.Metrics, Globals.TileSize);
|
||||
}
|
||||
|
||||
protected void Invalidate()
|
||||
{
|
||||
mapPanel.Invalidate(RenderMap);
|
||||
}
|
||||
|
||||
private void BasicSection_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case "BasePlayer":
|
||||
{
|
||||
foreach (var baseBuilding in map.Buildings.OfType<Building>().Select(x => x.Occupier).Where(x => x.BasePriority >= 0))
|
||||
{
|
||||
mapPanel.Invalidate(map, baseBuilding);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_PreRender(object sender, RenderEventArgs e)
|
||||
{
|
||||
if ((e.Cells != null) && (e.Cells.Count == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PreRenderMap();
|
||||
|
||||
using (var g = Graphics.FromImage(mapPanel.MapImage))
|
||||
{
|
||||
if (Properties.Settings.Default.Quality > 1)
|
||||
{
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
|
||||
}
|
||||
|
||||
MapRenderer.Render(plugin.GameType, RenderMap, g, e.Cells?.Where(p => map.Metrics.Contains(p)).ToHashSet(), Layers);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_PostRender(object sender, RenderEventArgs e)
|
||||
{
|
||||
PostRenderMap(e.Graphics);
|
||||
navigationWidget.Render(e.Graphics);
|
||||
}
|
||||
|
||||
protected virtual void PreRenderMap() { }
|
||||
|
||||
protected virtual void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
if ((Layers & MapLayerFlag.Waypoints) != MapLayerFlag.None)
|
||||
{
|
||||
var waypointBackgroundBrush = new SolidBrush(Color.FromArgb(96, Color.Black));
|
||||
var waypointBrush = new SolidBrush(Color.FromArgb(128, Color.DarkOrange));
|
||||
var waypointPen = new Pen(Color.DarkOrange);
|
||||
|
||||
foreach (var waypoint in map.Waypoints)
|
||||
{
|
||||
if (waypoint.Cell.HasValue)
|
||||
{
|
||||
var x = waypoint.Cell.Value % map.Metrics.Width;
|
||||
var y = waypoint.Cell.Value / map.Metrics.Width;
|
||||
|
||||
var location = new Point(x * Globals.TileWidth, y * Globals.TileHeight);
|
||||
var textBounds = new Rectangle(location, Globals.TileSize);
|
||||
|
||||
graphics.FillRectangle(waypointBackgroundBrush, textBounds);
|
||||
graphics.DrawRectangle(waypointPen, textBounds);
|
||||
|
||||
StringFormat stringFormat = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
|
||||
var text = waypoint.Name.ToString();
|
||||
var font = graphics.GetAdjustedFont(text, SystemFonts.DefaultFont, textBounds.Width, 24 / Globals.TileScale, 48 / Globals.TileScale, true);
|
||||
graphics.DrawString(text.ToString(), font, waypointBrush, textBounds, stringFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Layers & MapLayerFlag.TechnoTriggers) != MapLayerFlag.None)
|
||||
{
|
||||
var technoTriggerBackgroundBrush = new SolidBrush(Color.FromArgb(96, Color.Black));
|
||||
var technoTriggerBrush = new SolidBrush(Color.LimeGreen);
|
||||
var technoTriggerPen = new Pen(Color.LimeGreen);
|
||||
|
||||
foreach (var (cell, techno) in map.Technos)
|
||||
{
|
||||
var location = new Point(cell.X * Globals.TileWidth, cell.Y * Globals.TileHeight);
|
||||
|
||||
(string trigger, Rectangle bounds)[] triggers = null;
|
||||
if (techno is Terrain terrain)
|
||||
{
|
||||
triggers = new (string, Rectangle)[] { (terrain.Trigger, new Rectangle(location, terrain.Type.RenderSize)) };
|
||||
}
|
||||
else if (techno is Building building)
|
||||
{
|
||||
var size = new Size(building.Type.Size.Width * Globals.TileWidth, building.Type.Size.Height * Globals.TileHeight);
|
||||
triggers = new (string, Rectangle)[] { (building.Trigger, new Rectangle(location, size)) };
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
triggers = new (string, Rectangle)[] { (unit.Trigger, new Rectangle(location, Globals.TileSize)) };
|
||||
}
|
||||
else if (techno is InfantryGroup infantryGroup)
|
||||
{
|
||||
List<(string, Rectangle)> infantryTriggers = new List<(string, Rectangle)>();
|
||||
for (var i = 0; i < infantryGroup.Infantry.Length; ++i)
|
||||
{
|
||||
var infantry = infantryGroup.Infantry[i];
|
||||
if (infantry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var size = Globals.TileSize;
|
||||
var offset = Size.Empty;
|
||||
switch ((InfantryStoppingType)i)
|
||||
{
|
||||
case InfantryStoppingType.UpperLeft:
|
||||
offset.Width = -size.Width / 4;
|
||||
offset.Height = -size.Height / 4;
|
||||
break;
|
||||
case InfantryStoppingType.UpperRight:
|
||||
offset.Width = size.Width / 4;
|
||||
offset.Height = -size.Height / 4;
|
||||
break;
|
||||
case InfantryStoppingType.LowerLeft:
|
||||
offset.Width = -size.Width / 4;
|
||||
offset.Height = size.Height / 4;
|
||||
break;
|
||||
case InfantryStoppingType.LowerRight:
|
||||
offset.Width = size.Width / 4;
|
||||
offset.Height = size.Height / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
var bounds = new Rectangle(location + offset, size);
|
||||
infantryTriggers.Add((infantry.Trigger, bounds));
|
||||
}
|
||||
|
||||
triggers = infantryTriggers.ToArray();
|
||||
}
|
||||
|
||||
if (triggers != null)
|
||||
{
|
||||
StringFormat stringFormat = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
|
||||
foreach (var (trigger, bounds) in triggers.Where(x => !x.trigger.Equals("None", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var font = graphics.GetAdjustedFont(trigger, SystemFonts.DefaultFont, bounds.Width, 12 / Globals.TileScale, 24 / Globals.TileScale, true);
|
||||
var textBounds = graphics.MeasureString(trigger, font, bounds.Width, stringFormat);
|
||||
|
||||
var backgroundBounds = new RectangleF(bounds.Location, textBounds);
|
||||
backgroundBounds.Offset((bounds.Width - textBounds.Width) / 2.0f, (bounds.Height - textBounds.Height) / 2.0f);
|
||||
graphics.FillRectangle(technoTriggerBackgroundBrush, backgroundBounds);
|
||||
graphics.DrawRectangle(technoTriggerPen, Rectangle.Round(backgroundBounds));
|
||||
|
||||
graphics.DrawString(trigger, font, technoTriggerBrush, bounds, stringFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Layers & MapLayerFlag.CellTriggers) != MapLayerFlag.None)
|
||||
{
|
||||
var cellTriggersBackgroundBrush = new SolidBrush(Color.FromArgb(96, Color.Black));
|
||||
var cellTriggersBrush = new SolidBrush(Color.FromArgb(128, Color.White));
|
||||
var cellTriggerPen = new Pen(Color.White);
|
||||
|
||||
foreach (var (cell, cellTrigger) in map.CellTriggers)
|
||||
{
|
||||
var x = cell % map.Metrics.Width;
|
||||
var y = cell / map.Metrics.Width;
|
||||
|
||||
var location = new Point(x * Globals.TileWidth, y * Globals.TileHeight);
|
||||
var textBounds = new Rectangle(location, Globals.TileSize);
|
||||
|
||||
graphics.FillRectangle(cellTriggersBackgroundBrush, textBounds);
|
||||
graphics.DrawRectangle(cellTriggerPen, textBounds);
|
||||
|
||||
StringFormat stringFormat = new StringFormat
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
|
||||
var text = cellTrigger.Trigger;
|
||||
var font = graphics.GetAdjustedFont(text, SystemFonts.DefaultFont, textBounds.Width, 24 / Globals.TileScale, 48 / Globals.TileScale, true);
|
||||
graphics.DrawString(text.ToString(), font, cellTriggersBrush, textBounds, stringFormat);
|
||||
}
|
||||
}
|
||||
|
||||
if ((Layers & MapLayerFlag.Boundaries) != MapLayerFlag.None)
|
||||
{
|
||||
var boundsPen = new Pen(Color.Cyan, 8.0f);
|
||||
var bounds = Rectangle.FromLTRB(
|
||||
map.Bounds.Left * Globals.TileWidth,
|
||||
map.Bounds.Top * Globals.TileHeight,
|
||||
map.Bounds.Right * Globals.TileWidth,
|
||||
map.Bounds.Bottom * Globals.TileHeight
|
||||
);
|
||||
graphics.DrawRectangle(boundsPen, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
navigationWidget.Dispose();
|
||||
|
||||
mapPanel.PreRender -= MapPanel_PreRender;
|
||||
mapPanel.PostRender -= MapPanel_PostRender;
|
||||
|
||||
map.BasicSection.PropertyChanged -= BasicSection_PropertyChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
384
CnCTDRAMapEditor/Tools/WallsTool.cs
Normal file
384
CnCTDRAMapEditor/Tools/WallsTool.cs
Normal file
|
@ -0,0 +1,384 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class WallsTool : ViewTool
|
||||
{
|
||||
private readonly TypeComboBox wallTypeComboBox;
|
||||
private readonly MapPanel wallTypeMapPanel;
|
||||
|
||||
private readonly Dictionary<int, Overlay> undoOverlays = new Dictionary<int, Overlay>();
|
||||
private readonly Dictionary<int, Overlay> redoOverlays = new Dictionary<int, Overlay>();
|
||||
|
||||
private Map previewMap;
|
||||
protected override Map RenderMap => previewMap;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
private OverlayType selectedWallType;
|
||||
private OverlayType SelectedWallType
|
||||
{
|
||||
get => selectedWallType;
|
||||
set
|
||||
{
|
||||
if (selectedWallType != value)
|
||||
{
|
||||
if (placementMode && (selectedWallType != null))
|
||||
{
|
||||
mapPanel.Invalidate(map, navigationWidget.MouseCell);
|
||||
}
|
||||
|
||||
selectedWallType = value;
|
||||
wallTypeComboBox.SelectedValue = selectedWallType;
|
||||
|
||||
RefreshMapPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WallsTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, TypeComboBox wallTypeComboBox, MapPanel wallTypeMapPanel, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
previewMap = map;
|
||||
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseUp += MapPanel_MouseUp;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += WallTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += WallTool_KeyUp;
|
||||
|
||||
this.wallTypeComboBox = wallTypeComboBox;
|
||||
this.wallTypeComboBox.SelectedIndexChanged += WallTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
this.wallTypeMapPanel = wallTypeMapPanel;
|
||||
this.wallTypeMapPanel.BackColor = Color.White;
|
||||
this.wallTypeMapPanel.MaxZoom = 1;
|
||||
|
||||
navigationWidget.MouseCellChanged += MouseoverWidget_MouseCellChanged;
|
||||
|
||||
SelectedWallType = this.wallTypeComboBox.Types.First() as OverlayType;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void WallTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SelectedWallType = wallTypeComboBox.SelectedValue as OverlayType;
|
||||
}
|
||||
|
||||
private void WallTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void WallTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AddWall(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveWall(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
|
||||
{
|
||||
PickWall(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if ((undoOverlays.Count > 0) || (redoOverlays.Count > 0))
|
||||
{
|
||||
CommitChange();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MouseoverWidget_MouseCellChanged(object sender, MouseCellChangedEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (Control.MouseButtons == MouseButtons.Left)
|
||||
{
|
||||
AddWall(e.NewCell);
|
||||
}
|
||||
else if (Control.MouseButtons == MouseButtons.Right)
|
||||
{
|
||||
RemoveWall(e.NewCell);
|
||||
}
|
||||
|
||||
if (SelectedWallType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.OldCell, new Size(1, 1)), 1, 1));
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(e.NewCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddWall(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
if (SelectedWallType != null)
|
||||
{
|
||||
var overlay = new Overlay { Type = SelectedWallType, Icon = 0 };
|
||||
if (map.Technos.CanAdd(cell, overlay) && map.Buildings.CanAdd(cell, overlay))
|
||||
{
|
||||
if (!undoOverlays.ContainsKey(cell))
|
||||
{
|
||||
undoOverlays[cell] = map.Overlay[cell];
|
||||
}
|
||||
|
||||
map.Overlay[cell] = overlay;
|
||||
redoOverlays[cell] = overlay;
|
||||
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(location, new Size(1, 1)), 1, 1));
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveWall(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var overlay = map.Overlay[cell];
|
||||
if (overlay?.Type.IsWall ?? false)
|
||||
{
|
||||
if (!undoOverlays.ContainsKey(cell))
|
||||
{
|
||||
undoOverlays[cell] = map.Overlay[cell];
|
||||
}
|
||||
|
||||
map.Overlay[cell] = null;
|
||||
redoOverlays[cell] = null;
|
||||
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(location, new Size(1, 1)), 1, 1));
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CommitChange()
|
||||
{
|
||||
var undoOverlays2 = new Dictionary<int, Overlay>(undoOverlays);
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in undoOverlays2)
|
||||
{
|
||||
e.Map.Overlay[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate(e.Map, undoOverlays2.Keys.Select(k =>
|
||||
{
|
||||
e.Map.Metrics.GetLocation(k, out Point location);
|
||||
return Rectangle.Inflate(new Rectangle(location, new Size(1, 1)), 1, 1);
|
||||
}));
|
||||
}
|
||||
|
||||
var redoOverlays2 = new Dictionary<int, Overlay>(redoOverlays);
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
foreach (var kv in redoOverlays2)
|
||||
{
|
||||
e.Map.Overlay[kv.Key] = kv.Value;
|
||||
}
|
||||
e.MapPanel.Invalidate(e.Map, redoOverlays2.Keys.Select(k =>
|
||||
{
|
||||
e.Map.Metrics.GetLocation(k, out Point location);
|
||||
return Rectangle.Inflate(new Rectangle(location, new Size(1, 1)), 1, 1);
|
||||
}));
|
||||
}
|
||||
|
||||
undoOverlays.Clear();
|
||||
redoOverlays.Clear();
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
navigationWidget.MouseoverSize = Size.Empty;
|
||||
|
||||
if (SelectedWallType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
navigationWidget.MouseoverSize = new Size(1, 1);
|
||||
|
||||
if (SelectedWallType != null)
|
||||
{
|
||||
mapPanel.Invalidate(map, Rectangle.Inflate(new Rectangle(navigationWidget.MouseCell, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickWall(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var overlay = map.Overlay[cell];
|
||||
if ((overlay != null) && overlay.Type.IsWall)
|
||||
{
|
||||
SelectedWallType = overlay.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMapPanel()
|
||||
{
|
||||
wallTypeMapPanel.MapImage = SelectedWallType?.Thumbnail;
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click drag to add walls, Right-Click drag to remove walls";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick wall";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
{
|
||||
base.PreRenderMap();
|
||||
|
||||
previewMap = map.Clone();
|
||||
if (placementMode)
|
||||
{
|
||||
var location = navigationWidget.MouseCell;
|
||||
if (SelectedWallType != null)
|
||||
{
|
||||
if (previewMap.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var overlay = new Overlay { Type = SelectedWallType, Icon = 0, Tint = Color.FromArgb(128, Color.White) };
|
||||
if (previewMap.Technos.CanAdd(cell, overlay) && previewMap.Buildings.CanAdd(cell, overlay))
|
||||
{
|
||||
previewMap.Overlay[cell] = overlay;
|
||||
mapPanel.Invalidate(previewMap, Rectangle.Inflate(new Rectangle(location, new Size(1, 1)), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostRenderMap(Graphics graphics)
|
||||
{
|
||||
base.PostRenderMap(graphics);
|
||||
|
||||
var wallPen = new Pen(Color.Green, 4.0f);
|
||||
foreach (var (cell, overlay) in previewMap.Overlay)
|
||||
{
|
||||
if (overlay.Type.IsWall)
|
||||
{
|
||||
previewMap.Metrics.GetLocation(cell, out Point topLeft);
|
||||
var bounds = new Rectangle(new Point(topLeft.X * Globals.TileWidth, topLeft.Y * Globals.TileHeight), Globals.TileSize);
|
||||
graphics.DrawRectangle(wallPen, bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseUp -= MapPanel_MouseUp;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= WallTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= WallTool_KeyUp;
|
||||
|
||||
wallTypeComboBox.SelectedIndexChanged -= WallTypeComboBox_SelectedIndexChanged;
|
||||
|
||||
navigationWidget.MouseCellChanged -= MouseoverWidget_MouseCellChanged;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
243
CnCTDRAMapEditor/Tools/WaypointsTool.cs
Normal file
243
CnCTDRAMapEditor/Tools/WaypointsTool.cs
Normal file
|
@ -0,0 +1,243 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// The Command & Conquer Map Editor and corresponding source code is free
|
||||
// software: you can redistribute it and/or modify it under the terms of
|
||||
// the GNU General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
// The Command & Conquer Map Editor and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using MobiusEditor.Controls;
|
||||
using MobiusEditor.Event;
|
||||
using MobiusEditor.Interface;
|
||||
using MobiusEditor.Model;
|
||||
using MobiusEditor.Utility;
|
||||
using MobiusEditor.Widgets;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MobiusEditor.Tools
|
||||
{
|
||||
public class WaypointsTool : ViewTool
|
||||
{
|
||||
private readonly ComboBox waypointCombo;
|
||||
|
||||
private (Waypoint waypoint, int? cell)? undoWaypoint;
|
||||
private (Waypoint waypoint, int? cell)? redoWaypoint;
|
||||
|
||||
private bool placementMode;
|
||||
|
||||
public WaypointsTool(MapPanel mapPanel, MapLayerFlag layers, ToolStripStatusLabel statusLbl, ComboBox waypointCombo, IGamePlugin plugin, UndoRedoList<UndoRedoEventArgs> url)
|
||||
: base(mapPanel, layers, statusLbl, plugin, url)
|
||||
{
|
||||
this.mapPanel.MouseDown += MapPanel_MouseDown;
|
||||
this.mapPanel.MouseMove += MapPanel_MouseMove;
|
||||
(this.mapPanel as Control).KeyDown += WaypointsTool_KeyDown;
|
||||
(this.mapPanel as Control).KeyUp += WaypointsTool_KeyUp;
|
||||
|
||||
this.waypointCombo = waypointCombo;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void MapPanel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
SetWaypoint(navigationWidget.MouseCell);
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RemoveWaypoint(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
else if ((e.Button == MouseButtons.Left) || (e.Button == MouseButtons.Right))
|
||||
{
|
||||
PickWaypoint(navigationWidget.MouseCell);
|
||||
}
|
||||
}
|
||||
|
||||
private void WaypointsTool_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void WaypointsTool_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey)
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void MapPanel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!placementMode && (Control.ModifierKeys == Keys.Shift))
|
||||
{
|
||||
EnterPlacementMode();
|
||||
}
|
||||
else if (placementMode && (Control.ModifierKeys == Keys.None))
|
||||
{
|
||||
ExitPlacementMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetWaypoint(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var waypoint = map.Waypoints[waypointCombo.SelectedIndex];
|
||||
if (waypoint.Cell != cell)
|
||||
{
|
||||
if (undoWaypoint == null)
|
||||
{
|
||||
undoWaypoint = (waypoint, waypoint.Cell);
|
||||
}
|
||||
else if (undoWaypoint.Value.cell == cell)
|
||||
{
|
||||
undoWaypoint = null;
|
||||
}
|
||||
|
||||
waypoint.Cell = cell;
|
||||
redoWaypoint = (waypoint, waypoint.Cell);
|
||||
|
||||
CommitChange();
|
||||
|
||||
mapPanel.Invalidate();
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveWaypoint(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
var waypoint = map.Waypoints.Where(w => w.Cell == cell).FirstOrDefault();
|
||||
if (waypoint != null)
|
||||
{
|
||||
if (undoWaypoint == null)
|
||||
{
|
||||
undoWaypoint = (waypoint, waypoint.Cell);
|
||||
}
|
||||
|
||||
waypoint.Cell = null;
|
||||
redoWaypoint = (waypoint, null);
|
||||
|
||||
CommitChange();
|
||||
|
||||
mapPanel.Invalidate();
|
||||
|
||||
plugin.Dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnterPlacementMode()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = true;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void ExitPlacementMode()
|
||||
{
|
||||
if (!placementMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
placementMode = false;
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void PickWaypoint(Point location)
|
||||
{
|
||||
if (map.Metrics.GetCell(location, out int cell))
|
||||
{
|
||||
for (var i = 0; i < map.Waypoints.Length; ++i)
|
||||
{
|
||||
if (map.Waypoints[i].Cell == cell)
|
||||
{
|
||||
waypointCombo.SelectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CommitChange()
|
||||
{
|
||||
var undoWaypoint2 = undoWaypoint;
|
||||
void undoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
undoWaypoint2.Value.waypoint.Cell = undoWaypoint2.Value.cell;
|
||||
mapPanel.Invalidate();
|
||||
}
|
||||
|
||||
var redoWaypoint2 = redoWaypoint;
|
||||
void redoAction(UndoRedoEventArgs e)
|
||||
{
|
||||
redoWaypoint2.Value.waypoint.Cell = redoWaypoint2.Value.cell;
|
||||
mapPanel.Invalidate();
|
||||
}
|
||||
|
||||
undoWaypoint = null;
|
||||
redoWaypoint = null;
|
||||
|
||||
url.Track(undoAction, redoAction);
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
if (placementMode)
|
||||
{
|
||||
statusLbl.Text = "Left-Click to set cell waypoint, Right-Click to clear cell waypoint";
|
||||
}
|
||||
else
|
||||
{
|
||||
statusLbl.Text = "Shift to enter placement mode, Left-Click or Right-Click to pick cell waypoint";
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
mapPanel.MouseDown -= MapPanel_MouseDown;
|
||||
mapPanel.MouseMove -= MapPanel_MouseMove;
|
||||
(mapPanel as Control).KeyDown -= WaypointsTool_KeyDown;
|
||||
(mapPanel as Control).KeyUp -= WaypointsTool_KeyUp;
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in a new issue