1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef COMMAND_H
4 #define COMMAND_H
5 
6 #include <string>
7 #include <climits> // for INT_MAX
8 
9 #include "System/creg/creg_cond.h"
10 #include "System/float3.h"
11 #include <vector>
12 
13 // ID's lower than 0 are reserved for build options (cmd -x = unitdefs[x])
14 #define CMD_STOP                   0
15 #define CMD_INSERT                 1
16 #define CMD_REMOVE                 2
17 #define CMD_WAIT                   5
18 #define CMD_TIMEWAIT               6
19 #define CMD_DEATHWAIT              7
20 #define CMD_SQUADWAIT              8
21 #define CMD_GATHERWAIT             9
22 #define CMD_MOVE                  10
23 #define CMD_PATROL                15
24 #define CMD_FIGHT                 16
25 #define CMD_ATTACK                20
26 #define CMD_AREA_ATTACK           21
27 #define CMD_GUARD                 25
28 #define CMD_AISELECT              30 //FIXME REMOVE
29 #define CMD_GROUPSELECT           35
30 #define CMD_GROUPADD              36
31 #define CMD_GROUPCLEAR            37
32 #define CMD_REPAIR                40
33 #define CMD_FIRE_STATE            45
34 #define CMD_MOVE_STATE            50
35 #define CMD_SETBASE               55
36 #define CMD_INTERNAL              60
37 #define CMD_SELFD                 65
38 #define CMD_SET_WANTED_MAX_SPEED  70
39 #define CMD_LOAD_UNITS            75
40 #define CMD_LOAD_ONTO             76
41 #define CMD_UNLOAD_UNITS          80
42 #define CMD_UNLOAD_UNIT           81
43 #define CMD_ONOFF                 85
44 #define CMD_RECLAIM               90
45 #define CMD_CLOAK                 95
46 #define CMD_STOCKPILE            100
47 #define CMD_DGUN                 105
48 #define CMD_RESTORE              110
49 #define CMD_REPEAT               115
50 #define CMD_TRAJECTORY           120
51 #define CMD_RESURRECT            125
52 #define CMD_CAPTURE              130
53 #define CMD_AUTOREPAIRLEVEL      135
54 #define CMD_LOOPBACKATTACK       140
55 #define CMD_IDLEMODE             145
56 #define CMD_FAILED               150
57 
58 #define CMDTYPE_ICON                        0  // expect 0 parameters in return
59 #define CMDTYPE_ICON_MODE                   5  // expect 1 parameter in return (number selected mode)
60 #define CMDTYPE_ICON_MAP                   10  // expect 3 parameters in return (mappos)
61 #define CMDTYPE_ICON_AREA                  11  // expect 4 parameters in return (mappos+radius)
62 #define CMDTYPE_ICON_UNIT                  12  // expect 1 parameters in return (unitid)
63 #define CMDTYPE_ICON_UNIT_OR_MAP           13  // expect 1 parameters in return (unitid) or 3 parameters in return (mappos)
64 #define CMDTYPE_ICON_FRONT                 14  // expect 3 or 6 parameters in return (middle of front and right side of front if a front was defined)
65 #define CMDTYPE_COMBO_BOX                  15  // expect 1 parameter in return (number selected option)
66 #define CMDTYPE_ICON_UNIT_OR_AREA          16  // expect 1 parameter in return (unitid) or 4 parameters in return (mappos+radius)
67 #define CMDTYPE_NEXT                       17  // used with CMD_INTERNAL
68 #define CMDTYPE_PREV                       18  // used with CMD_INTERNAL
69 #define CMDTYPE_ICON_UNIT_FEATURE_OR_AREA  19  // expect 1 parameter in return (unitid or featureid+unitHandler->MaxUnits() (id>unitHandler->MaxUnits()=feature)) or 4 parameters in return (mappos+radius)
70 #define CMDTYPE_ICON_BUILDING              20  // expect 3 parameters in return (mappos)
71 #define CMDTYPE_CUSTOM                     21  // used with CMD_INTERNAL
72 #define CMDTYPE_ICON_UNIT_OR_RECTANGLE     22  // expect 1 parameter in return (unitid)
73                                                //     or 3 parameters in return (mappos)
74                                                //     or 6 parameters in return (startpos+endpos)
75 #define CMDTYPE_NUMBER                     23  // expect 1 parameter in return (number)
76 
77 
78 // wait codes
79 #define CMD_WAITCODE_TIMEWAIT    1.0f
80 #define CMD_WAITCODE_DEATHWAIT   2.0f
81 #define CMD_WAITCODE_SQUADWAIT   3.0f
82 #define CMD_WAITCODE_GATHERWAIT  4.0f
83 
84 
85 // bits for the option field of Command
86 #define META_KEY        (1 << 2) //   4
87 #define INTERNAL_ORDER  (1 << 3) //   8
88 #define RIGHT_MOUSE_KEY (1 << 4) //  16
89 #define SHIFT_KEY       (1 << 5) //  32
90 #define CONTROL_KEY     (1 << 6) //  64
91 #define ALT_KEY         (1 << 7) // 128
92 
93 enum {
94 	MOVESTATE_NONE     = -1,
95 	MOVESTATE_HOLDPOS  =  0,
96 	MOVESTATE_MANEUVER =  1,
97 	MOVESTATE_ROAM     =  2,
98 };
99 enum {
100 	FIRESTATE_NONE       = -1,
101 	FIRESTATE_HOLDFIRE   =  0,
102 	FIRESTATE_RETURNFIRE =  1,
103 	FIRESTATE_FIREATWILL =  2,
104 };
105 
106 namespace springLegacyAI {
107 
108 struct Command
109 {
110 private:
CR_DECLARE_STRUCTCommand111 	CR_DECLARE_STRUCT(Command)
112 /*
113 	TODO check if usage of System/MemPool.h for this struct improves performance
114 */
115 
116 public:
117 	Command()
118 		: aiCommandId(-1)
119 		, options(0)
120 		, tag(0)
121 		, timeOut(INT_MAX)
122 		, id(0)
123 	{}
124 
CommandCommand125 	Command(const Command& c) {
126 		*this = c;
127 	}
128 
129 	Command& operator = (const Command& c) {
130 		id = c.id;
131 		aiCommandId = c.aiCommandId;
132 		options = c.options;
133 		tag = c.tag;
134 		timeOut = c.timeOut;
135 		params = c.params;
136 		return *this;
137 	}
138 
CommandCommand139 	Command(const float3& pos)
140 		: aiCommandId(-1)
141 		, options(0)
142 		, tag(0)
143 		, timeOut(INT_MAX)
144 		, id(0)
145 	{
146 		PushPos(pos);
147 	}
148 
CommandCommand149 	Command(const int cmdID)
150 		: aiCommandId(-1)
151 		, options(0)
152 		, tag(0)
153 		, timeOut(INT_MAX)
154 		, id(cmdID)
155 	{}
156 
CommandCommand157 	Command(const int cmdID, const float3& pos)
158 		: aiCommandId(-1)
159 		, options(0)
160 		, tag(0)
161 		, timeOut(INT_MAX)
162 		, id(cmdID)
163 	{
164 		PushPos(pos);
165 	}
166 
CommandCommand167 	Command(const int cmdID, const unsigned char cmdOptions)
168 		: aiCommandId(-1)
169 		, options(cmdOptions)
170 		, tag(0)
171 		, timeOut(INT_MAX)
172 		, id(cmdID)
173 	{}
174 
CommandCommand175 	Command(const int cmdID, const unsigned char cmdOptions, const float param)
176 		: aiCommandId(-1)
177 		, options(cmdOptions)
178 		, tag(0)
179 		, timeOut(INT_MAX)
180 		, id(cmdID)
181 	{
182 		PushParam(param);
183 	}
184 
CommandCommand185 	Command(const int cmdID, const unsigned char cmdOptions, const float3& pos)
186 		: aiCommandId(-1)
187 		, options(cmdOptions)
188 		, tag(0)
189 		, timeOut(INT_MAX)
190 		, id(cmdID)
191 	{
192 		PushPos(pos);
193 	}
194 
CommandCommand195 	Command(const int cmdID, const unsigned char cmdOptions, const float param, const float3& pos)
196 		: aiCommandId(-1)
197 		, options(cmdOptions)
198 		, tag(0)
199 		, timeOut(INT_MAX)
200 		, id(cmdID)
201 	{
202 		PushParam(param);
203 		PushPos(pos);
204 	}
205 
~CommandCommand206 	~Command() { params.clear(); }
207 
208 	// returns true if the command references another object and
209 	// in this case also returns the param index of the object in cpos
IsObjectCommandCommand210 	bool IsObjectCommand(int& cpos) const {
211 		const int psize = params.size();
212 
213 		switch (id) {
214 			case CMD_ATTACK:
215 			case CMD_FIGHT:
216 			case CMD_DGUN:
217 				cpos = 0;
218 				return (1 <= psize && psize < 3);
219 			case CMD_GUARD:
220 			case CMD_LOAD_ONTO:
221 				cpos = 0;
222 				return (psize >= 1);
223 			case CMD_CAPTURE:
224 			case CMD_LOAD_UNITS:
225 			case CMD_RECLAIM:
226 			case CMD_REPAIR:
227 			case CMD_RESURRECT:
228 				cpos = 0;
229 				return (1 <= psize && psize < 4);
230 			case CMD_UNLOAD_UNIT:
231 				cpos = 3;
232 				return (psize >= 4);
233 			case CMD_INSERT: {
234 				if (psize < 3)
235 					return false;
236 
237 				Command icmd((int)params[1], (unsigned char)params[2]);
238 
239 				for (int p = 3; p < (int)psize; p++)
240 					icmd.params.push_back(params[p]);
241 
242 				if (!icmd.IsObjectCommand(cpos))
243 					return false;
244 
245 				cpos += 3;
246 				return true;
247 			}
248 		}
249 		return false;
250 	}
251 
IsAreaCommandCommand252 	bool IsAreaCommand() const {
253 		switch(id) {
254 			case CMD_CAPTURE:
255 			case CMD_LOAD_UNITS:
256 			case CMD_RECLAIM:
257 			case CMD_REPAIR:
258 			case CMD_RESURRECT:
259 				// params[0..2] always holds the position, params[3] the radius
260 				return (params.size() == 4);
261 			case CMD_UNLOAD_UNITS:
262 				return (params.size() == 5);
263 			case CMD_AREA_ATTACK:
264 				return true;
265 		}
266 		return false;
267 	}
268 
PushParamCommand269 	void PushParam(float par) { params.push_back(par); }
GetParamCommand270 	const float& GetParam(size_t idx) const { return params[idx]; }
271 
272 	/// const safe_vector<float>& GetParams() const { return params; }
GetParamsCountCommand273 	size_t GetParamsCount() const { return params.size(); }
274 
SetIDCommand275 	void SetID(int id)
276 #ifndef _MSC_VER
277 		__attribute__ ((deprecated))
278 #endif
279 		{ this->id = id; params.clear(); }
GetIDCommand280 	const int& GetID() const { return id; }
281 
PushPosCommand282 	void PushPos(const float3& pos)
283 	{
284 		params.push_back(pos.x);
285 		params.push_back(pos.y);
286 		params.push_back(pos.z);
287 	}
288 
PushPosCommand289 	void PushPos(const float* pos)
290 	{
291 		params.push_back(pos[0]);
292 		params.push_back(pos[1]);
293 		params.push_back(pos[2]);
294 	}
295 
GetPosCommand296 	float3 GetPos(const int idx) const {
297 		float3 p;
298 		p.x = params[idx    ];
299 		p.y = params[idx + 1];
300 		p.z = params[idx + 2];
301 		return p;
302 	}
303 
SetPosCommand304 	void SetPos(const int idx, const float3& p) {
305 		params[idx    ] = p.x;
306 		params[idx + 1] = p.y;
307 		params[idx + 2] = p.z;
308 	}
309 
310 public:
311 	/**
312 	 * AI Command callback id (passed in on handleCommand, returned
313 	 * in CommandFinished event)
314 	 */
315 	int aiCommandId;
316 
317 	/// option bits (RIGHT_MOUSE_KEY, ...)
318 	unsigned char options;
319 
320 	/// command parameters
321 	std::vector<float> params;
322 
323 	/// unique id within a CCommandQueue
324 	unsigned int tag;
325 
326 	/**
327 	 * Remove this command after this frame (absolute).
328 	 * This can only be set locally and is not sent over the network.
329 	 * (used for temporary orders)
330 	 * Examples:
331 	 * - 0
332 	 * - MAX_INT
333 	 * - currenFrame + 60
334 	 */
335 	int timeOut;
336 
337 //private:
338 	/// CMD_xxx code  (custom codes can also be used)
339 	int id;
340 };
341 
342 
343 struct CommandDescription {
344 private:
CR_DECLARE_STRUCTCommandDescription345 	CR_DECLARE_STRUCT(CommandDescription)
346 
347 public:
348 	CommandDescription():
349 		id(0),
350 		type(CMDTYPE_ICON),
351 		hidden(false),
352 		disabled(false),
353 		showUnique(false),
354 		onlyTexture(false) {}
355 
356 	/// CMD_xxx code (custom codes can also be used)
357 	int id;
358 	/// CMDTYPE_xxx code
359 	int type;
360 
361 	/// command name
362 	std::string name;
363 	/// the associated command action binding name
364 	std::string action;
365 	/// button texture
366 	std::string iconname;
367 	/// mouse cursor
368 	std::string mouseicon;
369 	/// tooltip text
370 	std::string tooltip;
371 
372 	/// if true dont show a button for the command
373 	bool hidden;
374 	/// for greying-out commands
375 	bool disabled;
376 	/// command only applies to single units
377 	bool showUnique;
378 	/// do not draw the name if the texture is available
379 	bool onlyTexture;
380 
381 	std::vector<std::string> params;
382 };
383 
384 } // namespace springLegacyAI
385 
386 #endif // COMMAND_H
387