diff --git a/src/Hub.cpp b/src/Hub.cpp index f8e5d1d..b46a0c8 100644 --- a/src/Hub.cpp +++ b/src/Hub.cpp @@ -175,7 +175,7 @@ void Hub::OnUnitIdle(const sc2::Unit& unit_) { case sc2::UNIT_TYPEID::PROTOSS_PROBE: case sc2::UNIT_TYPEID::TERRAN_SCV: case sc2::UNIT_TYPEID::ZERG_DRONE: { - if (m_free_workers.Swap(Worker(unit_), m_busy_workers)) + if (m_busy_workers.Swap(Worker(unit_), m_free_workers)) gHistory.info() << "Our busy worker has finished task" << std::endl; return; @@ -260,6 +260,30 @@ void Hub::AssignVespeneHarvester(const sc2::Unit& refinery_) { worker->GatherVespene(refinery_); } +void Hub::DistrubuteMineralWorker(const sc2::Unit* unit_) { + auto patches = gAPI->observer().GetUnits( + sc2::IsVisibleMineralPatch(), sc2::Unit::Alliance::Neutral); + auto townhalls = gAPI->observer().GetUnits( + IsNonSaturatedTownHall(), sc2::Unit::Alliance::Self); + + if (townhalls.Empty()) // no non-Saturated bases, use any finished + townhalls = gAPI->observer().GetUnits( + IsBuiltTownHall(), sc2::Unit::Alliance::Self); + + const sc2::Unit* townhall_target = townhalls.GetClosestUnit(unit_->pos); + + const sc2::Unit* mineral_target; + if (!townhall_target) // if no TownHalls existing (or landed?) + mineral_target = patches.GetClosestUnit(gAPI->observer().StartingLocation()); + else + mineral_target = patches.GetClosestUnit(townhall_target->pos); + + if (!mineral_target) + return; + + gAPI->action().Cast(*unit_, sc2::ABILITY_ID::SMART, *mineral_target); +} + bool Hub::AssignLarva(Order* order_) { if (m_larva.Empty()) return false; diff --git a/src/Hub.h b/src/Hub.h index 97a4838..3e59048 100644 --- a/src/Hub.h +++ b/src/Hub.h @@ -143,6 +143,8 @@ struct Hub { void AssignVespeneHarvester(const sc2::Unit& refinery_); + void DistrubuteMineralWorker(const sc2::Unit* unit_); + bool AssignLarva(Order* order_); const Cache& GetLarvas() const; diff --git a/src/core/Helpers.cpp b/src/core/Helpers.cpp index ee3752d..2978618 100644 --- a/src/core/Helpers.cpp +++ b/src/core/Helpers.cpp @@ -143,6 +143,25 @@ bool IsGasWorker::operator()(const sc2::Unit& unit_) const { return false; } +bool IsTownHall::operator()(const sc2::Unit& unit_) const { + return unit_.unit_type == sc2::UNIT_TYPEID::PROTOSS_NEXUS || + unit_.unit_type == sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER || + unit_.unit_type == sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND || + unit_.unit_type == sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS || + unit_.unit_type == sc2::UNIT_TYPEID::ZERG_HATCHERY || + unit_.unit_type == sc2::UNIT_TYPEID::ZERG_HIVE || + unit_.unit_type == sc2::UNIT_TYPEID::ZERG_LAIR; +} + +bool IsBuiltTownHall::operator()(const sc2::Unit& unit_) const { + return IsTownHall()(unit_) && unit_.build_progress == 1.0f; +} + +bool IsNonSaturatedTownHall::operator()(const sc2::Unit& unit_) const { + return IsTownHall()(unit_) && unit_.build_progress == 1.0f + && unit_.assigned_harvesters < unit_.ideal_harvesters; +} + bool IsIdleTownHall::operator()(const sc2::Unit& unit_) const { return sc2::IsTownHall()(unit_) && unit_.orders.empty() && unit_.build_progress == 1.0f; diff --git a/src/core/Helpers.h b/src/core/Helpers.h index d27b669..5e149dc 100644 --- a/src/core/Helpers.h +++ b/src/core/Helpers.h @@ -59,6 +59,18 @@ struct IsGasWorker { bool operator()(const sc2::Unit& unit_) const; }; +struct IsTownHall { + bool operator()(const sc2::Unit& unit_) const; +}; + +struct IsBuiltTownHall { + bool operator()(const sc2::Unit& unit_) const; +}; + +struct IsNonSaturatedTownHall { + bool operator()(const sc2::Unit& unit_) const; +}; + struct IsIdleTownHall { bool operator()(const sc2::Unit& unit_) const; }; diff --git a/src/plugins/Miner.cpp b/src/plugins/Miner.cpp index 959e95c..7ceed41 100644 --- a/src/plugins/Miner.cpp +++ b/src/plugins/Miner.cpp @@ -18,10 +18,11 @@ const int mule_energy_cost = 50; void SecureMineralsIncome(Builder* builder_) { auto town_halls = gAPI->observer().GetUnits(sc2::IsTownHall()); + auto numTotalWorkers = gAPI->observer().CountUnitType(gHub->GetCurrentWorkerType()); for (const auto& i : town_halls()) { - if (i->assigned_harvesters >= i->ideal_harvesters) - continue; + if (i->assigned_harvesters >= i->ideal_harvesters + 1 || numTotalWorkers > 80) + continue; // NOTE (impulsecloud): one extra, never >80 (pros stop at 77-ish?) if (!i->orders.empty()) continue; @@ -98,19 +99,11 @@ void Miner::OnUnitCreated(const sc2::Unit* unit_, Builder*) { } void Miner::OnUnitIdle(const sc2::Unit* unit_, Builder*) { - auto units = gAPI->observer().GetUnits(sc2::IsVisibleMineralPatch(), - sc2::Unit::Alliance::Neutral); - switch (unit_->unit_type.ToType()) { case sc2::UNIT_TYPEID::PROTOSS_PROBE: case sc2::UNIT_TYPEID::TERRAN_SCV: case sc2::UNIT_TYPEID::ZERG_DRONE: { - const sc2::Unit* mineral_target = units.GetClosestUnit( - gAPI->observer().StartingLocation()); - if (!mineral_target) - return; - - gAPI->action().Cast(*unit_, sc2::ABILITY_ID::SMART, *mineral_target); + gHub->DistrubuteMineralWorker(unit_); break; }