bwapi_wrapper 0.2.2

Bindings to BWAPI
Documentation
use core::ops::{Add, Div, Mul, Sub};

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Position {
    pub x: i32,
    pub y: i32,
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct TilePosition {
    pub x: i32,
    pub y: i32,
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct WalkPosition {
    pub x: i32,
    pub y: i32,
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Vector2D {
    pub x: f64,
    pub y: f64,
}

pub type PositionTuple = (i32, i32);
pub const ORIGIN: Position = Position { x: 0, y: 0 };

impl Position {
    pub fn new(x: i32, y: i32) -> Option<Self> {
        Some(Self { x, y })
    }

    pub fn to_tile_position(&self) -> TilePosition {
        TilePosition {
            x: self.x / 32,
            y: self.y / 32,
        }
    }

    pub fn to_walk_position(&self) -> WalkPosition {
        WalkPosition {
            x: self.x / 8,
            y: self.y / 8,
        }
    }

    pub fn get_approx_distance<P: Into<Position>>(&self, other: P) -> i32 {
        let p = other.into();
        let mut max = (self.x - p.x).abs();
        let mut min = (self.y - p.y).abs();

        if max < min {
            core::mem::swap(&mut max, &mut min);
        }

        if min <= (max >> 2) {
            return max;
        }

        let min_calc = (3 * min) >> 3;
        (min_calc >> 5) + min_calc + max - (max >> 4) - (max >> 6)
    }
}

impl TilePosition {
    pub fn to_position(&self) -> Position {
        Position {
            x: self.x * 32,
            y: self.y * 32,
        }
    }

    pub fn to_walk_position(&self) -> WalkPosition {
        WalkPosition {
            x: self.x * 8,
            y: self.y * 8,
        }
    }
}

impl WalkPosition {
    pub fn to_tile_position(&self) -> TilePosition {
        TilePosition {
            x: self.x / 4,
            y: self.y / 4,
        }
    }

    pub fn to_position(&self) -> Position {
        Position {
            x: self.x * 8,
            y: self.y * 8,
        }
    }
}

impl Vector2D {
    pub fn new(x: f64, y: f64) -> Option<Self> {
        if x == 0.0 && y == 0.0 {
            None
        } else {
            Some(Self { x, y })
        }
    }
}

macro_rules! pos_math_ops {
    ($($t:ty)*) => ($(
        impl $t {
            pub fn is_valid(&self) -> bool {
                self.x >= 0 && self.y >= 0
            }
        }

        impl From<PositionTuple> for $t {
            fn from(pos: PositionTuple) -> Self {
                Self { x: pos.0, y: pos.1 }
            }
        }

        impl Mul<i32> for $t {
            type Output = $t;

            fn mul(self, other: i32) -> Self::Output {
                Self::Output {
                    x: self.x * other,
                    y: self.y * other
                }
            }
        }

        impl Mul<$t> for i32 {
            type Output = $t;

            fn mul(self, other: $t) -> Self::Output {
                Self::Output {
                     x: self * other.x,
                     y: self * other.y
                }
            }
        }

        impl Div<i32> for $t {
            type Output = Self;
            fn div(self, other: i32) -> Self::Output {
                Self::Output {
                    x: self.x / other,
                    y: self.y / other,
                }
            }
        }

        impl Sub<$t> for $t {
            type Output = Self;

            fn sub(self, other: $t) -> Self::Output {
                Self::Output {
                    x: self.x - other.x,
                    y: self.y - other.y,
                }
            }
        }

        impl Add<$t> for $t {
            type Output = Self;

            fn add(self, other: $t) -> Self::Output {
                Self::Output {
                    x: self.x + other.x,
                    y: self.y + other.y,
                }
            }
        }
    )*)
}

pos_math_ops!(Position WalkPosition TilePosition);