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