1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef WAIT_COMMANDS_AI_H
4 #define WAIT_COMMANDS_AI_H
5 
6 #include <map>
7 #include <set>
8 #include <deque>
9 #include <string>
10 #include "System/Object.h"
11 #include "System/Misc/SpringTime.h"
12 #include "Sim/Units/UnitSet.h"
13 
14 class float3;
15 class CObject;
16 class CUnit;
17 struct Command;
18 class CCommandQueue;
19 
20 
21 class CWaitCommandsAI {
22 	CR_DECLARE_STRUCT(CWaitCommandsAI)
23 	CR_DECLARE_SUB(Wait)
24 	CR_DECLARE_SUB(TimeWait)
25 	CR_DECLARE_SUB(DeathWait)
26 	CR_DECLARE_SUB(SquadWait)
27 	CR_DECLARE_SUB(GatherWait)
28 	public:
29 		CWaitCommandsAI();
30 		~CWaitCommandsAI();
31 
32 		void Update();
33 		void DrawCommands() const;
34 
35 		// called from SelectedUnits
36 		void AddTimeWait(const Command& cmd);
37 		void AddDeathWait(const Command& cmd);
38 		void AddSquadWait(const Command& cmd);
39 		void AddGatherWait(const Command& cmd);
40 
41 		/// acknowledge a command received from the network
42 		void AcknowledgeCommand(const Command& cmd);
43 
44 		/// search a new unit's queue and add it to its wait commands
45 		void AddLocalUnit(CUnit* unit, const CUnit* builder);
46 
47 		void ClearUnitQueue(CUnit* unit, const CCommandQueue& queue);
48 		void RemoveWaitCommand(CUnit* unit, const Command& cmd);
49 
50 		void AddIcon(const Command& cmd, const float3& pos) const;
51 
52 	private:
53 		class Wait;
54 		bool InsertWaitObject(Wait* wait);
55 		void RemoveWaitObject(Wait* wait);
56 
57 	private:
58 		typedef int KeyType;
59 		typedef std::map<KeyType, Wait*> WaitMap;
60 		WaitMap waitMap;
61 		WaitMap unackedMap;
62 
63 	private:
64 		// Wait Base Class
65 		class Wait : public CObject {
66 			CR_DECLARE(Wait)
67 			public:
68 				virtual ~Wait();
69 				virtual void DependentDied(CObject* o) = 0; // from CObject
70 				virtual void AddUnit(CUnit* unit) = 0;
71 				virtual void RemoveUnit(CUnit* unit) = 0;
72 				virtual void Update() = 0;
Draw()73 				virtual void Draw() const {}
AddUnitPosition(const float3 & pos)74 				virtual void AddUnitPosition(const float3& pos) {}
GetStateText()75 				virtual const std::string& GetStateText() const { return noText; }
76 			public:
GetDeadTime()77 				spring_time GetDeadTime() const { return deadTime; }
GetCode()78 				float GetCode() const { return code; }
GetKey()79 				KeyType GetKey() const { return key; }
80 			public:
81 				static KeyType GetKeyFromFloat(float f);
82 				static float GetFloatFromKey(KeyType k);
83 			protected:
84 				Wait(float code);
85 				enum WaitState {
86 					Active, Queued, Missing
87 				};
88 				WaitState GetWaitState(const CUnit* unit) const;
89 				bool IsWaitingOn(const CUnit* unit) const;
90 				void SendCommand(const Command& cmd, const CUnitSet& unitSet);
91 				void SendWaitCommand(const CUnitSet& unitSet);
92 				/// removes the pointed at unit and returns an iterator to the next unit in the set
93 				CUnitSet::iterator RemoveUnitFromSet(CUnitSet::iterator it, CUnitSet& unitSet);
94 			protected:
95 				float code;
96 				KeyType key;
97 				bool valid;
98 				spring_time deadTime;
99 			protected:
100 				static KeyType GetNewKey();
101 			private:
102 				static KeyType keySource;
103 				static const std::string noText;
104 				void PostLoad();
105 		};
106 
107 		// TimeWait
108 		class TimeWait : public Wait {
109 			CR_DECLARE(TimeWait)
110 			public:
111 				static TimeWait* New(const Command& cmd, CUnit* unit);
112 				static TimeWait* New(int duration, CUnit* unit);
113 				~TimeWait();
114 				void DependentDied(CObject* o);
115 				void AddUnit(CUnit* unit);
116 				void RemoveUnit(CUnit* unit);
117 				void Update();
118 				void Draw() const;
119 				const std::string& GetStateText() const;
GetDuration()120 				int GetDuration() const { return duration; }
121 			private:
122 				TimeWait(const Command& cmd, CUnit* unit);
123 				TimeWait(int duration, CUnit* unit);
124 			private:
125 				CUnit* unit;
126 				bool enabled;
127 				int duration;
128 				int endFrame;
129 				bool factory;
130 		};
131 
132 		// DeathWait
133 		class DeathWait : public Wait {
134 			CR_DECLARE(DeathWait)
135 			public:
136 				static DeathWait* New(const Command& cmd);
137 				~DeathWait();
138 				void DependentDied(CObject* o);
139 				void AddUnit(CUnit* unit);
140 				void RemoveUnit(CUnit* unit);
141 				void Update();
142 				void Draw() const;
143 				void AddUnitPosition(const float3& pos);
144 			private:
145 				DeathWait(const Command& cmd);
146 				void SelectAreaUnits(const float3& pos0, const float3& pos1,
147 				                     CUnitSet& units, bool enemies);
148 			private:
149 				CUnitSet waitUnits;
150 				CUnitSet deathUnits;
151 				std::vector<float3> unitPos;
152 		};
153 
154 		// SquadWait
155 		class SquadWait : public Wait {
156 			CR_DECLARE(SquadWait)
157 			public:
158 				static SquadWait* New(const Command& cmd);
159 				~SquadWait();
160 				void DependentDied(CObject* o);
161 				void AddUnit(CUnit* unit);
162 				void RemoveUnit(CUnit* unit);
163 				void Update();
164 				void Draw() const;
GetStateText()165 				const std::string& GetStateText() const { return stateText; }
166 			private:
167 				SquadWait(const Command& cmd);
168 				void UpdateText();
169 			private:
170 				int squadCount;
171 				CUnitSet buildUnits;
172 				CUnitSet waitUnits;
173 				std::string stateText;
174 		};
175 
176 		// GatherWait
177 		class GatherWait : public Wait {
178 			CR_DECLARE(GatherWait)
179 			public:
180 				static GatherWait* New(const Command& cmd);
181 				~GatherWait();
182 				void DependentDied(CObject * o);
183 				void AddUnit(CUnit* unit);
184 				void RemoveUnit(CUnit* unit);
185 				void Update();
186 			private:
187 				GatherWait(const Command& cmd);
188 			private:
189 				CUnitSet waitUnits;
190 		};
191 };
192 
193 
194 extern CWaitCommandsAI waitCommandsAI;
195 
196 
197 #endif /* WAIT_COMMANDS_AI_H */
198