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 System.Linq;
14 using OpenRA.Primitives;
15 using OpenRA.Traits;
16 
17 namespace OpenRA.Mods.Common.Traits
18 {
19 	[Desc("Adds capacity to a player's harvested resource limit.")]
20 	public class StoresResourcesInfo : ITraitInfo
21 	{
22 		[FieldLoader.Require]
23 		public readonly int Capacity = 0;
24 
25 		[FieldLoader.Require]
26 		[Desc("Number of little squares used to display how filled unit is.")]
27 		public readonly int PipCount = 0;
28 
29 		public readonly PipType PipColor = PipType.Yellow;
30 
Create(ActorInitializer init)31 		public object Create(ActorInitializer init) { return new StoresResources(init.Self, this); }
32 	}
33 
34 	public class StoresResources : IPips, INotifyOwnerChanged, INotifyCapture, IStoreResources, ISync, INotifyKilled, INotifyAddedToWorld, INotifyRemovedFromWorld
35 	{
36 		readonly StoresResourcesInfo info;
37 		PlayerResources player;
38 
39 		[Sync]
40 		public int Stored { get { return player.ResourceCapacity == 0 ? 0 : (int)((long)info.Capacity * player.Resources / player.ResourceCapacity); } }
41 
StoresResources(Actor self, StoresResourcesInfo info)42 		public StoresResources(Actor self, StoresResourcesInfo info)
43 		{
44 			this.info = info;
45 			player = self.Owner.PlayerActor.Trait<PlayerResources>();
46 		}
47 
48 		int IStoreResources.Capacity { get { return info.Capacity; } }
49 
INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)50 		void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
51 		{
52 			player = newOwner.PlayerActor.Trait<PlayerResources>();
53 		}
54 
INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet<CaptureType> captureTypes)55 		void INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet<CaptureType> captureTypes)
56 		{
57 			var resources = Stored;
58 			oldOwner.PlayerActor.Trait<PlayerResources>().TakeResources(resources);
59 			newOwner.PlayerActor.Trait<PlayerResources>().GiveResources(resources);
60 		}
61 
INotifyKilled.Killed(Actor self, AttackInfo e)62 		void INotifyKilled.Killed(Actor self, AttackInfo e)
63 		{
64 			// Lose the stored resources
65 			player.TakeResources(Stored);
66 		}
67 
IPips.GetPips(Actor self)68 		IEnumerable<PipType> IPips.GetPips(Actor self)
69 		{
70 			return Enumerable.Range(0, info.PipCount).Select(i =>
71 				player.Resources * info.PipCount > i * player.ResourceCapacity
72 				? info.PipColor : PipType.Transparent);
73 		}
74 
INotifyAddedToWorld.AddedToWorld(Actor self)75 		void INotifyAddedToWorld.AddedToWorld(Actor self)
76 		{
77 			player.AddStorage(info.Capacity);
78 		}
79 
INotifyRemovedFromWorld.RemovedFromWorld(Actor self)80 		void INotifyRemovedFromWorld.RemovedFromWorld(Actor self)
81 		{
82 			player.RemoveStorage(info.Capacity);
83 		}
84 	}
85 }
86