BWAPI::Position Micro::GetKiteVector(BWAPI::Unit unit, BWAPI::Unit target) { BWAPI::Position fleeVec(target->getPosition() - unit->getPosition()); double fleeAngle = atan2(fleeVec.y, fleeVec.x); fleeVec = BWAPI::Position(static_cast<int>(64 * cos(fleeAngle)), static_cast<int>(64 * sin(fleeAngle))); return fleeVec; }
void WorkerManager::drawResourceDebugInfo() { if (!Config::Debug::DrawResourceInfo) { return; } for (auto & worker : workerData.getWorkers()) { UAB_ASSERT(worker != nullptr, "Worker was null"); char job = workerData.getJobCode(worker); BWAPI::Position pos = worker->getTargetPosition(); BWAPI::Broodwar->drawTextMap(worker->getPosition().x, worker->getPosition().y - 5, "\x07%c", job); BWAPI::Broodwar->drawLineMap(worker->getPosition().x, worker->getPosition().y, pos.x, pos.y, BWAPI::Colors::Cyan); BWAPI::Unit depot = workerData.getWorkerDepot(worker); if (depot) { BWAPI::Broodwar->drawLineMap(worker->getPosition().x, worker->getPosition().y, depot->getPosition().x, depot->getPosition().y, BWAPI::Colors::Orange); } } }
void GameCommander::setScoutUnits() { //BWAPI::Broodwar->drawTextScreen(200, 300, "%d", int(_scoutUnits.size())); if (!_scoutUnits.empty()) { BWAPI::Unit scout = *(_scoutUnits.begin()); if (!scout->exists()) { _scoutUnits.clear(); } } // if we haven't set a scout unit, do it if (_scoutUnits.empty())// && !_initialScoutSet) { BWAPI::Unit supplyProvider = getFirstSupplyProvider(); // if it exists if (supplyProvider) { // grab the closest worker to the supply provider to send to scout BWAPI::Unit workerScout = getClosestWorkerToTarget(supplyProvider->getPosition()); // if we find a worker (which we should) add it to the scout units if (workerScout) { ScoutManager::Instance().setWorkerScout(workerScout); assignUnit(workerScout, _scoutUnits); //_initialScoutSet = true; } } } }
void Squad::update() { // update all necessary unit information within this squad updateUnits(); // determine whether or not we should regroup const bool needToRegroup(needsToRegroup()); // draw some debug info if (Options::Debug::DRAW_UALBERTABOT_DEBUG && order.type == SquadOrder::Attack) { BWAPI::Broodwar->drawTextScreen(200, 330, "%s", regroupStatus.c_str()); BWAPI::Unit * closest = unitClosestToEnemy(); if (closest && (BWAPI::Broodwar->getFrameCount() % 24 == 0)) { BWAPI::Broodwar->setScreenPosition(closest->getPosition().x() - 320, closest->getPosition().y() - 200); } } // if we do need to regroup, do it if (needToRegroup) { InformationManager::Instance().lastFrameRegroup = 1; const BWAPI::Position regroupPosition(calcRegroupPosition()); BWAPI::Broodwar->drawTextScreen(200, 150, "REGROUP"); BWAPI::Broodwar->drawCircleMap(regroupPosition.x(), regroupPosition.y(), 30, BWAPI::Colors::Purple, true); meleeManager.regroup(regroupPosition); rangedManager.regroup(regroupPosition); } else // otherwise, execute micro { InformationManager::Instance().lastFrameRegroup = 1; meleeManager.execute(order); rangedManager.execute(order); transportManager.execute(order); detectorManager.setUnitClosestToEnemy(unitClosestToEnemy()); detectorManager.execute(order); } }
void Squad::draw() { if ((int)agents.size() == 0) return; if( DebugFlags::instance().getFlag(none) ) return; if( !DebugFlags::instance().getFlag(squad_details) ) return; // Draw a circle around the group const Position center = getCenter(); const int groupRadius = getRadius(); Broodwar->drawCircleMap(center.x(), center.y(), groupRadius, Colors::Grey); // Draw a circle around the leader const Unit& leaderUnit = leader->getUnit(); const int leaderX = leaderUnit.getPosition().x(); const int leaderY = leaderUnit.getPosition().y(); const int radius = leaderUnit.getRight() - leaderUnit.getPosition().x(); Broodwar->drawCircleMap(leaderX, leaderY, radius + 2, Colors::Red); Broodwar->drawCircleMap(leaderX, leaderY, radius - 2, Colors::Orange); BWAPI::Unit * unitTarget; // Draw squad leader enemy target if ((unitTarget = leader->getUnitTarget()) != NULL) { const int enemyX = unitTarget->getPosition().x(); const int enemyY = unitTarget->getPosition().y(); const int enemyRadius = unitTarget->getRight() - unitTarget->getPosition().x(); Broodwar->drawCircleMap(enemyX, enemyY, enemyRadius + 2, Colors::Green); Broodwar->drawCircleMap(enemyX, enemyY, enemyRadius - 2, Colors::Yellow); } // Draw lines from Agents to their leader // for (AgentSetIter it = agents.begin(); it != agents.end(); it++) // { // int agentX = (*it)->getUnit().getPosition().x(); // int agentY = (*it)->getUnit().getPosition().y(); // Broodwar->drawLineMap(agentX, agentY, leaderX, leaderY, Colors::Teal); // } }
bool Squad::unitNearEnemy(BWAPI::Unit unit) { assert(unit); BWAPI::Unitset enemyNear; MapGrid::Instance().GetUnits(enemyNear, unit->getPosition(), 400, false, true); return enemyNear.size() > 0; }
// Gets a SparCraft unit from a BWAPI::Unit, used for our own units since we have all their info const SparCraft::Unit CombatSimulation::getSparCraftUnit(BWAPI::Unit unit) const { return SparCraft::Unit( unit->getType(), SparCraft::Position(unit->getPosition()), unit->getID(), getSparCraftPlayerID(unit->getPlayer()), unit->getHitPoints() + unit->getShields(), 0, BWAPI::Broodwar->getFrameCount(), BWAPI::Broodwar->getFrameCount()); }
void Micro::SmartRepair(BWAPI::Unit unit, BWAPI::Unit target) { UAB_ASSERT(unit, "SmartRightClick: Unit not valid"); UAB_ASSERT(target, "SmartRightClick: Target not valid"); if (!unit || !target) { return; } // if we have issued a command to this unit already this frame, ignore this one if (unit->getLastCommandFrame() >= BWAPI::Broodwar->getFrameCount() || unit->isAttackFrame()) { return; } // get the unit's current command BWAPI::UnitCommand currentCommand(unit->getLastCommand()); // if we've already told this unit to move to this position, ignore this command if ((currentCommand.getType() == BWAPI::UnitCommandTypes::Repair) && (currentCommand.getTarget() == target)) { return; } // if nothing prevents it, attack the target unit->repair(target); TotalCommands++; if (Config::Debug::DrawUnitTargetInfo) { BWAPI::Broodwar->drawCircleMap(unit->getPosition(), dotRadius, BWAPI::Colors::Cyan, true); BWAPI::Broodwar->drawCircleMap(target->getPosition(), dotRadius, BWAPI::Colors::Cyan, true); BWAPI::Broodwar->drawLineMap(unit->getPosition(), target->getPosition(), BWAPI::Colors::Cyan); } }
void Micro::SmartAttackUnit(BWAPI::Unit attacker, BWAPI::Unit target) { UAB_ASSERT(attacker, "SmartAttackUnit: Attacker not valid"); UAB_ASSERT(target, "SmartAttackUnit: Target not valid"); if (!attacker || !target) { 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 attack this target, ignore this command if (currentCommand.getType() == BWAPI::UnitCommandTypes::Attack_Unit && currentCommand.getTarget() == target) { return; } // if nothing prevents it, attack the target attacker->attack(target); TotalCommands++; if (Config::Debug::DrawUnitTargetInfo) { BWAPI::Broodwar->drawCircleMap(attacker->getPosition(), dotRadius, BWAPI::Colors::Red, true); BWAPI::Broodwar->drawCircleMap(target->getPosition(), dotRadius, BWAPI::Colors::Red, true); BWAPI::Broodwar->drawLineMap( attacker->getPosition(), target->getPosition(), BWAPI::Colors::Red ); } }
void Micro::SmartMove(BWAPI::Unit 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); } }
void GameCommander::setScoutUnits() { // if we haven't set a scout unit, do it if (_scoutUnits.size()<2 && !_initialScoutSet) { BWAPI::Unit supplyProvider = getFirstSupplyProvider(); // if it exists if (supplyProvider) { // grab the Zergling to the supply provider to send to scout BWAPI::UnitInterface * scout = nullptr; for (auto unit : BWAPI::Broodwar->self()->getUnits()) { if (unit->getType() == BWAPI::UnitTypes::Zerg_Zergling && !isAssigned(unit)) { scout = unit; } } // if we find a zergling add it to the scout units if (scout) { if (ScoutManager::Instance().setScout(scout)) assignUnit(scout, _scoutUnits); if (_scoutUnits.size() == 2) { if (Config::Modules::UsingWorkerScout) { // grab the closest worker to the supply provider to send to scout BWAPI::Unit workerScout = getClosestWorkerToTarget(supplyProvider->getPosition()); // if we find a worker (which we should) add it to the scout units if (workerScout) { ScoutManager::Instance().setWorkerScout(workerScout); assignUnit(workerScout, _scoutUnits); _initialScoutSet = true; } } _initialScoutSet = true; } } } } }
InformationManager::InformationManager(BWAPI::Unit unit) { selfMapInfor = new char*[BWAPI::Broodwar->mapHeight()]; enemyMapInfor = new char*[BWAPI::Broodwar->mapHeight()]; for (int i = 0; i < BWAPI::Broodwar->mapHeight(); i++){ selfMapInfor[i] = new char[BWAPI::Broodwar->mapWidth()]; enemyMapInfor[i] = new char[BWAPI::Broodwar->mapWidth()]; } for (int i = 0; i < BWAPI::Broodwar->mapHeight(); i++) for (int j = 0; j < BWAPI::Broodwar->mapWidth(); j++){ selfMapInfor[i][j] = 0; enemyMapInfor[i][j] = 0; } BWAPI::Position tmpPos; //set base position basePosition = unit->getPosition(); //put my Unit to mapInfor }
void BaitManager::update(const std::set<BWAPI::Unit *> & baitUnits) { //BWAPI::Broodwar->printf("BaitUnits:%d, Position:%d,%d", baitUnits.size(), baitPos.x(),baitPos.y()); if (baitUnits.size() == 1 && mapLoaded) { BWAPI::Unit * baitUnit = *baitUnits.begin(); //BWAPI::Broodwar->printf("Moving Bait Unit"); baitPos = baitUnit->getPosition(); if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawBoxMap(baitUnit->getPosition().x() - 3, baitUnit->getPosition().y() - 12, baitUnit->getPosition().x() + 3, baitUnit->getPosition().y() + 12, BWAPI::Colors::Purple, true); if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawCircleMap(baitUnit->getPosition().x(), baitUnit->getPosition().y(), 100, BWAPI::Colors::Purple, false); if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawCircleMap(baitUnit->getPosition().x(), baitUnit->getPosition().y(), 320, BWAPI::Colors::Green, false); if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawCircleMap(baitUnit->getPosition().x(), baitUnit->getPosition().y(), 300, BWAPI::Colors::Red, false); moveBait(baitUnit); } }
void AIModule::camera() { if (game->getMouseState(BWAPI::M_LEFT)) { return; } const int CENTER_SCREEN_X = 320; const int CENTER_SCREEN_Y = 140; if (!autocam) { return; } UnitGroup interestingUnits = AllUnits()(isAttacking); if (interestingUnits.size() == 0) { return; } BWAPI::Unit *unit = (*interestingUnits.begin()); BWAPI::Position unitPosition = unit->getPosition(); int x, y; x = unitPosition.x() - CENTER_SCREEN_X; y = unitPosition.y() - CENTER_SCREEN_Y; if (x < 0) { x = 0; } if (y < 0) { y = 0; } BWAPI::Broodwar->setScreenPosition(x, y); }
void TurkAnalyzer::onUnitComplete(BWAPI::Unit unit) { if (unit->getType().isBuilding() && !unit->getPlayer()->isNeutral()) { Position pos = unit->getPosition(); //int seconds = Broodwar->getFrameCount() / 24; //int minutes = seconds / 60; //seconds %= 60; Broodwar->sendText("%.2d:%.2d: %s completed a %s", pos, unit->getPlayer()->getName().c_str(), unit->getType().c_str()); if (unit->getType() == BWAPI::UnitTypes::Protoss_Gateway) { FirstGateExist = true; } else if (unit->getType() == BWAPI::UnitTypes::Protoss_Pylon) { FirstPylonExist = true; } else if (unit->getType() == BWAPI::UnitTypes::Protoss_Assimilator) { FirstGasExist = true; } else if (unit->getType() == BWAPI::UnitTypes::Protoss_Cybernetics_Core) { FirstCybernetics = true; PylonLimiter = 1; } else if (unit->getType() == BWAPI::UpgradeTypes::Singularity_Charge) { Singularity = true; } else if (unit->getType() == BWAPI::UnitTypes::Protoss_Citadel_of_Adun) { FirstAdun = true; } else if (unit->getType() == BWAPI::UpgradeTypes::Leg_Enhancements) { Leg_Enhancements = true; } } }
void Micro::MutaDanceTarget(BWAPI::Unit muta, BWAPI::Unit target) { UAB_ASSERT(muta, "MutaDanceTarget: Muta not valid"); UAB_ASSERT(target, "MutaDanceTarget: Target not valid"); if (!muta || !target) { return; } const int cooldown = muta->getType().groundWeapon().damageCooldown(); const int latency = BWAPI::Broodwar->getLatency(); const double speed = muta->getType().topSpeed(); const double range = muta->getType().groundWeapon().maxRange(); const double distanceToTarget = muta->getDistance(target); const double distanceToFiringRange = std::max(distanceToTarget - range,0.0); const double timeToEnterFiringRange = distanceToFiringRange / speed; const int framesToAttack = static_cast<int>(timeToEnterFiringRange) + 2*latency; // How many frames are left before we can attack? const int currentCooldown = muta->isStartingAttack() ? cooldown : muta->getGroundWeaponCooldown(); BWAPI::Position fleeVector = GetKiteVector(target, muta); BWAPI::Position moveToPosition(muta->getPosition() + fleeVector); // If we can attack by the time we reach our firing range if(currentCooldown <= framesToAttack) { // Move towards and attack the target muta->attack(target); } else // Otherwise we cannot attack and should temporarily back off { // Determine direction to flee // Determine point to flee to if (moveToPosition.isValid()) { muta->rightClick(moveToPosition); } } }
void ScoutManager::gasSteal() { if (!Config::Strategy::GasStealWithScout) { _gasStealStatus = "Not using gas steal"; return; } if (_didGasSteal) { return; } if (!_workerScout) { _gasStealStatus = "No worker scout"; return; } BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy()); if (!enemyBaseLocation) { _gasStealStatus = "No enemy base location found"; return; } BWAPI::Unit enemyGeyser = getEnemyGeyser(); if (!enemyGeyser) { _gasStealStatus = "No enemy geyser found"; false; } if (!_didGasSteal) { ProductionManager::Instance().queueGasSteal(); _didGasSteal = true; Micro::SmartMove(_workerScout, enemyGeyser->getPosition()); _gasStealStatus = "Did Gas Steal"; } }
bool UnitUtil::IsValidUnit(BWAPI::Unit unit) { if (!unit) { return false; } if (unit->isCompleted() && unit->getHitPoints() > 0 && unit->exists() && unit->getType() != BWAPI::UnitTypes::Unknown && unit->getPosition().x != BWAPI::Positions::Unknown.x && unit->getPosition().y != BWAPI::Positions::Unknown.y) { return true; } else { return false; } }
// is the unit valid? bool InformationManager::isValidUnit(BWAPI::Unit unit) { // we only care about our units and enemy units if (unit->getPlayer() != BWAPI::Broodwar->self() && unit->getPlayer() != BWAPI::Broodwar->enemy()) { return false; } // if it's a weird unit, don't bother if (unit->getType() == BWAPI::UnitTypes::None || unit->getType() == BWAPI::UnitTypes::Unknown || unit->getType() == BWAPI::UnitTypes::Zerg_Larva || unit->getType() == BWAPI::UnitTypes::Zerg_Egg) { return false; } // if the position isn't valid throw it out if (!unit->getPosition().isValid()) { return false; } // s'all good baby baby return true; }
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); } } } } } } } } }
void Micro::SmartKiteTarget(BWAPI::Unit rangedUnit, BWAPI::Unit target) { UAB_ASSERT(rangedUnit, "SmartKiteTarget: Unit not valid"); UAB_ASSERT(target, "SmartKiteTarget: Target not valid"); if (!rangedUnit || !target) { return; } double range(rangedUnit->getType().groundWeapon().maxRange()); if (rangedUnit->getType() == BWAPI::UnitTypes::Protoss_Dragoon && BWAPI::Broodwar->self()->getUpgradeLevel(BWAPI::UpgradeTypes::Singularity_Charge)) { range = 6*32; } // determine whether the target can be kited bool kiteLonger = Config::Micro::KiteLongerRangedUnits.find(rangedUnit->getType()) != Config::Micro::KiteLongerRangedUnits.end(); if (!kiteLonger && (range <= target->getType().groundWeapon().maxRange())) { //if we can't kite it, there's no point Micro::SmartAttackUnit(rangedUnit, target); return; } bool kite(true); double dist(rangedUnit->getDistance(target)); double speed(rangedUnit->getType().topSpeed()); // if the unit can't attack back don't kite if ((rangedUnit->isFlying() && !UnitUtil::CanAttackAir(target)) || (!rangedUnit->isFlying() && !UnitUtil::CanAttackGround(target))) { kite = false; } double timeToEnter = std::max(0.0,(dist - range) / speed); if ((timeToEnter >= rangedUnit->getGroundWeaponCooldown())) { kite = false; } if (target->getType().isBuilding()) { kite = false; } // if we can't shoot, run away if (kite) { //BWAPI::Broodwar->printf("Kite"); BWAPI::Position fleePosition(rangedUnit->getPosition() - target->getPosition() + rangedUnit->getPosition()); BWAPI::Broodwar->drawLineMap(rangedUnit->getPosition(), fleePosition, BWAPI::Colors::Cyan); Micro::SmartMove(rangedUnit, fleePosition); } // otherwise shoot else { //BWAPI::Broodwar->printf("Not kite"); Micro::SmartAttackUnit(rangedUnit, target); } }
// calculates whether or not to regroup bool Squad::needsToRegroup() { if (!Config::Micro::UseSparcraftSimulation) { return false; } // if we are not attacking, never regroup if (_units.empty() || (_order.getType() != SquadOrderTypes::Attack)) { _regroupStatus = std::string("\x04 No combat units available"); return false; } BWAPI::Unit unitClosest = unitClosestToEnemy(); if (!unitClosest) { _regroupStatus = std::string("\x04 No closest unit"); return false; } // if none of our units are in attack range of any enemy units, don't retreat std::vector<UnitInfo> enemyCombatUnits; const auto & enemyUnitInfo = InformationManager::Instance().getUnitInfo(BWAPI::Broodwar->enemy()); bool anyInRange = false; for (const auto & eui : enemyUnitInfo) { bool inRange = false; for (const auto & u : _units) { int range = UnitUtil::GetAttackRange(eui.second.type, u->getType()); if (range + 128 >= eui.second.lastPosition.getDistance(u->getPosition())) { inRange = true; break; } } if (inRange) { anyInRange = true; break; } } if (!anyInRange) { _regroupStatus = std::string("\x04 No enemy units in attack range"); return false; } SparCraft::ScoreType score = 0; //do the SparCraft Simulation! CombatSimulation sim; sim.setCombatUnits(unitClosest->getPosition(), Config::Micro::CombatRegroupRadius); score = sim.simulateCombat(); // if we are DT rushing and we haven't lost a DT yet, no retreat! if (Config::Strategy::StrategyName == "Protoss_DTRush" && (BWAPI::Broodwar->self()->deadUnitCount(BWAPI::UnitTypes::Protoss_Dark_Templar) == 0)) { _regroupStatus = std::string("\x04 DARK TEMPLAR HOOOOO!"); return false; } bool retreat = score < 0; int switchTime = 100; bool waiting = false; // we should not attack unless 5 seconds have passed since a retreat if (retreat != _lastRetreatSwitchVal) { if (!retreat && (BWAPI::Broodwar->getFrameCount() - _lastRetreatSwitch < switchTime)) { waiting = true; retreat = _lastRetreatSwitchVal; } else { waiting = false; _lastRetreatSwitch = BWAPI::Broodwar->getFrameCount(); _lastRetreatSwitchVal = retreat; } } if (retreat) { _regroupStatus = std::string("\x04 Retreat - simulation predicts defeat"); } else { _regroupStatus = std::string("\x04 Attack - simulation predicts success"); } return retreat; }
int RangedManager::getPriorityDefault(BWAPI::Unit rangedUnit, BWAPI::Unit target) { BWAPI::UnitType rangedType = rangedUnit->getType(); BWAPI::UnitType targetType = target->getType(); if (target->getType() == BWAPI::UnitTypes::Zerg_Overlord) return 1; if (target->getType() == BWAPI::UnitTypes::Protoss_Photon_Cannon || target->getType() == BWAPI::UnitTypes::Zerg_Sunken_Colony) { return 8; } if (rangedUnit->getType() == BWAPI::UnitTypes::Zerg_Scourge) { if (target->getType() == BWAPI::UnitTypes::Protoss_Carrier) { return 100; } if (target->getType() == BWAPI::UnitTypes::Protoss_Corsair) { return 90; } } bool isThreat = rangedType.isFlyer() ? targetType.airWeapon() != BWAPI::WeaponTypes::None : targetType.groundWeapon() != BWAPI::WeaponTypes::None; if (target->getType().isWorker()) { isThreat = false; } if (target->getType() == BWAPI::UnitTypes::Zerg_Larva || target->getType() == BWAPI::UnitTypes::Zerg_Egg) { return 0; } if (rangedUnit->isFlying() && target->getType() == BWAPI::UnitTypes::Protoss_Carrier) { return 101; } // if the target is building something near our base something is fishy // highest priority is something that can attack us or aid in combat if (targetType == BWAPI::UnitTypes::Terran_Bunker || isThreat) { return 11; } // next priority is worker else if (targetType.isWorker()) { if (order.getType() != SquadOrderTypes::Defend&&BWTA::getRegion(rangedUnit->getPosition()) != BWTA::getRegion(BWAPI::Broodwar->self()->getStartLocation())) { return 4; } else return 1; } // next is special buildings else if (targetType == BWAPI::UnitTypes::Zerg_Spawning_Pool) { return 5; } // next is special buildings else if (targetType == BWAPI::UnitTypes::Protoss_Pylon) { return 5; } // next is buildings that cost gas else if (targetType.gasPrice() > 0) { return 4; } else if (targetType.mineralPrice() > 0) { return 3; } // then everything else else { return 1; } }
void RangedManager::assignTargetsOld(const BWAPI::Unitset & targets) { const BWAPI::Unitset & rangedUnits = getUnits(); // figure out targets BWAPI::Unitset rangedUnitTargets; for (auto & target : targets) { // conditions for targeting if (!(target->getType() == BWAPI::UnitTypes::Zerg_Larva) && !(target->getType() == BWAPI::UnitTypes::Zerg_Egg) && !(target->getType() == BWAPI::UnitTypes::Buildings) && (target->isTargetable()) && target->isVisible() && target->getType() != BWAPI::UnitTypes::Resource_Vespene_Geyser) { rangedUnitTargets.insert(target); } } auto attacker2target = assignEnemy(rangedUnits, rangedUnitTargets); BWAPI::Position shome = BWAPI::Position(BWTA::getStartLocation(BWAPI::Broodwar->self())->getPosition()); BWAPI::Unitset _rangedUnits = rangedUnits; auto _rangedUnitTargets = rangedUnitTargets; int maxChoices = rangedUnits.size() / 3 + 1, i = 0; std::map<BWAPI::Unit, std::pair<BWAPI::Unit, BWAPI::Unit> > dodgeUnits; BWAPI::Unitset threatens; for (BWAPI::Unit threatenClosest = NULL, unitClosetEnemy = NULL;;) { if (i++ > maxChoices) break; double dist = BWAPI::Broodwar->self()->getUpgradeLevel(BWAPI::UpgradeTypes::Singularity_Charge)?96:96; double enerange = BWAPI::Broodwar->self()->getUpgradeLevel(BWAPI::UpgradeTypes::Singularity_Charge) ? 80 : 80; for (auto & rangedUnit : _rangedUnits) { for (auto target : _rangedUnitTargets) { if (target->getType().isWorker() || (target->getType().isBuilding())) continue; if (target->getType().groundWeapon().maxRange() <= enerange) { if (rangedUnit->getDistance(target) < dist) { threatenClosest = target; unitClosetEnemy = rangedUnit; dist = rangedUnit->getDistance(target); } } } } if (threatenClosest != NULL) { threatens.insert(threatenClosest); BWAPI::Broodwar->drawCircleMap(threatenClosest->getPosition(), 2, BWAPI::Colors::Red, true); auto vec1 = unitClosetEnemy->getPosition() - threatenClosest->getPosition(); dodgeUnits[unitClosetEnemy] = std::make_pair(unitClosetEnemy, threatenClosest); auto __rangedUnits = rangedUnits; for (auto rangedUnit:__rangedUnits) { if (rangedUnit->getDistance(unitClosetEnemy) > unitClosetEnemy->getDistance(threatenClosest)+64) continue; auto vec2 = rangedUnit->getPosition() - threatenClosest->getPosition(); int judge = (vec1.x*vec2.x + vec1.y*vec2.y)*(vec1.x*vec2.x + vec1.y*vec2.y); if (judge * 6 > (vec1.x*vec1.x + vec1.y*vec1.y)*(vec2.x*vec2.x + vec2.y*vec2.y) * 5) { dodgeUnits[rangedUnit] = std::make_pair(unitClosetEnemy, threatenClosest); _rangedUnits.erase(rangedUnit); } } } else break; } BWAPI::Unitset withoutBuildingsAndWorkers = rangedUnitTargets; auto _withoutBuildingsAndWorkers = withoutBuildingsAndWorkers; for (auto target : _withoutBuildingsAndWorkers) if (target->getType().isBuilding() || target->getType().isWorker()) withoutBuildingsAndWorkers.erase(target); for (auto & rangedUnit : rangedUnits) { // train sub units such as scarabs or interceptors //trainSubUnits(rangedUnit); // if the order is to attack or defend int chokeZealot = 0; for (const auto & zealot : BWAPI::Broodwar->self()->getUnits()) { // trivial case: unit which exists matches the type if (zealot->getType() != BWAPI::UnitTypes::Protoss_Zealot) continue; if (zealot->isCompleted() == false) continue; auto ckpt = BWTA::getNearestChokepoint(zealot->getPosition()); if (zealot->getDistance(rangedUnit->getPosition()) < 300) { if (ckpt && ckpt->getWidth()<256 && ckpt->getCenter().getDistance(zealot->getPosition()) < 128) chokeZealot += 3; else chokeZealot += 1; } } bool danceMode; if (order.getType() == SquadOrderTypes::Defend) danceMode = chokeZealot < 3 && rangedUnits.size()<20; else danceMode = chokeZealot < 3 && rangedUnits.size()<20; if (order.getType() == SquadOrderTypes::Attack || order.getType() == SquadOrderTypes::Defend) { // if there are targets if (!rangedUnitTargets.empty()) { // find the best target for this zealot auto targetIdx = attacker2target.find(rangedUnit); BWAPI::Unit target = targetIdx == attacker2target.end() ? getTarget(rangedUnit, rangedUnitTargets) : targetIdx->second; // attack it if (dodgeUnits.find(rangedUnit) == dodgeUnits.end()) { Micro::SmartAttackUnit(rangedUnit, target); } else { if (danceMode) Micro::SmartKiteTarget(rangedUnit, target, dodgeUnits[rangedUnit].second, withoutBuildingsAndWorkers); else Micro::SmartAttackUnit(rangedUnit, target); //modified //BWAPI::Broodwar->sendText("%s", "old kite"); //Micro::SmartKiteTarget(rangedUnit, dodgeUnits[rangedUnit].second); } } // if there are no targets else { Micro::SmartAttackMove(rangedUnit, order.getPosition()); } } } }
int RangedManager::getAttackPriority(BWAPI::Unit attacker, BWAPI::Unit unit) { auto closestCarrier = UnitUtil::GetClosestOurUnitTypeToTarget(BWAPI::UnitTypes::Protoss_Carrier, attacker->getPosition()); if (closestCarrier&&closestCarrier->isCompleted()&&closestCarrier->getDistance(unit)<unit->getType().airWeapon().maxRange()) return getPrioritySaveCarrier(attacker, unit); else return getPriorityDefault(attacker, unit); }
void ExampleAIModule::onUnitComplete(BWAPI::Unit unit) { Broodwar->sendText("unit completed! id = %d positionX = %d, positionY = %d", unit->getID(), unit->getPosition().x, unit->getPosition().y); std::ofstream fileFerran; fileFerran.open("bwapi-data\\logs\\fileFerran.txt"); fileFerran << "unit id " << unit->getID(); fileFerran.close(); }
void BaseManager::update() { for(std::set<Base*>::iterator b = this->allBases.begin(); b != this->allBases.end(); b++) { Base *base = (*b); // periodicky check, ci baza pouziva najblizsi resource depot if (BWAPI::Broodwar->getFrameCount() % 300 == 231) { BWAPI::TilePosition tilePosition = base->getBaseLocation()->getTilePosition(); BWAPI::Position position = BWAPI::Position(tilePosition); UnitGroup centers = UnitGroup::getUnitGroup(BWAPI::Broodwar->getUnitsInRadius(position, 600)) (BWAPI::Broodwar->self()) (isResourceDepot); UnitGroup::iterator it; BWAPI::Unit *nearestCenter = NULL; double distance = 10000; for (it = centers.begin(); it != centers.end(); it++) { BWAPI::Unit *centerCandidate = (*it); dementor::Vector vector = dementor::Vector::fromPositions(position, centerCandidate->getPosition()); if (vector.getLength() < distance) { nearestCenter = centerCandidate; distance = vector.getLength(); } } if (nearestCenter != NULL) { base->setResourceDepot(nearestCenter); } if (base->getResourceDepot() != NULL) { if (!base->getResourceDepot()->exists()) { base->setResourceDepot(NULL); } else if (base->getResourceDepot()->isCompleted() || base->getResourceDepot()->getRemainingBuildTime() < 250) { base->setActive(true); } } } //Set Refinerys if (!base->isActiveGas() && base->hasGas()) { if (base->getRefinery() == NULL) { std::set<BWAPI::Unit*> baseGeysers = (*b)->getBaseLocation()->getGeysers(); BWAPI::TilePosition geyserLocation; //cycle through geysers & get tile location for(std::set<BWAPI::Unit*>::iterator bg = baseGeysers.begin(); bg != baseGeysers.end(); bg++) { geyserLocation = (*bg)->getTilePosition(); } //check for refinery already on geyser std::set<BWAPI::Unit*> unitsOnGeyser = BWAPI::Broodwar->getUnitsOnTile(geyserLocation.x(),geyserLocation.y()); for(std::set<BWAPI::Unit*>::iterator u = unitsOnGeyser.begin(); u != unitsOnGeyser.end(); u++) { BWAPI::Unit *unit = (*u); if (unit->getPlayer() == BWAPI::Broodwar->self() && unit->getType().isRefinery()) { base->setRefinery(*u); break; } } } if (base->getRefinery() != NULL) { if (!base->getRefinery()->exists()) { base->setResourceDepot(NULL); } else { if (base->getRefinery()->isCompleted() || base->getRefinery()->getRemainingBuildTime() < 250) { base->setActiveGas(true); } } } } } //check to see if any new base locations need to be added for(std::set<BWTA::BaseLocation*>::const_iterator bl = BWTA::getBaseLocations().begin(); bl != BWTA::getBaseLocations().end(); bl++) { if (location2base.find(*bl) == location2base.end()) { BWAPI::TilePosition tile = (*bl)->getTilePosition(); std::set<BWAPI::Unit*> units = BWAPI::Broodwar->getUnitsOnTile(tile.x(), tile.y()); for(std::set<BWAPI::Unit*>::iterator u = units.begin(); u != units.end(); u++) { if ((*u)->getPlayer() == BWAPI::Broodwar->self() && (*u)->getType().isResourceDepot()) { addBase(*bl); } } } } if(BWAPI::Broodwar->getFrameCount() % 500 == 0 && BWAPI::Broodwar->getFrameCount() >= 3000 && refineryBuildPriority > 0) { updateRefineries(); } }
void DevAIModule::onUnitEvade(BWAPI::Unit unit) { if (unit->getType() == UnitTypes::Spell_Scanner_Sweep) { Broodwar << "evade @ " << unit->getPosition() << std::endl; } }
void ZerglingMicro::micro(BWAPI::Unit* unit) { Task task = this->hc->ta->getTaskOfUnit(unit); UnitGroup allies = allEigenUnits().inRadius(dist(12), unit->getPosition()); UnitGroup enemiesground = allEnemyUnits().inRadius(dist(10), unit->getPosition()).not(isFlyer); UnitGroup enemiesair = allEnemyUnits().inRadius(dist(7), unit->getPosition())(isFlyer); if(amountCanAttackGround(enemiesair) > 0 && amountCanAttackAir(allies) == 0) { unit->move(moveAway(unit)); } else { if(task.getType() == ScoutTask) { if(allEnemyUnits().not(isBuilding).inRadius(dist(4), unit->getPosition()).size() > 0) { unit->move(moveAway(unit)); } else { if(unit->getDistance(task.getPosition()) < dist(4) && BWAPI::Broodwar->isVisible(BWAPI::TilePosition(task.getPosition()))) { if(!unit->isMoving()) { int x = unit->getPosition().x(); int y = unit->getPosition().y(); int factor = dist(10); int newx = x + (((rand() % 30)-15)*factor); int newy = y + (((rand() % 30)-15)*factor); unit->move(BWAPI::Position(newx, newy).makeValid()); } } else { unit->move(task.getPosition()); } } } else { UnitGroup swarms = allUnits()(Dark_Swarm); BWAPI::Unit* swarm = getNearestUnit(unit->getPosition(), swarms); if(swarm != NULL && swarm->getPosition().getDistance(unit->getPosition()) < dist(9)) { if(!isUnderDarkSwarm(unit) && !unit->isAttacking()) { unit->attack(swarm->getPosition()); } else { UnitGroup enemiesunderswarm = allEnemyUnits().inRadius(dist(6), unit->getPosition()).not(isFlyer); if(!unit->isAttacking() && enemiesunderswarm.size() > 0) { unit->attack(getNearestUnit(unit->getPosition(), enemiesunderswarm)); } } } else { if(allies.size() < amountCanAttackGround(enemiesground)) { unit->move(moveAway(unit)); } else { if(enemiesground.inRadius(dist(3), unit->getPosition()).size() > 0) { // game AI } else { if(enemiesground.size() > 0) { BWAPI::Unit* nearest = getNearestUnit(unit->getPosition(), enemiesground); unit->attack(nearest); } else { UnitGroup* ug = this->hc->eiugm->getGroupOfUnit(unit); if(ug != NULL && tooSplitUp(dist(7), *ug)) { BWAPI::Unit* nearest = getNearestUnit(ug->getCenter(), *ug); unit->attack(nearest); } else { unit->move(task.getPosition()); } } } } } } } }
int LurkerManager::targetsInRange(BWAPI::Unit LurkerUnit, const BWAPI::Unitset & targets) { BWAPI::Unitset nearbyEnemies; MapGrid::Instance().GetUnits(nearbyEnemies, LurkerUnit->getPosition() , BWAPI::UnitTypes::Zerg_Lurker.seekRange() + 10, false, true); return nearbyEnemies.size(); }