[Quest API] Add GetHateRandomBot(), GetHateRandomClient(), and GetHateRandomNPC() to Perl/Lua. (#1613)

- Add $mob->GetHateRandomBot() to Perl.
- Add $mob->GetHateRandomClient() to Perl.
- Add $mob->GetHateRandomNPC() to Perl.
- Add mob:GetHateRandomBot() to Lua.
- Add mob:GetHateRandomClient() to Lua.
- Add mob:GetHateRandomNPC() to Lua.
This commit is contained in:
Kinglykrab 2021-10-17 23:41:10 -04:00 committed by GitHub
parent 7823ff5336
commit 3dcddcba04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 248 additions and 1 deletions

View File

@ -797,3 +797,152 @@ std::list<struct_HateList*> HateList::GetHateListByDistance(int distance)
}
return hate_list;
}
#ifdef BOTS
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;
}
#endif
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;
}

View File

@ -49,6 +49,12 @@ public:
Mob *GetEscapingEntOnHateList(); // returns first eligble entity
Mob *GetEscapingEntOnHateList(Mob *center, float range = 0.0f, bool first = false);
#ifdef BOTS
Bot* GetRandomBotOnHateList(bool skip_mezzed = false);
#endif
Client* GetRandomClientOnHateList(bool skip_mezzed = false);
NPC* GetRandomNPCOnHateList(bool skip_mezzed = false);
bool IsEntOnHateList(Mob *mob);
bool IsHateListEmpty();
bool RemoveEntFromHateList(Mob *ent);

View File

