[Cleanup] Consolidate GetHateRandom(), GetHateRandomBot(), GetHateRandomClient(), and GetHateRandomNPC() (#3794)

* [Cleanup] Consolidate GetHateRandomBot(), GetHateRandomClient(), and GetHateRandomNPC()

# Notes
- These were separate methods and duplicated a lot of code, consolidated into the singular method using the `EntityFilterType`.

* Simplify random logic. Use filtered hate list.

* D

* D
This commit is contained in:
Alex King 2023-12-25 00:28:47 -05:00 committed by GitHub
parent 6db0a5c3f0
commit 6396a6fbef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 189 deletions

View File

@ -149,7 +149,7 @@ Mob* HateList::GetDamageTopOnHateList(Mob* hater)
return current;
}
Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed, EntityFilterType entity_type) {
Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed, EntityFilterType filter_type) {
Mob* close_entity = nullptr;
float close_distance = 99999.9f;
float this_distance;
@ -163,7 +163,7 @@ Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed, EntityFilte
continue;
}
switch (entity_type) {
switch (filter_type) {
case EntityFilterType::Bots:
if (!e->entity_on_hatelist->IsBot()) {
continue;
@ -589,47 +589,39 @@ Mob *HateList::GetMobWithMostHateOnList(bool skip_mezzed){
}
Mob *HateList::GetRandomMobOnHateList(bool skip_mezzed)
Mob *HateList::GetRandomMobOnHateList(EntityFilterType filter_type)
{
int count = list.size();
if (count <= 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
return nullptr;
if (count == 1) //No need to do all that extra work if we only have one hate entry
{
if (*list.begin() && (!skip_mezzed || !(*list.begin())->entity_on_hatelist->IsMezzed())) // Just in case tHateEntry is invalidated somehow...
return (*list.begin())->entity_on_hatelist;
const auto &l = GetFilteredHateList(filter_type);
int count = l.size();
if (count <= 0) { // If we don't have any entries it'll crash getting a random 0, -1 position.
return nullptr;
}
if (skip_mezzed) {
for (auto iter : list) {
if (iter->entity_on_hatelist->IsMezzed()) {
--count;
if (count == 1) { // No need to do all that extra work if we only have one hate entry
auto c = *l.begin();
if (c) {
Mob *m = c->entity_on_hatelist;
if (!m) {
return nullptr;
}
return m;
}
if (count <= 0) {
return nullptr;
}
return nullptr;
}
int random = zone->random.Int(0, count - 1);
int counter = 0;
auto r = l.begin();
int random_index = rand() % count;
for (auto iter : list) {
std::advance(r, random_index);
if (skip_mezzed && iter->entity_on_hatelist->IsMezzed()) {
continue;
}
if (counter < random) {
auto e = *r;
++counter;
continue;
}
return iter->entity_on_hatelist;
Mob *m = e->entity_on_hatelist;
if (m) {
return m;
}
return nullptr;
@ -877,153 +869,6 @@ void HateList::RemoveStaleEntries(int time_ms, float dist)
}
}
Bot* HateList::GetRandomBotOnHateList(bool skip_mezzed)
{
int count = list.size();
if (count <= 0) { //If we don't have any entries it'll crash getting a random 0, -1 position.
return nullptr;
}
if (count == 1) { //No need to do all that extra work if we only have one hate entry
if (*list.begin() && (*list.begin())->entity_on_hatelist->IsBot() && (!skip_mezzed || !(*list.begin())->entity_on_hatelist->IsMezzed())) {
return (*list.begin())->entity_on_hatelist->CastToBot();
}
return nullptr;
}
if (skip_mezzed) {
for (auto iter : list) {
if (iter->entity_on_hatelist->IsMezzed()) {
--count;
}
}
if (count <= 0) {
return nullptr;
}
}
int random = zone->random.Int(0, count - 1);
int counter = 0;
for (auto iter : list) {
if (!iter->entity_on_hatelist->IsBot()) {
continue;
}
if (skip_mezzed && iter->entity_on_hatelist->IsMezzed()) {
continue;
}
if (counter < random) {
++counter;
continue;
}
return iter->entity_on_hatelist->CastToBot();
}
return nullptr;
}
Client* HateList::GetRandomClientOnHateList(bool skip_mezzed)
{
int count = list.size();
if (count <= 0) { //If we don't have any entries it'll crash getting a random 0, -1 position.
return nullptr;
}
if (count == 1) { //No need to do all that extra work if we only have one hate entry
if (*list.begin() && (*list.begin())->entity_on_hatelist->IsClient() && (!skip_mezzed || !(*list.begin())->entity_on_hatelist->IsMezzed())) {
return (*list.begin())->entity_on_hatelist->CastToClient();
}
return nullptr;
}
if (skip_mezzed) {
for (auto iter : list) {
if (iter->entity_on_hatelist->IsMezzed()) {
--count;
}
}
if (count <= 0) {
return nullptr;
}
}
int random = zone->random.Int(0, count - 1);
int counter = 0;
for (auto iter : list) {
if (!iter->entity_on_hatelist->IsClient()) {
continue;
}
if (skip_mezzed && iter->entity_on_hatelist->IsMezzed()) {
continue;
}
if (counter < random) {
++counter;
continue;
}
return iter->entity_on_hatelist->CastToClient();
}
return nullptr;
}
NPC* HateList::GetRandomNPCOnHateList(bool skip_mezzed)
{
int count = list.size();
if (count <= 0) { //If we don't have any entries it'll crash getting a random 0, -1 position.
return nullptr;
}
if (count == 1) { //No need to do all that extra work if we only have one hate entry
if (*list.begin() && (*list.begin())->entity_on_hatelist->IsNPC() && (!skip_mezzed || !(*list.begin())->entity_on_hatelist->IsMezzed())) {
return (*list.begin())->entity_on_hatelist->CastToNPC();
}
return nullptr;
}
if (skip_mezzed) {
for (auto iter : list) {
if (iter->entity_on_hatelist->IsMezzed()) {
--count;
}
}
if (count <= 0) {
return nullptr;
}
}
int random = zone->random.Int(0, count - 1);
int counter = 0;
for (auto iter : list) {
if (!iter->entity_on_hatelist->IsNPC()) {
continue;
}
if (skip_mezzed && iter->entity_on_hatelist->IsMezzed()) {
continue;
}
if (counter < random) {
++counter;
continue;
}
return iter->entity_on_hatelist->CastToNPC();
}
return nullptr;
}
void HateList::DamageHateList(int64 damage, uint32 distance, EntityFilterType filter_type, bool is_percentage)
{
if (damage <= 0) {

View File

@ -41,17 +41,13 @@ public:
HateList();
~HateList();
Mob *GetClosestEntOnHateList(Mob *hater, bool skip_mezzed = false, EntityFilterType entity_type = EntityFilterType::All);
Mob *GetClosestEntOnHateList(Mob *hater, bool skip_mezzed = false, EntityFilterType filter_type = EntityFilterType::All);
Mob *GetDamageTopOnHateList(Mob *hater); // didn't add 'skip_mezzed' due to calls being in ::Death()
Mob *GetMobWithMostHateOnList(Mob *center, Mob *skip = nullptr, bool skip_mezzed = false, EntityFilterType entity_type = EntityFilterType::All);
Mob *GetRandomMobOnHateList(bool skip_mezzed = false);
Mob *GetMobWithMostHateOnList(Mob *center, Mob *skip = nullptr, bool skip_mezzed = false, EntityFilterType filter_type = EntityFilterType::All);
Mob *GetRandomMobOnHateList(EntityFilterType filter_type = EntityFilterType::All);
Mob *GetMobWithMostHateOnList(bool skip_mezzed = false);
Mob *GetEscapingMobOnHateList(Mob *center, float range = 0.0f, bool first = false);
Bot* GetRandomBotOnHateList(bool skip_mezzed = false);
Client *GetRandomClientOnHateList(bool skip_mezzed = false);
NPC *GetRandomNPCOnHateList(bool skip_mezzed = false);
bool IsEntOnHateList(Mob *mob);
bool IsHateListEmpty();
bool RemoveEntFromHateList(Mob *ent);

View File

@ -754,10 +754,10 @@ public:
NPC* GetHateTopNPC() { return hate_list.GetMobWithMostHateOnList(this, nullptr, false, EntityFilterType::NPCs)->CastToNPC();}
Mob* GetSecondaryHate(Mob *skip) { return hate_list.GetMobWithMostHateOnList(this, skip); }
Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTopOnHateList(other);}
Mob* GetHateRandom() { return hate_list.GetRandomMobOnHateList();}
Client* GetHateRandomClient() { return hate_list.GetRandomClientOnHateList(); }
NPC* GetHateRandomNPC() { return hate_list.GetRandomNPCOnHateList(); }
Bot* GetHateRandomBot() { return hate_list.GetRandomBotOnHateList(); }
Mob* GetHateRandom() { return hate_list.GetRandomMobOnHateList(); }
Bot* GetHateRandomBot() { return hate_list.GetRandomMobOnHateList(EntityFilterType::Bots)->CastToBot(); }
Client* GetHateRandomClient() { return hate_list.GetRandomMobOnHateList(EntityFilterType::Clients)->CastToClient(); }
NPC* GetHateRandomNPC() { return hate_list.GetRandomMobOnHateList(EntityFilterType::NPCs)->CastToNPC(); }
Mob* GetHateMost() { return hate_list.GetMobWithMostHateOnList();}
Mob* GetHateClosest(bool skip_mezzed = false) { return hate_list.GetClosestEntOnHateList(this, skip_mezzed); }
Bot* GetHateClosestBot(bool skip_mezzed = false) { return hate_list.GetClosestEntOnHateList(this, skip_mezzed, EntityFilterType::Bots)->CastToBot(); }