bwapi 0.2.0

Rust bindings to the Starcraft Broodwar game API
Documentation

use bwapi_sys as sys;
use iterator::BwIterator;
use from_raw::FromRaw;

use std::os::raw::c_void as void;

pub struct Unit(*mut sys::Unit);

#[repr(i32)]
#[allow(non_camel_case_types)]
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub enum UnitType {
    Terran_Marine = 0,
    Terran_Ghost,
    Terran_Vulture,
    Terran_Goliath,
    Terran_Goliath_Turret,
    Terran_Siege_Tank_Tank_Mode,
    Terran_Siege_Tank_Tank_Mode_Turret,
    Terran_SCV,
    Terran_Wraith,
    Terran_Science_Vessel,
    Hero_Gui_Montag,
    Terran_Dropship,
    Terran_Battlecruiser,
    Terran_Vulture_Spider_Mine,
    Terran_Nuclear_Missile,
    Terran_Civilian,
    Hero_Sarah_Kerrigan,
    Hero_Alan_Schezar,
    Hero_Alan_Schezar_Turret,
    Hero_Jim_Raynor_Vulture,
    Hero_Jim_Raynor_Marine,
    Hero_Tom_Kazansky,
    Hero_Magellan,
    Hero_Edmund_Duke_Tank_Mode,
    Hero_Edmund_Duke_Tank_Mode_Turret,
    Hero_Edmund_Duke_Siege_Mode,
    Hero_Edmund_Duke_Siege_Mode_Turret,
    Hero_Arcturus_Mengsk,
    Hero_Hyperion,
    Hero_Norad_II,
    Terran_Siege_Tank_Siege_Mode,
    Terran_Siege_Tank_Siege_Mode_Turret,
    Terran_Firebat,
    Spell_Scanner_Sweep,
    Terran_Medic,
    Zerg_Larva,
    Zerg_Egg,
    Zerg_Zergling,
    Zerg_Hydralisk,
    Zerg_Ultralisk,
    Zerg_Broodling,
    Zerg_Drone,
    Zerg_Overlord,
    Zerg_Mutalisk,
    Zerg_Guardian,
    Zerg_Queen,
    Zerg_Defiler,
    Zerg_Scourge,
    Hero_Torrasque,
    Hero_Matriarch,
    Zerg_Infested_Terran,
    Hero_Infested_Kerrigan,
    Hero_Unclean_One,
    Hero_Hunter_Killer,
    Hero_Devouring_One,
    Hero_Kukulza_Mutalisk,
    Hero_Kukulza_Guardian,
    Hero_Yggdrasill,
    Terran_Valkyrie,
    Zerg_Cocoon,
    Protoss_Corsair,
    Protoss_Dark_Templar,
    Zerg_Devourer,
    Protoss_Dark_Archon,
    Protoss_Probe,
    Protoss_Zealot,
    Protoss_Dragoon,
    Protoss_High_Templar,
    Protoss_Archon,
    Protoss_Shuttle,
    Protoss_Scout,
    Protoss_Arbiter,
    Protoss_Carrier,
    Protoss_Interceptor,
    Hero_Dark_Templar,
    Hero_Zeratul,
    Hero_Tassadar_Zeratul_Archon,
    Hero_Fenix_Zealot,
    Hero_Fenix_Dragoon,
    Hero_Tassadar,
    Hero_Mojo,
    Hero_Warbringer,
    Hero_Gantrithor,
    Protoss_Reaver,
    Protoss_Observer,
    Protoss_Scarab,
    Hero_Danimoth,
    Hero_Aldaris,
    Hero_Artanis,
    Critter_Rhynadon,
    Critter_Bengalaas,
    Special_Cargo_Ship,
    Special_Mercenary_Gunship,
    Critter_Scantid,
    Critter_Kakaru,
    Critter_Ragnasaur,
    Critter_Ursadon,
    Zerg_Lurker_Egg,
    Hero_Raszagal,
    Hero_Samir_Duran,
    Hero_Alexei_Stukov,
    Special_Map_Revealer,
    Hero_Gerard_DuGalle,
    Zerg_Lurker,
    Hero_Infested_Duran,
    Spell_Disruption_Web,
    Terran_Command_Center,
    Terran_Comsat_Station,
    Terran_Nuclear_Silo,
    Terran_Supply_Depot,
    Terran_Refinery,
    Terran_Barracks,
    Terran_Academy,
    Terran_Factory,
    Terran_Starport,
    Terran_Control_Tower,
    Terran_Science_Facility,
    Terran_Covert_Ops,
    Terran_Physics_Lab,
    Unused_Terran1,
    Terran_Machine_Shop,
    Unused_Terran2,
    Terran_Engineering_Bay,
    Terran_Armory,
    Terran_Missile_Turret,
    Terran_Bunker,
    Special_Crashed_Norad_II,
    Special_Ion_Cannon,
    Powerup_Uraj_Crystal,
    Powerup_Khalis_Crystal,
    Zerg_Infested_Command_Center,
    Zerg_Hatchery,
    Zerg_Lair,
    Zerg_Hive,
    Zerg_Nydus_Canal,
    Zerg_Hydralisk_Den,
    Zerg_Defiler_Mound,
    Zerg_Greater_Spire,
    Zerg_Queens_Nest,
    Zerg_Evolution_Chamber,
    Zerg_Ultralisk_Cavern,
    Zerg_Spire,
    Zerg_Spawning_Pool,
    Zerg_Creep_Colony,
    Zerg_Spore_Colony,
    Unused_Zerg1,
    Zerg_Sunken_Colony,
    Special_Overmind_With_Shell,
    Special_Overmind,
    Zerg_Extractor,
    Special_Mature_Chrysalis,
    Special_Cerebrate,
    Special_Cerebrate_Daggoth,
    Unused_Zerg2,
    Protoss_Nexus,
    Protoss_Robotics_Facility,
    Protoss_Pylon,
    Protoss_Assimilator,
    Unused_Protoss1,
    Protoss_Observatory,
    Protoss_Gateway,
    Unused_Protoss2,
    Protoss_Photon_Cannon,
    Protoss_Citadel_of_Adun,
    Protoss_Cybernetics_Core,
    Protoss_Templar_Archives,
    Protoss_Forge,
    Protoss_Stargate,
    Special_Stasis_Cell_Prison,
    Protoss_Fleet_Beacon,
    Protoss_Arbiter_Tribunal,
    Protoss_Robotics_Support_Bay,
    Protoss_Shield_Battery,
    Special_Khaydarin_Crystal_Form,
    Special_Protoss_Temple,
    Special_XelNaga_Temple,
    Resource_Mineral_Field,
    Resource_Mineral_Field_Type_2,
    Resource_Mineral_Field_Type_3,
    Unused_Cave,
    Unused_Cave_In,
    Unused_Cantina,
    Unused_Mining_Platform,
    Unused_Independant_Command_Center,
    Special_Independant_Starport,
    Unused_Independant_Jump_Gate,
    Unused_Ruins,
    Unused_Khaydarin_Crystal_Formation,
    Resource_Vespene_Geyser,
    Special_Warp_Gate,
    Special_Psi_Disrupter,
    Unused_Zerg_Marker,
    Unused_Terran_Marker,
    Unused_Protoss_Marker,
    Special_Zerg_Beacon,
    Special_Terran_Beacon,
    Special_Protoss_Beacon,
    Special_Zerg_Flag_Beacon,
    Special_Terran_Flag_Beacon,
    Special_Protoss_Flag_Beacon,
    Special_Power_Generator,
    Special_Overmind_Cocoon,
    Spell_Dark_Swarm,
    Special_Floor_Missile_Trap,
    Special_Floor_Hatch,
    Special_Upper_Level_Door,
    Special_Right_Upper_Level_Door,
    Special_Pit_Door,
    Special_Right_Pit_Door,
    Special_Floor_Gun_Trap,
    Special_Wall_Missile_Trap,
    Special_Wall_Flame_Trap,
    Special_Right_Wall_Missile_Trap,
    Special_Right_Wall_Flame_Trap,
    Special_Start_Location,
    Powerup_Flag,
    Powerup_Young_Chrysalis,
    Powerup_Psi_Emitter,
    Powerup_Data_Disk,
    Powerup_Khaydarin_Crystal,
    Powerup_Mineral_Cluster_Type_1,
    Powerup_Mineral_Cluster_Type_2,
    Powerup_Protoss_Gas_Orb_Type_1,
    Powerup_Protoss_Gas_Orb_Type_2,
    Powerup_Zerg_Gas_Sac_Type_1,
    Powerup_Zerg_Gas_Sac_Type_2,
    Powerup_Terran_Gas_Tank_Type_1,
    Powerup_Terran_Gas_Tank_Type_2,

    None,
    AllUnits,
    Men,
    Buildings,
    Factories,
    Unknown,
    MAX
}

