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.Mods.Common.Activities;
14 using OpenRA.Mods.Common.Orders;
15 using OpenRA.Primitives;
16 using OpenRA.Traits;
17 
18 namespace OpenRA.Mods.Common.Traits
19 {
20 	[Desc("Donate money to actors with the `AcceptsDeliveredCash` trait.")]
21 	class DeliversCashInfo : ITraitInfo
22 	{
23 		[Desc("The amount of cash the owner receives.")]
24 		public readonly int Payload = 500;
25 
26 		[Desc("The amount of experience the donating player receives.")]
27 		public readonly int PlayerExperience = 0;
28 
29 		[Desc("Identifier checked against AcceptsDeliveredCash.ValidTypes. Only needed if the latter is not empty.")]
30 		public readonly string Type = null;
31 
32 		[Desc("Sound to play when delivering cash")]
33 		public readonly string[] Sounds = { };
34 
35 		[VoiceReference]
36 		public readonly string Voice = "Action";
37 
Create(ActorInitializer init)38 		public object Create(ActorInitializer init) { return new DeliversCash(this); }
39 	}
40 
41 	class DeliversCash : IIssueOrder, IResolveOrder, IOrderVoice, INotifyCashTransfer
42 	{
43 		readonly DeliversCashInfo info;
44 
DeliversCash(DeliversCashInfo info)45 		public DeliversCash(DeliversCashInfo info)
46 		{
47 			this.info = info;
48 		}
49 
50 		public IEnumerable<IOrderTargeter> Orders
51 		{
52 			get { yield return new DeliversCashOrderTargeter(); }
53 		}
54 
IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)55 		public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
56 		{
57 			if (order.OrderID != "DeliverCash")
58 				return null;
59 
60 			return new Order(order.OrderID, self, target, queued);
61 		}
62 
VoicePhraseForOrder(Actor self, Order order)63 		public string VoicePhraseForOrder(Actor self, Order order)
64 		{
65 			if (order.OrderString != "DeliverCash")
66 				return null;
67 
68 			return info.Voice;
69 		}
70 
ResolveOrder(Actor self, Order order)71 		public void ResolveOrder(Actor self, Order order)
72 		{
73 			if (order.OrderString != "DeliverCash")
74 				return;
75 
76 			self.QueueActivity(order.Queued, new DonateCash(self, order.Target, info.Payload, info.PlayerExperience));
77 			self.ShowTargetLines();
78 		}
79 
INotifyCashTransfer.OnAcceptingCash(Actor self, Actor donor)80 		void INotifyCashTransfer.OnAcceptingCash(Actor self, Actor donor) { }
81 
INotifyCashTransfer.OnDeliveringCash(Actor self, Actor acceptor)82 		void INotifyCashTransfer.OnDeliveringCash(Actor self, Actor acceptor)
83 		{
84 			if (info.Sounds.Length > 0)
85 				Game.Sound.Play(SoundType.World, info.Sounds, self.World, self.CenterPosition);
86 		}
87 
88 		public class DeliversCashOrderTargeter : UnitOrderTargeter
89 		{
DeliversCashOrderTargeter()90 			public DeliversCashOrderTargeter()
91 				: base("DeliverCash", 5, "enter", false, true) { }
92 
CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)93 			public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
94 			{
95 				var type = self.Info.TraitInfo<DeliversCashInfo>().Type;
96 				var targetInfo = target.Info.TraitInfoOrDefault<AcceptsDeliveredCashInfo>();
97 				return targetInfo != null
98 					&& targetInfo.ValidStances.HasStance(target.Owner.Stances[self.Owner])
99 					&& (targetInfo.ValidTypes.Count == 0
100 						|| (!string.IsNullOrEmpty(type) && targetInfo.ValidTypes.Contains(type)));
101 			}
102 
CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)103 			public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
104 			{
105 				var type = self.Info.TraitInfo<DeliversCashInfo>().Type;
106 				var targetInfo = target.Info.TraitInfoOrDefault<AcceptsDeliveredCashInfo>();
107 				return targetInfo != null
108 					&& targetInfo.ValidStances.HasStance(target.Owner.Stances[self.Owner])
109 					&& (targetInfo.ValidTypes.Count == 0
110 						|| (!string.IsNullOrEmpty(type) && targetInfo.ValidTypes.Contains(type)));
111 			}
112 		}
113 	}
114 }
115