diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 1e655a6bc..5ccdc8672 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -791,6 +791,45 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data) } } +void Corpse::RemoveItemByID(uint32 item_id, int quantity) { + if (!database.GetItem(item_id)) { + return; + } + + if (!HasItem(item_id)) { + return; + } + + int removed_count = 0; + for (auto current_item = itemlist.begin(); current_item != itemlist.end(); ++current_item) { + ServerLootItem_Struct* sitem = *current_item; + if (removed_count == quantity) { + break; + } + + if (sitem && sitem->item_id == item_id) { + int stack_size = sitem->charges > 1 ? sitem->charges : 1; + if ((removed_count + stack_size) <= quantity) { + removed_count += stack_size; + is_corpse_changed = true; + itemlist.erase(current_item); + } else { + int amount_left = (quantity - removed_count); + if (amount_left > 0) { + if (stack_size > amount_left) { + removed_count += amount_left; + sitem->charges -= amount_left; + is_corpse_changed = true; + } else if (stack_size == amount_left) { + removed_count += amount_left; + itemlist.erase(current_item); + } + } + } + } + } +} + void Corpse::SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum) { this->copper = in_copper; this->silver = in_silver; diff --git a/zone/corpse.h b/zone/corpse.h index acbd63ac5..a395c1956 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -95,6 +95,7 @@ class Corpse : public Mob { int32 GetPlayerKillItem() { return player_kill_item; } void RemoveItem(uint16 lootslot); void RemoveItem(ServerLootItem_Struct* item_data); + void RemoveItemByID(uint32 item_id, int quantity = 1); void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); /* Corpse: Coin */ diff --git a/zone/lua_corpse.cpp b/zone/lua_corpse.cpp index 200e13ce3..29a9eb31c 100644 --- a/zone/lua_corpse.cpp +++ b/zone/lua_corpse.cpp @@ -177,6 +177,16 @@ uint16 Lua_Corpse::GetFirstSlotByItemID(uint32 item_id) { return self->GetFirstSlotByItemID(item_id); } +void Lua_Corpse::RemoveItemByID(uint32 item_id) { + Lua_Safe_Call_Void(); + self->RemoveItemByID(item_id); +} + +void Lua_Corpse::RemoveItemByID(uint32 item_id, int quantity) { + Lua_Safe_Call_Void(); + self->RemoveItemByID(item_id, quantity); +} + Lua_Corpse_Loot_List Lua_Corpse::GetLootList(lua_State* L) { Lua_Safe_Call_Class(Lua_Corpse_Loot_List); Lua_Corpse_Loot_List ret; @@ -227,6 +237,8 @@ luabind::scope lua_register_corpse() { .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("RemoveItemByID", (void(Lua_Corpse::*)(uint32))&Lua_Corpse::RemoveItemByID) + .def("RemoveItemByID", (void(Lua_Corpse::*)(uint32,int))&Lua_Corpse::RemoveItemByID) .def("GetLootList", (Lua_Corpse_Loot_List(Lua_Corpse::*)(lua_State* L))&Lua_Corpse::GetLootList); } diff --git a/zone/lua_corpse.h b/zone/lua_corpse.h index c8c9bf470..0df694b51 100644 --- a/zone/lua_corpse.h +++ b/zone/lua_corpse.h @@ -44,6 +44,8 @@ public: void AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5); uint32 GetWornItem(int16 equipSlot); void RemoveItem(uint16 lootslot); + void RemoveItemByID(uint32 item_id); + void RemoveItemByID(uint32 item_id, int quantity); void SetCash(uint32 copper, uint32 silver, uint32 gold, uint32 platinum); void RemoveCash(); bool IsEmpty(); diff --git a/zone/perl_player_corpse.cpp b/zone/perl_player_corpse.cpp index dd01acda4..f4e85c214 100644 --- a/zone/perl_player_corpse.cpp +++ b/zone/perl_player_corpse.cpp @@ -599,6 +599,24 @@ XS(XS_Corpse_GetFirstSlotByItemID) { XSRETURN(1); } +XS(XS_Corpse_RemoveItemByID); +XS(XS_Corpse_RemoveItemByID) { + dXSARGS; + if (items != 2 && items != 3) + Perl_croak(aTHX_ "Usage: Corpse::RemoveItemByID(THIS, uint32 item_id, [int quantity = 1])"); // @categories Script Utility + { + Corpse *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); + int quantity = 1; + VALIDATE_THIS_IS_CORPSE; + if (items == 3) + quantity = (int) SvIV(ST(2)); + + THIS->RemoveItemByID(item_id, quantity); + } + XSRETURN_EMPTY; +} + XS(XS_Corpse_GetLootList); XS(XS_Corpse_GetLootList) { dXSARGS; @@ -672,6 +690,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, "RemoveItemByID"), XS_Corpse_RemoveItemByID, file, "$$;$"); newXSproto(strcpy(buf, "GetLootList"), XS_Corpse_GetLootList, file, "$"); XSRETURN_YES; }