impl UnitType {
    fn as_sys(self) -> sys::UnitType {
        sys::UnitType { id: self as i32 }
    }
}

impl Unit {
    pub fn id(&self) -> i32 {
        unsafe {
            sys::Unit_getID(self.0)
        }
    }

    pub fn get_type(&self) -> UnitType {
        unsafe {
            let raw_type = sys::Unit_getType(self.0).id;
            assert!(raw_type >= 0);
            assert!(raw_type < UnitType::MAX as i32);

            ::std::mem::transmute(raw_type)
        }
    }

    pub fn exists(&self) -> bool {
        unsafe {
            sys::Unit_exists(self.0)
        }
    }

    pub fn is_idle(&self) -> bool {
        unsafe {
            sys::Unit_isIdle(self.0)
        }
    }

    pub fn is_moving(&self) -> bool {
        unsafe {
            sys::Unit_isMoving(self.0)
        }
    }

    pub fn is_carrying_minerals(&self) -> bool {
        unsafe {
            sys::Unit_isCarryingMinerals(self.0)
        }
    }

    pub fn is_carrying_gas(&self) -> bool {
        unsafe {
            sys::Unit_isCarryingGas(self.0)
        }
    }

    pub fn return_cargo(&self, shift_queue_command: bool) -> bool {
        unsafe {
            sys::Unit_returnCargo(self.0, shift_queue_command)
        }
    }

