void UnitClass::build(TilePosition target, BWAPI::UnitType type) { if(exists()) { const Position targetPosition(target.x()*32+type.tileWidth()*16, target.y()*32+type.tileHeight()*16); if(getDistance(type, targetPosition) > 48 || !MapHelper::isAllVisible(target, type)) { move(targetPosition, 0); return; } if(mUnit->getOrder() == BWAPI::Orders::PlaceBuilding) { if(mUnit->getBuildType() == type && mUnit->getOrderTargetPosition() == targetPosition) return; } if(mUnit->getLastCommand().getType() == BWAPI::UnitCommandTypes::Build && mUnit->getLastCommand().getUnitType() == type && mUnit->getLastCommand().getTargetTilePosition() == target) { if(mLastOrderExecuteTime >= BWAPI::Broodwar->getFrameCount()) return; } if(mUnit->build(target, type)) mLastOrderExecuteTime = BWAPI::Broodwar->getFrameCount() + BWAPI::Broodwar->getRemainingLatencyFrames(); else move(targetPosition, 0); } }
bool BuildingPlacer::canBuildHere(BWAPI::TilePosition position, BWAPI::UnitType type) const { if (!BWAPI::Broodwar->canBuildHere(NULL, position, type)) return false; for(int x = position.x(); x < position.x() + type.tileWidth(); x++) for(int y = position.y(); y < position.y() + type.tileHeight(); y++) if (reserveMap[x][y]) return false; return true; }
bool BuildingPlacer::canBuildHereWithSpace(BWAPI::TilePosition position, BWAPI::UnitType type) const { if (!this->canBuildHere(position, type)) return false; int width=type.tileWidth(); int height=type.tileHeight(); if (type==BWAPI::UnitTypes::Terran_Command_Center || type==BWAPI::UnitTypes::Terran_Factory || type==BWAPI::UnitTypes::Terran_Starport || type==BWAPI::UnitTypes::Terran_Science_Facility) { width+=2; } int startx = position.x() - buildDistance; if (startx<0) startx=0; int starty = position.y() - buildDistance; if (starty<0) starty=0; int endx = position.x() + width + buildDistance; if (endx>BWAPI::Broodwar->mapWidth()) endx=BWAPI::Broodwar->mapWidth(); int endy = position.y() + height + buildDistance; if (endy>BWAPI::Broodwar->mapHeight()) endy=BWAPI::Broodwar->mapHeight(); for(int x = startx; x < endx; x++) for(int y = starty; y < endy; y++) if (!type.isRefinery()) if (!buildable(x, y)) return false; if (position.x()>3) { int startx2=startx-2; if (startx2<0) startx2=0; for(int x = startx2; x < startx; x++) for(int y = starty; y < endy; y++) { std::set<BWAPI::Unit*> units = BWAPI::Broodwar->unitsOnTile(x, y); for(std::set<BWAPI::Unit*>::iterator i = units.begin(); i != units.end(); i++) { if (!(*i)->isLifted()) { BWAPI::UnitType type=(*i)->getType(); if (type==BWAPI::UnitTypes::Terran_Command_Center || type==BWAPI::UnitTypes::Terran_Factory || type==BWAPI::UnitTypes::Terran_Starport || type==BWAPI::UnitTypes::Terran_Science_Facility) { return false; } } } } } return true; }
bool BuildingPlacer::canBuildHere(BWAPI::TilePosition position, BWAPI::UnitType type) const { //returns true if we can build this type of unit here. Takes into account reserved tiles. if (!BWAPI::Broodwar->canBuildHere(NULL, position, type)) return false; for(int x = position.x(); x < position.x() + type.tileWidth(); x++) for(int y = position.y(); y < position.y() + type.tileHeight(); y++) if (reserveMap[x][y]) return false; return true; }
bool BuildingPlacer::tileOverlapsBaseLocation(BWAPI::TilePosition tile, BWAPI::UnitType type) const { // if it's a resource depot we don't care if it overlaps if (type.isResourceDepot()) { return false; } // dimensions of the proposed location int tx1 = tile.x; int ty1 = tile.y; int tx2 = tx1 + type.tileWidth(); int ty2 = ty1 + type.tileHeight(); // for each base location for (BWTA::BaseLocation * base : BWTA::getBaseLocations()) { // dimensions of the base location int bx1 = base->getTilePosition().x; int by1 = base->getTilePosition().y; int bx2 = bx1 + BWAPI::Broodwar->self()->getRace().getCenter().tileWidth(); int by2 = by1 + BWAPI::Broodwar->self()->getRace().getCenter().tileHeight(); // conditions for non-overlap are easy bool noOverlap = (tx2 < bx1) || (tx1 > bx2) || (ty2 < by1) || (ty1 > by2); // if the reverse is true, return true if (!noOverlap) { return true; } } // otherwise there is no overlap return false; }
//returns true if we can build this type of unit here with the specified amount of space. //space value is stored in this->buildDistance. bool BuildingPlacer::canBuildHereWithSpace(BWAPI::TilePosition position, const Building & b, int buildDist, bool horizontalOnly) const { BWAPI::UnitType type = b.type; //if we can't build here, we of course can't build here with space if (!canBuildHere(position, b)) { return false; } // height and width of the building int width(b.type.tileWidth()); int height(b.type.tileHeight()); //make sure we leave space for add-ons. These types of units can have addons: if (b.type==BWAPI::UnitTypes::Terran_Command_Center || b.type==BWAPI::UnitTypes::Terran_Factory || b.type==BWAPI::UnitTypes::Terran_Starport || b.type==BWAPI::UnitTypes::Terran_Science_Facility) { width += 2; } // define the rectangle of the building spot int startx = position.x - buildDist; int starty = position.y - buildDist; int endx = position.x + width + buildDist; int endy = position.y + height + buildDist; if (b.type.isAddon()) { const BWAPI::UnitType builderType = type.whatBuilds().first; BWAPI::TilePosition builderTile(position.x - builderType.tileWidth(), position.y + 2 - builderType.tileHeight()); startx = builderTile.x - buildDist; starty = builderTile.y - buildDist; endx = position.x + width + buildDist; endy = position.y + height + buildDist; } if (horizontalOnly) { starty += buildDist; endy -= buildDist; } // if this rectangle doesn't fit on the map we can't build here if (startx < 0 || starty < 0 || endx > BWAPI::Broodwar->mapWidth() || endx < position.x + width || endy > BWAPI::Broodwar->mapHeight()) { return false; } // if we can't build here, or space is reserved, or it's in the resource box, we can't build here for(int x = startx; x < endx; x++) { for(int y = starty; y < endy; y++) { if (!b.type.isRefinery()) { if (!buildable(b, x, y) || reserveMap[x][y] || ((b.type != BWAPI::UnitTypes::Protoss_Photon_Cannon) && isInResourceBox(x,y))) { return false; } } } } return true; }
void UnitClass::drawUnitTilePosition() { TilePosition tile = getTilePosition(); BWAPI::UnitType type = getType(); Player player = getPlayer(); BWAPI::Broodwar->drawBox(BWAPI::CoordinateType::Map, tile.x()*32, tile.y()*32, (tile.x()+type.tileWidth())*32, (tile.y()+type.tileHeight())*32, player->getColor()); }
bool BuildingPlacer::canBuildHereWithSpace(BWAPI::TilePosition position, BWAPI::UnitType type, int buildDist) const { //returns true if we can build this type of unit here with the specified amount of space. //space value is stored in this->buildDistance. //if we can't build here, we of course can't build here with space if (!this->canBuildHere(position, type)) return false; int width=type.tileWidth(); int height=type.tileHeight(); //make sure we leave space for add-ons. These types of units can have addons: if (type==BWAPI::UnitTypes::Terran_Command_Center || type==BWAPI::UnitTypes::Terran_Factory || type==BWAPI::UnitTypes::Terran_Starport || type==BWAPI::UnitTypes::Terran_Science_Facility) { width+=2; } int startx = position.x() - buildDist; if (startx<0) return false; int starty = position.y() - buildDist; if (starty<0) return false; int endx = position.x() + width + buildDist; if (endx>BWAPI::Broodwar->mapWidth()) return false; int endy = position.y() + height + buildDist; if (endy>BWAPI::Broodwar->mapHeight()) return false; if (!type.isRefinery()) { for(int x = startx; x < endx; x++) for(int y = starty; y < endy; y++) if (!buildable(x, y) || reserveMap[x][y]) return false; } if (position.x()>3) { int startx2=startx-2; if (startx2<0) startx2=0; for(int x = startx2; x < startx; x++) for(int y = starty; y < endy; y++) { std::set<BWAPI::Unit*> units = BWAPI::Broodwar->getUnitsOnTile(x, y); for(std::set<BWAPI::Unit*>::iterator i = units.begin(); i != units.end(); i++) { if (!(*i)->isLifted()) { BWAPI::UnitType type=(*i)->getType(); if (type==BWAPI::UnitTypes::Terran_Command_Center || type==BWAPI::UnitTypes::Terran_Factory || type==BWAPI::UnitTypes::Terran_Starport || type==BWAPI::UnitTypes::Terran_Science_Facility) { return false; } } } } } return true; }
CheckNeighbourhoodImpl<TileHasPower> HasPower(const BWAPI::UnitType& type) { return CheckRelativePos(type.tileWidth()/2, type.tileHeight()/2, TileHasPower()); }
CheckNeighbourhoodImpl<TC> CheckUnitTilesWithAddonWithSpace(const BWAPI::UnitType& type, int s, const TC& c) { int width = type.tileWidth() + (type.canBuildAddon() ? 2 : 0); return CheckNeighbourhood(-s, width+s, -s, type.tileHeight()+s, c); }
CheckNeighbourhoodImpl<TC> CheckUnitTilesWithSpace(const BWAPI::UnitType& type, int s, const TC& c) { return CheckNeighbourhood(-s, type.tileWidth()+s, -s, type.tileHeight()+s, c); }
CheckNeighbourhoodImpl<TC> CheckUnitTilesWithAddon(const BWAPI::UnitType& type, const TC& c) { int width = type.tileWidth() + (type.canBuildAddon() ? 2 : 0); return CheckNeighbourhood(0, width, 0, type.tileHeight(), c); }
CheckNeighbourhoodImpl<TC> CheckUnitTiles(const BWAPI::UnitType& type, const TC& c) { return CheckNeighbourhood(0, type.tileWidth(), 0, type.tileHeight(), c); }