diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 2ad425f3a..1ae4c22c1 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -2926,6 +2926,22 @@ XS(XS__countitem) { XSRETURN_IV(quantity); } +XS(XS__removeitem); +XS(XS__removeitem) { + dXSARGS; + if (items < 1 || items > 2) + Perl_croak(aTHX_ "Usage: quest::removeitem(int item_id, [int quantity = 1])"); + + uint32 item_id = (int) SvIV(ST(0)); + uint32 quantity = 1; + if (items > 1) + quantity = (int) SvIV(ST(1)); + + quest_manager.removeitem(item_id, quantity); + + XSRETURN_EMPTY; +} + XS(XS__getitemname); XS(XS__getitemname) { dXSARGS; @@ -6312,6 +6328,7 @@ EXTERN_C XS(boot_quest) { newXS(strcpy(buf, "rain"), XS__rain, file); newXS(strcpy(buf, "rebind"), XS__rebind, file); newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file); + newXS(strcpy(buf, "removeitem"), XS__removeitem, file); newXS(strcpy(buf, "removetitle"), XS__removetitle, file); newXS(strcpy(buf, "repopzone"), XS__repopzone, file); newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 1fb257150..ecb072369 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -806,6 +806,14 @@ int lua_count_item(uint32 item_id) { return quest_manager.countitem(item_id); } +void lua_remove_item(uint32 item_id) { + quest_manager.removeitem(item_id); +} + +void lua_remove_item(uint32 item_id, uint32 quantity) { + quest_manager.removeitem(item_id, quantity); +} + void lua_update_spawn_timer(uint32 id, uint32 new_time) { quest_manager.UpdateSpawnTimer(id, new_time); } @@ -2487,6 +2495,8 @@ luabind::scope lua_register_general() { luabind::def("modify_npc_stat", &lua_modify_npc_stat), luabind::def("collect_items", &lua_collect_items), luabind::def("count_item", &lua_count_item), + luabind::def("remove_item", (void(*)(uint32))&lua_remove_item), + luabind::def("remove_item", (void(*)(uint32,uint32))&lua_remove_item), luabind::def("update_spawn_timer", &lua_update_spawn_timer), luabind::def("merchant_set_item", (void(*)(uint32,uint32))&lua_merchant_set_item), luabind::def("merchant_set_item", (void(*)(uint32,uint32,uint32))&lua_merchant_set_item), diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 15651b1be..631bb1218 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2729,6 +2729,43 @@ int QuestManager::countitem(uint32 item_id) { return quantity; } +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); + } + } + } + } + } +} + void QuestManager::UpdateSpawnTimer(uint32 id, uint32 newTime) { bool found = false; diff --git a/zone/questmgr.h b/zone/questmgr.h index 18c20907f..f3f656e51 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -227,6 +227,7 @@ public: int collectitems(uint32 item_id, bool remove); int collectitems_processSlot(int16 slot_id, uint32 item_id, bool remove); int countitem(uint32 item_id); + void removeitem(uint32 item_id, uint32 quantity = 1); std::string getitemname(uint32 item_id); void enabletitle(int titleset); bool checktitle(int titlecheck);