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.Linq;
13 using OpenRA.Mods.Cnc.Effects;
14 using OpenRA.Mods.Common.Traits;
15 using OpenRA.Mods.Common.Traits.Radar;
16 using OpenRA.Traits;
17 
18 namespace OpenRA.Mods.Cnc.Traits
19 {
20 	[Desc("Requires `GpsWatcher` on the player actor.")]
21 	class GpsPowerInfo : SupportPowerInfo
22 	{
23 		[Desc("Delay in ticks between launching and revealing the map.")]
24 		public readonly int RevealDelay = 0;
25 
26 		public readonly string DoorImage = "atek";
27 
28 		[SequenceReference("DoorImage")]
29 		public readonly string DoorSequence = "active";
30 
31 		[PaletteReference("DoorPaletteIsPlayerPalette")]
32 		[Desc("Palette to use for rendering the launch animation")]
33 		public readonly string DoorPalette = "player";
34 
35 		[Desc("Custom palette is a player palette BaseName")]
36 		public readonly bool DoorPaletteIsPlayerPalette = true;
37 
38 		public readonly string SatelliteImage = "sputnik";
39 
40 		[SequenceReference("SatelliteImage")]
41 		public readonly string SatelliteSequence = "idle";
42 
43 		[PaletteReference("SatellitePaletteIsPlayerPalette")]
44 		[Desc("Palette to use for rendering the satellite projectile")]
45 		public readonly string SatellitePalette = "player";
46 
47 		[Desc("Custom palette is a player palette BaseName")]
48 		public readonly bool SatellitePaletteIsPlayerPalette = true;
49 
50 		[Desc("Requires an actor with an online `ProvidesRadar` to show GPS dots.")]
51 		public readonly bool RequiresActiveRadar = true;
52 
Create(ActorInitializer init)53 		public override object Create(ActorInitializer init) { return new GpsPower(init.Self, this); }
54 	}
55 
56 	class GpsPower : SupportPower, INotifyKilled, INotifySold, INotifyOwnerChanged, ITick
57 	{
58 		readonly Actor self;
59 		readonly GpsPowerInfo info;
60 		GpsWatcher owner;
61 
GpsPower(Actor self, GpsPowerInfo info)62 		public GpsPower(Actor self, GpsPowerInfo info)
63 			: base(self, info)
64 		{
65 			this.self = self;
66 			this.info = info;
67 			owner = self.Owner.PlayerActor.Trait<GpsWatcher>();
68 			owner.GpsAdd(self);
69 		}
70 
Charged(Actor self, string key)71 		public override void Charged(Actor self, string key)
72 		{
73 			self.Owner.PlayerActor.Trait<SupportPowerManager>().Powers[key].Activate(new Order());
74 		}
75 
Activate(Actor self, Order order, SupportPowerManager manager)76 		public override void Activate(Actor self, Order order, SupportPowerManager manager)
77 		{
78 			base.Activate(self, order, manager);
79 
80 			self.World.AddFrameEndTask(w =>
81 			{
82 				PlayLaunchSounds();
83 
84 				w.Add(new SatelliteLaunch(self, info));
85 			});
86 		}
87 
INotifyKilled.Killed(Actor self, AttackInfo e)88 		void INotifyKilled.Killed(Actor self, AttackInfo e) { RemoveGps(self); }
89 
INotifySold.Selling(Actor self)90 		void INotifySold.Selling(Actor self) { }
INotifySold.Sold(Actor self)91 		void INotifySold.Sold(Actor self) { RemoveGps(self); }
92 
RemoveGps(Actor self)93 		void RemoveGps(Actor self)
94 		{
95 			// Extra function just in case something needs to be added later
96 			owner.GpsRemove(self);
97 		}
98 
INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)99 		void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
100 		{
101 			RemoveGps(self);
102 			owner = newOwner.PlayerActor.Trait<GpsWatcher>();
103 			owner.GpsAdd(self);
104 		}
105 
106 		bool NoActiveRadar { get { return !self.World.ActorsHavingTrait<ProvidesRadar>(r => !r.IsTraitDisabled).Any(a => a.Owner == self.Owner); } }
107 		bool wasPaused;
108 
ITick.Tick(Actor self)109 		void ITick.Tick(Actor self)
110 		{
111 			if (!wasPaused && (IsTraitPaused || (info.RequiresActiveRadar && NoActiveRadar)))
112 			{
113 				wasPaused = true;
114 				RemoveGps(self);
115 			}
116 			else if (wasPaused && !IsTraitPaused && !(info.RequiresActiveRadar && NoActiveRadar))
117 			{
118 				wasPaused = false;
119 				owner.GpsAdd(self);
120 			}
121 		}
122 	}
123 }
124