diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 478c9ac50..6b26cba8a 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -155,13 +155,18 @@ Mob* HateList::GetDamageTopOnHateList(Mob* hater) return current; } -Mob* HateList::GetClosestEntOnHateList(Mob *hater) { +Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed) { Mob* close_entity = nullptr; float close_distance = 99999.9f; float this_distance; auto iterator = list.begin(); while (iterator != list.end()) { + if (skip_mezzed && (*iterator)->entity_on_hatelist->IsMezzed()) { + ++iterator; + continue; + } + this_distance = DistanceSquaredNoZ((*iterator)->entity_on_hatelist->GetPosition(), hater->GetPosition()); if ((*iterator)->entity_on_hatelist != nullptr && this_distance <= close_distance) { close_distance = this_distance; @@ -297,7 +302,7 @@ int HateList::GetHateRatio(Mob *top, Mob *other) // skip is used to ignore a certain mob on the list // Currently used for getting 2nd on list for aggro meter -Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) +Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip, bool skip_mezzed) { // hack fix for zone shutdown crashes on some servers if (!zone->IsLoaded()) @@ -335,6 +340,11 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) continue; } + if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) { + ++iterator; + continue; + } + if (cur->entity_on_hatelist->Sanctuary()) { if (hate == -1) { @@ -465,6 +475,11 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) continue; } + if (skip_mezzed && cur->entity_on_hatelist->IsMezzed()) { + ++iterator; + continue; + } + if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy)) { top_hate = cur->entity_on_hatelist; @@ -480,7 +495,7 @@ Mob *HateList::GetEntWithMostHateOnList(Mob *center, Mob *skip) return nullptr; } -Mob *HateList::GetEntWithMostHateOnList(){ +Mob *HateList::GetEntWithMostHateOnList(bool skip_mezzed){ Mob* top = nullptr; int64 hate = -1; @@ -490,8 +505,10 @@ Mob *HateList::GetEntWithMostHateOnList(){ struct_HateList *cur = (*iterator); if (cur && cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate)) { - top = cur->entity_on_hatelist; - hate = cur->stored_hate_amount; + if (!skip_mezzed || !cur->entity_on_hatelist->IsMezzed()) { + top = cur->entity_on_hatelist; + hate = cur->stored_hate_amount; + } } ++iterator; } @@ -499,26 +516,50 @@ Mob *HateList::GetEntWithMostHateOnList(){ } -Mob *HateList::GetRandomEntOnHateList() +Mob *HateList::GetRandomEntOnHateList(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 NULL; + 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()) // Just in case tHateEntry is invalidated somehow... + if (*list.begin() && (!skip_mezzed || !(*list.begin())->entity_on_hatelist->IsMezzed())) // Just in case tHateEntry is invalidated somehow... return (*list.begin())->entity_on_hatelist; - return NULL; + return nullptr; } - auto iterator = list.begin(); - int random = zone->random.Int(0, count - 1); - for (int i = 0; i < random; i++) - ++iterator; + if (skip_mezzed) { - return (*iterator)->entity_on_hatelist; + 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 (skip_mezzed && iter->entity_on_hatelist->IsMezzed()) { + continue; + } + if (counter < random) { + + ++counter; + continue; + } + + return iter->entity_on_hatelist; + } + + return nullptr; } Mob *HateList::GetEscapingEntOnHateList() { diff --git a/zone/hate_list.h b/zone/hate_list.h index 96d8ed067..44613bdea 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -41,11 +41,11 @@ public: HateList(); ~HateList(); - Mob *GetClosestEntOnHateList(Mob *hater); - Mob *GetDamageTopOnHateList(Mob *hater); - Mob *GetEntWithMostHateOnList(Mob *center, Mob *skip = nullptr); - Mob *GetRandomEntOnHateList(); - Mob *GetEntWithMostHateOnList(); + Mob *GetClosestEntOnHateList(Mob *hater, bool skip_mezzed = false); + Mob *GetDamageTopOnHateList(Mob *hater); // didn't add 'skip_mezzed' due to calls being in ::Death() + Mob *GetEntWithMostHateOnList(Mob *center, Mob *skip = nullptr, bool skip_mezzed = false); + Mob *GetRandomEntOnHateList(bool skip_mezzed = false); + Mob *GetEntWithMostHateOnList(bool skip_mezzed = false); Mob *GetEscapingEntOnHateList(); // returns first eligble entity Mob *GetEscapingEntOnHateList(Mob *center, float range = 0.0f, bool first = false);