|
BWAPI
|
#include <PsiStormAction.h>


Public Member Functions | |
| PsiStormAction (Unit unit) | |
| bool | update (const Goal &squadGoal, const UnitGroup &squadUnitGroup) |
Definition at line 6 of file PsiStormAction.h.
| PsiStormAction::PsiStormAction | ( | Unit | unit | ) | [inline] |
Definition at line 9 of file PsiStormAction.h.
: SingleMicroActionBaseClass(unit) {}
| bool PsiStormAction::update | ( | const Goal & | squadGoal, |
| const UnitGroup & | squadUnitGroup | ||
| ) | [virtual] |
Implements SingleMicroActionBaseClass.
Definition at line 8 of file PsiStormAction.cpp.
References BWAPI::TechTypes::Archon_Warp, BWAPI::Orders::ArchonWarp, ActionTypeDef::Attack, GoalTypeDef::Base, BWAPI::Broodwar, BWAPI::Orders::CastPsionicStorm, UnitGroup::empty(), BWAPI::TechType::energyUsed(), UnitGroup::erase(), Goal::getActionType(), Goal::getBase(), UnitGroup::getBestFittingToCircle(), UnitGroup::getCenter(), Goal::getGoalType(), BWAPI::Game::getRemainingLatencyFrames(), BWAPI::TechType::getWeapon(), BWAPI::Errors::Incompatible_TechType, Singleton< T >::Instance(), BWAPI::UnitType::isBuilding(), LOGMESSAGEERROR, BWAPI::WeaponType::maxRange(), SingleMicroActionBaseClass::mUnit, Vector::normalise(), BWAPI::UnitTypes::Protoss_High_Templar, BWAPI::UnitTypes::Protoss_Interceptor, BWAPI::UnitTypes::Protoss_Scarab, BWAPI::TechTypes::Psionic_Storm, UnitGroup::size(), BWAPI::UnitTypes::Terran_Vulture_Spider_Mine, BWAPI::UnitTypes::Zerg_Egg, and BWAPI::UnitTypes::Zerg_Larva.
{
if(mUnit->getOrder() == BWAPI::Orders::CastPsionicStorm)
return true;
//TODO : Morph arcon temp in here with some non ideal code till group micro actions is complete, checks if it can actually morph the archon,
// ie not using 3.6
static bool allowsArchonMorph = true;
if(allowsArchonMorph)
{
if(mUnit->getOrder() == BWAPI::Orders::ArchonWarp)
return true;
bool warpPriorityLow = squadGoal.getActionType() != ActionType::Attack || squadGoal.getGoalType() != GoalType::Base || mUnit->getPosition().getApproxDistance(squadGoal.getBase()->getCenterLocation()) > 32*20;
const int energyToTransformAt = warpPriorityLow ? 48 : 65;
if(mUnit->getEnergy() <= energyToTransformAt)
{
Unit otherTemp;
int closestDistance = std::numeric_limits<int>::max();
for each(Unit ht in UnitTracker::Instance().selectAllUnits(BWAPI::UnitTypes::Protoss_High_Templar))
{
if(ht == mUnit)
continue;
if(ht->getOrder() == BWAPI::Orders::ArchonWarp)
continue;
if(ht->getEnergy() > energyToTransformAt)
continue;
int distance = mUnit->getDistance(ht);
if(distance < closestDistance)
{
closestDistance = distance;
otherTemp = ht;
}
}
if(otherTemp)
{
Unit otherClosestTemp;
int otherClosestDistance = std::numeric_limits<int>::max();
for each(Unit ht in UnitTracker::Instance().selectAllUnits(BWAPI::UnitTypes::Protoss_High_Templar))
{
if(ht == otherTemp)
continue;
if(ht->getOrder() == BWAPI::Orders::ArchonWarp)
continue;
if(ht->getEnergy() > energyToTransformAt)
continue;
int distance = otherTemp->getDistance(ht);
if(distance < otherClosestDistance)
{
otherClosestDistance = distance;
otherClosestTemp = ht;
}
}
if(otherClosestTemp == mUnit)
{
mUnit->useTech(BWAPI::TechTypes::Archon_Warp, otherTemp);
otherTemp->useTech(BWAPI::TechTypes::Archon_Warp, mUnit);
if(BWAPI::Broodwar->getLastError() == BWAPI::Errors::Incompatible_TechType)
{
LOGMESSAGEERROR("Archon Warp Failed, Old BWAPI Version?");
allowsArchonMorph = false;
}
return true;
}
}
}
}
if(mUnit->getSpellCooldown() > BWAPI::Broodwar->getRemainingLatencyFrames())
return false;
if(BWAPI::Broodwar->self()->hasResearched(BWAPI::TechTypes::Psionic_Storm) && mUnit->getEnergy() >= BWAPI::TechTypes::Psionic_Storm.energyUsed())
{
int numTargetting = UnitInformation::Instance().getUnitsTargetting(mUnit).size();
UnitGroup targetsToChooseFrom;
for each(Unit unit in UnitTracker::Instance().selectAllEnemy())
{
if(!unit->exists() || unit->isStasised() || unit->isUnderStorm())
continue;
const BWAPI::UnitType &type = unit->getType();
if(type.isBuilding() || type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine || type == BWAPI::UnitTypes::Zerg_Egg || type == BWAPI::UnitTypes::Protoss_Interceptor || type == BWAPI::UnitTypes::Zerg_Larva || type == BWAPI::UnitTypes::Protoss_Scarab)
continue;
if(mUnit->getDistance(unit) > BWAPI::TechTypes::Psionic_Storm.getWeapon().maxRange())
continue;
targetsToChooseFrom.insert(unit);
}
UnitGroup targets(targetsToChooseFrom);
bool castUrgenty = (numTargetting > 2 || (numTargetting > 0 && mUnit->totalHitPointFraction() < 0.6));
int tries = 0;
bool tryAgain = true;
while(tryAgain)
{
tryAgain = false;
/* There are 3 targets or there are targets and we need to cast urgently */
if(targets.size() >= 3 || (castUrgenty && !targets.empty()))
{
targets = targets.getBestFittingToCircle(64, BWAPI::Broodwar->getRemainingLatencyFrames()+BWAPI::Broodwar->getLatencyFrames());
if(targets.size() >= 3 || (castUrgenty && !targets.empty()))
{
BWAPI::Position castLocation = targets.getCenter();
int inStormCount = 0;
for each(Unit unit in UnitTracker::Instance().selectAllUnits())
{
if(!unit->isUnderStorm() && unit->getDistance(castLocation) < 64)
++inStormCount;
if(inStormCount > 1)
break;
}
if(inStormCount <= 1)
{
int distanceToStorm = mUnit->getDistance(castLocation);
if(distanceToStorm <= BWAPI::TechTypes::Psionic_Storm.getWeapon().maxRange())
{
mUnit->useTech(BWAPI::TechTypes::Psionic_Storm, castLocation);
LatencyTracker::Instance().placingStorm(mUnit, castLocation);
}
else
{
Vector newCastLocation = mUnit->getPosition() - castLocation;
newCastLocation.normalise();
newCastLocation *= float(distanceToStorm - BWAPI::TechTypes::Psionic_Storm.getWeapon().maxRange());
newCastLocation += Vector(castLocation);
mUnit->useTech(BWAPI::TechTypes::Psionic_Storm, newCastLocation);
LatencyTracker::Instance().placingStorm(mUnit, newCastLocation);
}
return true;
}
else
{
++tries;
if(tries < 3)
{
targets = targetsToChooseFrom;
for each(Unit unit in targetsToChooseFrom)
{
if(unit->getDistance(castLocation) < 64)
targets.erase(unit);
}
if(targets.size() >= 3 || (castUrgenty && !targets.empty()))
tryAgain = true;
}
}
}
}
}
}
return false;
}
1.7.6.1