mod ability;
mod action;
mod buff;
mod game;
mod image;
mod player;
mod score;
mod unit;
mod upgrade;
use na;
use na::geometry;
use sc2_proto::common;
use sc2_proto::data;
use sc2_proto::raw;
use sc2_proto::sc2api;
use super::{ Result, FromProto, IntoSc2 };
pub use self::ability::*;
pub use self::action::*;
pub use self::buff::*;
pub use self::game::*;
pub use self::image::*;
pub use self::player::*;
pub use self::score::*;
pub use self::unit::*;
pub use self::upgrade::*;
pub type Color = (u8, u8, u8);
#[derive(Debug, Copy, Clone)]
pub struct Rect<T> {
pub x: T,
pub y: T,
pub w: T,
pub h: T
}
pub type Vector2 = na::Vector2<f32>;
pub type Vector3 = na::Vector3<f32>;
pub type Point2 = geometry::Point2<f32>;
pub type Point3 = geometry::Point3<f32>;
#[derive(Debug, Copy, Clone)]
pub struct Rect2 {
pub from: Point2,
pub to: Point2,
}
pub type Point2I = na::Vector2<i32>;
#[derive(Debug, Copy, Clone)]
pub struct Rect2I {
pub from: Point2I,
pub to: Point2I,
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Visibility {
Hidden,
Fogged,
Visible,
FullHidden
}
#[derive(Debug, Copy, Clone)]
pub struct AvailableAbility {
pub ability: Ability,
pub requires_point: bool,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum AbilityTarget {
Point,
Unit,
PointOrUnit,
PointOrNone,
}
#[derive(Debug, Clone)]
pub struct AbilityData {
pub available: bool,
pub ability: Ability,
pub link_name: String,
pub link_index: u32,
pub button_name: String,
pub friendly_name: String,
pub hotkey: String,
pub remaps_to_ability: Option<Ability>,
pub remaps_from_ability: Vec<Ability>,
pub target: Option<AbilityTarget>,
pub allow_minimap: bool,
pub allow_autocast: bool,
pub is_building: bool,
pub footprint_radius: f32,
pub is_instant_placement: bool,
pub cast_range: f32,
}
impl AbilityData {
pub fn get_generalized_ability(&self) -> Ability {
match self.remaps_to_ability {
Some(remap) => remap,
None => self.ability
}
}
}
impl FromProto<data::AbilityData> for AbilityData {
fn from_proto(mut data: data::AbilityData) -> Result<Self> {
Ok(
Self {
available: data.get_available(),
ability: Ability::from_proto(data.get_ability_id())?,
link_name: data.take_link_name(),
link_index: data.get_link_index(),
button_name: data.take_button_name(),
friendly_name: data.take_friendly_name(),
hotkey: data.take_hotkey(),
remaps_to_ability: {
if data.has_remaps_to_ability_id() {
Some(
Ability::from_proto(
data.get_remaps_to_ability_id()
)?
)
}
else {
None
}
},
remaps_from_ability: vec![ ],
target: match data.get_target() {
data::AbilityData_Target::None => {
None
},
data::AbilityData_Target::Point => {
Some(AbilityTarget::Point)
},
data::AbilityData_Target::Unit => {
Some(AbilityTarget::Unit)
},
data::AbilityData_Target::PointOrUnit => {
Some(AbilityTarget::PointOrUnit)
},
data::AbilityData_Target::PointOrNone => {
Some(AbilityTarget::PointOrNone)
},
},
allow_minimap: data.get_allow_minimap(),
allow_autocast: data.get_allow_autocast(),
is_building: data.get_is_building(),
footprint_radius: data.get_footprint_radius(),
is_instant_placement: data.get_is_instant_placement(),
cast_range: data.get_cast_range(),
}
)
}
}
#[derive(Debug, Clone)]
pub struct AvailableUnitAbilities {
pub abilities: Vec<AvailableAbility>,
pub unit_tag: Tag,
pub unit_type: UnitType,
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Attribute {
Light,
Armored,
Biological,
Mechanical,
Robotic,
Psionic,
Massive,
Structure,
Hover,
Heroic,
Summoned
}
impl FromProto<data::Attribute> for Attribute {
fn from_proto(a: data::Attribute) -> Result<Self> {
Ok(
match a {
data::Attribute::Light => Attribute::Light,
data::Attribute::Armored => Attribute::Armored,
data::Attribute::Biological => Attribute::Biological,
data::Attribute::Mechanical => Attribute::Mechanical,
data::Attribute::Robotic => Attribute::Robotic,
data::Attribute::Psionic => Attribute::Psionic,
data::Attribute::Massive => Attribute::Massive,
data::Attribute::Structure => Attribute::Structure,
data::Attribute::Hover => Attribute::Hover,
data::Attribute::Heroic => Attribute::Heroic,
data::Attribute::Summoned => Attribute::Summoned,
}
)
}
}
#[derive(Debug, Copy, Clone)]
pub struct DamageBonus {
pub attribute: Attribute,
pub bonus: f32,
}
impl FromProto<data::DamageBonus> for DamageBonus {
fn from_proto(b: data::DamageBonus) -> Result<Self> {
Ok(
Self {
attribute: b.get_attribute().into_sc2()?,
bonus: b.get_bonus()
}
)
}
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum WeaponTargetType {
Ground,
Air,
Any,
}
impl FromProto<data::Weapon_TargetType> for WeaponTargetType {
fn from_proto(target: data::Weapon_TargetType) -> Result<Self> {
Ok(
match target {
data::Weapon_TargetType::Ground => WeaponTargetType::Ground,
data::Weapon_TargetType::Air => WeaponTargetType::Air,
data::Weapon_TargetType::Any => WeaponTargetType::Any,
}
)
}
}
#[derive(Debug, Clone)]
pub struct Weapon {
pub target_type: WeaponTargetType,
pub damage: f32,
pub damage_bonus: Vec<DamageBonus>,
pub attacks: u32,
pub range: f32,
pub speed: f32,
}
impl FromProto<data::Weapon> for Weapon {
fn from_proto(mut w: data::Weapon) -> Result<Self> {
Ok(
Self {
target_type: w.get_field_type().into_sc2()?,
damage: w.get_damage(),
damage_bonus: {
let mut bonuses = vec![ ];
for b in w.take_damage_bonus().into_iter() {
bonuses.push(b.into_sc2()?);
}
bonuses
},
attacks: w.get_attacks(),
range: w.get_range(),
speed: w.get_speed(),
}
)
}
}
#[derive(Debug, Clone)]
pub struct UnitTypeData {
pub unit_type: UnitType,
pub name: String,
pub available: bool,
pub cargo_size: u32,
pub mineral_cost: u32,
pub vespene_cost: u32,
pub attributes: Vec<Attribute>,
pub movement_speed: f32,
pub armor: f32,
pub weapons: Vec<Weapon>,
pub food_required: f32,
pub food_provided: f32,
pub ability: Ability,
pub race: Option<Race>,
pub build_time: f32,
pub has_minerals: bool,
pub has_vespene: bool,
pub tech_alias: Vec<UnitType>,
pub unit_alias: UnitType,
pub tech_requirement: UnitType,
pub require_attached: bool,
}
impl FromProto<data::UnitTypeData> for UnitTypeData {
fn from_proto(mut data: data::UnitTypeData) -> Result<Self> {
Ok(
Self {
unit_type: data.get_unit_id().into_sc2()?,
name: data.get_name().to_string(),
available: data.get_available(),
cargo_size: data.get_cargo_size(),
mineral_cost: data.get_mineral_cost(),
vespene_cost: data.get_vespene_cost(),
attributes: {
let mut attributes = vec![ ];
for a in data.take_attributes().into_iter() {
attributes.push(a.into_sc2()?);
}
attributes
},
movement_speed: data.get_movement_speed(),
armor: data.get_armor(),
weapons: {
let mut weapons = vec![ ];
for w in data.take_weapons().into_iter() {
weapons.push(w.into_sc2()?);
}
weapons
},
food_required: data.get_food_required(),
food_provided: data.get_food_provided(),
ability: data.get_ability_id().into_sc2()?,
race: {
if data.has_race()
&& data.get_race() != common::Race::NoRace
{
Some(data.get_race().into_sc2()?)
}
else {
None
}
},
build_time: data.get_build_time(),
has_minerals: data.get_has_minerals(),
has_vespene: data.get_has_vespene(),
tech_alias: {
let mut aliases = vec![ ];
for a in data.get_tech_alias() {
aliases.push(UnitType::from_proto(*a)?);
}
aliases
},
unit_alias: UnitType::from_proto(data.get_unit_alias())?,
tech_requirement: UnitType::from_proto(
data.get_tech_requirement()
)?,
require_attached: data.get_require_attached()
}
)
}
}
#[derive(Debug, Clone)]
pub struct UpgradeData {
pub upgrade: Upgrade,
pub name: String,
pub mineral_cost: u32,
pub vespene_cost: u32,
pub ability: Ability,
pub research_time: f32,
}
impl FromProto<data::UpgradeData> for UpgradeData {
fn from_proto(mut data: data::UpgradeData) -> Result<Self> {
Ok(
Self {
upgrade: Upgrade::from_proto(data.get_upgrade_id())?,
name: data.take_name(),
mineral_cost: data.get_mineral_cost(),
vespene_cost: data.get_vespene_cost(),
ability: Ability::from_proto(data.get_ability_id())?,
research_time: data.get_research_time(),
}
)
}
}
#[derive(Debug, Clone)]
pub struct BuffData {
pub buff: Buff,
pub name: String,
}
impl FromProto<data::BuffData> for BuffData {
fn from_proto(mut data: data::BuffData) -> Result<Self> {
Ok(
BuffData {
buff: Buff::from_proto(data.get_buff_id())?,
name: data.take_name(),
}
)
}
}
#[derive(Debug, Clone)]
pub struct EffectData {
pub effect: Ability,
pub name: String,
pub friendly_name: String,
pub radius: f32,
}
#[derive(Debug, Clone)]
pub struct Effect {
pub effect: Ability,
pub positions: Vec<Point2>,
}
#[derive(Debug, Copy, Clone)]
pub struct PowerSource {
pub tag: Tag,
pub pos: Point2,
pub radius: f32,
}
impl From<raw::PowerSource> for PowerSource {
fn from(source: raw::PowerSource) -> Self {
Self {
tag: source.get_tag(),
pos: {
let pos = source.get_pos();
Point2::new(pos.get_x(), pos.get_y())
},
radius: source.get_radius(),
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct ReplayPlayerInfo {
pub player_id: u32,
pub mmr: i32,
pub apm: i32,
pub race: Race,
pub race_selected: Option<Race>,
pub game_result: Option<GameResult>,
}
impl FromProto<sc2api::PlayerInfoExtra> for ReplayPlayerInfo {
fn from_proto(info: sc2api::PlayerInfoExtra) -> Result<Self> {
Ok(
Self {
player_id: info.get_player_info().get_player_id(),
race: info.get_player_info().get_race_actual().into_sc2()?,
race_selected: {
if info.get_player_info().has_race_requested() {
let proto_race = info.get_player_info()
.get_race_requested()
;
if proto_race != common::Race::NoRace {
Some(proto_race.into_sc2()?)
}
else {
None
}
}
else {
None
}
},
mmr: info.get_player_mmr(),
apm: info.get_player_apm(),
game_result: {
if info.has_player_result() {
Some(info.get_player_result().get_result().into_sc2()?)
}
else {
None
}
}
}
)
}
}
#[derive(Debug, Clone)]
pub struct ReplayInfo {
pub map_name: String,
pub map_path: String,
pub game_version: String,
pub data_version: String,
pub duration: f32,
pub duration_steps: u32,
pub data_build: u32,
pub base_build: u32,
pub players: Vec<ReplayPlayerInfo>
}
impl FromProto<sc2api::ResponseReplayInfo> for ReplayInfo {
fn from_proto(mut info: sc2api::ResponseReplayInfo) -> Result<Self> {
Ok(
Self {
map_name: info.take_map_name(),
map_path: info.take_local_map_path(),
game_version: info.take_game_version(),
data_version: info.take_data_version(),
duration: info.get_game_duration_seconds(),
duration_steps: info.get_game_duration_loops(),
data_build: info.get_data_build(),
base_build: info.get_base_build(),
players: {
let mut player_info = vec![ ];
for p in info.take_player_info().into_iter() {
player_info.push(p.into_sc2()?);
}
player_info
}
}
)
}
}