#include "BuildingPlacement.h" namespace { auto & map = BWEM::Map::Instance(); } //@TODO save a target build position with each sunken/spore colony // so that each base gets the right number of each //@TODO also make sure sunkens don't block off the natural //@TODO place hatcheries closer to the main ramp and tech buildings farther back TilePosition BuildingPlacement::getPosition(BWAPI::UnitType unit) { TilePosition tp = Macro::players.at(Macro::selfID).bases.front().tilePosition; if (unit == UnitTypes::Zerg_Sunken_Colony && Macro::players.at(Macro::selfID).bases.size() > 1) { for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++) { if (Macro::players.at(Macro::selfID).bases.at(i).sunkenCount + Macro::players.at(Macro::selfID).bases.at(i).creepColonyCount < Macro::players.at(Macro::selfID).bases.at(i).desiredSunkenCount()) tp = Macro::players.at(Macro::selfID).bases.at(i).defenseLocation; } } else if (unit == UnitTypes::Zerg_Spore_Colony && Macro::players.at(Macro::selfID).bases.size() > 1) { for (size_t i = 0; i < Macro::players.at(Macro::selfID).bases.size(); i++) { if (Macro::players.at(Macro::selfID).bases.at(i).sporeCount + Macro::players.at(Macro::selfID).bases.at(i).creepColonyCount < Macro::players.at(Macro::selfID).bases.at(i).desiredSporeCount()) tp = Macro::players.at(Macro::selfID).bases.at(i).defenseLocation; } } else if (unit == UnitTypes::Zerg_Extractor) { for (auto b : Macro::players.at(Macro::selfID).bases) { if (b.gasPatches > b.extractorsBuilt()) { for (auto unit : BWAPI::Broodwar->getNeutralUnits()) { if ((unit->getType() == BWAPI::UnitTypes::Resource_Vespene_Geyser) && unit->getDistance(b.base->getPosition()) < 400) { tp = unit->getTilePosition(); } } //tp = b.base->getClosestUnit(UnitTypes::Resource_Vespene_Geyser)->getTilePosition(); } } } else { tp = Broodwar->getBuildLocation(unit, Macro::players.at(Macro::selfID).bases.front().tilePosition); } checkBounds(tp); return tp; } bool BuildingPlacement::build(CUnit unit) { bool built = false; int buildingRange = 4; for (int x = -buildingRange; x <= buildingRange; x++) { for (int y = -buildingRange; y <= buildingRange; y++) { TilePosition tp = TilePosition(unit.target.x + x, unit.target.y + y); if (!(tp == Macro::lastBuildLocation) && unit.unit->build(unit.targetUnit, tp)) { built = true; break; } } } return built; } TilePosition BuildingPlacement::checkBounds(TilePosition tp) { if (tp.x < 1) tp.x = 1; if (tp.y < 1) tp.y = 1; if (tp.x > map.Size().x) tp.x = map.Size().x - 2; if (tp.y > map.Size().y) tp.y = map.Size().y - 2; return tp; } std::vector BuildingPlacement::getDirection(TilePosition tp1, TilePosition tp2) { double deltaX = tp1.x - tp2.x; double deltaY = tp1.y - tp2.y; double slope = sqrt(pow(deltaX, 2.0) + pow(deltaY, 2.0)); std::vector vector; vector.push_back((deltaX / slope)); vector.push_back((deltaY / slope)); return vector; }