1 use crate::server::{ |
1 use crate::server::{ |
2 client::HWClient, |
2 client::HWClient, |
3 coretypes::{ClientId, GameCfg, GameCfg::*, RoomId, TeamInfo, Voting, MAX_HEDGEHOGS_PER_TEAM}, |
3 coretypes::{ |
|
4 ClientId, GameCfg, GameCfg::*, RoomConfig, RoomId, TeamInfo, Voting, MAX_HEDGEHOGS_PER_TEAM, |
|
5 }, |
4 }; |
6 }; |
5 use bitflags::*; |
7 use bitflags::*; |
6 use serde::{Deserialize, Serialize}; |
8 use serde::{Deserialize, Serialize}; |
7 use serde_derive::{Deserialize, Serialize}; |
9 use serde_derive::{Deserialize, Serialize}; |
8 use serde_yaml; |
10 use serde_yaml; |
9 use std::{collections::HashMap, iter}; |
11 use std::{collections::HashMap, iter}; |
10 |
12 |
11 const MAX_TEAMS_IN_ROOM: u8 = 8; |
13 const MAX_TEAMS_IN_ROOM: u8 = 8; |
12 const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM; |
14 const MAX_HEDGEHOGS_IN_ROOM: u8 = MAX_HEDGEHOGS_PER_TEAM * MAX_HEDGEHOGS_PER_TEAM; |
13 |
|
14 #[derive(Clone, Serialize, Deserialize)] |
|
15 struct Ammo { |
|
16 name: String, |
|
17 settings: Option<String>, |
|
18 } |
|
19 |
|
20 #[derive(Clone, Serialize, Deserialize)] |
|
21 struct Scheme { |
|
22 name: String, |
|
23 settings: Vec<String>, |
|
24 } |
|
25 |
|
26 #[derive(Clone, Serialize, Deserialize)] |
|
27 struct RoomConfig { |
|
28 feature_size: u32, |
|
29 map_type: String, |
|
30 map_generator: u32, |
|
31 maze_size: u32, |
|
32 seed: String, |
|
33 template: u32, |
|
34 |
|
35 ammo: Ammo, |
|
36 scheme: Scheme, |
|
37 script: String, |
|
38 theme: String, |
|
39 drawn_map: Option<String>, |
|
40 } |
|
41 |
|
42 impl RoomConfig { |
|
43 fn new() -> RoomConfig { |
|
44 RoomConfig { |
|
45 feature_size: 12, |
|
46 map_type: "+rnd+".to_string(), |
|
47 map_generator: 0, |
|
48 maze_size: 0, |
|
49 seed: "seed".to_string(), |
|
50 template: 0, |
|
51 |
|
52 ammo: Ammo { |
|
53 name: "Default".to_string(), |
|
54 settings: None, |
|
55 }, |
|
56 scheme: Scheme { |
|
57 name: "Default".to_string(), |
|
58 settings: Vec::new(), |
|
59 }, |
|
60 script: "Normal".to_string(), |
|
61 theme: "\u{1f994}".to_string(), |
|
62 drawn_map: None, |
|
63 } |
|
64 } |
|
65 } |
|
66 |
15 |
67 fn client_teams_impl( |
16 fn client_teams_impl( |
68 teams: &[(ClientId, TeamInfo)], |
17 teams: &[(ClientId, TeamInfo)], |
69 client_id: ClientId, |
18 client_id: ClientId, |
70 ) -> impl Iterator<Item = &TeamInfo> + Clone { |
19 ) -> impl Iterator<Item = &TeamInfo> + Clone { |
71 teams |
20 teams |
72 .iter() |
21 .iter() |
73 .filter(move |(id, _)| *id == client_id) |
22 .filter(move |(id, _)| *id == client_id) |
74 .map(|(_, t)| t) |
23 .map(|(_, t)| t) |
75 } |
|
76 |
|
77 fn map_config_from(c: &RoomConfig) -> Vec<String> { |
|
78 vec![ |
|
79 c.feature_size.to_string(), |
|
80 c.map_type.to_string(), |
|
81 c.map_generator.to_string(), |
|
82 c.maze_size.to_string(), |
|
83 c.seed.to_string(), |
|
84 c.template.to_string(), |
|
85 ] |
|
86 } |
|
87 |
|
88 fn game_config_from(c: &RoomConfig) -> Vec<GameCfg> { |
|
89 use crate::server::coretypes::GameCfg::*; |
|
90 let mut v = vec![ |
|
91 Ammo(c.ammo.name.to_string(), c.ammo.settings.clone()), |
|
92 Scheme(c.scheme.name.to_string(), c.scheme.settings.clone()), |
|
93 Script(c.script.to_string()), |
|
94 Theme(c.theme.to_string()), |
|
95 ]; |
|
96 if let Some(ref m) = c.drawn_map { |
|
97 v.push(DrawnMap(m.to_string())) |
|
98 } |
|
99 v |
|
100 } |
24 } |
101 |
25 |
102 pub struct GameInfo { |
26 pub struct GameInfo { |
103 pub teams_in_game: u8, |
27 pub teams_in_game: u8, |
104 pub teams_at_start: Vec<(ClientId, TeamInfo)>, |
28 pub teams_at_start: Vec<(ClientId, TeamInfo)>, |
288 self.teams.iter().min_by_key(|(_, t)| t.color) |
212 self.teams.iter().min_by_key(|(_, t)| t.color) |
289 != self.teams.iter().max_by_key(|(_, t)| t.color) |
213 != self.teams.iter().max_by_key(|(_, t)| t.color) |
290 } |
214 } |
291 |
215 |
292 pub fn set_config(&mut self, cfg: GameCfg) { |
216 pub fn set_config(&mut self, cfg: GameCfg) { |
293 let c = &mut self.config; |
217 self.config.set_config(cfg); |
294 match cfg { |
|
295 FeatureSize(s) => c.feature_size = s, |
|
296 MapType(t) => c.map_type = t, |
|
297 MapGenerator(g) => c.map_generator = g, |
|
298 MazeSize(s) => c.maze_size = s, |
|
299 Seed(s) => c.seed = s, |
|
300 Template(t) => c.template = t, |
|
301 |
|
302 Ammo(n, s) => { |
|
303 c.ammo = Ammo { |
|
304 name: n, |
|
305 settings: s, |
|
306 } |
|
307 } |
|
308 Scheme(n, s) => { |
|
309 c.scheme = Scheme { |
|
310 name: n, |
|
311 settings: s, |
|
312 } |
|
313 } |
|
314 Script(s) => c.script = s, |
|
315 Theme(t) => c.theme = t, |
|
316 DrawnMap(m) => c.drawn_map = Some(m), |
|
317 }; |
|
318 } |
218 } |
319 |
219 |
320 pub fn start_round(&mut self) { |
220 pub fn start_round(&mut self) { |
321 if self.game_info.is_none() { |
221 if self.game_info.is_none() { |
322 self.game_info = Some(GameInfo::new(self.teams.clone(), self.config.clone())); |
222 self.game_info = Some(GameInfo::new(self.teams.clone(), self.config.clone())); |
381 c.scheme.name.to_string(), |
281 c.scheme.name.to_string(), |
382 c.ammo.name.to_string(), |
282 c.ammo.name.to_string(), |
383 ] |
283 ] |
384 } |
284 } |
385 |
285 |
|
286 pub fn active_config(&self) -> &RoomConfig { |
|
287 match self.game_info { |
|
288 Some(ref info) => &info.config, |
|
289 None => &self.config, |
|
290 } |
|
291 } |
|
292 |
386 pub fn map_config(&self) -> Vec<String> { |
293 pub fn map_config(&self) -> Vec<String> { |
387 match self.game_info { |
294 match self.game_info { |
388 Some(ref info) => map_config_from(&info.config), |
295 Some(ref info) => info.config.to_map_config(), |
389 None => map_config_from(&self.config), |
296 None => self.config.to_map_config(), |
390 } |
297 } |
391 } |
298 } |
392 |
299 |
393 pub fn game_config(&self) -> Vec<GameCfg> { |
300 pub fn game_config(&self) -> Vec<GameCfg> { |
394 match self.game_info { |
301 match self.game_info { |
395 Some(ref info) => game_config_from(&info.config), |
302 Some(ref info) => info.config.to_game_config(), |
396 None => game_config_from(&self.config), |
303 None => self.config.to_game_config(), |
397 } |
304 } |
398 } |
305 } |
399 |
306 |
400 pub fn save_config(&mut self, name: String, location: String) { |
307 pub fn save_config(&mut self, name: String, location: String) { |
401 self.saves.insert( |
308 self.saves.insert( |