diff --git a/common/inventory_profile.cpp b/common/inventory_profile.cpp index 743b0a31c..3f4c3b3dc 100644 --- a/common/inventory_profile.cpp +++ b/common/inventory_profile.cpp @@ -590,6 +590,37 @@ bool EQ::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Quan // Checks that user has at least 'quantity' number of items in a given inventory slot // Returns first slot it was found in, or SLOT_INVALID if not found +bool EQ::InventoryProfile::HasAugmentEquippedByID(uint32 item_id) +{ + bool has_equipped = false; + ItemInstance* item = nullptr; + + for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) { + item = GetItem(slot_id); + if (item && item->ContainsAugmentByID(item_id)) { + has_equipped = true; + break; + } + } + + return has_equipped; +} + +int EQ::InventoryProfile::CountAugmentEquippedByID(uint32 item_id) +{ + int quantity = 0; + ItemInstance* item = nullptr; + + for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) { + item = GetItem(slot_id); + if (item && item->ContainsAugmentByID(item_id)) { + quantity += item->CountAugmentByID(item_id); + } + } + + return quantity; +} + //This function has a flaw in that it only returns the last stack that it looked at //when quantity is greater than 1 and not all of quantity can be found in 1 stack. int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where) diff --git a/common/inventory_profile.h b/common/inventory_profile.h index 58a65e443..b32b028fb 100644 --- a/common/inventory_profile.h +++ b/common/inventory_profile.h @@ -140,6 +140,12 @@ namespace EQ // Remove item from inventory (and take control of memory) ItemInstance* PopItem(int16 slot_id); + // Check if player has a specific augment equipped by Item ID + bool HasAugmentEquippedByID(uint32 item_id); + + // Check how many of a specific augment the player has equipped by Item ID + int CountAugmentEquippedByID(uint32 item_id); + // Check whether there is space for the specified number of the specified item. bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity); diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 5ff9e9630..cd6d17712 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -708,6 +708,26 @@ bool EQ::ItemInstance::ContainsAugmentByID(uint32 item_id) return false; } +int EQ::ItemInstance::CountAugmentByID(uint32 item_id) +{ + int quantity = 0; + if (!m_item || !m_item->IsClassCommon()) { + return quantity; + } + + if (!item_id) { + return quantity; + } + + for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) { + if (GetAugmentItemID(augment_slot) == item_id) { + quantity++; + } + } + + return quantity; +} + // Has attack/delay? bool EQ::ItemInstance::IsWeapon() const { diff --git a/common/item_instance.h b/common/item_instance.h index 008e4aefd..c6b97dd78 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -133,6 +133,7 @@ namespace EQ ItemInstance* RemoveAugment(uint8 index); bool IsAugmented(); bool ContainsAugmentByID(uint32 item_id); + int CountAugmentByID(uint32 item_id); ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const; bool UpdateOrnamentationInfo(); static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false); diff --git a/zone/lua_inventory.cpp b/zone/lua_inventory.cpp index 3f9af6947..f19b9af87 100644 --- a/zone/lua_inventory.cpp +++ b/zone/lua_inventory.cpp @@ -164,6 +164,16 @@ int Lua_Inventory::GetSlotByItemInst(Lua_ItemInst inst) { return self->GetSlotByItemInst(inst); } +int Lua_Inventory::CountAugmentEquippedByID(uint32 item_id) { + Lua_Safe_Call_Int(); + return self->CountAugmentEquippedByID(item_id); +} + +bool Lua_Inventory::HasAugmentEquippedByID(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->HasAugmentEquippedByID(item_id); +} + luabind::scope lua_register_inventory() { return luabind::class_("Inventory") .def(luabind::constructor<>()) @@ -174,6 +184,7 @@ luabind::scope lua_register_inventory() { .def("CalcSlotId", (int(Lua_Inventory::*)(int,int))&Lua_Inventory::CalcSlotId) .def("CanItemFitInContainer", (bool(Lua_Inventory::*)(Lua_Item,Lua_Item))&Lua_Inventory::CanItemFitInContainer) .def("CheckNoDrop", (bool(Lua_Inventory::*)(int))&Lua_Inventory::CheckNoDrop) + .def("CountAugmentEquippedByID", (int(Lua_Inventory::*)(uint32))&Lua_Inventory::CountAugmentEquippedByID) .def("DeleteItem", (bool(Lua_Inventory::*)(int))&Lua_Inventory::DeleteItem) .def("DeleteItem", (bool(Lua_Inventory::*)(int,int))&Lua_Inventory::DeleteItem) .def("FindFreeSlot", (int(Lua_Inventory::*)(bool,bool))&Lua_Inventory::FindFreeSlot) @@ -182,6 +193,7 @@ luabind::scope lua_register_inventory() { .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int))&Lua_Inventory::GetItem) .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int,int))&Lua_Inventory::GetItem) .def("GetSlotByItemInst", (int(Lua_Inventory::*)(Lua_ItemInst))&Lua_Inventory::GetSlotByItemInst) + .def("HasAugmentEquippedByID", (bool(Lua_Inventory::*)(uint32))&Lua_Inventory::HasAugmentEquippedByID) .def("HasItem", (int(Lua_Inventory::*)(int))&Lua_Inventory::HasItem) .def("HasItem", (int(Lua_Inventory::*)(int,int))&Lua_Inventory::HasItem) .def("HasItem", (int(Lua_Inventory::*)(int,int,int))&Lua_Inventory::HasItem) diff --git a/zone/lua_inventory.h b/zone/lua_inventory.h index b64e9c48c..33ba80b39 100644 --- a/zone/lua_inventory.h +++ b/zone/lua_inventory.h @@ -43,7 +43,9 @@ public: bool DeleteItem(int slot_id); bool DeleteItem(int slot_id, int quantity); bool CheckNoDrop(int slot_id); + int CountAugmentEquippedByID(uint32 item_id); Lua_ItemInst PopItem(int slot_id); + bool HasAugmentEquippedByID(uint32 item_id); int HasItem(int item_id); int HasItem(int item_id, int quantity); int HasItem(int item_id, int quantity, int where); diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 1c5155e5d..149c087b6 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -264,6 +264,16 @@ void Lua_ItemInst::ClearTimers() { self->ClearTimers(); } +bool Lua_ItemInst::ContainsAugmentByID(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->ContainsAugmentByID(item_id); +} + +int Lua_ItemInst::CountAugmentByID(uint32 item_id) { + Lua_Safe_Call_Int(); + return self->CountAugmentByID(item_id); +} + luabind::scope lua_register_iteminst() { return luabind::class_("ItemInst") .def(luabind::constructor<>()) @@ -274,6 +284,8 @@ luabind::scope lua_register_iteminst() { .def("AddExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::AddExp) .def("ClearTimers", (void(Lua_ItemInst::*)(void))&Lua_ItemInst::ClearTimers) .def("Clone", (Lua_ItemInst(Lua_ItemInst::*)(void))&Lua_ItemInst::Clone) + .def("ContainsAugmentByID", (bool(Lua_ItemInst::*)(uint32))&Lua_ItemInst::ContainsAugmentByID) + .def("CountAugmentByID", (int(Lua_ItemInst::*)(uint32))&Lua_ItemInst::CountAugmentByID) .def("DeleteCustomData", (void(Lua_ItemInst::*)(std::string))&Lua_ItemInst::DeleteCustomData) .def("GetAugment", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugment) .def("GetAugmentItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugmentItemID) diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h index 7614bea5d..c0a4d50c4 100644 --- a/zone/lua_iteminst.h +++ b/zone/lua_iteminst.h @@ -80,6 +80,8 @@ public: void SetTimer(std::string name, uint32 time); void StopTimer(std::string name); void ClearTimers(); + bool ContainsAugmentByID(uint32 item_id); + int CountAugmentByID(uint32 item_id); private: bool cloned_; diff --git a/zone/perl_inventory.cpp b/zone/perl_inventory.cpp index c2ea6679c..140042a47 100644 --- a/zone/perl_inventory.cpp +++ b/zone/perl_inventory.cpp @@ -414,6 +414,41 @@ XS(XS_Inventory_PutItem) { XSRETURN(1); } +XS(XS_Inventory_HasAugmentEquippedByID); +XS(XS_Inventory_HasAugmentEquippedByID) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Inventory::HasAugmentEquippedByID(THIS, uint32 item_id)"); + { + EQ::InventoryProfile* THIS; + bool has_equipped = false; + uint32 item_id = (uint32) SvUV(ST(1)); + VALIDATE_THIS_IS_INVENTORY; + has_equipped = THIS->HasAugmentEquippedByID(item_id); + ST(0) = boolSV(has_equipped); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + +XS(XS_Inventory_CountAugmentEquippedByID); +XS(XS_Inventory_CountAugmentEquippedByID) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Inventory::CountAugmentEquippedByID(THIS, uint32 item_id)"); + { + EQ::InventoryProfile* THIS; + int quantity = 0; + uint32 item_id = (uint32) SvUV(ST(1)); + dXSTARG; + VALIDATE_THIS_IS_INVENTORY; + quantity = THIS->CountAugmentEquippedByID(item_id); + XSprePUSH; + PUSHi((IV)quantity); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -430,6 +465,7 @@ XS(boot_Inventory) { char buf[128]; XS_VERSION_BOOTCHECK; newXSproto(strcpy(buf, "CanItemFitInContainer"), XS_Inventory_CanItemFitInContainer, file, "$$$"); + newXSproto(strcpy(buf, "CountAugmentEquippedByID"), XS_Inventory_CountAugmentEquippedByID, file, "$$"); newXSproto(strcpy(buf, "CheckNoDrop"), XS_Inventory_CheckNoDrop, file, "$$"); newXSproto(strcpy(buf, "DeleteItem"), XS_Inventory_DeleteItem, file, "$$;$"); newXSproto(strcpy(buf, "FindFreeSlot"), XS_Inventory_FindFreeSlot, file, "$$$;$$"); @@ -439,6 +475,7 @@ XS(boot_Inventory) { newXSproto(strcpy(buf, "GetSlotByItemInst"), XS_Inventory_GetSlotByItemInst, file, "$$"); newXSproto(strcpy(buf, "GetSlotFromMaterial"), XS_Inventory_GetSlotFromMaterial, file, "$$"); newXSproto(strcpy(buf, "GetSlotID"), XS_Inventory_GetSlotID, file, "$$;$"); + newXSproto(strcpy(buf, "HasAugmentEquippedByID"), XS_Inventory_HasAugmentEquippedByID, file, "$$"); newXSproto(strcpy(buf, "HasItem"), XS_Inventory_HasItem, file, "$$;$$"); newXSproto(strcpy(buf, "HasItemByLoreGroup"), XS_Inventory_HasItemByLoreGroup, file, "$$;$"); newXSproto(strcpy(buf, "HasItemByUse"), XS_Inventory_HasItemByUse, file, "$$;$$"); diff --git a/zone/perl_questitem.cpp b/zone/perl_questitem.cpp index 30a5a7ca1..709201a71 100644 --- a/zone/perl_questitem.cpp +++ b/zone/perl_questitem.cpp @@ -168,6 +168,41 @@ XS(XS_QuestItem_GetID) { XSRETURN(1); } +XS(XS_QuestItem_ContainsAugmentByID); /* prototype to pass -Wmissing-prototypes */ +XS(XS_QuestItem_ContainsAugmentByID) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: QuestItem::ContainsAugmentByID(THIS, uint32 item_id)"); // @categories Inventory and Items + { + EQ::ItemInstance *THIS; + uint32 item_id = (uint32) SvUV(ST(1)); + bool contains_augment = false; + VALIDATE_THIS_IS_ITEM; + contains_augment = THIS->ContainsAugmentByID(item_id); + ST(0) = boolSV(contains_augment); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + +XS(XS_QuestItem_CountAugmentByID); /* prototype to pass -Wmissing-prototypes */ +XS(XS_QuestItem_CountAugmentByID) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: QuestItem::CountAugmentByID(THIS, uint32 item_id)"); // @categories Inventory and Items + { + EQ::ItemInstance *THIS; + int quantity = 0; + uint32 item_id = (uint32) SvUV(ST(1)); + dXSTARG; + VALIDATE_THIS_IS_ITEM; + quantity = THIS->CountAugmentByID(item_id); + XSprePUSH; + PUSHi((IV) quantity); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -186,6 +221,8 @@ XS(boot_QuestItem) { //add the strcpy stuff to get rid of const warnings.... XS_VERSION_BOOTCHECK; + newXSproto(strcpy(buf, "ContainsAugmentByID"), XS_QuestItem_ContainsAugmentByID, file, "$$"); + newXSproto(strcpy(buf, "CountAugmentByID"), XS_QuestItem_CountAugmentByID, file, "$$"); newXSproto(strcpy(buf, "GetAugment"), XS_QuestItem_GetAugment, file, "$$"); newXSproto(strcpy(buf, "GetCharges"), XS_QuestItem_GetCharges, file, "$"); newXSproto(strcpy(buf, "GetID"), XS_QuestItem_GetID, file, "$");