diff options
author | Shauren <none@none> | 2010-08-04 10:34:30 +0200 |
---|---|---|
committer | Shauren <none@none> | 2010-08-04 10:34:30 +0200 |
commit | b7d34dcb534a14098f1666bf6de38d9895642191 (patch) | |
tree | 20e02e2ec035463ff8070277d69d665ab76bf104 | |
parent | 846aa122605e6862b3c0a58e2d741c379aa1a3ef (diff) |
Cleaned up item flags: separated item proto flags and item field flags
Implemented use of:
ITEM_PROTO_FLAG_PROSPECTABLE and ITEM_PROTO_FLAG_MILLABLE now checked instead of bag family mask
ITEM_PROTO_FLAG_SMART_LOOT for profession recipes, player has to have skillline and not know the recipe
ITEM_PROTO_FLAG_OPENABLE item has to have it set to use item_loot_template
ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA if this is set item can never be used in arena
ITEM_FLAG_UNLOCKED marks unlocked items
Simplified BoA check for mail sending
Stackable items are no longer refundable
Removed useless code that always set ITEM_FIELD_FLAGS equal to proto flags
Unlocking items (lockpicking) is now blizzlike
--HG--
branch : trunk
-rw-r--r-- | sql/updates/9160_characters_item_instance.sql | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Container/Bag.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemPrototype.h | 109 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 86 | ||||
-rw-r--r-- | src/server/game/Loot/LootMgr.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Mails/Mail.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/ItemHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/LootHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/SpellHandler.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Handlers/TradeHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 11 |
15 files changed, 186 insertions, 141 deletions
diff --git a/sql/updates/9160_characters_item_instance.sql b/sql/updates/9160_characters_item_instance.sql new file mode 100644 index 00000000000..5ee6abc4082 --- /dev/null +++ b/sql/updates/9160_characters_item_instance.sql @@ -0,0 +1,3 @@ +SET @allowedFlags := 0x00000001 | 0x00000008 | 0x00000200 | 0x00001000 | 0x00008000 | 0x00010000; + +UPDATE `item_instance` SET `flags` = (`flags` & @allowedFlags); diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index 4a4d3c50d84..2d7aa490e32 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -87,7 +87,6 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability); SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability); - SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags & 0xFFFFFFF7); // TEMP HACK, DONT REMOVE - Shauren SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1); // Setting the number of Slots the Container has diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 91df6372d09..6efc320d3d2 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -278,11 +278,8 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i,itemProto->Spells[i].SpellCharges); - SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags & 0xFFFFFFF7); // TEMP HACK, DONT REMOVE - Shauren SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration)); - SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0); - return true; } @@ -369,13 +366,13 @@ void Item::SaveToDB() CharacterDatabase.Execute(ss.str().c_str()); - if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) CharacterDatabase.PExecute("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow()); }break; case ITEM_REMOVED: { CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid); - if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow()); delete this; return; @@ -437,7 +434,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { - ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED, false); + ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } @@ -1120,10 +1117,10 @@ void Item::DeleteRefundDataFromDB() void Item::SetNotRefundable(Player *owner, bool changestate) { - if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE)) return; - RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); + RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); // Following is not applicable in the trading procedure if (changestate) SetState(ITEM_CHANGED, owner); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 400ce86ef68..22409a6813b 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -234,9 +234,9 @@ class Item : public Object void SetOwnerGUID(uint64 guid) { SetUInt64Value(ITEM_FIELD_OWNER, guid); } Player* GetOwner()const; - void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); } - bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); } - bool IsBoundAccountWide() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); } + void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, val); } + bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND); } + bool IsBoundAccountWide() const { return (GetProto()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; } bool IsBindedNotWith(Player const* player) const; bool IsBoundByEnchant() const; virtual void SaveToDB(); @@ -246,6 +246,7 @@ class Item : public Object void SaveRefundDataToDB(); void DeleteRefundDataFromDB(); + bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); } bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; } bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; } bool CanBeTraded(bool mail = false) const; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 1a91ad10c6b..5941aea792f 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -103,33 +103,86 @@ enum ItemBondingType #define MAX_BIND_TYPE 6 -// masks for ITEM_FIELD_FLAGS field -enum ITEM_FLAGS -{ - ITEM_FLAGS_BINDED = 0x00000001, // set in game at binding, not set in template - ITEM_FLAGS_CONJURED = 0x00000002, - ITEM_FLAGS_OPENABLE = 0x00000004, - ITEM_FLAGS_WRAPPED = 0x00000008, - ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability == 0) - ITEM_FLAGS_INDESTRUCTIBLE = 0x00000020, // Item can not be destroyed, except by using spell (item can be reagent for spell and then allowed) - ITEM_FLAGS_USABLE = 0x00000040, // ? - ITEM_FLAGS_NO_EQUIP_COOLDOWN = 0x00000080, // ? - ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper - ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not - ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase - ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter - ITEM_FLAGS_REFUNDABLE_2 = 0x00008000, - ITEM_FLAGS_UNK1 = 0x00010000, - ITEM_FLAGS_PROSPECTABLE = 0x00040000, - ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, - ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, - ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip - ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0 - ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way) - ITEM_FLAGS_TRIGGERED_CAST = 0x10000000, // used by enchanting scrolls made with vellum - ITEM_FLAGS_ENCHANT_SCROLL = 0x10000000, // for enchant scrolls - ITEM_FLAGS_MILLABLE = 0x20000000, - ITEM_FLAGS_BOP_TRADEABLE = 0x80000000 +/* TODO + // need to know cases when using item is not allowed in shapeshift + ITEM_PROTO_FLAG_USABLE_WHEN_SHAPESHIFTED = 0x00800000, // Item can be used in shapeshift forms +*/ + +enum ItemProtoFlags +{ + ITEM_PROTO_FLAG_UNK1 = 0x00000001, // ? + ITEM_PROTO_FLAG_CONJURED = 0x00000002, // Conjured item + ITEM_PROTO_FLAG_OPENABLE = 0x00000004, // Item can be right clicked to open for loot + ITEM_PROTO_FLAG_HEROIC = 0x00000008, // Makes green "Heroic" text appear on item + ITEM_PROTO_FLAG_DEPRECATED = 0x00000010, // Cannot equip or use + ITEM_PROTO_FLAG_INDESTRUCTIBLE = 0x00000020, // Item can not be destroyed, except by using spell (item can be reagent for spell) + ITEM_PROTO_FLAG_UNK2 = 0x00000040, // ? + ITEM_PROTO_FLAG_NO_EQUIP_COOLDOWN = 0x00000080, // No default 30 seconds cooldown when equipped + ITEM_PROTO_FLAG_UNK3 = 0x00000100, // ? + ITEM_PROTO_FLAG_WRAPPER = 0x00000200, // Item can wrap other items + ITEM_PROTO_FLAG_UNK4 = 0x00000400, // ? + ITEM_PROTO_FLAG_PARTY_LOOT = 0x00000800, // Looting this item does not remove it from available loot + ITEM_PROTO_FLAG_REFUNDABLE = 0x00001000, // Item can be returned to vendor for its original cost (extended cost) + ITEM_PROTO_FLAG_CHARTER = 0x00002000, // Item is guild or arena charter + ITEM_PROTO_FLAG_UNK5 = 0x00004000, // Only readable items have this (but not all) + ITEM_PROTO_FLAG_UNK6 = 0x00008000, // ? + ITEM_PROTO_FLAG_UNK7 = 0x00010000, // ? + ITEM_PROTO_FLAG_UNK8 = 0x00020000, // ? + ITEM_PROTO_FLAG_PROSPECTABLE = 0x00040000, // Item can be prospected + ITEM_PROTO_FLAG_UNIQUE_EQUIPPED = 0x00080000, // You can only equip one of these + ITEM_PROTO_FLAG_UNK9 = 0x00100000, // ? + ITEM_PROTO_FLAG_USEABLE_IN_ARENA = 0x00200000, // Item can be used during arena match + ITEM_PROTO_FLAG_THROWABLE = 0x00400000, // Some Thrown weapons have it (and only Thrown) but not all + ITEM_PROTO_FLAG_USABLE_WHEN_SHAPESHIFTED = 0x00800000, // Item can be used in shapeshift forms + ITEM_PROTO_FLAG_UNK10 = 0x01000000, // ? + ITEM_PROTO_FLAG_SMART_LOOT = 0x02000000, // Profession recipes: can only be looted if you meet requirements and don't already know it + ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA = 0x04000000, // Item cannot be used in arena + ITEM_PROTO_FLAG_BIND_TO_ACCOUNT = 0x08000000, // Item binds to account and can be sent only to your own characters + ITEM_PROTO_FLAG_TRIGGERED_CAST = 0x10000000, // Spell is cast with triggered flag + ITEM_PROTO_FLAG_MILLABLE = 0x20000000, // Item can be milled + ITEM_PROTO_FLAG_UNK11 = 0x40000000, // ? + ITEM_PROTO_FLAG_UNK12 = 0x80000000 // ? +}; + +/* TODO +*/ + +enum ItemFieldFlags +{ + ITEM_FLAG_SOULBOUND = 0x00000001, // Item is soulbound and cannot be traded + ITEM_FLAG_UNK1 = 0x00000002, // ? + ITEM_FLAG_UNLOCKED = 0x00000004, // Item had lock but can be opened now + ITEM_FLAG_WRAPPED = 0x00000008, // Item is wrapped and contains another item + ITEM_FLAG_UNK3 = 0x00000010, // ? + ITEM_FLAG_UNK4 = 0x00000020, // ? + ITEM_FLAG_UNK5 = 0x00000040, // ? + ITEM_FLAG_UNK6 = 0x00000080, // ? + ITEM_FLAG_UNK7 = 0x00000100, // ? + ITEM_FLAG_READABLE = 0x00000200, // Opens text page when right clicked + ITEM_FLAG_UNK9 = 0x00000400, // ? + ITEM_FLAG_UNK10 = 0x00000800, // ? + ITEM_FLAG_REFUNDABLE = 0x00001000, // Item can be returned to vendor for its original cost (extended cost) + ITEM_FLAG_UNK11 = 0x00002000, // ? + ITEM_FLAG_UNK12 = 0x00004000, // ? + ITEM_FLAG_UNK13 = 0x00008000, // ? + ITEM_FLAG_UNK14 = 0x00010000, // ? + ITEM_FLAG_UNK15 = 0x00020000, // ? + ITEM_FLAG_UNK16 = 0x00040000, // ? + ITEM_FLAG_UNK17 = 0x00080000, // ? + ITEM_FLAG_UNK18 = 0x00100000, // ? + ITEM_FLAG_UNK19 = 0x00200000, // ? + ITEM_FLAG_UNK20 = 0x00400000, // ? + ITEM_FLAG_UNK21 = 0x00800000, // ? + ITEM_FLAG_UNK22 = 0x01000000, // ? + ITEM_FLAG_UNK23 = 0x02000000, // ? + ITEM_FLAG_UNK24 = 0x04000000, // ? + ITEM_FLAG_UNK25 = 0x08000000, // ? + ITEM_FLAG_UNK26 = 0x10000000, // ? + ITEM_FLAG_UNK27 = 0x20000000, // ? + ITEM_FLAG_UNK28 = 0x40000000, // ? + ITEM_FLAG_BOP_TRADEABLE = 0x80000000, // ? + + ITEM_FLAG_MAIL_TEXT_MASK = ITEM_FLAG_READABLE | ITEM_FLAG_UNK13 | ITEM_FLAG_UNK14 }; enum ItemFlagsExtra @@ -653,7 +706,7 @@ struct ItemPrototype bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; } bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; } bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; } - bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAGS_CONJURED); } + bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_PROTO_FLAG_CONJURED); } }; struct ItemLocale diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 01b17142d49..a338f9b76f9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11893,7 +11893,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) DestroyItem(slot, i, update); } - if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); RemoveEnchantmentDurations(pItem); @@ -12256,14 +12256,9 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) if (IsInventoryPos(dst)) { - bool isRefundable = pSrcItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - // change item amount before check (for unique max count check) pSrcItem->SetCount(pSrcItem->GetCount() - count); - if (isRefundable) - SendRefundInfo(pSrcItem); - ItemPosCountVec dest; uint8 msg = CanStoreItem(dstbag, dstslot, dest, pNewItem, false); if (msg != EQUIP_ERR_OK) @@ -12278,25 +12273,12 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) pSrcItem->SendUpdateToPlayer(this); pSrcItem->SetState(ITEM_CHANGED, this); StoreItem(dest, pNewItem, true); - if (isRefundable) - { - pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost()); - pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney()); - pNewItem->SetRefundRecipient(GetGUIDLow()); - pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime()); - pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - } } else if (IsBankPos (dst)) { - bool isRefundable = pSrcItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - // change item amount before check (for unique max count check) pSrcItem->SetCount(pSrcItem->GetCount() - count); - if (isRefundable) - SendRefundInfo(pSrcItem); - ItemPosCountVec dest; uint8 msg = CanBankItem(dstbag, dstslot, dest, pNewItem, false); if (msg != EQUIP_ERR_OK) @@ -12311,15 +12293,6 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) pSrcItem->SendUpdateToPlayer(this); pSrcItem->SetState(ITEM_CHANGED, this); BankItem(dest, pNewItem, true); - if (isRefundable) - { - AddRefundReference(pNewItem->GetGUIDLow()); - pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost()); - pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney()); - pNewItem->SetRefundRecipient(GetGUIDLow()); - pNewItem->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, pSrcItem->GetPlayedTime()); - pNewItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); - } } else if (IsEquipmentPos (dst)) { @@ -16751,7 +16724,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) } // "Conjured items disappear if you are logged out for more than 15 minutes" - if (timediff > 15*MINUTE && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED)) + if (timediff > 15*MINUTE && proto->Flags & ITEM_PROTO_FLAG_CONJURED) { CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); item->FSetState(ITEM_REMOVED); @@ -16759,13 +16732,13 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) continue; } - if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE)) { if (item->GetPlayedTime() > (2*HOUR)) { sLog.outDebug("Item::LoadFromDB, Item GUID: %u: refund time expired, deleting refund data and removing refundable flag.", item->GetGUIDLow()); CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow()); - item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); + item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); } else { @@ -16777,7 +16750,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) sLog.outDebug("Item::LoadFromDB, " "Item GUID: %u has field flags & ITEM_FLAGS_REFUNDABLE but has no data in item_refund_instance, removing flag.", item->GetGUIDLow()); - RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE); + item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); } else { @@ -19784,8 +19757,9 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 GetSession()->SendPacket(&data); SendNewItem(it, pProto->BuyCount*count, true, false, false); - if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE) && crItem->ExtendedCost) + if (pProto->Flags & ITEM_PROTO_FLAG_REFUNDABLE && crItem->ExtendedCost && pProto->GetMaxStackSize() == 1) { + it->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); it->SetRefundRecipient(GetGUIDLow()); it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); @@ -19842,8 +19816,9 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 AutoUnequipOffhandIfNeed(); - if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE) && crItem->ExtendedCost) + if (pProto->Flags & ITEM_PROTO_FLAG_REFUNDABLE && crItem->ExtendedCost && pProto->GetMaxStackSize() == 1) { + it->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); it->SetRefundRecipient(GetGUIDLow()); it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); @@ -21047,7 +21022,7 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3 void Player::ApplyEquipCooldown(Item * pItem) { - if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_NO_EQUIP_COOLDOWN)) + if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_PROTO_FLAG_NO_EQUIP_COOLDOWN)) return; for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) @@ -22842,7 +22817,7 @@ uint8 Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) c uint8 Player::CanEquipUniqueItem(ItemPrototype const* itemProto, uint8 except_slot, uint32 limit_count) const { // check unique-equipped on item - if (itemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED) + if (itemProto->Flags & ITEM_PROTO_FLAG_UNIQUE_EQUIPPED) { // there is an equip limit on this item if (HasItemOrGemWithIdEquipped(itemProto->ItemId,1,except_slot)) @@ -23904,7 +23879,7 @@ void Player::SendRefundInfo(Item *item) // This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours. item->UpdatePlayedTime(this); - if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE)) { sLog.outDebug("Item refund: item not refundable!"); return; @@ -23924,17 +23899,15 @@ void Player::SendRefundInfo(Item *item) return; } - uint32 itemCount = item->GetCount(); - WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); data << uint64(item->GetGUID()); // item guid - data << uint32(item->GetPaidMoney() * itemCount); // money cost - data << uint32(iece->reqhonorpoints * itemCount); // honor point cost - data << uint32(iece->reqarenapoints * itemCount); // arena point cost + data << uint32(item->GetPaidMoney()); // money cost + data << uint32(iece->reqhonorpoints); // honor point cost + data << uint32(iece->reqarenapoints); // arena point cost for (uint8 i = 0; i < 5; ++i) // item cost data { - data << iece->reqitem[i]; - data << (iece->reqitemcount[i] * itemCount); + data << uint32(iece->reqitem[i]); + data << uint32(iece->reqitemcount[i]); } data << uint32(0); data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); @@ -23943,7 +23916,7 @@ void Player::SendRefundInfo(Item *item) void Player::RefundItem(Item *item) { - if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE)) { sLog.outDebug("Item refund: item not refundable!"); return; @@ -23973,13 +23946,10 @@ void Player::RefundItem(Item *item) return; } - uint32 itemCount = item->GetCount(); // stacked refundable items. - uint32 moneyRefund = item->GetPaidMoney()*itemCount; - bool store_error = false; for (uint8 i = 0; i < 5; ++i) { - uint32 count = iece->reqitemcount[i] * itemCount; + uint32 count = iece->reqitemcount[i]; uint32 itemid = iece->reqitem[i]; if (count && itemid) @@ -24006,13 +23976,13 @@ void Player::RefundItem(Item *item) WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4+4+4+4+4*4+4*4); data << uint64(item->GetGUID()); // item guid data << uint32(0); // 0, or error code - data << uint32(moneyRefund); // money cost - data << uint32(iece->reqhonorpoints * itemCount); // honor point cost - data << uint32(iece->reqarenapoints * itemCount); // arena point cost + data << uint32(item->GetPaidMoney()); // money cost + data << uint32(iece->reqhonorpoints); // honor point cost + data << uint32(iece->reqarenapoints); // arena point cost for (uint8 i = 0; i < 5; ++i) // item cost data { data << iece->reqitem[i]; - data << (iece->reqitemcount[i] * itemCount); + data << (iece->reqitemcount[i]); } GetSession()->SendPacket(&data); @@ -24025,7 +23995,7 @@ void Player::RefundItem(Item *item) // Grant back extendedcost items for (uint8 i = 0; i < 5; ++i) { - uint32 count = iece->reqitemcount[i] * itemCount; + uint32 count = iece->reqitemcount[i]; uint32 itemid = iece->reqitem[i]; if (count && itemid) { @@ -24038,17 +24008,15 @@ void Player::RefundItem(Item *item) } // Grant back money - if (moneyRefund) + if (uint32 moneyRefund = item->GetPaidMoney()) ModifyMoney(moneyRefund); // Grant back Honor points - uint32 honorRefund = iece->reqhonorpoints * itemCount; - if (honorRefund) + if (uint32 honorRefund = iece->reqhonorpoints) ModifyHonorPoints(honorRefund); // Grant back Arena points - uint32 arenaRefund = iece->reqarenapoints * itemCount; - if (arenaRefund) + if (uint32 arenaRefund = iece->reqarenapoints) ModifyArenaPoints(arenaRefund); } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index d331f7e7ca1..38bad409718 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -330,7 +330,7 @@ LootItem::LootItem(LootStoreItem const& li) conditions = li.conditions; ItemPrototype const* proto = objmgr.GetItemPrototype(itemid); - freeforall = proto && (proto->Flags & ITEM_FLAGS_PARTY_LOOT); + freeforall = proto && (proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT); needs_quest = li.needs_quest; @@ -354,6 +354,10 @@ bool LootItem::AllowedForPlayer(Player const * player) const if (!pProto) return false; + // not show loot for players without profession or those who already know the recipe + if ((pProto->Flags & ITEM_PROTO_FLAG_SMART_LOOT) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId))) + return false; + // not show loot for not own team if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && player->GetTeam() != HORDE) return false; @@ -399,7 +403,7 @@ void Loot::AddItem(LootStoreItem const & item) if (item.conditions.empty()) { ItemPrototype const* proto = objmgr.GetItemPrototype(item.itemid); - if (!proto || (proto->Flags & ITEM_FLAGS_PARTY_LOOT) == 0) + if (!proto || (proto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0) ++unlootedCount; } } @@ -1470,7 +1474,7 @@ void LoadLootTemplates_Item() // remove real entries and check existence loot for (uint32 i = 1; i < sItemStorage.MaxEntry; ++i) if (ItemPrototype const *proto = sItemStorage.LookupEntry<ItemPrototype>(i)) - if (ids_set.find(proto->ItemId) != ids_set.end()) + if (ids_set.find(proto->ItemId) != ids_set.end() && proto->Flags & ITEM_PROTO_FLAG_OPENABLE) ids_set.erase(proto->ItemId); // output error for any still listed (not referenced from appropriate table) ids @@ -1489,7 +1493,7 @@ void LoadLootTemplates_Milling() if (!proto) continue; - if ((proto->BagFamily & BAG_FAMILY_MASK_HERBS) == 0) + if (!(proto->Flags & ITEM_PROTO_FLAG_MILLABLE)) continue; if (ids_set.find(proto->ItemId) != ids_set.end()) @@ -1538,7 +1542,7 @@ void LoadLootTemplates_Prospecting() if (!proto) continue; - if ((proto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) == 0) + if (!(proto->Flags & ITEM_PROTO_FLAG_PROSPECTABLE)) continue; if (ids_set.find(proto->ItemId) != ids_set.end()) diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index 77f971bf4d0..7cf1138d610 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -161,16 +161,14 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) return; } // test the receiver's Faction... or all items are account bound - bool accountBound = false; + bool accountBound = items_count ? true : false; for (uint8 i = 0; i < items_count; ++i) { - Item* item = pl->GetItemByGuid(itemGUIDs[i]) ; - if (item ) + Item* item = pl->GetItemByGuid(itemGUIDs[i]); + if (item) { - ItemPrototype const* itemProto= item->GetProto(); - if(itemProto && (itemProto->Flags & ITEM_FLAGS_BOA)) - accountBound = true; - else + ItemPrototype const* itemProto = item->GetProto(); + if(!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) { accountBound = false; break; @@ -224,13 +222,13 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) return; } - if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION)) + if (item->GetProto()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } - if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; @@ -702,7 +700,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data) bodyItem->SetText(m->body); bodyItem->SetUInt32Value(ITEM_FIELD_CREATOR, m->sender); - bodyItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPER | ITEM_FLAGS_REFUNDABLE_2 | ITEM_FLAGS_UNK1); + bodyItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_MAIL_TEXT_MASK); sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId); diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp index e4252854f09..af82a1fed11 100644 --- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp @@ -239,7 +239,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) return; } - if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) + if (it->GetProto()->Flags & ITEM_PROTO_FLAG_CONJURED || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp index 39c3b61a445..262679cda6c 100644 --- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp @@ -263,7 +263,7 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket & recv_data) return; } - if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_INDESTRUCTIBLE)) + if (pItem->GetProto()->Flags & ITEM_PROTO_FLAG_INDESTRUCTIBLE) { _player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, NULL, NULL); return; @@ -1049,7 +1049,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) return; } - if (!gift->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPER))// cheating: non-wrapper wrapper + if (!(gift->GetProto()->Flags & ITEM_PROTO_FLAG_WRAPPER)) // cheating: non-wrapper wrapper { _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL); return; @@ -1120,7 +1120,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) case 21830: item->SetEntry(21831); break; } item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); - item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); + item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED); item->SetState(ITEM_CHANGED, _player); if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` @@ -1219,7 +1219,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) ItemPrototype const* iGemProto = Gems[i]->GetProto(); // unique item (for new and already placed bit removed enchantments - if (iGemProto->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED) + if (iGemProto->Flags & ITEM_PROTO_FLAG_UNIQUE_EQUIPPED) { for (int j = 0; j < MAX_GEM_SOCKETS; ++j) { diff --git a/src/server/game/Server/Protocol/Handlers/LootHandler.cpp b/src/server/game/Server/Protocol/Handlers/LootHandler.cpp index 55aefb3c1f5..0b438a15b6a 100644 --- a/src/server/game/Server/Protocol/Handlers/LootHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/LootHandler.cpp @@ -407,8 +407,7 @@ void WorldSession::DoLootRelease(uint64 lguid) ItemPrototype const* proto = pItem->GetProto(); // destroy only 5 items from stack in case prospecting and milling - if ((proto->BagFamily & (BAG_FAMILY_MASK_MINING_SUPP|BAG_FAMILY_MASK_HERBS)) && - proto->Class == ITEM_CLASS_TRADE_GOODS) + if (proto->Flags & (ITEM_PROTO_FLAG_PROSPECTABLE | ITEM_PROTO_FLAG_MILLABLE)) { pItem->m_lootGenerated = false; pItem->loot.clear(); diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index 937f6799f87..c47c235556f 100644 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -94,9 +94,16 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) } // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB) - if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) && pUser->InArena()) + if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_PROTO_FLAG_USEABLE_IN_ARENA) && pUser->InArena()) { - pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); + pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL); + return; + } + + // don't allow items banned in arena + if (proto->Flags & ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA && pUser->InArena()) + { + pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL); return; } @@ -209,15 +216,15 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) return; } - // required picklocking - if (lockInfo->Skill[1] || lockInfo->Skill[0]) + // was not unlocked yet + if (pItem->IsLocked()) { pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL); return; } } - if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))// wrapped? + if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped? { QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow()); if (result) diff --git a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp index 6191b88587e..33bc48ace50 100644 --- a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp @@ -104,7 +104,7 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) data << uint32(item->GetProto()->DisplayInfoID);// display id data << uint32(item->GetCount()); // stack count // wrapped: hide stats but show giftcreator name - data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED) ? 1 : 0); + data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED) ? 1 : 0); data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)); // perm. enchantment and gems data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8a805cca947..8ab005cc064 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4469,7 +4469,7 @@ void Spell::TakeReagents() return; // do not take reagents for these item casts - if (m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_TRIGGERED_CAST) + if (m_CastItem && m_CastItem->GetProto()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST) return; Player* p_caster = (Player*)m_caster; @@ -5235,12 +5235,25 @@ SpellCastResult Spell::CheckCast(bool strict) m_spellInfo->EffectImplicitTargetA[i] != TARGET_GAMEOBJECT_ITEM) break; + uint32 spellId = m_spellInfo->Id; if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc. // we need a go target in case of TARGET_GAMEOBJECT - || m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT && !m_targets.getGOTarget() - // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM - || m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_ITEM && !m_targets.getGOTarget() && - (!m_targets.getItemTarget() || !m_targets.getItemTarget()->GetProto()->LockID || m_targets.getItemTarget()->GetOwner() != m_caster)) + || m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT && !m_targets.getGOTarget()) + return SPELL_FAILED_BAD_TARGETS; + + Item *pTempItem = NULL; + if (m_targets.getTargetMask() & TARGET_FLAG_TRADE_ITEM) + { + if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData()) + pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.getItemTargetGUID())); + } + else if (m_targets.getTargetMask() & TARGET_FLAG_ITEM) + pTempItem = m_caster->ToPlayer()->GetItemByGuid(m_targets.getItemTargetGUID()); + + // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT_ITEM && + !m_targets.getGOTarget() && + (!pTempItem || !pTempItem->GetProto()->LockID || !pTempItem->IsLocked())) return SPELL_FAILED_BAD_TARGETS; if (m_spellInfo->Id != 1842 || m_targets.getGOTarget() && @@ -5588,7 +5601,7 @@ SpellCastResult Spell::CheckCast(bool strict) TradeSlots slot = TradeSlots(m_targets.getItemTargetGUID()); if (slot != TRADE_SLOT_NONTRADED) - return SPELL_FAILED_ITEM_NOT_READY; + return SPELL_FAILED_BAD_TARGETS; if (!m_IsTriggeredSpell) if (my_trade->GetSpell()) @@ -5998,7 +6011,7 @@ SpellCastResult Spell::CheckItems() } // do not take reagents for these item casts - if (!(m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_TRIGGERED_CAST)) + if (!(m_CastItem && m_CastItem->GetProto()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)) { // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case. if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo)) @@ -6110,7 +6123,7 @@ SpellCastResult Spell::CheckItems() if (m_targets.getItemTarget()->GetOwner() != m_caster) return SPELL_FAILED_NOT_TRADEABLE; // do not allow to enchant vellum from scroll made by vellum-prevent exploit - if (m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_TRIGGERED_CAST) + if (m_CastItem && m_CastItem->GetProto()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST) return SPELL_FAILED_TOTEM_CATEGORY; ItemPosCountVec dest; uint8 msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1); @@ -6193,7 +6206,7 @@ SpellCastResult Spell::CheckItems() if (!m_targets.getItemTarget()) return SPELL_FAILED_CANT_BE_PROSPECTED; //ensure item is a prospectable ore - if (!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS) + if (!(m_targets.getItemTarget()->GetProto()->Flags & ITEM_PROTO_FLAG_PROSPECTABLE)) return SPELL_FAILED_CANT_BE_PROSPECTED; //prevent prospecting in trade slot if (m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID()) @@ -6216,7 +6229,7 @@ SpellCastResult Spell::CheckItems() if (!m_targets.getItemTarget()) return SPELL_FAILED_CANT_BE_MILLED; //ensure item is a millable herb - if (!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS) + if (!(m_targets.getItemTarget()->GetProto()->Flags & ITEM_PROTO_FLAG_MILLABLE)) return SPELL_FAILED_CANT_BE_MILLED; //prevent milling in trade slot if (m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID()) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 43d34112c91..f7a45311b0f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3254,7 +3254,10 @@ void Spell::EffectOpenLock(uint32 effIndex) return; } - SendLoot(guid, LOOT_SKINNING); + if (gameObjTarget) + SendLoot(guid, LOOT_SKINNING); + else + itemTarget->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); // not allow use skill grow at item base open if (!m_CastItem && skillId != SKILL_NONE) @@ -3885,7 +3888,7 @@ void Spell::EffectEnchantItemPerm(uint32 effect_idx) else { // do not increase skill if vellum used - if (!(m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_TRIGGERED_CAST)) + if (!(m_CastItem && m_CastItem->GetProto()->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)) p_caster->UpdateCraftSkill(m_spellInfo->Id); uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; @@ -7271,7 +7274,7 @@ void Spell::EffectProspecting(uint32 /*i*/) return; Player* p_caster = (Player*)m_caster; - if (!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)) + if (!itemTarget || !(itemTarget->GetProto()->Flags & ITEM_PROTO_FLAG_PROSPECTABLE)) return; if (itemTarget->GetCount() < 5) @@ -7293,7 +7296,7 @@ void Spell::EffectMilling(uint32 /*i*/) return; Player* p_caster = (Player*)m_caster; - if (!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS)) + if (!itemTarget || !(itemTarget->GetProto()->Flags & ITEM_PROTO_FLAG_MILLABLE)) return; if (itemTarget->GetCount() < 5) |