1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System.Collections.Generic; 13 using OpenRA.Graphics; 14 using OpenRA.Traits; 15 16 namespace OpenRA.Mods.Common.Traits 17 { 18 [Desc("Required for the map editor to work. Attach this to the world actor.")] 19 public class EditorSelectionLayerInfo : ITraitInfo 20 { 21 [PaletteReference] 22 [Desc("Palette to use for rendering the placement sprite.")] 23 public readonly string Palette = TileSet.TerrainPaletteInternalName; 24 25 [Desc("Sequence image where the selection overlay types are defined.")] 26 public readonly string Image = "editor-overlay"; 27 28 [SequenceReference("Image")] 29 [Desc("Sequence to use for the copy overlay.")] 30 public readonly string CopySequence = "copy"; 31 32 [SequenceReference("Image")] 33 [Desc("Sequence to use for the paste overlay.")] 34 public readonly string PasteSequence = "paste"; 35 Create(ActorInitializer init)36 public virtual object Create(ActorInitializer init) { return new EditorSelectionLayer(init.Self, this); } 37 } 38 39 public class EditorSelectionLayer : IWorldLoaded, IRenderAboveShroud 40 { 41 readonly EditorSelectionLayerInfo info; 42 readonly Map map; 43 readonly Sprite copySprite; 44 readonly Sprite pasteSprite; 45 PaletteReference palette; 46 47 public CellRegion CopyRegion { get; private set; } 48 public CellRegion PasteRegion { get; private set; } 49 EditorSelectionLayer(Actor self, EditorSelectionLayerInfo info)50 public EditorSelectionLayer(Actor self, EditorSelectionLayerInfo info) 51 { 52 if (self.World.Type != WorldType.Editor) 53 return; 54 55 this.info = info; 56 map = self.World.Map; 57 copySprite = map.Rules.Sequences.GetSequence(info.Image, info.CopySequence).GetSprite(0); 58 pasteSprite = map.Rules.Sequences.GetSequence(info.Image, info.PasteSequence).GetSprite(0); 59 } 60 IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)61 void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr) 62 { 63 if (w.Type != WorldType.Editor) 64 return; 65 66 palette = wr.Palette(info.Palette); 67 } 68 SetCopyRegion(CPos start, CPos end)69 public void SetCopyRegion(CPos start, CPos end) 70 { 71 CopyRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end }); 72 } 73 SetPasteRegion(CPos start, CPos end)74 public void SetPasteRegion(CPos start, CPos end) 75 { 76 PasteRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end }); 77 } 78 Clear()79 public void Clear() 80 { 81 CopyRegion = PasteRegion = null; 82 } 83 IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr)84 IEnumerable<IRenderable> IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr) 85 { 86 if (wr.World.Type != WorldType.Editor) 87 yield break; 88 89 if (CopyRegion != null) 90 foreach (var c in CopyRegion) 91 yield return new SpriteRenderable(copySprite, wr.World.Map.CenterOfCell(c), 92 WVec.Zero, -511, palette, 1f, true); 93 94 if (PasteRegion != null) 95 foreach (var c in PasteRegion) 96 yield return new SpriteRenderable(pasteSprite, wr.World.Map.CenterOfCell(c), 97 WVec.Zero, -511, palette, 1f, true); 98 } 99 100 bool IRenderAboveShroud.SpatiallyPartitionable { get { return false; } } 101 } 102 } 103