52 lines
1.6 KiB
C++
52 lines
1.6 KiB
C++
#ifndef MT_AUTOHUNT_GROUP_SELECT_H
|
|
#define MT_AUTOHUNT_GROUP_SELECT_H
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <stdint.h>
|
|
|
|
namespace mt_autohunt {
|
|
struct Candidate {
|
|
uint64_t group; // actual server party, or a unique key for an ungrouped monster
|
|
uint32_t vid;
|
|
int distance;
|
|
bool eligible;
|
|
};
|
|
struct Selection {
|
|
int groups;
|
|
std::vector<uint32_t> mobs;
|
|
Selection() : groups(0) {}
|
|
};
|
|
inline Selection SelectGroups(const std::vector<Candidate>& candidates, int count) {
|
|
Selection out;
|
|
if (count != 3 && count != 10 && count != 20) return out;
|
|
struct Group {
|
|
uint64_t key;
|
|
int distance;
|
|
bool eligible;
|
|
std::vector<uint32_t> mobs;
|
|
Group() : key(0), distance(2147483647), eligible(true) {}
|
|
};
|
|
std::map<uint64_t, Group> groups;
|
|
for (size_t i = 0; i < candidates.size(); ++i) {
|
|
const Candidate& c = candidates[i];
|
|
Group& g = groups[c.group];
|
|
g.key = c.group;
|
|
g.distance = std::min(g.distance, c.distance);
|
|
g.eligible = g.eligible && c.eligible;
|
|
g.mobs.push_back(c.vid);
|
|
}
|
|
std::vector<std::pair<int, uint64_t> > ordered;
|
|
for (std::map<uint64_t, Group>::const_iterator i = groups.begin(); i != groups.end(); ++i)
|
|
if (i->second.eligible) ordered.push_back(std::make_pair(i->second.distance, i->first));
|
|
std::sort(ordered.begin(), ordered.end());
|
|
for (size_t i = 0; i < ordered.size() && out.groups < count; ++i) {
|
|
const Group& g = groups[ordered[i].second];
|
|
out.mobs.insert(out.mobs.end(), g.mobs.begin(), g.mobs.end());
|
|
++out.groups;
|
|
}
|
|
return out;
|
|
}
|
|
}
|
|
#endif
|