// UnitType constructor ActionTypeData::ActionTypeData(BWAPI::UnitType t, const ActionID id) : type (UnitType) , unit (t) , raceID (GetRaceID(t.getRace())) , actionID (id) , mineralPriceVal (t.mineralPrice() * Constants::RESOURCE_SCALE) , gasPriceVal (t.gasPrice() * Constants::RESOURCE_SCALE) , supplyRequiredVal (t.supplyRequired()) , supplyProvidedVal (t.supplyProvided()) , buildTimeVal (t.buildTime()) , numberProduced (1) , name (t.getName()) , metaName (t.getName()) , building (t.isBuilding()) , worker (t.isWorker()) , refinery (t.isRefinery()) , resourceDepot (t.isResourceDepot()) , supplyProvider (t.supplyProvided() > 0 && !t.isResourceDepot()) , canProduceBool (t.isBuilding() && t.canProduce()) , canAttackBool (t.canAttack()) , whatBuildsUnitType (t.whatBuilds().first) , addon (t.isAddon()) , morphed (false) , reqAddon (false) , reqAddonID (0) { if (t == BWAPI::UnitTypes::Zerg_Zergling || t == BWAPI::UnitTypes::Zerg_Scourge) { numberProduced = 2; } if (t == BWAPI::UnitTypes::Zerg_Lair || t == BWAPI::UnitTypes::Zerg_Hive || t == BWAPI::UnitTypes::Zerg_Greater_Spire || t == BWAPI::UnitTypes::Zerg_Lurker || t == BWAPI::UnitTypes::Zerg_Guardian || t == BWAPI::UnitTypes::Zerg_Sunken_Colony || t == BWAPI::UnitTypes::Zerg_Spore_Colony) { morphed = true; } setShortName(); }
BWAPI::Unit ProductionManager::getProducer(MetaType t, BWAPI::Position closestTo) { // get the type of unit that builds this BWAPI::UnitType producerType = t.whatBuilds(); // make a set of all candidate producers BWAPI::Unitset candidateProducers; for (auto & unit : BWAPI::Broodwar->self()->getUnits()) { UAB_ASSERT(unit != nullptr, "Unit was null"); // reasons a unit can not train the desired type if (unit->getType() != producerType) { continue; } if (!unit->isCompleted()) { continue; } if (unit->isTraining()) { continue; } if (unit->isLifted()) { continue; } if (!unit->isPowered()) { continue; } // if the type is an addon, some special cases if (t.getUnitType().isAddon()) { // if the unit already has an addon, it can't make one if (unit->getAddon() != nullptr) { continue; } // if we just told this unit to build an addon, then it will not be building another one // this deals with the frame-delay of telling a unit to build an addon and it actually starting to build if (unit->getLastCommand().getType() == BWAPI::UnitCommandTypes::Build_Addon && (BWAPI::Broodwar->getFrameCount() - unit->getLastCommandFrame() < 10)) { continue; } bool isBlocked = false; // if the unit doesn't have space to build an addon, it can't make one BWAPI::TilePosition addonPosition(unit->getTilePosition().x + unit->getType().tileWidth(), unit->getTilePosition().y + unit->getType().tileHeight() - t.getUnitType().tileHeight()); BWAPI::Broodwar->drawBoxMap(addonPosition.x*32, addonPosition.y*32, addonPosition.x*32 + 64, addonPosition.y*32 + 64, BWAPI::Colors::Red); for (int i=0; i<unit->getType().tileWidth() + t.getUnitType().tileWidth(); ++i) { for (int j=0; j<unit->getType().tileHeight(); ++j) { BWAPI::TilePosition tilePos(unit->getTilePosition().x + i, unit->getTilePosition().y + j); // if the map won't let you build here, we can't build it if (!BWAPI::Broodwar->isBuildable(tilePos)) { isBlocked = true; BWAPI::Broodwar->drawBoxMap(tilePos.x*32, tilePos.y*32, tilePos.x*32 + 32, tilePos.y*32 + 32, BWAPI::Colors::Red); } // if there are any units on the addon tile, we can't build it BWAPI::Unitset uot = BWAPI::Broodwar->getUnitsOnTile(tilePos.x, tilePos.y); if (uot.size() > 0 && !(uot.size() == 1 && *(uot.begin()) == unit)) { isBlocked = true;; BWAPI::Broodwar->drawBoxMap(tilePos.x*32, tilePos.y*32, tilePos.x*32 + 32, tilePos.y*32 + 32, BWAPI::Colors::Red); } } } if (isBlocked) { continue; } } // if the type requires an addon and the producer doesn't have one typedef std::pair<BWAPI::UnitType, int> ReqPair; for (const ReqPair & pair : t.getUnitType().requiredUnits()) { BWAPI::UnitType requiredType = pair.first; if (requiredType.isAddon()) { if (!unit->getAddon() || (unit->getAddon()->getType() != requiredType)) { continue; } } } // if we haven't cut it, add it to the set of candidates candidateProducers.insert(unit); } return getClosestUnitToPosition(candidateProducers, closestTo); }
BWAPI::UnitInterface* BuildingManager::getAddonProducer(MetaType t) { // get the type of unit that builds this BWAPI::UnitType producerType = t.whatBuilds(); for (BWAPI::UnitInterface* unit : BWAPI::Broodwar->self()->getUnits()) { // reasons a unit can not train the desired type if (unit->getType() != producerType) { continue; } if (!unit->isCompleted()) { continue; } if (unit->isTraining()) { continue; } if (unit->isLifted()) { continue; } if (!unit->isPowered()) { continue; } // if the type is an addon, some special cases if (t.getUnitType().isAddon()) { // if the unit already has an addon, it can't make one if (unit->getAddon() != NULL) { continue; } // if the unit doesn't have space to build an addon, it can't make one /*BWAPI::TilePosition addonPosition = unit->getTilePosition() + BWAPI::TilePosition(unit->getType().tileWidth(), unit->getType().tileHeight()-t.unitType.tileHeight()); BWAPI::Broodwar->drawBoxMap(addonPosition.x*32, addonPosition.y*32, addonPosition.x*32 + 64, addonPosition.y*32 + 64, BWAPI::Colors::Blue); for (int i=0; i<=unit->getType().tileWidth(); ++i) { for (int j=0; j<=unit->getType().tileHeight(); ++j) { BWAPI::TilePosition tilePos = addonPosition + BWAPI::TilePosition(i, j); // if the map won't let you build here, we can't build it if (!BWAPI::Broodwar->isBuildable(tilePos)) { continue; } // if there are any units on the addon tile, we can't build it if (BWAPI::Broodwar->getUnitsOnTile(tilepos.x, tilepos.y).size() > 0) { continue; } } }*/ } // if the type requires an addon and the producer doesn't have one typedef std::pair<BWAPI::UnitType, int> ReqPair; for (const ReqPair & pair : t.getUnitType().requiredUnits()) { BWAPI::UnitType requiredType = pair.first; if (requiredType.isAddon()) { if (!unit->getAddon() || (unit->getAddon()->getType() != requiredType)) { continue; } } } // if we haven't cut it, add it to the set of candidates BWAPI::Broodwar->printf("Found an addon producer"); return unit; } return NULL; }