Skip to content

Commit

Permalink
Issue alkurbatov#56 "Save minerals/geysers in Expansions"
Browse files Browse the repository at this point in the history
During Expansion creation, save resources from Clusters to use for later.
  • Loading branch information
ImpulseCloud committed Mar 5, 2021
1 parent edae1f5 commit 8ae7db8
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 7 deletions.
60 changes: 53 additions & 7 deletions src/core/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "core/API.h"

#include "sc2lib/sc2_search.h"
#include <sc2api/sc2_unit_filters.h>

#include <cmath>

Expand Down Expand Up @@ -50,7 +51,7 @@ size_t CalculateQueries(float radius, float step_size, const sc2::Point2D& cente
struct Cluster {
explicit Cluster(uint64_t id_);

void AddPoint(const sc2::Point3D& point_);
void AddResource(const sc2::Unit* resource_);

float Height() const;

Expand All @@ -60,6 +61,7 @@ struct Cluster {
sc2::Point3D center_of_mass;
sc2::Point3D town_hall_location;
std::vector<sc2::Point3D> points;
std::vector<const sc2::Unit*> resources;
};

typedef std::vector<Cluster> Clusters;
Expand All @@ -68,16 +70,18 @@ Cluster::Cluster(uint64_t id_): id(id_) {
points.reserve(10);
}

void Cluster::AddPoint(const sc2::Point3D& point_) {
void Cluster::AddResource(const sc2::Unit* resource_) {
resources.push_back(resource_);

if (points.empty()) {
center_of_mass = point_;
center_of_mass = resource_->pos;
} else {
center_of_mass =
(center_of_mass * static_cast<float>(points.size() - 1) + point_)
(center_of_mass * static_cast<float>(points.size() - 1) + resource_->pos)
/ static_cast<float>(points.size());
}

points.push_back(point_);
points.push_back(resource_->pos);
}

float Cluster::Height() const {
Expand All @@ -97,6 +101,32 @@ Expansion::Expansion(const sc2::Point3D& town_hall_location_):
town_hall_location(town_hall_location_), owner(Owner::NEUTRAL) {
}

void Expansion::AddResource(const sc2::Unit* resource_) {
if (sc2::IsGeyser()(resource_->unit_type))
geysers.push_back(resource_->tag);
else
minerals.push_back(resource_->tag);
}

const sc2::Unit* Expansion::getClosestMineralTo(const sc2::Point2D& point_) const {
float distance = std::numeric_limits<float>::max();

const sc2::Unit* target = nullptr;
for (const auto i : minerals) {
const sc2::Unit* unit = gAPI->observer().GetUnit(i);
if (!unit)
continue;

float d = sc2::DistanceSquared2D(unit->pos, point_);
if (d < distance) {
distance = d;
target = unit;
}
}

return target;
}

Expansions CalculateExpansionLocations() {
Clusters clusters;
clusters.reserve(20);
Expand All @@ -115,15 +145,15 @@ Expansions CalculateExpansionLocations() {

for (auto& j : clusters) {
if (sc2::DistanceSquared3D(i->pos, j.points.back()) < 225.0f) {
j.AddPoint(i->pos);
j.AddResource(&(*i));
cluster_found = true;
break;
}
}

if (!cluster_found) {
clusters.emplace_back(clusters.size());
clusters.back().AddPoint(i->pos);
clusters.back().AddResource(&(*i));
}
}

Expand All @@ -146,11 +176,27 @@ Expansions CalculateExpansionLocations() {
queries[j].target_pos.y,
i.Height());
expansions.emplace_back(town_hall_location);
for (auto res: i.resources)
expansions.back().AddResource(res);
break;
}

start_index += query_size[i.id];
}

// NOTE (implusecloud): Include start location, since CanBePlaced will fail
// TownHall tag will be added during its OnCreated event.
expansions.emplace_back(gAPI->observer().StartingLocation());

auto minerals = gAPI->observer().GetUnits(
sc2::IsVisibleMineralPatch(), sc2::Unit::Alliance::Neutral);
for (auto& i : minerals())
expansions.back().AddResource(i);

auto geysers = gAPI->observer().GetUnits(
sc2::IsVisibleGeyser(), sc2::Unit::Alliance::Neutral);
for (auto& i : geysers())
expansions.back().AddResource(i);

return expansions;
}
8 changes: 8 additions & 0 deletions src/core/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ enum Owner {
struct Expansion {
explicit Expansion(const sc2::Point3D& town_hall_location_);

void AddResource(const sc2::Unit* resource_);

const sc2::Unit* getClosestMineralTo(const sc2::Point2D& point_) const;

sc2::Point3D town_hall_location;
Owner owner;
sc2::Tag town_hall_tag; // valid for Owner::SELF or ENEMY
// NOTE (impulsecloud): check for dead builder, send new
std::vector<sc2::Tag> minerals;
std::vector<sc2::Tag> geysers;
};

typedef std::vector<Expansion> Expansions;
Expand Down
36 changes: 36 additions & 0 deletions src/plugins/Miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,42 @@ void CallDownMULE() {
}
}

void DistrubuteMineralWorker(const sc2::Unit* unit_) {
if (!unit_)
return;

const Expansion* expansion_target = nullptr;
float target_dist = std::numeric_limits<float>::max();

for (auto& i : gHub->GetExpansions()) {
if (i.owner != Owner::SELF)
continue;

const sc2::Unit* th = gAPI->observer().GetUnit(i.town_hall_tag);
float dist = DistanceSquared2D(unit_->pos, th->pos);

if (dist < target_dist && th->build_progress == 1.0f
&& th->assigned_harvesters < th->ideal_harvesters) {
target_dist = dist;
expansion_target = &i;
}
}

const sc2::Unit* mineral_target = nullptr;
if (expansion_target)
mineral_target = expansion_target->getClosestMineralTo(unit_->pos);
else {
mineral_target = gAPI->observer().GetUnits(
sc2::IsVisibleMineralPatch(), sc2::Unit::Alliance::Neutral)
.GetClosestUnit(gAPI->observer().StartingLocation());
}

if (!mineral_target)
return;

gAPI->action().Cast(*unit_, sc2::ABILITY_ID::SMART, *mineral_target);
}

} // namespace

void Miner::OnStep(Builder* builder_) {
Expand Down

0 comments on commit 8ae7db8

Please sign in to comment.