// selects which units will be scouting // currently only selects the worker scout after first pylon built // this does NOT take that worker away from worker manager, but it still works // TODO: take this worker away from worker manager in a clever way void GameCommander::setScoutUnits() { // if we have just built our first suply provider, set the worker to a scout if (numWorkerScouts == 0) { // get the first supply provider we come across in our units, this should be the first one we make BWAPI::UnitInterface* supplyProvider = getFirstSupplyProvider(); // if it exists if (supplyProvider) { // grab the closest worker to the supply provider to send to scout BWAPI::UnitInterface* workerScout = getClosestWorkerToTarget(supplyProvider->getPosition()); // if we find a worker (which we should) add it to the scout vector if (workerScout) { numWorkerScouts++; scoutUnits.insert(workerScout); assignedUnits.insert(workerScout); WorkerManager::Instance().setScoutWorker(workerScout); } } } }
void WorkerManager::updateWorkerStatus() { // for each of our Workers for (BWAPI::UnitInterface* worker : workerData.getWorkers()) { if (!worker->isCompleted()) { continue; } // if it's idle if (worker->isIdle() && (workerData.getWorkerJob(worker) != WorkerData::Build) && (workerData.getWorkerJob(worker) != WorkerData::Move) && (workerData.getWorkerJob(worker) != WorkerData::Scout)) { //printf("Worker %d set to idle", worker->getID()); // set its job to idle workerData.setWorkerJob(worker, WorkerData::Idle, NULL); } // if its job is gas if (workerData.getWorkerJob(worker) == WorkerData::Gas) { BWAPI::UnitInterface* refinery = workerData.getWorkerResource(worker); // if the refinery doesn't exist anymore if (!refinery || !refinery->exists() || refinery->getHitPoints() <= 0) { setMineralWorker(worker); } } } }
void WorkerManager::drawResourceDebugInfo() { if (!Config::Debug::DrawResourceInfo) { return; } for (BWAPI::UnitInterface* worker : workerData.getWorkers()) { UAB_ASSERT(worker != NULL, "Worker was null"); char job = workerData.getJobCode(worker); BWAPI::Position pos = worker->getTargetPosition(); BWAPI::Broodwar->drawTextMap(worker->getPosition().x, worker->getPosition().y - 5, "\x07%c", job); BWAPI::Broodwar->drawLineMap(worker->getPosition().x, worker->getPosition().y, pos.x, pos.y, BWAPI::Colors::Cyan); BWAPI::UnitInterface* depot = workerData.getWorkerDepot(worker); if (depot) { BWAPI::Broodwar->drawLineMap(worker->getPosition().x, worker->getPosition().y, depot->getPosition().x, depot->getPosition().y, BWAPI::Colors::Orange); } } }
void WorkerData::drawDepotDebugInfo() { for (BWAPI::UnitInterface* depot : depots) { int x = depot->getPosition().x - 64; int y = depot->getPosition().y - 32; if (Config::Debug::DrawWorkerInfo) BWAPI::Broodwar->drawBoxMap(x-2, y-1, x+75, y+14, BWAPI::Colors::Black, true); if (Config::Debug::DrawWorkerInfo) BWAPI::Broodwar->drawTextMap(x, y, "\x04 Workers: %d", getNumAssignedWorkers(depot)); std::vector<BWAPI::UnitInterface*> minerals = getMineralPatchesNearDepot(depot); for (size_t m(0); m<minerals.size(); ++m) { BWAPI::UnitInterface* mineral = minerals[m]; int x = mineral->getPosition().x; int y = mineral->getPosition().y; if (workersOnMineralPatch.find(mineral) != workersOnMineralPatch.end()) { //if (Config::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawBoxMap(x-2, y-1, x+75, y+14, BWAPI::Colors::Black, true); //if (Config::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawTextMap(x, y, "\x04 Workers: %d", workersOnMineralPatch[mineral]); } } } }
void GameCommander::setScoutUnits() { // if we haven't set our first worker scout, try and do it if (!workerScoutSet) { BWAPI::UnitInterface* supplyProvider = getFirstSupplyProvider(); // if it exists if (supplyProvider) { // grab the closest worker to the supply provider to send to scout BWAPI::UnitInterface* workerScout = getClosestWorkerToTarget(supplyProvider->getPosition()); // if we find a worker (which we should) add it to the scout vector if (workerScout) { workerScoutSet = true; scoutUnits.insert(workerScout); assignedUnits.insert(workerScout); WorkerManager::Instance().setScoutWorker(workerScout); } } } else { // we have previously set a worker scout, so go through our units to find him and if he exists put him in the scout squad BWAPI::UnitInterface * workerScout = WorkerManager::Instance().getWorkerScout(); if (workerScout) { scoutUnits.insert(workerScout); } } }
void ScoutManager::update(const std::set<BWAPI::UnitInterface*> & scoutUnits) { if (scoutUnits.size() == 1) { BWAPI::UnitInterface* scoutUnit = *scoutUnits.begin(); if (scoutUnit->getType().isWorker()) { if (scoutUnit != workerScout) { numWorkerScouts++; workerScout = scoutUnit; } } } moveScouts(); }
void ProductionManager::performCommand(BWAPI::UnitCommandType t) { // if it is a cancel construction, it is probably the extractor trick if (t == BWAPI::UnitCommandTypes::Cancel_Construction) { BWAPI::UnitInterface* extractor = NULL; for (BWAPI::UnitInterface* unit : BWAPI::Broodwar->self()->getUnits()) { if (unit->getType() == BWAPI::UnitTypes::Zerg_Extractor) { extractor = unit; } } if (extractor) { extractor->cancelConstruction(); } } }
// calculates whether or not to regroup bool Squad::needsToRegroup() { if (!Config::Micro::UseSparcraftSimulation) { return false; } // if we are not attacking, never regroup if (units.empty() || (order.type != SquadOrder::Attack)) { regroupStatus = std::string("\x04 No combat units available"); return false; } BWAPI::UnitInterface* unitClosest = unitClosestToEnemy(); if (!unitClosest) { regroupStatus = std::string("\x04 No closest unit"); return false; } SparCraft::ScoreType score = 0; //do the SparCraft Simulation! CombatSimulation sim; sim.setCombatUnits(unitClosest->getPosition(), Config::Micro::CombatRegroupRadius + InformationManager::Instance().lastFrameRegroup * 300); score = sim.simulateCombat(); // if we are DT rushing and we haven't lost a DT yet, no retreat! if (Config::Strategy::StrategyName == "Protoss_DTRush" && (BWAPI::Broodwar->self()->deadUnitCount(BWAPI::UnitTypes::Protoss_Dark_Templar) == 0)) { regroupStatus = std::string("\x04 DARK TEMPLAR HOOOOO!"); return false; } bool retreat = score < 0; int switchTime = 100; bool waiting = false; // we should not attack unless 5 seconds have passed since a retreat if (retreat != lastRetreatSwitchVal) { if (!retreat && (BWAPI::Broodwar->getFrameCount() - lastRetreatSwitch < switchTime)) { waiting = true; retreat = lastRetreatSwitchVal; } else { waiting = false; lastRetreatSwitch = BWAPI::Broodwar->getFrameCount(); lastRetreatSwitchVal = retreat; } } if (retreat) { regroupStatus = std::string("\x04 Retreat - simulation predicts defeat"); } else { regroupStatus = std::string("\x04 Attack - simulation predicts success"); } return retreat; }
// When the next item in the queue is a building, this checks to see if we should move to it // This function is here as it needs to access prodction manager's reserved resources info void ProductionManager::predictWorkerMovement(const Building & b, int timeLimitMS) { // get a possible building location for the building if (!haveLocationForThisBuilding) { try { predictedTilePosition = BuildingManager::Instance().getBuildingLocation(b, timeLimitMS); } catch (std::runtime_error &) { //Logger::LogAppendToFile(UAB_LOGFILE, "Timed out in predict movement: %s frame:%d\n", e.what(), // BWAPI::Broodwar->getFrameCount()); return; } } if (predictedTilePosition.isValid()) { haveLocationForThisBuilding = true; } else { return; } // draw a box where the building will be placed int x1 = predictedTilePosition.x * 32; int x2 = x1 + (b.type.tileWidth()) * 32; int y1 = predictedTilePosition.y * 32; int y2 = y1 + (b.type.tileHeight()) * 32; if (Options::Debug::DRAW_UALBERTABOT_DEBUG) { BWAPI::Broodwar->drawBoxMap(x1, y1, x2, y2, BWAPI::Colors::Blue, false); } // where we want the worker to walk to BWAPI::Position walkToPosition = BWAPI::Position(x1 + (b.type.tileWidth()/2)*32, y1 + (b.type.tileHeight()/2)*32); // compute how many resources we need to construct this building int mineralsRequired = std::max(0, b.type.mineralPrice() - getFreeMinerals()); int gasRequired = std::max(0, b.type.gasPrice() - getFreeGas()); // get a candidate worker to move to this location BWAPI::UnitInterface* moveWorker = WorkerManager::Instance().getMoveWorker(walkToPosition); // Conditions under which to move the worker: // - there's a valid worker to move // - we haven't yet assigned a worker to move to this location // - the build position is valid // - we will have the required resources by the time the worker gets there if (moveWorker && haveLocationForThisBuilding && !assignedWorkerForThisBuilding && (predictedTilePosition != BWAPI::TilePositions::None) && WorkerManager::Instance().willHaveResources(mineralsRequired, gasRequired, moveWorker->getDistance(walkToPosition)) ) { // we have assigned a worker assignedWorkerForThisBuilding = true; // tell the worker manager to move this worker WorkerManager::Instance().setMoveWorker(mineralsRequired, gasRequired, walkToPosition); } }