1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::{
bot::Rs,
geometry::{Point2, Rect, Size},
pixel_map::{ByteMap, PixelMap},
player::{AIBuild, Difficulty, PlayerType, Race},
FromProto,
};
use rustc_hash::FxHashMap;
use sc2_proto::sc2api::ResponseGameInfo;
use std::path::Path;
#[derive(Default, Clone)]
pub struct GameInfo {
pub map_name: String,
pub map_name_path: String,
pub mod_names: Vec<String>,
pub local_map_path: String,
pub players: FxHashMap<u32, PlayerInfo>,
pub map_size: Size,
pub pathing_grid: PixelMap,
pub terrain_height: Rs<ByteMap>,
pub placement_grid: PixelMap,
pub playable_area: Rect,
pub start_locations: Vec<Point2>,
pub map_center: Point2,
}
impl FromProto<ResponseGameInfo> for GameInfo {
fn from_proto(game_info: ResponseGameInfo) -> Self {
let start_raw = game_info.get_start_raw();
let map_size = start_raw.get_map_size();
let area = start_raw.get_playable_area();
let area_p0 = area.get_p0();
let area_p1 = area.get_p1();
let area_p0_x = area_p0.get_x();
let area_p0_y = area_p0.get_y();
let area_p1_x = area_p1.get_x();
let area_p1_y = area_p1.get_y();
let local_map_path = game_info.get_local_map_path().to_string();
Self {
map_name: game_info.get_map_name().to_string(),
mod_names: game_info.get_mod_names().to_vec(),
map_name_path: Path::new(&local_map_path)
.file_stem()
.unwrap()
.to_str()
.unwrap()
.to_string(),
local_map_path,
players: game_info
.get_player_info()
.iter()
.map(|i| {
let id = i.get_player_id();
(
id,
PlayerInfo {
id,
player_type: PlayerType::from_proto(i.get_field_type()),
race_requested: Race::from_proto(i.get_race_requested()),
race_actual: i.race_actual.map(Race::from_proto),
difficulty: i.difficulty.map(Difficulty::from_proto),
ai_build: i.ai_build.map(AIBuild::from_proto),
player_name: i.player_name.as_ref().cloned(),
},
)
})
.collect(),
map_size: Size::new(map_size.get_x() as usize, map_size.get_y() as usize),
pathing_grid: PixelMap::from_proto(start_raw.get_pathing_grid()),
terrain_height: Rs::new(ByteMap::from_proto(start_raw.get_terrain_height())),
placement_grid: PixelMap::from_proto(start_raw.get_placement_grid()),
playable_area: Rect::new(
area_p0_x as usize,
area_p0_y as usize,
area_p1_x as usize,
area_p1_y as usize,
),
start_locations: start_raw
.get_start_locations()
.iter()
.map(Point2::from_proto)
.collect(),
map_center: Point2::new(
(area_p0_x + (area_p1_x - area_p0_x) / 2) as f32,
(area_p0_y + (area_p1_y - area_p0_y) / 2) as f32,
),
}
}
}
#[derive(Clone)]
pub struct PlayerInfo {
pub id: u32,
pub player_type: PlayerType,
pub race_requested: Race,
pub race_actual: Option<Race>,
pub difficulty: Option<Difficulty>,
pub ai_build: Option<AIBuild>,
pub player_name: Option<String>,
}