// this function will check to see if all preconditions are met and then create a unit void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item) { if (!producer) { return; } MetaType t = item.metaType; // if we're dealing with a building if (t.isUnit() && t.getUnitType().isBuilding() && t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair && t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive && t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire && !t.getUnitType().isAddon()) { // send the building task to the building manager if (t.getUnitType() == BWAPI::UnitTypes::Terran_Bunker) { BWAPI::TilePosition tp = BWAPI::TilePosition(BWTA::getNearestChokepoint(BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation()))->getCenter()); BuildingManager::Instance().addBuildingTask(t.getUnitType(), tp, item.isGasSteal); } else { BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal); } } else if (t.getUnitType().isAddon()) { //BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight()); producer->buildAddon(t.getUnitType()); } // if we're dealing with a non-building unit else if (t.isUnit()) { // if the race is zerg, morph the unit if (t.getUnitType().getRace() == BWAPI::Races::Zerg) { producer->morph(t.getUnitType()); // if not, train the unit } else { producer->train(t.getUnitType()); } } // if we're dealing with a tech research else if (t.isTech()) { producer->research(t.getTechType()); } else if (t.isUpgrade()) { //Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n"); producer->upgrade(t.getUpgradeType()); } else { } }
void ConstructionManager::update() { std::set<BWAPI::Unit*> myPlayerUnits = SelectAll()(isCompleted)(GetAddon,(BWAPI::Unit*)NULL).not(isCarryingMinerals,isCarryingGas,isGatheringGas); //iterate through all the builder types for(std::map<BWAPI::UnitType,std::set<Building*> >::iterator i=this->buildingsNeedingBuilders.begin();i!=this->buildingsNeedingBuilders.end();i++) { if (!i->second.empty()) //if its empty, we don't really need builders of this type { for(std::set<BWAPI::Unit*>::iterator u = myPlayerUnits.begin(); u != myPlayerUnits.end(); u++) { //if this unit is completed and the right type, and doesn't have an addon, and we aren't already using it if ((*u)->getType()==i->first && this->builders.find(*u)==this->builders.end()) { //bid value depends on distance - we like closer builders better double min_dist=1000000; for(std::set<Building*>::iterator b = i->second.begin(); b != i->second.end(); b++) { double dist = (*u)->getPosition().getDistance((*b)->position); if (dist < min_dist) min_dist = dist; } if (min_dist < 10) min_dist = 10; if (min_dist > 256*32 + 10) min_dist = 256*32 + 10; double bid = 80 - (min_dist - 10)/(256*32)*60; //if this isn't a worker, we don't care about distance if (!(*u)->getType().isWorker()) arbitrator->setBid(this, *u, 80); else arbitrator->setBid(this, *u, bid); } } } } std::list<Building>::iterator i_next; int index=0; //iterate through all the incomplete buildings for(std::list<Building>::iterator i=this->incompleteBuildings.begin();i!=this->incompleteBuildings.end();i=i_next) { index++; i_next=i; i_next++; Building* b = &(*i); if (!b->started && b->buildingUnit!=NULL) //buildingUnit exists, so we've started actual construction { startedCount[b->type]++; b->started=true; } if (b->type.isAddon()) //if the type is an addon { if (b->builderUnit!=NULL) b->buildingUnit=b->builderUnit->getAddon(); //set buildingUnit to the addon (whether the addon exists or not) BWAPI::Unit* u = b->builderUnit; BWAPI::Unit* s = b->buildingUnit; if (s!=NULL && s->isCompleted()) //if the building exists and is completed { startedCount[b->type]--; plannedCount[b->type]--; if (u != NULL) { this->builders.erase(u); arbitrator->removeBid(this,u); } this->placer->freeTiles(b->tilePosition, 4,3); this->placer->freeTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2); //If the building is complete, we can forget about it. this->incompleteBuildings.erase(i); } else //building either does not exist, or is incomplete { if (BWAPI::Broodwar->canMake(NULL,b->type)) { if (u == NULL) //if we don't have a builder, ask for one and wait for it to be offered buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b); else { if (u->getAddon() == NULL) //if the addon does not exist yet { if (u->isLifted()) //if the builder is lifted, find somehwere to land { if (BWAPI::Broodwar->getFrameCount()>b->lastOrderFrame+BWAPI::Broodwar->getLatency()*2) { if (!this->placer->canBuildHereWithSpace(b->tilePosition,b->type)) { this->placer->freeTiles(b->tilePosition, 4,3); this->placer->freeTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2); b->tilePosition=placer->getBuildLocationNear(b->tilePosition,*b->type.whatBuilds().first); this->placer->reserveTiles(b->tilePosition, 4,3); this->placer->reserveTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2); } u->land(b->tilePosition); b->lastOrderFrame = BWAPI::Broodwar->getFrameCount(); } } else { if (u->isTraining()) //if the builder is training, cancel it - we have control over the builder { u->cancelTrain(); } else { if (u->getTilePosition()!=b->tilePosition) //we may need to lift to find a build site with enough space for an add-on { //b->tilePosition is set in onOffer() u->lift(); b->lastOrderFrame = BWAPI::Broodwar->getFrameCount(); } else //otherwise, we may be in a good spot to make the add-on { //check to see if we can build here bool buildable=true; for(int x=b->tilePosition.x()+4;x<b->tilePosition.x()+6;x++) for(int y=b->tilePosition.y()+1;y<b->tilePosition.y()+3;y++) if (!this->placer->buildable(x,y) || BWAPI::Broodwar->hasCreep(x,y)) buildable=false; if (buildable) //if so, start making the add-on { u->buildAddon(b->type); } else { //otherwise, lift up (once we are lifted we will look for a valid spot to land and build) u->lift(); b->lastOrderFrame = BWAPI::Broodwar->getFrameCount(); } } } } } } } } } else //if the type is a normal building (not an addon) { if (b->tilePosition==BWAPI::TilePositions::None) //if we don't have a build location yet { if ((BWAPI::Broodwar->getFrameCount()+index)%25==0) { //get a build location near the goal position b->tilePosition = this->placer->getBuildLocationNear(b->goalPosition, b->type); if (b->tilePosition!=BWAPI::TilePositions::None) { b->position = BWAPI::Position(b->tilePosition.x()*32 + b->type.tileWidth()*16, b->tilePosition.y()*32 + b->type.tileHeight()*16); this->placer->reserveTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight()); } } //if we didn't find a build location yet, or cannot make the building, skip this building for now if (b->tilePosition==BWAPI::TilePositions::None) continue; } //if the builder dies, set it to null if (b->builderUnit!=NULL && !b->builderUnit->exists()) b->builderUnit=NULL; //if the building dies, or isn't the right type, set it to null if (b->buildingUnit!=NULL && (!b->buildingUnit->exists() || b->buildingUnit->getType()!=b->type)) b->buildingUnit=NULL; if (b->buildingUnit == NULL) //if we don't have a building yet, look for it { //look at the units on the tile to see if it exists yet std::set<BWAPI::Unit*> unitsOnTile = BWAPI::Broodwar->unitsOnTile(b->tilePosition.x(), b->tilePosition.y()); for(std::set<BWAPI::Unit*>::iterator t = unitsOnTile.begin(); t != unitsOnTile.end(); t++) if ((*t)->getType() == b->type && !(*t)->isLifted()) { //we found the building b->buildingUnit = *t; break; } //maybe the builder _is_ the building! (Zerg) if (b->buildingUnit == NULL && b->builderUnit!=NULL && b->builderUnit->getType().isBuilding()) { //we found the building b->buildingUnit = b->builderUnit; } } BWAPI::Unit* u = b->builderUnit; BWAPI::Unit* s = b->buildingUnit; if (s != NULL && s->isCompleted()) //if the building is completed, we're done { startedCount[b->type]--; plannedCount[b->type]--; if (u != NULL) { this->builders.erase(u); arbitrator->removeBid(this,u); } this->placer->freeTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight()); //If the building is complete, we can forget about it. this->incompleteBuildings.erase(i); } else //otherwise, it doesn't exist or is incomplete { if (s == NULL) //if the building doesn't even exist { if (u == NULL) //ask for a builder if we don't have one yet buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b); else //if we have a worker { if (!u->isConstructing()) //if the worker isn't constructing { double distance = u->getPosition().getDistance(b->position); if (distance > 100) //if its too far away, tell it to go to the build site u->rightClick(b->position); else //if its close enough, tell it to build if (BWAPI::Broodwar->canBuildHere(u, b->tilePosition, b->type)) //if we can build here, tell the worker to build { if (BWAPI::Broodwar->canMake(u, b->type)) u->build(b->tilePosition, b->type); } else //if we cannot build here, we need to find another build site (reset the tilePosition) { this->placer->freeTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight()); b->tilePosition = BWAPI::TilePositions::None; b->position = BWAPI::Positions::None; } } } } else //if the building does exist { if (b->type.getRace() != BWAPI::Races::Terran) //if its not terran, we can forget about the builder (i.e. probe is not needed to finish construction) { if (u != NULL) { this->builders.erase(u); arbitrator->removeBid(this, u); b->builderUnit = NULL; u = b->builderUnit; } } else { //if the buildind is terran, the worker may have been killed if (u == NULL) //looks like the worker was killed, or revoked. In either case we need to ask for another worker to finish our building buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b); else { //we have a worker, so lets rightClick it on the incomplete building so it can resume construction if (BWAPI::Broodwar->getFrameCount()%(4*BWAPI::Broodwar->getLatency())==0) { if (!u->isConstructing() || !s->isBeingConstructed()) { //right click builder on building u->rightClick(s); //also right click building on builder for good luck! :D s->rightClick(u); } } } } } } } } }
// this function will check to see if all preconditions are met and then create a unit void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item) { if (!producer) { return; } MetaType t = item.metaType; // if we're dealing with a building if (t.isUnit() && t.getUnitType().isBuilding() && t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair && t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive && t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire && t.getUnitType() != BWAPI::UnitTypes::Zerg_Sunken_Colony && !t.getUnitType().isAddon()) { // send the building task to the building manager BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal); } else if (t.getUnitType().isAddon()) { //BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight()); producer->buildAddon(t.getUnitType()); } // if we're dealing with a non-building unit else if (t.isUnit()) { // if the race is zerg, morph the unit if (t.getUnitType().getRace() == BWAPI::Races::Zerg) { producer->morph(t.getUnitType()); if (t.getUnitType() == BWAPI::UnitTypes::Zerg_Overlord) { _overlordTimer = BWAPI::Broodwar->getFrameCount() + t.getUnitType().buildTime() + 35; } // if not, train the unit } else { producer->train(t.getUnitType()); } } // if we're dealing with a tech research else if (t.isTech()) { producer->research(t.getTechType()); } else if (t.isUpgrade()) { //Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n"); if (t.getUpgradeType() == BWAPI::UpgradeTypes::Muscular_Augments) { muscBuildTimer = BWAPI::Broodwar->getFrameCount() + t.getUpgradeType().upgradeTime(); muscBuild = true; } producer->upgrade(t.getUpgradeType()); } else { } }
// this function will check to see if all preconditions are met and then create a unit void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item) { if (!producer) { return; } MetaType t = item.metaType; // if we're dealing with a building if (t.isUnit() && t.getUnitType().isBuilding() && t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair && t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive && t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire && t.getUnitType() != BWAPI::UnitTypes::Zerg_Sunken_Colony && !t.getUnitType().isAddon()) { // send the building task to the building manager BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal); } else if (t.getUnitType().isAddon()) { //BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight()); producer->buildAddon(t.getUnitType()); } // if we're dealing with a non-building unit else if (t.isUnit()) { // if the race is zerg, morph the unit if (t.getUnitType().getRace() == BWAPI::Races::Zerg) { if (t.getUnitType() == BWAPI::UnitTypes::Zerg_Overlord) { overlordBuildTimer = BWAPI::Broodwar->getFrameCount() + t.getUnitType().buildTime(); canOverlord = true; } producer->morph(t.getUnitType()); // if not, train the unit } else { producer->train(t.getUnitType()); } } // if we're dealing with a tech research else if (t.isTech()) { producer->research(t.getTechType()); } else if (t.isUpgrade()) { if (t.getUpgradeType() == BWAPI::UpgradeTypes::Zerg_Carapace) { BWAPI::Broodwar->printf("Got a request for carapace upgrade using producer x %d y %d: \n", producer->getTilePosition().x, producer->getTilePosition().y); } else if (t.getUpgradeType() == BWAPI::UpgradeTypes::Zerg_Missile_Attacks) { BWAPI::Broodwar->printf("Got a request for missile attacks upgrade using producer x %d y %d : \n", producer->getTilePosition().x, producer->getTilePosition().y); } producer = getEvolutionChamberProducer(producer, t); //BWAPI::Broodwar->printf("Got request for capace or missile attacks with producer type : x : %d y: %d\n", producer->getTilePosition().x, producer->getTilePosition().y); //} //Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n"); producer->upgrade(t.getUpgradeType()); upgradingStuff.insert(producer); } else { } }