//ctx add
BWAPI::TilePosition BuildingPlacer::getBuildLocationFarFromChokePoint(const Building & b, int buildDist, bool horizontalOnly, bool flag) const
{
	SparCraft::Timer t;
	t.start();

	BWAPI::TilePosition startTitlePos = BWAPI::Broodwar->self()->getStartLocation();
	BWTA::Chokepoint *chokePoint = BWTA::getNearestChokepoint(startTitlePos);
	BWAPI::Position chokeCenterPosition = chokePoint->getCenter();
	BWTA::Region *baseRegion = BWTA::getRegion(BWAPI::Broodwar->self()->getStartLocation());
	BWTA::Polygon basePolygon = baseRegion->getPolygon();
	BWAPI::Position farPosition =  BWAPI::Position(0, 0);
	BWAPI::TilePosition resultPosition = BWAPI::TilePosition(0, 0);
	double dis = 0.0;

	

	for (int i = 0; i < (int)basePolygon.size(); i++) {
		BWAPI::Position point = basePolygon[i];
		double ms1 = t.getElapsedTimeInMilliSec();
		if (point.getDistance(chokeCenterPosition) > dis) {
			dis = point.getDistance(chokeCenterPosition);
			farPosition = point;
		}
	}

	const std::vector<BWAPI::TilePosition> & closestToBuilding = MapTools::Instance().getClosestTilesTo(BWAPI::Position(b.desiredPosition));

	//get best solution
	dis = farPosition.getDistance(BWAPI::Position(startTitlePos));
	
	if (flag == true) {
		for (size_t i = 0; i < closestToBuilding.size(); ++i)
		{
			double ms1 = t.getElapsedTimeInMilliSec();
			if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis > farPosition.getDistance(BWAPI::Position(closestToBuilding[i])))
			{
				resultPosition = closestToBuilding[i];
				break;
				//return closestToBuilding[i];
			}
		}
	}
	else {
		for (size_t i = 0; i < closestToBuilding.size(); ++i)
		{
			double ms1 = t.getElapsedTimeInMilliSec();
			if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis < farPosition.getDistance(BWAPI::Position(closestToBuilding[i])))
			{
				resultPosition = closestToBuilding[i];
				break;
				//return closestToBuilding[i];
			}
		}
	}
	
	if (!basePolygon.isInside(BWAPI::Position(resultPosition))) {
		resultPosition = getBuildLocationNear(b, buildDist, horizontalOnly);
	}

	return resultPosition;
}
예제 #2
0
void ProductionManager::buildBunker() {
	BWAPI::Position base = BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation());
	BWTA::Chokepoint *entrance = BWTA::getNearestChokepoint(base); 
	MetaType bunker = MetaType(BWAPI::UnitTypes::Terran_Bunker);
	BWAPI::Unit producer = ProductionManager::Instance().getProducer(bunker, entrance->getCenter());

	int numBarracks = BWAPI::Broodwar->self()->allUnitCount(BWAPI::UnitTypes::Terran_Barracks);
	bool canMake = canMakeNow(producer, bunker);

	Building b(bunker.getUnitType(), BWAPI::TilePosition(entrance->getCenter()));
	b.isGasSteal = false;

	// set the producer as the closest worker, but do not set its job yet
	producer = WorkerManager::Instance().getBuilder(b, false);
	// get a possible building location for the building
	
	if (!_haveLocationForThisBuilding)
	{
		_predictedTilePosition = BuildingManager::Instance().getBuildingLocation(b);
	}

	if (_predictedTilePosition != BWAPI::TilePositions::None)
	{
		_haveLocationForThisBuilding = true;
	}

	if (producer && canMake && (numBarracks > 0))
	{
		// create it
		create(producer, BuildOrderItem(bunker, 1, true));
		_assignedWorkerForThisBuilding = false;
		_haveLocationForThisBuilding = false;

		// 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 (Config::Debug::DrawWorkerInfo)
		{
			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::Unit 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);
		}
	}
}