|
BWAPI
|
#include <BasicUnitAction.h>


Public Member Functions | |
| BasicUnitAction (Unit unit, const std::list< std::set< BWAPI::UnitType >> &targetPriorities) | |
| bool | update (const Goal &squadGoal, const UnitGroup &squadUnitGroup) |
Private Attributes | |
| std::list< std::set < BWAPI::UnitType > > | mTargetPriorities |
Definition at line 6 of file BasicUnitAction.h.
| BasicUnitAction::BasicUnitAction | ( | Unit | unit, |
| const std::list< std::set< BWAPI::UnitType >> & | targetPriorities | ||
| ) | [inline] |
Definition at line 9 of file BasicUnitAction.h.
: SingleMicroActionBaseClass(unit), mTargetPriorities(targetPriorities) {}
| bool BasicUnitAction::update | ( | const Goal & | squadGoal, |
| const UnitGroup & | squadUnitGroup | ||
| ) | [virtual] |
Implements SingleMicroActionBaseClass.
Definition at line 22 of file BasicUnitAction.cpp.
References ActionTypeDef::Attack, BWAPI::Broodwar, ActionTypeDef::Defend, BWAPI::TechTypes::EMP_Shockwave, BWAPI::TechType::energyUsed(), Goal::getActionType(), BWAPI::Game::getRemainingLatencyFrames(), BWAPI::TechType::getWeapon(), ActionTypeDef::Hold, Singleton< T >::Instance(), UnitHelper::isArmyUnit(), UnitHelper::isStaticDefense(), BWAPI::UnitType::isWorker(), AccessTypeDef::Lost, BWAPI::WeaponType::maxRange(), mTargetPriorities, SingleMicroActionBaseClass::mUnit, BWAPI::UnitTypes::Protoss_Arbiter, BWAPI::UnitTypes::Protoss_Scarab, BWAPI::UnitTypes::Protoss_Zealot, ActionTypeDef::Retreat, BWAPI::UnitType::seekRange(), stayAtRange(), BWAPI::UnitType::supplyProvided(), BWAPI::UnitTypes::Terran_Bunker, BWAPI::UnitTypes::Terran_Science_Vessel, BWAPI::UnitTypes::Terran_Vulture_Spider_Mine, BWAPI::UnitType::topSpeed(), BWAPI::UnitTypes::Zerg_Egg, and BWAPI::UnitTypes::Zerg_Larva.
{
const int seekRange = 448;
// TODO: Implement a better system, maybe some PFs and other goodies
// currently a copy paste of 2010 micro
if(mUnit->isAttackFrame() || mUnit->isStasised() || mUnit->isLockedDown())
return true;
const bool isTargetOfThreat = AOEThreatTracker::Instance().isTargetOfThreat(mUnit);
if(!isTargetOfThreat)
{
const AOEThreat &closestThreat = AOEThreatTracker::Instance().getClosestThreat(mUnit);
if(closestThreat)
{
const int distanceToThreat = mUnit->getDistance(closestThreat->getPosition());
if(distanceToThreat < closestThreat->getRadius()+32)
{
stayAtRange(mUnit, closestThreat->getPosition(), closestThreat->getRadius() + 64, distanceToThreat);
return true;
}
}
}
const BWAPI::UnitType &actionUnitType = mUnit->getType();
const bool shouldEngage = squadGoal.getActionType() == ActionType::Attack || squadGoal.getActionType() == ActionType::Defend || squadGoal.getActionType() == ActionType::Hold;
int currentTargetPriority = std::numeric_limits<int>::max();
Unit currentTargetUnit;
int goalTartgetDistance = std::numeric_limits<int>::max();
int goalTargetPriority = std::numeric_limits<int>::max();
Unit goalTargetUnit;
int closestUnitDistance = std::numeric_limits<int>::max();
int closestUnitRange = 0;
Unit closestUnit;
UnitGroup possibleTargets;
for each(Unit unit in UnitTracker::Instance().selectAllEnemy())
{
if(unit->isStasised())
continue;
const BWAPI::UnitType &type = unit->getType();
if(type == BWAPI::UnitTypes::Zerg_Egg || type == BWAPI::UnitTypes::Zerg_Larva || type == BWAPI::UnitTypes::Protoss_Scarab)
continue;
if(unit->accessibility() == AccessType::Lost)
continue;
if(mUnit->getPosition().getApproxDistance(unit->getPosition()) > seekRange)
continue;
if(unit->canAttack(mUnit) || type == BWAPI::UnitTypes::Terran_Science_Vessel)
{
const int weaponRange = type == BWAPI::UnitTypes::Terran_Science_Vessel ? BWAPI::TechTypes::EMP_Shockwave.getWeapon().maxRange() : type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine ? BWAPI::UnitTypes::Terran_Vulture_Spider_Mine.seekRange() : unit->getWeaponMaxRange(mUnit);
const int distance = mUnit->getDistance(unit) - weaponRange;
if(distance < closestUnitDistance)
{
closestUnitRange = weaponRange;
closestUnitDistance = distance;
closestUnit = unit;
}
}
if(type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine && actionUnitType == BWAPI::UnitTypes::Protoss_Zealot)
continue;
if(!mUnit->canAttackNow(unit))
continue;
//TODO: health tracker of some type, if the unit will be dead by the time the bullet hits, continue
const bool isActionUnitSlower = actionUnitType.topSpeed()*0.7 < type.topSpeed();
const bool isUnitGoalWorthy = (shouldEngage && squadGoal.getEngageUnits().count(unit) != 0) || unit->isInRange(mUnit) || mUnit->isInRange(unit);
int unitPriority = isUnitGoalWorthy ? 0 : isActionUnitSlower ? 4 : 2;
std::list<std::set<BWAPI::UnitType>>::const_iterator it = mTargetPriorities.begin();
while(it != mTargetPriorities.end())
{
if(it->count(type) != 0)
break;
else
++unitPriority;
++it;
}
if(it == mTargetPriorities.end())//Unit not found in the priorities list
{
if(UnitHelper::isArmyUnit(type) || UnitHelper::isStaticDefense(type) || type == BWAPI::UnitTypes::Terran_Bunker)
unitPriority += 1;
else if(type.isWorker())
unitPriority += 2;
else if(type.supplyProvided() > 0)
unitPriority += 3;
else
unitPriority += 4;
if(!unit->isCompleted())
unitPriority += 1;
}
if(squadGoal.getActionType() != ActionType::Retreat && mUnit->isInRange(unit))
{
if(unitPriority < currentTargetPriority || (unitPriority == currentTargetPriority && unit->totalHitPointFraction() < currentTargetUnit->totalHitPointFraction()))
{
currentTargetPriority = unitPriority;
currentTargetUnit = unit;
}
}
if(!isUnitGoalWorthy && isActionUnitSlower)
continue;
const int distance = mUnit->getDistance(unit);
if(unitPriority < goalTargetPriority || (unitPriority == goalTargetPriority && distance < goalTartgetDistance))
{
goalTartgetDistance = distance;
goalTargetPriority = unitPriority;
goalTargetUnit = unit;
}
}
// If the target of a threat, dont do anything to cause it to move
if(isTargetOfThreat)
{
if(currentTargetUnit)
mUnit->attack(currentTargetUnit);
else
mUnit->stop();
return true;
}
const int closestDistance = closestUnit ? mUnit->getDistance(closestUnit) : 0;
if(closestUnit)
{
bool doNotEngageClosest = false;
if(closestDistance < closestUnitRange + 250)
{
if(squadGoal.getAvoidUnits().count(closestUnit) != 0)
doNotEngageClosest = true;
else
doNotEngageClosest = !goalTargetUnit && mUnit->getDistance(squadGoal.getPositionForMerge()) < 140;
}
if(doNotEngageClosest)
{
stayAtRange(mUnit, closestUnit->getPosition(), closestUnitRange + 290, closestDistance);
return true;
}
bool canAttack = mUnit->canAttackAir() || mUnit->canAttackGround();
if(actionUnitType == BWAPI::UnitTypes::Protoss_Arbiter)
canAttack = false;
if(!canAttack && actionUnitType.isSpellcaster())
{
for each(BWAPI::TechType tech in mUnit->getType().abilities())
{
if(BWAPI::Broodwar->self()->hasResearched(tech) && mUnit->getEnergy() >= tech.energyUsed())
canAttack = true;
}
}
int rangeToStayAt = 0;
if(!canAttack)
rangeToStayAt = closestUnitRange+32;
if(actionUnitType.maxEnergy() > 0 && closestUnit->getType() == BWAPI::UnitTypes::Terran_Science_Vessel)
rangeToStayAt = std::max(rangeToStayAt, BWAPI::TechTypes::EMP_Shockwave.getWeapon().maxRange()+32);
if(rangeToStayAt != 0 && closestDistance < rangeToStayAt)
{
stayAtRange(mUnit, closestUnit->getPosition(), rangeToStayAt, closestDistance);
return true;
}
}
const bool canAttackCurrentTarget = currentTargetUnit && mUnit->getRemainingCooldown(currentTargetUnit) <= BWAPI::Broodwar->getRemainingLatencyFrames();
const bool isCurrentTargetImportant = currentTargetUnit && (UnitHelper::isArmyUnit(currentTargetUnit->getType()) || UnitHelper::isStaticDefense(currentTargetUnit->getType()));
const bool goalBetterThanCurrent = canAttackCurrentTarget && goalTargetPriority < currentTargetPriority && !isCurrentTargetImportant;
if(goalBetterThanCurrent)
{
mUnit->attack(goalTargetUnit);
return true;
}
else if(canAttackCurrentTarget)
{
mUnit->attack(currentTargetUnit);
return true;
}
if(closestUnit && !goalTargetUnit && closestUnit->getType() == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine)
{
if(closestDistance < BWAPI::UnitTypes::Terran_Vulture_Spider_Mine.seekRange()+32)
{
stayAtRange(mUnit, closestUnit->getPosition(), BWAPI::UnitTypes::Terran_Vulture_Spider_Mine.seekRange()+32, closestDistance);
return true;
}
}
if(closestUnit && closestUnit->exists() && currentTargetUnit)
{
if(mUnit->canAttack(closestUnit))
{
const int myRange = mUnit->getWeaponMaxRange(closestUnit);
if(closestDistance < myRange && myRange > 60)
{
stayAtRange(mUnit, closestUnit->getPosition(), myRange, closestDistance);
return true;
}
}
}
if(goalTargetUnit && goalTargetPriority < currentTargetPriority)
{
mUnit->attack(goalTargetUnit);
return true;
}
if(!canAttackCurrentTarget)
{
if(squadGoal.getActionType() == ActionType::Attack)
{
if(!isCurrentTargetImportant && mUnit->getDistance(currentTargetUnit) > 5)
{
mUnit->move(currentTargetUnit->getPosition());
return true;
}
}
}
if(currentTargetUnit)
{
mUnit->attack(currentTargetUnit);
return true;
}
if(closestUnit && mUnit->canAttack(closestUnit))
{
mUnit->attack(closestUnit);
return true;
}
return false;
}
std::list<std::set<BWAPI::UnitType> > BasicUnitAction::mTargetPriorities [private] |
Definition at line 14 of file BasicUnitAction.h.
Referenced by update().
1.7.6.1