[Quest API] Add corpse->GetLootList() and npc->GetLootList() to Perl and Lua. (#1529)

* [Quest API] Add corpse->GetLootList() and npc->GetLootList() to Perl and Lua.
- Add $corpse->GetLootList() to Perl.
- Add $npc->GetLootList() to Perl.
- Add corpse:GetLootList() to Lua.
- Add npc:GetLootList() to Lua.

Returns an array of item IDs for use with corpse and NPC methods such as HasItem(item_id), CountItem(item_id), and GetFirstSlotByItemID(item_id).

* Categories.

* Modify Lua to use classes.
This commit is contained in:
Kinglykrab 2021-09-12 23:38:38 -04:00 committed by GitHub
parent 97dcba70cf
commit 56b9b6f2c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 148 additions and 8 deletions

View File

@ -1462,12 +1462,12 @@ bool Corpse::HasItem(uint32 item_id) {
for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) {
ServerLootItem_Struct* loot_item = *current_item;
if (!loot_item) {
LogError("NPC::CountItem() - ItemList error, null item");
LogError("Corpse::HasItem() - ItemList error, null item");
continue;
}
if (!loot_item->item_id || !database.GetItem(loot_item->item_id)) {
LogError("NPC::CountItem() - Database error, invalid item");
LogError("Corpse::HasItem() - Database error, invalid item");
continue;
}
@ -1487,12 +1487,12 @@ uint16 Corpse::CountItem(uint32 item_id) {
for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) {
ServerLootItem_Struct* loot_item = *current_item;
if (!loot_item) {
LogError("NPC::CountItem() - ItemList error, null item");
LogError("Corpse::CountItem() - ItemList error, null item");
continue;
}
if (!loot_item->item_id || !database.GetItem(loot_item->item_id)) {
LogError("NPC::CountItem() - Database error, invalid item");
LogError("Corpse::CountItem() - Database error, invalid item");
continue;
}
@ -1747,3 +1747,21 @@ bool Corpse::MovePlayerCorpseToNonInstance()
return false;
}
std::vector<int> Corpse::GetLootList() {
std::vector<int> corpse_items;
for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) {
ServerLootItem_Struct* loot_item = *current_item;
if (!loot_item) {
LogError("Corpse::GetLootList() - ItemList error, null item");
continue;
}
if (std::find(corpse_items.begin(), corpse_items.end(), loot_item->item_id) != corpse_items.end()) {
continue;
}
corpse_items.push_back(loot_item->item_id);
}
return corpse_items;
}

View File

@ -117,6 +117,7 @@ class Corpse : public Mob {
uint16 CountItem(uint32 item_id);
uint32 GetItemIDBySlot(uint16 loot_slot);
uint16 GetFirstSlotByItemID(uint32 item_id);
std::vector<int> GetLootList();
void LootItem(Client* client, const EQApplicationPacket* app);
void EndLoot(Client* client, const EQApplicationPacket* app);
void MakeLootRequestPackets(Client* client, const EQApplicationPacket* app);

View File

@ -2,11 +2,16 @@
#include "lua.hpp"
#include <luabind/luabind.hpp>
#include <luabind/iterator_policy.hpp>
#include "corpse.h"
#include "lua_corpse.h"
#include "lua_client.h"
struct Lua_Corpse_Loot_List {
std::vector<uint32> entries;
};
uint32 Lua_Corpse::GetCharID() {
Lua_Safe_Call_Int();
return self->GetCharID();
@ -172,6 +177,18 @@ uint16 Lua_Corpse::GetFirstSlotByItemID(uint32 item_id) {
return self->GetFirstSlotByItemID(item_id);
}
Lua_Corpse_Loot_List Lua_Corpse::GetLootList(lua_State* L) {
Lua_Safe_Call_Class(Lua_Corpse_Loot_List);
Lua_Corpse_Loot_List ret;
auto loot_list = self->GetLootList();
for (auto item_id : loot_list) {
ret.entries.push_back(item_id);
}
return ret;
}
luabind::scope lua_register_corpse() {
return luabind::class_<Lua_Corpse, Lua_Mob>("Corpse")
.def(luabind::constructor<>())
@ -209,7 +226,13 @@ luabind::scope lua_register_corpse() {
.def("HasItem", (bool(Lua_Corpse::*)(uint32))&Lua_Corpse::HasItem)
.def("CountItem", (uint16(Lua_Corpse::*)(uint32))&Lua_Corpse::CountItem)
.def("GetItemIDBySlot", (uint32(Lua_Corpse::*)(uint16))&Lua_Corpse::GetItemIDBySlot)
.def("GetFirstSlotByItemID", (uint16(Lua_Corpse::*)(uint32))&Lua_Corpse::GetFirstSlotByItemID);
.def("GetFirstSlotByItemID", (uint16(Lua_Corpse::*)(uint32))&Lua_Corpse::GetFirstSlotByItemID)
.def("GetLootList", (Lua_Corpse_Loot_List(Lua_Corpse::*)(lua_State* L))&Lua_Corpse::GetLootList);
}
luabind::scope lua_register_corpse_loot_list() {
return luabind::class_<Lua_Corpse_Loot_List>("CorpseLootList")
.def_readwrite("entries", &Lua_Corpse_Loot_List::entries, luabind::return_stl_iterator);
}
#endif

View File

@ -6,12 +6,14 @@
class Corpse;
class Lua_Client;
struct Lua_Corpse_Loot_List;
namespace luabind {
struct scope;
}
luabind::scope lua_register_corpse();
luabind::scope lua_register_corpse_loot_list();
class Lua_Corpse : public Lua_Mob
{
@ -58,6 +60,7 @@ public:
uint16 CountItem(uint32 item_id);
uint32 GetItemIDBySlot(uint16 loot_slot);
uint16 GetFirstSlotByItemID(uint32 item_id);
Lua_Corpse_Loot_List GetLootList(lua_State* L);
};
#endif

View File

@ -2,11 +2,16 @@
#include "lua.hpp"
#include <luabind/luabind.hpp>
#include <luabind/iterator_policy.hpp>
#include "npc.h"
#include "lua_npc.h"
#include "lua_client.h"
struct Lua_NPC_Loot_List {
std::vector<uint32> entries;
};
void Lua_NPC::Signal(int id) {
Lua_Safe_Call_Void();
self->SignalNPC(id);
@ -618,6 +623,18 @@ float Lua_NPC::GetSpellScale()
return self->GetSpellScale();
}
Lua_NPC_Loot_List Lua_NPC::GetLootList(lua_State* L) {
Lua_Safe_Call_Class(Lua_NPC_Loot_List);
Lua_NPC_Loot_List ret;
auto loot_list = self->GetLootList();
for (auto item_id : loot_list) {
ret.entries.push_back(item_id);
}
return ret;
}
luabind::scope lua_register_npc() {
return luabind::class_<Lua_NPC, Lua_Mob>("NPC")
.def(luabind::constructor<>())
@ -740,7 +757,13 @@ luabind::scope lua_register_npc() {
.def("GetItemIDBySlot", (uint32(Lua_NPC::*)(uint16))&Lua_NPC::GetItemIDBySlot)
.def("GetFirstSlotByItemID", (uint16(Lua_NPC::*)(uint32))&Lua_NPC::GetFirstSlotByItemID)
.def("GetHealScale", (float(Lua_NPC::*)(void))&Lua_NPC::GetHealScale)
.def("GetSpellScale", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpellScale);
.def("GetSpellScale", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpellScale)
.def("GetLootList", (Lua_NPC_Loot_List(Lua_NPC::*)(lua_State* L))&Lua_NPC::GetLootList);
}
luabind::scope lua_register_npc_loot_list() {
return luabind::class_<Lua_NPC_Loot_List>("NPCLootList")
.def_readwrite("entries", &Lua_NPC_Loot_List::entries, luabind::return_stl_iterator);
}
#endif

View File

@ -8,12 +8,14 @@ class NPC;
class Lua_Mob;
class Lua_NPC;
class Lua_Client;
struct Lua_NPC_Loot_List;
namespace luabind {
struct scope;
}
luabind::scope lua_register_npc();
luabind::scope lua_register_npc_loot_list();
class Lua_NPC : public Lua_Mob
{
@ -146,6 +148,7 @@ public:
uint16 GetFirstSlotByItemID(uint32 item_id);
float GetHealScale();
float GetSpellScale();
Lua_NPC_Loot_List GetLootList(lua_State* L);
};
#endif

View File

@ -1121,6 +1121,8 @@ void LuaParser::MapFunctions(lua_State *L) {
lua_register_object_list(),
lua_register_door_list(),
lua_register_spawn_list(),
lua_register_corpse_loot_list(),
lua_register_npc_loot_list(),
lua_register_group(),
lua_register_raid(),
lua_register_corpse(),

View File

@ -682,12 +682,12 @@ bool NPC::HasItem(uint32 item_id) {
for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) {
ServerLootItem_Struct* loot_item = *current_item;
if (!loot_item) {
LogError("NPC::CountItem() - ItemList error, null item");
LogError("NPC::HasItem() - ItemList error, null item");
continue;
}
if (!loot_item->item_id || !database.GetItem(loot_item->item_id)) {
LogError("NPC::CountItem() - Database error, invalid item");
LogError("NPC::HasItem() - Database error, invalid item");
continue;
}
@ -3474,3 +3474,21 @@ bool NPC::IsGuard()
}
return false;
}
std::vector<int> NPC::GetLootList() {
std::vector<int> npc_items;
for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) {
ServerLootItem_Struct* loot_item = *current_item;
if (!loot_item) {
LogError("NPC::GetLootList() - ItemList error, null item");
continue;
}
if (std::find(npc_items.begin(), npc_items.end(), loot_item->item_id) != npc_items.end()) {
continue;
}
npc_items.push_back(loot_item->item_id);
}
return npc_items;
}

View File

@ -208,6 +208,7 @@ public:
uint16 CountItem(uint32 item_id);
uint32 GetItemIDBySlot(uint16 loot_slot);
uint16 GetFirstSlotByItemID(uint32 item_id);
std::vector<int> GetLootList();
uint32 CountLoot();
inline uint32 GetLoottableID() const { return loottable_id; }
virtual void UpdateEquipmentLight();

View File

@ -1846,6 +1846,29 @@ XS(XS_NPC_GetSpellScale) {
XSRETURN(1);
}
XS(XS_NPC_GetLootList);
XS(XS_NPC_GetLootList) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: NPC::GetLootList(THIS)"); // @categories Script Utility
{
NPC *THIS;
VALIDATE_THIS_IS_NPC;
auto npc_items = THIS->GetLootList();
auto item_count = npc_items.size();
if (item_count > 0) {
EXTEND(sp, item_count);
for (int index = 0; index < item_count; ++index) {
ST(index) = sv_2mortal(newSVuv(npc_items[index]));
}
XSRETURN(item_count);
}
SV* return_value = &PL_sv_undef;
ST(0) = return_value;
XSRETURN(1);
}
}
#ifdef __cplusplus
extern "C"
#endif
@ -1970,6 +1993,7 @@ XS(boot_NPC) {
newXSproto(strcpy(buf, "GetFirstSlotByItemID"), XS_NPC_GetFirstSlotByItemID, file, "$$");
newXSproto(strcpy(buf, "GetHealScale"), XS_NPC_GetHealScale, file, "$");
newXSproto(strcpy(buf, "GetSpellScale"), XS_NPC_GetSpellScale, file, "$");
newXSproto(strcpy(buf, "GetLootList"), XS_NPC_GetLootList, file, "$");
XSRETURN_YES;
}

View File

@ -599,6 +599,29 @@ XS(XS_Corpse_GetFirstSlotByItemID) {
XSRETURN(1);
}
XS(XS_Corpse_GetLootList);
XS(XS_Corpse_GetLootList) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Corpse::GetLootList(THIS)"); // @categories Script Utility
{
Corpse *THIS;
VALIDATE_THIS_IS_CORPSE;
auto corpse_items = THIS->GetLootList();
auto item_count = corpse_items.size();
if (item_count > 0) {
EXTEND(sp, item_count);
for (int index = 0; index < item_count; ++index) {
ST(index) = sv_2mortal(newSVuv(corpse_items[index]));
}
XSRETURN(item_count);
}
SV* return_value = &PL_sv_undef;
ST(0) = return_value;
XSRETURN(1);
}
}
#ifdef __cplusplus
extern "C"
#endif
@ -649,6 +672,7 @@ XS(boot_Corpse) {
newXSproto(strcpy(buf, "CountItem"), XS_Corpse_CountItem, file, "$$");
newXSproto(strcpy(buf, "GetItemIDBySlot"), XS_Corpse_GetItemIDBySlot, file, "$$");
newXSproto(strcpy(buf, "GetFirstSlotByItemID"), XS_Corpse_GetFirstSlotByItemID, file, "$$");
newXSproto(strcpy(buf, "GetLootList"), XS_Corpse_GetLootList, file, "$");
XSRETURN_YES;
}