diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 67d98be22..b4b6725bb 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -785,3 +785,15 @@ void HateList::RemoveStaleEntries(int time_ms, float dist) } } +std::list HateList::GetHateListByDistance(int distance) +{ + std::list hate_list; + int squared_distance = (distance * distance); + for (auto hate_iterator : list) { + auto hate_entry = hate_iterator->entity_on_hatelist; + if (distance == 0 || (distance > 0 && DistanceSquaredNoZ(hate_owner->GetPosition(), hate_entry->GetPosition()) <= squared_distance)) { + hate_list.push_back(hate_iterator); + } + } + return hate_list; +} diff --git a/zone/hate_list.h b/zone/hate_list.h index 44613bdea..71c1f31cf 100644 --- a/zone/hate_list.h +++ b/zone/hate_list.h @@ -60,6 +60,7 @@ public: int32 GetEntHateAmount(Mob *ent, bool in_damage = false); std::list& GetHateList() { return list; } + std::list GetHateListByDistance(int distance = 0); void AddEntToHateList(Mob *ent, int32 in_hate = 0, int32 in_damage = 0, bool in_is_frenzied = false, bool add_to_hate_list_if_not_exist = true); void DoFactionHits(int32 npc_faction_level_id); diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 600851698..08d8d5bdc 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2309,6 +2309,34 @@ void Lua_Mob::SetBucket(std::string bucket_name, std::string bucket_value, std:: self->SetBucket(bucket_name, bucket_value, expiration); } +Lua_Mob Lua_Mob::GetHateClosest() { + Lua_Safe_Call_Class(Lua_Mob); + return Lua_Mob(self->GetHateClosest()); +} + +Lua_HateList Lua_Mob::GetHateListByDistance() { + Lua_Safe_Call_Class(Lua_HateList); + Lua_HateList ret; + auto list = self->GetHateListByDistance(); + for (auto hate_entry : list) { + Lua_HateEntry entry(hate_entry); + ret.entries.push_back(entry); + } + return ret; +} + +Lua_HateList Lua_Mob::GetHateListByDistance(int distance) { + Lua_Safe_Call_Class(Lua_HateList); + Lua_HateList ret; + auto list = self->GetHateListByDistance(distance); + for (auto hate_entry : list) { + Lua_HateEntry entry(hate_entry); + ret.entries.push_back(entry); + } + return ret; +} + + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -2475,9 +2503,12 @@ luabind::scope lua_register_mob() { .def("GetPet", &Lua_Mob::GetPet) .def("GetOwner", &Lua_Mob::GetOwner) .def("GetHateList", &Lua_Mob::GetHateList) + .def("GetHateListByDistance", (Lua_HateList(Lua_Mob::*)(void))&Lua_Mob::GetHateListByDistance) + .def("GetHateListByDistance", (Lua_HateList(Lua_Mob::*)(int))&Lua_Mob::GetHateListByDistance) .def("GetHateTop", (Lua_Mob(Lua_Mob::*)(void))&Lua_Mob::GetHateTop) .def("GetHateDamageTop", (Lua_Mob(Lua_Mob::*)(Lua_Mob))&Lua_Mob::GetHateDamageTop) .def("GetHateRandom", (Lua_Mob(Lua_Mob::*)(void))&Lua_Mob::GetHateRandom) + .def("GetHateClosest", &Lua_Mob::GetHateClosest) .def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::AddToHateList) .def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int))&Lua_Mob::AddToHateList) .def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int,int))&Lua_Mob::AddToHateList) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index d2994f669..58245a4b0 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -198,9 +198,12 @@ public: Lua_Mob GetPet(); Lua_Mob GetOwner(); Lua_HateList GetHateList(); + Lua_HateList GetHateListByDistance(); + Lua_HateList GetHateListByDistance(int distance); Lua_Mob GetHateTop(); Lua_Mob GetHateDamageTop(Lua_Mob other); Lua_Mob GetHateRandom(); + Lua_Mob GetHateClosest(); void AddToHateList(Lua_Mob other); void AddToHateList(Lua_Mob other, int hate); void AddToHateList(Lua_Mob other, int hate, int damage); diff --git a/zone/mob.h b/zone/mob.h index 69f487c5d..61be1a0c2 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -642,6 +642,7 @@ public: Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTopOnHateList(other);} Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();} Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();} + Mob* GetHateClosest() { return hate_list.GetClosestEntOnHateList(this); } bool IsEngaged() { return(!hate_list.IsHateListEmpty()); } bool HasPrimaryAggro() { return PrimaryAggro; } bool HasAssistAggro() { return AssistAggro; } @@ -656,6 +657,7 @@ public: bool IsOnFeignMemory(Client *attacker) const; void PrintHateListToClient(Client *who) { hate_list.PrintHateListToClient(who); } std::list& GetHateList() { return hate_list.GetHateList(); } + std::list GetHateListByDistance(int distance = 0) { return hate_list.GetHateListByDistance(distance); } bool CheckLosFN(Mob* other); bool CheckLosFN(float posX, float posY, float posZ, float mobSize); static bool CheckLosFN(glm::vec3 posWatcher, float sizeWatcher, glm::vec3 posTarget, float sizeTarget); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 5e5f7981b..48af0f5c7 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -6179,6 +6179,45 @@ XS(XS_Mob_SetBucket) { XSRETURN_EMPTY; } +XS(XS_Mob_GetHateListByDistance); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_GetHateListByDistance) { + dXSARGS; + int num_entries = 0; + if (items < 1 || items > 2) + Perl_croak(aTHX_ "Usage: Mob::GetHateListByDistance(THIS, int distance)"); // @categories Hate and Aggro + { + Mob *THIS; + int distance = 0; + VALIDATE_THIS_IS_MOB; + if (items == 2) + distance = (int) SvIV(ST(1)); + + auto list = THIS->GetHateListByDistance(distance); + for (auto hate_entry : list) { + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "HateEntry", (void *) hate_entry); + XPUSHs(ST(0)); + num_entries++; + } + } + XSRETURN(num_entries); +} + +XS(XS_Mob_GetHateClosest); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_GetHateClosest) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::GetHateClosest(THIS)"); // @categories Hate and Aggro + { + Mob *THIS; + Mob *closest_mob; + VALIDATE_THIS_IS_MOB; + closest_mob = THIS->GetHateClosest(); + ST(0) = sv_newmortal(); + sv_setref_pv(ST(0), "Mob", (void *) closest_mob); + } + XSRETURN(1); +} #ifdef __cplusplus extern "C" @@ -6525,6 +6564,8 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "GetBucketKey"), XS_Mob_GetBucketKey, file, "$"); newXSproto(strcpy(buf, "GetBucketRemaining"), XS_Mob_GetBucketRemaining, file, "$$"); newXSproto(strcpy(buf, "SetBucket"), XS_Mob_SetBucket, file, "$$$;$"); + newXSproto(strcpy(buf, "GetHateClosest"), XS_Mob_GetHateClosest, file, "$"); + newXSproto(strcpy(buf, "GetHateListByDistance"), XS_Mob_GetHateListByDistance, file, "$;$"); XSRETURN_YES; }