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 OpenRA.Activities;
13 using OpenRA.Graphics;
14 using OpenRA.Traits;
15 
16 namespace OpenRA.Mods.Common.Traits.Render
17 {
18 	[Desc("Displays an overlay whenever resources are harvested by the actor.")]
19 	class WithHarvestOverlayInfo : ITraitInfo, Requires<RenderSpritesInfo>, Requires<BodyOrientationInfo>
20 	{
21 		[SequenceReference]
22 		[Desc("Sequence name to use")]
23 		public readonly string Sequence = "harvest";
24 
25 		[Desc("Position relative to body")]
26 		public readonly WVec LocalOffset = WVec.Zero;
27 
28 		[PaletteReference]
29 		public readonly string Palette = "effect";
30 
Create(ActorInitializer init)31 		public object Create(ActorInitializer init) { return new WithHarvestOverlay(init.Self, this); }
32 	}
33 
34 	class WithHarvestOverlay : INotifyHarvesterAction
35 	{
36 		readonly WithHarvestOverlayInfo info;
37 		readonly Animation anim;
38 		bool visible;
39 
WithHarvestOverlay(Actor self, WithHarvestOverlayInfo info)40 		public WithHarvestOverlay(Actor self, WithHarvestOverlayInfo info)
41 		{
42 			this.info = info;
43 			var rs = self.Trait<RenderSprites>();
44 			var body = self.Trait<BodyOrientation>();
45 
46 			anim = new Animation(self.World, rs.GetImage(self), RenderSprites.MakeFacingFunc(self));
47 			anim.IsDecoration = true;
48 			anim.Play(info.Sequence);
49 			rs.Add(new AnimationWithOffset(anim,
50 				() => body.LocalToWorld(info.LocalOffset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
51 				() => !visible,
52 				p => ZOffsetFromCenter(self, p, 0)), info.Palette);
53 		}
54 
INotifyHarvesterAction.Harvested(Actor self, ResourceType resource)55 		void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource)
56 		{
57 			if (visible)
58 				return;
59 
60 			visible = true;
61 			anim.PlayThen(info.Sequence, () => visible = false);
62 		}
63 
INotifyHarvesterAction.MovingToResources(Actor self, CPos targetCell)64 		void INotifyHarvesterAction.MovingToResources(Actor self, CPos targetCell) { }
INotifyHarvesterAction.MovingToRefinery(Actor self, Actor targetRefinery)65 		void INotifyHarvesterAction.MovingToRefinery(Actor self, Actor targetRefinery) { }
INotifyHarvesterAction.MovementCancelled(Actor self)66 		void INotifyHarvesterAction.MovementCancelled(Actor self) { }
INotifyHarvesterAction.Docked()67 		void INotifyHarvesterAction.Docked() { }
INotifyHarvesterAction.Undocked()68 		void INotifyHarvesterAction.Undocked() { }
69 
ZOffsetFromCenter(Actor self, WPos pos, int offset)70 		public static int ZOffsetFromCenter(Actor self, WPos pos, int offset)
71 		{
72 			var delta = self.CenterPosition - pos;
73 			return delta.Y + delta.Z + offset;
74 		}
75 	}
76 }
77