Skip to content

Commit abb2744

Browse files
committed
Feature #34: Fix gas saturation
If gas oversaturated, remove from busy_workers and call DistributeWorker. If gas under-saturated and any base is mineral-oversaturated, send one of those mineral workers to that gas.
1 parent 3e4a5de commit abb2744

File tree

5 files changed

+105
-57
lines changed

5 files changed

+105
-57
lines changed

src/Hub.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,25 @@ void Hub::AssignVespeneHarvester(const sc2::Unit& refinery_) {
279279
worker->GatherVespene(refinery_);
280280
}
281281

282+
const sc2::Unit* Hub::RemoveVespeneHarvester(const sc2::Unit& refinery_) {
283+
const std::list<Worker>& workers = m_busy_workers();
284+
for (auto& worker : workers) {
285+
const sc2::Unit* unit = gAPI->observer().GetUnit(worker.Tag());
286+
if (!unit || worker.GetJob() != GATHERING_VESPENE)
287+
continue;
288+
289+
if (!unit->orders.empty() &&
290+
unit->orders.front().target_unit_tag == refinery_.tag &&
291+
unit->last_seen_game_loop == gAPI->observer().GetGameLoop()) {
292+
293+
m_busy_workers.Swap(worker, m_free_workers);
294+
return unit;
295+
}
296+
}
297+
298+
return nullptr;
299+
}
300+
282301
bool Hub::AssignLarva(Order* order_) {
283302
if (m_larva.Empty())
284303
return false;

src/Hub.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
template <typename T>
1717
struct Cache {
18+
const std::list<T>& operator()();
19+
1820
bool Empty() const;
1921

2022
uint64_t Count() const;
@@ -37,6 +39,11 @@ struct Cache {
3739
std::list<T> m_objects;
3840
};
3941

42+
template <typename T>
43+
const std::list<T>& Cache<T>::operator()() {
44+
return m_objects;
45+
}
46+
4047
template <typename T>
4148
bool Cache<T>::Empty() const {
4249
return m_objects.empty();
@@ -145,6 +152,8 @@ struct Hub {
145152

146153
void AssignVespeneHarvester(const sc2::Unit& refinery_);
147154

155+
const sc2::Unit* RemoveVespeneHarvester(const sc2::Unit& refinery_);
156+
148157
bool AssignLarva(Order* order_);
149158

150159
const Cache<GameObject>& GetLarvas() const;

src/objects/Worker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ void Worker::GatherVespene(const sc2::Unit& target_) {
2727
gAPI->action().Cast(ToUnit(), sc2::ABILITY_ID::SMART, target_);
2828
m_job = Job::GATHERING_VESPENE;
2929
}
30+
31+
Job Worker::GetJob() const {
32+
return m_job;
33+
}

src/objects/Worker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct Worker: GameObject {
2222
void Build(Order* order_, const sc2::Point2D& point_);
2323

2424
void GatherVespene(const sc2::Unit& target_);
25+
26+
Job GetJob() const;
2527

2628
private:
2729
Job m_job;

src/plugins/Miner.cpp

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,63 +16,6 @@
1616
namespace {
1717
const int mule_energy_cost = 50;
1818

19-
void SecureMineralsIncome(Builder* builder_) {
20-
auto town_halls = gAPI->observer().GetUnits(sc2::IsTownHall());
21-
22-
for (const auto& i : town_halls()) {
23-
if (!i->orders.empty() || i->build_progress != BUILD_FINISHED)
24-
continue;
25-
26-
if (i->assigned_harvesters > i->ideal_harvesters)
27-
continue;
28-
29-
if (builder_->CountScheduledOrders(gHub->GetCurrentWorkerType()) > 0)
30-
continue;
31-
32-
// FIXME (alkurbatov): We should set an assignee for drones
33-
// and pick a larva closest to the assignee.
34-
if (gHub->GetCurrentRace() == sc2::Race::Zerg) {
35-
builder_->ScheduleOptionalOrder(sc2::UNIT_TYPEID::ZERG_DRONE);
36-
continue;
37-
}
38-
39-
builder_->ScheduleOptionalOrder(gHub->GetCurrentWorkerType(), i);
40-
}
41-
}
42-
43-
void SecureVespeneIncome() {
44-
auto refineries = gAPI->observer().GetUnits(IsRefinery());
45-
46-
for (const auto& i : refineries()) {
47-
if (i->assigned_harvesters >= i->ideal_harvesters)
48-
continue;
49-
50-
gHub->AssignVespeneHarvester(*i);
51-
}
52-
}
53-
54-
void CallDownMULE() {
55-
auto orbitals = gAPI->observer().GetUnits(
56-
IsUnit(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND));
57-
58-
if (orbitals.Empty())
59-
return;
60-
61-
auto units = gAPI->observer().GetUnits(sc2::IsVisibleMineralPatch(),
62-
sc2::Unit::Alliance::Neutral);
63-
64-
for (const auto& i : orbitals()) {
65-
if (i->energy < mule_energy_cost)
66-
continue;
67-
68-
const sc2::Unit* mineral_target = units.GetClosestUnit(i->pos);
69-
if (!mineral_target)
70-
continue;
71-
72-
gAPI->action().Cast(*i, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, *mineral_target);
73-
}
74-
}
75-
7619
const Expansion* GetBestMiningExpansionNear(const sc2::Unit* unit_) {
7720
if (!unit_)
7821
return nullptr;
@@ -136,6 +79,77 @@ void DistrubuteMineralWorker(const sc2::Unit* unit_) {
13679
gAPI->action().Cast(*unit_, sc2::ABILITY_ID::SMART, *mineral_target);
13780
}
13881

82+
void SecureMineralsIncome(Builder* builder_) {
83+
auto town_halls = gAPI->observer().GetUnits(sc2::IsTownHall());
84+
85+
for (const auto& i : town_halls()) {
86+
if (!i->orders.empty() || i->build_progress != BUILD_FINISHED)
87+
continue;
88+
89+
if (i->assigned_harvesters > i->ideal_harvesters)
90+
continue;
91+
92+
if (builder_->CountScheduledOrders(gHub->GetCurrentWorkerType()) > 0)
93+
continue;
94+
95+
// FIXME (alkurbatov): We should set an assignee for drones
96+
// and pick a larva closest to the assignee.
97+
if (gHub->GetCurrentRace() == sc2::Race::Zerg) {
98+
builder_->ScheduleOptionalOrder(sc2::UNIT_TYPEID::ZERG_DRONE);
99+
continue;
100+
}
101+
102+
builder_->ScheduleOptionalOrder(gHub->GetCurrentWorkerType(), i);
103+
}
104+
}
105+
106+
void SecureVespeneIncome() {
107+
auto refineries = gAPI->observer().GetUnits(IsRefinery());
108+
109+
for (const auto& i : refineries()) {
110+
if (i->assigned_harvesters > i->ideal_harvesters) { // gas ideal_harvesters is always 3
111+
const sc2::Unit* removed = gHub->RemoveVespeneHarvester(*i);
112+
DistrubuteMineralWorker(removed);
113+
continue;
114+
}
115+
116+
if (i->assigned_harvesters == i->ideal_harvesters) // gas already saturated
117+
continue;
118+
119+
auto town_halls = gAPI->observer().GetUnits(sc2::IsTownHall());
120+
auto close_town_hall = town_halls.GetClosestUnit(i->pos);
121+
if (close_town_hall &&
122+
close_town_hall->assigned_harvesters > close_town_hall->ideal_harvesters) {
123+
gHub->AssignVespeneHarvester(*i); // reassign overflow mineral workers
124+
continue;
125+
}
126+
127+
gHub->AssignVespeneHarvester(*i);
128+
}
129+
}
130+
131+
void CallDownMULE() {
132+
auto orbitals = gAPI->observer().GetUnits(
133+
IsUnit(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND));
134+
135+
if (orbitals.Empty())
136+
return;
137+
138+
auto units = gAPI->observer().GetUnits(sc2::IsVisibleMineralPatch(),
139+
sc2::Unit::Alliance::Neutral);
140+
141+
for (const auto& i : orbitals()) {
142+
if (i->energy < mule_energy_cost)
143+
continue;
144+
145+
const sc2::Unit* mineral_target = units.GetClosestUnit(i->pos);
146+
if (!mineral_target)
147+
continue;
148+
149+
gAPI->action().Cast(*i, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, *mineral_target);
150+
}
151+
}
152+
139153
} // namespace
140154

141155
void Miner::OnStep(Builder* builder_) {

0 commit comments

Comments
 (0)