1use std::error::Error;
2
3use spring_ai_sys::COMMAND_TO_ID_ENGINE;
4
5use crate::ai_interface::callback::{
6 command::{
7 command_data::{
8 unit::{
9 AiSelectUnitCommandData, AttackAreaUnitCommandData, AttackUnitCommandData,
10 BuildUnitCommandData, CaptureAreaUnitCommanddData, CaptureUnitCommanddData,
11 CloakUnitCommandData, CustomUnitCommanddData, DGunUnitCommandData,
12 FightUnitCommandData, GuardUnitCommandData, LoadOntoUnitCommandData,
13 LoadUnitsAreaCommandData, LoadUnitsUnitCommandData, MoveUnitCommandData,
14 PatrolUnitCommandData, ReclaimAreaUnitCommandData, ReclaimFeatureUnitCommandData,
15 ReclaimUnitUnitCommandData, RepairUnitCommandData, RestoreAreaUnitCommandData,
16 ResurrectAreaUnitCommandData, ResurrectUnitCommandData, SelfDestroyUnitCommandData,
17 SetAutoRepairLevelUnitCommandData, SetBaseUnitCommandData, SetFireUnitCommandData,
18 SetIdleModeCommandData, SetMoveStateCommandData, SetUnitOnOffCommandData,
19 SetUnitRepeatCommandData, SetUnitStockpileCommandData, SetUnitStopCommandData,
20 SetUnitTrajectoryCommandData, SetUnitUnloadAreaCommandData,
21 SetUnitUnloadCommandData, SetUnitWaitCommandData, SetUnitWaitGatherCommandData,
22 SetUnitWaitSquadCommandData, SetUnitWaitTimeCommandData,
23 },
24 CommandData,
25 },
26 command_topic::CommandTopic,
27 options::UnitCommandOptions,
28 },
29 engine::handle_command,
30 facing::Facing,
31 feature::Feature,
32 fire_state::FireState,
33 idle_mode::IdleMode,
34 move_state::MoveState,
35 position::Position,
36 trajectory::Trajectory,
37 unit::Unit,
38 unit_def::UnitDef,
39};
40
41impl Unit {
42 pub fn select(
43 &self,
44 options: &[UnitCommandOptions],
45 command_id: Option<i32>,
46 timeout: Option<i32>,
47 ) -> Result<(), &'static str> {
48 let mut command_data = AiSelectUnitCommandData {
49 unit_id: self.unit_id,
50 group_id: -1,
51 options: options.to_vec(),
52 timeout: timeout.unwrap_or(i32::MAX),
53 };
54
55 handle_command(
56 self.ai_id,
57 COMMAND_TO_ID_ENGINE,
58 command_id.unwrap_or(-1),
59 CommandTopic::UnitAISelect.into(),
60 &mut command_data.c_data(),
61 )
62 }
63
64 pub fn attack(
65 &self,
66 options: &[UnitCommandOptions],
67 command_id: Option<i32>,
68 timeout: Option<i32>,
69 target: Unit,
70 ) -> Result<(), &'static str> {
71 let mut command_data = AttackUnitCommandData {
72 unit_id: self.unit_id,
73 group_id: -1,
74 options: options.to_vec(),
75 timeout: timeout.unwrap_or(i32::MAX),
76 target_unit_id: target.unit_id,
77 };
78
79 handle_command(
80 self.ai_id,
81 COMMAND_TO_ID_ENGINE,
82 command_id.unwrap_or(-1),
83 CommandTopic::UnitAttack.into(),
84 &mut command_data.c_data(),
85 )
86 }
87
88 pub fn attack_area(
89 &self,
90 options: &[UnitCommandOptions],
91 command_id: Option<i32>,
92 timeout: Option<i32>,
93 position: [f32; 3],
94 radius: f32,
95 ) -> Result<(), &'static str> {
96 let mut command_data = AttackAreaUnitCommandData {
97 unit_id: self.unit_id,
98 group_id: -1,
99 options: options.to_vec(),
100 timeout: timeout.unwrap_or(i32::MAX),
101 attack_position: position,
102 radius,
103 };
104
105 handle_command(
106 self.ai_id,
107 COMMAND_TO_ID_ENGINE,
108 command_id.unwrap_or(-1),
109 CommandTopic::UnitAttackArea.into(),
110 &mut command_data.c_data(),
111 )
112 }
113
114 pub fn build<P: Position, D: PartialEq<UnitDef>>(
115 &self,
116 options: &[UnitCommandOptions],
117 command_id: Option<i32>,
118 timeout: Option<i32>,
119 to_build_unit_def: D,
120 position: P,
121 facing: Facing,
122 ) -> Result<(), Box<dyn Error>> {
123 let mut building_def_opt = None;
124 for unit_def in self.unit_def()?.building().build_options()? {
125 if to_build_unit_def == unit_def {
126 building_def_opt = Some(unit_def);
127 }
128 }
129
130 if let Some(building_def) = building_def_opt {
131 let building_x = building_def.miscellaneous().x_size()?;
132 let building_z = building_def.miscellaneous().z_size()?;
133
134 let mut build_position = position.to_f32_array(self.ai_id)?;
135 build_position[0] =
136 ((build_position[0] + (building_x as f32 / 2.0)) / 16.0).trunc() * 16.0;
137 build_position[2] =
138 ((build_position[2] + (building_z as f32 / 2.0)) / 16.0).trunc() * 16.0;
139
140 let mut command_data = BuildUnitCommandData {
141 unit_id: self.unit_id,
142 group_id: -1,
143 options: options.to_vec(),
144 timeout: timeout.unwrap_or(i32::MAX),
145 to_build_unit_def_id: building_def.def_id,
146 build_position,
147 facing,
148 };
149
150 handle_command(
151 self.ai_id,
152 COMMAND_TO_ID_ENGINE,
153 command_id.unwrap_or(-1),
154 CommandTopic::UnitBuild.into(),
155 &mut command_data.c_data(),
156 )?;
157 }
158
159 Ok(())
160 }
161
162 pub fn capture(
163 &self,
164 options: &[UnitCommandOptions],
165 command_id: Option<i32>,
166 timeout: Option<i32>,
167 target: Unit,
168 ) -> Result<(), &'static str> {
169 let mut command_data = CaptureUnitCommanddData {
170 unit_id: self.unit_id,
171 group_id: -1,
172 options: options.to_vec(),
173 timeout: timeout.unwrap_or(i32::MAX),
174 to_capture_unit_id: target.unit_id,
175 };
176
177 handle_command(
178 self.ai_id,
179 COMMAND_TO_ID_ENGINE,
180 command_id.unwrap_or(-1),
181 CommandTopic::UnitCapture.into(),
182 &mut command_data.c_data(),
183 )
184 }
185
186 pub fn capture_area(
187 &self,
188 options: &[UnitCommandOptions],
189 command_id: Option<i32>,
190 timeout: Option<i32>,
191 position: [f32; 3],
192 radius: f32,
193 ) -> Result<(), &'static str> {
194 let mut command_data = CaptureAreaUnitCommanddData {
195 unit_id: self.unit_id,
196 group_id: -1,
197 options: options.to_vec(),
198 timeout: timeout.unwrap_or(i32::MAX),
199 position,
200 radius,
201 };
202
203 handle_command(
204 self.ai_id,
205 COMMAND_TO_ID_ENGINE,
206 command_id.unwrap_or(-1),
207 CommandTopic::UnitCaptureArea.into(),
208 &mut command_data.c_data(),
209 )
210 }
211
212 pub fn cloak(
213 &self,
214 options: &[UnitCommandOptions],
215 command_id: Option<i32>,
216 timeout: Option<i32>,
217 cloak: bool,
218 ) -> Result<(), &'static str> {
219 let mut command_data = CloakUnitCommandData {
220 unit_id: self.unit_id,
221 group_id: -1,
222 options: options.to_vec(),
223 timeout: timeout.unwrap_or(i32::MAX),
224 cloak,
225 };
226
227 handle_command(
228 self.ai_id,
229 COMMAND_TO_ID_ENGINE,
230 command_id.unwrap_or(-1),
231 CommandTopic::UnitCloak.into(),
232 &mut command_data.c_data(),
233 )
234 }
235
236 pub fn custom_command(
237 &self,
238 options: &[UnitCommandOptions],
239 command_id: Option<i32>,
240 timeout: Option<i32>,
241 parameters: Vec<f32>,
242 ) -> Result<(), &'static str> {
243 let mut command_data = CustomUnitCommanddData {
244 unit_id: self.unit_id,
245 group_id: -1,
246 options: options.to_vec(),
247 timeout: timeout.unwrap_or(i32::MAX),
248 command_id: command_id.unwrap_or(-1),
249 parameters,
250 };
251
252 handle_command(
253 self.ai_id,
254 COMMAND_TO_ID_ENGINE,
255 command_id.unwrap_or(-1),
256 CommandTopic::UnitCustom.into(),
257 &mut command_data.c_data(),
258 )
259 }
260
261 pub fn dgun_unit(
262 &self,
263 options: &[UnitCommandOptions],
264 command_id: Option<i32>,
265 timeout: Option<i32>,
266 target: Unit,
267 ) -> Result<(), &'static str> {
268 let mut command_data = DGunUnitCommandData {
269 unitId: self.unit_id,
270 groupId: -1,
271 options: options.to_vec(),
272 timeOut: timeout.unwrap_or(i32::MAX),
273 toAttackUnitId: target.unit_id,
274 };
275
276 handle_command(
277 self.ai_id,
278 COMMAND_TO_ID_ENGINE,
279 command_id.unwrap_or(-1),
280 CommandTopic::UnitDGun.into(),
281 &mut command_data.c_data(),
282 )
283 }
284
285 pub fn fight<P: Position>(
286 &self,
287 options: &[UnitCommandOptions],
288 command_id: Option<i32>,
289 timeout: Option<i32>,
290 position: P,
291 ) -> Result<(), &'static str> {
292 let mut command_data = FightUnitCommandData {
293 unitId: self.unit_id,
294 groupId: -1,
295 options: options.to_vec(),
296 timeOut: timeout.unwrap_or(i32::MAX),
297 position: position.to_f32_array(self.ai_id).unwrap(),
298 };
299
300 handle_command(
301 self.ai_id,
302 COMMAND_TO_ID_ENGINE,
303 command_id.unwrap_or(-1),
304 CommandTopic::UnitFight.into(),
305 &mut command_data.c_data(),
306 )
307 }
308
309 pub fn guard(
310 &self,
311 options: &[UnitCommandOptions],
312 command_id: Option<i32>,
313 timeout: Option<i32>,
314 target: Unit,
315 ) -> Result<(), &'static str> {
316 let mut command_data = GuardUnitCommandData {
317 unitId: self.unit_id,
318 groupId: -1,
319 options: options.to_vec(),
320 timeOut: timeout.unwrap_or(i32::MAX),
321 to_guard_unit_id: target.unit_id,
322 };
323
324 handle_command(
325 self.ai_id,
326 COMMAND_TO_ID_ENGINE,
327 command_id.unwrap_or(-1),
328 CommandTopic::UnitGuard.into(),
329 &mut command_data.c_data(),
330 )
331 }
332
333 pub fn load_onto(
334 &self,
335 options: &[UnitCommandOptions],
336 command_id: Option<i32>,
337 timeout: Option<i32>,
338 target: Unit,
339 ) -> Result<(), &'static str> {
340 let mut command_data = LoadOntoUnitCommandData {
341 unitId: self.unit_id,
342 groupId: -1,
343 options: options.to_vec(),
344 timeOut: timeout.unwrap_or(i32::MAX),
345 transporter_unit_id: target.unit_id,
346 };
347
348 handle_command(
349 self.ai_id,
350 COMMAND_TO_ID_ENGINE,
351 command_id.unwrap_or(-1),
352 CommandTopic::UnitLoadOnto.into(),
353 &mut command_data.c_data(),
354 )
355 }
356
357 pub fn load_units(
358 &self,
359 options: &[UnitCommandOptions],
360 command_id: Option<i32>,
361 timeout: Option<i32>,
362 targets: &[Unit],
363 ) -> Result<(), &'static str> {
364 let mut command_data = LoadUnitsUnitCommandData {
365 unitId: self.unit_id,
366 groupId: -1,
367 options: options.to_vec(),
368 timeOut: timeout.unwrap_or(i32::MAX),
369 to_load_unit_ids: targets.iter().map(|t| t.unit_id).collect(),
370 };
371
372 handle_command(
373 self.ai_id,
374 COMMAND_TO_ID_ENGINE,
375 command_id.unwrap_or(-1),
376 CommandTopic::UnitLoadUnits.into(),
377 &mut command_data.c_data(),
378 )
379 }
380
381 pub fn load_units_area(
382 &self,
383 options: &[UnitCommandOptions],
384 command_id: Option<i32>,
385 timeout: Option<i32>,
386 position: [f32; 3],
387 radius: f32,
388 ) -> Result<(), &'static str> {
389 let mut command_data = LoadUnitsAreaCommandData {
390 unitId: self.unit_id,
391 groupId: -1,
392 options: options.to_vec(),
393 timeOut: timeout.unwrap_or(i32::MAX),
394 position,
395 radius,
396 };
397
398 handle_command(
399 self.ai_id,
400 COMMAND_TO_ID_ENGINE,
401 command_id.unwrap_or(-1),
402 CommandTopic::UnitLoadUnitsArea.into(),
403 &mut command_data.c_data(),
404 )
405 }
406
407 pub fn move_unit<P: Position>(
408 &self,
409 options: &[UnitCommandOptions],
410 command_id: Option<i32>,
411 timeout: Option<i32>,
412 to_pos: P,
413 ) -> Result<(), Box<dyn Error>> {
414 let mut command_data = MoveUnitCommandData {
415 unit_id: self.unit_id,
416 group_id: -1,
417 options: options.to_vec(),
418 timeout: timeout.unwrap_or(i32::MAX),
419 to_pos: to_pos.to_f32_array(self.ai_id)?,
420 };
421
422 handle_command(
423 self.ai_id,
424 COMMAND_TO_ID_ENGINE,
425 command_id.unwrap_or(-1),
426 CommandTopic::UnitMove.into(),
427 &mut command_data.c_data(),
428 )?;
429
430 Ok(())
431 }
432
433 pub fn patrol<P: Position>(
434 &self,
435 options: &[UnitCommandOptions],
436 command_id: Option<i32>,
437 timeout: Option<i32>,
438 to_pos: P,
439 ) -> Result<(), Box<dyn Error>> {
440 let mut command_data = PatrolUnitCommandData {
441 unit_id: self.unit_id,
442 group_id: -1,
443 options: options.to_vec(),
444 timeout: timeout.unwrap_or(i32::MAX),
445 to_pos: to_pos.to_f32_array(self.ai_id)?,
446 };
447
448 handle_command(
449 self.ai_id,
450 COMMAND_TO_ID_ENGINE,
451 command_id.unwrap_or(-1),
452 CommandTopic::UnitPatrol.into(),
453 &mut command_data.c_data(),
454 )?;
455
456 Ok(())
457 }
458
459 pub fn reclaim_area<P: Position>(
460 &self,
461 options: &[UnitCommandOptions],
462 command_id: Option<i32>,
463 timeout: Option<i32>,
464 position: P,
465 radius: f32,
466 ) -> Result<(), &'static str> {
467 let mut command_data = ReclaimAreaUnitCommandData {
468 unit_id: self.unit_id,
469 group_id: -1,
470 options: options.to_vec(),
471 timeout: timeout.unwrap_or(i32::MAX),
472 position: position.to_f32_array(self.ai_id).unwrap(),
473 radius,
474 };
475
476 handle_command(
477 self.ai_id,
478 COMMAND_TO_ID_ENGINE,
479 command_id.unwrap_or(-1),
480 CommandTopic::UnitReclaimArea.into(),
481 &mut command_data.c_data(),
482 )
483 }
484
485 pub fn reclaim_feature(
486 &self,
487 options: &[UnitCommandOptions],
488 command_id: Option<i32>,
489 timeout: Option<i32>,
490 target: Feature,
491 ) -> Result<(), &'static str> {
492 let mut command_data = ReclaimFeatureUnitCommandData {
493 unit_id: self.unit_id,
494 group_id: -1,
495 options: options.to_vec(),
496 timeout: timeout.unwrap_or(i32::MAX),
497 to_reclaim_feature_id: target.feature_id,
498 };
499
500 handle_command(
501 self.ai_id,
502 COMMAND_TO_ID_ENGINE,
503 command_id.unwrap_or(-1),
504 CommandTopic::UnitReclaimFeature.into(),
505 &mut command_data.c_data(),
506 )
507 }
508
509 pub fn reclaim_unit(
510 &self,
511 options: &[UnitCommandOptions],
512 command_id: Option<i32>,
513 timeout: Option<i32>,
514 target: Unit,
515 ) -> Result<(), &'static str> {
516 let mut command_data = ReclaimUnitUnitCommandData {
517 unit_id: self.unit_id,
518 group_id: -1,
519 options: options.to_vec(),
520 timeout: timeout.unwrap_or(i32::MAX),
521 to_reclaim_unit_id: target.unit_id,
522 };
523
524 handle_command(
525 self.ai_id,
526 COMMAND_TO_ID_ENGINE,
527 command_id.unwrap_or(-1),
528 CommandTopic::UnitReclaimFeature.into(),
529 &mut command_data.c_data(),
530 )
531 }
532
533 pub fn repair_unit(
534 &self,
535 options: &[UnitCommandOptions],
536 command_id: Option<i32>,
537 timeout: Option<i32>,
538 target: Unit,
539 ) -> Result<(), &'static str> {
540 let mut command_data = RepairUnitCommandData {
541 unit_id: self.unit_id,
542 group_id: -1,
543 options: options.to_vec(),
544 timeout: timeout.unwrap_or(i32::MAX),
545 to_repair_unit_id: target.unit_id,
546 };
547
548 handle_command(
549 self.ai_id,
550 COMMAND_TO_ID_ENGINE,
551 command_id.unwrap_or(-1),
552 CommandTopic::UnitRepair.into(),
553 &mut command_data.c_data(),
554 )
555 }
556
557 pub fn restore_area(
558 &self,
559 options: &[UnitCommandOptions],
560 command_id: Option<i32>,
561 timeout: Option<i32>,
562 position: [f32; 3],
563 radius: f32,
564 ) -> Result<(), &'static str> {
565 let mut command_data = RestoreAreaUnitCommandData {
566 unit_id: self.unit_id,
567 group_id: -1,
568 options: options.to_vec(),
569 timeout: timeout.unwrap_or(i32::MAX),
570 position,
571 radius,
572 };
573
574 handle_command(
575 self.ai_id,
576 COMMAND_TO_ID_ENGINE,
577 command_id.unwrap_or(-1),
578 CommandTopic::UnitRestoreArea.into(),
579 &mut command_data.c_data(),
580 )
581 }
582
583 pub fn resurrect_unit(
584 &self,
585 options: &[UnitCommandOptions],
586 command_id: Option<i32>,
587 timeout: Option<i32>,
588 target: Unit,
589 ) -> Result<(), &'static str> {
590 let mut command_data = ResurrectUnitCommandData {
591 unit_id: self.unit_id,
592 group_id: -1,
593 options: options.to_vec(),
594 timeout: timeout.unwrap_or(i32::MAX),
595 to_resurrect_feature_id: target.unit_id,
596 };
597
598 handle_command(
599 self.ai_id,
600 COMMAND_TO_ID_ENGINE,
601 command_id.unwrap_or(-1),
602 CommandTopic::UnitResurrect.into(),
603 &mut command_data.c_data(),
604 )
605 }
606
607 pub fn resurrect_area(
608 &self,
609 options: &[UnitCommandOptions],
610 command_id: Option<i32>,
611 timeout: Option<i32>,
612 position: [f32; 3],
613 radius: f32,
614 ) -> Result<(), &'static str> {
615 let mut command_data = ResurrectAreaUnitCommandData {
616 unit_id: self.unit_id,
617 group_id: -1,
618 options: options.to_vec(),
619 timeout: timeout.unwrap_or(i32::MAX),
620 position,
621 radius,
622 };
623
624 handle_command(
625 self.ai_id,
626 COMMAND_TO_ID_ENGINE,
627 command_id.unwrap_or(-1),
628 CommandTopic::UnitResurrectArea.into(),
629 &mut command_data.c_data(),
630 )
631 }
632
633 pub fn self_destruct(
634 &self,
635 options: &[UnitCommandOptions],
636 command_id: Option<i32>,
637 timeout: Option<i32>,
638 ) -> Result<(), &'static str> {
639 let mut command_data = SelfDestroyUnitCommandData {
640 unit_id: self.unit_id,
641 group_id: -1,
642 options: options.to_vec(),
643 timeout: timeout.unwrap_or(i32::MAX),
644 };
645
646 handle_command(
647 self.ai_id,
648 COMMAND_TO_ID_ENGINE,
649 command_id.unwrap_or(-1),
650 CommandTopic::UnitSelfDestroy.into(),
651 &mut command_data.c_data(),
652 )
653 }
654
655 pub fn set_auto_repair_level(
656 &self,
657 options: &[UnitCommandOptions],
658 command_id: Option<i32>,
659 timeout: Option<i32>,
660 auto_repair_level: i32,
661 ) -> Result<(), &'static str> {
662 let mut command_data = SetAutoRepairLevelUnitCommandData {
663 unit_id: self.unit_id,
664 group_id: -1,
665 options: options.to_vec(),
666 timeout: timeout.unwrap_or(i32::MAX),
667 auto_repair_level,
668 };
669
670 handle_command(
671 self.ai_id,
672 COMMAND_TO_ID_ENGINE,
673 command_id.unwrap_or(-1),
674 CommandTopic::UnitSetAutoRepairLevel.into(),
675 &mut command_data.c_data(),
676 )
677 }
678
679 pub fn set_base_command(
680 &self,
681 options: &[UnitCommandOptions],
682 command_id: Option<i32>,
683 timeout: Option<i32>,
684 base_position: [f32; 3],
685 ) -> Result<(), &'static str> {
686 let mut command_data = SetBaseUnitCommandData {
687 unit_id: self.unit_id,
688 group_id: -1,
689 options: options.to_vec(),
690 timeout: timeout.unwrap_or(i32::MAX),
691 base_position,
692 };
693
694 handle_command(
695 self.ai_id,
696 COMMAND_TO_ID_ENGINE,
697 command_id.unwrap_or(-1),
698 CommandTopic::UnitSetBase.into(),
699 &mut command_data.c_data(),
700 )
701 }
702
703 pub fn set_fire_state(
704 &self,
705 options: &[UnitCommandOptions],
706 command_id: Option<i32>,
707 timeout: Option<i32>,
708 fire_state: FireState,
709 ) -> Result<(), &'static str> {
710 let mut command_data = SetFireUnitCommandData {
711 unit_id: self.unit_id,
712 group_id: -1,
713 options: options.to_vec(),
714 timeout: timeout.unwrap_or(i32::MAX),
715 fire_state,
716 };
717
718 handle_command(
719 self.ai_id,
720 COMMAND_TO_ID_ENGINE,
721 command_id.unwrap_or(-1),
722 CommandTopic::UnitSetFireState.into(),
723 &mut command_data.c_data(),
724 )
725 }
726
727 pub fn set_idle_mode(
728 &self,
729 options: &[UnitCommandOptions],
730 command_id: Option<i32>,
731 timeout: Option<i32>,
732 idle_mode: IdleMode,
733 ) -> Result<(), &'static str> {
734 let mut command_data = SetIdleModeCommandData {
735 unit_id: self.unit_id,
736 group_id: -1,
737 options: options.to_vec(),
738 timeout: timeout.unwrap_or(i32::MAX),
739 idle_mode,
740 };
741
742 handle_command(
743 self.ai_id,
744 COMMAND_TO_ID_ENGINE,
745 command_id.unwrap_or(-1),
746 CommandTopic::UnitSetIdleMode.into(),
747 &mut command_data.c_data(),
748 )
749 }
750
751 pub fn set_move_state(
752 &self,
753 options: &[UnitCommandOptions],
754 command_id: Option<i32>,
755 timeout: Option<i32>,
756 move_state: MoveState,
757 ) -> Result<(), &'static str> {
758 let mut command_data = SetMoveStateCommandData {
759 unit_id: self.unit_id,
760 group_id: -1,
761 options: options.to_vec(),
762 timeout: timeout.unwrap_or(i32::MAX),
763 move_state,
764 };
765
766 handle_command(
767 self.ai_id,
768 COMMAND_TO_ID_ENGINE,
769 command_id.unwrap_or(-1),
770 CommandTopic::UnitSetMoveState.into(),
771 &mut command_data.c_data(),
772 )
773 }
774
775 pub fn set_on_off(
776 &self,
777 options: &[UnitCommandOptions],
778 command_id: Option<i32>,
779 timeout: Option<i32>,
780 on: bool,
781 ) -> Result<(), &'static str> {
782 let mut command_data = SetUnitOnOffCommandData {
783 unit_id: self.unit_id,
784 group_id: -1,
785 options: options.to_vec(),
786 timeout: timeout.unwrap_or(i32::MAX),
787 on,
788 };
789
790 handle_command(
791 self.ai_id,
792 COMMAND_TO_ID_ENGINE,
793 command_id.unwrap_or(-1),
794 CommandTopic::UnitSetOnOff.into(),
795 &mut command_data.c_data(),
796 )
797 }
798
799 pub fn set_repeat(
800 &self,
801 options: &[UnitCommandOptions],
802 command_id: Option<i32>,
803 timeout: Option<i32>,
804 repeat: bool,
805 ) -> Result<(), &'static str> {
806 let mut command_data = SetUnitRepeatCommandData {
807 unit_id: self.unit_id,
808 group_id: -1,
809 options: options.to_vec(),
810 timeout: timeout.unwrap_or(i32::MAX),
811 repeat,
812 };
813
814 handle_command(
815 self.ai_id,
816 COMMAND_TO_ID_ENGINE,
817 command_id.unwrap_or(-1),
818 CommandTopic::UnitSetRepeat.into(),
819 &mut command_data.c_data(),
820 )
821 }
822
823 pub fn set_trajectory(
824 &self,
825 options: &[UnitCommandOptions],
826 command_id: Option<i32>,
827 timeout: Option<i32>,
828 trajectory: Trajectory,
829 ) -> Result<(), &'static str> {
830 let mut command_data = SetUnitTrajectoryCommandData {
831 unit_id: self.unit_id,
832 group_id: -1,
833 options: options.to_vec(),
834 timeout: timeout.unwrap_or(i32::MAX),
835 trajectory,
836 };
837
838 handle_command(
839 self.ai_id,
840 COMMAND_TO_ID_ENGINE,
841 command_id.unwrap_or(-1),
842 CommandTopic::UnitSetTrajectory.into(),
843 &mut command_data.c_data(),
844 )
845 }
846
847 pub fn stockpile(
848 &self,
849 options: &[UnitCommandOptions],
850 command_id: Option<i32>,
851 timeout: Option<i32>,
852 ) -> Result<(), &'static str> {
853 let mut command_data = SetUnitStockpileCommandData {
854 unit_id: self.unit_id,
855 group_id: -1,
856 options: options.to_vec(),
857 timeout: timeout.unwrap_or(i32::MAX),
858 };
859
860 handle_command(
861 self.ai_id,
862 COMMAND_TO_ID_ENGINE,
863 command_id.unwrap_or(-1),
864 CommandTopic::UnitStockpile.into(),
865 &mut command_data.c_data(),
866 )
867 }
868
869 pub fn stop(
870 &self,
871 options: &[UnitCommandOptions],
872 command_id: Option<i32>,
873 timeout: Option<i32>,
874 ) -> Result<(), &'static str> {
875 let mut command_data = SetUnitStopCommandData {
876 unit_id: self.unit_id,
877 group_id: -1,
878 options: options.to_vec(),
879 timeout: timeout.unwrap_or(i32::MAX),
880 };
881
882 handle_command(
883 self.ai_id,
884 COMMAND_TO_ID_ENGINE,
885 command_id.unwrap_or(-1),
886 CommandTopic::UnitStop.into(),
887 &mut command_data.c_data(),
888 )
889 }
890
891 pub fn unload(
892 &self,
893 options: &[UnitCommandOptions],
894 command_id: Option<i32>,
895 timeout: Option<i32>,
896 position: [f32; 3],
897 to_unload_unit: Unit,
898 ) -> Result<(), &'static str> {
899 let mut command_data = SetUnitUnloadCommandData {
900 unit_id: self.unit_id,
901 group_id: -1,
902 options: options.to_vec(),
903 timeout: timeout.unwrap_or(i32::MAX),
904 position,
905 to_unload_unit_id: to_unload_unit.unit_id,
906 };
907
908 handle_command(
909 self.ai_id,
910 COMMAND_TO_ID_ENGINE,
911 command_id.unwrap_or(-1),
912 CommandTopic::UnitUnloadUnit.into(),
913 &mut command_data.c_data(),
914 )
915 }
916
917 pub fn unload_area(
918 &self,
919 options: &[UnitCommandOptions],
920 command_id: Option<i32>,
921 timeout: Option<i32>,
922 position: [f32; 3],
923 radius: f32,
924 ) -> Result<(), &'static str> {
925 let mut command_data = SetUnitUnloadAreaCommandData {
926 unit_id: self.unit_id,
927 group_id: -1,
928 options: options.to_vec(),
929 timeout: timeout.unwrap_or(i32::MAX),
930 position,
931 radius,
932 };
933
934 handle_command(
935 self.ai_id,
936 COMMAND_TO_ID_ENGINE,
937 command_id.unwrap_or(-1),
938 CommandTopic::UnitUnloadUnitsArea.into(),
939 &mut command_data.c_data(),
940 )
941 }
942
943 pub fn wait(
944 &self,
945 options: &[UnitCommandOptions],
946 command_id: Option<i32>,
947 timeout: Option<i32>,
948 ) -> Result<(), &'static str> {
949 let mut command_data = SetUnitWaitCommandData {
950 unit_id: self.unit_id,
951 group_id: -1,
952 options: options.to_vec(),
953 timeout: timeout.unwrap_or(i32::MAX),
954 };
955
956 handle_command(
957 self.ai_id,
958 COMMAND_TO_ID_ENGINE,
959 command_id.unwrap_or(-1),
960 CommandTopic::UnitWait.into(),
961 &mut command_data.c_data(),
962 )
963 }
964
965 pub fn wait_death(
966 &self,
967 options: &[UnitCommandOptions],
968 command_id: Option<i32>,
969 timeout: Option<i32>,
970 ) -> Result<(), &'static str> {
971 let mut command_data = SetUnitWaitCommandData {
972 unit_id: self.unit_id,
973 group_id: -1,
974 options: options.to_vec(),
975 timeout: timeout.unwrap_or(i32::MAX),
976 };
977
978 handle_command(
979 self.ai_id,
980 COMMAND_TO_ID_ENGINE,
981 command_id.unwrap_or(-1),
982 CommandTopic::UnitWaitDeath.into(),
983 &mut command_data.c_data(),
984 )
985 }
986
987 pub fn wait_gather(
988 &self,
989 options: &[UnitCommandOptions],
990 command_id: Option<i32>,
991 timeout: Option<i32>,
992 ) -> Result<(), &'static str> {
993 let mut command_data = SetUnitWaitGatherCommandData {
994 unit_id: self.unit_id,
995 group_id: -1,
996 options: options.to_vec(),
997 timeout: timeout.unwrap_or(i32::MAX),
998 };
999
1000 handle_command(
1001 self.ai_id,
1002 COMMAND_TO_ID_ENGINE,
1003 command_id.unwrap_or(-1),
1004 CommandTopic::UnitWaitGather.into(),
1005 &mut command_data.c_data(),
1006 )
1007 }
1008
1009 pub fn wait_squad(
1010 &self,
1011 options: &[UnitCommandOptions],
1012 command_id: Option<i32>,
1013 timeout: Option<i32>,
1014 num_units: i32,
1015 ) -> Result<(), &'static str> {
1016 let mut command_data = SetUnitWaitSquadCommandData {
1017 unit_id: self.unit_id,
1018 group_id: -1,
1019 options: options.to_vec(),
1020 timeout: timeout.unwrap_or(i32::MAX),
1021 num_units,
1022 };
1023
1024 handle_command(
1025 self.ai_id,
1026 COMMAND_TO_ID_ENGINE,
1027 command_id.unwrap_or(-1),
1028 CommandTopic::UnitWaitSquad.into(),
1029 &mut command_data.c_data(),
1030 )
1031 }
1032
1033 pub fn wait_time(
1034 &self,
1035 options: &[UnitCommandOptions],
1036 command_id: Option<i32>,
1037 timeout: Option<i32>,
1038 time: i32,
1039 ) -> Result<(), &'static str> {
1040 let mut command_data = SetUnitWaitTimeCommandData {
1041 unit_id: self.unit_id,
1042 group_id: -1,
1043 options: options.to_vec(),
1044 timeout: timeout.unwrap_or(i32::MAX),
1045 time,
1046 };
1047
1048 handle_command(
1049 self.ai_id,
1050 COMMAND_TO_ID_ENGINE,
1051 command_id.unwrap_or(-1),
1052 CommandTopic::UnitWaitTime.into(),
1053 &mut command_data.c_data(),
1054 )
1055 }
1056}