spring_ai_rs/ai_interface/callback/
teams.rs1use std::error::Error;
2
3use serde::{Deserialize, Serialize};
4use slog::Logger;
5
6use crate::{
7 ai_interface::{callback::resource::Resource, AIInterface},
8 get_callback,
9};
10
11#[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
12pub struct Team {
13 pub ai_id: i32,
14 pub team_id: i32,
15}
16
17#[derive(Debug, Copy, Clone)]
18pub struct TeamAll {
19 color: [i16; 3],
20 allied: bool,
21}
22
23#[derive(Debug, Copy, Clone)]
24pub struct TeamInterface {
25 pub ai_id: i32,
26}
27
28const MAX_TEAM: usize = 32;
29
30impl AIInterface {
31 pub fn team_interface(&self) -> TeamInterface {
32 TeamInterface { ai_id: self.ai_id }
33 }
34}
35
36impl TeamInterface {
37 pub fn get_teams(&self) -> Result<Vec<Team>, Box<dyn Error>> {
38 let get_teams = get_callback!(self.ai_id, Game_getTeams)?;
39
40 let mut ret = Vec::new();
41 for i in 0..unsafe { get_teams(self.ai_id) } {
42 ret.push(Team {
43 ai_id: self.ai_id,
44 team_id: i,
45 })
46 }
47
48 Ok(ret)
49 }
50
51 pub fn enemy_teams(&self) -> Result<Vec<Team>, Box<dyn Error>> {
52 let get_enemy_team_funcs = get_callback!(self.ai_id, getEnemyTeams)?;
53
54 let mut team_ids = [-1_i32; MAX_TEAM];
55 unsafe { get_enemy_team_funcs(self.ai_id, team_ids.as_mut_ptr(), MAX_TEAM as i32) };
56 Ok(team_ids
57 .iter()
58 .cloned()
59 .filter_map(|team_id| {
60 if team_id == -1 {
61 None
62 } else {
63 Some(Team {
64 ai_id: self.ai_id,
65 team_id,
66 })
67 }
68 })
69 .collect())
70 }
71
72 pub fn ally_teams(&self) -> Result<Vec<Team>, Box<dyn Error>> {
73 let get_ally_team_funcs = get_callback!(self.ai_id, getAlliedTeams)?;
74
75 let mut team_ids = [-1_i32; MAX_TEAM];
76 unsafe { get_ally_team_funcs(self.ai_id, team_ids.as_mut_ptr(), MAX_TEAM as i32) };
77 Ok(team_ids
78 .iter()
79 .cloned()
80 .filter_map(|team_id| {
81 if team_id == -1 {
82 None
83 } else {
84 Some(Team {
85 ai_id: self.ai_id,
86 team_id,
87 })
88 }
89 })
90 .collect())
91 }
92
93 pub fn current_team(&self) -> Result<Team, Box<dyn Error>> {
94 let current_team_func = get_callback!(self.ai_id, Game_getMyTeam)?;
95
96 Ok(Team {
97 ai_id: self.ai_id,
98 team_id: unsafe { current_team_func(self.ai_id) },
99 })
100 }
101}
102
103impl Team {
104 pub fn color(&self) -> Result<[i16; 3], Box<dyn Error>> {
105 let team_color_func = get_callback!(self.ai_id, Game_getTeamColor)?;
106
107 let mut color_ret = [0_i16; 3];
108 unsafe { team_color_func(self.ai_id, self.team_id, color_ret.as_mut_ptr()) };
109
110 Ok([color_ret[0], color_ret[1], color_ret[2]])
111 }
112
113 pub fn allied(&self, logger: &Logger) -> Result<bool, Box<dyn Error>> {
114 let is_allied = get_callback!(self.ai_id, Game_isAllied)?;
115 let current_team_id = AIInterface::new(self.ai_id)
116 .team_interface()
117 .current_team()?
118 .team_id;
119 let ret = Ok(unsafe { is_allied(self.ai_id, self.team_id, current_team_id) });
120 ret
121 }
122
123 pub fn all(&self, logger: &Logger) -> Result<TeamAll, Box<dyn Error>> {
124 Ok(TeamAll {
125 color: self.color()?,
126 allied: self.allied(logger)?,
127 })
128 }
129}
130
131#[derive(Debug, Copy, Clone)]
132pub struct TeamResource {
133 ai_id: i32,
134 other_team_id: i32,
135 resource_id: i32,
136}
137
138#[derive(Debug, Clone)]
139pub struct TeamResourceAll {
140 name: String,
141 income_multiplier: f32,
142 current: f32,
143 income: f32,
144 usage: f32,
145 storage: f32,
146 pull: f32,
147 share: f32,
148 sent: f32,
149 received: f32,
150 excess: f32,
151}
152
153impl TeamResource {
154 pub fn new(team: &Team, resource: &Resource) -> Self {
155 Self {
156 ai_id: team.ai_id,
157 other_team_id: team.team_id,
158 resource_id: resource.resource_id,
159 }
160 }
161
162 pub fn name(&self) -> Result<String, Box<dyn Error>> {
163 Resource {
164 ai_id: self.ai_id,
165 resource_id: self.resource_id,
166 }
167 .name()
168 }
169
170 pub fn income_multiplier(&self) -> Result<f32, Box<dyn Error>> {
171 let income_multiplier_func = get_callback!(self.ai_id, Game_getTeamIncomeMultiplier)?;
172 Ok(unsafe { income_multiplier_func(self.ai_id, self.other_team_id) })
173 }
174
175 pub fn current(&self) -> Result<f32, Box<dyn Error>> {
176 let team_resource_current = get_callback!(self.ai_id, Game_getTeamResourceCurrent)?;
177 Ok(unsafe { team_resource_current(self.ai_id, self.other_team_id, self.resource_id) })
178 }
179
180 pub fn income(&self) -> Result<f32, Box<dyn Error>> {
181 let team_resource_income = get_callback!(self.ai_id, Game_getTeamResourceIncome)?;
182 Ok(unsafe { team_resource_income(self.ai_id, self.other_team_id, self.resource_id) })
183 }
184
185 pub fn usage(&self) -> Result<f32, Box<dyn Error>> {
186 let team_resource_usage = get_callback!(self.ai_id, Game_getTeamResourceUsage)?;
187 Ok(unsafe { team_resource_usage(self.ai_id, self.other_team_id, self.resource_id) })
188 }
189
190 pub fn storage(&self) -> Result<f32, Box<dyn Error>> {
191 let team_resource_storage = get_callback!(self.ai_id, Game_getTeamResourceStorage)?;
192 Ok(unsafe { team_resource_storage(self.ai_id, self.other_team_id, self.resource_id) })
193 }
194
195 pub fn pull(&self) -> Result<f32, Box<dyn Error>> {
196 let team_resource_pull = get_callback!(self.ai_id, Game_getTeamResourcePull)?;
197 Ok(unsafe { team_resource_pull(self.ai_id, self.other_team_id, self.resource_id) })
198 }
199
200 pub fn share(&self) -> Result<f32, Box<dyn Error>> {
201 let team_resource_share = get_callback!(self.ai_id, Game_getTeamResourceShare)?;
202 Ok(unsafe { team_resource_share(self.ai_id, self.other_team_id, self.resource_id) })
203 }
204
205 pub fn sent(&self) -> Result<f32, Box<dyn Error>> {
206 let team_resource_sent = get_callback!(self.ai_id, Game_getTeamResourceSent)?;
207 Ok(unsafe { team_resource_sent(self.ai_id, self.other_team_id, self.resource_id) })
208 }
209
210 pub fn received(&self) -> Result<f32, Box<dyn Error>> {
211 let team_resource_received = get_callback!(self.ai_id, Game_getTeamResourceReceived)?;
212 Ok(unsafe { team_resource_received(self.ai_id, self.other_team_id, self.resource_id) })
213 }
214
215 pub fn excess(&self) -> Result<f32, Box<dyn Error>> {
216 let team_resource_excess = get_callback!(self.ai_id, Game_getTeamResourceExcess)?;
217 Ok(unsafe { team_resource_excess(self.ai_id, self.other_team_id, self.resource_id) })
218 }
219
220 pub fn all(&self) -> Result<TeamResourceAll, Box<dyn Error>> {
221 Ok(TeamResourceAll {
222 name: self.name()?,
223 income_multiplier: self.income_multiplier()?,
224 current: self.current()?,
225 income: self.income()?,
226 usage: self.usage()?,
227 storage: self.storage()?,
228 pull: self.pull()?,
229 share: self.share()?,
230 sent: self.sent()?,
231 received: self.received()?,
232 excess: self.excess()?,
233 })
234 }
235}