    pub fn loaded_units(&self) -> Box<Iterator<Item=Unit>> {
        unsafe {
            let iter = sys::Unit_getLoadedUnits(self.0) as *mut sys::Iterator;
            Box::new(BwIterator::from(iter))
        }
    }

    pub fn distance_to<T>(&self, t: &T) -> i32
        where T: HasPosition
    {
        unsafe {
            sys::Unit_getDistance_Position(self.0, t.position())
        }
    }

    pub fn right_click<T>(&self, target: &T, shift_queue_command: bool) -> bool
        where T: RightClickable
    {
        target.dispatch_right_click(self, shift_queue_command)
    }

    pub fn train(&self, unit_type: UnitType) -> bool {
        unsafe {
            sys::Unit_train(self.0, unit_type.as_sys())
        }
    }
}

pub trait HasPosition {
    fn position(&self) -> sys::Position;
}

impl HasPosition for sys::Position {
    fn position(&self) -> sys::Position {
        self.clone()
    }
}

impl HasPosition for Unit {
    fn position(&self) -> sys::Position {
        unsafe {
            sys::Unit_getPosition(self.0)
        }
    }
}

pub trait RightClickable {
    fn dispatch_right_click(&self, source: &Unit, shift_queue_command: bool) -> bool;
}

impl RightClickable for Unit {
    fn dispatch_right_click(&self, source: &Unit, shift_queue_command: bool) -> bool {
        unsafe {
            sys::Unit_rightClick_Unit(source.0, self.0, shift_queue_command)
        }
    }
}

impl RightClickable for sys::Position {
    fn dispatch_right_click(&self, source: &Unit, shift_queue_command: bool) -> bool {
        unsafe {
            sys::Unit_rightClick_Position(source.0, *self, shift_queue_command)
        }
    }
}

impl FromRaw for Unit {
    unsafe fn from_raw(raw: *mut void) -> Unit {
        assert!(!raw.is_null());
        Unit(raw as *mut sys::Unit)
    }
}