diff --git a/common/item_instance.h b/common/item_instance.h index 1b1d4043e..5aa699b10 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -108,7 +108,8 @@ namespace EQ bool AvailableWearSlot(uint32 aug_wear_slots) const; int8 AvailableAugmentSlot(int32 augment_type) const; bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const; - inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); } + inline uint32 GetAugmentType() const { return m_item ? m_item->AugType : 0; } + inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; } inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); } diff --git a/zone/client.h b/zone/client.h index 17a0ee97d..4dced69a5 100644 --- a/zone/client.h +++ b/zone/client.h @@ -967,6 +967,8 @@ public: void DropItem(int16 slot_id, bool recurse = true); void DropItemQS(EQ::ItemInstance* inst, bool pickup); + bool IsAugmentRestricted(uint8 item_type, uint32 augment_restriction); + int GetItemLinkHash(const EQ::ItemInstance* inst); // move to ItemData..or make use of the pre-calculated database field void SendItemLink(const EQ::ItemInstance* inst, bool sendtoall=false); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 5aec134fe..5db281eed 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -415,173 +415,10 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, } // check for augment to item restriction - if(enforce_restrictions) { - bool is_restricted = false; - uint8 item_type = item->ItemType; - switch (augtest->AugRestrict) { - case EQ::item::AugRestrictionAny: - break; - case EQ::item::AugRestrictionArmor: - switch (item_type) { - case EQ::item::ItemTypeArmor: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestrictionWeapons: - switch (item_type) { - case EQ::item::ItemType1HSlash: - case EQ::item::ItemType1HBlunt: - case EQ::item::ItemType1HPiercing: - case EQ::item::ItemTypeMartial: - case EQ::item::ItemType2HSlash: - case EQ::item::ItemType2HBlunt: - case EQ::item::ItemType2HPiercing: - case EQ::item::ItemTypeBow: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction1HWeapons: - switch (item_type) { - case EQ::item::ItemType1HSlash: - case EQ::item::ItemType1HBlunt: - case EQ::item::ItemType1HPiercing: - case EQ::item::ItemTypeMartial: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction2HWeapons: - switch (item_type) { - case EQ::item::ItemType2HSlash: - case EQ::item::ItemType2HBlunt: - case EQ::item::ItemType2HPiercing: - case EQ::item::ItemTypeBow: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction1HSlash: - switch (item_type) { - case EQ::item::ItemType1HSlash: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction1HBlunt: - switch (item_type) { - case EQ::item::ItemType1HBlunt: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestrictionPiercing: - switch (item_type) { - case EQ::item::ItemType1HPiercing: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestrictionHandToHand: - switch (item_type) { - case EQ::item::ItemTypeMartial: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction2HSlash: - switch (item_type) { - case EQ::item::ItemType2HSlash: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction2HBlunt: - switch (item_type) { - case EQ::item::ItemType2HBlunt: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction2HPierce: - switch (item_type) { - case EQ::item::ItemType2HPiercing: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestrictionBows: - switch (item_type) { - case EQ::item::ItemTypeBow: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestrictionShields: - switch (item_type) { - case EQ::item::ItemTypeShield: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction1HSlash1HBluntOrHandToHand: - switch (item_type) { - case EQ::item::ItemType1HSlash: - case EQ::item::ItemType1HBlunt: - case EQ::item::ItemTypeMartial: - break; - default: - is_restricted = true; - break; - } - break; - case EQ::item::AugRestriction1HBluntOrHandToHand: - switch (item_type) { - case EQ::item::ItemType1HBlunt: - case EQ::item::ItemTypeMartial: - break; - default: - is_restricted = true; - break; - } - break; - // These 3 are in-work - case EQ::item::AugRestrictionUnknown1: - case EQ::item::AugRestrictionUnknown2: - case EQ::item::AugRestrictionUnknown3: - default: - is_restricted = true; - break; - } + if (enforce_restrictions) { + bool is_restricted = IsAugmentRestricted(item->ItemType, augtest->AugRestrict); - if(is_restricted) { + if (is_restricted) { Message( Chat::Red, fmt::format( @@ -4766,3 +4603,154 @@ int32 Bot::GetAugmentIDAt(int16 slot_id, uint8 augslot) { // None found return INVALID_ID; } + +bool Client::IsAugmentRestricted(uint8 item_type, uint32 augment_restriction) +{ + switch (augment_restriction) { + case EQ::item::AugRestrictionAny: + break; + case EQ::item::AugRestrictionArmor: + switch (item_type) { + case EQ::item::ItemTypeArmor: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionWeapons: + switch (item_type) { + case EQ::item::ItemType1HSlash: + case EQ::item::ItemType1HBlunt: + case EQ::item::ItemType1HPiercing: + case EQ::item::ItemTypeMartial: + case EQ::item::ItemType2HSlash: + case EQ::item::ItemType2HBlunt: + case EQ::item::ItemType2HPiercing: + case EQ::item::ItemTypeBow: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction1HWeapons: + switch (item_type) { + case EQ::item::ItemType1HSlash: + case EQ::item::ItemType1HBlunt: + case EQ::item::ItemType1HPiercing: + case EQ::item::ItemTypeMartial: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction2HWeapons: + switch (item_type) { + case EQ::item::ItemType2HSlash: + case EQ::item::ItemType2HBlunt: + case EQ::item::ItemType2HPiercing: + case EQ::item::ItemTypeBow: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction1HSlash: + switch (item_type) { + case EQ::item::ItemType1HSlash: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction1HBlunt: + switch (item_type) { + case EQ::item::ItemType1HBlunt: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionPiercing: + switch (item_type) { + case EQ::item::ItemType1HPiercing: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionHandToHand: + switch (item_type) { + case EQ::item::ItemTypeMartial: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction2HSlash: + switch (item_type) { + case EQ::item::ItemType2HSlash: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction2HBlunt: + switch (item_type) { + case EQ::item::ItemType2HBlunt: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction2HPierce: + switch (item_type) { + case EQ::item::ItemType2HPiercing: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionBows: + switch (item_type) { + case EQ::item::ItemTypeBow: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionShields: + switch (item_type) { + case EQ::item::ItemTypeShield: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction1HSlash1HBluntOrHandToHand: + switch (item_type) { + case EQ::item::ItemType1HSlash: + case EQ::item::ItemType1HBlunt: + case EQ::item::ItemTypeMartial: + break; + default: + return true; + } + break; + case EQ::item::AugRestriction1HBluntOrHandToHand: + switch (item_type) { + case EQ::item::ItemType1HBlunt: + case EQ::item::ItemTypeMartial: + break; + default: + return true; + } + break; + case EQ::item::AugRestrictionUnknown1: + case EQ::item::AugRestrictionUnknown2: + case EQ::item::AugRestrictionUnknown3: + default: + return true; + } + + return false; +} diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 105e634b9..f10f28f23 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -70,7 +70,7 @@ bool Lua_ItemInst::IsAugmentable() { return self->IsAugmentable(); } -int Lua_ItemInst::GetAugmentType() { +uint32 Lua_ItemInst::GetAugmentType() { Lua_Safe_Call_Int(); return self->GetAugmentType(); } diff --git a/zone/lua_iteminst.h b/zone/lua_iteminst.h index bf5bd1853..4e5534677 100644 --- a/zone/lua_iteminst.h +++ b/zone/lua_iteminst.h @@ -40,7 +40,7 @@ public: bool IsEquipable(int race, int class_); bool IsEquipable(int slot_id); bool IsAugmentable(); - int GetAugmentType(); + uint32 GetAugmentType(); bool IsExpendable(); Lua_ItemInst GetItem(int slot); Lua_Item GetItem(); diff --git a/zone/string_ids.h b/zone/string_ids.h index c6df06290..0f7de013e 100644 --- a/zone/string_ids.h +++ b/zone/string_ids.h @@ -368,6 +368,7 @@ #define DUNGEON_SEALED 5141 //The gateway to the dungeon is sealed off to you. Perhaps you would be able to enter if you needed to adventure there. #define ADVENTURE_COMPLETE 5147 //You received %1 points for successfully completing the adventure. #define SUCCOR_FAIL 5169 //The portal collapes before you can escape! +#define AUGMENT_RESTRICTED 5480 //The item does not satisfy the augment's restrictions. #define PET_ATTACKING 5501 //%1 tells you, 'Attacking %2 Master.' #define AVOID_STUNNING_BLOW 5753 //You avoid the stunning blow. #define FATAL_BOW_SHOT 5745 //%1 performs a FATAL BOW SHOT!! diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index a76fd1150..262678a6a 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -117,7 +117,18 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme return; } - if (!RuleB(Inventory, AllowMultipleOfSameAugment) && tobe_auged->ContainsAugmentByID(auged_with->GetID())) { + if ( + RuleB(Inventory, EnforceAugmentRestriction) && + user->IsAugmentRestricted(tobe_auged->GetItemType(), auged_with->GetAugmentRestriction()) + ) { + user->MessageString(Chat::Red, AUGMENT_RESTRICTED); + return; + } + + if ( + !RuleB(Inventory, AllowMultipleOfSameAugment) && + tobe_auged->ContainsAugmentByID(auged_with->GetID()) + ) { user->Message(Chat::Red, "Error: Cannot put multiple of the same augment in an item."); return; }