diff options
Diffstat (limited to 'src/game/Item.cpp')
-rw-r--r-- | src/game/Item.cpp | 119 |
1 files changed, 92 insertions, 27 deletions
diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 766bd81d640..36ddcd16828 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include "WorldPacket.h" #include "Database/DatabaseEnv.h" #include "ItemEnchantmentMgr.h" +#include "SpellMgr.h" void AddItemsSetItem(Player*player,Item *item) { @@ -206,6 +207,10 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP)) return false; return true; + case ITEM_SUBCLASS_INSCRIPTION_CONTAINER: + if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP)) + return false; + return true; default: return false; } @@ -261,7 +266,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner) SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability); SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability); - for(int i = 0; i < 5; ++i) + for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i,itemProto->Spells[i].SpellCharges); SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags); @@ -284,7 +289,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff) } SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION) - diff); - SetState(ITEM_CHANGED); // save new time in database + SetState(ITEM_CHANGED, owner); // save new time in database } void Item::SaveToDB() @@ -297,7 +302,7 @@ void Item::SaveToDB() CharacterDatabase.PExecute( "DELETE FROM item_instance WHERE guid = '%u'", guid ); std::ostringstream ss; ss << "INSERT INTO item_instance (guid,owner_guid,data) VALUES (" << guid << "," << GUID_LOPART(GetOwnerGUID()) << ",'"; - for(uint16 i = 0; i < m_valuesCount; i++ ) + for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "' )"; CharacterDatabase.Execute( ss.str().c_str() ); @@ -306,7 +311,7 @@ void Item::SaveToDB() { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; - for(uint16 i = 0; i < m_valuesCount; i++ ) + for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; @@ -346,7 +351,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) if (!result) { - sLog.outError("ERROR: Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid)); + sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid)); return false; } @@ -354,7 +359,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) if(!LoadValues(fields[0].GetString())) { - sLog.outError("ERROR: Item #%d have broken data in `data` field. Can't be loaded.",guid); + sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.",guid); if (delete_result) delete result; return false; } @@ -407,7 +412,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; - for(uint16 i = 0; i < m_valuesCount; i++ ) + for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; @@ -450,7 +455,7 @@ uint32 Item::GetSkill() const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] = { - 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0 + 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0 }; ItemPrototype const* proto = GetProto(); @@ -694,18 +699,19 @@ bool Item::IsEquipped() const return !IsInBag() && m_slot < EQUIPMENT_SLOT_END; } -bool Item::CanBeTraded() const +bool Item::CanBeTraded(bool mail) const { - if(IsSoulBound()) + if ((!mail || !IsBoundAccountWide()) && IsSoulBound()) return false; - if(IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) ) + + if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) ) return false; - if(Player* owner = GetOwner()) + if (Player* owner = GetOwner()) { - if(owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK ) + if (owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK ) return false; - if(owner->GetLootGUID()==GetGUID()) + if (owner->GetLootGUID()==GetGUID()) return false; } @@ -740,6 +746,12 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const if (spellInfo->EquippedItemClass != -1) // -1 == any item class { + // Special case - accept vellum for armor/weapon requirements + if( (spellInfo->EquippedItemClass==ITEM_CLASS_ARMOR && proto->IsArmorVellum()) + ||( spellInfo->EquippedItemClass==ITEM_CLASS_WEAPON && proto->IsWeaponVellum())) + if (spellmgr.IsSkillTypeSpell(spellInfo->Id, SKILL_ENCHANTING)) // only for enchanting spells + return true; + if(spellInfo->EquippedItemClass != int32(proto->Class)) return false; // wrong item class @@ -752,7 +764,12 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const if(spellInfo->EquippedItemInventoryTypeMask != 0) // 0 == any inventory type { - if((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0) + // Special case - accept weapon type for main and offhand requirements + if(proto->InventoryType == INVTYPE_WEAPON && + (spellInfo->EquippedItemInventoryTypeMask & (1 << INVTYPE_WEAPONMAINHAND) || + spellInfo->EquippedItemInventoryTypeMask & (1 << INVTYPE_WEAPONOFFHAND))) + return true; + else if ((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0) return false; // inventory type not present in mask } @@ -765,9 +782,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges)) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); SetState(ITEM_CHANGED); } @@ -776,7 +793,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) if(GetEnchantmentDuration(slot) == duration) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); SetState(ITEM_CHANGED); } @@ -785,7 +802,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges) if(GetEnchantmentCharges(slot) == charges) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); SetState(ITEM_CHANGED); } @@ -795,14 +812,14 @@ void Item::ClearEnchantment(EnchantmentSlot slot) return; for(uint8 x = 0; x < 3; ++x) - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0); SetState(ITEM_CHANGED); } bool Item::GemsFitSockets() const { bool fits = true; - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) { uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color; @@ -842,7 +859,7 @@ bool Item::GemsFitSockets() const uint8 Item::GetGemCountWithID(uint32 GemID) const { uint8 count = 0; - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) { uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); if(!enchant_id) @@ -858,6 +875,29 @@ uint8 Item::GetGemCountWithID(uint32 GemID) const return count; } +uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const +{ + uint8 count = 0; + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) + { + uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); + if(!enchant_id) + continue; + + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!enchantEntry) + continue; + + ItemPrototype const* gemProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID); + if(!gemProto) + continue; + + if(gemProto->ItemLimitCategory==limitCategory) + ++count; + } + return count; +} + bool Item::IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const { ItemPrototype const* proto = GetProto(); @@ -886,8 +926,8 @@ Item* Item::CreateItem( uint32 item, uint32 count, Player const* player ) ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); if( pProto ) { - if ( count > pProto->Stackable ) - count = pProto->Stackable; + if ( count > pProto->GetMaxStackSize()) + count = pProto->GetMaxStackSize(); assert(count !=0 && "pProto->Stackable==0 but checked at loading already"); @@ -917,3 +957,28 @@ Item* Item::CloneItem( uint32 count, Player const* player ) const return newItem; } +bool Item::IsBindedNotWith( Player const* player ) const +{ + // not binded item + if(!IsSoulBound()) + return false; + + // own item + if(GetOwnerGUID()== player->GetGUID()) + return false; + + // not BOA item case + if(!IsBoundAccountWide()) + return true; + + // online + if(Player* owner = objmgr.GetPlayer(GetOwnerGUID())) + { + return owner->GetSession()->GetAccountId() != player->GetSession()->GetAccountId(); + } + // offline slow case + else + { + return objmgr.GetPlayerAccountIdByGUID(GetOwnerGUID()) != player->GetSession()->GetAccountId(); + } +} |