11 use std::{collections::HashMap, iter}; |
11 use std::{collections::HashMap, iter}; |
12 |
12 |
13 pub const MAX_TEAMS_IN_ROOM: u8 = 8; |
13 pub const MAX_TEAMS_IN_ROOM: u8 = 8; |
14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM; |
14 pub const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_TEAMS_IN_ROOM * MAX_HEDGEHOGS_PER_TEAM; |
15 |
15 |
|
16 fn client_teams_impl( |
|
17 teams: &[(ClientId, TeamInfo)], |
|
18 client_id: ClientId, |
|
19 ) -> impl Iterator<Item = &TeamInfo> + Clone { |
|
20 teams |
|
21 .iter() |
|
22 .filter(move |(id, _)| *id == client_id) |
|
23 .map(|(_, t)| t) |
|
24 } |
|
25 |
16 pub struct GameInfo { |
26 pub struct GameInfo { |
|
27 pub teams_in_game: u8, |
|
28 pub teams_at_start: Vec<(ClientId, TeamInfo)>, |
17 pub left_teams: Vec<String>, |
29 pub left_teams: Vec<String>, |
18 pub msg_log: Vec<String>, |
30 pub msg_log: Vec<String>, |
19 pub sync_msg: Option<String>, |
31 pub sync_msg: Option<String>, |
20 pub is_paused: bool, |
32 pub is_paused: bool, |
21 config: RoomConfig, |
33 config: RoomConfig, |
26 GameInfo { |
38 GameInfo { |
27 left_teams: Vec::new(), |
39 left_teams: Vec::new(), |
28 msg_log: Vec::new(), |
40 msg_log: Vec::new(), |
29 sync_msg: None, |
41 sync_msg: None, |
30 is_paused: false, |
42 is_paused: false, |
|
43 teams_in_game: teams.len() as u8, |
|
44 teams_at_start: teams, |
31 config, |
45 config, |
32 } |
46 } |
|
47 } |
|
48 |
|
49 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone { |
|
50 client_teams_impl(&self.teams_at_start, client_id) |
33 } |
51 } |
34 } |
52 } |
35 |
53 |
36 #[derive(Serialize, Deserialize)] |
54 #[derive(Serialize, Deserialize)] |
37 pub struct RoomSave { |
55 pub struct RoomSave { |
124 &self.teams.last().unwrap().1 |
142 &self.teams.last().unwrap().1 |
125 } |
143 } |
126 |
144 |
127 pub fn remove_team(&mut self, team_name: &str) { |
145 pub fn remove_team(&mut self, team_name: &str) { |
128 if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) { |
146 if let Some(index) = self.teams.iter().position(|(_, t)| t.name == team_name) { |
|
147 self.teams.remove(index); |
|
148 |
129 if let Some(info) = &mut self.game_info { |
149 if let Some(info) = &mut self.game_info { |
130 info.left_teams.push(team_name.to_string()); |
150 info.left_teams.push(team_name.to_string()); |
|
151 info.teams_in_game -= 1; |
131 |
152 |
132 if let Some(m) = &info.sync_msg { |
153 if let Some(m) = &info.sync_msg { |
133 info.msg_log.push(m.clone()); |
154 info.msg_log.push(m.clone()); |
134 info.sync_msg = None |
155 info.sync_msg = None |
135 } |
156 } |
136 let remove_msg = |
157 let remove_msg = |
137 crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes())); |
158 crate::utils::to_engine_msg(iter::once(b'F').chain(team_name.bytes())); |
138 info.msg_log.push(remove_msg.clone()); |
159 info.msg_log.push(remove_msg.clone()); |
139 } else { |
|
140 self.teams.remove(index); |
|
141 } |
160 } |
142 } |
161 } |
143 } |
162 } |
144 |
163 |
145 pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> { |
164 pub fn set_hedgehogs_number(&mut self, n: u8) -> Vec<String> { |
146 let mut names = Vec::new(); |
165 let mut names = Vec::new(); |
147 let teams = &mut self.teams; |
166 let teams = match self.game_info { |
|
167 Some(ref mut info) => &mut info.teams_at_start, |
|
168 None => &mut self.teams, |
|
169 }; |
|
170 |
148 if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM { |
171 if teams.len() as u8 * n <= MAX_HEDGEHOGS_IN_ROOM { |
149 for (_, team) in teams.iter_mut() { |
172 for (_, team) in teams.iter_mut() { |
150 team.hedgehogs_number = n; |
173 team.hedgehogs_number = n; |
151 names.push(team.name.clone()) |
174 names.push(team.name.clone()) |
152 } |
175 } |
153 self.default_hedgehog_number = n; |
176 self.default_hedgehog_number = n; |
154 } |
177 } |
155 names |
178 names |
156 } |
179 } |
157 |
180 |
158 pub fn teams_in_game(&self) -> Option<u8> { |
|
159 self.game_info |
|
160 .as_ref() |
|
161 .map(|info| (self.teams.len() - info.left_teams.len()) as u8) |
|
162 } |
|
163 |
|
164 pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)> |
181 pub fn find_team_and_owner_mut<F>(&mut self, f: F) -> Option<(ClientId, &mut TeamInfo)> |
165 where |
182 where |
166 F: Fn(&TeamInfo) -> bool, |
183 F: Fn(&TeamInfo) -> bool, |
167 { |
184 { |
168 self.teams |
185 self.teams |
178 self.teams |
195 self.teams |
179 .iter() |
196 .iter() |
180 .find_map(|(_, t)| Some(t).filter(|t| f(&t))) |
197 .find_map(|(_, t)| Some(t).filter(|t| f(&t))) |
181 } |
198 } |
182 |
199 |
183 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> + Clone { |
200 pub fn client_teams(&self, client_id: ClientId) -> impl Iterator<Item = &TeamInfo> { |
184 self.teams |
201 client_teams_impl(&self.teams, client_id) |
185 .iter() |
|
186 .filter(move |(id, _)| *id == client_id) |
|
187 .map(|(_, t)| t) |
|
188 } |
202 } |
189 |
203 |
190 pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> { |
204 pub fn client_team_indices(&self, client_id: ClientId) -> Vec<u8> { |
191 self.teams |
205 self.teams |
192 .iter() |
206 .iter() |