1use std::error::Error;
2
3use slog::{trace, Logger};
4use spring_ai_sys::{
5 SUnitCapturedEvent, SUnitCreatedEvent, SUnitDamagedEvent, SUnitDestroyedEvent,
6 SUnitFinishedEvent, SUnitGivenEvent, SUnitIdleEvent, SUnitMoveFailedEvent,
7};
8
9use crate::{
10 ai_interface::{
11 callback::{teams::Team, unit::Unit, weapon_def::WeaponDef},
12 AIInterface,
13 },
14 event::void_to_event,
15};
16
17pub struct UnitCapturedWrapper {
18 pub unit_captured_func: UnitCapturedFuncType,
19}
20
21impl UnitCapturedWrapper {
22 pub const fn new(unit_captured_func: UnitCapturedFuncType) -> Self {
23 Self { unit_captured_func }
24 }
25}
26
27inventory::collect!(UnitCapturedWrapper);
28
29pub type UnitCapturedFuncType =
30 fn(&Logger, AIInterface, Unit, Team, Team) -> Result<(), Box<dyn Error>>;
31
32pub fn unit_captured_wrapper(
33 logger: &Logger,
34 skirmish_ai_id: libc::c_int,
35 data: *const libc::c_void,
36 unit_captured_func: &UnitCapturedFuncType,
37) -> Result<(), Box<dyn Error>> {
38 let unit_captured_data = void_to_event::<SUnitCapturedEvent>(data as *mut libc::c_void)?;
39
40 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_captured_data,);
41
42 unit_captured_func(
43 logger,
44 AIInterface::new(skirmish_ai_id),
45 Unit {
46 unit_id: unit_captured_data.unitId,
47 ai_id: skirmish_ai_id,
48 },
49 Team {
50 ai_id: skirmish_ai_id,
51 team_id: unit_captured_data.oldTeamId,
52 },
53 Team {
54 ai_id: skirmish_ai_id,
55 team_id: unit_captured_data.newTeamId,
56 },
57 )
58}
59
60pub struct UnitCreatedWrapper {
61 pub unit_created_func: UnitCreatedFuncType,
62}
63
64impl UnitCreatedWrapper {
65 pub const fn new(unit_created_func: UnitCreatedFuncType) -> Self {
66 Self { unit_created_func }
67 }
68}
69
70inventory::collect!(UnitCreatedWrapper);
71
72pub type UnitCreatedFuncType = fn(&Logger, AIInterface, Unit, Unit) -> Result<(), Box<dyn Error>>;
73
74pub fn unit_created_wrapper(
75 logger: &Logger,
76 skirmish_ai_id: libc::c_int,
77 data: *const libc::c_void,
78 unit_created_func: &UnitCreatedFuncType,
79) -> Result<(), Box<dyn Error>> {
80 let unit_created_data = void_to_event::<SUnitCreatedEvent>(data as *mut libc::c_void)?;
81
82 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_created_data,);
83
84 unit_created_func(
85 logger,
86 AIInterface::new(skirmish_ai_id),
87 Unit {
88 unit_id: unit_created_data.unit,
89 ai_id: skirmish_ai_id,
90 },
91 Unit {
92 unit_id: unit_created_data.builder,
93 ai_id: skirmish_ai_id,
94 },
95 )
96}
97
98pub struct UnitDamagedWrapper {
99 pub unit_damaged_func: UnitDamagedFuncType,
100}
101
102impl UnitDamagedWrapper {
103 pub const fn new(unit_damaged_func: UnitDamagedFuncType) -> Self {
104 Self { unit_damaged_func }
105 }
106}
107
108inventory::collect!(UnitDamagedWrapper);
109
110pub type UnitDamagedFuncType = fn(
111 &Logger,
112 AIInterface,
113 Unit,
114 Unit,
115 f32,
116 [f32; 3],
117 WeaponDef,
118 bool,
119) -> Result<(), Box<dyn Error>>;
120
121pub fn unit_damaged_wrapper(
122 logger: &Logger,
123 skirmish_ai_id: libc::c_int,
124 data: *const libc::c_void,
125 unit_damaged_func: &UnitDamagedFuncType,
126) -> Result<(), Box<dyn Error>> {
127 let unit_damaged_data = void_to_event::<SUnitDamagedEvent>(data as *mut libc::c_void)?;
128
129 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_damaged_data,);
130 let direction = unsafe { Vec::from_raw_parts(unit_damaged_data.dir_posF3, 3, 3) };
131
132 unit_damaged_func(
133 logger,
134 AIInterface::new(skirmish_ai_id),
135 Unit {
136 unit_id: unit_damaged_data.unit,
137 ai_id: skirmish_ai_id,
138 },
139 Unit {
140 unit_id: unit_damaged_data.attacker,
141 ai_id: skirmish_ai_id,
142 },
143 unit_damaged_data.damage,
144 [direction[0], direction[1], direction[2]],
145 WeaponDef {
146 weapon_def_id: unit_damaged_data.weaponDefId,
147 ai_id: skirmish_ai_id,
148 },
149 unit_damaged_data.paralyzer,
150 )
151}
152
153pub struct UnitDestroyedWrapper {
154 pub unit_destroyed_func: UnitDestroyedFuncType,
155}
156
157impl UnitDestroyedWrapper {
158 pub const fn new(unit_destroyed_func: UnitDestroyedFuncType) -> Self {
159 Self {
160 unit_destroyed_func,
161 }
162 }
163}
164
165inventory::collect!(UnitDestroyedWrapper);
166
167pub type UnitDestroyedFuncType = fn(&Logger, AIInterface, Unit, Unit) -> Result<(), Box<dyn Error>>;
168
169pub fn unit_destroyed_wrapper(
170 logger: &Logger,
171 skirmish_ai_id: libc::c_int,
172 data: *const libc::c_void,
173 unit_destroyed_func: &UnitDestroyedFuncType,
174) -> Result<(), Box<dyn Error>> {
175 let unit_destroyed_data = void_to_event::<SUnitDestroyedEvent>(data as *mut libc::c_void)?;
176
177 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_destroyed_data,);
178
179 unit_destroyed_func(
180 logger,
181 AIInterface::new(skirmish_ai_id),
182 Unit {
183 unit_id: unit_destroyed_data.unit,
184 ai_id: skirmish_ai_id,
185 },
186 Unit {
187 unit_id: unit_destroyed_data.attacker,
188 ai_id: skirmish_ai_id,
189 },
190 )
191}
192
193pub struct UnitFinishedWrapper {
194 pub unit_finished_func: UnitFinishedFuncType,
195}
196
197impl UnitFinishedWrapper {
198 pub const fn new(unit_finished_func: UnitFinishedFuncType) -> Self {
199 Self { unit_finished_func }
200 }
201}
202
203inventory::collect!(UnitFinishedWrapper);
204
205pub type UnitFinishedFuncType = fn(&Logger, AIInterface, Unit) -> Result<(), Box<dyn Error>>;
206
207pub fn unit_finished_wrapper(
208 logger: &Logger,
209 skirmish_ai_id: libc::c_int,
210 data: *const libc::c_void,
211 unit_finished_func: &UnitFinishedFuncType,
212) -> Result<(), Box<dyn Error>> {
213 let unit_finished_data = void_to_event::<SUnitFinishedEvent>(data as *mut libc::c_void)?;
214
215 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_finished_data,);
216
217 unit_finished_func(
218 logger,
219 AIInterface::new(skirmish_ai_id),
220 Unit {
221 unit_id: unit_finished_data.unit,
222 ai_id: skirmish_ai_id,
223 },
224 )
225}
226
227pub struct UnitGivenWrapper {
228 pub unit_given_func: UnitGivenFuncType,
229}
230
231impl UnitGivenWrapper {
232 pub const fn new(unit_given_func: UnitGivenFuncType) -> Self {
233 Self { unit_given_func }
234 }
235}
236
237inventory::collect!(UnitGivenWrapper);
238
239pub type UnitGivenFuncType =
240 fn(&Logger, AIInterface, Unit, Team, Team) -> Result<(), Box<dyn Error>>;
241
242pub fn unit_given_wrapper(
243 logger: &Logger,
244 skirmish_ai_id: libc::c_int,
245 data: *const libc::c_void,
246 unit_given_func: &UnitGivenFuncType,
247) -> Result<(), Box<dyn Error>> {
248 let unit_given_data = void_to_event::<SUnitGivenEvent>(data as *mut libc::c_void)?;
249
250 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_given_data,);
251
252 unit_given_func(
253 logger,
254 AIInterface::new(skirmish_ai_id),
255 Unit {
256 unit_id: unit_given_data.unitId,
257 ai_id: skirmish_ai_id,
258 },
259 Team {
260 ai_id: skirmish_ai_id,
261 team_id: unit_given_data.oldTeamId,
262 },
263 Team {
264 ai_id: skirmish_ai_id,
265 team_id: unit_given_data.newTeamId,
266 },
267 )
268}
269
270pub struct UnitIdleWrapper {
271 pub unit_idle_func: UnitIdleFuncType,
272}
273
274impl UnitIdleWrapper {
275 pub const fn new(unit_idle_func: UnitIdleFuncType) -> Self {
276 Self { unit_idle_func }
277 }
278}
279
280inventory::collect!(UnitIdleWrapper);
281
282pub type UnitIdleFuncType = fn(&Logger, AIInterface, Unit) -> Result<(), Box<dyn Error>>;
283
284pub fn unit_idle_wrapper(
285 logger: &Logger,
286 skirmish_ai_id: libc::c_int,
287 data: *const libc::c_void,
288 unit_idle_func: &UnitIdleFuncType,
289) -> Result<(), Box<dyn Error>> {
290 let unit_idle_data = void_to_event::<SUnitIdleEvent>(data as *mut libc::c_void)?;
291
292 trace!(logger, "ID: {}; {:?}", skirmish_ai_id, unit_idle_data,);
293
294 unit_idle_func(
295 logger,
296 AIInterface::new(skirmish_ai_id),
297 Unit {
298 unit_id: unit_idle_data.unit,
299 ai_id: skirmish_ai_id,
300 },
301 )
302}
303
304pub struct UnitMoveFailedWrapper {
305 pub unit_move_failed_func: UnitMoveFailedFuncType,
306}
307
308impl UnitMoveFailedWrapper {
309 pub const fn new(unit_move_failed_func: UnitMoveFailedFuncType) -> Self {
310 Self {
311 unit_move_failed_func,
312 }
313 }
314}
315
316inventory::collect!(UnitMoveFailedWrapper);
317
318pub type UnitMoveFailedFuncType = fn(&Logger, AIInterface, Unit) -> Result<(), Box<dyn Error>>;
319
320pub fn unit_move_failed_wrapper(
321 logger: &Logger,
322 skirmish_ai_id: libc::c_int,
323 data: *const libc::c_void,
324 unit_move_failed_func: &UnitMoveFailedFuncType,
325) -> Result<(), Box<dyn Error>> {
326 let unit_move_failed_data = void_to_event::<SUnitMoveFailedEvent>(data as *mut libc::c_void)?;
327
328 trace!(
329 logger,
330 "ID: {}; {:?}",
331 skirmish_ai_id,
332 unit_move_failed_data,
333 );
334
335 unit_move_failed_func(
336 logger,
337 AIInterface::new(skirmish_ai_id),
338 Unit {
339 unit_id: unit_move_failed_data.unit,
340 ai_id: skirmish_ai_id,
341 },
342 )
343}