diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index d003d10a1..2abb5b8a9 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -155,28 +155,54 @@ Mob* HateList::GetDamageTopOnHateList(Mob* hater) return current; } -Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed) { +Mob* HateList::GetClosestEntOnHateList(Mob *hater, bool skip_mezzed, EntityFilterType entity_type) { 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; + for (const auto& e : list) { + if (!e->entity_on_hatelist) { 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; - close_entity = (*iterator)->entity_on_hatelist; + if (skip_mezzed && e->entity_on_hatelist->IsMezzed()) { + continue; + } + + switch (entity_type) { + case EntityFilterType::Bots: + if (!e->entity_on_hatelist->IsBot()) { + continue; + } + break; + case EntityFilterType::Clients: + if (!e->entity_on_hatelist->IsClient()) { + continue; + } + break; + case EntityFilterType::NPCs: + if (!e->entity_on_hatelist->IsNPC()) { + continue; + } + break; + case EntityFilterType::All: + default: + break; + } + + this_distance = DistanceSquaredNoZ(e->entity_on_hatelist->GetPosition(), hater->GetPosition()); + if (this_distance <= close_distance) { + close_distance = this_distance; + close_entity = e->entity_on_hatelist; } - ++iterator; } - if ((!close_entity && hater->IsNPC()) || (close_entity && close_entity->DivineAura())) + if ( + (!close_entity && hater->IsNPC()) || + (close_entity && close_entity->DivineAura()) + ) { close_entity = hater->CastToNPC()->GetHateTop(); + } return close_entity; } diff --git a/zone/hate_list.h b/zone/hate_list.h index 9af5d27b0..c1d37ce73 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -41,7 +41,7 @@ public: HateList(); ~HateList(); - Mob *GetClosestEntOnHateList(Mob *hater, bool skip_mezzed = false); + Mob *GetClosestEntOnHateList(Mob *hater, bool skip_mezzed = false, EntityFilterType entity_type = EntityFilterType::All); 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); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 32c85c272..121948e89 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2376,6 +2376,41 @@ Lua_Mob Lua_Mob::GetHateClosest() { return Lua_Mob(self->GetHateClosest()); } +Lua_Mob Lua_Mob::GetHateClosest(bool skip_mezzed) { + Lua_Safe_Call_Class(Lua_Mob); + return Lua_Mob(self->GetHateClosest(skip_mezzed)); +} + +Lua_Bot Lua_Mob::GetHateClosestBot() { + Lua_Safe_Call_Class(Lua_Bot); + return Lua_Bot(self->GetHateClosestBot()); +} + +Lua_Bot Lua_Mob::GetHateClosestBot(bool skip_mezzed) { + Lua_Safe_Call_Class(Lua_Bot); + return Lua_Bot(self->GetHateClosestBot()); +} + +Lua_Client Lua_Mob::GetHateClosestClient() { + Lua_Safe_Call_Class(Lua_Client); + return Lua_Client(self->GetHateClosestClient()); +} + +Lua_Client Lua_Mob::GetHateClosestClient(bool skip_mezzed) { + Lua_Safe_Call_Class(Lua_Client); + return Lua_Client(self->GetHateClosestClient(skip_mezzed)); +} + +Lua_NPC Lua_Mob::GetHateClosestNPC() { + Lua_Safe_Call_Class(Lua_NPC); + return Lua_NPC(self->GetHateClosestNPC()); +} + +Lua_NPC Lua_Mob::GetHateClosestNPC(bool skip_mezzed) { + Lua_Safe_Call_Class(Lua_NPC); + return Lua_NPC(self->GetHateClosestNPC(skip_mezzed)); +} + Lua_HateList Lua_Mob::GetHateListByDistance() { Lua_Safe_Call_Class(Lua_HateList); Lua_HateList ret; @@ -3253,7 +3288,14 @@ luabind::scope lua_register_mob() { .def("GetHaste", (int(Lua_Mob::*)(void))&Lua_Mob::GetHaste) .def("GetHateAmount", (int64(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetHateAmount) .def("GetHateAmount", (int64(Lua_Mob::*)(Lua_Mob,bool))&Lua_Mob::GetHateAmount) - .def("GetHateClosest", &Lua_Mob::GetHateClosest) + .def("GetHateClosest", (Lua_Mob(Lua_Mob::*)(void))&Lua_Mob::GetHateClosest) + .def("GetHateClosest", (Lua_Mob(Lua_Mob::*)(bool))&Lua_Mob::GetHateClosest) + .def("GetHateClosestBot", (Lua_Bot(Lua_Mob::*)(void))&Lua_Mob::GetHateClosestBot) + .def("GetHateClosestBot", (Lua_Bot(Lua_Mob::*)(bool))&Lua_Mob::GetHateClosestBot) + .def("GetHateClosestClient", (Lua_Client(Lua_Mob::*)(void))&Lua_Mob::GetHateClosestClient) + .def("GetHateClosestClient", (Lua_Client(Lua_Mob::*)(bool))&Lua_Mob::GetHateClosestClient) + .def("GetHateClosestNPC", (Lua_NPC(Lua_Mob::*)(void))&Lua_Mob::GetHateClosestNPC) + .def("GetHateClosestNPC", (Lua_NPC(Lua_Mob::*)(bool))&Lua_Mob::GetHateClosestNPC) .def("GetHateDamageTop", (Lua_Mob(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetHateDamageTop) .def("GetHateList", &Lua_Mob::GetHateList) .def("GetHateListBots", (Lua_HateList(Lua_Mob::*)(void))&Lua_Mob::GetHateListBots) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 00532a849..954717869 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -227,6 +227,13 @@ public: Lua_Client GetHateRandomClient(); Lua_NPC GetHateRandomNPC(); Lua_Mob GetHateClosest(); + Lua_Mob GetHateClosest(bool skip_mezzed); + Lua_Bot GetHateClosestBot(); + Lua_Bot GetHateClosestBot(bool skip_mezzed); + Lua_Client GetHateClosestClient(); + Lua_Client GetHateClosestClient(bool skip_mezzed); + Lua_NPC GetHateClosestNPC(); + Lua_NPC GetHateClosestNPC(bool skip_mezzed); void AddToHateList(Lua_Mob other); void AddToHateList(Lua_Mob other, int64 hate); void AddToHateList(Lua_Mob other, int64 hate, int64 damage); diff --git a/zone/mob.h b/zone/mob.h index 25eabc945..e802857bc 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -732,7 +732,10 @@ public: NPC* GetHateRandomNPC() { return hate_list.GetRandomNPCOnHateList(); } Bot* GetHateRandomBot() { return hate_list.GetRandomBotOnHateList(); } Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();} - Mob* GetHateClosest() { return hate_list.GetClosestEntOnHateList(this); } + 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(); } + Client* GetHateClosestClient(bool skip_mezzed = false) { return hate_list.GetClosestEntOnHateList(this, skip_mezzed, EntityFilterType::Clients)->CastToClient(); } + NPC* GetHateClosestNPC(bool skip_mezzed = false) { return hate_list.GetClosestEntOnHateList(this, skip_mezzed, EntityFilterType::NPCs)->CastToNPC(); } bool IsEngaged() { return(!hate_list.IsHateListEmpty()); } bool HasPrimaryAggro() { return PrimaryAggro; } bool HasAssistAggro() { return AssistAggro; } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 7542c1a3d..2316cf110 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2437,6 +2437,41 @@ Mob* Perl_Mob_GetHateClosest(Mob* self) // @categories Hate and Aggro return self->GetHateClosest(); } +Mob* Perl_Mob_GetHateClosest(Mob* self, bool skip_mezzed) // @categories Hate and Aggro +{ + return self->GetHateClosest(skip_mezzed); +} + +Bot* Perl_Mob_GetHateClosestBot(Mob* self) // @categories Hate and Aggro +{ + return self->GetHateClosestBot(); +} + +Bot* Perl_Mob_GetHateClosestBot(Mob* self, bool skip_mezzed) // @categories Hate and Aggro +{ + return self->GetHateClosestBot(skip_mezzed); +} + +Client* Perl_Mob_GetHateClosestClient(Mob* self) // @categories Hate and Aggro +{ + return self->GetHateClosestClient(); +} + +Client* Perl_Mob_GetHateClosestClient(Mob* self, bool skip_mezzed) // @categories Hate and Aggro +{ + return self->GetHateClosestClient(skip_mezzed); +} + +NPC* Perl_Mob_GetHateClosestNPC(Mob* self) // @categories Hate and Aggro +{ + return self->GetHateClosestNPC(); +} + +NPC* Perl_Mob_GetHateClosestNPC(Mob* self, bool skip_mezzed) // @categories Hate and Aggro +{ + return self->GetHateClosestNPC(skip_mezzed); +} + std::string Perl_Mob_GetLastName(Mob* self) // @categories Script Utility { return self->GetLastName(); @@ -3193,7 +3228,14 @@ void perl_register_mob() package.add("GetHaste", &Perl_Mob_GetHaste); package.add("GetHateAmount", (int64_t(*)(Mob*, Mob*))&Perl_Mob_GetHateAmount); package.add("GetHateAmount", (int64_t(*)(Mob*, Mob*, bool))&Perl_Mob_GetHateAmount); - package.add("GetHateClosest", &Perl_Mob_GetHateClosest); + package.add("GetHateClosest", (Mob*(*)(Mob*))&Perl_Mob_GetHateClosest); + package.add("GetHateClosest", (Mob*(*)(Mob*, bool))&Perl_Mob_GetHateClosest); + package.add("GetHateClosestBot", (Bot*(*)(Mob*))&Perl_Mob_GetHateClosestBot); + package.add("GetHateClosestBot", (Bot*(*)(Mob*, bool))&Perl_Mob_GetHateClosestBot); + package.add("GetHateClosestClient", (Client*(*)(Mob*))&Perl_Mob_GetHateClosestClient); + package.add("GetHateClosestClient", (Client*(*)(Mob*, bool))&Perl_Mob_GetHateClosestClient); + package.add("GetHateClosestNPC", (NPC*(*)(Mob*))&Perl_Mob_GetHateClosestNPC); + package.add("GetHateClosestNPC", (NPC*(*)(Mob*, bool))&Perl_Mob_GetHateClosestNPC); package.add("GetHateDamageTop", &Perl_Mob_GetHateDamageTop); package.add("GetHateList", &Perl_Mob_GetHateList); package.add("GetHateListBots", (perl::array(*)(Mob*))&Perl_Mob_GetHateListBots);