98 lines
3.1 KiB
C++
98 lines
3.1 KiB
C++
#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<double> 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<double> vector;
|
|
vector.push_back((deltaX / slope));
|
|
vector.push_back((deltaY / slope));
|
|
return vector;
|
|
} |