diff --git a/zone/client.cpp b/zone/client.cpp index 614917da9..9fbd42b98 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -10129,3 +10129,67 @@ void Client::SetAFK(uint8 afk_flag) { entity_list.QueueClients(this, outapp); safe_delete(outapp); } + +int Client::CountItem(uint32 item_id) +{ + int quantity = 0; + EQ::ItemInstance *item = nullptr; + static const int16 slots[][2] = { + { EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END }, + { EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END }, + { EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END}, + { EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END }, + { EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END }, + { EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END }, + { EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END }, + }; + const size_t size = sizeof(slots) / sizeof(slots[0]); + for (int slot_index = 0; slot_index < size; ++slot_index) { + for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) { + item = GetInv().GetItem(slot_id); + if (item && item->GetID() == item_id) { + quantity += (item->IsStackable() ? item->GetCharges() : 1); + } + } + } + + return quantity; +} + +void Client::RemoveItem(uint32 item_id, uint32 quantity) +{ + EQ::ItemInstance *item = nullptr; + static const int16 slots[][2] = { + { EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END }, + { EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END }, + { EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END}, + { EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END }, + { EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END }, + { EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END }, + { EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END }, + }; + int removed_count = 0; + const size_t size = sizeof(slots) / sizeof(slots[0]); + for (int slot_index = 0; slot_index < size; ++slot_index) { + for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) { + if (removed_count == quantity) { + break; + } + + item = GetInv().GetItem(slot_id); + if (item && item->GetID() == item_id) { + int stack_size = item->IsStackable() ? item->GetCharges() : 1; + if ((removed_count + stack_size) <= quantity) { + removed_count += stack_size; + DeleteItemInInventory(slot_id, stack_size, true); + } else { + int amount_left = (quantity - removed_count); + if (amount_left > 0 && stack_size >= amount_left) { + removed_count += amount_left; + DeleteItemInInventory(slot_id, amount_left, true); + } + } + } + } + } +} diff --git a/zone/client.h b/zone/client.h index beaf191b4..9408ff1c7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -907,6 +907,8 @@ public: bool PushItemOnCursor(const EQ::ItemInstance& inst, bool client_update = false); void SendCursorBuffer(); void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true); + int CountItem(uint32 item_id); + void RemoveItem(uint32 item_id, uint32 quantity = 1); bool SwapItem(MoveItem_Struct* move_in); void SwapItemResync(MoveItem_Struct* move_slots); void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 35ac56006..c08d27fad 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -2138,6 +2138,21 @@ void Lua_Client::ResetAllDisciplineTimers() { self->ResetAllDisciplineTimers(); } +int Lua_Client::CountItem(uint32 item_id) { + Lua_Safe_Call_Int(); + return self->CountItem(item_id); +} + +void Lua_Client::RemoveItem(uint32 item_id) { + Lua_Safe_Call_Void(); + return self->RemoveItem(item_id); +} + +void Lua_Client::RemoveItem(uint32 item_id, uint32 quantity) { + Lua_Safe_Call_Void(); + return self->RemoveItem(item_id, quantity); +} + luabind::scope lua_register_client() { return luabind::class_("Client") .def(luabind::constructor<>()) @@ -2501,7 +2516,10 @@ luabind::scope lua_register_client() { .def("Popup", (void(Lua_Client::*)(const char*,const char*,uint32,uint32,uint32,uint32))& Lua_Client::Popup) .def("Popup", (void(Lua_Client::*)(const char*,const char*,uint32,uint32,uint32,uint32,const char*,const char*))& Lua_Client::Popup) .def("Popup", (void(Lua_Client::*)(const char*,const char*,uint32,uint32,uint32,uint32,const char*,const char*,uint32))&Lua_Client::Popup) - .def("ResetAllDisciplineTimers", (void(Lua_Client::*)(void))&Lua_Client::ResetAllDisciplineTimers); + .def("ResetAllDisciplineTimers", (void(Lua_Client::*)(void))&Lua_Client::ResetAllDisciplineTimers) + .def("CountItem", (int(Lua_Client::*)(uint32))&Lua_Client::CountItem) + .def("RemoveItem", (void(Lua_Client::*)(uint32))&Lua_Client::RemoveItem) + .def("RemoveItem", (void(Lua_Client::*)(uint32,uint32))&Lua_Client::RemoveItem); } luabind::scope lua_register_inventory_where() { diff --git a/zone/lua_client.h b/zone/lua_client.h index f13b69daf..d95af104a 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -366,6 +366,9 @@ public: void Popup(const char* title, const char* text, uint32 popup_id, uint32 negative_id, uint32 button_type, uint32 duration); void Popup(const char* title, const char* text, uint32 popup_id, uint32 negative_id, uint32 button_type, uint32 duration, const char* button_name_one, const char* button_name_two); void Popup(const char* title, const char* text, uint32 popup_id, uint32 negative_id, uint32 button_type, uint32 duration, const char* button_name_one, const char* button_name_two, uint32 sound_controls); + int CountItem(uint32 item_id); + void RemoveItem(uint32 item_id); + void RemoveItem(uint32 item_id, uint32 quantity); void SetPrimaryWeaponOrnamentation(uint32 model_id); void SetSecondaryWeaponOrnamentation(uint32 model_id); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 034611fb4..bcd118fc1 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -5345,6 +5345,43 @@ XS(XS_Client_ResetAllDisciplineTimers) { XSRETURN_EMPTY; } +XS(XS_Client_CountItem); +XS(XS_Client_CountItem) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::CountItem(THIS, uint32 item_id)"); + { + Client* THIS; + int item_count = 0; + uint32 item_id = (uint32) SvUV(ST(1)); + dXSTARG; + VALIDATE_THIS_IS_CLIENT; + item_count = THIS->CountItem(item_id); + XSprePUSH; + PUSHu((UV) item_count); + } + XSRETURN(1); +} + +XS(XS_Client_RemoveItem); +XS(XS_Client_RemoveItem) { + dXSARGS; + if (items != 2 && items != 3) + Perl_croak(aTHX_ "Usage: Client::RemoveItem(THIS, uint32 item_id, [uint32 quantity = 1])"); // @categories Spells and Disciplines + { + Client *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); + uint32 quantity = 1; + VALIDATE_THIS_IS_CLIENT; + if (items == 3) { + quantity = (uint32) SvUV(ST(2)); + } + + THIS->RemoveItem(item_id, quantity); + } + XSRETURN_EMPTY; +} + #ifdef __cplusplus extern "C" #endif @@ -5395,6 +5432,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$"); newXSproto(strcpy(buf, "CreateExpedition"), XS_Client_CreateExpedition, file, "$$$$$$$;$"); newXSproto(strcpy(buf, "Connected"), XS_Client_Connected, file, "$"); + newXSproto(strcpy(buf, "CountItem"), XS_Client_CountItem, file, "$$"); newXSproto(strcpy(buf, "DecreaseByID"), XS_Client_DecreaseByID, file, "$$$"); newXSproto(strcpy(buf, "DeleteItemInInventory"), XS_Client_DeleteItemInInventory, file, "$$;$$"); newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$"); @@ -5563,6 +5601,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "RefundAA"), XS_Client_RefundAA, file, "$$"); newXSproto(strcpy(buf, "RemoveAllExpeditionLockouts"), XS_Client_RemoveAllExpeditionLockouts, file, "$;$"); newXSproto(strcpy(buf, "RemoveExpeditionLockout"), XS_Client_RemoveExpeditionLockout, file, "$$$"); + newXSproto(strcpy(buf, "RemoveItem"), XS_Client_RemoveItem, file, "$$;$"); newXSproto(strcpy(buf, "RemoveNoRent"), XS_Client_RemoveNoRent, file, "$"); newXSproto(strcpy(buf, "ResetAA"), XS_Client_ResetAA, file, "$"); newXSproto(strcpy(buf, "ResetAllDisciplineTimers"), XS_Client_ResetAllDisciplineTimers, file, "$"); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 0ec4a4309..8848f7eda 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2645,65 +2645,12 @@ int QuestManager::collectitems(uint32 item_id, bool remove) int QuestManager::countitem(uint32 item_id) { QuestManagerCurrentQuestVars(); - int quantity = 0; - EQ::ItemInstance *item = nullptr; - static const int16 slots[][2] = { - { EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END }, - { EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END }, - { EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END}, - { EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END }, - { EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END }, - { EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END }, - { EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END }, - }; - const size_t size = sizeof(slots) / sizeof(slots[0]); - for (int slot_index = 0; slot_index < size; ++slot_index) { - for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) { - item = initiator->GetInv().GetItem(slot_id); - if (item && item->GetID() == item_id) { - quantity += item->IsStackable() ? item->GetCharges() : 1; - } - } - } - - return quantity; + return initiator->CountItem(item_id); } void QuestManager::removeitem(uint32 item_id, uint32 quantity) { QuestManagerCurrentQuestVars(); - EQ::ItemInstance *item = nullptr; - static const int16 slots[][2] = { - { EQ::invslot::POSSESSIONS_BEGIN, EQ::invslot::POSSESSIONS_END }, - { EQ::invbag::GENERAL_BAGS_BEGIN, EQ::invbag::GENERAL_BAGS_END }, - { EQ::invbag::CURSOR_BAG_BEGIN, EQ::invbag::CURSOR_BAG_END}, - { EQ::invslot::BANK_BEGIN, EQ::invslot::BANK_END }, - { EQ::invbag::BANK_BAGS_BEGIN, EQ::invbag::BANK_BAGS_END }, - { EQ::invslot::SHARED_BANK_BEGIN, EQ::invslot::SHARED_BANK_END }, - { EQ::invbag::SHARED_BANK_BAGS_BEGIN, EQ::invbag::SHARED_BANK_BAGS_END }, - }; - int removed_count = 0; - const size_t size = sizeof(slots) / sizeof(slots[0]); - for (int slot_index = 0; slot_index < size; ++slot_index) { - for (int slot_id = slots[slot_index][0]; slot_id <= slots[slot_index][1]; ++slot_id) { - if (removed_count == quantity) - break; - - item = initiator->GetInv().GetItem(slot_id); - if (item && item->GetID() == item_id) { - int stack_size = item->IsStackable() ? item->GetCharges() : 1; - if ((removed_count + stack_size) <= quantity) { - removed_count += stack_size; - initiator->DeleteItemInInventory(slot_id, stack_size, true); - } else { - int amount_left = (quantity - removed_count); - if (amount_left > 0 && stack_size >= amount_left) { - removed_count += amount_left; - initiator->DeleteItemInInventory(slot_id, amount_left, true); - } - } - } - } - } + initiator->RemoveItem(item_id, quantity); } void QuestManager::UpdateSpawnTimer(uint32 id, uint32 newTime)