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.Traits;
13 
14 namespace OpenRA.Mods.Common.Traits
15 {
16 	[Desc("Toggles a condition on and off when a specified order type is received.")]
17 	public class ToggleConditionOnOrderInfo : PausableConditionalTraitInfo
18 	{
19 		[FieldLoader.Require]
20 		[GrantedConditionReference]
21 		[Desc("Condition to grant.")]
22 		public readonly string Condition = null;
23 
24 		[FieldLoader.Require]
25 		[Desc("Order name that toggles the condition.")]
26 		public readonly string OrderName = null;
27 
28 		[NotificationReference("Sounds")]
29 		public readonly string EnabledSound = null;
30 
31 		[NotificationReference("Speech")]
32 		public readonly string EnabledSpeech = null;
33 
34 		[NotificationReference("Sounds")]
35 		public readonly string DisabledSound = null;
36 
37 		[NotificationReference("Speech")]
38 		public readonly string DisabledSpeech = null;
39 
Create(ActorInitializer init)40 		public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(init.Self, this); }
41 	}
42 
43 	public class ToggleConditionOnOrder : PausableConditionalTrait<ToggleConditionOnOrderInfo>, IResolveOrder
44 	{
45 		ConditionManager conditionManager;
46 		int conditionToken = ConditionManager.InvalidConditionToken;
47 
48 		// If the trait is paused this may be true with no condition granted
49 		[Sync]
50 		bool enabled = false;
51 
ToggleConditionOnOrder(Actor self, ToggleConditionOnOrderInfo info)52 		public ToggleConditionOnOrder(Actor self, ToggleConditionOnOrderInfo info)
53 			: base(info) { }
54 
Created(Actor self)55 		protected override void Created(Actor self)
56 		{
57 			base.Created(self);
58 
59 			conditionManager = self.TraitOrDefault<ConditionManager>();
60 		}
61 
SetCondition(Actor self, bool granted)62 		void SetCondition(Actor self, bool granted)
63 		{
64 			if (conditionManager == null)
65 				return;
66 
67 			if (granted && conditionToken == ConditionManager.InvalidConditionToken)
68 			{
69 				conditionToken = conditionManager.GrantCondition(self, Info.Condition);
70 
71 				if (Info.EnabledSound != null)
72 					Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.EnabledSound, self.Owner.Faction.InternalName);
73 
74 				if (Info.EnabledSpeech != null)
75 					Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName);
76 			}
77 			else if (!granted && conditionToken != ConditionManager.InvalidConditionToken)
78 			{
79 				conditionToken = conditionManager.RevokeCondition(self, conditionToken);
80 
81 				if (Info.DisabledSound != null)
82 					Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.DisabledSound, self.Owner.Faction.InternalName);
83 
84 				if (Info.DisabledSpeech != null)
85 					Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.DisabledSpeech, self.Owner.Faction.InternalName);
86 			}
87 		}
88 
IResolveOrder.ResolveOrder(Actor self, Order order)89 		void IResolveOrder.ResolveOrder(Actor self, Order order)
90 		{
91 			if (!IsTraitDisabled && !IsTraitPaused && order.OrderString == Info.OrderName)
92 			{
93 				enabled = !enabled;
94 				SetCondition(self, enabled);
95 			}
96 		}
97 
TraitDisabled(Actor self)98 		protected override void TraitDisabled(Actor self)
99 		{
100 			// Disabling the trait resets the condition
101 			enabled = false;
102 			SetCondition(self, false);
103 		}
104 
TraitPaused(Actor self)105 		protected override void TraitPaused(Actor self)
106 		{
107 			// Pausing the trait removes the condition
108 			// but does not reset the enabled value
109 			SetCondition(self, false);
110 		}
111 
TraitResumed(Actor self)112 		protected override void TraitResumed(Actor self)
113 		{
114 			// Unpausing the trait restores the previous state
115 			SetCondition(self, enabled);
116 		}
117 	}
118 }
119