spring_ai_rs/ai_interface/callback/unit_def/
mod.rs1use 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 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}