@ -5,9 +5,13 @@
#include "client.h"
#include "npc.h"
#ifdef BOTS
#include "lua_bot.h"
#endif
#include "lua_item.h"
#include "lua_iteminst.h"
#include "lua_mob.h"
#include "lua_npc.h"
#include "lua_hate_list.h"
#include "lua_client.h"
#include "lua_stat_bonuses.h"
@ -2402,6 +2406,23 @@ void Lua_Mob::RemoveAllNimbusEffects() {
self->RemoveAllNimbusEffects();
}
#ifdef BOTS
Lua_Bot Lua_Mob::GetHateRandomBot() {
Lua_Safe_Call_Class(Lua_Bot);
return Lua_Bot(self->GetHateRandomBot());
}
#endif
Lua_Client Lua_Mob::GetHateRandomClient() {
Lua_Safe_Call_Class(Lua_Client);
return Lua_Client(self->GetHateRandomClient());
}
Lua_NPC Lua_Mob::GetHateRandomNPC() {
Lua_Safe_Call_Class(Lua_NPC);
return Lua_NPC(self->GetHateRandomNPC());
}
luabind::scope lua_register_mob() {
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
.def(luabind::constructor<>())
@ -2810,7 +2831,12 @@ luabind::scope lua_register_mob() {
.def("GetLastName", &Lua_Mob::GetLastName)
.def("CanClassEquipItem", &Lua_Mob::CanClassEquipItem)
.def("CanRaceEquipItem", &Lua_Mob::CanRaceEquipItem)
.def("RemoveAllNimbusEffects", &Lua_Mob::RemoveAllNimbusEffects);
.def("RemoveAllNimbusEffects", &Lua_Mob::RemoveAllNimbusEffects)
#ifdef BOTS
.def("GetHateRandomBot", (Lua_Bot(Lua_Mob::*)(void))&Lua_Mob::GetHateRandomBot)
#endif
.def("GetHateRandomClient", (Lua_Client(Lua_Mob::*)(void))&Lua_Mob::GetHateRandomClient)
.def("GetHateRandomNPC", (Lua_NPC(Lua_Mob::*)(void))&Lua_Mob::GetHateRandomNPC);
}
luabind::scope lua_register_special_abilities() {

View File

@ -9,6 +9,11 @@ struct Lua_HateList;
class Lua_Item;
class Lua_ItemInst;
class Lua_StatBonuses;
#ifdef BOTS
class Lua_Bot;
#endif
class Lua_NPC;
class Lua_Client;
namespace luabind {
struct scope;
@ -205,6 +210,11 @@ public:
Lua_Mob GetHateTop();
Lua_Mob GetHateDamageTop(Lua_Mob other);
Lua_Mob GetHateRandom();
#ifdef BOTS
Lua_Bot GetHateRandomBot();
#endif
Lua_Client GetHateRandomClient();
Lua_NPC GetHateRandomNPC();
Lua_Mob GetHateClosest();
void AddToHateList(Lua_Mob other);
void AddToHateList(Lua_Mob other, int hate);

View File

@ -649,6 +649,11 @@ public:
Mob* GetSecondaryHate(Mob *skip) { return hate_list.GetEntWithMostHateOnList(this, skip); }
Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTopOnHateList(other);}
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
Client* GetHateRandomClient() { return hate_list.GetRandomClientOnHateList(); }
NPC* GetHateRandomNPC() { return hate_list.GetRandomNPCOnHateList(); }
#ifdef BOTS
Bot* GetHateRandomBot() { return hate_list.GetRandomBotOnHateList(); }
#endif
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
Mob* GetHateClosest() { return hate_list.GetClosestEntOnHateList(this); }
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }

View File

@ -6357,6 +6357,38 @@ XS(XS_Mob_ShieldAbility) {
XSRETURN_EMPTY;
}
XS(XS_Mob_GetHateRandomClient); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetHateRandomClient) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::GetHateRandomClient(THIS)"); // @categories Hate and Aggro
{
Mob* THIS;
Client* RETVAL;
VALIDATE_THIS_IS_MOB;
RETVAL = THIS->GetHateRandomClient();
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "Client", (void *) RETVAL);
}
XSRETURN(1);
}
XS(XS_Mob_GetHateRandomNPC); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetHateRandomNPC) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::GetHateRandomNPC(THIS)"); // @categories Hate and Aggro
{
Mob* THIS;
NPC* RETVAL;
VALIDATE_THIS_IS_MOB;
RETVAL = THIS->GetHateRandomNPC();
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "NPC", (void *) RETVAL);
}
XSRETURN(1);
}
#ifdef BOTS
XS(XS_Mob_CastToBot); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_CastToBot)
@ -6374,6 +6406,22 @@ XS(XS_Mob_CastToBot)
}
XSRETURN(1);
}
XS(XS_Mob_GetHateRandomBot); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetHateRandomBot) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::GetHateRandomBot(THIS)"); // @categories Hate and Aggro
{
Mob* THIS;
Bot* RETVAL;
VALIDATE_THIS_IS_MOB;
RETVAL = THIS->GetHateRandomBot();
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "Bot", (void *) RETVAL);
}
XSRETURN(1);
}
#endif
#ifdef __cplusplus
@ -6729,8 +6777,11 @@ XS(boot_Mob) {
newXSproto(strcpy(buf, "RemoveAllNimbusEffects"), XS_Mob_RemoveAllNimbusEffects, file, "$");
newXSproto(strcpy(buf, "AddNimbusEffect"), XS_Mob_AddNimbusEffect, file, "$$");
newXSproto(strcpy(buf, "ShieldAbility"), XS_Mob_ShieldAbility, file, "$$$$$$$$");
newXSproto(strcpy(buf, "GetHateRandomClient"), XS_Mob_GetHateRandomClient, file, "$");
newXSproto(strcpy(buf, "GetHateRandomNPC"), XS_Mob_GetHateRandomNPC, file, "$");
#ifdef BOTS
newXSproto(strcpy(buf, "CastToBot"), XS_Mob_CastToBot, file, "$");
newXSproto(strcpy(buf, "GetHateRandomBot"), XS_Mob_GetHateRandomBot, file, "$");
#endif
XSRETURN_YES;
}