Unit* CompaniaDefensiva::buscarObjetivosMarines() {
    // Los marines atacan a cualquier unidad enemiga que haya entrado a la region defendida por la compañia defensiva
    Unit *objetivo = NULL;

    if (!Broodwar->enemy()->getUnits().empty()) {
        std::set<Unit*>::const_iterator ItObj;

        Region *inicial = BWTA::getStartLocation(Broodwar->self())->getRegion();

        ItObj = Broodwar->enemy()->getUnits().begin();
        while (ItObj != Broodwar->enemy()->getUnits().end()) {
            // Busca la primer unidad enemiga que este dentro de la region defendida por la compañia defensiva
            if ((*ItObj)->exists() && ((*ItObj)->isVisible()) && ((*ItObj)->isDetected()) && (inicial->getPolygon().isInside((*ItObj)->getPosition()))) {
                if (objetivo == NULL) {
                    objetivo = (*ItObj);
                    return objetivo;
                }
                else {
                    if ((objetivo->getType().size() == UnitSizeTypes::Large) && (((*ItObj)->getType().size() == UnitSizeTypes::Medium) || ((*ItObj)->getType().size() == UnitSizeTypes::Small)))
                        objetivo = (*ItObj);
                    else if ((objetivo->getType().size() == UnitSizeTypes::Medium) && ((*ItObj)->getType().size() == UnitSizeTypes::Small))
                        objetivo = (*ItObj);
                }
            }

            ItObj++;
        }
    }

    return objetivo;
}
Unit* CompaniaDefensiva::buscarObjetivosGhost() {
    // Los objetivos para los fantasmas seran unidades mecanicas, ya que las mismas pueden ser locked down
    Unit *objetivo = NULL;

    if (!Broodwar->enemy()->getUnits().empty()) {
        std::set<Unit*>::const_iterator ItObj;

        Region *inicial = BWTA::getStartLocation(Broodwar->self())->getRegion();

        ItObj = Broodwar->enemy()->getUnits().begin();
        while (ItObj != Broodwar->enemy()->getUnits().end()) {
            // Busca una unidad mecanica que este dentro de la region defendida por el fantasma o una unidad mecanica que este atacando alguna unidad nuestra que este dentro de la region defendida por la compañia defensiva
            if ((*ItObj)->exists() && ((*ItObj)->isVisible()) && (*ItObj)->getType().isMechanical() && (!(*ItObj)->isLockedDown()) && (inicial->getPolygon().isInside((*ItObj)->getPosition()) || ((*ItObj)->getOrderTarget() != NULL && inicial->getPolygon().isInside((*ItObj)->getOrderTarget()->getPosition())) || (((*ItObj)->getTarget() != NULL) && inicial->getPolygon().isInside((*ItObj)->getTarget()->getPosition())))) {
                if (objetivo == NULL) {
                    objetivo = (*ItObj);
                    return objetivo;
                }
                else {
                    // Busca unidad enemiga de mayor tamaño que cumpla las condiciones para ser atacada por los fantasmas
                    if ((objetivo->getType().size() == UnitSizeTypes::Small) && (((*ItObj)->getType().size() == UnitSizeTypes::Medium) || ((*ItObj)->getType().size() == UnitSizeTypes::Large)))
                        objetivo = (*ItObj);
                    else if ((objetivo->getType().size() == UnitSizeTypes::Medium) && ((*ItObj)->getType().size() == UnitSizeTypes::Large))
                        objetivo = (*ItObj);
                }
            }

            ItObj++;
        }
    }

    return objetivo;
}
Example #3
0
void TechTask::giveUnit(Unit unit)
{
	if(unit->getType() == mType.whatResearches())
	{
		mUnit = unit;
		assert(mReservedResources == false);
		ResourceTracker::Instance().reserveCurrentMinerals(mRequiredSatisfyTime, mType.mineralPrice());
		ResourceTracker::Instance().reserveCurrentGas(mRequiredSatisfyTime, mType.gasPrice());
		mReservedResources = true;
	}
}
Example #4
0
void Constructor::buildingDestroyed(Unit building)
{
    if (building->getType().getID() == UnitTypes::Protoss_Pylon.getID())
    {
        return;
    }
    if (building->getType().getID() == UnitTypes::Terran_Supply_Depot.getID())
    {
        return;
    }
    if (building->getType().isAddon())
    {
        return;
    }
    if (building->getType().getID() == UnitTypes::Zerg_Sunken_Colony.getID())
    {
        buildPlan.insert(buildPlan.begin(),UnitTypes::Zerg_Spore_Colony);
        return;
    }
    buildPlan.insert(buildPlan.begin(), building->getType());
}
Example #5
0
void TargetingAgent::checkTarget(BaseAgent* agent)
{
    Unit* cTarget = agent->getUnit()->getTarget();
    if (cTarget == NULL)
    {
        cTarget = agent->getUnit()->getOrderTarget();
    }

    if (cTarget != NULL)
    {
        Unit* pTarget = findTarget(agent);
        if (pTarget != NULL && pTarget->getPlayer()->isEnemy(Broodwar->self()))
        {
            if (pTarget->getType().getID() != cTarget->getType().getID())
            {
                //Show debug info for selected unit, or first
                //in list if mulitple units are selected.
                set<Unit*> units = Broodwar->getSelectedUnits();
                if ((int)units.size() > 0)
                {
                    int unitID = (*units.begin())->getID();
                    if (agent->getUnitID() == unitID)
                    {
                        int uX = agent->getUnit()->getPosition().x();
                        int uY = agent->getUnit()->getPosition().y();
                        int tX = pTarget->getPosition().x();
                        int tY = pTarget->getPosition().y();
                        Broodwar->drawLineMap(uX,uY,tX,tY,Colors::Yellow);
                    }
                }
                UnitAgent* ua = (UnitAgent*)agent;
                if (ua->canSwitchTarget())
                {
                    agent->getUnit()->attack(pTarget, true);
                    agent->getUnit()->rightClick(pTarget, true);
                }
            }
        }
    }
}
Example #6
0
bool CommandOptimizer::add(UnitCommand command)
{
  // ignore queued and invalid commands, or return if optimizer is disabled
  if (level == 0 ||
    command.isQueued() ||
    command.getType() >= UnitCommandTypes::None)
    return false;

  // Store some commonly accessed variables
  UnitCommandType uct = command.getType();
  Unit utarg = command.getTarget();
  UnitType  targType = utarg ? utarg->getType() : UnitTypes::None;
  Unit uthis = command.getUnit();
  UnitType  thisType = uthis ? uthis->getType() : UnitTypes::None;

  //  Exclude commands that cannot be optimized.
  if (uct == UnitCommandTypes::Build_Addon ||
    uct == UnitCommandTypes::Land ||
    uct == UnitCommandTypes::Build ||
    uct == UnitCommandTypes::Place_COP ||
    uct == UnitCommandTypes::Research ||
    uct == UnitCommandTypes::Upgrade ||
    (level < 4 &&
    uct == UnitCommandTypes::Use_Tech_Unit &&
    (command.getTechType() == TechTypes::Archon_Warp ||
    command.getTechType() == TechTypes::Dark_Archon_Meld)))
    return false;


  // Simplify some commands if possible to decrease their size
  if (uct == UnitCommandTypes::Attack_Unit)
  {
    // Use Right Click for Attack Unit
    if (thisType.canAttack() && utarg && Broodwar->self() && Broodwar->self()->isEnemy(utarg->getPlayer()))
      command.type = UnitCommandTypes::Right_Click_Unit;
  }
  else if (uct == UnitCommandTypes::Move)
  {
    // Use Right Click for Move
    command = UnitCommand::rightClick(uthis, command.getTargetPosition());
  }
  else if (uct == UnitCommandTypes::Gather)
  {
    // Use Right Click for gather
    if (targType.isResourceContainer())
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Set_Rally_Position)
  {
    // Use Right Click for Set Rally
    if (thisType.canProduce() &&
      thisType != UnitTypes::Protoss_Carrier && thisType != UnitTypes::Hero_Gantrithor &&
      thisType != UnitTypes::Protoss_Reaver  && thisType != UnitTypes::Hero_Warbringer)
      command = UnitCommand::rightClick(uthis, command.getTargetPosition());
  }
  else if (uct == UnitCommandTypes::Set_Rally_Unit)
  {
    // Use Right Click for Set Rally
    if (thisType.canProduce() &&
      thisType != UnitTypes::Protoss_Carrier && thisType != UnitTypes::Hero_Gantrithor &&
      thisType != UnitTypes::Protoss_Reaver  && thisType != UnitTypes::Hero_Warbringer)
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Use_Tech_Unit)
  {
    // Use Right Click for infestation
    if (command.getTechType() == TechTypes::Infestation &&
      (thisType == UnitTypes::Zerg_Queen || thisType == UnitTypes::Hero_Matriarch) &&
      targType == UnitTypes::Terran_Command_Center)
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Train)
  {
    // Create a single placeholder since we assume it stores an interceptor or scarab when it's not important
    if (thisType == UnitTypes::Protoss_Carrier ||
      thisType == UnitTypes::Hero_Gantrithor ||
      thisType == UnitTypes::Protoss_Reaver ||
      thisType == UnitTypes::Hero_Warbringer)
      command = UnitCommand::train(uthis, UnitTypes::Protoss_Interceptor);
  }
  else if (uct == UnitCommandTypes::Use_Tech)
  {
    // Simplify siege/cloak/burrow tech to their specific commands to allow grouping them
    switch (command.getTechType())
    {
    case TechTypes::Enum::Tank_Siege_Mode:
      if (command.unit && command.unit->isSieged())
        command = UnitCommand::unsiege(uthis);
      else
        command = UnitCommand::siege(uthis);
      break;
    case TechTypes::Enum::Personnel_Cloaking:
    case TechTypes::Enum::Cloaking_Field:
      if (command.unit && command.unit->isCloaked())
        command = UnitCommand::decloak(uthis);
      else
        command = UnitCommand::cloak(uthis);
      break;
    case TechTypes::Enum::Burrowing:
      if (command.unit && command.unit->isBurrowed())
        command = UnitCommand::unburrow(uthis);
      else
        command = UnitCommand::burrow(uthis);
      break;
    }
  }

  // Exclude commands not optimized at optimizer level 1 (no multi-select buildings)
  if (level <= 1 && thisType < UnitTypes::None && thisType.isBuilding())
    return false;

  // Exclude commands not optimized at or below optimizer level 2 (no position commands)
  if (level <= 2 &&
    (uct == UnitCommandTypes::Attack_Move ||
    uct == UnitCommandTypes::Move ||
    uct == UnitCommandTypes::Patrol ||
    uct == UnitCommandTypes::Right_Click_Position ||
    uct == UnitCommandTypes::Set_Rally_Position ||
    uct == UnitCommandTypes::Unload_All_Position ||
    uct == UnitCommandTypes::Use_Tech_Position))
    return false;

  if (level >= 4)
  {
    // Convert tech unit target to tech position target commands so that they can be
    // optimized with nearby tech position commands of the same type.
    if (uct == UnitCommandTypes::Use_Tech_Unit && command.getTechType().targetsPosition() && utarg)
      command = UnitCommand::useTech(uthis, command.getTechType(), utarg->getPosition());

    // Align locations to 32 pixels
    if (uct == UnitCommandTypes::Attack_Move ||
      uct == UnitCommandTypes::Move ||
      uct == UnitCommandTypes::Patrol ||
      uct == UnitCommandTypes::Right_Click_Position ||
      uct == UnitCommandTypes::Set_Rally_Position ||
      uct == UnitCommandTypes::Unload_All_Position ||
      uct == UnitCommandTypes::Use_Tech_Position)
      command = UnitCommand(uthis, uct, utarg, command.x & (~0x1F), command.y & (~0x1F), command.extra);
    else if (uct == UnitCommandTypes::Use_Tech_Unit &&   // Group Archon & Dark Archon merging
      (command.getTechType() == TechTypes::Archon_Warp ||
      command.getTechType() == TechTypes::Dark_Archon_Meld))
      command = UnitCommand::useTech(uthis, command.getTechType(), nullptr);
  }

  // Set last immediate command again in case it was altered when inserting it into the optimizer
  static_cast<UnitImpl*>(command.unit)->setLastImmediateCommand(command);

  // Add command to the command optimizer buffer and unload it later (newest commands first)
  optimizerQueue[command.getType().getID()].push_front(command);
  return true;
}
Example #7
0
lionheart::Action lionheart::MathewWarenski::playSmartCharge(
    Unit const &u, SituationReport report, Plan p)
{

  if (u.getType() == CROWN)
  {

    // if (p.movesToEnemy() < 6) return p.moveToLocation(15, 15);
    return Action();
  }

  if (p.movesToEnemyCrown() <= u.getMoveSpeed())
  {
    if (!p.hasAttack())
    {
      return p.moveToEnemyCrown();
    }
  }
  if (u.getType() == ARCHER)
  {
    if (!p.hasAttack())
    {
      if (enemyWaiting)
      {

        bool kingOnWall = false;
        for (int i = 0; i < 30; i++)
        {
          for (int j = 1; j <= 2; j++)
          {
            auto backwall = flipIfWest(ENEMY_EAST_WALL - j, 29);

            if (report.things[i][backwall].unit == CROWN)
            {
              kingY = i;
              kingX = backwall;
              kingOnWall = true;
            }
          }
        }

        if (kingOnWall)
        {
          auto col = flipIfWest(29, 29);
          auto loc = u.getLocation();
          if (loc.row == kingY && loc.col == col)
          {

            if (facingEast && u.getFacing() != lionheart::Direction::WEST)
            {
              return turn(lionheart::Direction::WEST);
            }
            else if (!facingEast && u.getFacing() != lionheart::Direction::EAST)
            {
              return turn(lionheart::Direction::EAST);
            }

            return lionheart::attack({ kingY, kingX });
          }
          else if (report.things[kingY][col].unit == ARCHER)
          {
            return p.attackEnemy();
          }

          return p.moveToLocation(kingY, col);
        }
      }

      return p.moveToEnemyCrown();
    }
  }
  if (p.hasAttack())
  {
    return p.attackEnemy();
  }
  return p.moveToEnemyCrown();
}
Example #8
0
void ClientGameSession::handleEvent(Packet& packet)
{
	int id = packet.getId();
	switch(id)
	{
		case EVENT_GAME_FULLSTATE:
			{
                int newGameTime;
                packet >> newGameTime;

                GAME_LOG_DEBUG("Full game state received. Old gametimer = " << gameTimer << ". New server gametime = " << newGameTime << ". Estimated delay = " << Game::shared().getNetworkDelay());

                //Round the delay to 10 ms so that the game timer is always a multiple of 10 ms
                gameTimer = newGameTime + ((int)(Game::shared().getNetworkDelay()*1000)/10)*10;

				int count;
				packet >> count;
				for(int i = 0; i < count; ++i)
				{
					int clientId;
					packet >> clientId;

					int factionId;
					packet >> factionId;

					Faction* faction = getFactionById(factionId);
					if(!faction)
					{
						faction = createFaction(factionId);
						factions.push_back(faction);
					}

					faction->deserialize(packet);
					faction->setClientId(clientId);

					if(clientId == Game::shared().getClientId())
						localFaction = faction;

					//If any of the units that we have was NOT sent in this list they must be deleted
					//So we keep a list of IDs that we have and check which ones are in the packet
					//This method might be a bit slow but this process only happens in rare situations
					//so we do not bother adding extra member variables to the unit class to accomplish this
					vector<int> allIDs;
					for(list<Unit*>::iterator it = factions[i]->getUnits().begin(); it != factions[i]->getUnits().end(); ++it)
						allIDs.push_back((*it)->getId());

					int unitCount;
					packet >> unitCount;
					for(int i = 0; i < unitCount; ++i)
					{
						int id;
						packet >> id;

						for(vector<int>::iterator iter = allIDs.begin(); iter != allIDs.end(); ++iter)
							if( *iter == id ){ allIDs.erase(iter); break; }

						Unit* unit = getUnitById(id);
						bool newUnit = false;
						if(!unit)
						{
							newUnit = true;
							unit = createUnit(id, 0);
						}
						unit->deserialize(packet);

						if(faction == localFaction) unit->setLocal(true);

						Object* obj = unit->getObject();
						if(!obj) obj = Root::shared().getScene()->createObject();

						obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
						obj->setAnimation("stand");

						unit->setObject(obj);

						float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);

						unit->setPosition(vec3(unit->getPosition().x,
									heightModel,
									unit->getPosition().z));

						if(newUnit) faction->addUnit(unit);
						if(unit->getType() == 2 && faction == localFaction)
						{
							input->setSpecPos(unit->getPosition());
						}

						unit->getInfo()->onSpawn(unit);
					}

					//now allIDs contains a list of units that were not in the packet so they must be deleted
					//note that we can not just delete them because of reference counts and so on.
					//we make them obsolte so that they are deleted next frame
					for(vector<int>::iterator iter = allIDs.begin(); iter != allIDs.end(); ++iter)
					{
						Unit* unit = getUnitById(*iter); //if unit == 0 then there are some serious issues ;)
						if(unit) unit->markForDelete();
					}

				}
				rebuildCellList();
			}
			break;

		case EVENT_CLIENT_CONNECTED:
			{
				int clientId;
				packet >> clientId;

				int factionId;
				packet >> factionId;

				Faction* faction = createFaction(clientId);
				faction->deserialize(packet);
				faction->setClientId(clientId);
				factions.push_back(faction);

				if(clientId == Game::shared().getClientId())
					localFaction = faction;

				int unitCount;
				packet >> unitCount;
				for(int i = 0; i < unitCount; ++i)
				{
					int id;
					packet >> id;
					Unit* unit = createUnit(id, 0);
					unit->deserialize(packet);

					if(faction == localFaction) unit->setLocal(true);

					Object* obj = Root::shared().getScene()->createObject();
					obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
					obj->setAnimation("stand");

					unit->setObject(obj);

					float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);

					unit->setPosition(vec3(unit->getPosition().x,
								heightModel,
								unit->getPosition().z));

					faction->addUnit(unit);
				}
			}
			break;

		case EVENT_CLIENT_DISCONNECTED:
			{
				int id;
				packet >> id;
				GAME_LOG_INFO("Client " << id << " disconnected.");
				for(vector<Faction*>::iterator iter = factions.begin(); iter != factions.end(); ++iter)
				{
					if( (*iter)->getClientId() == id )
					{
						GAME_LOG_INFO("Client " << id << " removed from game session. NOT removing faction!");
						//delete *iter;
						//iter = factions.erase(iter);
						break;
					}
				}
			}
			break;

		case EVENT_MOVE_UNIT: {
                                  int timeStamp;
                                  packet >> timeStamp;

								  int numUnits;
								  packet >> numUnits;

                                  GAME_LOG_DEBUG("Move packet for " << numUnits << " units. " << (gameTimer - timeStamp) << " ms delay. Sent at server-gametime " << timeStamp << ". Recieved at client-gametime " << gameTimer);

								  int unitId;
                                  int nodeCount;
                                  vec2 pos;
                                  float yaw;
                                  vec2 tempPos;
                                  vector<vec2> pathNodes;
								  for(int i = 0; i < numUnits; ++i)
                                  {
									  packet >> unitId;
                                      packet >> pos;
                                      packet >> yaw;
                                      packet >> nodeCount;
                                      pathNodes.clear();
                                      for(int i = 0; i < nodeCount; ++i){ packet >> tempPos; pathNodes.push_back(tempPos); }
									  Unit* unit = getUnitById(unitId);
                                      if(unit) unit->setUnitMovement(timeStamp, pos, yaw, pathNodes);
								  }
								  break;
							  }

		case EVENT_ATTACK_MOVE_UNIT:
							  {
                                  int timeStamp;
                                  packet >> timeStamp;

								  int numUnits;
								  packet >> numUnits;

								  int unitId, targetUnitId;
								  for(int i = 0; i < numUnits; ++i) {
									  packet >> unitId >> targetUnitId;
									  Unit* unit = getUnitById(unitId);
									  Unit* targetUnit = getUnitById(targetUnitId);
									  if(unit && targetUnit) unit->setTargetUnit(timeStamp, targetUnit);
								  }

								  break;
							  }

		case EVENT_UNIT_DIED:
							  {
								  int id;
								  packet >> id;
								  Unit* unit = getUnitById(id);
								  if(unit)
								  {
									  unit->makeDead();
									  unit->getInfo()->onDeath(unit);
								  }
							  }
							  break;

		case EVENT_UNIT_SPAWNED:
							  {
								  int factionId, unitId;
								  packet >> factionId >> unitId;
								  Faction* faction = getFactionById(factionId);
								  if(!faction)
								  {
									  GAME_LOG_WARNING("Unit spawn packet received for invalid faction!");
								  }
								  else
								  {
									  Unit* unit = getUnitById(unitId);
									  bool newUnit = false;
									  if(unit)
										  GAME_LOG_WARNING("Spawn packet for unit that already existed");
									  else
									  {
										  newUnit = true;
										  unit = createUnit(unitId, 0);
									  }
									  unit->deserialize(packet);
									  if(faction == localFaction) unit->setLocal(true);
									  if(newUnit) unit->setCellFromList(unitCells);

									  Object* obj = unit->getObject();
									  if(!obj) obj = Root::shared().getScene()->createObject();
									  obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
									  obj->setAnimation("stand");
									  unit->setObject(obj);

									  float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);
									  unit->setPosition(vec3(unit->getPosition().x, heightModel, unit->getPosition().z));

									  //This must happen after the object is set, because
									  //then it will set the correct tint color
									  if(newUnit) faction->addUnit(unit);

									  unit->getInfo()->onSpawn(unit);
								  }
							  }
							  break;

		case EVENT_PLAYER_DEFEAT:
							  {
								  int factionID;
								  packet >> factionID;
								  LOG_INFO("Player lost: " << factionID + 1);
								  Arya::SoundManager::shared().play("defeat.wav");
							  }
							  break;

		case EVENT_PLAYER_VICTORY:
							  {
								  int factionID;
								  packet >> factionID;
								  LOG_INFO("Game won by player: " << factionID + 1);
								  Arya::SoundManager::shared().play("victory.wav");
							  }
							  break;

		default:
							  GAME_LOG_INFO("ClientGameSession: unknown event received! (" << id << ")");
							  break;
	}
}
void ExampleTournamentAI::onFrame()
{
  if ( Broodwar->getFrameCount() < 64 )
    return;

  /*if ( Broodwar->enemy()->allUnitCount(UnitTypes::AllUnits) > 0 )
    Broodwar->setLocalSpeed(30);
  else
    Broodwar->setLocalSpeed(0);*/

  int thisAPM = Broodwar->getAPM();
  if ( thisAPM > maxAPM )
    maxAPM = thisAPM;

  char hcolor = 2;
  if ( maxAPM < 500 )
    hcolor = 7;
  else if ( maxAPM < 1500 )
    hcolor = 4;
  else if ( maxAPM < 2500 )
    hcolor = 3;
  else
    hcolor = 6;

  char color = 2;
  if ( thisAPM < 500 )
    color = 7;
  else if ( thisAPM < 1500 )
    color = 4;
  else if ( thisAPM < 2500 )
    color = 3;
  else
    color = 6;
  
  Broodwar->setTextSize(3);
  Broodwar->drawTextScreen(4, 4, "\x13" "\x07" "%s", pszBotName);
  Broodwar->setTextSize();

  Broodwar->drawTextScreen(2, 2, "\x04" "%s\n" "\x07" "APM: %c%d\n" "\x07" "Highest APM: %c%d", Broodwar->mapName().c_str(), color, thisAPM, hcolor, maxAPM);
  // draw supplies
  if ( isJoiner )
    Broodwar->drawTextScreen(560, 40, "\x07" "Supply: %d/%d", Broodwar->self()->supplyUsed()/2, Broodwar->self()->supplyTotal()/2);

  // iterate self units for event identification
  for ( std::set<Unit*>::const_iterator i = self->getUnits().begin(),
        iend = self->getUnits().end();
        i != iend;
        ++i )
  {
    Unit *u = *i;

    if ( !u->exists() )
      continue;

    if ( u->isStartingAttack() )
      AddEvent(u->getPosition(), 20, 30);//, "starting attack");

    if ( u->isUnderAttack() )
      AddEvent(u->getPosition(), 20, 50);//, "under attack");
/*
    if ( u->isBeingHealed() )
      AddEvent(u->getPosition(), 2, 5, "being healed");

    if ( u->isRepairing() )
      AddEvent(u->getPosition(), 1, 3);//, "repairing");
*/
    if ( u->isCompleted() && !u->getType().isBuilding() && !u->isInvincible() && u->isUnderStorm() )
      AddEvent(u->getPosition(), 100, 50);//, "under psi storm");

    if ( u->isCompleted() && u->getType().maxHitPoints() && (u->getHitPoints()*100)/u->getType().maxHitPoints() <= 2 )
    {
      std::set<Unit*> urad = u->getUnitsInRadius(512);
      bool enemyInRad = false;
      for ( std::set<Unit*>::iterator ur = urad.begin(),
            urend = urad.end();
            ur != urend;
            ++ur )
      {
        if ( (*ur)->exists() && (self->isEnemy((*ur)->getPlayer()) || (*ur)->getPlayer()->isEnemy(self)) )
        {
          enemyInRad = true;
          break;
        }
      }
      if ( !enemyInRad )
        AddEvent(u->getPosition(), 20, 30);//, "really low hp");
    }
/*
    if ( u->getKillCount() != 0 && u->getKillCount() % 50 == 0 )
      AddEvent(u->getPosition(), 100, 20, "massive kill count");
*/

    Order o = u->getOrder();

    // states
    if ( o == Orders::BuildingLiftOff ||
         o == Orders::BuildingLand    ||
         o == Orders::Burrowing       ||
         o == Orders::Unburrowing     ||
         o == Orders::Sieging         ||
         o == Orders::Unsieging       ||
         o == Orders::OpenDoor        ||
         o == Orders::CloseDoor       ||
         o == Orders::Cloak           ||
         o == Orders::Decloak )
      AddEvent(u->getPosition(), 5, 15);//, o.c_str());

    // abilities
    if (  o == Orders::CastConsume            ||
          o == Orders::CastDarkSwarm          ||
          o == Orders::CastDefensiveMatrix    ||
          o == Orders::CastDisruptionWeb      ||
          o == Orders::CastEMPShockwave       ||
          o == Orders::CastEnsnare            ||
          o == Orders::CastFeedback           ||
          o == Orders::CastHallucination      ||
          o == Orders::CastInfestation        ||
          o == Orders::CastIrradiate          ||
          o == Orders::CastLockdown           ||
          o == Orders::CastMaelstrom          ||
          o == Orders::CastMindControl        ||
          o == Orders::CastOpticalFlare       ||
          o == Orders::CastParasite           ||
          o == Orders::CastPlague             ||
          o == Orders::CastPsionicStorm       ||
          o == Orders::CastRecall             ||
          o == Orders::CastRestoration        ||
          o == Orders::CastSpawnBroodlings    ||
          o == Orders::CastStasisField        ||
          o == Orders::FireYamatoGun          ||
          o == Orders::RechargeShieldsUnit )
    {
      if ( u->getTarget() )
        AddEvent(u->getTarget()->getPosition(), 30, 50);//, o.c_str());
      else
        AddEvent(u->getOrderTargetPosition(), 30, 50);
    }
    // scanner
    if ( o == Orders::CastScannerSweep && 
          u->getLastCommand().getType() == UnitCommandTypes::Use_Tech_Position && 
          u->getLastCommand().getTechType() == TechTypes::Scanner_Sweep )
      AddEvent(u->getLastCommand().getTargetPosition(), 100, 50);

    // more abilities
    if ( o == Orders::PlaceMine )
      AddEvent(u->getPosition(), 2, 10);

    // other
    if (  o == Orders::EnterNydusCanal  ||
          //o == Orders::EnterTransport ||
          o == Orders::GuardianAspect   ||
          o == Orders::MoveUnload       ||
          o == Orders::PickupBunker     ||
          o == Orders::PickupTransport  ||
          o == Orders::PlaceAddon       ||
          o == Orders::SelfDestrucing   ||
          o == Orders::Unload           ||
          o == Orders::ZergBirth )
      AddEvent(u->getPosition(), 50, 40);//, o.c_str());
  }
  RunEvents();
}