Пример #1
0
void Micro::SmartMove(BWAPI::UnitInterface* attacker, const BWAPI::Position & targetPosition)
{
    UAB_ASSERT(attacker, "SmartAttackMove: Attacker not valid");
    UAB_ASSERT(targetPosition.isValid(), "SmartAttackMove: targetPosition not valid");

    if (!attacker || !targetPosition.isValid())
    {
        return;
    }

    // if we have issued a command to this unit already this frame, ignore this one
    if (attacker->getLastCommandFrame() >= BWAPI::Broodwar->getFrameCount() || attacker->isAttackFrame())
    {
        return;
    }

    // get the unit's current command
    BWAPI::UnitCommand currentCommand(attacker->getLastCommand());

    // if we've already told this unit to move to this position, ignore this command
    if ((currentCommand.getType() == BWAPI::UnitCommandTypes::Move) && (currentCommand.getTargetPosition() == targetPosition) && attacker->isMoving())
    {
        return;
    }

    // if nothing prevents it, attack the target
    attacker->move(targetPosition);
    TotalCommands++;

    if (Config::Debug::DrawUnitTargetInfo) 
    {
        BWAPI::Broodwar->drawCircleMap(attacker->getPosition(), dotRadius, BWAPI::Colors::White, true);
        BWAPI::Broodwar->drawCircleMap(targetPosition, dotRadius, BWAPI::Colors::White, true);
        BWAPI::Broodwar->drawLineMap(attacker->getPosition(), targetPosition, BWAPI::Colors::White);
    }
}
Пример #2
0
void WraithManagerExt::executeMicro(const UnitVector & targets)
{
	const UnitVector & selectedUnits = getUnits();
	_noTurretTargetsNo = 0;

	// figure out targets
	UnitVector selectedUnitTargets;
	for (size_t i(0); i<targets.size(); i++)
	{
		// conditions for targeting
		if (targets[i]->isVisible())
		{
			selectedUnitTargets.push_back(targets[i]);

			if (!isTurret(targets[i]))
			{
				_noTurretTargetsNo++;
			}

		}
	}

	setAverageEnemyPosition(selectedUnitTargets);

	// For each unit
	BOOST_FOREACH(BWAPI::Unit * selectedUnit, selectedUnits)
	{
		// Adjust cloak to the situation
		manageCloak(selectedUnit, selectedUnitTargets);

		// if the order is to attack or defend
		if (order.type == order.Attack || order.type == order.Defend)
		{
			// if there are targets
			if (!selectedUnitTargets.empty())
			{
				// find the best target for this unit
				BWAPI::Unit * target = getTarget(selectedUnit, selectedUnitTargets);

				// attack it				
				kiteTarget(selectedUnit, target);

			}
			// if there are no targets
			else
			{
				// if we're not near the order position
				if (selectedUnit->getDistance(order.position) > 100)
				{
					// move to it	

					// Border movement
					BWAPI::Position movePosition;
					if (order.type == SquadOrder::Attack
						&& (StrategyManager::Instance().getCurrentStrategy() == StrategyManager::Instance().TerranWraithRush1Port))
					{
						movePosition = UnitManagerExt::Instance().getMovePosition(selectedUnit);
					}
					else
					{
						movePosition = order.position;
					}
					// eof Border movement
					if (!movePosition.isValid())
					{
						movePosition.makeValid();
					}

					smartAttackMove(selectedUnit, movePosition);
				}
			}
		}

		if (Options::Debug::DRAW_UALBERTABOT_DEBUG)
		{
			BWAPI::Broodwar->drawLineMap(selectedUnit->getPosition().x(), selectedUnit->getPosition().y(),
				selectedUnit->getTargetPosition().x(), selectedUnit->getTargetPosition().y(), Options::Debug::COLOR_LINE_TARGET);
		}
	}
Пример #3
0
void CombatCommander::updateDefenseSquads() 
{
	if (_combatUnits.empty() || BWAPI::Broodwar->self()->allUnitCount(BWAPI::UnitTypes::Terran_Science_Vessel) == 1)
    { 
        return; 
    }
    
    BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
    BWTA::Region * enemyRegion = nullptr;
    if (enemyBaseLocation)
    {
        enemyRegion = BWTA::getRegion(enemyBaseLocation->getPosition());
    }

	// for each of our occupied regions
	for (BWTA::Region * myRegion : InformationManager::Instance().getOccupiedRegions(BWAPI::Broodwar->self()))
	{
        // don't defend inside the enemy region, this will end badly when we are stealing gas
        if (myRegion == enemyRegion)
        {
            continue;
        }

		BWAPI::Position regionCenter = myRegion->getCenter();
		if (!regionCenter.isValid())
		{
			continue;
		}

		// start off assuming all enemy units in region are just workers
		int numDefendersPerEnemyUnit = 2;

		// all of the enemy units in this region
		BWAPI::Unitset enemyUnitsInRegion;
        for (auto & unit : BWAPI::Broodwar->enemy()->getUnits())
        {
            // if it's an overlord, don't worry about it for defense, we don't care what they see
            if (unit->getType() == BWAPI::UnitTypes::Zerg_Overlord)
            {
                continue;
            }

            if (BWTA::getRegion(BWAPI::TilePosition(unit->getPosition())) == myRegion)
            {
                enemyUnitsInRegion.insert(unit);
            }
        }

        // we can ignore the first enemy worker in our region since we assume it is a scout
        for (auto & unit : enemyUnitsInRegion)
        {
            if (unit->getType().isWorker())
            {
                enemyUnitsInRegion.erase(unit);
                break;
            }
        }

        int numEnemyFlyingInRegion = std::count_if(enemyUnitsInRegion.begin(), enemyUnitsInRegion.end(), [](BWAPI::Unit u) { return u->isFlying(); });
        int numEnemyGroundInRegion = std::count_if(enemyUnitsInRegion.begin(), enemyUnitsInRegion.end(), [](BWAPI::Unit u) { return !u->isFlying(); });

        std::stringstream squadName;
        squadName << "Base Defense " << regionCenter.x << " " << regionCenter.y; 
        
        // if there's nothing in this region to worry about
        if (enemyUnitsInRegion.empty())
        {
            // if a defense squad for this region exists, remove it
            if (_squadData.squadExists(squadName.str()))
            {
                _squadData.getSquad(squadName.str()).clear();
            }
            
            // and return, nothing to defend here
            continue;
        }
        else 
        {
            // if we don't have a squad assigned to this region already, create one
            if (!_squadData.squadExists(squadName.str()))
            {
                SquadOrder defendRegion(SquadOrderTypes::Defend, regionCenter, 32 * 25, "Defend Region!");
                _squadData.addSquad(squadName.str(), Squad(squadName.str(), defendRegion, BaseDefensePriority));
            }
        }

        // assign units to the squad
        if (_squadData.squadExists(squadName.str()))
        {
            Squad & defenseSquad = _squadData.getSquad(squadName.str());

            // figure out how many units we need on defense
	        int flyingDefendersNeeded = numDefendersPerEnemyUnit * numEnemyFlyingInRegion;
	        int groundDefensersNeeded = numDefendersPerEnemyUnit * numEnemyGroundInRegion;

            updateDefenseSquadUnits(defenseSquad, flyingDefendersNeeded, groundDefensersNeeded);
        }
        else
        {
            UAB_ASSERT_WARNING(false, "Squad should have existed: %s", squadName.str().c_str());
        }
	}

    // for each of our defense squads, if there aren't any enemy units near the position, remove the squad
    std::set<std::string> uselessDefenseSquads;
    for (const auto & kv : _squadData.getSquads())
    {
        const Squad & squad = kv.second;
        const SquadOrder & order = squad.getSquadOrder();

        if (order.getType() != SquadOrderTypes::Defend)
        {
            continue;
        }

        bool enemyUnitInRange = false;
        for (auto & unit : BWAPI::Broodwar->enemy()->getUnits())
        {
            if (unit->getPosition().getDistance(order.getPosition()) < order.getRadius())
            {
                enemyUnitInRange = true;
                break;
            }
        }

        if (!enemyUnitInRange)
        {
            _squadData.getSquad(squad.getName()).clear();
        }
    }
}
Пример #4
0
//dist is distance between middle unit and target gravity center, interval is length of arc between two units
bool MicroManager::formSquad(const BWAPI::Unitset & targets, int dist, int radius, double angle, int interval)
{
	const BWAPI::Unitset & meleeUnits = getUnits();
	bool attacked = false;
	BWAPI::Position tpos = targets.getPosition();
	BWAPI::Position mpos = meleeUnits.getPosition();

	//do not from squad when fighting or close to enemy
	for (auto & unit : meleeUnits){
		if (unit->isUnderAttack() || unit->isAttackFrame() || targets.size() == 0|| unit->getDistance(tpos) < 80)
			attacked = true;
	}
	if (attacked) {
		BWAPI::Broodwar->drawTextScreen(200, 340, "%s", "Attacked or No targets, Stop Formation");
		return false;
	}
	//if there is a building near the unit, do not form
	for (auto & target : targets){
		auto type = target->getType();
		if (type.isBuilding()){
			return false;
		}
	}
	//Formation is set false by Squad for 5 seconds after formation finished once
	if (!getFormation()){
		BWAPI::Broodwar->drawTextScreen(200, 340, "%s", "Finished Formation");
		return false;
	}
	//BWAPI::Broodwar->drawTextScreen(200, 340, "%s", "Forming");

	const double PI = 3.14159265;

	double ang = angle / 180 * PI;

	//the angle of mid_point on arc
	double m_ang = atan2(mpos.y - tpos.y, mpos.x - tpos.x);
	//circle center
	int cx = (int)(tpos.x - (radius-dist) * cos(m_ang));
	int cy = (int)(tpos.y - (radius-dist) * sin(m_ang));
	BWAPI::Position c;
	c.x = cx; c.y = cy;
	//mid_point on arc
	BWAPI::Position m;
	m.x = (int)(cx + radius*cos(m_ang));
	m.y = (int)(cy + radius*sin(m_ang));
	BWAPI::Broodwar->drawLineMap(c, m, BWAPI::Colors::Yellow);

	BWAPI::Unitset unassigned;
	for (auto & unit : meleeUnits){
		unassigned.insert(unit);
	}

	//move every positions on the arc to the closest unit
	BWAPI::Position tmp;
	int try_time = 0;
	int r = radius;
	int total_dest_dist = 0;
	int num_assigned = 0;

	while (unassigned.size() > 0 && try_time < 5){
		double ang_interval = interval * 1.0 / r;
		double final_ang;
		int num_to_assign;
		int max_units = (int)(ang / ang_interval) + 1;
		if (unassigned.size() < (unsigned)max_units){
			num_to_assign = unassigned.size();
			final_ang = ang_interval * num_to_assign;
		}
		else {
			num_to_assign = max_units;
			final_ang = ang;
		}
		for (int i = 0; i < num_to_assign; i++) {
			//assign from two ends to middle
			double a = m_ang + pow(-1, i % 2)*(final_ang / 2 - (i / 2)*ang_interval);
			int min_dist = MAXINT;
			BWAPI::Unit closest_unit = nullptr;
			tmp.x = (int)(cx + r * cos(a));
			tmp.y = (int)(cy + r * sin(a));
			for (auto & unit : unassigned){
				int d = unit->getDistance(tmp);
				if (d < min_dist){
					min_dist = d;
					closest_unit = unit;
				}
			}
			//if it's a unit far away from fight, do not assign it to a position
			if (closest_unit && min_dist > 300){
				unassigned.erase(closest_unit);
				continue;
			}
			if (tmp.isValid() && closest_unit){
				BWAPI::Broodwar->drawLineMap(closest_unit->getPosition(), tmp, BWAPI::Colors::Red);
				Micro::SmartMove(closest_unit, tmp);
				unassigned.erase(closest_unit);
				//find the total distance between unit and destination
				total_dest_dist += min_dist;
				num_assigned++;
			}		
		}
		r += 40;
		try_time++;
	}

	//if max destination distance less than 32, means forming has been finished
	if (num_assigned > 0 && total_dest_dist / num_assigned <= 32){
		return true;
	}
	else {
		BWAPI::Broodwar->drawTextScreen(200, 340, "%s", "Forming");
		return false;
	}
}