spring_ai_rs/ai_interface/callback/
teams.rs

1use 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}