1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #include "Interface/AISCommands.h"
4 
5 #include <limits.h>
6 #include <stdlib.h>
7 
initSUnitCommand(void * sUnitCommand)8 void initSUnitCommand(void* sUnitCommand) {
9 
10 	struct SStopUnitCommand* scmd = (struct SStopUnitCommand*) sUnitCommand;
11 
12 	scmd->unitId = -1;
13 	scmd->groupId = -1;
14 	scmd->options = 0;
15 	scmd->timeOut = INT_MAX;
16 }
17 
18 
19 #ifdef __cplusplus
20 #ifdef    BUILDING_AI
21 #include "LegacyCpp/Command.h"
22 #define CMD_MANUALFIRE CMD_DGUN
23 using namespace springLegacyAI;
24 #else  // BUILDING_AI
25 #include "Sim/Units/CommandAI/Command.h"
26 #endif // BUILDING_AI
27 
freeSUnitCommand(void * sCommandData,int sCommandId)28 void freeSUnitCommand(void* sCommandData, int sCommandId) {
29 
30 	switch (sCommandId) {
31 		case COMMAND_UNIT_LOAD_UNITS:
32 		{
33 			struct SLoadUnitsUnitCommand* cmd = (struct SLoadUnitsUnitCommand*) sCommandData;
34 			FREE(cmd->toLoadUnitIds);
35 			break;
36 		}
37 		case COMMAND_UNIT_MOVE:
38 		{
39 			struct SMoveUnitCommand* cmd = static_cast<struct SMoveUnitCommand*>(sCommandData);
40 			FREE(cmd->toPos_posF3);
41 			break;
42 		}
43 		case COMMAND_UNIT_PATROL:
44 		{
45 			struct SPatrolUnitCommand* cmd = static_cast<struct SPatrolUnitCommand*>(sCommandData);
46 			FREE(cmd->toPos_posF3);
47 			break;
48 		}
49 		case COMMAND_UNIT_FIGHT:
50 		{
51 			struct SFightUnitCommand* cmd = static_cast<struct SFightUnitCommand*>(sCommandData);
52 			FREE(cmd->toPos_posF3);
53 			break;
54 		}
55 		case COMMAND_UNIT_ATTACK_AREA:
56 		{
57 			struct SAttackAreaUnitCommand* cmd = static_cast<struct SAttackAreaUnitCommand*>(sCommandData);
58 			FREE(cmd->toAttackPos_posF3);
59 			break;
60 		}
61 		case COMMAND_UNIT_SET_BASE:
62 		{
63 			struct SSetBaseUnitCommand* cmd = static_cast<struct SSetBaseUnitCommand*>(sCommandData);
64 			FREE(cmd->basePos_posF3);
65 			break;
66 			}
67 		case COMMAND_UNIT_LOAD_UNITS_AREA:
68 		{
69 			struct SLoadUnitsAreaUnitCommand* cmd = static_cast<struct SLoadUnitsAreaUnitCommand*>(sCommandData);
70 			FREE(cmd->pos_posF3);
71 			break;
72 			}
73 		case COMMAND_UNIT_UNLOAD_UNIT:
74 		{
75 			struct SUnloadUnitCommand* cmd = static_cast<struct SUnloadUnitCommand*>(sCommandData);
76 			FREE(cmd->toPos_posF3);
77 			break;
78 		}
79 		case COMMAND_UNIT_UNLOAD_UNITS_AREA:
80 		{
81 			struct SUnloadUnitsAreaUnitCommand* cmd = static_cast<struct SUnloadUnitsAreaUnitCommand*>(sCommandData);
82 			FREE(cmd->toPos_posF3);
83 			break;
84 		}
85 		case COMMAND_UNIT_RECLAIM_AREA:
86 		{
87 			struct SReclaimAreaUnitCommand* cmd = static_cast<struct SReclaimAreaUnitCommand*>(sCommandData);
88 			FREE(cmd->pos_posF3);
89 			break;
90 		}
91 		case COMMAND_UNIT_D_GUN_POS:
92 		{
93 			struct SDGunPosUnitCommand* cmd = static_cast<struct SDGunPosUnitCommand*>(sCommandData);
94 			FREE(cmd->pos_posF3);
95 			break;
96 		}
97 		case COMMAND_UNIT_RESTORE_AREA:
98 		{
99 			struct SRestoreAreaUnitCommand* cmd = static_cast<struct SRestoreAreaUnitCommand*>(sCommandData);
100 			FREE(cmd->pos_posF3);
101 			break;
102 		}
103 		case COMMAND_UNIT_RESURRECT_AREA:
104 		{
105 			struct SResurrectAreaUnitCommand* cmd = static_cast<struct SResurrectAreaUnitCommand*>(sCommandData);
106 			FREE(cmd->pos_posF3);
107 			break;
108 		}
109 		case COMMAND_UNIT_CAPTURE_AREA:
110 		{
111 			struct SCaptureAreaUnitCommand* cmd = static_cast<struct SCaptureAreaUnitCommand*>(sCommandData);
112 			FREE(cmd->pos_posF3);
113 			break;
114 		}
115 		case COMMAND_UNIT_BUILD:
116 		{
117 			struct SBuildUnitCommand* cmd = static_cast<struct SBuildUnitCommand*>(sCommandData);
118 			FREE(cmd->buildPos_posF3);
119 			break;
120 		}
121 		case COMMAND_UNIT_CUSTOM:
122 		{
123 			struct SCustomUnitCommand* cmd = static_cast<struct SCustomUnitCommand*>(sCommandData);
124 			FREE(cmd->params);
125 			break;
126 		}
127 	}
128 
129 	FREE(sCommandData);
130 }
131 
allocFloatArr3(const std::vector<float> & from,const size_t firstValIndex=0)132 static float* allocFloatArr3(const std::vector<float>& from, const size_t firstValIndex = 0) {
133 
134 	float* to = (float*) calloc(3, sizeof(float));
135 
136 	to[0] = from[firstValIndex + 0];
137 	to[1] = from[firstValIndex + 1];
138 	to[2] = from[firstValIndex + 2];
139 
140 	return to;
141 }
142 
mallocSUnitCommand(int unitId,int groupId,const Command * c,int * sCommandId,int maxUnits)143 void* mallocSUnitCommand(int unitId, int groupId, const Command* c, int* sCommandId, int maxUnits) {
144 
145 	int aiCmdId = extractAICommandTopic(c, maxUnits);
146 	void* sCommandData;
147 
148 	switch (aiCmdId) {
149 		case COMMAND_UNIT_STOP:
150 		{
151 			SStopUnitCommand* cmd = static_cast<SStopUnitCommand*>(malloc(sizeof (SStopUnitCommand)));
152 			cmd->unitId = unitId;
153 			cmd->groupId = groupId;
154 			cmd->options = c->options;
155 			cmd->timeOut = c->timeOut;
156 
157 			sCommandData = cmd;
158 			break;
159 		}
160 		case COMMAND_UNIT_WAIT:
161 		{
162 			SWaitUnitCommand* cmd = static_cast<SWaitUnitCommand*>(malloc(sizeof (SWaitUnitCommand)));
163 			cmd->unitId = unitId;
164 			cmd->groupId = groupId;
165 			cmd->options = c->options;
166 			cmd->timeOut = c->timeOut;
167 
168 			sCommandData = cmd;
169 			break;
170 		}
171 		case COMMAND_UNIT_WAIT_TIME:
172 		{
173 			STimeWaitUnitCommand* cmd = static_cast<STimeWaitUnitCommand*>(malloc(sizeof (STimeWaitUnitCommand)));
174 			cmd->unitId = unitId;
175 			cmd->groupId = groupId;
176 			cmd->options = c->options;
177 			cmd->timeOut = c->timeOut;
178 			cmd->time = c->params[0];
179 
180 			sCommandData = cmd;
181 			break;
182 		}
183 		case COMMAND_UNIT_WAIT_DEATH:
184 		{
185 			SDeathWaitUnitCommand* cmd = static_cast<SDeathWaitUnitCommand*>(malloc(sizeof (SDeathWaitUnitCommand)));
186 			cmd->unitId = unitId;
187 			cmd->groupId = groupId;
188 			cmd->options = c->options;
189 			cmd->timeOut = c->timeOut;
190 			cmd->toDieUnitId = (int) c->params[0];
191 
192 			sCommandData = cmd;
193 			break;
194 		}
195 		case COMMAND_UNIT_WAIT_SQUAD:
196 		{
197 			SSquadWaitUnitCommand* cmd = static_cast<SSquadWaitUnitCommand*>(malloc(sizeof (SSquadWaitUnitCommand)));
198 			cmd->unitId = unitId;
199 			cmd->groupId = groupId;
200 			cmd->options = c->options;
201 			cmd->timeOut = c->timeOut;
202 			cmd->numUnits = (int) c->params[0];
203 
204 			sCommandData = cmd;
205 			break;
206 		}
207 		case COMMAND_UNIT_WAIT_GATHER:
208 		{
209 			SGatherWaitUnitCommand* cmd = static_cast<SGatherWaitUnitCommand*>(malloc(sizeof (SGatherWaitUnitCommand)));
210 			cmd->unitId = unitId;
211 			cmd->groupId = groupId;
212 			cmd->options = c->options;
213 			cmd->timeOut = c->timeOut;
214 
215 			sCommandData = cmd;
216 			break;
217 		}
218 		case COMMAND_UNIT_MOVE:
219 		{
220 			SMoveUnitCommand* cmd = static_cast<SMoveUnitCommand*>(malloc(sizeof (SMoveUnitCommand)));
221 			cmd->unitId = unitId;
222 			cmd->groupId = groupId;
223 			cmd->options = c->options;
224 			cmd->timeOut = c->timeOut;
225 			cmd->toPos_posF3 = allocFloatArr3(c->params, 0);
226 
227 			sCommandData = cmd;
228 			break;
229 		}
230 		case COMMAND_UNIT_PATROL:
231 		{
232 			SPatrolUnitCommand* cmd = static_cast<SPatrolUnitCommand*>(malloc(sizeof (SPatrolUnitCommand)));
233 			cmd->unitId = unitId;
234 			cmd->groupId = groupId;
235 			cmd->options = c->options;
236 			cmd->timeOut = c->timeOut;
237 			cmd->toPos_posF3 = allocFloatArr3(c->params, 0);
238 
239 			sCommandData = cmd;
240 			break;
241 		}
242 		case COMMAND_UNIT_FIGHT:
243 		{
244 			SFightUnitCommand* cmd = static_cast<SFightUnitCommand*>(malloc(sizeof (SFightUnitCommand)));
245 			cmd->unitId = unitId;
246 			cmd->groupId = groupId;
247 			cmd->options = c->options;
248 			cmd->timeOut = c->timeOut;
249 			cmd->toPos_posF3 = allocFloatArr3(c->params, 0);
250 
251 			sCommandData = cmd;
252 			break;
253 		}
254 		case COMMAND_UNIT_ATTACK:
255 		{
256 			SAttackUnitCommand* cmd = static_cast<SAttackUnitCommand*>(malloc(sizeof (SAttackUnitCommand)));
257 			cmd->unitId = unitId;
258 			cmd->groupId = groupId;
259 			cmd->options = c->options;
260 			cmd->timeOut = c->timeOut;
261 			cmd->toAttackUnitId = (int) c->params[0];
262 
263 			sCommandData = cmd;
264 			break;
265 		}
266 		case COMMAND_UNIT_ATTACK_AREA:
267 		{
268 			float radius = 0.0f;
269 			if (c->params.size() >= 4) radius = c->params[3];
270 			SAttackAreaUnitCommand* cmd = static_cast<SAttackAreaUnitCommand*>(malloc(sizeof (SAttackAreaUnitCommand)));
271 			cmd->unitId = unitId;
272 			cmd->groupId = groupId;
273 			cmd->options = c->options;
274 			cmd->timeOut = c->timeOut;
275 			cmd->toAttackPos_posF3 = allocFloatArr3(c->params, 0);
276 			cmd->radius = radius;
277 
278 			sCommandData = cmd;
279 			break;
280 		}
281 		case COMMAND_UNIT_GUARD:
282 		{
283 			SGuardUnitCommand* cmd = static_cast<SGuardUnitCommand*>(malloc(sizeof (SGuardUnitCommand)));
284 			cmd->unitId = unitId;
285 			cmd->groupId = groupId;
286 			cmd->options = c->options;
287 			cmd->timeOut = c->timeOut;
288 			cmd->toGuardUnitId = (int) c->params[0];
289 
290 			sCommandData = cmd;
291 			break;
292 		}
293 		case COMMAND_UNIT_AI_SELECT:
294 		{
295 			SAiSelectUnitCommand* cmd = static_cast<SAiSelectUnitCommand*>(malloc(sizeof (SAiSelectUnitCommand)));
296 			cmd->unitId = unitId;
297 			cmd->groupId = groupId;
298 			cmd->options = c->options;
299 			cmd->timeOut = c->timeOut;
300 
301 			sCommandData = cmd;
302 			break;
303 		}
304 		case COMMAND_UNIT_GROUP_ADD:
305 		{
306 			SGroupAddUnitCommand* cmd = static_cast<SGroupAddUnitCommand*>(malloc(sizeof (SGroupAddUnitCommand)));
307 			cmd->unitId = unitId;
308 			cmd->groupId = groupId;
309 			cmd->options = c->options;
310 			cmd->timeOut = c->timeOut;
311 			cmd->toGroupId = (int) c->params[0];
312 
313 			sCommandData = cmd;
314 			break;
315 		}
316 		case COMMAND_UNIT_GROUP_CLEAR:
317 		{
318 			SGroupClearUnitCommand* cmd = static_cast<SGroupClearUnitCommand*>(malloc(sizeof (SGroupClearUnitCommand)));
319 			cmd->unitId = unitId;
320 			cmd->groupId = groupId;
321 			cmd->options = c->options;
322 			cmd->timeOut = c->timeOut;
323 
324 			sCommandData = cmd;
325 			break;
326 		}
327 		case COMMAND_UNIT_REPAIR:
328 		{
329 			SRepairUnitCommand* cmd = static_cast<SRepairUnitCommand*>(malloc(sizeof (SRepairUnitCommand)));
330 			cmd->unitId = unitId;
331 			cmd->groupId = groupId;
332 			cmd->options = c->options;
333 			cmd->timeOut = c->timeOut;
334 			cmd->toRepairUnitId = (int) c->params[0];
335 
336 			sCommandData = cmd;
337 			break;
338 		}
339 		case COMMAND_UNIT_SET_FIRE_STATE:
340 		{
341 			SSetFireStateUnitCommand* cmd = static_cast<SSetFireStateUnitCommand*>(malloc(sizeof (SSetFireStateUnitCommand)));
342 			cmd->unitId = unitId;
343 			cmd->groupId = groupId;
344 			cmd->options = c->options;
345 			cmd->timeOut = c->timeOut;
346 			cmd->fireState = (int) c->params[0];
347 
348 			sCommandData = cmd;
349 			break;
350 		}
351 		case COMMAND_UNIT_SET_MOVE_STATE:
352 		{
353 			SSetMoveStateUnitCommand* cmd = static_cast<SSetMoveStateUnitCommand*>(malloc(sizeof (SSetMoveStateUnitCommand)));
354 			cmd->unitId = unitId;
355 			cmd->groupId = groupId;
356 			cmd->options = c->options;
357 			cmd->timeOut = c->timeOut;
358 			cmd->moveState = (int) c->params[0];
359 
360 			sCommandData = cmd;
361 			break;
362 		}
363 		case COMMAND_UNIT_SET_BASE:
364 		{
365 			SSetBaseUnitCommand* cmd = static_cast<SSetBaseUnitCommand*>(malloc(sizeof (SSetBaseUnitCommand)));
366 			cmd->unitId = unitId;
367 			cmd->groupId = groupId;
368 			cmd->options = c->options;
369 			cmd->timeOut = c->timeOut;
370 			cmd->basePos_posF3 = allocFloatArr3(c->params, 0);
371 
372 			sCommandData = cmd;
373 			break;
374 		}
375 		case COMMAND_UNIT_SELF_DESTROY:
376 		{
377 			SSelfDestroyUnitCommand* cmd = static_cast<SSelfDestroyUnitCommand*>(malloc(sizeof (SSelfDestroyUnitCommand)));
378 			cmd->unitId = unitId;
379 			cmd->groupId = groupId;
380 			cmd->options = c->options;
381 			cmd->timeOut = c->timeOut;
382 
383 			sCommandData = cmd;
384 			break;
385 		}
386 		case COMMAND_UNIT_SET_WANTED_MAX_SPEED:
387 		{
388 			SSetWantedMaxSpeedUnitCommand* cmd = static_cast<SSetWantedMaxSpeedUnitCommand*>(malloc(sizeof (SSetWantedMaxSpeedUnitCommand)));
389 			cmd->unitId = unitId;
390 			cmd->groupId = groupId;
391 			cmd->options = c->options;
392 			cmd->timeOut = c->timeOut;
393 			cmd->wantedMaxSpeed = c->params[0];
394 
395 			sCommandData = cmd;
396 			break;
397 		}
398 		case COMMAND_UNIT_LOAD_UNITS:
399 		{
400 			//int numToLoadUnits = 1;
401 			const int toLoadUnitIds_size = c->params.size();
402 
403 			SLoadUnitsUnitCommand* cmd = static_cast<SLoadUnitsUnitCommand*>(malloc(sizeof (SLoadUnitsUnitCommand)));
404 			cmd->unitId  = unitId;
405 			cmd->groupId = groupId;
406 			cmd->options = c->options;
407 			cmd->timeOut = c->timeOut;
408 
409 			cmd->toLoadUnitIds_size = toLoadUnitIds_size;
410 			cmd->toLoadUnitIds      = static_cast<int*>(calloc(toLoadUnitIds_size, sizeof(int)));
411 			int u;
412 			for (u=0; u < toLoadUnitIds_size; ++u) {
413 				cmd->toLoadUnitIds[u] = static_cast<int>(c->params.at(u));
414 			}
415 
416 			sCommandData = cmd;
417 			break;
418 		}
419 		case COMMAND_UNIT_LOAD_UNITS_AREA:
420 		{
421 			float radius = 0.0f;
422 			if (c->params.size() >= 4) radius = c->params[3];
423 			SLoadUnitsAreaUnitCommand* cmd = static_cast<SLoadUnitsAreaUnitCommand*>(malloc(sizeof (SLoadUnitsAreaUnitCommand)));
424 			cmd->unitId = unitId;
425 			cmd->groupId = groupId;
426 			cmd->options = c->options;
427 			cmd->timeOut = c->timeOut;
428 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
429 			cmd->radius = radius;
430 
431 			sCommandData = cmd;
432 			break;
433 		}
434 		case COMMAND_UNIT_LOAD_ONTO:
435 		{
436 			SLoadOntoUnitCommand* cmd = static_cast<SLoadOntoUnitCommand*>(malloc(sizeof (SLoadOntoUnitCommand)));
437 			cmd->unitId = unitId;
438 			cmd->groupId = groupId;
439 			cmd->options = c->options;
440 			cmd->timeOut = c->timeOut;
441 			cmd->transporterUnitId = (int) c->params[0];
442 
443 			sCommandData = cmd;
444 			break;
445 		}
446 		case COMMAND_UNIT_UNLOAD_UNIT:
447 		{
448 			SUnloadUnitCommand* cmd = static_cast<SUnloadUnitCommand*>(malloc(sizeof (SUnloadUnitCommand)));
449 			cmd->unitId = unitId;
450 			cmd->groupId = groupId;
451 			cmd->options = c->options;
452 			cmd->timeOut = c->timeOut;
453 			cmd->toPos_posF3 = allocFloatArr3(c->params, 0);
454 			cmd->toUnloadUnitId = (int) c->params[3];
455 
456 			sCommandData = cmd;
457 			break;
458 		}
459 		case COMMAND_UNIT_UNLOAD_UNITS_AREA:
460 		{
461 			float radius = 0.0f;
462 			if (c->params.size() >= 4) radius = c->params[3];
463 			SUnloadUnitsAreaUnitCommand* cmd = static_cast<SUnloadUnitsAreaUnitCommand*>(malloc(sizeof (SUnloadUnitsAreaUnitCommand)));
464 			cmd->unitId = unitId;
465 			cmd->groupId = groupId;
466 			cmd->options = c->options;
467 			cmd->timeOut = c->timeOut;
468 			cmd->toPos_posF3 = allocFloatArr3(c->params, 0);
469 			cmd->radius = radius;
470 
471 			sCommandData = cmd;
472 			break;
473 		}
474 		case COMMAND_UNIT_SET_ON_OFF:
475 		{
476 			SSetOnOffUnitCommand* cmd = static_cast<SSetOnOffUnitCommand*>(malloc(sizeof (SSetOnOffUnitCommand)));
477 			cmd->unitId  = unitId;
478 			cmd->groupId = groupId;
479 			cmd->options = c->options;
480 			cmd->timeOut = c->timeOut;
481 			cmd->on      = (bool) c->params[0];
482 
483 			sCommandData = cmd;
484 			break;
485 		}
486 		case COMMAND_UNIT_RECLAIM_UNIT:
487 		{
488 			SReclaimUnitUnitCommand* cmd = static_cast<SReclaimUnitUnitCommand*>(malloc(sizeof (SReclaimUnitUnitCommand)));
489 			cmd->unitId          = unitId;
490 			cmd->groupId         = groupId;
491 			cmd->options         = c->options;
492 			cmd->timeOut         = c->timeOut;
493 			cmd->toReclaimUnitId = (int) c->params[0];
494 
495 			sCommandData = cmd;
496 			break;
497 		}
498 		case COMMAND_UNIT_RECLAIM_FEATURE:
499 		{
500 			SReclaimFeatureUnitCommand* cmd = static_cast<SReclaimFeatureUnitCommand*>(malloc(sizeof (SReclaimFeatureUnitCommand)));
501 			cmd->unitId             = unitId;
502 			cmd->groupId            = groupId;
503 			cmd->options            = c->options;
504 			cmd->timeOut            = c->timeOut;
505 			cmd->toReclaimFeatureId = ((int) c->params[0]) - maxUnits;
506 
507 			sCommandData = cmd;
508 			break;
509 		}
510 		case COMMAND_UNIT_RECLAIM_AREA:
511 		{
512 			float radius = 0.0f;
513 			if (c->params.size() >= 4) radius = c->params[3];
514 			SReclaimAreaUnitCommand* cmd = static_cast<SReclaimAreaUnitCommand*>(malloc(sizeof (SReclaimAreaUnitCommand)));
515 			cmd->unitId    = unitId;
516 			cmd->groupId   = groupId;
517 			cmd->options   = c->options;
518 			cmd->timeOut   = c->timeOut;
519 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
520 			cmd->radius    = radius;
521 
522 			sCommandData = cmd;
523 			break;
524 		}
525 		case COMMAND_UNIT_CLOAK:
526 		{
527 			SCloakUnitCommand* cmd = static_cast<SCloakUnitCommand*>(malloc(sizeof (SCloakUnitCommand)));
528 			cmd->unitId = unitId;
529 			cmd->groupId = groupId;
530 			cmd->options = c->options;
531 			cmd->timeOut = c->timeOut;
532 			cmd->cloak = (bool) c->params[0];
533 
534 			sCommandData = cmd;
535 			break;
536 		}
537 		case COMMAND_UNIT_STOCKPILE:
538 		{
539 			SStockpileUnitCommand* cmd = static_cast<SStockpileUnitCommand*>(malloc(sizeof (SStockpileUnitCommand)));
540 			cmd->unitId = unitId;
541 			cmd->groupId = groupId;
542 			cmd->options = c->options;
543 			cmd->timeOut = c->timeOut;
544 
545 			sCommandData = cmd;
546 			break;
547 		}
548 		case COMMAND_UNIT_D_GUN:
549 		{
550 			SDGunUnitCommand* cmd = static_cast<SDGunUnitCommand*>(malloc(sizeof (SDGunUnitCommand)));
551 			cmd->unitId = unitId;
552 			cmd->groupId = groupId;
553 			cmd->options = c->options;
554 			cmd->timeOut = c->timeOut;
555 			cmd->toAttackUnitId = static_cast<int>(c->params[0]);
556 
557 			sCommandData = cmd;
558 			break;
559 		}
560 		case COMMAND_UNIT_D_GUN_POS:
561 		{
562 			SDGunPosUnitCommand* cmd = static_cast<SDGunPosUnitCommand*>(malloc(sizeof (SDGunPosUnitCommand)));
563 			cmd->unitId = unitId;
564 			cmd->groupId = groupId;
565 			cmd->options = c->options;
566 			cmd->timeOut = c->timeOut;
567 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
568 
569 			sCommandData = cmd;
570 			break;
571 		}
572 		case COMMAND_UNIT_RESTORE_AREA:
573 		{
574 			float radius = 0.0f;
575 			if (c->params.size() >= 4) radius = c->params[3];
576 			SRestoreAreaUnitCommand* cmd = static_cast<SRestoreAreaUnitCommand*>(malloc(sizeof (SRestoreAreaUnitCommand)));
577 			cmd->unitId = unitId;
578 			cmd->groupId = groupId;
579 			cmd->options = c->options;
580 			cmd->timeOut = c->timeOut;
581 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
582 			cmd->radius = radius;
583 
584 			sCommandData = cmd;
585 			break;
586 		}
587 		case COMMAND_UNIT_SET_REPEAT:
588 		{
589 			SSetRepeatUnitCommand* cmd = static_cast<SSetRepeatUnitCommand*>(malloc(sizeof (SSetRepeatUnitCommand)));
590 			cmd->unitId = unitId;
591 			cmd->groupId = groupId;
592 			cmd->options = c->options;
593 			cmd->timeOut = c->timeOut;
594 			cmd->repeat = (bool) c->params[0];
595 
596 			sCommandData = cmd;
597 			break;
598 		}
599 		case COMMAND_UNIT_SET_TRAJECTORY:
600 		{
601 			SSetTrajectoryUnitCommand* cmd = static_cast<SSetTrajectoryUnitCommand*>(malloc(sizeof (SSetTrajectoryUnitCommand)));
602 			cmd->unitId = unitId;
603 			cmd->groupId = groupId;
604 			cmd->options = c->options;
605 			cmd->timeOut = c->timeOut;
606 			cmd->trajectory = static_cast<int>(c->params[0]);
607 
608 			sCommandData = cmd;
609 			break;
610 		}
611 		case COMMAND_UNIT_RESURRECT:
612 		{
613 			SResurrectUnitCommand* cmd = static_cast<SResurrectUnitCommand*>(malloc(sizeof (SResurrectUnitCommand)));
614 			cmd->unitId = unitId;
615 			cmd->groupId = groupId;
616 			cmd->options = c->options;
617 			cmd->timeOut = c->timeOut;
618 			cmd->toResurrectFeatureId = static_cast<int>(c->params[0]);
619 
620 			sCommandData = cmd;
621 			break;
622 		}
623 		case COMMAND_UNIT_RESURRECT_AREA:
624 		{
625 			float radius = 0.0f;
626 			if (c->params.size() >= 4) radius = c->params[3];
627 			SResurrectAreaUnitCommand* cmd = static_cast<SResurrectAreaUnitCommand*>(malloc(sizeof (SResurrectAreaUnitCommand)));
628 			cmd->unitId = unitId;
629 			cmd->groupId = groupId;
630 			cmd->options = c->options;
631 			cmd->timeOut = c->timeOut;
632 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
633 			cmd->radius = radius;
634 
635 			sCommandData = cmd;
636 			break;
637 		}
638 		case COMMAND_UNIT_CAPTURE:
639 		{
640 			SCaptureUnitCommand* cmd = static_cast<SCaptureUnitCommand*>(malloc(sizeof (SCaptureUnitCommand)));
641 			cmd->unitId = unitId;
642 			cmd->groupId = groupId;
643 			cmd->options = c->options;
644 			cmd->timeOut = c->timeOut;
645 			cmd->toCaptureUnitId = static_cast<int>(c->params[0]);
646 
647 			sCommandData = cmd;
648 			break;
649 		}
650 		case COMMAND_UNIT_CAPTURE_AREA:
651 		{
652 			float radius = 0.0f;
653 			if (c->params.size() >= 4) radius = c->params[3];
654 			SCaptureAreaUnitCommand* cmd = static_cast<SCaptureAreaUnitCommand*>(malloc(sizeof (SCaptureAreaUnitCommand)));
655 			cmd->unitId = unitId;
656 			cmd->groupId = groupId;
657 			cmd->options = c->options;
658 			cmd->timeOut = c->timeOut;
659 			cmd->pos_posF3 = allocFloatArr3(c->params, 0);
660 			cmd->radius = radius;
661 
662 			sCommandData = cmd;
663 			break;
664 		}
665 		case COMMAND_UNIT_SET_AUTO_REPAIR_LEVEL:
666 		{
667 			SSetAutoRepairLevelUnitCommand* cmd = static_cast<SSetAutoRepairLevelUnitCommand*>(malloc(sizeof (SSetAutoRepairLevelUnitCommand)));
668 			cmd->unitId = unitId;
669 			cmd->groupId = groupId;
670 			cmd->options = c->options;
671 			cmd->timeOut = c->timeOut;
672 			cmd->autoRepairLevel = static_cast<int>(c->params[0]);
673 
674 			sCommandData = cmd;
675 			break;
676 		}
677 		case COMMAND_UNIT_SET_IDLE_MODE:
678 		{
679 			SSetIdleModeUnitCommand* cmd = static_cast<SSetIdleModeUnitCommand*>(malloc(sizeof (SSetIdleModeUnitCommand)));
680 			cmd->unitId = unitId;
681 			cmd->groupId = groupId;
682 			cmd->options = c->options;
683 			cmd->timeOut = c->timeOut;
684 			cmd->idleMode = static_cast<int>(c->params[0]);
685 
686 			sCommandData = cmd;
687 			break;
688 		}
689 		case COMMAND_UNIT_BUILD:
690 		{
691 			int toBuildUnitDefId = -c->GetID();
692 			int facing = UNIT_COMMAND_BUILD_NO_FACING;
693 			if (c->params.size() >= 4) facing = c->params[3];
694 			SBuildUnitCommand* cmd = static_cast<SBuildUnitCommand*>(malloc(sizeof (SBuildUnitCommand)));
695 			cmd->unitId = unitId;
696 			cmd->groupId = groupId;
697 			cmd->options = c->options;
698 			cmd->timeOut = c->timeOut;
699 			cmd->toBuildUnitDefId = toBuildUnitDefId;
700 			if (c->params.size() >= 3) {
701 				cmd->buildPos_posF3 = allocFloatArr3(c->params, 0);
702 			} else {
703 				cmd->buildPos_posF3 = NULL;
704 			}
705 			cmd->facing = facing;
706 
707 			sCommandData = cmd;
708 			break;
709 		}
710 		default:
711 		case COMMAND_UNIT_CUSTOM:
712 		{
713 			const int cmdId          = c->GetID();
714 			const size_t params_size = c->params.size();
715 			SCustomUnitCommand* cmd  = static_cast<SCustomUnitCommand*>(malloc(sizeof (SCustomUnitCommand)));
716 			cmd->unitId      = unitId;
717 			cmd->groupId     = groupId;
718 			cmd->options     = c->options;
719 			cmd->timeOut     = c->timeOut;
720 			cmd->cmdId       = cmdId;
721 			cmd->params_size = params_size;
722 			cmd->params      = static_cast<float*>(calloc(params_size, sizeof(float)));
723 			int p;
724 			for (p=0; p < params_size; ++p) {
725 				cmd->params[p] = c->params.at(p);
726 			}
727 
728 			sCommandData = cmd;
729 			break;
730 		}
731 
732 	}
733 
734 	*sCommandId = aiCmdId;
735 
736 	return sCommandData;
737 }
738 
739 
toInternalUnitCommandTopic(int aiCmdTopic,const void * sUnitCommandData)740 int toInternalUnitCommandTopic(int aiCmdTopic, const void* sUnitCommandData) {
741 
742 	int internalUnitCommandTopic;
743 
744 	switch (aiCmdTopic) {
745 		case COMMAND_UNIT_BUILD:
746 		{
747 			const SBuildUnitCommand* cmd = reinterpret_cast<const SBuildUnitCommand*>(sUnitCommandData);
748 			internalUnitCommandTopic = -cmd->toBuildUnitDefId;
749 			break;
750 		}
751 		case COMMAND_UNIT_STOP:
752 		{
753 			internalUnitCommandTopic = CMD_STOP;
754 			break;
755 		}
756 		case COMMAND_UNIT_WAIT:
757 		{
758 			internalUnitCommandTopic = CMD_WAIT;
759 			break;
760 		}
761 		case COMMAND_UNIT_WAIT_TIME:
762 		{
763 			internalUnitCommandTopic = CMD_TIMEWAIT;
764 			break;
765 		}
766 		case COMMAND_UNIT_WAIT_DEATH:
767 		{
768 			internalUnitCommandTopic = CMD_DEATHWAIT;
769 			break;
770 		}
771 		case COMMAND_UNIT_WAIT_SQUAD:
772 		{
773 			internalUnitCommandTopic = CMD_SQUADWAIT;
774 			break;
775 		}
776 		case COMMAND_UNIT_WAIT_GATHER:
777 		{
778 			internalUnitCommandTopic = CMD_GATHERWAIT;
779 			break;
780 		}
781 		case COMMAND_UNIT_MOVE:
782 		{
783 			internalUnitCommandTopic = CMD_MOVE;
784 			break;
785 		}
786 		case COMMAND_UNIT_PATROL:
787 		{
788 			internalUnitCommandTopic = CMD_PATROL;
789 			break;
790 		}
791 		case COMMAND_UNIT_FIGHT:
792 		{
793 			internalUnitCommandTopic = CMD_FIGHT;
794 			break;
795 		}
796 		case COMMAND_UNIT_ATTACK:
797 		{
798 			internalUnitCommandTopic = CMD_ATTACK;
799 			break;
800 		}
801 		case COMMAND_UNIT_ATTACK_AREA:
802 		{
803 			internalUnitCommandTopic = CMD_ATTACK;
804 			break;
805 		}
806 		case COMMAND_UNIT_GUARD:
807 		{
808 			internalUnitCommandTopic = CMD_GUARD;
809 			break;
810 		}
811 		case COMMAND_UNIT_AI_SELECT:
812 		{
813 			internalUnitCommandTopic = CMD_AISELECT;
814 			break;
815 		}
816 		case COMMAND_UNIT_GROUP_ADD:
817 		{
818 			internalUnitCommandTopic = CMD_GROUPADD;
819 			break;
820 		}
821 		case COMMAND_UNIT_GROUP_CLEAR:
822 		{
823 			internalUnitCommandTopic = CMD_GROUPCLEAR;
824 			break;
825 		}
826 		case COMMAND_UNIT_REPAIR:
827 		{
828 			internalUnitCommandTopic = CMD_REPAIR;
829 			break;
830 		}
831 		case COMMAND_UNIT_SET_FIRE_STATE:
832 		{
833 			internalUnitCommandTopic = CMD_FIRE_STATE;
834 			break;
835 		}
836 		case COMMAND_UNIT_SET_MOVE_STATE:
837 		{
838 			internalUnitCommandTopic = CMD_MOVE_STATE;
839 			break;
840 		}
841 		case COMMAND_UNIT_SET_BASE:
842 		{
843 			internalUnitCommandTopic = CMD_SETBASE;
844 			break;
845 		}
846 		case COMMAND_UNIT_SELF_DESTROY:
847 		{
848 			internalUnitCommandTopic = CMD_SELFD;
849 			break;
850 		}
851 		case COMMAND_UNIT_SET_WANTED_MAX_SPEED:
852 		{
853 			internalUnitCommandTopic = CMD_SET_WANTED_MAX_SPEED;
854 			break;
855 		}
856 		case COMMAND_UNIT_LOAD_UNITS:
857 		{
858 			internalUnitCommandTopic = CMD_LOAD_UNITS;
859 			break;
860 		}
861 		case COMMAND_UNIT_LOAD_UNITS_AREA:
862 		{
863 			internalUnitCommandTopic = CMD_LOAD_UNITS;
864 			break;
865 		}
866 		case COMMAND_UNIT_LOAD_ONTO:
867 		{
868 			internalUnitCommandTopic = CMD_LOAD_ONTO;
869 			break;
870 		}
871 		case COMMAND_UNIT_UNLOAD_UNITS_AREA:
872 		{
873 			internalUnitCommandTopic = CMD_UNLOAD_UNITS;
874 			break;
875 		}
876 		case COMMAND_UNIT_UNLOAD_UNIT:
877 		{
878 			internalUnitCommandTopic = CMD_UNLOAD_UNIT;
879 			break;
880 		}
881 		case COMMAND_UNIT_SET_ON_OFF:
882 		{
883 			internalUnitCommandTopic = CMD_ONOFF;
884 			break;
885 		}
886 		case COMMAND_UNIT_RECLAIM_UNIT:
887 		{
888 			internalUnitCommandTopic = CMD_RECLAIM;
889 			break;
890 		}
891 		case COMMAND_UNIT_RECLAIM_FEATURE:
892 		{
893 			internalUnitCommandTopic = CMD_RECLAIM;
894 			break;
895 		}
896 		case COMMAND_UNIT_RECLAIM_AREA:
897 		{
898 			internalUnitCommandTopic = CMD_RECLAIM;
899 			break;
900 		}
901 		case COMMAND_UNIT_CLOAK:
902 		{
903 			internalUnitCommandTopic = CMD_CLOAK;
904 			break;
905 		}
906 		case COMMAND_UNIT_STOCKPILE:
907 		{
908 			internalUnitCommandTopic = CMD_STOCKPILE;
909 			break;
910 		}
911 
912 		case COMMAND_UNIT_D_GUN:
913 		{
914 			// FIXME
915 			internalUnitCommandTopic = CMD_MANUALFIRE;
916 			break;
917 		}
918 		case COMMAND_UNIT_D_GUN_POS:
919 		{
920 			// FIXME
921 			internalUnitCommandTopic = CMD_MANUALFIRE;
922 			break;
923 		}
924 
925 		case COMMAND_UNIT_RESTORE_AREA:
926 		{
927 			internalUnitCommandTopic = CMD_RESTORE;
928 			break;
929 		}
930 		case COMMAND_UNIT_SET_REPEAT:
931 		{
932 			internalUnitCommandTopic = CMD_REPEAT;
933 			break;
934 		}
935 		case COMMAND_UNIT_SET_TRAJECTORY:
936 		{
937 			internalUnitCommandTopic = CMD_TRAJECTORY;
938 			break;
939 		}
940 		case COMMAND_UNIT_RESURRECT:
941 		{
942 			internalUnitCommandTopic = CMD_RESURRECT;
943 			break;
944 		}
945 		case COMMAND_UNIT_RESURRECT_AREA:
946 		{
947 			internalUnitCommandTopic = CMD_RESURRECT;
948 			break;
949 		}
950 		case COMMAND_UNIT_CAPTURE:
951 		{
952 			internalUnitCommandTopic = CMD_CAPTURE;
953 			break;
954 		}
955 		case COMMAND_UNIT_CAPTURE_AREA:
956 		{
957 			internalUnitCommandTopic = CMD_CAPTURE;
958 			break;
959 		}
960 		case COMMAND_UNIT_SET_AUTO_REPAIR_LEVEL:
961 		{
962 			internalUnitCommandTopic = CMD_AUTOREPAIRLEVEL;
963 			break;
964 		}
965 		case COMMAND_UNIT_SET_IDLE_MODE:
966 		{
967 			internalUnitCommandTopic = CMD_IDLEMODE;
968 			break;
969 		}
970 		case COMMAND_UNIT_CUSTOM:
971 		{
972 			const SCustomUnitCommand* cmd = reinterpret_cast<const SCustomUnitCommand*>(sUnitCommandData);
973 			internalUnitCommandTopic = cmd->cmdId;
974 			break;
975 		}
976 		default:
977 		{
978 			internalUnitCommandTopic = -1;
979 		}
980 	}
981 
982 	return internalUnitCommandTopic;
983 }
984 
985 
extractAICommandTopic(const Command * engineCmd,int maxUnits)986 int extractAICommandTopic(const Command* engineCmd, int maxUnits) {
987 
988 	const int internalUnitCmdTopic = engineCmd->GetID();
989 	int aiCommandTopic;
990 
991 	switch (internalUnitCmdTopic) {
992 		case CMD_STOP:
993 		{
994 			aiCommandTopic = COMMAND_UNIT_STOP;
995 			break;
996 		}
997 		case CMD_WAIT:
998 		{
999 			aiCommandTopic = COMMAND_UNIT_WAIT;
1000 			break;
1001 		}
1002 		case CMD_TIMEWAIT:
1003 		{
1004 			aiCommandTopic = COMMAND_UNIT_WAIT_TIME;
1005 			break;
1006 		}
1007 		case CMD_DEATHWAIT:
1008 		{
1009 			aiCommandTopic = COMMAND_UNIT_WAIT_DEATH;
1010 			break;
1011 		}
1012 		case CMD_SQUADWAIT:
1013 		{
1014 			aiCommandTopic = COMMAND_UNIT_WAIT_SQUAD;
1015 			break;
1016 		}
1017 		case CMD_GATHERWAIT:
1018 		{
1019 			aiCommandTopic = COMMAND_UNIT_WAIT_GATHER;
1020 			break;
1021 		}
1022 		case CMD_MOVE:
1023 		{
1024 			aiCommandTopic = COMMAND_UNIT_MOVE;
1025 			break;
1026 		}
1027 		case CMD_PATROL:
1028 		{
1029 			aiCommandTopic = COMMAND_UNIT_PATROL;
1030 			break;
1031 		}
1032 		case CMD_FIGHT:
1033 		{
1034 			aiCommandTopic = COMMAND_UNIT_FIGHT;
1035 			break;
1036 		}
1037 		case CMD_ATTACK:
1038 		{
1039 			if (engineCmd->params.size() < 3) {
1040 				aiCommandTopic = COMMAND_UNIT_ATTACK;
1041 			} else {
1042 				aiCommandTopic = COMMAND_UNIT_ATTACK_AREA;
1043 			}
1044 			break;
1045 		}
1046 		case CMD_GUARD:
1047 		{
1048 			aiCommandTopic = COMMAND_UNIT_GUARD;
1049 			break;
1050 		}
1051 		case CMD_AISELECT:
1052 		{
1053 			aiCommandTopic = COMMAND_UNIT_AI_SELECT;
1054 			break;
1055 		}
1056 		case CMD_GROUPADD:
1057 		{
1058 			aiCommandTopic = COMMAND_UNIT_GROUP_ADD;
1059 			break;
1060 		}
1061 		case CMD_GROUPCLEAR:
1062 		{
1063 			aiCommandTopic = COMMAND_UNIT_GROUP_CLEAR;
1064 			break;
1065 		}
1066 		case CMD_REPAIR:
1067 		{
1068 			aiCommandTopic = COMMAND_UNIT_REPAIR;
1069 			break;
1070 		}
1071 		case CMD_FIRE_STATE:
1072 		{
1073 			aiCommandTopic = COMMAND_UNIT_SET_FIRE_STATE;
1074 			break;
1075 		}
1076 		case CMD_MOVE_STATE:
1077 		{
1078 			aiCommandTopic = COMMAND_UNIT_SET_MOVE_STATE;
1079 			break;
1080 		}
1081 		case CMD_SETBASE:
1082 		{
1083 			aiCommandTopic = COMMAND_UNIT_SET_BASE;
1084 			break;
1085 		}
1086 		case CMD_SELFD:
1087 		{
1088 			aiCommandTopic = COMMAND_UNIT_SELF_DESTROY;
1089 			break;
1090 		}
1091 		case CMD_SET_WANTED_MAX_SPEED:
1092 		{
1093 			aiCommandTopic = COMMAND_UNIT_SET_WANTED_MAX_SPEED;
1094 			break;
1095 		}
1096 		case CMD_LOAD_UNITS:
1097 		{
1098 			if (engineCmd->params.size() < 3) {
1099 				aiCommandTopic = COMMAND_UNIT_LOAD_UNITS;
1100 			} else {
1101 				aiCommandTopic = COMMAND_UNIT_LOAD_UNITS_AREA;
1102 			}
1103 			break;
1104 		}
1105 		case CMD_LOAD_ONTO:
1106 		{
1107 			aiCommandTopic = COMMAND_UNIT_LOAD_ONTO;
1108 			break;
1109 		}
1110 		case CMD_UNLOAD_UNITS:
1111 		{
1112 			aiCommandTopic = COMMAND_UNIT_UNLOAD_UNITS_AREA;
1113 			break;
1114 		}
1115 		case CMD_UNLOAD_UNIT:
1116 		{
1117 			aiCommandTopic = COMMAND_UNIT_UNLOAD_UNIT;
1118 			break;
1119 		}
1120 		case CMD_ONOFF:
1121 		{
1122 			aiCommandTopic = COMMAND_UNIT_SET_ON_OFF;
1123 			break;
1124 		}
1125 		case CMD_RECLAIM:
1126 		{
1127 			if (engineCmd->params.size() < 3 || engineCmd->params.size() == 5) {
1128 				if (engineCmd->params[0] < maxUnits) {
1129 					aiCommandTopic = COMMAND_UNIT_RECLAIM_UNIT;
1130 				} else {
1131 					aiCommandTopic = COMMAND_UNIT_RECLAIM_FEATURE;
1132 				}
1133 			} else {
1134 				aiCommandTopic = COMMAND_UNIT_RECLAIM_AREA;
1135 			}
1136 			break;
1137 		}
1138 		case CMD_CLOAK:
1139 		{
1140 			aiCommandTopic = COMMAND_UNIT_CLOAK;
1141 			break;
1142 		}
1143 		case CMD_STOCKPILE:
1144 		{
1145 			aiCommandTopic = COMMAND_UNIT_STOCKPILE;
1146 			break;
1147 		}
1148 		case CMD_MANUALFIRE:
1149 		{
1150 			// FIXME
1151 			if (engineCmd->params.size() < 3) {
1152 				aiCommandTopic = COMMAND_UNIT_D_GUN;
1153 			} else {
1154 				aiCommandTopic = COMMAND_UNIT_D_GUN_POS;
1155 			}
1156 			break;
1157 		}
1158 		case CMD_RESTORE:
1159 		{
1160 			aiCommandTopic = COMMAND_UNIT_RESTORE_AREA;
1161 			break;
1162 		}
1163 		case CMD_REPEAT:
1164 		{
1165 			aiCommandTopic = COMMAND_UNIT_SET_REPEAT;
1166 			break;
1167 		}
1168 		case CMD_TRAJECTORY:
1169 		{
1170 			aiCommandTopic = COMMAND_UNIT_SET_TRAJECTORY;
1171 			break;
1172 		}
1173 		case CMD_RESURRECT:
1174 		{
1175 			if (engineCmd->params.size() < 3) {
1176 				aiCommandTopic = COMMAND_UNIT_RESURRECT;
1177 			} else {
1178 				aiCommandTopic = COMMAND_UNIT_RESURRECT_AREA;
1179 			}
1180 			break;
1181 		}
1182 		case CMD_CAPTURE:
1183 		{
1184 			if (engineCmd->params.size() < 3 || engineCmd->params.size() == 5) {
1185 				aiCommandTopic = COMMAND_UNIT_CAPTURE;
1186 			} else {
1187 				aiCommandTopic = COMMAND_UNIT_CAPTURE_AREA;
1188 			}
1189 			break;
1190 		}
1191 		case CMD_AUTOREPAIRLEVEL:
1192 		{
1193 			aiCommandTopic = COMMAND_UNIT_SET_AUTO_REPAIR_LEVEL;
1194 			break;
1195 		}
1196 		case CMD_IDLEMODE:
1197 		{
1198 			aiCommandTopic = COMMAND_UNIT_SET_IDLE_MODE;
1199 			break;
1200 		}
1201 		default:
1202 		{
1203 			if (internalUnitCmdTopic < 0) {
1204 				aiCommandTopic = COMMAND_UNIT_BUILD;
1205 			} else {
1206 				aiCommandTopic = COMMAND_UNIT_CUSTOM;
1207 			}
1208 			break;
1209 		}
1210 	}
1211 
1212 	return aiCommandTopic;
1213 }
1214 
newCommand(void * sUnitCommandData,int sCommandId,int maxUnits)1215 Command* newCommand(void* sUnitCommandData, int sCommandId, int maxUnits) {
1216 
1217 	Command* c = NULL;
1218 
1219 	switch (sCommandId) {
1220 		case COMMAND_UNIT_BUILD:
1221 		{
1222 			SBuildUnitCommand* cmd = static_cast<SBuildUnitCommand*>(sUnitCommandData);
1223 			c = new Command(-cmd->toBuildUnitDefId, cmd->options);
1224 			c->timeOut = cmd->timeOut;
1225 
1226 			if (cmd->buildPos_posF3 != NULL) {
1227 				c->PushPos(cmd->buildPos_posF3);
1228 			}
1229 			if (cmd->facing != UNIT_COMMAND_BUILD_NO_FACING) c->PushParam(cmd->facing);
1230 			break;
1231 		}
1232 		case COMMAND_UNIT_STOP:
1233 		{
1234 			SStopUnitCommand* cmd = static_cast<SStopUnitCommand*>(sUnitCommandData);
1235 			c = new Command(CMD_STOP, cmd->options);
1236 			c->timeOut = cmd->timeOut;
1237 			break;
1238 		}
1239 		case COMMAND_UNIT_WAIT:
1240 		{
1241 			SWaitUnitCommand* cmd = static_cast<SWaitUnitCommand*>(sUnitCommandData);
1242 			c = new Command(CMD_WAIT, cmd->options);
1243 			c->timeOut = cmd->timeOut;
1244 			break;
1245 		}
1246 		case COMMAND_UNIT_WAIT_TIME:
1247 		{
1248 			STimeWaitUnitCommand* cmd = static_cast<STimeWaitUnitCommand*>(sUnitCommandData);
1249 			c = new Command(CMD_TIMEWAIT, cmd->options, cmd->time);
1250 			c->timeOut = cmd->timeOut;
1251 
1252 			break;
1253 		}
1254 		case COMMAND_UNIT_WAIT_DEATH:
1255 		{
1256 			SDeathWaitUnitCommand* cmd = static_cast<SDeathWaitUnitCommand*>(sUnitCommandData);
1257 			c = new Command(CMD_DEATHWAIT, cmd->options, cmd->toDieUnitId);
1258 			c->timeOut = cmd->timeOut;
1259 
1260 			break;
1261 		}
1262 		case COMMAND_UNIT_WAIT_SQUAD:
1263 		{
1264 			SSquadWaitUnitCommand* cmd = static_cast<SSquadWaitUnitCommand*>(sUnitCommandData);
1265 			c = new Command(CMD_SQUADWAIT, cmd->options, cmd->numUnits);
1266 			c->timeOut = cmd->timeOut;
1267 
1268 			break;
1269 		}
1270 		case COMMAND_UNIT_WAIT_GATHER:
1271 		{
1272 			SGatherWaitUnitCommand* cmd = static_cast<SGatherWaitUnitCommand*>(sUnitCommandData);
1273 			c = new Command(CMD_GATHERWAIT, cmd->options);
1274 			c->timeOut = cmd->timeOut;
1275 			break;
1276 		}
1277 		case COMMAND_UNIT_MOVE:
1278 		{
1279 			SMoveUnitCommand* cmd = static_cast<SMoveUnitCommand*>(sUnitCommandData);
1280 			c = new Command(CMD_MOVE, cmd->options);
1281 			c->timeOut = cmd->timeOut;
1282 
1283 			c->PushPos(cmd->toPos_posF3);
1284 			break;
1285 		}
1286 		case COMMAND_UNIT_PATROL:
1287 		{
1288 			SPatrolUnitCommand* cmd = static_cast<SPatrolUnitCommand*>(sUnitCommandData);
1289 			c = new Command(CMD_PATROL, cmd->options);
1290 			c->timeOut = cmd->timeOut;
1291 
1292 			c->PushPos(cmd->toPos_posF3);
1293 			break;
1294 		}
1295 		case COMMAND_UNIT_FIGHT:
1296 		{
1297 			SFightUnitCommand* cmd = static_cast<SFightUnitCommand*>(sUnitCommandData);
1298 			c = new Command(CMD_FIGHT, cmd->options);
1299 			c->timeOut = cmd->timeOut;
1300 
1301 			c->PushPos(cmd->toPos_posF3);
1302 			break;
1303 		}
1304 		case COMMAND_UNIT_ATTACK:
1305 		{
1306 			SAttackUnitCommand* cmd = static_cast<SAttackUnitCommand*>(sUnitCommandData);
1307 			c = new Command(CMD_ATTACK, cmd->options, cmd->toAttackUnitId);
1308 			c->timeOut = cmd->timeOut;
1309 
1310 			break;
1311 		}
1312 		case COMMAND_UNIT_ATTACK_AREA:
1313 		{
1314 			SAttackAreaUnitCommand* cmd = static_cast<SAttackAreaUnitCommand*>(sUnitCommandData);
1315 			c = new Command(CMD_ATTACK, cmd->options);
1316 			c->timeOut = cmd->timeOut;
1317 
1318 			c->PushPos(cmd->toAttackPos_posF3);
1319 			c->PushParam(cmd->radius);
1320 			break;
1321 		}
1322 		case COMMAND_UNIT_GUARD:
1323 		{
1324 			SGuardUnitCommand* cmd = static_cast<SGuardUnitCommand*>(sUnitCommandData);
1325 			c = new Command(CMD_GUARD, cmd->options, cmd->toGuardUnitId);
1326 			c->timeOut = cmd->timeOut;
1327 
1328 			break;
1329 		}
1330 		case COMMAND_UNIT_GROUP_ADD:
1331 		{
1332 			SGroupAddUnitCommand* cmd = static_cast<SGroupAddUnitCommand*>(sUnitCommandData);
1333 			c = new Command(CMD_GROUPADD, cmd->options, cmd->toGroupId);
1334 			c->timeOut = cmd->timeOut;
1335 
1336 			break;
1337 		}
1338 		case COMMAND_UNIT_GROUP_CLEAR:
1339 		{
1340 			SGroupClearUnitCommand* cmd = static_cast<SGroupClearUnitCommand*>(sUnitCommandData);
1341 			c = new Command(CMD_GROUPCLEAR, cmd->options);
1342 			c->timeOut = cmd->timeOut;
1343 			break;
1344 		}
1345 		case COMMAND_UNIT_REPAIR:
1346 		{
1347 			SRepairUnitCommand* cmd = static_cast<SRepairUnitCommand*>(sUnitCommandData);
1348 			c = new Command(CMD_REPAIR, cmd->options, cmd->toRepairUnitId);
1349 			c->timeOut = cmd->timeOut;
1350 
1351 			break;
1352 		}
1353 		case COMMAND_UNIT_SET_FIRE_STATE:
1354 		{
1355 			SSetFireStateUnitCommand* cmd = static_cast<SSetFireStateUnitCommand*>(sUnitCommandData);
1356 			c = new Command(CMD_FIRE_STATE, cmd->options, cmd->fireState);
1357 			c->timeOut = cmd->timeOut;
1358 
1359 			break;
1360 		}
1361 		case COMMAND_UNIT_SET_MOVE_STATE:
1362 		{
1363 			SSetMoveStateUnitCommand* cmd = static_cast<SSetMoveStateUnitCommand*>(sUnitCommandData);
1364 			c = new Command(CMD_MOVE_STATE, cmd->options, cmd->moveState);
1365 			c->timeOut = cmd->timeOut;
1366 
1367 			break;
1368 		}
1369 		case COMMAND_UNIT_SET_BASE:
1370 		{
1371 			SSetBaseUnitCommand* cmd = static_cast<SSetBaseUnitCommand*>(sUnitCommandData);
1372 			c = new Command(CMD_SETBASE, cmd->options);
1373 			c->timeOut = cmd->timeOut;
1374 
1375 			c->PushPos(cmd->basePos_posF3);
1376 			break;
1377 		}
1378 		case COMMAND_UNIT_SELF_DESTROY:
1379 		{
1380 			SSelfDestroyUnitCommand* cmd = static_cast<SSelfDestroyUnitCommand*>(sUnitCommandData);
1381 			c = new Command(CMD_SELFD, cmd->options);
1382 			c->timeOut = cmd->timeOut;
1383 			break;
1384 		}
1385 		case COMMAND_UNIT_SET_WANTED_MAX_SPEED:
1386 		{
1387 			SSetWantedMaxSpeedUnitCommand* cmd = static_cast<SSetWantedMaxSpeedUnitCommand*>(sUnitCommandData);
1388 			c = new Command(CMD_SET_WANTED_MAX_SPEED, cmd->options, cmd->wantedMaxSpeed);
1389 			c->timeOut = cmd->timeOut;
1390 
1391 			break;
1392 		}
1393 		case COMMAND_UNIT_LOAD_UNITS:
1394 		{
1395 			SLoadUnitsUnitCommand* cmd = static_cast<SLoadUnitsUnitCommand*>(sUnitCommandData);
1396 			c = new Command(CMD_LOAD_UNITS, cmd->options);
1397 			c->timeOut = cmd->timeOut;
1398 
1399 			for (int i = 0; i < cmd->toLoadUnitIds_size; ++i) {
1400 				c->PushParam(cmd->toLoadUnitIds[i]);
1401 			}
1402 			break;
1403 		}
1404 		case COMMAND_UNIT_LOAD_UNITS_AREA:
1405 		{
1406 			SLoadUnitsAreaUnitCommand* cmd = static_cast<SLoadUnitsAreaUnitCommand*>(sUnitCommandData);
1407 			c = new Command(CMD_LOAD_UNITS, cmd->options);
1408 			c->timeOut = cmd->timeOut;
1409 
1410 			c->PushPos(cmd->pos_posF3);
1411 			c->PushParam(cmd->radius);
1412 			break;
1413 		}
1414 		case COMMAND_UNIT_LOAD_ONTO:
1415 		{
1416 			SLoadOntoUnitCommand* cmd = static_cast<SLoadOntoUnitCommand*>(sUnitCommandData);
1417 			c = new Command(CMD_LOAD_ONTO, cmd->options, cmd->transporterUnitId);
1418 			c->timeOut = cmd->timeOut;
1419 
1420 			break;
1421 		}
1422 		case COMMAND_UNIT_UNLOAD_UNITS_AREA:
1423 		{
1424 			SUnloadUnitsAreaUnitCommand* cmd = static_cast<SUnloadUnitsAreaUnitCommand*>(sUnitCommandData);
1425 			c = new Command(CMD_UNLOAD_UNITS, cmd->options);
1426 			c->timeOut = cmd->timeOut;
1427 
1428 			c->PushPos(cmd->toPos_posF3);
1429 			c->PushParam(cmd->radius);
1430 			break;
1431 		}
1432 		case COMMAND_UNIT_UNLOAD_UNIT:
1433 		{
1434 			SUnloadUnitCommand* cmd = static_cast<SUnloadUnitCommand*>(sUnitCommandData);
1435 			c = new Command(CMD_UNLOAD_UNIT, cmd->options);
1436 			c->timeOut = cmd->timeOut;
1437 
1438 			c->PushPos(cmd->toPos_posF3);
1439 			c->PushParam(cmd->toUnloadUnitId);
1440 			break;
1441 		}
1442 		case COMMAND_UNIT_SET_ON_OFF:
1443 		{
1444 			SSetOnOffUnitCommand* cmd = static_cast<SSetOnOffUnitCommand*>(sUnitCommandData);
1445 			c = new Command(CMD_ONOFF, cmd->options, cmd->on ? 1 : 0);
1446 			c->timeOut = cmd->timeOut;
1447 
1448 			break;
1449 		}
1450 		case COMMAND_UNIT_RECLAIM_UNIT:
1451 		{
1452 			SReclaimUnitUnitCommand* cmd = static_cast<SReclaimUnitUnitCommand*>(sUnitCommandData);
1453 			c = new Command(CMD_RECLAIM, cmd->options, cmd->toReclaimUnitId);
1454 			c->timeOut = cmd->timeOut;
1455 
1456 			break;
1457 		}
1458 		case COMMAND_UNIT_RECLAIM_FEATURE:
1459 		{
1460 			SReclaimFeatureUnitCommand* cmd = static_cast<SReclaimFeatureUnitCommand*>(sUnitCommandData);
1461 			c = new Command(CMD_RECLAIM, cmd->options, maxUnits + cmd->toReclaimFeatureId);
1462 			c->timeOut = cmd->timeOut;
1463 
1464 			break;
1465 		}
1466 		case COMMAND_UNIT_RECLAIM_AREA:
1467 		{
1468 			SReclaimAreaUnitCommand* cmd = static_cast<SReclaimAreaUnitCommand*>(sUnitCommandData);
1469 			c = new Command(CMD_RECLAIM, cmd->options);
1470 			c->timeOut = cmd->timeOut;
1471 
1472 			c->PushPos(cmd->pos_posF3);
1473 			c->PushParam(cmd->radius);
1474 			break;
1475 		}
1476 		case COMMAND_UNIT_CLOAK:
1477 		{
1478 			SCloakUnitCommand* cmd = static_cast<SCloakUnitCommand*>(sUnitCommandData);
1479 			c = new Command(CMD_CLOAK, cmd->options, cmd->cloak ? 1 : 0);
1480 			c->timeOut = cmd->timeOut;
1481 
1482 			break;
1483 		}
1484 		case COMMAND_UNIT_STOCKPILE:
1485 		{
1486 			SStockpileUnitCommand* cmd = static_cast<SStockpileUnitCommand*>(sUnitCommandData);
1487 			c = new Command(CMD_STOCKPILE, cmd->options);
1488 			c->timeOut = cmd->timeOut;
1489 			break;
1490 		}
1491 
1492 		case COMMAND_UNIT_D_GUN:
1493 		{
1494 			// FIXME
1495 			SDGunUnitCommand* cmd = static_cast<SDGunUnitCommand*>(sUnitCommandData);
1496 			c = new Command(CMD_MANUALFIRE, cmd->options, cmd->toAttackUnitId);
1497 			c->timeOut = cmd->timeOut;
1498 
1499 			break;
1500 		}
1501 		case COMMAND_UNIT_D_GUN_POS:
1502 		{
1503 			// FIXME
1504 			SDGunPosUnitCommand* cmd = static_cast<SDGunPosUnitCommand*>(sUnitCommandData);
1505 			c = new Command(CMD_MANUALFIRE, cmd->options);
1506 			c->timeOut = cmd->timeOut;
1507 
1508 			c->PushPos(cmd->pos_posF3);
1509 			break;
1510 		}
1511 
1512 		case COMMAND_UNIT_RESTORE_AREA:
1513 		{
1514 			SRestoreAreaUnitCommand* cmd = static_cast<SRestoreAreaUnitCommand*>(sUnitCommandData);
1515 			c = new Command(CMD_RESTORE, cmd->options);
1516 			c->timeOut = cmd->timeOut;
1517 
1518 			c->PushPos(cmd->pos_posF3);
1519 			c->PushParam(cmd->radius);
1520 			break;
1521 		}
1522 		case COMMAND_UNIT_SET_REPEAT:
1523 		{
1524 			SSetRepeatUnitCommand* cmd = static_cast<SSetRepeatUnitCommand*>(sUnitCommandData);
1525 			c = new Command(CMD_REPEAT, cmd->options, cmd->repeat ? 1 : 0);
1526 			c->timeOut = cmd->timeOut;
1527 
1528 			break;
1529 		}
1530 		case COMMAND_UNIT_SET_TRAJECTORY:
1531 		{
1532 			SSetTrajectoryUnitCommand* cmd = static_cast<SSetTrajectoryUnitCommand*>(sUnitCommandData);
1533 			c = new Command(CMD_TRAJECTORY, cmd->options, cmd->trajectory);
1534 			c->timeOut = cmd->timeOut;
1535 
1536 			break;
1537 		}
1538 		case COMMAND_UNIT_RESURRECT:
1539 		{
1540 			SResurrectUnitCommand* cmd = static_cast<SResurrectUnitCommand*>(sUnitCommandData);
1541 			c = new Command(CMD_RESURRECT, cmd->options, cmd->toResurrectFeatureId);
1542 			c->timeOut = cmd->timeOut;
1543 
1544 			break;
1545 		}
1546 		case COMMAND_UNIT_RESURRECT_AREA:
1547 		{
1548 			SResurrectAreaUnitCommand* cmd = static_cast<SResurrectAreaUnitCommand*>(sUnitCommandData);
1549 			c = new Command(CMD_RESURRECT, cmd->options);
1550 			c->timeOut = cmd->timeOut;
1551 
1552 			c->PushPos(cmd->pos_posF3);
1553 			c->PushParam(cmd->radius);
1554 			break;
1555 		}
1556 		case COMMAND_UNIT_CAPTURE:
1557 		{
1558 			SCaptureUnitCommand* cmd = static_cast<SCaptureUnitCommand*>(sUnitCommandData);
1559 			c = new Command(CMD_CAPTURE, cmd->options, cmd->toCaptureUnitId);
1560 			c->timeOut = cmd->timeOut;
1561 
1562 			break;
1563 		}
1564 		case COMMAND_UNIT_CAPTURE_AREA:
1565 		{
1566 			SCaptureAreaUnitCommand* cmd = static_cast<SCaptureAreaUnitCommand*>(sUnitCommandData);
1567 			c = new Command(CMD_CAPTURE, cmd->options);
1568 			c->timeOut = cmd->timeOut;
1569 
1570 			c->PushPos(cmd->pos_posF3);
1571 			c->PushParam(cmd->radius);
1572 			break;
1573 		}
1574 		case COMMAND_UNIT_SET_AUTO_REPAIR_LEVEL:
1575 		{
1576 			SSetAutoRepairLevelUnitCommand* cmd = static_cast<SSetAutoRepairLevelUnitCommand*>(sUnitCommandData);
1577 			c = new Command(CMD_AUTOREPAIRLEVEL, cmd->options, cmd->autoRepairLevel);
1578 			c->timeOut = cmd->timeOut;
1579 
1580 			break;
1581 		}
1582 		case COMMAND_UNIT_SET_IDLE_MODE:
1583 		{
1584 			SSetIdleModeUnitCommand* cmd = static_cast<SSetIdleModeUnitCommand*>(sUnitCommandData);
1585 			c = new Command(CMD_IDLEMODE, cmd->options, cmd->idleMode);
1586 			c->timeOut = cmd->timeOut;
1587 
1588 			break;
1589 		}
1590 		case COMMAND_UNIT_CUSTOM:
1591 		{
1592 			SCustomUnitCommand* cmd = static_cast<SCustomUnitCommand*>(sUnitCommandData);
1593 			c = new Command(cmd->cmdId, cmd->options);
1594 			c->timeOut = cmd->timeOut;
1595 
1596 			for (int i = 0; i < cmd->params_size; ++i) {
1597 				c->PushParam(cmd->params[i]);
1598 			}
1599 			break;
1600 		}
1601 		default:
1602 		{
1603 			delete c;
1604 			c = NULL;
1605 		}
1606 	}
1607 
1608 	return c;
1609 }
1610 
1611 #endif // __cplusplus
1612