Item* Item::CloneItem(uint32 count, Player const* player) const { Item* newItem = CreateItem(GetEntry(), count, player, GetItemRandomPropertyId()); if (!newItem) return NULL; newItem->SetGuidValue(ITEM_FIELD_CREATOR, GetGuidValue(ITEM_FIELD_CREATOR)); newItem->SetGuidValue(ITEM_FIELD_GIFTCREATOR, GetGuidValue(ITEM_FIELD_GIFTCREATOR)); newItem->SetUInt32Value(ITEM_FIELD_FLAGS, GetUInt32Value(ITEM_FIELD_FLAGS)); newItem->SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION)); return newItem; }
Item* Item::CloneItem(uint32 count, Player const* player /*= nullptr*/) const { Item* newItem = CreateItem(GetEntry(), count, player); if (!newItem) return nullptr; newItem->SetGuidValue(ITEM_FIELD_CREATOR, GetGuidValue(ITEM_FIELD_CREATOR)); newItem->SetGuidValue(ITEM_FIELD_GIFTCREATOR, GetGuidValue(ITEM_FIELD_GIFTCREATOR)); newItem->SetUInt32Value(ITEM_FIELD_FLAGS, GetUInt32Value(ITEM_FIELD_FLAGS) & ~(ITEM_FIELD_FLAG_REFUNDABLE | ITEM_FIELD_FLAG_BOP_TRADEABLE)); newItem->SetUInt32Value(ITEM_FIELD_DURATION, GetUInt32Value(ITEM_FIELD_DURATION)); // player CAN be NULL in which case we must not update random properties because that accesses player's item update queue if (player) newItem->SetItemRandomProperties(GetItemRandomPropertyId()); return newItem; }
bool Item::LoadFromDB(uint32 guidLow, Field* fields, ObjectGuid ownerGuid) { // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(ObjectGuid(HIGHGUID_ITEM, guidLow)); if (!LoadValues(fields[0].GetString())) { sLog.outError("Item::LoadFromDB: %s have broken data in `data` field. Can't be loaded.", GetGuidStr().c_str()); return false; } SetText(fields[1].GetCppString()); bool needSave = false; // need explicit save data at load fixes // overwrite possible wrong/corrupted guid ObjectGuid new_item_guid = ObjectGuid(HIGHGUID_ITEM, guidLow); if (GetGuidValue(OBJECT_FIELD_GUID) != new_item_guid) { SetGuidValue(OBJECT_FIELD_GUID, new_item_guid); needSave = true; } ItemPrototype const* proto = GetProto(); if (!proto) return false; // update max durability (and durability) if need if (proto->MaxDurability != GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) { SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability) SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); needSave = true; } // recalculate suffix factor if (GetItemRandomPropertyId() < 0) { if (UpdateItemSuffixFactor()) needSave = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BINDED, false); needSave = true; } // update duration if need, and remove if not need if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); needSave = true; } // set correct owner if (ownerGuid && GetOwnerGuid() != ownerGuid) { SetOwnerGuid(ownerGuid); needSave = true; } // set correct wrapped state if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { // wrapped item must be wrapper (used version that not stackable) if (!(proto->Flags & ITEM_FLAG_WRAPPER) || GetMaxStackCount() > 1) { RemoveFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED); needSave = true; // also cleanup for sure gift table DeleteGiftsFromDB(); } } if (needSave) // normal item changed state set not work at loading { std::ostringstream ss; for (uint16 i = 0; i < m_valuesCount; ++i) ss << GetUInt32Value(i) << " "; static SqlStatementID updItem; SqlStatement stmt = CharacterDatabase.CreateStatement(updItem, "UPDATE item_instance SET owner_guid = ?, data = ? WHERE guid = ?"); stmt.PExecute(GetOwnerGuid().GetCounter(), ss.str().c_str(), guidLow); } return true; }
void Item::SaveToDB(SQLTransaction& trans) { bool isInTransaction = bool(trans); if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); ObjectGuid::LowType guid = GetGUID().GetCounter(); switch (uState) { case ITEM_NEW: case ITEM_CHANGED: { uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(uState == ITEM_NEW ? CHAR_REP_ITEM_INSTANCE : CHAR_UPD_ITEM_INSTANCE); stmt->setUInt32( index, GetEntry()); stmt->setUInt32(++index, GetOwnerGUID().GetCounter()); stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_CREATOR).GetCounter()); stmt->setUInt32(++index, GetGuidValue(ITEM_FIELD_GIFTCREATOR).GetCounter()); stmt->setUInt32(++index, GetCount()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURATION)); std::ostringstream ssSpells; for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) ssSpells << GetSpellCharges(i) << ' '; stmt->setString(++index, ssSpells.str()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_FLAGS)); std::ostringstream ssEnchants; for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i) { ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' '; } stmt->setString(++index, ssEnchants.str()); stmt->setInt16 (++index, GetItemRandomPropertyId()); stmt->setUInt16(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)); stmt->setString(++index, m_text); stmt->setUInt32(++index, guid); trans->Append(stmt); if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER); stmt->setUInt32(0, GetOwnerGUID().GetCounter()); stmt->setUInt32(1, guid); trans->Append(stmt); } break; } case ITEM_REMOVED: { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); stmt->setUInt32(0, guid); trans->Append(stmt); if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); stmt->setUInt32(0, guid); trans->Append(stmt); } if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); // Delete the items if this is a container if (!loot.isLooted()) sLootItemStorage->RemoveStoredLootForContainer(GetGUID().GetCounter()); delete this; return; } case ITEM_UNCHANGED: break; } SetState(ITEM_UNCHANGED); if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); }
bool Item::LoadFromDB(uint32 guidLow, uint64 owner_guid, QueryResult *result) { // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guidLow, 0, HIGHGUID_ITEM); bool delete_result = false; if(!result) { result = CharacterDatabase.PQuery("SELECT data FROM item_instance WHERE guid = '%u'", guidLow); delete_result = true; } if (!result) { sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ", guidLow, GUID_LOPART(owner_guid)); return false; } Field *fields = result->Fetch(); if (!LoadValues(fields[0].GetString())) { sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.", guidLow); if (delete_result) delete result; return false; } bool need_save = false; // need explicit save data at load fixes // overwrite possible wrong/corrupted guid ObjectGuid new_item_guid = ObjectGuid(HIGHGUID_ITEM, guidLow); if (GetGuidValue(OBJECT_FIELD_GUID) != new_item_guid) { SetGuidValue(OBJECT_FIELD_GUID, new_item_guid); need_save = true; } if (delete_result) delete result; ItemPrototype const* proto = GetProto(); if(!proto) return false; // update max durability (and durability) if need if(proto->MaxDurability!= GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) { SetUInt32Value(ITEM_FIELD_MAXDURABILITY,proto->MaxDurability); if(GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability) SetUInt32Value(ITEM_FIELD_DURABILITY,proto->MaxDurability); need_save = true; } // recalculate suffix factor if(GetItemRandomPropertyId() < 0) { if(UpdateItemSuffixFactor()) need_save = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED, false); need_save = true; } // update duration if need, and remove if not need if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } // set correct owner if (owner_guid != 0 && GetOwnerGUID() != owner_guid) { SetOwnerGUID(owner_guid); need_save = true; } if (need_save) // normal item changed state set not work at loading { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guidLow << "'"; CharacterDatabase.Execute( ss.str().c_str() ); } return true; }
bool Item::LoadFromDB(uint32 guidLow, uint64 owner_guid, Field *fields) { // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guidLow, 0, HIGHGUID_ITEM); if (!LoadValues(fields[0].GetString())) { sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.", guidLow); return false; } bool need_save = false; // need explicit save data at load fixes // overwrite possible wrong/corrupted guid ObjectGuid new_item_guid = ObjectGuid(HIGHGUID_ITEM, guidLow); if (GetGuidValue(OBJECT_FIELD_GUID) != new_item_guid) { SetGuidValue(OBJECT_FIELD_GUID, new_item_guid); need_save = true; } ItemPrototype const* proto = GetProto(); if(!proto) return false; // update max durability (and durability) if need if(proto->MaxDurability!= GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) { SetUInt32Value(ITEM_FIELD_MAXDURABILITY,proto->MaxDurability); if(GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability) SetUInt32Value(ITEM_FIELD_DURABILITY,proto->MaxDurability); need_save = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_BINDED, false); need_save = true; } // update duration if need, and remove if not need if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } // set correct owner if (owner_guid != 0 && GetOwnerGUID() != owner_guid) { SetOwnerGUID(owner_guid); need_save = true; } // set correct wrapped state if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { // wrapped item must be wrapper (used version that not stackable) if (!(proto->Flags & ITEM_FLAG_WRAPPER) || GetMaxStackCount() > 1) { RemoveFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED); need_save = true; // also cleanup for sure gift table CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow()); } } if (need_save) // normal item changed state set not work at loading { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guidLow << "'"; CharacterDatabase.Execute( ss.str().c_str() ); } return true; }