diff options
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 27 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 14 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 10 |
3 files changed, 42 insertions, 9 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index fed55249eba..c9e1cb072fe 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -2054,6 +2054,33 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } } + + auto isValidEquipmentSlot = [&](uint32 itemEntry, uint8 slot) + { + ItemEntry const* dbcItem = sItemStore.LookupEntry(itemEntry); + if (!dbcItem) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses unknown item {} (slot {}) for creature {}, skipped.", itemEntry, slot, e.entryOrGuid); + return false; + } + + if (std::ranges::none_of(InventoryTypesEquipable, [dbcItem](InventoryType inventoryType) { return inventoryType == dbcItem->InventoryType; })) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses item {} (slot {}) not equipable in a hand for creature {}, skipped.", itemEntry, slot, e.entryOrGuid); + return false; + } + + return true; + }; + + if (e.action.equip.slot1 && !isValidEquipmentSlot(e.action.equip.slot1, 0)) + return false; + + if (e.action.equip.slot2 && !isValidEquipmentSlot(e.action.equip.slot2, 1)) + return false; + + if (e.action.equip.slot3 && !isValidEquipmentSlot(e.action.equip.slot3, 2)) + return false; } break; } diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 1c8cf91c5fc..c4212348c4e 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -415,6 +415,20 @@ enum InventoryType : uint8 #define MAX_INVTYPE 35 +constexpr std::array<InventoryType, 10> InventoryTypesEquipable = +{ + INVTYPE_WEAPON, + INVTYPE_SHIELD, + INVTYPE_RANGED, + INVTYPE_2HWEAPON, + INVTYPE_WEAPONMAINHAND, + INVTYPE_WEAPONOFFHAND, + INVTYPE_HOLDABLE, + INVTYPE_THROWN, + INVTYPE_RANGEDRIGHT, + INVTYPE_PROFESSION_TOOL +}; + enum ItemClass : uint8 { ITEM_CLASS_CONSUMABLE = 0, diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 10cb845f24d..d3f17f0acf4 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1526,15 +1526,7 @@ void ObjectMgr::LoadEquipmentTemplates() continue; } - if (dbcItem->InventoryType != INVTYPE_WEAPON && - dbcItem->InventoryType != INVTYPE_SHIELD && - dbcItem->InventoryType != INVTYPE_RANGED && - dbcItem->InventoryType != INVTYPE_2HWEAPON && - dbcItem->InventoryType != INVTYPE_WEAPONMAINHAND && - dbcItem->InventoryType != INVTYPE_WEAPONOFFHAND && - dbcItem->InventoryType != INVTYPE_HOLDABLE && - dbcItem->InventoryType != INVTYPE_THROWN && - dbcItem->InventoryType != INVTYPE_RANGEDRIGHT) + if (std::ranges::none_of(InventoryTypesEquipable, [dbcItem](InventoryType inventoryType) { return inventoryType == dbcItem->InventoryType; })) { TC_LOG_ERROR("sql.sql", "Item (ID={}) in creature_equip_template.ItemID{} for CreatureID = {} and ID = {} is not equipable in a hand, forced to 0.", equipmentInfo.Items[i].ItemId, i + 1, entry, id); |