// this function will check to see if all preconditions are met and then create a unit
void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item) 
{
    if (!producer)
    {
        return;
    }

    MetaType t = item.metaType;

    // if we're dealing with a building
    if (t.isUnit() && t.getUnitType().isBuilding() 
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair 
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire
        && !t.getUnitType().isAddon())
    {
        // send the building task to the building manager
		if (t.getUnitType() == BWAPI::UnitTypes::Terran_Bunker)
		{
			BWAPI::TilePosition tp = BWAPI::TilePosition(BWTA::getNearestChokepoint(BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation()))->getCenter());
			BuildingManager::Instance().addBuildingTask(t.getUnitType(), tp, item.isGasSteal);
		}
		else {
			BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal);
		}
    }
    else if (t.getUnitType().isAddon())
    {
        //BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight());
        producer->buildAddon(t.getUnitType());
    }
    // if we're dealing with a non-building unit
    else if (t.isUnit()) 
    {
        // if the race is zerg, morph the unit
        if (t.getUnitType().getRace() == BWAPI::Races::Zerg) 
        {
            producer->morph(t.getUnitType());
        // if not, train the unit
        } 
        else 
        {
            producer->train(t.getUnitType());
        }
    }
    // if we're dealing with a tech research
    else if (t.isTech())
    {
        producer->research(t.getTechType());
    }
    else if (t.isUpgrade())
    {
        //Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n");
        producer->upgrade(t.getUpgradeType());
    }
    else
    {	
		
    }
}
Example #2
0
void ConstructionManager::update()
{
  std::set<BWAPI::Unit*> myPlayerUnits = SelectAll()(isCompleted)(GetAddon,(BWAPI::Unit*)NULL).not(isCarryingMinerals,isCarryingGas,isGatheringGas);

  //iterate through all the builder types
  for(std::map<BWAPI::UnitType,std::set<Building*> >::iterator i=this->buildingsNeedingBuilders.begin();i!=this->buildingsNeedingBuilders.end();i++)
  {
    if (!i->second.empty()) //if its empty, we don't really need builders of this type
    {
      for(std::set<BWAPI::Unit*>::iterator u = myPlayerUnits.begin(); u != myPlayerUnits.end(); u++)
      {
        //if this unit is completed and the right type, and doesn't have an addon, and we aren't already using it
        if ((*u)->getType()==i->first && this->builders.find(*u)==this->builders.end())
        {
          //bid value depends on distance - we like closer builders better
          double min_dist=1000000;
          for(std::set<Building*>::iterator b = i->second.begin(); b != i->second.end(); b++)
          {
            double dist = (*u)->getPosition().getDistance((*b)->position);
            if (dist < min_dist)
              min_dist = dist;
          }
          if (min_dist < 10)
            min_dist = 10;
          if (min_dist > 256*32 + 10)
            min_dist = 256*32 + 10;
          double bid = 80 - (min_dist - 10)/(256*32)*60;
          //if this isn't a worker, we don't care about distance
          if (!(*u)->getType().isWorker())
            arbitrator->setBid(this, *u, 80);
          else
            arbitrator->setBid(this, *u, bid);
        }
      }
    }
  }
  std::list<Building>::iterator i_next;
  int index=0;

  //iterate through all the incomplete buildings
  for(std::list<Building>::iterator i=this->incompleteBuildings.begin();i!=this->incompleteBuildings.end();i=i_next)
  {
    index++;
    i_next=i;
    i_next++;
    Building* b = &(*i);
    if (!b->started && b->buildingUnit!=NULL) //buildingUnit exists, so we've started actual construction
    {
      startedCount[b->type]++;
      b->started=true;
    }
    if (b->type.isAddon()) //if the type is an addon
    {
      if (b->builderUnit!=NULL)
        b->buildingUnit=b->builderUnit->getAddon(); //set buildingUnit to the addon (whether the addon exists or not)

      BWAPI::Unit* u = b->builderUnit;
      BWAPI::Unit* s = b->buildingUnit;
      if (s!=NULL && s->isCompleted()) //if the building exists and is completed
      {
        startedCount[b->type]--;
        plannedCount[b->type]--;
        if (u != NULL)
        {
          this->builders.erase(u);
          arbitrator->removeBid(this,u);
        }
        this->placer->freeTiles(b->tilePosition, 4,3);
        this->placer->freeTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2);

        //If the building is complete, we can forget about it.
        this->incompleteBuildings.erase(i);
      }
      else //building either does not exist, or is incomplete
      {
        if (BWAPI::Broodwar->canMake(NULL,b->type))
        {
          if (u == NULL) //if we don't have a builder, ask for one and wait for it to be offered
            buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b);
          else
          {
            if (u->getAddon() == NULL) //if the addon does not exist yet
            {
              if (u->isLifted()) //if the builder is lifted, find somehwere to land
              {
                if (BWAPI::Broodwar->getFrameCount()>b->lastOrderFrame+BWAPI::Broodwar->getLatency()*2)
                {
                  if (!this->placer->canBuildHereWithSpace(b->tilePosition,b->type))
                  {
                    this->placer->freeTiles(b->tilePosition, 4,3);
                    this->placer->freeTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2);
                    b->tilePosition=placer->getBuildLocationNear(b->tilePosition,*b->type.whatBuilds().first);
                    this->placer->reserveTiles(b->tilePosition, 4,3);
                    this->placer->reserveTiles(b->tilePosition+BWAPI::TilePosition(4,1), 2,2);
                  }
                  u->land(b->tilePosition);
                  b->lastOrderFrame = BWAPI::Broodwar->getFrameCount();
                }
              }
              else
              {
                if (u->isTraining()) //if the builder is training, cancel it - we have control over the builder
                {
                  u->cancelTrain();
                }
                else
                {
                  if (u->getTilePosition()!=b->tilePosition) //we may need to lift to find a build site with enough space for an add-on
                  { //b->tilePosition is set in onOffer()
                    u->lift();
                    b->lastOrderFrame = BWAPI::Broodwar->getFrameCount();
                  }
                  else //otherwise, we may be in a good spot to make the add-on
                  {
                    //check to see if we can build here
                    bool buildable=true;
                    for(int x=b->tilePosition.x()+4;x<b->tilePosition.x()+6;x++)
                      for(int y=b->tilePosition.y()+1;y<b->tilePosition.y()+3;y++)
                        if (!this->placer->buildable(x,y) || BWAPI::Broodwar->hasCreep(x,y))
                          buildable=false;
                    if (buildable) //if so, start making the add-on
                    {
                      u->buildAddon(b->type);
                    }
                    else
                    {
                      //otherwise, lift up (once we are lifted we will look for a valid spot to land and build)
                      u->lift();
                      b->lastOrderFrame = BWAPI::Broodwar->getFrameCount();
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    else //if the type is a normal building (not an addon)
    {
      if (b->tilePosition==BWAPI::TilePositions::None) //if we don't have a build location yet
      {
        if ((BWAPI::Broodwar->getFrameCount()+index)%25==0)
        {
          //get a build location near the goal position
          b->tilePosition = this->placer->getBuildLocationNear(b->goalPosition, b->type);
          if (b->tilePosition!=BWAPI::TilePositions::None)
          {
            b->position = BWAPI::Position(b->tilePosition.x()*32 + b->type.tileWidth()*16, b->tilePosition.y()*32 + b->type.tileHeight()*16);
            this->placer->reserveTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight());
          }
        }
        //if we didn't find a build location yet, or cannot make the building, skip this building for now
        if (b->tilePosition==BWAPI::TilePositions::None)
          continue;
      }

      //if the builder dies, set it to null
      if (b->builderUnit!=NULL && !b->builderUnit->exists())
        b->builderUnit=NULL;

      //if the building dies, or isn't the right type, set it to null
      if (b->buildingUnit!=NULL && (!b->buildingUnit->exists() || b->buildingUnit->getType()!=b->type))
        b->buildingUnit=NULL;

      if (b->buildingUnit == NULL) //if we don't have a building yet, look for it
      {
        //look at the units on the tile to see if it exists yet
        std::set<BWAPI::Unit*> unitsOnTile = BWAPI::Broodwar->unitsOnTile(b->tilePosition.x(), b->tilePosition.y());
        for(std::set<BWAPI::Unit*>::iterator t = unitsOnTile.begin(); t != unitsOnTile.end(); t++)
          if ((*t)->getType() == b->type && !(*t)->isLifted())
          {
            //we found the building
            b->buildingUnit = *t;
            break;
          }
        //maybe the builder _is_ the building! (Zerg)
        if (b->buildingUnit == NULL && b->builderUnit!=NULL && b->builderUnit->getType().isBuilding())
        {
          //we found the building
          b->buildingUnit = b->builderUnit;
        }
      }
      BWAPI::Unit* u = b->builderUnit;
      BWAPI::Unit* s = b->buildingUnit;
      if (s != NULL && s->isCompleted()) //if the building is completed, we're done
      {
        startedCount[b->type]--;
        plannedCount[b->type]--;
        if (u != NULL)
        {
          this->builders.erase(u);
          arbitrator->removeBid(this,u);
        }
        this->placer->freeTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight());

        //If the building is complete, we can forget about it.
        this->incompleteBuildings.erase(i);
      }
      else //otherwise, it doesn't exist or is incomplete
      {
        if (s == NULL) //if the building doesn't even exist
        {
          if (u == NULL) //ask for a builder if we don't have one yet
            buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b);
          else //if we have a worker
          {
            if (!u->isConstructing()) //if the worker isn't constructing
            {
              double distance = u->getPosition().getDistance(b->position);
              if (distance > 100) //if its too far away, tell it to go to the build site
                u->rightClick(b->position);
              else //if its close enough, tell it to build
                if (BWAPI::Broodwar->canBuildHere(u, b->tilePosition, b->type)) //if we can build here, tell the worker to build
                {
                  if (BWAPI::Broodwar->canMake(u, b->type))
                    u->build(b->tilePosition, b->type);
                }
                else //if we cannot build here, we need to find another build site (reset the tilePosition)
                {
                  this->placer->freeTiles(b->tilePosition, b->type.tileWidth(), b->type.tileHeight());
                  b->tilePosition = BWAPI::TilePositions::None;
                  b->position = BWAPI::Positions::None;
                }              
            }
          }
        }
        else //if the building does exist
        {
          if (b->type.getRace() != BWAPI::Races::Terran) //if its not terran, we can forget about the builder (i.e. probe is not needed to finish construction)
          {
            if (u != NULL)
            {
              this->builders.erase(u);
              arbitrator->removeBid(this, u);
              b->builderUnit = NULL;  
              u = b->builderUnit;
            }
          }
          else
          {
            //if the buildind is terran, the worker may have been killed
            if (u == NULL) //looks like the worker was killed, or revoked. In either case we need to ask for another worker to finish our building
              buildingsNeedingBuilders[*b->type.whatBuilds().first].insert(b);
            else
            {
              //we have a worker, so lets rightClick it on the incomplete building so it can resume construction
              if (BWAPI::Broodwar->getFrameCount()%(4*BWAPI::Broodwar->getLatency())==0)
              {
                if (!u->isConstructing() || !s->isBeingConstructed())
                {
                  //right click builder on building
                  u->rightClick(s);
                  //also right click building on builder for good luck! :D
                  s->rightClick(u);
                }
              }
            }
          }
        }
      }
    }
  }
}
Example #3
0
// this function will check to see if all preconditions are met and then create a unit
void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item)
{
	if (!producer)
	{
		return;
	}

	MetaType t = item.metaType;

	// if we're dealing with a building
	if (t.isUnit() && t.getUnitType().isBuilding()
		&& t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair
		&& t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive
		&& t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire
		&& t.getUnitType() != BWAPI::UnitTypes::Zerg_Sunken_Colony
		&& !t.getUnitType().isAddon())
	{
		// send the building task to the building manager
		BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal);
	}
	else if (t.getUnitType().isAddon())
	{
		//BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight());
		producer->buildAddon(t.getUnitType());
	}
	// if we're dealing with a non-building unit
	else if (t.isUnit())
	{
		// if the race is zerg, morph the unit
		if (t.getUnitType().getRace() == BWAPI::Races::Zerg)
		{
			producer->morph(t.getUnitType());
			if (t.getUnitType() == BWAPI::UnitTypes::Zerg_Overlord)
			{
				_overlordTimer = BWAPI::Broodwar->getFrameCount() + t.getUnitType().buildTime() + 35;
			}

			// if not, train the unit
		}
		else
		{
			producer->train(t.getUnitType());
		}
	}
	// if we're dealing with a tech research
	else if (t.isTech())
	{
		producer->research(t.getTechType());
	}
	else if (t.isUpgrade())
	{
		//Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n");
		
		if (t.getUpgradeType() == BWAPI::UpgradeTypes::Muscular_Augments)
		{
			muscBuildTimer = BWAPI::Broodwar->getFrameCount() + t.getUpgradeType().upgradeTime();
			muscBuild = true;
		}
		producer->upgrade(t.getUpgradeType());
	}
	else
	{

	}
}
Example #4
0
// this function will check to see if all preconditions are met and then create a unit
void ProductionManager::create(BWAPI::Unit producer, BuildOrderItem & item) 
{
    if (!producer)
    {
        return;
    }

    MetaType t = item.metaType;

    // if we're dealing with a building
    if (t.isUnit() && t.getUnitType().isBuilding() 
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Lair 
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Hive
        && t.getUnitType() != BWAPI::UnitTypes::Zerg_Greater_Spire
		&& t.getUnitType() != BWAPI::UnitTypes::Zerg_Sunken_Colony
        && !t.getUnitType().isAddon())
    {
        // send the building task to the building manager
        BuildingManager::Instance().addBuildingTask(t.getUnitType(), BWAPI::Broodwar->self()->getStartLocation(), item.isGasSteal);
    }
    else if (t.getUnitType().isAddon())
    {
        //BWAPI::TilePosition addonPosition(producer->getTilePosition().x + producer->getType().tileWidth(), producer->getTilePosition().y + producer->getType().tileHeight() - t.unitType.tileHeight());
        producer->buildAddon(t.getUnitType());
    }
    // if we're dealing with a non-building unit
    else if (t.isUnit()) 
    {
        // if the race is zerg, morph the unit
        if (t.getUnitType().getRace() == BWAPI::Races::Zerg) 
        {
			if (t.getUnitType() == BWAPI::UnitTypes::Zerg_Overlord)
			{
				overlordBuildTimer = BWAPI::Broodwar->getFrameCount() + t.getUnitType().buildTime();
				canOverlord = true;
			}
            producer->morph(t.getUnitType());
        // if not, train the unit
        } 
        else 
        {
            producer->train(t.getUnitType());
        }
    }
    // if we're dealing with a tech research
    else if (t.isTech())
    {
        producer->research(t.getTechType());
    }
    else if (t.isUpgrade())
    {
		if (t.getUpgradeType() == BWAPI::UpgradeTypes::Zerg_Carapace)
		{
			BWAPI::Broodwar->printf("Got a request for carapace upgrade using producer x %d y %d: \n", producer->getTilePosition().x, producer->getTilePosition().y);
		}
		else if (t.getUpgradeType() == BWAPI::UpgradeTypes::Zerg_Missile_Attacks)
		{
			BWAPI::Broodwar->printf("Got a request for missile attacks upgrade using producer x %d y %d : \n", producer->getTilePosition().x, producer->getTilePosition().y);
		}
		producer = getEvolutionChamberProducer(producer, t);
		//BWAPI::Broodwar->printf("Got request for capace or missile attacks with producer type : x : %d  y: %d\n", producer->getTilePosition().x, producer->getTilePosition().y);
		//}
        //Logger::Instance().log("Produce Upgrade: " + t.getName() + "\n");
        producer->upgrade(t.getUpgradeType());
		upgradingStuff.insert(producer);
    }
    else
    {	
		
    }
}