235 lines
5.7 KiB
C#
235 lines
5.7 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright (c) The OpenRA Developers and Contributors
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you 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. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenRA.Graphics;
|
|
using OpenRA.Mods.Common.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Widgets
|
|
{
|
|
public sealed class EditorMarkerLayerBrush : IEditorBrush
|
|
{
|
|
public int? Template;
|
|
|
|
readonly WorldRenderer worldRenderer;
|
|
readonly World world;
|
|
readonly EditorActionManager editorActionManager;
|
|
readonly MarkerLayerOverlay markerLayerOverlay;
|
|
readonly EditorViewportControllerWidget editorWidget;
|
|
|
|
PaintMarkerTileEditorAction action;
|
|
bool painting;
|
|
|
|
public EditorMarkerLayerBrush(EditorViewportControllerWidget editorWidget, int? id, WorldRenderer wr)
|
|
{
|
|
this.editorWidget = editorWidget;
|
|
worldRenderer = wr;
|
|
world = wr.World;
|
|
|
|
editorActionManager = world.WorldActor.Trait<EditorActionManager>();
|
|
markerLayerOverlay = world.WorldActor.Trait<MarkerLayerOverlay>();
|
|
|
|
Template = id;
|
|
action = new PaintMarkerTileEditorAction(Template, markerLayerOverlay);
|
|
}
|
|
|
|
public bool HandleMouseInput(MouseInput mi)
|
|
{
|
|
if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
|
|
return false;
|
|
|
|
if (mi.Button == MouseButton.Right)
|
|
{
|
|
if (mi.Event == MouseInputEvent.Up)
|
|
{
|
|
editorWidget.ClearBrush();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if (mi.Button == MouseButton.Left && mi.Event != MouseInputEvent.Up)
|
|
{
|
|
action.Add(worldRenderer.Viewport.ViewToWorld(mi.Location));
|
|
painting = true;
|
|
}
|
|
else if (painting && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
|
|
{
|
|
if (action.DidPaintTiles)
|
|
editorActionManager.Add(action);
|
|
|
|
action = new PaintMarkerTileEditorAction(Template, markerLayerOverlay);
|
|
painting = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { }
|
|
IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) { yield break; }
|
|
IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) { yield break; }
|
|
|
|
public void Tick() { }
|
|
|
|
public void Dispose() { }
|
|
}
|
|
|
|
readonly struct PaintMarkerTile
|
|
{
|
|
public readonly CPos Cell;
|
|
public readonly int? Previous;
|
|
|
|
public PaintMarkerTile(CPos cell, int? previous)
|
|
{
|
|
Cell = cell;
|
|
Previous = previous;
|
|
}
|
|
}
|
|
|
|
class PaintMarkerTileEditorAction : IEditorAction
|
|
{
|
|
[FluentReference("amount", "type")]
|
|
const string AddedMarkerTiles = "notification-added-marker-tiles";
|
|
|
|
[FluentReference("amount")]
|
|
const string RemovedMarkerTiles = "notification-removed-marker-tiles";
|
|
|
|
public string Text { get; private set; }
|
|
|
|
readonly int? type;
|
|
readonly MarkerLayerOverlay markerLayerOverlay;
|
|
|
|
readonly List<PaintMarkerTile> paintTiles = new();
|
|
|
|
public bool DidPaintTiles => paintTiles.Count > 0;
|
|
|
|
public PaintMarkerTileEditorAction(
|
|
int? type,
|
|
MarkerLayerOverlay markerLayerOverlay)
|
|
{
|
|
this.markerLayerOverlay = markerLayerOverlay;
|
|
this.type = type;
|
|
}
|
|
|
|
public void Execute()
|
|
{
|
|
}
|
|
|
|
public void Do()
|
|
{
|
|
foreach (var paintTile in paintTiles)
|
|
markerLayerOverlay.SetTile(paintTile.Cell, type);
|
|
}
|
|
|
|
public void Undo()
|
|
{
|
|
foreach (var paintTile in paintTiles)
|
|
markerLayerOverlay.SetTile(paintTile.Cell, paintTile.Previous);
|
|
}
|
|
|
|
public void Add(CPos target)
|
|
{
|
|
foreach (var cell in markerLayerOverlay.CalculateMirrorPositions(target))
|
|
{
|
|
var existing = markerLayerOverlay.CellLayer[cell];
|
|
if (existing == type)
|
|
continue;
|
|
|
|
paintTiles.Add(new PaintMarkerTile(cell, existing));
|
|
markerLayerOverlay.SetTile(cell, type);
|
|
}
|
|
|
|
if (type != null)
|
|
Text = FluentProvider.GetMessage(AddedMarkerTiles, "amount", paintTiles.Count, "type", type);
|
|
else
|
|
Text = FluentProvider.GetMessage(RemovedMarkerTiles, "amount", paintTiles.Count);
|
|
}
|
|
}
|
|
|
|
class ClearSelectedMarkerTilesEditorAction : IEditorAction
|
|
{
|
|
[FluentReference("amount", "type")]
|
|
const string ClearedSelectedMarkerTiles = "notification-cleared-selected-marker-tiles";
|
|
|
|
public string Text { get; }
|
|
|
|
readonly MarkerLayerOverlay markerLayerOverlay;
|
|
readonly HashSet<CPos> tiles;
|
|
readonly int tile;
|
|
|
|
public ClearSelectedMarkerTilesEditorAction(
|
|
int tile,
|
|
MarkerLayerOverlay markerLayerOverlay)
|
|
{
|
|
this.tile = tile;
|
|
this.markerLayerOverlay = markerLayerOverlay;
|
|
|
|
tiles = new HashSet<CPos>(markerLayerOverlay.Tiles[tile]);
|
|
|
|
Text = FluentProvider.GetMessage(ClearedSelectedMarkerTiles, "amount", tiles.Count, "type", tile);
|
|
}
|
|
|
|
public void Execute()
|
|
{
|
|
Do();
|
|
}
|
|
|
|
public void Do()
|
|
{
|
|
markerLayerOverlay.ClearSelected(tile);
|
|
}
|
|
|
|
public void Undo()
|
|
{
|
|
markerLayerOverlay.SetSelected(tile, tiles);
|
|
}
|
|
}
|
|
|
|
class ClearAllMarkerTilesEditorAction : IEditorAction
|
|
{
|
|
[FluentReference("amount")]
|
|
const string ClearedAllMarkerTiles = "notification-cleared-all-marker-tiles";
|
|
|
|
public string Text { get; }
|
|
|
|
readonly MarkerLayerOverlay markerLayerOverlay;
|
|
readonly Dictionary<int, HashSet<CPos>> tiles;
|
|
|
|
public ClearAllMarkerTilesEditorAction(
|
|
MarkerLayerOverlay markerLayerOverlay)
|
|
{
|
|
this.markerLayerOverlay = markerLayerOverlay;
|
|
tiles = new Dictionary<int, HashSet<CPos>>(markerLayerOverlay.Tiles);
|
|
|
|
var allTilesCount = tiles.Values.Select(x => x.Count).Sum();
|
|
|
|
Text = FluentProvider.GetMessage(ClearedAllMarkerTiles, "amount", allTilesCount);
|
|
}
|
|
|
|
public void Execute()
|
|
{
|
|
Do();
|
|
}
|
|
|
|
public void Do()
|
|
{
|
|
markerLayerOverlay.ClearAll();
|
|
}
|
|
|
|
public void Undo()
|
|
{
|
|
markerLayerOverlay.SetAll(tiles);
|
|
}
|
|
}
|
|
}
|