// STEP 2: ASSIGN WORKERS TO BUILDINGS WITHOUT THEM void BuildingManager::assignWorkersToUnassignedBuildings() { // for each building that doesn't have a builder, assign one for (Building & b : m_buildings) { if (b.status != BuildingStatus::Unassigned) { continue; } BOT_ASSERT(b.builderUnitTag == 0, "Error: Tried to assign a builder to a building that already had one "); if (m_debugMode) { printf("Assigning Worker To: %s", sc2::UnitTypeToName(b.type)); } // grab a worker unit from WorkerManager which is closest to this final position sc2::Point2D testLocation = getBuildingLocation(b); if (!m_bot.Map().isValid(testLocation)) { continue; } b.finalPosition = testLocation; // grab the worker unit from WorkerManager which is closest to this final position UnitTag builderUnitTag = m_bot.Workers().getBuilder(b); b.builderUnitTag = builderUnitTag; if (!b.builderUnitTag) { continue; } // reserve this building's space m_buildingPlacer.reserveTiles((int)b.finalPosition.x, (int)b.finalPosition.y, Util::GetUnitTypeWidth(b.type, m_bot), Util::GetUnitTypeHeight(b.type, m_bot)); b.status = BuildingStatus::Assigned; } }
// STEP 2: ASSIGN WORKERS TO BUILDINGS WITHOUT THEM void BuildingManager::assignWorkersToUnassignedBuildings() { // for each building that doesn't have a builder, assign one buildingData.begin(ConstructionData::Unassigned); while (buildingData.hasNextBuilding(ConstructionData::Unassigned)) { Building & b = buildingData.getNextBuilding(ConstructionData::Unassigned); if (debugMode) { BWAPI::Broodwar->printf("Assigning Worker To: %s", b.type.getName().c_str()); } // remove all refineries after 3, i don't know why this happens if (b.type.isRefinery() && (BWAPI::Broodwar->self()->allUnitCount(b.type) >= 3)) { buildingData.removeCurrentBuilding(ConstructionData::Unassigned); break; } // get the building location BWAPI::TilePosition testLocation = getBuildingLocation(b); // if we can't find a valid build location, we can't assign this building if (!testLocation.isValid()) { continue; } // set the final position of the building as this location b.finalPosition = testLocation; // grab a worker unit from WorkerManager which is closest to this final position BWAPI::Unit * workerToAssign = WorkerManager::Instance().getBuilder(b); // if the worker exists if (workerToAssign) { //BWAPI::Broodwar->printf("VALID WORKER BEING ASSIGNED: %d", workerToAssign->getID()); // TODO: special case of terran building whose worker died mid construction // send the right click command to the buildingUnit to resume construction // skip the buildingsAssigned step and push it back into buildingsUnderConstruction // set the worker we have assigned b.builderUnit = workerToAssign; // re-search for a building location with the builder unit ignored for space testLocation = getBuildingLocation(b); // hopefully this will not blow up if (!testLocation.isValid()) { continue; } // set the final position of the building b.finalPosition = testLocation; // reserve this space BuildingPlacer::Instance().reserveTiles(b.finalPosition, b.type.tileWidth(), b.type.tileHeight()); // this building has now been assigned buildingData.addBuilding(ConstructionData::Assigned, b); // remove this Building buildingData.removeCurrentBuilding(ConstructionData::Unassigned); } } }