Exemplo n.º 1
0
// STEP 3: ISSUE CONSTRUCTION ORDERS TO ASSIGN BUILDINGS AS NEEDED
void BuildingManager::constructAssignedBuildings() 
{
	// for each of the buildings which have been assigned a worker
	buildingData.begin(ConstructionData::Assigned);
	while(buildingData.hasNextBuilding(ConstructionData::Assigned)) 
	{
		// get a handy reference to the worker
		Building & b = buildingData.getNextBuilding(ConstructionData::Assigned);

		// if that worker is not currently constructing
		if (!b.builderUnit->isConstructing()) 
		{
			// if we haven't explored the build position, go there
			if (!isBuildingPositionExplored(b))
			{
				b.builderUnit->move(BWAPI::Position(b.finalPosition));
				//BWAPI::Broodwar->printf("Can't see build position, walking there");
			}
			// if this is not the first time we've sent this guy to build this
			// it must be the case that something was in the way of building
			else if (b.buildCommandGiven) 
			{
				//BWAPI::Broodwar->printf("A builder got stuck");
				// tell worker manager the unit we had is not needed now, since we might not be able
				// to get a valid location soon enough
				WorkerManager::Instance().finishedWithWorker(b.builderUnit);

				// free the previous location in reserved
				BuildingPlacer::Instance().freeTiles(b.finalPosition, b.type.tileWidth(), b.type.tileHeight());

				// nullify its current builder unit
				b.builderUnit = NULL;

				// reset the build command given flag
				b.buildCommandGiven = false;

				// add the building back to be assigned
				buildingData.addBuilding(ConstructionData::Unassigned, b);

				// remove the building from Assigned
				buildingData.removeCurrentBuilding(ConstructionData::Assigned);
			}
			else
			{
				if (debugMode) { BWAPI::Broodwar->printf("Issuing Build Command To %s", b.type.getName().c_str()); }

				// issue the build order!
				b.builderUnit->build(b.finalPosition, b.type);

				// set the flag to true
				b.buildCommandGiven = true;
			}
		}
	}
}
Exemplo n.º 2
0
// STEP 3: ISSUE CONSTRUCTION ORDERS TO ASSIGN BUILDINGS AS NEEDED
void BuildingManager::constructAssignedBuildings()
{
    for (auto & b : m_buildings)
    {
        if (b.status != BuildingStatus::Assigned)
        {
            continue;
        }

        // TODO: not sure if this is the correct way to tell if the building is constructing
        sc2::AbilityID buildAbility = m_bot.Data(b.type).buildAbility;
        const sc2::Unit * builderUnit = m_bot.GetUnit(b.builderUnitTag);

        bool isConstructing = false;

        // if we're zerg and the builder unit is null, we assume it morphed into the building
        if (m_bot.GetPlayerRace(Players::Self) == sc2::Race::Zerg)
        {
            if (!builderUnit)
            {
                isConstructing = true;
            }
        }
        else
        {
            BOT_ASSERT(builderUnit, "null builder unit");
            isConstructing = (builderUnit->orders.size() > 0) && (builderUnit->orders[0].ability_id == buildAbility);
        }

        // if that worker is not currently constructing
        if (!isConstructing)
        {
            // if we haven't explored the build position, go there
            if (!isBuildingPositionExplored(b))
            {
                Micro::SmartMove(*builderUnit, b.finalPosition, m_bot);
            }
            // if this is not the first time we've sent this guy to build this
            // it must be the case that something was in the way of building
            else if (b.buildCommandGiven)
            {
                // TODO: in here is where we would check to see if the builder died on the way
                //       or if things are taking too long, or the build location is no longer valid
            }
            else
            {
                // if it's a refinery, the build command has to be on the geyser unit tag
                if (Util::IsRefineryType(b.type))
                {
                    // first we find the geyser at the desired location
                    UnitTag geyserTag = 0;
                    for (auto & unit : m_bot.Observation()->GetUnits())
                    {
                        if (Util::IsGeyser(unit) && Util::Dist(b.finalPosition, unit.pos) < 3)
                        {
                            geyserTag = unit.tag;
                            break;
                        }
                    }

                    if (geyserTag)
                    {
                        Micro::SmartBuildTag(b.builderUnitTag, b.type, geyserTag, m_bot);
                    }
                    else
                    {
                        std::cout << "WARNING: NO VALID GEYSER UNIT FOUND TO BUILD ON, SKIPPING REFINERY\n";
                    }
                }
                // if it's not a refinery, we build right on the position
                else
                {
                    Micro::SmartBuild(b.builderUnitTag, b.type, b.finalPosition, m_bot);
                }

                // set the flag to true
                b.buildCommandGiven = true;
            }
        }
    }
}