spring_ai_rs/ai_interface/callback/unit_def/
mod.rs

1use std::{collections::HashMap, error::Error, ffi::CStr, hash::Hash, str::FromStr};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    ai_interface::{
7        callback::{
8            resource::Resource,
9            unit_def::{
10                aircraft::{UnitAircraft, UnitAircraftAll},
11                auto_heal::{UnitAutoHeal, UnitAutoHealAll},
12                building::{UnitBuilding, UnitBuildingAll},
13                cloak::{UnitCloak, UnitCloakAll},
14                combat::{UnitCombat, UnitCombatAll},
15                construction::{UnitConstruction, UnitConstructionAll},
16                death::{UnitDeath, UnitDeathAll},
17                detection::{UnitDetection, UnitDetectionAll},
18                flanking::{UnitFlanking, UnitFlankingAll},
19                flare::{UnitFlare, UnitFlareAll},
20                kind::base::UnitDefKind,
21                miscellaneous::{UnitMiscellaneous, UnitMiscellaneousAll},
22                model::{UnitModel, UnitModelAll},
23                movement::{UnitMovement, UnitMovementAll},
24                resource::{UnitResource, UnitResourceAll},
25                transport::{UnitTransport, UnitTransportAll},
26                vision::{UnitVision, UnitVisionAll},
27                weapon_mount::UnitWeaponMountAll,
28            },
29        },
30        AIInterface,
31    },
32    get_callback,
33};
34
35pub mod aircraft;
36pub mod auto_heal;
37pub mod building;
38pub mod cloak;
39pub mod combat;
40pub mod construction;
41pub mod death;
42pub mod detection;
43pub mod flanking;
44pub mod flare;
45pub mod kind;
46pub mod miscellaneous;
47pub mod model;
48pub mod movement;
49pub mod resource;
50pub mod transport;
51pub mod vision;
52pub mod weapon_mount;
53
54#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
55pub struct UnitDef {
56    pub ai_id: i32,
57    pub def_id: i32,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct UnitDefAll {
62    pub name: String,
63    pub display_name: String,
64    pub kind: UnitDefKind,
65    pub model: UnitModelAll,
66    pub resource: HashMap<Resource, UnitResourceAll>,
67    pub construction: UnitConstructionAll,
68    pub auto_heal: UnitAutoHealAll,
69    pub movement: UnitMovementAll,
70    pub vision: UnitVisionAll,
71    pub detection: UnitDetectionAll,
72    pub building: UnitBuildingAll,
73    pub flanking: UnitFlankingAll,
74    pub combat: UnitCombatAll,
75    pub death: UnitDeathAll,
76    pub aircraft: UnitAircraftAll,
77    pub transport: UnitTransportAll,
78    pub cloak: UnitCloakAll,
79    pub flare: UnitFlareAll,
80    pub weapon_mounts: Vec<UnitWeaponMountAll>,
81    pub miscellaneous: UnitMiscellaneousAll,
82}
83
84impl UnitDef {
85    pub fn name(&self) -> Result<String, Box<dyn Error>> {
86        let get_unit_def_name = get_callback!(self.ai_id, UnitDef_getName)?;
87        Ok(String::from(
88            unsafe { CStr::from_ptr(get_unit_def_name(self.ai_id, self.def_id)) }.to_str()?,
89        ))
90    }
91
92    pub fn display_name(&self) -> Result<String, Box<dyn Error>> {
93        let get_unit_def_display_name = get_callback!(self.ai_id, UnitDef_getHumanName)?;
94        Ok(String::from(
95            unsafe { CStr::from_ptr(get_unit_def_display_name(self.ai_id, self.def_id)) }
96                .to_str()?,
97        ))
98    }
99
100    pub fn kind(&self) -> Result<UnitDefKind, Box<dyn Error>> {
101        Ok(UnitDefKind::from_str(&self.name()?)?)
102    }
103
104    pub fn model(&self) -> UnitModel {
105        UnitModel {
106            ai_id: self.ai_id,
107            def_id: self.def_id,
108        }
109    }
110
111    pub fn resource(&self, resource: Resource) -> UnitResource {
112        UnitResource {
113            ai_id: self.ai_id,
114            def_id: self.def_id,
115            resource,
116        }
117    }
118
119    pub fn construction(&self) -> UnitConstruction {
120        UnitConstruction {
121            ai_id: self.ai_id,
122            def_id: self.def_id,
123        }
124    }
125
126    pub fn auto_heal(&self) -> UnitAutoHeal {
127        UnitAutoHeal {
128            ai_id: self.ai_id,
129            def_id: self.def_id,
130        }
131    }
132
133    pub fn movement(&self) -> UnitMovement {
134        UnitMovement {
135            ai_id: self.ai_id,
136            def_id: self.def_id,
137        }
138    }
139
140    pub fn vision(&self) -> UnitVision {
141        UnitVision {
142            ai_id: self.ai_id,
143            def_id: self.def_id,
144        }
145    }
146
147    pub fn detection(&self) -> UnitDetection {
148        UnitDetection {
149            ai_id: self.ai_id,
150            def_id: self.def_id,
151        }
152    }
153
154    pub fn building(&self) -> UnitBuilding {
155        UnitBuilding {
156            ai_id: self.ai_id,
157            def_id: self.def_id,
158        }
159    }
160
161    pub fn flanking(&self) -> UnitFlanking {
162        UnitFlanking {
163            ai_id: self.ai_id,
164            def_id: self.def_id,
165        }
166    }
167
168    pub fn combat(&self) -> UnitCombat {
169        UnitCombat {
170            ai_id: self.ai_id,
171            def_id: self.def_id,
172        }
173    }
174
175    pub fn death(&self) -> UnitDeath {
176        UnitDeath {
177            ai_id: self.ai_id,
178            def_id: self.def_id,
179        }
180    }
181
182    pub fn aircraft(&self) -> UnitAircraft {
183        UnitAircraft {
184            ai_id: self.ai_id,
185            def_id: self.def_id,
186        }
187    }
188
189    pub fn transport(&self) -> UnitTransport {
190        UnitTransport {
191            ai_id: self.ai_id,
192            def_id: self.def_id,
193        }
194    }
195
196    pub fn cloak(&self) -> UnitCloak {
197        UnitCloak {
198            ai_id: self.ai_id,
199            def_id: self.def_id,
200        }
201    }
202
203    pub fn flare(&self) -> UnitFlare {
204        UnitFlare {
205            ai_id: self.ai_id,
206            def_id: self.def_id,
207        }
208    }
209
210    pub fn miscellaneous(&self) -> UnitMiscellaneous {
211        UnitMiscellaneous {
212            ai_id: self.ai_id,
213            def_id: self.def_id,
214        }
215    }
216
217    // TODO:
218    //    pub fn UnitDef_getYardMap(&self) -> Result<(), Box<dyn Error>> {
219    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_getYardMap)?;
220    //        Ok(())
221    //    }
222
223    //    pub fn UnitDef_isNeedGeo(&self) -> Result<(), Box<dyn Error>> {
224    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isNeedGeo)?;
225    //        Ok(())
226    //    }
227    //    pub fn UnitDef_isFeature(&self) -> Result<(), Box<dyn Error>> {
228    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isFeature)?;
229    //        Ok(())
230    //    }
231    //    pub fn UnitDef_isHideDamage(&self) -> Result<(), Box<dyn Error>> {
232    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isHideDamage)?;
233    //        Ok(())
234    //    }
235    //    pub fn UnitDef_isShowPlayerName(&self) -> Result<(), Box<dyn Error>> {
236    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isShowPlayerName)?;
237    //        Ok(())
238    //    }
239
240    //    pub fn UnitDef_getHighTrajectoryType(&self) -> Result<(), Box<dyn Error>> {
241    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_getHighTrajectoryType)?;
242    //        Ok(())
243    //    }
244    //    pub fn UnitDef_getNoChaseCategory(&self) -> Result<(), Box<dyn Error>> {
245    //        let get_no_chase_category_func = get_callback!(self.ai_id, UnitDef_getNoChaseCategory)?;
246    //        Ok(())
247    //    }
248    //
249    //
250    //    pub fn UnitDef_isAbleToLoopbackAttack(&self) -> Result<(), Box<dyn Error>> {
251    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isAbleToLoopbackAttack)?;
252    //        Ok(())
253    //    }
254    //    pub fn UnitDef_isLevelGround(&self) -> Result<(), Box<dyn Error>> {
255    //        let get_is_level_ground_func = get_callback!(self.ai_id, UnitDef_isLevelGround)?;
256    //        Ok(())
257    //    }
258    //
259    //    pub fn UnitDef_getDecoyDef(&self) -> Result<(), Box<dyn Error>> {
260    //        let get_decoy_def_func = get_callback!(self.ai_id, UnitDef_getDecoyDef)?;
261    //        Ok(())
262    //    }
263    //    pub fn UnitDef_isDontLand(&self) -> Result<(), Box<dyn Error>> {
264    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isDontLand)?;
265    //        Ok(())
266    //    }
267    //    pub fn UnitDef_getShieldDef(&self) -> Result<(), Box<dyn Error>> {
268    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_getShieldDef)?;
269    //        Ok(())
270    //    }
271    //    pub fn UnitDef_getStockpileDef(&self) -> Result<(), Box<dyn Error>> {
272    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_getStockpileDef)?;
273    //        Ok(())
274    //    }
275    //
276    //    pub fn UnitDef_getCustomParams(&self) -> Result<(), Box<dyn Error>> {
277    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_getCustomParams)?;
278    //        Ok(())
279    //    }
280    //    pub fn UnitDef_isMoveDataAvailable(&self) -> Result<(), Box<dyn Error>> {
281    //        let get_is_able_to_self_d_func = get_callback!(self.ai_id, UnitDef_isMoveDataAvailable)?;
282    //        Ok(())
283    //    }
284
285    pub fn all(&self) -> Result<UnitDefAll, Box<dyn Error>> {
286        Ok(UnitDefAll {
287            name: self.name()?,
288            display_name: self.display_name()?,
289            kind: self.kind()?,
290            model: self.model().all()?,
291            resource: AIInterface::new(self.ai_id)
292                .resource_interface()
293                .get_resources()?
294                .into_iter()
295                .filter_map(|resource| {
296                    if let Ok(res) = self.resource(resource).all() {
297                        Some((resource, res))
298                    } else {
299                        None
300                    }
301                })
302                .collect(),
303            construction: self.construction().all()?,
304            auto_heal: self.auto_heal().all()?,
305            movement: self.movement().all()?,
306            vision: self.vision().all()?,
307            detection: self.detection().all()?,
308            building: self.building().all()?,
309            flanking: self.flanking().all()?,
310            combat: self.combat().all()?,
311            death: self.death().all()?,
312            aircraft: self.aircraft().all()?,
313            transport: self.transport().all()?,
314            cloak: self.cloak().all()?,
315            flare: self.flare().all()?,
316            weapon_mounts: self
317                .weapon_mounts()?
318                .into_iter()
319                .filter_map(|weapon| weapon.all().ok())
320                .collect(),
321            miscellaneous: self.miscellaneous().all()?,
322        })
323    }
324}