Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • stebr364/pycommandcenter
  • starcraft-ai-course/pycommandcenter
  • eriah592/pycommandcenter
  • edvbe696/pycommandcenter
  • dawab699/pycommandcenter
  • hanja189/pycommandcenter
  • teoga849/pycommandcenter
  • musab250/pycommandcenter
  • emibr898/pycommandcenter
  • chrgu102/pycommandcenter
  • axega544/pycommandcenter
  • edvth289/pycommandcenter
  • jonbo278/py-command-center-v-2
13 results
Show changes
#include "ReplayUnit.h"
ReplayUnit::ReplayUnit(const sc2::Unit * unit, IDAReplayObserver & replayObserver)
: m_replayObserver(&replayObserver), Unit(unit), m_type(unit->unit_type, replayObserver, replayObserver)
{
}
const UnitType & ReplayUnit::getType() const
{
return m_type;
}
bool ReplayUnit::hasTarget() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
if (getUnitPtr()->orders.size() > 0) {
if (getUnitPtr()->orders[0].target_unit_tag != NULL) {
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
// IDAReplayObserver checks if the unit with this tag still exists
if (m_replayObserver->UnitExists(t_id)){
// IDAReplayObserver finds the unit with this tag, and returns true if valid
return m_replayObserver->GetUnit(t_id).isValid();
}
}
}
return false;
}
ReplayUnit ReplayUnit::getTarget() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
// if unit has order, check tag of target of first order
if (getUnitPtr()->orders.size() > 0) {
// t_id is set to the unit tag of the target
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
// Checks if the tag is a null tag or the unit have been removed
if (t_id != sc2::NullTag && m_replayObserver->UnitExists(t_id)){
// IDAReplayObserver finds the unit with this tag
return m_replayObserver->GetUnit(t_id);
}
}
return *this;
}
int ReplayUnit::getPlayer() const
{
return m_unit->owner;
}
#pragma once
#include "Unit.h"
#include "IDAReplayObserver.h"
class IDAReplayObserver;
//! A Unit that have a replayobserver insted of an Agent,
class ReplayUnit: public Unit
{
mutable IDAReplayObserver * m_replayObserver;
UnitType m_type;
public:
ReplayUnit(const sc2::Unit * unit, IDAReplayObserver & replayObserver);
const UnitType & getType() const;
bool hasTarget() const;
ReplayUnit getTarget() const;
int getPlayer() const;
};
\ No newline at end of file
This diff is collapsed.
......@@ -31,18 +31,22 @@ struct TypeData
class TechTree
{
IDABot & m_bot;
sc2::Client & m_client;
std::map<UnitType, TypeData> m_unitTypeData;
std::map<CCUpgrade, TypeData> m_upgradeData;
void initUnitTypeData();
void initUpgradeData();
bool suppressWarnings;
public:
TechTree(IDABot & bot);
TechTree(sc2::Client & client);
void onStart();
void setSuppressWarnings(bool b);
bool getSuppressWarnings() const;
const TypeData & getData(const UnitType & type) const;
const TypeData & getData(const CCUpgrade & type) const;
const TypeData & getData(const MetaType & type) const;
......
#include "Unit.h"
#include "IDABot.h"
#include "sc2api/sc2_gametypes.h"
Unit::Unit()
: m_bot(nullptr)
......@@ -13,7 +14,14 @@ Unit::Unit(const sc2::Unit * unit, IDABot & bot)
: m_bot(&bot)
, m_unit(unit)
, m_unitID(unit->tag)
, m_unitType(unit->unit_type, bot)
, m_unitType(unit->unit_type, bot, bot)
{
}
Unit::Unit(const sc2::Unit * unit)
: m_unit(unit)
, m_unitID(unit->tag)
{
}
......@@ -111,7 +119,7 @@ bool Unit::isCompleted() const
bool Unit::isTraining() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->orders.size() > 0;
return m_unit->orders.size() > 0 && m_unitType.isBuilding();
}
bool Unit::isBeingConstructed() const
......@@ -328,17 +336,31 @@ void Unit::ability(sc2::AbilityID ability, const Unit& target) const
Unit Unit::getTarget() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
// if unit has order, check tag of target of first order
if(getUnitPtr()->orders.size() > 0){
// t_id is set to the unit tag of the target
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
// IDABot finds the unit with this tag
return m_bot->GetUnit(t_id);
}
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
// Make sure the returned tag is not the NullTag
if (t_id == sc2::NullTag) {
return *this;
}
// Make sure the Tag references a valid unit
if (m_bot->Observation()->GetUnit(t_id) == nullptr) {
return *this;
}
Unit this_unit = Unit(m_unit, *m_bot);
return this_unit;
// Convert the tag to a Unit object
Unit unit = m_bot->GetUnit(t_id);
if (unit.isValid()) {
return unit;
} else {
return *this;
}
}
return *this;
}
bool Unit::hasTarget() const
......@@ -346,10 +368,16 @@ bool Unit::hasTarget() const
BOT_ASSERT(isValid(), "Unit is not valid");
if (getUnitPtr()->orders.size() > 0) {
if (getUnitPtr()->orders[0].target_unit_tag != NULL) {
if (getUnitPtr()->orders[0].target_unit_tag != sc2::NullTag) {
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
// IDABot finds the unit with this tag, and returns true if valid
return m_bot->GetUnit(t_id).isValid();
if (m_bot->Observation()->GetUnit(t_id) == nullptr) {
return false;
}
Unit unit = m_bot->GetUnit(t_id);
return unit.isValid();
}
}
......@@ -396,6 +424,20 @@ float Unit::getProgress() const
return -1;
}
const std::vector<float> Unit::getAllProgress() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
// If unit has order, return progress of first order
std::vector<float> progressions;
if (getUnitPtr()->orders.size() > 0) {
for(int i = 0; i < getUnitPtr()->orders.size(); i++) {
progressions.push_back(getUnitPtr()->orders[i].progress);
}
}
return progressions;
}
sc2::AbilityID Unit::getCurrentAbilityID() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
......@@ -470,4 +512,14 @@ bool Unit::isCarryingGas() const
bool Unit::isCarryingMinerals() const
{
return sc2::IsCarryingMinerals(*m_unit);
}
\ No newline at end of file
}
float Unit::maxShields() const
{
return m_unit->shield_max;
}
float Unit::maxEnergy() const
{
return m_unit->energy_max;
}
......@@ -11,13 +11,15 @@ class Unit
CCUnitID m_unitID;
UnitType m_unitType;
const sc2::Unit * m_unit;
protected:
const sc2::Unit * m_unit;
public:
Unit();
Unit(const sc2::Unit * unit, IDABot & bot);
Unit(const sc2::Unit * unit);
const sc2::Unit * getUnitPtr() const;
const sc2::UnitTypeID & getAPIUnitType() const;
......@@ -54,6 +56,7 @@ public:
Unit getTarget() const;
CCHealth getMaxHitPoints() const;
float getProgress() const;
const std::vector<float> getAllProgress() const;
sc2::AbilityID getCurrentAbilityID() const;
void holdPosition() const;
void patrol(const CCPosition & targetPosition) const;
......@@ -68,6 +71,8 @@ public:
int mineralsLeftInMineralfield() const;
int getOwner() const;
bool isCarryingGas() const;
float maxShields() const;
float maxEnergy() const;
void stop () const;
......
......@@ -13,7 +13,7 @@ UnitInfoManager::UnitInfoManager(IDABot & bot)
void UnitInfoManager::onStart()
{
updateUnitInfo();
}
void UnitInfoManager::onFrame()
......
#include "UnitType.h"
#include "IDABot.h"
#include "IDAReplayObserver.h"
UnitType::UnitType()
: m_bot(nullptr)
: m_client(nullptr)
, m_type(0)
{
}
UnitType::UnitType(const sc2::UnitTypeID & type, IDABot & bot)
: m_bot(&bot)
UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client)
: m_client(&client)
, m_bot(nullptr)
, m_observer(nullptr)
, m_type(type)
{
}
UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDABot & bot)
: m_client(&client)
, m_bot(&bot)
, m_observer(nullptr)
, m_type(type)
{
}
UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDAReplayObserver & observer)
: m_client(&client)
, m_bot(nullptr)
, m_observer(&observer)
, m_type(type)
{
}
sc2::UnitTypeID UnitType::getAPIUnitType() const
......@@ -47,7 +70,12 @@ std::string UnitType::getName() const
CCRace UnitType::getRace() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].race;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed to get race, try with game running!" << std::endl;
return CCRace::Random;
}
return m_client->Observation()->GetUnitTypeData()[m_type].race;
}
bool UnitType::isCombatUnit() const
......@@ -112,9 +140,12 @@ bool UnitType::isRefinery() const
#ifdef SC2API
switch (m_type.ToType())
{
case sc2::UNIT_TYPEID::TERRAN_REFINERY : return true;
case sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR : return true;
case sc2::UNIT_TYPEID::ZERG_EXTRACTOR : return true;
case sc2::UNIT_TYPEID::TERRAN_REFINERY : return true;
case sc2::UNIT_TYPEID::TERRAN_REFINERYRICH : return true;
case sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR : return true;
case sc2::UNIT_TYPEID::PROTOSS_ASSIMILATORRICH : return true;
case sc2::UNIT_TYPEID::ZERG_EXTRACTOR : return true;
case sc2::UNIT_TYPEID::ZERG_EXTRACTORRICH : return true;
default: return false;
}
#else
......@@ -148,6 +179,10 @@ bool UnitType::isGeyser() const
case sc2::UNIT_TYPEID::NEUTRAL_VESPENEGEYSER : return true;
case sc2::UNIT_TYPEID::NEUTRAL_PROTOSSVESPENEGEYSER : return true;
case sc2::UNIT_TYPEID::NEUTRAL_SPACEPLATFORMGEYSER : return true;
case sc2::UNIT_TYPEID::NEUTRAL_SHAKURASVESPENEGEYSER: return true;
case sc2::UNIT_TYPEID::NEUTRAL_RICHVESPENEGEYSER : return true;
case sc2::UNIT_TYPEID::NEUTRAL_PURIFIERVESPENEGEYSER: return true;
default: return false;
}
#else
......@@ -160,12 +195,15 @@ bool UnitType::isMineral() const
#ifdef SC2API
switch (m_type.ToType())
{
case sc2::UNIT_TYPEID::NEUTRAL_MINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_MINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_RICHMINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_RICHMINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_LABMINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_LABMINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_MINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_MINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_RICHMINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_RICHMINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_LABMINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_LABMINERALFIELD750 : return true;
case sc2::UNIT_TYPEID::NEUTRAL_PURIFIERMINERALFIELD : return true;
case sc2::UNIT_TYPEID::NEUTRAL_PURIFIERMINERALFIELD750 : return true;
default: return false;
}
#else
......@@ -189,10 +227,74 @@ bool UnitType::isWorker() const
#endif
}
bool UnitType::canAttackGound() const
{
#ifdef SC2API
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed canAttackGround, try with game running!" << std::endl;
return false;
}
auto & weapons = m_client->Observation()->GetUnitTypeData()[m_type].weapons;
if (weapons.empty())
{
return false;
}
for (auto & weapon : weapons)
{
if (weapon.type == sc2::Weapon::TargetType::Ground || weapon.type == sc2::Weapon::TargetType::Any)
{
return true;
}
}
return false;
#else
// TODO: this is nothing right now...
// just like with the attackRange we should never get in here.
return 0.0f;
#endif
}
bool UnitType::canAttackAir() const
{
#ifdef SC2API
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed canAttackAir, try with game running!" << std::endl;
return false;
}
auto & weapons = m_client->Observation()->GetUnitTypeData()[m_type].weapons;
if (weapons.empty())
{
return false;
}
for (auto & weapon : weapons)
{
if (weapon.type == sc2::Weapon::TargetType::Air || weapon.type == sc2::Weapon::TargetType::Any)
{
return true;
}
}
return false;
#else
// TODO: this is nothing right now...
// just like with the attackRange we should never get in here.
return 0.0f;
#endif
}
CCPositionType UnitType::getAttackRange() const
{
#ifdef SC2API
auto & weapons = m_bot->Observation()->GetUnitTypeData()[m_type].weapons;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getAttackRange, try with game running!" << std::endl;
return 0.0f;
}
auto & weapons = m_client->Observation()->GetUnitTypeData()[m_type].weapons;
if (weapons.empty())
{
......@@ -215,12 +317,62 @@ CCPositionType UnitType::getAttackRange() const
#endif
}
float UnitType::getAttackDamage() const
{
#ifdef SC2API
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getAttackDamage, try with game running!" << std::endl;
return 0.0f;
}
auto & weapons = m_client->Observation()->GetUnitTypeData()[m_type].weapons;
if (weapons.empty())
{
return 0.0f;
}
float maxDamage = 0.0f;
for (auto & weapon : weapons)
{
if (weapon.range > maxDamage)
{
maxDamage = weapon.damage_;
}
}
return maxDamage;
#else
// TODO: this is nothing right now...
// just like with the attackRange we should never get in here.
return 0.0f;
#endif
}
int UnitType::tileWidth() const
{
#ifdef SC2API
if (isMineral()) { return 2; }
if (isGeyser()) { return 3; }
else { return (int)(2 * m_bot->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius); }
else {
if (m_client->Observation()->GetAbilityData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed tileWidth, try with game running!" << std::endl;
return 0;
}
else if (m_bot != nullptr)
{
return (int)(2 * m_client->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius);
}
else if (m_observer != nullptr)
{
return (int)(2 * m_client->Observation()->GetAbilityData()[m_observer->Data(*this).buildAbility].footprint_radius);
}
else
{
return -1;
}
}
#else
return m_type.tileWidth();
#endif
......@@ -231,16 +383,48 @@ int UnitType::tileHeight() const
#ifdef SC2API
if (isMineral()) { return 1; }
if (isGeyser()) { return 3; }
else { return (int)(2 * m_bot->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius); }
else {
if (m_client->Observation()->GetAbilityData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed tileHeight, try with game running!" << std::endl;
return 0;
}
else if (m_bot != nullptr)
{
return (int)(2 * m_client->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius);
}
else if (m_observer != nullptr)
{
return (int)(2 * m_client->Observation()->GetAbilityData()[m_observer->Data(*this).buildAbility].footprint_radius);
}
else
{
return -1;
}
}
#else
return m_type.tileHeight();
#endif
}
bool UnitType::isAddon() const
{
#ifdef SC2API
return m_bot->Data(*this).isAddon;
if (m_bot != nullptr)
{
return m_bot->Data(*this).isAddon;
}
else if (m_observer != nullptr)
{
return m_observer->Data(*this).isAddon;
}
else
{
return false;
}
#else
return m_type.isAddon();
#endif
......@@ -249,7 +433,19 @@ bool UnitType::isAddon() const
bool UnitType::isBuilding() const
{
#ifdef SC2API
return m_bot->Data(*this).isBuilding;
if (m_bot != nullptr)
{
return m_bot->Data(*this).isBuilding;
}
else if (m_observer != nullptr)
{
return m_observer->Data(*this).isBuilding;
}
else
{
return false;
}
#else
return m_type.isBuilding();
#endif
......@@ -258,7 +454,13 @@ bool UnitType::isBuilding() const
int UnitType::supplyProvided() const
{
#ifdef SC2API
return (int)m_bot->Observation()->GetUnitTypeData()[m_type].food_provided;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed supplyProvided, try with game running!" << std::endl;
return 0;
}
return (int)m_client->Observation()->GetUnitTypeData()[m_type].food_provided;
#else
return m_type.supplyProvided();
#endif
......@@ -267,7 +469,13 @@ int UnitType::supplyProvided() const
int UnitType::supplyRequired() const
{
#ifdef SC2API
return (int)m_bot->Observation()->GetUnitTypeData()[m_type].food_required;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed supplyRequired, try with game running!" << std::endl;
return 0;
}
return (int)m_client->Observation()->GetUnitTypeData()[m_type].food_required;
#else
return m_type.supplyRequired();
#endif
......@@ -276,7 +484,12 @@ int UnitType::supplyRequired() const
int UnitType::mineralPrice() const
{
#ifdef SC2API
return (int)m_bot->Observation()->GetUnitTypeData()[m_type].mineral_cost;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed mineralPrice, try with game running!" << std::endl;
return 0;
}
return (int)m_client->Observation()->GetUnitTypeData()[m_type].mineral_cost;
#else
return m_type.mineralPrice();
#endif
......@@ -285,7 +498,12 @@ int UnitType::mineralPrice() const
int UnitType::gasPrice() const
{
#ifdef SC2API
return (int)m_bot->Observation()->GetUnitTypeData()[m_type].vespene_cost;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed gasPrice, try with game running!" << std::endl;
return 0;
}
return (int)m_client->Observation()->GetUnitTypeData()[m_type].vespene_cost;
#else
return m_type.gasPrice();
#endif
......@@ -368,7 +586,7 @@ bool UnitType::isMorphedBuilding() const
}
#else
return m_type == BWAPI::UnitTypes::Zerg_Sunken_Colony ||
m_type == BWAPI::UnitTypes::Zerg_Spore_Colony ||w
m_type == BWAPI::UnitTypes::Zerg_Spore_Colony ||
m_type == BWAPI::UnitTypes::Zerg_Lair ||
m_type == BWAPI::UnitTypes::Zerg_Hive ||
m_type == BWAPI::UnitTypes::Zerg_Greater_Spire;
......@@ -377,30 +595,60 @@ bool UnitType::isMorphedBuilding() const
int UnitType::getMovementSpeed() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].movement_speed;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getMovementSpeed, try with game running!" << std::endl;
return 0;
}
return m_client->Observation()->GetUnitTypeData()[m_type].movement_speed;
}
int UnitType::getSightRange() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].sight_range;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getSightRange, try with game running!" << std::endl;
return 0;
}
return m_client->Observation()->GetUnitTypeData()[m_type].sight_range;
}
UnitTypeID UnitType::getRequiredStructure() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].tech_requirement;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getRequiredStructure, try with game running!" << std::endl;
return UnitTypeID();
}
return m_client->Observation()->GetUnitTypeData()[m_type].tech_requirement;
}
std::vector<sc2::UnitTypeID> UnitType::getEquivalentUnits() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].tech_alias;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getEquivalentUnits, try with game running!" << std::endl;
return std::vector<sc2::UnitTypeID>();
}
return m_client->Observation()->GetUnitTypeData()[m_type].tech_alias;
}
bool UnitType::requiredAttached() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].require_attached;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed requiredAttached, try with game running!" << std::endl;
return false;
}
return m_client->Observation()->GetUnitTypeData()[m_type].require_attached;
}
float UnitType::getBuildTime() const
{
return m_bot->Observation()->GetUnitTypeData()[m_type].build_time;
if (m_client->Observation()->GetUnitTypeData().empty()) // Check to hopefully avoid segfaults
{
std::cout << "Failed getBuildTime, try with game running!" << std::endl;
return 0.0f;
}
return m_client->Observation()->GetUnitTypeData()[m_type].build_time;
}
\ No newline at end of file
......@@ -4,17 +4,24 @@
class IDABot;
class IDAReplayObserver;
class UnitType
{
mutable IDABot * m_bot;
mutable sc2::Client * m_client;
mutable IDABot * m_bot;
mutable IDAReplayObserver * m_observer;
sc2::UnitTypeID m_type;
public:
UnitType();
UnitType(const sc2::UnitTypeID & type, IDABot & bot);
UnitType(const sc2::UnitTypeID & type, sc2::Client & client);
UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDABot & m_bot);
UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDAReplayObserver & observer);
sc2::UnitTypeID getAPIUnitType() const;
bool is(const sc2::UnitTypeID & type) const;
......@@ -42,7 +49,10 @@ public:
bool canAttack() const;
bool canMove() const;
bool isAddon() const;
bool canAttackGound() const;
bool canAttackAir() const;
CCPositionType getAttackRange() const;
float getAttackDamage() const;
int tileWidth() const;
int tileHeight() const;
int supplyProvided() const;
......
......@@ -3,7 +3,7 @@ import sys
sys.path.append('build/python-api-src')
from library import UnitTypeID, UNIT_TYPEID
from commandcenter import UnitTypeID, UNIT_TYPEID
class TestUnitType(unittest.TestCase):
......