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
#pragma once
#include "IDABot.h"
class MyAgent : public IDABot
{
// Worker management
enum Assignment {
Scout,
Mineral,
Gas,
BuildWalking,
BuildBuilding
};
struct AssignmentData {
// When assigned to building, this corresponds to the location for the building
CCTilePosition buildGoal;
};
// Building management
// Worker assignment book-keeping
std::map<Unit, Assignment> workerAssignment;
// When workers are assigned to either minerals or gas, they get assigned a base
std::map<const BaseLocation *, std::vector<Unit>> base_assignment;
std::vector<UnitType> build_order; // TODO: Not used
std::vector<UnitType> CreateBuildPlan();
void CreateMaximizeMilitaryBuildPlan(std::vector<UnitType> &build_plan, size_t &available_food);
void CreateMaximizeEconomyBuildPlan(size_t &number_of_minerals, size_t &number_of_workers, size_t &available_food, std::vector<UnitType> &build_plan);
void assignScout();
void manageWorkers(std::vector<UnitType> & build_plan);
void manageBuilding(std::vector<UnitType> & build_plan);
bool isFree(Unit & worker);
void assignWork(Unit & worker, Assignment assignment);
std::map<UnitType, int> numberOfTypeBeingBuilt() const;
const BaseLocation * AssignBase(Unit & worker);
CCTilePosition getBuildPosition(UnitType & building);
Unit getClosestMineral(const CCPosition & unit) const;
struct BuildStatus
{
UnitType type;
CCTilePosition position;
int idle;
};
std::map<Unit, BuildStatus> currently_building;
// Military management
std::map<UnitType, int> military_goal;
// Economy
struct Resources
{
int minerals;
int gas;
};
Resources military_spending{};
Resources economy_spending{};
// Getters
std::vector<Unit> getWorkers();
// Maybe
std::vector<Unit> getProducer(const MetaType & type, bool includeBusy = false, bool include_incomplete = false);
public:
MyAgent();
void OnGameStart() override;
void OnStep() override;
};
\ No newline at end of file
#include "ProductionManager.h"
#include "Util.h"
#include "IDABot.h"
ProductionManager::ProductionManager(IDABot & bot)
: m_bot (bot)
, m_buildingManager (bot)
, m_queue (bot)
{
}
void ProductionManager::setBuildOrder(const BuildOrder & buildOrder)
{
m_queue.clearAll();
for (size_t i(0); i<buildOrder.size(); ++i)
{
m_queue.queueAsLowestPriority(buildOrder[i], true);
}
}
void ProductionManager::onStart()
{
m_buildingManager.onStart();
//setBuildOrder(m_bot.Strategy().getOpeningBookBuildOrder());
}
void ProductionManager::onFrame()
{
fixBuildOrderDeadlock();
manageBuildOrderQueue();
// TODO: if nothing is currently building, get a new goal from the strategy manager
// TODO: detect if there's a build order deadlock once per second
// TODO: triggers for game things like cloaked units etc
m_buildingManager.onFrame();
drawProductionInformation();
}
// on unit destroy
void ProductionManager::onUnitDestroy(const Unit & unit)
{
// TODO: might have to re-do build order if a vital unit died
}
void ProductionManager::manageBuildOrderQueue()
{
// if there is nothing in the queue, oh well
if (m_queue.isEmpty())
{
return;
}
// the current item to be used
BuildOrderItem & currentItem = m_queue.getHighestPriorityItem();
// while there is still something left in the queue
while (!m_queue.isEmpty())
{
// this is the unit which can produce the currentItem
Unit producer = getProducer(currentItem.type);
// check to see if we can make it right now
bool canMake = canMakeNow(producer, currentItem.type);
// TODO: if it's a building and we can't make it yet, predict the worker movement to the location
// if we can make the current item
if (producer.isValid() && canMake)
{
// create it and remove it from the _queue
create(producer, currentItem);
m_queue.removeCurrentHighestPriorityItem();
// don't actually loop around in here
break;
}
// otherwise, if we can skip the current item
else if (m_queue.canSkipItem())
{
// skip it
m_queue.skipItem();
// and get the next one
currentItem = m_queue.getNextHighestPriorityItem();
}
else
{
// so break out
break;
}
}
}
void ProductionManager::fixBuildOrderDeadlock()
{
if (m_queue.isEmpty()) { return; }
BuildOrderItem & currentItem = m_queue.getHighestPriorityItem();
// check to see if we have the prerequisites for the topmost item
bool hasRequired = m_bot.Data(currentItem.type).requiredUnits.empty();
for (auto & required : m_bot.Data(currentItem.type).requiredUnits)
{
if (m_bot.UnitInfo().getUnitTypeCount(Players::Self, required, false) > 0 || m_buildingManager.isBeingBuilt(required))
{
hasRequired = true;
break;
}
}
if (!hasRequired)
{
std::cout << currentItem.type.getName() << " needs " << m_bot.Data(currentItem.type).requiredUnits[0].getName() << "\n";
m_queue.queueAsHighestPriority(MetaType(m_bot.Data(currentItem.type).requiredUnits[0], m_bot), true);
fixBuildOrderDeadlock();
return;
}
// build the producer of the unit if we don't have one
bool hasProducer = m_bot.Data(currentItem.type).whatBuilds.empty();
for (auto & producer : m_bot.Data(currentItem.type).whatBuilds)
{
if (m_bot.UnitInfo().getUnitTypeCount(Players::Self, producer, false) > 0 || m_buildingManager.isBeingBuilt(producer))
{
hasProducer = true;
break;
}
}
if (!hasProducer)
{
m_queue.queueAsHighestPriority(MetaType(m_bot.Data(currentItem.type).whatBuilds[0], m_bot), true);
fixBuildOrderDeadlock();
}
// build a refinery if we don't have one and the thing costs gas
auto refinery = Util::GetRefinery(m_bot.GetPlayerRace(Players::Self), m_bot);
if (m_bot.Data(currentItem.type).gasCost > 0 && m_bot.UnitInfo().getUnitTypeCount(Players::Self, refinery, false) == 0)
{
m_queue.queueAsHighestPriority(MetaType(refinery, m_bot), true);
}
// build supply if we need some
auto supplyProvider = Util::GetSupplyProvider(m_bot.GetPlayerRace(Players::Self), m_bot);
if (m_bot.Data(currentItem.type).supplyCost > (m_bot.GetMaxSupply() - m_bot.GetCurrentSupply()) && !m_buildingManager.isBeingBuilt(supplyProvider))
{
m_queue.queueAsHighestPriority(MetaType(supplyProvider, m_bot), true);
}
}
Unit ProductionManager::getProducer(const MetaType & type, CCPosition closestTo)
{
// get all the types of units that cna build this type
auto & producerTypes = m_bot.Data(type).whatBuilds;
// make a set of all candidate producers
std::vector<Unit> candidateProducers;
for (auto unit : m_bot.UnitInfo().getUnits(Players::Self))
{
// reasons a unit can not train the desired type
if (std::find(producerTypes.begin(), producerTypes.end(), unit.getType()) == producerTypes.end()) { continue; }
if (!unit.isCompleted()) { continue; }
if (m_bot.Data(unit).isBuilding && unit.isTraining()) { continue; }
if (unit.isFlying()) { continue; }
// TODO: if unit is not powered continue
// TODO: if the type is an addon, some special cases
// TODO: if the type requires an addon and the producer doesn't have one
// if we haven't cut it, add it to the set of candidates
candidateProducers.push_back(unit);
}
return getClosestUnitToPosition(candidateProducers, closestTo);
}
Unit ProductionManager::getClosestUnitToPosition(const std::vector<Unit> & units, CCPosition closestTo)
{
if (units.size() == 0)
{
return Unit();
}
// if we don't care where the unit is return the first one we have
if (closestTo.x == 0 && closestTo.y == 0)
{
return units[0];
}
Unit closestUnit;
double minDist = std::numeric_limits<double>::max();
for (auto & unit : units)
{
double distance = Util::Dist(unit, closestTo);
if (!closestUnit.isValid() || distance < minDist)
{
closestUnit = unit;
minDist = distance;
}
}
return closestUnit;
}
// this function will check to see if all preconditions are met and then create a unit
void ProductionManager::create(const Unit & producer, BuildOrderItem & item)
{
if (!producer.isValid())
{
return;
}
// if we're dealing with a building
if (item.type.isBuilding())
{
if (item.type.getUnitType().isMorphedBuilding())
{
producer.morph(item.type.getUnitType());
}
else
{
m_buildingManager.addBuildingTask(item.type.getUnitType(), Util::GetTilePosition(m_bot.GetStartLocation()));
}
}
// if we're dealing with a non-building unit
else if (item.type.isUnit())
{
producer.train(item.type.getUnitType());
}
else if (item.type.isUpgrade())
{
// TODO: UPGRADES
//Micro::SmartAbility(producer, m_bot.Data(item.type.getUpgradeID()).buildAbility, m_bot);
}
}
bool ProductionManager::canMakeNow(const Unit & producer, const MetaType & type)
{
if (!producer.isValid() || !meetsReservedResources(type))
{
return false;
}
#ifdef SC2API
sc2::AvailableAbilities available_abilities = m_bot.Query()->GetAbilitiesForUnit(producer.getUnitPtr());
// quick check if the unit can't do anything it certainly can't build the thing we want
if (available_abilities.abilities.empty())
{
return false;
}
else
{
// check to see if one of the unit's available abilities matches the build ability type
sc2::AbilityID MetaTypeAbility = m_bot.Data(type).buildAbility;
for (const sc2::AvailableAbility & available_ability : available_abilities.abilities)
{
if (available_ability.ability_id == MetaTypeAbility)
{
return true;
}
}
}
return false;
#else
bool canMake = meetsReservedResources(type);
if (canMake)
{
if (type.isUnit())
{
canMake = BWAPI::Broodwar->canMake(type.getUnitType().getAPIUnitType(), producer.getUnitPtr());
}
else if (type.isTech())
{
canMake = BWAPI::Broodwar->canResearch(type.getTechType(), producer.getUnitPtr());
}
else if (type.isUpgrade())
{
canMake = BWAPI::Broodwar->canUpgrade(type.getUpgrade(), producer.getUnitPtr());
}
else
{
BOT_ASSERT(false, "Unknown type");
}
}
return canMake;
#endif
}
bool ProductionManager::detectBuildOrderDeadlock()
{
// TODO: detect build order deadlocks here
return false;
}
int ProductionManager::getFreeMinerals()
{
return m_bot.GetMinerals() - m_buildingManager.getReservedMinerals();
}
int ProductionManager::getFreeGas()
{
return m_bot.GetGas() - m_buildingManager.getReservedGas();
}
// return whether or not we meet resources, including building reserves
bool ProductionManager::meetsReservedResources(const MetaType & type)
{
// return whether or not we meet the resources
int minerals = m_bot.Data(type).mineralCost;
int gas = m_bot.Data(type).gasCost;
return (m_bot.Data(type).mineralCost <= getFreeMinerals()) && (m_bot.Data(type).gasCost <= getFreeGas());
}
void ProductionManager::drawProductionInformation()
{
std::stringstream ss;
ss << "Production Information\n\n";
for (auto & unit : m_bot.UnitInfo().getUnits(Players::Self))
{
if (unit.isBeingConstructed())
{
//ss << sc2::UnitTypeToName(unit.unit_type) << " " << unit.build_progress << "\n";
}
}
ss << m_queue.getQueueInformation();
m_bot.Map().drawTextScreen(0.01f, 0.01f, ss.str(), CCColor(255, 255, 0));
}
#pragma once
#include "Common.h"
#include "BuildOrder.h"
#include "BuildingManager.h"
#include "BuildOrderQueue.h"
class IDABot;
class ProductionManager
{
IDABot & m_bot;
BuildingManager m_buildingManager;
BuildOrderQueue m_queue;
Unit getClosestUnitToPosition(const std::vector<Unit> & units, CCPosition closestTo);
bool meetsReservedResources(const MetaType & type);
bool canMakeNow(const Unit & producer, const MetaType & type);
bool detectBuildOrderDeadlock();
void setBuildOrder(const BuildOrder & buildOrder);
void create(const Unit & producer, BuildOrderItem & item);
void manageBuildOrderQueue();
int getFreeMinerals();
int getFreeGas();
void fixBuildOrderDeadlock();
public:
ProductionManager(IDABot & bot);
void onStart();
void onFrame();
void onUnitDestroy(const Unit & unit);
void drawProductionInformation();
Unit getProducer(const MetaType & type, CCPosition closestTo = CCPosition(0, 0));
};
#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
......@@ -2,8 +2,8 @@
#include "IDABot.h"
#include "MetaType.h"
TechTree::TechTree(IDABot & bot)
: m_bot(bot)
TechTree::TechTree(sc2::Client & client)
: m_client(client), suppressWarnings(false)
{
}
......@@ -12,160 +12,251 @@ void TechTree::onStart()
{
initUnitTypeData();
initUpgradeData();
/* As it turns out, some of the hard-coded values are wrong. Instead of
going through each and checking, we fix them with information from a
(hopefully) up to date JSON-file. Sorry in advance, this was the best
solution at the time. Hopefully the JSON-files are still up to date. */
TechTreeImproved tree;
bool success = tree.LoadData();
// If the file was not successfully open/parsed, don't replace the unitTypeData.
if (!success)
{
return;
}
std::set<sc2::UNIT_TYPEID> updated;
for (const BuildDescription & description : tree.BuildDescriptions())
{
if (m_unitTypeData.count(UnitType(description.result_type, m_client)) == 0)
{
//std::cout << "Inserting new information about UNIT_TYPEID: "
// << sc2::UnitTypeToName(description.result_type) << " ("
// << static_cast<unsigned int>(description.result_type) << ")"
// << std::endl;
}
TypeData & data = m_unitTypeData[UnitType(description.result_type, m_client)];
// If this is the first time we a way to build this type, remove previous data
if (updated.count(description.result_type) == 0)
{
data.whatBuilds.clear();
data.requiredUnits.clear();
data.requiredUpgrades.clear();
updated.insert(description.result_type);
data.buildTime = description.buildTime; // The time in seconds it takes to create the unit
data.buildAbility = sc2::ABILITY_ID::INVALID;
}
data.whatBuilds.push_back(UnitType(description.producer_type, m_client));
if (description.build_ability != sc2::ABILITY_ID::INVALID) data.buildAbility = description.build_ability;
if (description.morph_ability != sc2::ABILITY_ID::INVALID) data.morphAbility = description.morph_ability;
for (sc2::UNIT_TYPEID unit_typeid : description.buildings_needed)
{
data.requiredUnits.push_back(UnitType(unit_typeid, m_client));
}
for (sc2::UNIT_TYPEID unit_typeid : description.addons_needed)
{
data.requiredAddons.push_back(UnitType(unit_typeid, m_client));
}
}
for (std::pair <const sc2::UpgradeID, TypeData> & pair : m_upgradeData)
{
const sc2::UpgradeID id = pair.first;
TypeData & data = pair.second;
data.whatBuilds.clear();
data.requiredUnits.clear();
data.requiredUpgrades.clear();
for (const ResearchDescription & description : tree.HowToResearch(id))
{
data.buildAbility = description.ability_used;
data.whatBuilds.push_back(UnitType(description.producer_type, m_client));
for (sc2::UNIT_TYPEID unit_typeid : description.buildings_needed)
{
data.requiredUnits.push_back(UnitType(unit_typeid, m_client));
}
for (sc2::UPGRADE_ID upgrade_id : description.upgrades_needed)
{
data.requiredUpgrades.push_back(upgrade_id);
}
}
}
}
void TechTree::setSuppressWarnings(bool b)
{
suppressWarnings = b;
}
bool TechTree::getSuppressWarnings() const
{
return suppressWarnings;
}
void TechTree::initUnitTypeData()
{
m_unitTypeData[UnitType(0, m_bot)] = TypeData();
m_unitTypeData[UnitType(0, m_client)] = TypeData();
// Protoss Buildings unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLONOVERCHARGED, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::EFFECT_PHOTONOVERCHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_bot), UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_PYLON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_NEXUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_ASSIMILATOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_CYBERNETICSCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot), UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_DARKSHRINE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FLEETBEACON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FORGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GATEWAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOTONCANNON, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_PHOTONCANNON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSBAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSFACILITY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TEMPLARARCHIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TWILIGHTCOUNCIL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, {}, { sc2::UPGRADE_ID::WARPGATERESEARCH } };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLONOVERCHARGED, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::EFFECT_PHOTONOVERCHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_client), UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_PYLON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_NEXUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_ASSIMILATOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_CYBERNETICSCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client), UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_DARKSHRINE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FLEETBEACON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FORGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GATEWAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOTONCANNON, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_PHOTONCANNON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSBAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSFACILITY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TEMPLARARCHIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TWILIGHTCOUNCIL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, {}, { sc2::UPGRADE_ID::WARPGATERESEARCH } };
// Protoss Units unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot)] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_PROBE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MOTHERSHIPCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ZEALOT, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZEALOT, sc2::ABILITY_ID::TRAINWARP_ZEALOT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_SENTRY, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SENTRY, sc2::ABILITY_ID::TRAINWARP_SENTRY, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STALKER, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_STALKER, sc2::ABILITY_ID::TRAINWARP_STALKER, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_HIGHTEMPLAR, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HIGHTEMPLAR, sc2::ABILITY_ID::TRAINWARP_HIGHTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKTEMPLAR, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DARKTEMPLAR, sc2::ABILITY_ID::TRAINWARP_DARKTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ADEPT, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ADEPT, sc2::ABILITY_ID::TRAINWARP_ADEPT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_COLOSSUS, m_bot)] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_COLOSSUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DISRUPTOR, m_bot)] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DISRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPPRISM, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WARPPRISM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_OBSERVER, m_bot)] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_OBSERVER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_IMMORTAL, m_bot)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_IMMORTAL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_bot)] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CARRIER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_bot)] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ORACLE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOENIX, m_bot)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_PHOENIX, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_VOIDRAY, m_bot)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VOIDRAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPEST, m_bot)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_TEMPEST, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_INTERCEPTOR, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INTERCEPTORS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLESTASISTRAP, m_bot)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STASISTRAP, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client)] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_PROBE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MOTHERSHIPCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ZEALOT, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZEALOT, sc2::ABILITY_ID::TRAINWARP_ZEALOT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_SENTRY, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SENTRY, sc2::ABILITY_ID::TRAINWARP_SENTRY, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STALKER, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_STALKER, sc2::ABILITY_ID::TRAINWARP_STALKER, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_HIGHTEMPLAR, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HIGHTEMPLAR, sc2::ABILITY_ID::TRAINWARP_HIGHTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKTEMPLAR, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DARKTEMPLAR, sc2::ABILITY_ID::TRAINWARP_DARKTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ADEPT, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ADEPT, sc2::ABILITY_ID::TRAINWARP_ADEPT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_COLOSSUS, m_client)] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_COLOSSUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DISRUPTOR, m_client)] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DISRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPPRISM, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WARPPRISM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_OBSERVER, m_client)] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_OBSERVER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_IMMORTAL, m_client)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_IMMORTAL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_client)] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CARRIER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_client)] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ORACLE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOENIX, m_client)] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_PHOENIX, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_VOIDRAY, m_client)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VOIDRAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPEST, m_client)] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_TEMPEST, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_INTERCEPTOR, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INTERCEPTORS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLESTASISTRAP, m_client)] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STASISTRAP, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_client) }, {}, {} };
// Terran Buildings m g s t unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_COMMANDCENTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_SUPPLYDEPOT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REFINERY, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_REFINERY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ARMORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SENSORTOWER, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SENSORTOWER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FUSIONCORE, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FUSIONCORE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GHOSTACADEMY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BUNKER, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BUNKER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ENGINEERINGBAY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MISSILETURRET, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_MISSILETURRET, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_ORBITALCOMMAND, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_PLANETARYFORTRESS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_COMMANDCENTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_SUPPLYDEPOT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REFINERY, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_REFINERY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ARMORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SENSORTOWER, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SENSORTOWER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FUSIONCORE, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FUSIONCORE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GHOSTACADEMY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BUNKER, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BUNKER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ENGINEERINGBAY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MISSILETURRET, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_MISSILETURRET, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_ORBITALCOMMAND, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_PLANETARYFORTRESS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
// Terran Addons m g s t unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSREACTOR, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYREACTOR, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTREACTOR, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSREACTOR, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYREACTOR, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTREACTOR, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
// Terran Equivalent Buildings
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_bot)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)];
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_client)] = m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client)];
// Terran Units m g s t unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_SCV, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOST, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_GHOST, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARAUDER, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARAUDER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARINE, m_bot)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REAPER, m_bot)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_REAPER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_HELLION, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HELLION, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_CYCLONE, m_bot)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CYCLONE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SIEGETANK, m_bot)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SIEGETANK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THOR, m_bot)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_WIDOWMINE, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WIDOWMINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_NUKE, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NUKE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BANSHEE, m_bot)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANSHEE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BATTLECRUISER, m_bot)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BATTLECRUISER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_LIBERATOR, m_bot)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_LIBERATOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_VIKINGFIGHTER, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIKINGFIGHTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_RAVEN, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_RAVEN, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MEDIVAC, m_bot)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MEDIVAC, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MULE, m_bot)] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THORAP, m_bot)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0,{ UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) },{},{} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_SCV, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOST, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_GHOST, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARAUDER, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARAUDER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARINE, m_client)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REAPER, m_client)] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_REAPER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_HELLION, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HELLION, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_CYCLONE, m_client)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CYCLONE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SIEGETANK, m_client)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SIEGETANK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THOR, m_client)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_WIDOWMINE, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WIDOWMINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_NUKE, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NUKE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BANSHEE, m_client)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANSHEE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BATTLECRUISER, m_client)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BATTLECRUISER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_LIBERATOR, m_client)] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_LIBERATOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_VIKINGFIGHTER, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIKINGFIGHTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_RAVEN, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_RAVEN, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MEDIVAC, m_client)] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MEDIVAC, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MULE, m_client)] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THORAP, m_client)] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0,{ UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) },{},{} };
// Zerg Buildings m g s t unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_HATCHERY, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EXTRACTOR, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_EXTRACTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPAWNINGPOOL, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_EVOLUTIONCHAMBER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BANELINGNEST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_HYDRALISKDEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INFESTATIONPIT, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSCANAL, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSWORM, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSNETWORK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROACHWARREN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPINECRAWLER, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPINECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_GREATERSPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPORECRAWLER, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPORECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ULTRALISKCAVERN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_LAIR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot) }, {UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot)}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_HIVE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_HATCHERY, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EXTRACTOR, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_EXTRACTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPAWNINGPOOL, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_EVOLUTIONCHAMBER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BANELINGNEST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_HYDRALISKDEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INFESTATIONPIT, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSCANAL, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSWORM, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSNETWORK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROACHWARREN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPINECRAWLER, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPINECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_GREATERSPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPORECRAWLER, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPORECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ULTRALISKCAVERN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_LAIR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client) }, {UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client)}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_HIVE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };
// Zerg Units m g s t unit bld wrk rfn sup hall add
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_OVERLORD, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, true, false, false, sc2::ABILITY_ID::TRAIN_OVERLORD, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELING, m_bot)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANELING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_CORRUPTOR, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CORRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot)] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DRONE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISK, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HYDRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LURKERDENMP, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTOR, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_INFESTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_MUTALISK, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MUTALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACH, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ROACH, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SWARMHOSTMP, m_bot)] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SWARMHOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISK, m_bot)] = { sc2::Race::Zerg, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ULTRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_VIPER, m_bot)] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIPER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ZERGLING, m_bot)] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZERGLING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_QUEEN, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_QUEEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EGG, m_bot)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_OVERLORD, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, true, false, false, sc2::ABILITY_ID::TRAIN_OVERLORD, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELING, m_client)] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::MORPH_BANELING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_CORRUPTOR, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CORRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client)] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DRONE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, {}, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISK, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HYDRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LURKERDENMP, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTOR, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_INFESTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_MUTALISK, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MUTALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACH, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ROACH, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SWARMHOSTMP, m_client)] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SWARMHOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISK, m_client)] = { sc2::Race::Zerg, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ULTRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_VIPER, m_client)] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIPER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ZERGLING, m_client)] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZERGLING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_QUEEN, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_QUEEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EGG, m_client)] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
// Set the Mineral / Gas cost of each unit
for (auto & kv : m_unitTypeData)
{
if (!kv.first.isValid()) { continue; }
auto & data = m_bot.Observation()->GetUnitTypeData()[kv.first.getAPIUnitType()];
auto & data = m_client.Observation()->GetUnitTypeData()[kv.first.getAPIUnitType()];
kv.second.mineralCost = data.mineral_cost;
kv.second.gasCost = data.vespene_cost;
}
// fix the cumulative prices of morphed buildings
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)).mineralCost;
m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client)).mineralCost;
}
void TechTree::initUpgradeData()
......@@ -174,102 +265,105 @@ void TechTree::initUpgradeData()
m_upgradeData[0] = TypeData();
// Terran Upgrades
m_upgradeData[sc2::UPGRADE_ID::BANSHEECLOAK] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEECLOAKINGFIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BANSHEESPEED] = { sc2::Race::Terran, 200, 200, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEEHYPERFLIGHTROTORS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BATTLECRUISERENABLESPECIALIZATIONS]= { sc2::Race::Terran, 150, 150, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BATTLECRUISERWEAPONREFIT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DRILLCLAWS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_DRILLINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HIGHCAPACITYBARRELS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INFERNALPREIGNITER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HISECAUTOTRACKING] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HISECAUTOTRACKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::LIBERATORAGRANGEUPGRADE] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADVANCEDBALLISTICS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MAGFIELDLAUNCHERS] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MAGFIELDLAUNCHERS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MEDIVACINCREASESPEEDBOOST] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HIGHCAPACITYFUELTANKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEOSTEELFRAME] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEOSTEELFRAME, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PERSONALCLOAKING] = { sc2::Race::Terran, 150, 150, 0, 1920, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PERSONALCLOAKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PUNISHERGRENADES] = { sc2::Race::Terran, 50, 50, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CONCUSSIVESHELLS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENCORVIDREACTOR] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENCORVIDREACTOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENRECALIBRATEDEXPLOSIVES] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENRECALIBRATEDEXPLOSIVES, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::SHIELDWALL] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_COMBATSHIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::STIMPACK] = { sc2::Race::Terran, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_STIMPACK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANBUILDINGARMOR] = { sc2::Race::Terran, 150, 150, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSTRUCTUREARMORUPGRADE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::BANSHEECLOAK] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEECLOAKINGFIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BANSHEESPEED] = { sc2::Race::Terran, 200, 200, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEEHYPERFLIGHTROTORS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BATTLECRUISERENABLESPECIALIZATIONS]= { sc2::Race::Terran, 150, 150, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BATTLECRUISERWEAPONREFIT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DRILLCLAWS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_DRILLINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HIGHCAPACITYBARRELS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INFERNALPREIGNITER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HISECAUTOTRACKING] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HISECAUTOTRACKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::LIBERATORAGRANGEUPGRADE] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADVANCEDBALLISTICS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MAGFIELDLAUNCHERS] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CYCLONELOCKONDAMAGE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MEDIVACINCREASESPEEDBOOST] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HIGHCAPACITYFUELTANKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEOSTEELFRAME] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEOSTEELFRAME, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PERSONALCLOAKING] = { sc2::Race::Terran, 150, 150, 0, 1920, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PERSONALCLOAKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PUNISHERGRENADES] = { sc2::Race::Terran, 50, 50, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CONCUSSIVESHELLS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENCORVIDREACTOR] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENCORVIDREACTOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENRECALIBRATEDEXPLOSIVES] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENRECALIBRATEDEXPLOSIVES, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::SHIELDWALL] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_COMBATSHIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::STIMPACK] = { sc2::Race::Terran, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_STIMPACK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANBUILDINGARMOR] = { sc2::Race::Terran, 150, 150, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSTRUCTUREARMORUPGRADE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2} };
// Protoss Upgrades
m_upgradeData[sc2::UPGRADE_ID::ADEPTPIERCINGATTACK] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADEPTRESONATINGGLAIVES, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BLINKTECH] = { sc2::Race::Protoss, 150, 150, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BLINK, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CARRIERLAUNCHSPEEDUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INTERCEPTORGRAVITONCATAPULT, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHARGE] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DARKTEMPLARBLINKUPGRADE] = { sc2::Race::Protoss, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_SHADOWSTRIKE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EXTENDEDTHERMALLANCE] = { sc2::Race::Protoss, 200, 200, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_EXTENDEDTHERMALLANCE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GRAVITICDRIVE] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICDRIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OBSERVERGRAVITICBOOSTER] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICBOOSTER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PHOENIXRANGEUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1440, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PHOENIXANIONPULSECRYSTALS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL2] = { sc2::Race::Protoss, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3] = { sc2::Race::Protoss, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PSISTORMTECH] = { sc2::Race::Protoss, 200, 200, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PSISTORM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::WARPGATERESEARCH] = { sc2::Race::Protoss, 50, 50, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ADEPTPIERCINGATTACK] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADEPTRESONATINGGLAIVES, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BLINKTECH] = { sc2::Race::Protoss, 150, 150, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BLINK, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CARRIERLAUNCHSPEEDUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INTERCEPTORGRAVITONCATAPULT, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHARGE] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DARKTEMPLARBLINKUPGRADE] = { sc2::Race::Protoss, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_SHADOWSTRIKE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EXTENDEDTHERMALLANCE] = { sc2::Race::Protoss, 200, 200, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_EXTENDEDTHERMALLANCE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GRAVITICDRIVE] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICDRIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OBSERVERGRAVITICBOOSTER] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICBOOSTER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PHOENIXRANGEUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1440, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PHOENIXANIONPULSECRYSTALS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL2] = { sc2::Race::Protoss, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3] = { sc2::Race::Protoss, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PSISTORMTECH] = { sc2::Race::Protoss, 200, 200, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PSISTORM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::WARPGATERESEARCH] = { sc2::Race::Protoss, 50, 50, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
// Zerg Upgrades
m_upgradeData[sc2::UPGRADE_ID::BURROW] = { sc2::Race::Zerg, 100, 100, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BURROW, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CENTRIFICALHOOKS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CENTRIFUGALHOOKS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHITINOUSPLATING] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHITINOUSPLATING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEGROOVEDSPINES] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GROOVEDSPINES, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEMUSCULARAUGMENTS] = { sc2::Race::Zerg, 150, 150, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MUSCULARAUGMENTS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GLIALRECONSTITUTION] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GLIALREGENERATION, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_upgradeData[sc2::UPGRADE_ID::INFESTORENERGYUPGRADE] = { sc2::Race::Zerg, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PATHOGENGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEURALPARASITE] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEURALPARASITE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OVERLORDSPEED] = { sc2::Race::Zerg, 100, 100, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PNEUMATIZEDCARAPACE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TUNNELINGCLAWS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TUNNELINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2] = { sc2::Race::Zerg, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL3] = { sc2::Race::Zerg, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {UnitType( sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGATTACKSPEED] = { sc2::Race::Zerg, 200, 200, 0, 2080, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGADRENALGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGMOVEMENTSPEED] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGMETABOLICBOOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::BURROW] = { sc2::Race::Zerg, 100, 100, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BURROW, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CENTRIFICALHOOKS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CENTRIFUGALHOOKS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHITINOUSPLATING] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHITINOUSPLATING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEGROOVEDSPINES] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GROOVEDSPINES, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEMUSCULARAUGMENTS] = { sc2::Race::Zerg, 150, 150, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MUSCULARAUGMENTS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GLIALRECONSTITUTION] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GLIALREGENERATION, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_upgradeData[sc2::UPGRADE_ID::INFESTORENERGYUPGRADE] = { sc2::Race::Zerg, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PATHOGENGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEURALPARASITE] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEURALPARASITE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OVERLORDSPEED] = { sc2::Race::Zerg, 100, 100, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PNEUMATIZEDCARAPACE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TUNNELINGCLAWS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TUNNELINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2] = { sc2::Race::Zerg, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL3] = { sc2::Race::Zerg, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {UnitType( sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGATTACKSPEED] = { sc2::Race::Zerg, 200, 200, 0, 2080, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGADRENALGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGMOVEMENTSPEED] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGMETABOLICBOOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2} };
}
const TypeData & TechTree::getData(const UnitType & type) const
{
if (m_unitTypeData.find(type) == m_unitTypeData.end())
{
std::cout << "WARNING: Unit type not found: " << type.getName() << "\n";
if (!suppressWarnings)
{
std::cout << "WARNING: Unit type not found: " << type.getName() << "\n";
}
return m_unitTypeData.begin()->second;
}
......@@ -280,7 +374,10 @@ const TypeData & TechTree::getData(const CCUpgrade & type) const
{
if (m_upgradeData.find(type) == m_upgradeData.end())
{
std::cout << "WARNING: Upgrade not found: " << sc2::UpgradeIDToName(type) << "\n";
if (!suppressWarnings)
{
std::cout << "WARNING: Upgrade not found: " << sc2::UpgradeIDToName(type) << "\n";
}
return m_unitTypeData.begin()->second;
}
......@@ -301,4 +398,4 @@ const TypeData & TechTree::getData(const MetaType & type) const
BOT_ASSERT(false, "Can't getData this type: %s", type.getName().c_str());
return m_unitTypeData.begin()->second;
}
\ No newline at end of file
}
......@@ -24,23 +24,29 @@ struct TypeData
sc2::AbilityID warpAbility = 0; // the ability that creates this item via warp-in
std::vector<UnitType> whatBuilds; // any of these units can build the item
std::vector<UnitType> requiredUnits; // owning ONE of these is required to make
std::vector<CCUpgrade> requiredUpgrades; // having ALL of these is required to make
std::vector<sc2::UPGRADE_ID> requiredUpgrades; // having ALL of these is required to make
std::vector<UnitType> requiredAddons; // a unit of this type must be present next to the producer
sc2::AbilityID morphAbility = 0; // the ability which morphes the producer into this type
};
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 "TechTree.h"
#include "Util.h"
#include "CCBot.h"
#include "BuildType.h"
#include "Timer.hpp"
TechTree::TechTree(CCBot & bot)
: m_bot(bot)
{
}
void TechTree::onStart()
{
initUnitTypeData();
initUpgradeData();
}
void TechTree::initUnitTypeData()
{
m_upgradeData[0] = TypeData();
// Protoss Buildings unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_PYLON] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_PYLON, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_NEXUS] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_NEXUS, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_ASSIMILATOR, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_CYBERNETICSCORE, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY, sc2::UNIT_TYPEID::PROTOSS_WARPGATE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_DARKSHRINE, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FLEETBEACON, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_FORGE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FORGE, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_NEXUS }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_GATEWAY] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GATEWAY, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_NEXUS }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_STARGATE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARGATE, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_PHOTONCANNON] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_PHOTONCANNON, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSBAY, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSFACILITY, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TEMPLARARCHIVE, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TWILIGHTCOUNCIL, 0, { sc2::UNIT_TYPEID::PROTOSS_PROBE }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_WARPGATE] = { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_WARPGATE, 0, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, {}, { sc2::UPGRADE_ID::WARPGATERESEARCH } };
// Protoss Units unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_PROBE] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_PROBE, 0, { sc2::UNIT_TYPEID::PROTOSS_NEXUS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MOTHERSHIPCORE, 0, { sc2::UNIT_TYPEID::PROTOSS_NEXUS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ZEALOT] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZEALOT, sc2::ABILITY_ID::TRAINWARP_ZEALOT, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_SENTRY] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SENTRY, sc2::ABILITY_ID::TRAINWARP_SENTRY, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_STALKER] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_STALKER, sc2::ABILITY_ID::TRAINWARP_STALKER, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_HIGHTEMPLAR] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HIGHTEMPLAR, sc2::ABILITY_ID::TRAINWARP_HIGHTEMPLAR, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, { sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_DARKTEMPLAR] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DARKTEMPLAR, sc2::ABILITY_ID::TRAINWARP_DARKTEMPLAR, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, { sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ADEPT] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ADEPT, sc2::ABILITY_ID::TRAINWARP_ADEPT, { sc2::UNIT_TYPEID::PROTOSS_GATEWAY }, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_COLOSSUS] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_COLOSSUS, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_DISRUPTOR] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DISRUPTOR, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_WARPPRISM] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WARPPRISM, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_OBSERVER] = { sc2::Race::Protoss, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_OBSERVER, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_IMMORTAL] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_IMMORTAL, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_CARRIER] = { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CARRIER, 0, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ORACLE] = { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ORACLE, 0, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_PHOENIX] = { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_PHOENIX, 0, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_VOIDRAY] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VOIDRAY, 0, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_TEMPEST] = { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_TEMPEST, 0, { sc2::UNIT_TYPEID::PROTOSS_STARGATE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_INTERCEPTOR] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INTERCEPTORS, 0, { sc2::UNIT_TYPEID::PROTOSS_CARRIER }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::PROTOSS_ORACLESTASISTRAP] = { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STASISTRAP, 0, { sc2::UNIT_TYPEID::PROTOSS_ORACLE }, {}, {} };
// Terran Buildings m g s t unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_COMMANDCENTER, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, true, false, false, sc2::ABILITY_ID::BUILD_SUPPLYDEPOT, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_REFINERY] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_REFINERY, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_ARMORY] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ARMORY, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_FACTORY, sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BARRACKS] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BARRACKS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SENSORTOWER] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SENSORTOWER, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FACTORY] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FACTORY, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_BARRACKS, sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FUSIONCORE] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FUSIONCORE, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_STARPORT, sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_STARPORT] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARPORT, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_FACTORY, sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GHOSTACADEMY, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_BARRACKS, sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BUNKER] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BUNKER, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_BARRACKS, sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ENGINEERINGBAY, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_MISSILETURRET] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_MISSILETURRET, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_ORBITALCOMMAND, 0, { sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_PLANETARYFORTRESS, 0, { sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER }, {}, {} };
// Terran Addons m g s t unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BARRACKSREACTOR] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_BARRACKS, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_BARRACKS, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FACTORYREACTOR] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_FACTORY, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_FACTORY, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_STARPORTREACTOR] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_STARPORT, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB] = { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_STARPORT, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
// Terran Equivalent Buildings
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT];
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BARRACKS];
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER];
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_FACTORY];
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND];
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING] = m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_STARPORT];
// Terran Units m g s t unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SCV] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, true, false, false, false, false, sc2::ABILITY_ID::TRAIN_SCV, 0, { sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_GHOST] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_GHOST, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_MARAUDER] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARAUDER, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, { sc2::UNIT_TYPEID::TERRAN_TECHLAB, sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_MARINE] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARINE, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_REAPER] = { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_REAPER, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKS }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_HELLION] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HELLION, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_CYCLONE] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CYCLONE, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_SIEGETANK] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SIEGETANK, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, { sc2::UNIT_TYPEID::TERRAN_TECHLAB, sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_THOR] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_WIDOWMINE] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WIDOWMINE, 0, { sc2::UNIT_TYPEID::TERRAN_FACTORY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_NUKE] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NUKE, 0, { sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BANSHEE] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANSHEE, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, { sc2::UNIT_TYPEID::TERRAN_TECHLAB, sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_BATTLECRUISER] = { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BATTLECRUISER, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_LIBERATOR] = { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_LIBERATOR, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_VIKINGFIGHTER] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIKINGFIGHTER, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_RAVEN] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_RAVEN, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, { sc2::UNIT_TYPEID::TERRAN_TECHLAB, sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_MEDIVAC] = { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MEDIVAC, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORT }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::TERRAN_MULE] = { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, 0, { sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND }, {}, {} };
// Zerg Buildings m g s t unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_HATCHERY] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::BUILD_HATCHERY, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_EXTRACTOR] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, true, false, false, false, sc2::ABILITY_ID::BUILD_EXTRACTOR, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPAWNINGPOOL, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_HATCHERY, sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_EVOLUTIONCHAMBER, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_HATCHERY, sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_BANELINGNEST] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BANELINGNEST, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_HYDRALISKDEN, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INFESTATIONPIT, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_NYDUSCANAL] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSWORM, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSNETWORK, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_ROACHWARREN] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROACHWARREN, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_SPINECRAWLER] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPINECRAWLER, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_SPIRE] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPIRE, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_GREATERSPIRE] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_GREATERSPIRE, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_SPORECRAWLER] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPORECRAWLER, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ULTRALISKCAVERN, 0, { sc2::UNIT_TYPEID::ZERG_DRONE }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_LAIR] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_LAIR, 0, { sc2::UNIT_TYPEID::ZERG_HATCHERY }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_HIVE] = { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, true, false, sc2::ABILITY_ID::MORPH_HIVE, 0, { sc2::UNIT_TYPEID::ZERG_LAIR }, {}, {} };
// Zerg Units m g s t unit bld wrk rfn sup hall add
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_OVERLORD] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, true, false, false, sc2::ABILITY_ID::TRAIN_OVERLORD, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_BANELING] = { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANELING, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_BANELINGNEST }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_CORRUPTOR] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CORRUPTOR, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_DRONE] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DRONE, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, {}, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_HYDRALISK] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HYDRALISK, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, sc2::UNIT_TYPEID::ZERG_LURKERDENMP }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_INFESTOR] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_INFESTOR, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_MUTALISK] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MUTALISK, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_ROACH] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ROACH, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_ROACHWARREN }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_SWARMHOSTMP] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SWARMHOST, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_ULTRALISK] = { sc2::Race::Zerg, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ULTRALISK, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_VIPER] = { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIPER, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_ZERGLING] = { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZERGLING, 0, { sc2::UNIT_TYPEID::ZERG_LARVA }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_QUEEN] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_QUEEN, 0, { sc2::UNIT_TYPEID::ZERG_HATCHERY }, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_LARVA] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { 0 }, { 0 }, {} };
m_unitTypeData[sc2::UNIT_TYPEID::ZERG_EGG] = { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { 0 }, { 0 }, {} };
// Set the Mineral / Gas cost of each unit
for (auto & kv : m_unitTypeData)
{
if (kv.first == 0) { continue; }
auto & data = m_bot.Observation()->GetUnitTypeData();
kv.second.mineralCost = m_bot.Observation()->GetUnitTypeData()[kv.first].mineral_cost;
kv.second.gasCost = m_bot.Observation()->GetUnitTypeData()[kv.first].vespene_cost;
}
}
void TechTree::initUpgradeData()
{
// 0 data for null / error return
m_upgradeData[0] = TypeData();
// Terran Upgrades
m_upgradeData[sc2::UPGRADE_ID::BANSHEECLOAK] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEECLOAKINGFIELD, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BANSHEESPEED] = { sc2::Race::Terran, 200, 200, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEEHYPERFLIGHTROTORS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BATTLECRUISERENABLESPECIALIZATIONS]= { sc2::Race::Terran, 150, 150, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BATTLECRUISERWEAPONREFIT, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DRILLCLAWS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_DRILLINGCLAWS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HIGHCAPACITYBARRELS] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INFERNALPREIGNITER, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::HISECAUTOTRACKING] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HISECAUTOTRACKING, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::LIBERATORAGRANGEUPGRADE] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADVANCEDBALLISTICS, 0, { sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MAGFIELDLAUNCHERS] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MAGFIELDLAUNCHERS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::MEDIVACINCREASESPEEDBOOST] = { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HIGHCAPACITYFUELTANKS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEOSTEELFRAME] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEOSTEELFRAME, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PERSONALCLOAKING] = { sc2::Race::Terran, 150, 150, 0, 1920, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PERSONALCLOAKING, 0, { sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PUNISHERGRENADES] = { sc2::Race::Terran, 50, 50, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CONCUSSIVESHELLS, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENCORVIDREACTOR] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENCORVIDREACTOR, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::RAVENRECALIBRATEDEXPLOSIVES] = { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENRECALIBRATEDEXPLOSIVES, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::SHIELDWALL] = { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_COMBATSHIELD, 0, { sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::STIMPACK] = { sc2::Race::Terran, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_STIMPACK, 0, { sc2::UNIT_TYPEID::TERRAN_SCV }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANBUILDINGARMOR] = { sc2::Race::Terran, 150, 150, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSTRUCTUREARMORUPGRADE, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL1, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL2, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL3, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY }, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1] = { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2] = { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL3] = { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::TERRAN_ARMORY }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2} };
// Protoss Upgrades
m_upgradeData[sc2::UPGRADE_ID::ADEPTPIERCINGATTACK] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADEPTRESONATINGGLAIVES, 0, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::BLINKTECH] = { sc2::Race::Protoss, 150, 150, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BLINK, 0, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CARRIERLAUNCHSPEEDUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INTERCEPTORGRAVITONCATAPULT, 0, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHARGE] = { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHARGE, 0, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::DARKTEMPLARBLINKUPGRADE] = { sc2::Race::Protoss, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_SHADOWSTRIKE, 0, { sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EXTENDEDTHERMALLANCE] = { sc2::Race::Protoss, 200, 200, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_EXTENDEDTHERMALLANCE, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GRAVITICDRIVE] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICDRIVE, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OBSERVERGRAVITICBOOSTER] = { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICBOOSTER, 0, { sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PHOENIXRANGEUPGRADE] = { sc2::Race::Protoss, 150, 150, 0, 1440, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PHOENIXANIONPULSECRYSTALS, 0, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL1, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL2, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL3, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL2] = { sc2::Race::Protoss, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3] = { sc2::Race::Protoss, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, { sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL1, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL2, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL3, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1] = { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2] = { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL3] = { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1] = { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL1, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2] = { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL2, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL3] = { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL3, 0, { sc2::UNIT_TYPEID::PROTOSS_FORGE }, { sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::PSISTORMTECH] = { sc2::Race::Protoss, 200, 200, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PSISTORM, 0, { sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::WARPGATERESEARCH] = { sc2::Race::Protoss, 50, 50, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_WARPGATE, 0, { sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE }, {}, {} };
// Zerg Upgrades
m_upgradeData[sc2::UPGRADE_ID::BURROW] = { sc2::Race::Zerg, 100, 100, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BURROW, 0, { sc2::UNIT_TYPEID::ZERG_HATCHERY, sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CENTRIFICALHOOKS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CENTRIFUGALHOOKS, 0, { sc2::UNIT_TYPEID::ZERG_BANELINGNEST }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::CHITINOUSPLATING] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHITINOUSPLATING, 0, { sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEGROOVEDSPINES] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GROOVEDSPINES, 0, { sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::EVOLVEMUSCULARAUGMENTS] = { sc2::Race::Zerg, 150, 150, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MUSCULARAUGMENTS, 0, { sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::GLIALRECONSTITUTION] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GLIALREGENERATION, 0, { sc2::UNIT_TYPEID::ZERG_ROACHWARREN }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_upgradeData[sc2::UPGRADE_ID::INFESTORENERGYUPGRADE] = { sc2::Race::Zerg, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PATHOGENGLANDS, 0, { sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::NEURALPARASITE] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEURALPARASITE, 0, { sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::OVERLORDSPEED] = { sc2::Race::Zerg, 100, 100, 0, 960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PNEUMATIZEDCARAPACE, 0, { sc2::UNIT_TYPEID::ZERG_HATCHERY, sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::TUNNELINGCLAWS] = { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TUNNELINGCLAWS, 0, { sc2::UNIT_TYPEID::ZERG_ROACHWARREN }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL1, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL2, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL3, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, { sc2::UNIT_TYPEID::ZERG_HIVE }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL1, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2] = { sc2::Race::Zerg, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL2, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL3] = { sc2::Race::Zerg, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL3, 0, { sc2::UNIT_TYPEID::ZERG_SPIRE, sc2::UNIT_TYPEID::ZERG_GREATERSPIRE }, { sc2::UNIT_TYPEID::ZERG_HIVE }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2 } };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1] = { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL1, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2] = { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL2, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL3] = { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL3, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGATTACKSPEED] = { sc2::Race::Zerg, 200, 200, 0, 2080, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGADRENALGLANDS, 0, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGLINGMOVEMENTSPEED] = { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGMETABOLICBOOST, 0, { sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1] = { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL1, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, {}, {} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2] = { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL2, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_LAIR, sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1} };
m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL3] = { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL3, 0, { sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER }, { sc2::UNIT_TYPEID::ZERG_HIVE }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2} };
}
const TypeData & TechTree::getData(const sc2::UnitTypeID & type) const
{
if (m_unitTypeData.find(type) == m_unitTypeData.end())
{
//std::cout << "WARNING: Unit type not found: " << sc2::UnitTypeToName(type) << "\n";
return m_unitTypeData.at(0);
}
return m_unitTypeData.at(type);
}
const TypeData & TechTree::getData(const sc2::UpgradeID & type) const
{
if (m_upgradeData.find(type) == m_upgradeData.end())
{
//std::cout << "WARNING: Upgrade not found: " << sc2::UpgradeIDToName(type) << "\n";
return m_unitTypeData.at(0);
}
return m_upgradeData.at(type);
}
const TypeData & TechTree::getData(const BuildType & type) const
{
if (type.getBuildType() == BuildTypes::Unit)
{
return getData(type.getUnitTypeID());
}
else if (type.getBuildType() == BuildTypes::Upgrade)
{
return getData(type.getUpgradeID());
}
BOT_ASSERT(false, "Can't getData this type: %s", type.getName().c_str());
return m_unitTypeData.at(0);
}
#include "TechTreeImproved.h"
using json = nlohmann::json;
TechTreeImproved::TechTreeImproved() { }
sc2::UNIT_TYPEID string_to_id(const std::string & str)
{
return static_cast<sc2::UNIT_TYPEID>(std::stoi(str));
}
std::string id_to_string(int id)
{
return sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(id));
}
void add_requirement(ResearchDescription & description, json & requirement)
{
std::string type = requirement["type"];
if (type == "and")
{
for (auto & subrequirement : requirement["operands"])
{
add_requirement(description, subrequirement);
}
}
else if (type == "not")
{
// Ignore this. This is used for: "We cannot do upgrade X if upgrade X is already running somewhere."
}
else if (type == "unitCount")
{
if (requirement["state"] == "CompleteOnly")
{
for (auto & unit : requirement["unit"])
{
//std::cout << "Just building: " << sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(unit)) << " (" << unit << ")" << std::endl;
description.buildings_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else
{
std::cout << "Unexpected state: " << requirement["state"] << std::endl;
}
}
else if (type == "eq")
{
// TODO: Should we be more careful here?
sc2::UPGRADE_ID id = static_cast<sc2::UPGRADE_ID>(requirement["operands"][0]["upgrade"]);
int count = static_cast<int>(requirement["operands"][1]["value"]);
if (count == 1)
{
description.upgrades_needed.push_back(id);
}
}
}
void add_requirement(BuildDescription & description, json & requirement)
{
std::string type = requirement["type"];
if (type == "and")
{
for (auto & subrequirement : requirement["operands"])
{
add_requirement(description, subrequirement);
}
}
else if (type == "unitCount")
{
// Units that needs to be completed at the unit location -> Addons
if (requirement["state"] == "CompleteOnlyAtUnit")
{
for (auto & unit : requirement["unit"])
{
//std::cout << "Addon: " << sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(unit)) << " (" << unit << ")" << std::endl;
sc2::UNIT_TYPEID unit_typeid = static_cast<sc2::UNIT_TYPEID>(unit);
if (unit_typeid == sc2::UNIT_TYPEID::TERRAN_TECHLAB)
{
switch (description.producer_type)
{
case sc2::UNIT_TYPEID::TERRAN_BARRACKS:
unit_typeid = sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB;
break;
case sc2::UNIT_TYPEID::TERRAN_FACTORY:
unit_typeid = sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB;
break;
case sc2::UNIT_TYPEID::TERRAN_STARPORT:
unit_typeid = sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB;
break;
default:
std::wcout << "Unknown producer type for TECHLAB addon: " << sc2::UnitTypeToName(unit_typeid) << std::endl;
}
}
description.addons_needed.push_back(unit_typeid);
}
}
else if (requirement["state"] == "CompleteOnly")
{
for (auto & unit : requirement["unit"])
{
//std::cout << "Just building: " << sc2::UnitTypeToName(static_cast<sc2::UNIT_TYPEID>(unit)) << " (" << unit << ")" << std::endl;
description.buildings_needed.push_back(static_cast<sc2::UNIT_TYPEID>(unit));
}
}
else
{
//std::cout << "Unsupported" << std::endl;
//std::cout << requirement << std::endl;
}
}
}
void parse_build_description(BuildDescription & description, json & build_item)
{
description.result_type = static_cast<sc2::UNIT_TYPEID>(build_item["unit"]);
description.build_ability = static_cast<sc2::ABILITY_ID>(build_item["ability"]);
description.buildTime = static_cast<int>(build_item["time"]); // The time in seconds it takes to create the unit parsed from the json file
if (build_item.find("requires") != build_item.end())
{
//std::cout << "Building unit: " << id_to_string(build_item["unit"]) << " requires" << std::endl;
auto & requires = build_item["requires"][0];
add_requirement(description, requires);
}
}
void parse_research_item(ResearchDescription & description, json & research_item)
{
//std::cout << "Parsing " << research_item["upgradeName"] << std::endl;
description.result_type = static_cast<sc2::UPGRADE_ID>(research_item["upgrade"]);
description.ability_used = static_cast<sc2::ABILITY_ID>(research_item["ability"]);
if (research_item.find("requires") != research_item.end() && research_item["requires"].size() > 0)
{
auto & requires = research_item["requires"][0];
add_requirement(description, requires);
}
}
void TechTreeImproved::parse_unit(json::iterator it)
{
sc2::UNIT_TYPEID producer_id = string_to_id(it.key());
//std::string name = sc2::UnitTypeToName(producer_id);
if (it.value().find("builds") != it.value().end())
{
auto & builds = it.value()["builds"];
for (auto & build_item : builds)
{
BuildDescription description;
description.producer_type = producer_id;
parse_build_description(description, build_item);
if (result_to_data.count(description.result_type) > 0)
{
//std::cout << "Found more than one way to build " << sc2::UnitTypeToName(description.result_type) << " (" << (unsigned int) description.result_type << ")" << std::endl;
result_to_data[description.result_type].push_back(description);
}
else
{
result_to_data[description.result_type] = { description };
}
build_descriptions.push_back(description);
}
}
// TODO: Use the result from the call to find for actually looking up data later, instead of searching twice
if (it.value().find("researches") != it.value().end())
{
//std::cout << "Found upgrades on unit " << it.value()["name"] << std::endl;
for (auto & research_item : it.value()["researches"])
{
ResearchDescription description;
description.producer_type = producer_id;
parse_research_item(description, research_item);
if (upgrade_to_data.count(description.result_type))
{
upgrade_to_data[description.result_type].push_back(description);
}
else
{
upgrade_to_data[description.result_type] = { description };
}
research_descriptions.push_back(description);
}
}
if (it.value().find("morphs") != it.value().end())
{
for (auto & morph_item : it.value()["morphs"])
{
BuildDescription description;
description.producer_type = producer_id;
description.morph_ability = static_cast<sc2::ABILITY_ID>(morph_item["ability"]);
description.result_type = static_cast<sc2::UNIT_TYPEID>(morph_item["unit"]);
if (morph_item.find("requires") != morph_item.end())
{
for (auto & requirement : morph_item["requires"])
{
std::string type = requirement["type"];
if (type == "unitCount")
{
for (auto & unit : requirement["unit"])
{
sc2::UNIT_TYPEID unit_typeid = static_cast<sc2::UNIT_TYPEID>(unit);
description.buildings_needed.push_back(unit_typeid);
}
}
else if (type == "upgradeCount")
{
sc2::UPGRADE_ID upgrade_id = static_cast<sc2::UPGRADE_ID>(requirement["upgrade"]);
description.upgrades_needed.push_back(upgrade_id);
}
}
}
build_descriptions.push_back(description);
}
}
}
bool TechTreeImproved::LoadData() {
std::ifstream i("techtree.json");
if (!i.good())
{
std::wcerr << "File techtree.json cannot be found, information regarding addons and required buildings will not be up to date. Please put techtree.json in working directory." << std::endl;
return false;
}
// Parse the file's content
json j;
i >> j;
// Time to parse content of the JSON file
for (auto & race : j)
{
for (json::iterator it = race.begin(); it != race.end(); ++it)
{
parse_unit(it);
}
}
return true;
}
const std::vector<BuildDescription> & TechTreeImproved::HowToBuild(sc2::UnitTypeID unit) const
{
if (result_to_data.count(unit) > 0)
{
return result_to_data.at(unit);
}
else
{
std::cout << "No information about unit type " << sc2::UnitTypeToName(unit) << " (" << static_cast<int>(unit) << ")" << std::endl;
return empty_build;
}
}
const std::vector<ResearchDescription> & TechTreeImproved::HowToResearch(sc2::UpgradeID upgrade) const
{
if (upgrade_to_data.count(upgrade))
{
return upgrade_to_data.at(upgrade);
}
else
{
std::cout << "No information about upgrade type " << sc2::UpgradeIDToName(upgrade) << " (" << static_cast<int>(upgrade) << ")" << std::endl;
return empty_research;
}
}
#pragma once
#include "nlohmann/json.hpp"
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include "sc2api/sc2_typeenums.h"
struct BuildDescription
{
sc2::UNIT_TYPEID producer_type;
sc2::UNIT_TYPEID result_type;
sc2::AbilityID build_ability;
sc2::AbilityID morph_ability;
std::vector<sc2::UNIT_TYPEID> buildings_needed;
std::vector<sc2::UNIT_TYPEID> addons_needed;
std::vector<sc2::UPGRADE_ID> upgrades_needed;
int buildTime; // The time in seconds it takes to create the unit
};
struct ResearchDescription
{
sc2::UPGRADE_ID result_type;
sc2::UNIT_TYPEID producer_type;
sc2::AbilityID ability_used;
std::vector<sc2::UNIT_TYPEID> buildings_needed;
std::vector<sc2::UPGRADE_ID> upgrades_needed;
};
class TechTreeImproved
{
std::map<sc2::UNIT_TYPEID, std::vector<BuildDescription>> result_to_data;
std::map<sc2::UPGRADE_ID, std::vector<ResearchDescription>> upgrade_to_data;
std::vector<BuildDescription> build_descriptions;
std::vector<ResearchDescription> research_descriptions;
// If there is no BuildDescription for a given type, a reference to tihs list is returned.
const std::vector<BuildDescription> empty_build {};
const std::vector<ResearchDescription> empty_research {};
void parse_unit(nlohmann::json::iterator it);
public:
TechTreeImproved();
bool LoadData();
// Given a unit, how can we build it?
const std::vector<BuildDescription> & HowToBuild(sc2::UnitTypeID unit) const;
const std::vector<ResearchDescription> & HowToResearch(sc2::UpgradeID upgrade) const;
const std::vector<BuildDescription> & BuildDescriptions() const { return build_descriptions; }
const std::vector<ResearchDescription> & ResearchDescriptions() const { return research_descriptions; }
};
#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
......@@ -146,6 +154,16 @@ bool Unit::isFlying() const
#endif
}
std::vector<CCBuff> Unit::buffs() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
return m_unit->buffs;
#else
return m_unit->buffs();
#endif
}
bool Unit::isAlive() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
......@@ -226,7 +244,7 @@ void Unit::move(const CCPosition & targetPosition) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::MOVE, targetPosition);
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::GENERAL_MOVE, targetPosition);
#else
m_unit->move(targetPosition);
#endif
......@@ -236,7 +254,7 @@ void Unit::move(const CCTilePosition & targetPosition) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::MOVE, CCPosition((float)targetPosition.x, (float)targetPosition.y));
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::GENERAL_MOVE, CCPosition((float)targetPosition.x, (float)targetPosition.y));
#else
m_unit->move(CCPosition(targetPosition));
#endif
......@@ -259,47 +277,249 @@ void Unit::repair(const Unit & target) const
void Unit::build(const UnitType & buildingType, CCTilePosition pos) const
{
BOT_ASSERT(m_bot->Map().isConnected(getTilePosition(), pos), "Error: Build Position is not connected to worker");
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(buildingType).buildAbility, Util::GetPosition(pos));
#else
m_unit->build(buildingType.getAPIUnitType(), pos);
#endif
if (m_bot->Map().isConnected(getTilePosition(), pos))
{
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(buildingType).buildAbility, Util::GetPosition(pos));
}
else
{
printf("Warning! Cannot build at location (%d, %d) and therefore ignoring command.", pos.x, pos.y);
}
}
void Unit::buildTarget(const UnitType & buildingType, const Unit & target) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(buildingType).buildAbility, target.getUnitPtr());
#else
BOT_ASSERT(false, "buildTarget shouldn't be called for BWAPI bots");
#endif
}
void Unit::train(const UnitType & type) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(type).buildAbility);
#else
m_unit->train(type.getAPIUnitType());
#endif
}
void Unit::morph(const UnitType & type) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(type).buildAbility);
#else
m_unit->morph(type.getAPIUnitType());
#endif
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(type).morphAbility);
}
void Unit::research(sc2::UpgradeID upgrade) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
m_bot->Actions()->UnitCommand(m_unit, m_bot->Data(upgrade).buildAbility);
}
bool Unit::isConstructing(const UnitType & type) const
{
sc2::AbilityID buildAbility = m_bot->Data(type).buildAbility;
return (getUnitPtr()->orders.size() > 0) && (getUnitPtr()->orders[0].ability_id == buildAbility);
}
\ No newline at end of file
}
void Unit::ability(sc2::AbilityID ability) const
{
m_bot->Actions()->UnitCommand(getUnitPtr(), ability, false);
}
void Unit::ability(sc2::AbilityID ability, const sc2::Point2D& point) const
{
m_bot->Actions()->UnitCommand(getUnitPtr(), ability, point, false);
}
void Unit::ability(sc2::AbilityID ability, const Unit& target) const
{
m_bot->Actions()->UnitCommand(getUnitPtr(), ability, target.getUnitPtr(), false);
}
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;
// 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;
}
// 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
{
BOT_ASSERT(isValid(), "Unit is not valid");
if (getUnitPtr()->orders.size() > 0) {
if (getUnitPtr()->orders[0].target_unit_tag != sc2::NullTag) {
CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
if (m_bot->Observation()->GetUnit(t_id) == nullptr) {
return false;
}
Unit unit = m_bot->GetUnit(t_id);
return unit.isValid();
}
}
return false;
}
bool Unit::isBlip() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
#ifdef SC2API
return m_unit->is_blip;
#else
return m_unit->isBlip();
#endif
}
CCHealth Unit::getMaxHitPoints() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->health_max;
}
float Unit::getFacing() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->facing;
}
float Unit::getRadius() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->radius;
}
float Unit::getProgress() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
// If unit has order, return progress of first order
if (getUnitPtr()->orders.size() > 0) {
return getUnitPtr()->orders[0].progress;
}
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");
// If unit has order, return AbilityID of first order
if (getUnitPtr()->orders.size() > 0) {
return getUnitPtr()->orders[0].ability_id;
}
// return invalid AbilityID
return sc2::ABILITY_ID::INVALID;
}
void Unit::holdPosition() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::GENERAL_HOLDPOSITION);
}
void Unit::patrol(const CCPosition & targetPosition) const
{
BOT_ASSERT(isValid(), "Unit is not valid");
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::GENERAL_PATROL, targetPosition);
}
void Unit::stopDance() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
m_bot->Actions()->UnitCommand(m_unit, sc2::ABILITY_ID::STOP_DANCE);
}
/*
// Implementation by Dawid Abucewicz
bool Unit::isCarryingMinerals() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
std::vector<CCBuff> buffs = m_unit->buffs;
for (auto & b : buffs)
{
if (b.to_string() == "271" or b.to_string() == "272")
{
return true;
}
}
return false;
}
*/
int Unit::gasLeftInGeyser() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->vespene_contents;
}
int Unit::mineralsLeftInMineralfield() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->mineral_contents;
}
int Unit::getOwner() const
{
BOT_ASSERT(isValid(), "Unit is not valid");
return m_unit->owner;
}
// Implemented with Blizzard SC2 API
bool Unit::isCarryingGas() const
{
return sc2::IsCarryingVespene(*m_unit);
}
bool Unit::isCarryingMinerals() const
{
return sc2::IsCarryingMinerals(*m_unit);
}
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;
......@@ -33,6 +35,7 @@ public:
CCHealth getEnergy() const;
CCPlayer getPlayer() const;
CCUnitID getID() const;
std::vector< CCBuff > buffs() const;
float getBuildPercentage() const;
int getWeaponCooldown() const;
bool isCompleted() const;
......@@ -46,6 +49,31 @@ public:
bool isValid() const;
bool isTraining() const;
bool isConstructing(const UnitType & type) const;
bool isCarryingMinerals() const;
bool isBlip() const;
bool hasTarget() const;
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;
void stopDance() const;
float getFacing() const;
float getRadius() const;
/*
API extended summer 2020
*/
int gasLeftInGeyser() const;
int mineralsLeftInMineralfield() const;
int getOwner() const;
bool isCarryingGas() const;
float maxShields() const;
float maxEnergy() const;
void stop () const;
void attackUnit (const Unit & target) const;
......@@ -58,4 +86,8 @@ public:
void buildTarget (const UnitType & buildingType, const Unit & target) const;
void train (const UnitType & buildingType) const;
void morph (const UnitType & type) const;
void research (sc2::UpgradeID upgrade) const;
void ability (sc2::AbilityID ability) const;
void ability (sc2::AbilityID ability, const sc2::Point2D & point) const;
void ability (sc2::AbilityID ability, const Unit & target) 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
......@@ -84,8 +112,7 @@ bool UnitType::isCombatUnit() const
bool UnitType::isSupplyProvider() const
{
// TODO: Is this a bug?
return (supplyProvided() < 0) && !isResourceDepot();
return (supplyProvided() > 0) && !isResourceDepot();
}
bool UnitType::isResourceDepot() const
......@@ -113,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
......@@ -149,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
......@@ -161,10 +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_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
......@@ -188,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())
{
......@@ -214,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
......@@ -230,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
......@@ -248,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
......@@ -257,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
......@@ -266,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
......@@ -275,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
......@@ -284,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
......@@ -373,3 +592,63 @@ bool UnitType::isMorphedBuilding() const
m_type == BWAPI::UnitTypes::Zerg_Greater_Spire;
#endif
}
int UnitType::getMovementSpeed() const
{
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
{
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
{
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
{
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
{
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
{
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
......@@ -2,18 +2,26 @@
#include "Common.h"
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;
......@@ -22,6 +30,10 @@ public:
std::string getName() const;
CCRace getRace() const;
int getMovementSpeed() const;
int getSightRange() const;
sc2::UnitTypeID getRequiredStructure() const;
bool isValid() const;
bool isBuilding() const;
......@@ -37,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;
......@@ -46,6 +61,9 @@ public:
int gasPrice() const;
const std::vector<UnitType> & whatBuilds() const;
std::vector<sc2::UnitTypeID> getEquivalentUnits() const;
bool requiredAttached() const;
float getBuildTime() const;
static UnitType GetUnitTypeFromName(const std::string & name, IDABot & bot);
......
#include "WorkerManager.h"
#include "IDABot.h"
#include "Util.h"
#include "Building.h"
WorkerManager::WorkerManager(IDABot & bot)
: m_bot (bot)
, m_workerData (bot)
{
}
void WorkerManager::onStart()
{
}
void WorkerManager::onFrame()
{
m_workerData.updateAllWorkerData();
handleGasWorkers();
handleIdleWorkers();
drawResourceDebugInfo();
drawWorkerInformation();
m_workerData.drawDepotDebugInfo();
handleRepairWorkers();
}
void WorkerManager::setRepairWorker(Unit worker, const Unit & unitToRepair)
{
m_workerData.setWorkerJob(worker, WorkerJobs::Repair, unitToRepair);
}
void WorkerManager::stopRepairing(Unit worker)
{
m_workerData.setWorkerJob(worker, WorkerJobs::Idle);
}
void WorkerManager::handleGasWorkers()
{
// for each unit we have
for (auto & unit : m_bot.UnitInfo().getUnits(Players::Self))
{
// if that unit is a refinery
if (unit.getType().isRefinery() && unit.isCompleted())
{
// get the number of workers currently assigned to it
int numAssigned = m_workerData.getNumAssignedWorkers(unit);
// if it's less than we want it to be, fill 'er up
for (int i=0; i<(3-numAssigned); ++i)
{
auto gasWorker = getGasWorker(unit);
if (gasWorker.isValid())
{
m_workerData.setWorkerJob(gasWorker, WorkerJobs::Gas, unit);
}
}
}
}
}
void WorkerManager::handleIdleWorkers()
{
// for each of our workers
for (auto & worker : m_workerData.getWorkers())
{
if (!worker.isValid()) { continue; }
bool isIdle = worker.isIdle();
if (worker.isIdle() &&
(m_workerData.getWorkerJob(worker) != WorkerJobs::Build) &&
(m_workerData.getWorkerJob(worker) != WorkerJobs::Move) &&
(m_workerData.getWorkerJob(worker) != WorkerJobs::Scout))
{
m_workerData.setWorkerJob(worker, WorkerJobs::Idle);
}
// if it is idle
if (m_workerData.getWorkerJob(worker) == WorkerJobs::Idle)
{
setMineralWorker(worker);
}
}
}
void WorkerManager::handleRepairWorkers()
{
// TODO
}
Unit WorkerManager::getClosestMineralWorkerTo(const CCPosition & pos) const
{
Unit closestMineralWorker;
double closestDist = std::numeric_limits<double>::max();
// for each of our workers
for (auto & worker : m_workerData.getWorkers())
{
if (!worker.isValid()) { continue; }
// if it is a mineral worker
if (m_workerData.getWorkerJob(worker) == WorkerJobs::Minerals)
{
double dist = Util::DistSq(worker.getPosition(), pos);
if (!closestMineralWorker.isValid() || dist < closestDist)
{
closestMineralWorker = worker;
dist = closestDist;
}
}
}
return closestMineralWorker;
}
// set a worker to mine minerals
void WorkerManager::setMineralWorker(const Unit & unit)
{
// check if there is a mineral available to send the worker to
auto depot = getClosestDepot(unit);
// if there is a valid mineral
if (depot.isValid())
{
// update m_workerData with the new job
m_workerData.setWorkerJob(unit, WorkerJobs::Minerals, depot);
}
}
Unit WorkerManager::getClosestDepot(Unit worker) const
{
Unit closestDepot;
double closestDistance = std::numeric_limits<double>::max();
for (auto & unit : m_bot.UnitInfo().getUnits(Players::Self))
{
if (!unit.isValid()) { continue; }
if (unit.getType().isResourceDepot() && unit.isCompleted())
{
double distance = Util::Dist(unit, worker);
if (!closestDepot.isValid() || distance < closestDistance)
{
closestDepot = unit;
closestDistance = distance;
}
}
}
return closestDepot;
}
// other managers that need workers call this when they're done with a unit
void WorkerManager::finishedWithWorker(const Unit & unit)
{
if (m_workerData.getWorkerJob(unit) != WorkerJobs::Scout)
{
m_workerData.setWorkerJob(unit, WorkerJobs::Idle);
}
}
Unit WorkerManager::getGasWorker(Unit refinery) const
{
return getClosestMineralWorkerTo(refinery.getPosition());
}
void WorkerManager::setBuildingWorker(Unit worker, Building & b)
{
m_workerData.setWorkerJob(worker, WorkerJobs::Build, b.buildingUnit);
}
// gets a builder for BuildingManager to use
// if setJobAsBuilder is true (default), it will be flagged as a builder unit
// set 'setJobAsBuilder' to false if we just want to see which worker will build a building
Unit WorkerManager::getBuilder(Building & b, bool setJobAsBuilder) const
{
Unit builderWorker = getClosestMineralWorkerTo(Util::GetPosition(b.finalPosition));
// if the worker exists (one may not have been found in rare cases)
if (builderWorker.isValid() && setJobAsBuilder)
{
m_workerData.setWorkerJob(builderWorker, WorkerJobs::Build, b.builderUnit);
}
return builderWorker;
}
// sets a worker as a scout
void WorkerManager::setScoutWorker(Unit workerTag)
{
m_workerData.setWorkerJob(workerTag, WorkerJobs::Scout);
}
void WorkerManager::setCombatWorker(Unit workerTag)
{
m_workerData.setWorkerJob(workerTag, WorkerJobs::Combat);
}
void WorkerManager::drawResourceDebugInfo()
{
for (auto & worker : m_workerData.getWorkers())
{
if (!worker.isValid()) { continue; }
if (worker.isIdle())
{
m_bot.Map().drawText(worker.getPosition(), m_workerData.getJobCode(worker));
}
auto depot = m_workerData.getWorkerDepot(worker);
if (depot.isValid())
{
m_bot.Map().drawLine(worker.getPosition(), depot.getPosition());
}
}
}
void WorkerManager::drawWorkerInformation()
{
std::stringstream ss;
ss << "Workers: " << m_workerData.getWorkers().size() << "\n";
int yspace = 0;
for (auto & worker : m_workerData.getWorkers())
{
ss << m_workerData.getJobCode(worker) << " " << worker.getID() << "\n";
m_bot.Map().drawText(worker.getPosition(), m_workerData.getJobCode(worker));
}
m_bot.Map().drawTextScreen(0.75f, 0.2f, ss.str());
}
bool WorkerManager::isFree(Unit worker) const
{
return m_workerData.getWorkerJob(worker) == WorkerJobs::Minerals || m_workerData.getWorkerJob(worker) == WorkerJobs::Idle;
}
bool WorkerManager::isWorkerScout(Unit worker) const
{
return (m_workerData.getWorkerJob(worker) == WorkerJobs::Scout);
}
bool WorkerManager::isBuilder(Unit worker) const
{
return (m_workerData.getWorkerJob(worker) == WorkerJobs::Build);
}
int WorkerManager::getNumMineralWorkers()
{
return m_workerData.getWorkerJobCount(WorkerJobs::Minerals);
}
int WorkerManager::getNumGasWorkers()
{
return m_workerData.getWorkerJobCount(WorkerJobs::Gas);
}
#pragma once
#include "WorkerData.h"
class Building;
class IDABot;
class WorkerManager
{
IDABot & m_bot;
mutable WorkerData m_workerData;
Unit m_previousClosestWorker;
void setMineralWorker(const Unit & unit);
void handleIdleWorkers();
void handleGasWorkers();
void handleRepairWorkers();
public:
WorkerManager(IDABot & bot);
void onStart();
void onFrame();
void finishedWithWorker(const Unit & unit);
void drawResourceDebugInfo();
void drawWorkerInformation();
void setScoutWorker(Unit worker);
void setCombatWorker(Unit worker);
void setBuildingWorker(Unit worker, Building & b);
void setRepairWorker(Unit worker,const Unit & unitToRepair);
void stopRepairing(Unit worker);
int getNumMineralWorkers();
int getNumGasWorkers();
bool isWorkerScout(Unit worker) const;
bool isFree(Unit worker) const;
bool isBuilder(Unit worker) const;
Unit getBuilder(Building & b,bool setJobAsBuilder = true) const;
Unit getClosestDepot(Unit worker) const;
Unit getGasWorker(Unit refinery) const;
Unit getClosestMineralWorkerTo(const CCPosition & pos) const;
};
#include "Common.h"
#include "IDABot.h"
#include "MyAgent.h"
#include "Util.h"
#include "sc2utils/sc2_manage_process.h"
#include "sc2api/sc2_api.h"
#include "TechTreeImproved.h"
int main(int argc, char* argv[])
{
......@@ -22,7 +24,8 @@ int main(int argc, char* argv[])
sc2::Difficulty enemyDifficulty = sc2::Difficulty::Easy;
// Add the custom bot, it will control the players.
IDABot bot1;
MyAgent bot1;
//IDABot bot1;
//IDABot bot2;
// WARNING: Bot logic has not been thorougly tested on step sizes > 1
......
import unittest
import sys
sys.path.append('build/python-api-src')
from commandcenter import UnitTypeID, UNIT_TYPEID
class TestUnitType(unittest.TestCase):
def test_equality(self):
self.assertTrue(UNIT_TYPEID.TERRAN_ARMORY == UNIT_TYPEID.TERRAN_ARMORY)
def test_inequality(self):
self.assertFalse(UNIT_TYPEID.TERRAN_ARMORY != UNIT_TYPEID.TERRAN_ARMORY)
def test_convert_equality(self):
unit_typeid = UNIT_TYPEID.TERRAN_ARMORY
self.assertTrue(unit_typeid == UnitTypeID(unit_typeid))
self.assertTrue(UnitTypeID(unit_typeid) == unit_typeid)
self.assertFalse(UnitTypeID(unit_typeid) != unit_typeid)
if __name__ == '__main__':
unittest.main()