diff options
author | Shauren <shauren.trinity@gmail.com> | 2015-08-12 23:05:36 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2015-08-12 23:05:36 +0200 |
commit | 81abfe93bb96e5a769dc855f06fdc7578b352b39 (patch) | |
tree | 66e5231c62ec9dfc180cceb80a714632afaf93a3 | |
parent | f4724badb65a6471df37ef249929548861f86362 (diff) |
Core/Void Storage: Implemented saving item upgrade and bonuses for items deposited in void storage
-rw-r--r-- | sql/base/characters_database.sql | 2 | ||||
-rw-r--r-- | sql/updates/characters/2015_08_12_00_characters.sql | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Object/ObjectGuid.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 40 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 25 | ||||
-rw-r--r-- | src/server/game/Handlers/VoidStorageHandler.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.cpp | 24 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 4 |
8 files changed, 68 insertions, 77 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 82c455aee8a..f28cc6ad1b4 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1549,6 +1549,8 @@ CREATE TABLE `character_void_storage` ( `creatorGuid` bigint(20) unsigned NOT NULL DEFAULT '0', `randomProperty` int(10) unsigned NOT NULL DEFAULT '0', `suffixFactor` int(10) unsigned NOT NULL DEFAULT '0', + `upgradeId` int(10) unsigned NOT NULL DEFAULT '0', + `bonusListIDs` text, PRIMARY KEY (`itemId`), UNIQUE KEY `idx_player_slot` (`playerGuid`,`slot`), KEY `idx_player` (`playerGuid`) diff --git a/sql/updates/characters/2015_08_12_00_characters.sql b/sql/updates/characters/2015_08_12_00_characters.sql new file mode 100644 index 00000000000..9abe6972718 --- /dev/null +++ b/sql/updates/characters/2015_08_12_00_characters.sql @@ -0,0 +1,3 @@ +ALTER TABLE `character_void_storage` + ADD `upgradeId` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `suffixFactor`, + ADD `bonusListIDs` TEXT AFTER `upgradeId`; diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index 23d6b4f4dde..9b1c2516c18 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -205,6 +205,10 @@ class ObjectGuid ObjectGuid() : _low(0), _high(0) { } ObjectGuid(ObjectGuid const&) = default; + ObjectGuid(ObjectGuid&&) = default; + + ObjectGuid& operator=(ObjectGuid const&) = default; + ObjectGuid& operator=(ObjectGuid&&) = default; std::vector<uint8> GetRawValue() const; void SetRawValue(std::vector<uint8> const& guid); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bcf31957e5f..56e34d0382b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17787,7 +17787,7 @@ void Player::_LoadVoidStorage(PreparedQueryResult result) do { - // SELECT itemid, itemEntry, slot, creatorGuid FROM character_void_storage WHERE playerGuid = ? + // SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor, upgradeId, bonusListIDs FROM character_void_storage WHERE playerGuid = ? Field* fields = result->Fetch(); uint64 itemId = fields[0].GetUInt64(); @@ -17796,6 +17796,11 @@ void Player::_LoadVoidStorage(PreparedQueryResult result) ObjectGuid creatorGuid = ObjectGuid::Create<HighGuid::Player>(fields[3].GetUInt64()); uint32 randomProperty = fields[4].GetUInt32(); uint32 suffixFactor = fields[5].GetUInt32(); + uint32 upgradeId = fields[6].GetUInt32(); + std::vector<uint32> bonusListIDs; + Tokenizer bonusListIdTokens(fields[7].GetString(), ' '); + for (char const* token : bonusListIdTokens) + bonusListIDs.push_back(atoul(token)); if (!itemId) { @@ -17822,7 +17827,7 @@ void Player::_LoadVoidStorage(PreparedQueryResult result) creatorGuid.Clear(); } - _voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomProperty, suffixFactor); + _voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomProperty, suffixFactor, upgradeId, bonusListIDs); } while (result->NextRow()); } @@ -19422,7 +19427,7 @@ void Player::_SaveVoidStorage(SQLTransaction& trans) } else { - // REPLACE INTO character_inventory (itemId, playerGuid, itemEntry, slot, creatorGuid) VALUES (?, ?, ?, ?, ?) + // REPLACE INTO character_inventory (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor, upgradeId, bonusListIDs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM); stmt->setUInt64(0, _voidStorageItems[i]->ItemId); stmt->setUInt64(1, GetGUID().GetCounter()); @@ -19431,6 +19436,11 @@ void Player::_SaveVoidStorage(SQLTransaction& trans) stmt->setUInt64(4, _voidStorageItems[i]->CreatorGuid.GetCounter()); stmt->setUInt32(5, _voidStorageItems[i]->ItemRandomPropertyId); stmt->setUInt32(6, _voidStorageItems[i]->ItemSuffixFactor); + stmt->setUInt32(7, _voidStorageItems[i]->ItemUpgradeId); + std::ostringstream bonusListIDs; + for (int32 bonusListID : _voidStorageItems[i]->BonusListIDs) + bonusListIDs << bonusListID << ' '; + stmt->setString(8, bonusListIDs.str()); } trans->Append(stmt); @@ -26113,7 +26123,7 @@ uint8 Player::GetNumOfVoidStorageFreeSlots() const return count; } -uint8 Player::AddVoidStorageItem(VoidStorageItem const& item) +uint8 Player::AddVoidStorageItem(VoidStorageItem&& item) { uint8 slot = GetNextVoidStorageFreeSlot(); @@ -26123,30 +26133,10 @@ uint8 Player::AddVoidStorageItem(VoidStorageItem const& item) return 255; } - _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemEntry, - item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor); + _voidStorageItems[slot] = new VoidStorageItem(std::move(item)); return slot; } -void Player::AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item) -{ - if (slot >= VOID_STORAGE_MAX_SLOT) - { - GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); - return; - } - - if (_voidStorageItems[slot]) - { - TC_LOG_ERROR("misc", "Player::AddVoidStorageItemAtSlot - Player (%s, name: %s) tried to add an item to an used slot (item id: " UI64FMTD ", entry: %u, slot: %u).", GetGUID().ToString().c_str(), GetName().c_str(), _voidStorageItems[slot]->ItemId, _voidStorageItems[slot]->ItemEntry, slot); - GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); - return; - } - - _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemId, - item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor); -} - void Player::DeleteVoidStorageItem(uint8 slot) { if (slot >= VOID_STORAGE_MAX_SLOT) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 4218a058798..4167c632668 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1162,28 +1162,22 @@ struct BGData struct VoidStorageItem { - VoidStorageItem() + VoidStorageItem() : ItemId(0), ItemEntry(0), ItemRandomPropertyId(0), ItemSuffixFactor(0), ItemUpgradeId(0) { } + VoidStorageItem(uint64 id, uint32 entry, ObjectGuid const& creator, uint32 randomPropertyId, uint32 suffixFactor, uint32 upgradeId, std::vector<uint32> const& bonuses) + : ItemId(id), ItemEntry(entry), CreatorGuid(creator), ItemRandomPropertyId(randomPropertyId), + ItemSuffixFactor(suffixFactor), ItemUpgradeId(upgradeId) { - ItemId = 0; - ItemEntry = 0; - ItemRandomPropertyId = 0; - ItemSuffixFactor = 0; - } - - VoidStorageItem(uint64 id, uint32 entry, ObjectGuid creator, uint32 randomPropertyId, uint32 suffixFactor) - { - ItemId = id; - ItemEntry = entry; - CreatorGuid = creator; - ItemRandomPropertyId = randomPropertyId; - ItemSuffixFactor = suffixFactor; + BonusListIDs.insert(BonusListIDs.end(), bonuses.begin(), bonuses.end()); } + VoidStorageItem(VoidStorageItem&& vsi) = default; uint64 ItemId; uint32 ItemEntry; ObjectGuid CreatorGuid; uint32 ItemRandomPropertyId; uint32 ItemSuffixFactor; + uint32 ItemUpgradeId; + std::vector<int32> BonusListIDs; }; class TradeData @@ -2623,8 +2617,7 @@ class Player : public Unit, public GridObject<Player> void LockVoidStorage() { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); } uint8 GetNextVoidStorageFreeSlot() const; uint8 GetNumOfVoidStorageFreeSlots() const; - uint8 AddVoidStorageItem(VoidStorageItem const& item); - void AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item); + uint8 AddVoidStorageItem(VoidStorageItem&& item); void DeleteVoidStorageItem(uint8 slot); bool SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot); VoidStorageItem* GetVoidStorageItem(uint8 slot) const; diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp index 4ad507895a4..55f85114f10 100644 --- a/src/server/game/Handlers/VoidStorageHandler.cpp +++ b/src/server/game/Handlers/VoidStorageHandler.cpp @@ -139,6 +139,10 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor return; } + WorldPackets::VoidStorage::VoidStorageTransferChanges voidStorageTransferChanges; + voidStorageTransferChanges.AddedItems.reserve(VOID_STORAGE_MAX_DEPOSIT); + voidStorageTransferChanges.RemovedItems.reserve(VOID_STORAGE_MAX_DEPOSIT); + std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT]; uint8 depositCount = 0; for (uint32 i = 0; i < voidStorageTransfer.Deposits.size(); ++i) @@ -150,25 +154,25 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor continue; } - // TODO: Save these fields to database - for now disallow storing these items to prevent data loss - if (item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK) || !item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS).empty()) - continue; - - VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetGuidValue(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor()); + VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetGuidValue(ITEM_FIELD_CREATOR), + item->GetItemRandomPropertyId(), item->GetItemSuffixFactor(), item->GetModifier(ITEM_MODIFIER_UPGRADE_ID), item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS)); - uint8 slot = _player->AddVoidStorageItem(itemVS); + WorldPackets::VoidStorage::VoidItem voidItem; + voidItem.Guid = ObjectGuid::Create<HighGuid::Item>(itemVS.ItemId); + voidItem.Creator = item->GetGuidValue(ITEM_FIELD_CREATOR); + voidItem.Item.Initialize(&itemVS); + voidItem.Slot = _player->AddVoidStorageItem(std::move(itemVS)); - depositItems[depositCount++] = std::make_pair(itemVS, slot); + voidStorageTransferChanges.AddedItems.push_back(voidItem); _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + ++depositCount; } int64 cost = depositCount * VOID_STORAGE_STORE_ITEM_COST; _player->ModifyMoney(-cost); - VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW]; - uint8 withdrawCount = 0; for (uint32 i = 0; i < voidStorageTransfer.Withdrawals.size(); ++i) { uint8 slot = 0; @@ -188,32 +192,17 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor return; } - Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); + Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId, GuidSet(), itemVS->BonusListIDs); item->SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, itemVS->ItemSuffixFactor); item->SetGuidValue(ITEM_FIELD_CREATOR, itemVS->CreatorGuid); + item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, itemVS->ItemUpgradeId); item->SetBinding(true); - _player->SendNewItem(item, 1, false, false, false); - withdrawItems[withdrawCount++] = *itemVS; + voidStorageTransferChanges.RemovedItems.push_back(ObjectGuid::Create<HighGuid::Item>(itemVS->ItemId)); _player->DeleteVoidStorageItem(slot); } - WorldPackets::VoidStorage::VoidStorageTransferChanges voidStorageTransferChanges; - voidStorageTransferChanges.AddedItems.resize(depositCount); - voidStorageTransferChanges.RemovedItems.resize(withdrawCount); - - for (uint8 i = 0; i < depositCount; ++i) - { - voidStorageTransferChanges.AddedItems[i].Guid = ObjectGuid::Create<HighGuid::Item>(depositItems[i].first.ItemId); - voidStorageTransferChanges.AddedItems[i].Creator = depositItems[i].first.CreatorGuid; - voidStorageTransferChanges.AddedItems[i].Slot = depositItems[i].second; - voidStorageTransferChanges.AddedItems[i].Item.Initialize(&depositItems[i].first); - } - - for (uint8 i = 0; i < withdrawCount; ++i) - voidStorageTransferChanges.RemovedItems[i] = ObjectGuid::Create<HighGuid::Item>(withdrawItems[i].ItemId); - SendPacket(voidStorageTransferChanges.Write()); SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index 26dda8e646e..7d54ebe3ec6 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -185,14 +185,13 @@ void WorldPackets::Item::ItemInstance::Initialize(::Item const* item) ItemBonus->Context = item->GetUInt32Value(ITEM_FIELD_CONTEXT); } - uint32 mask = item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK); - if (mask != 0) - Modifications = WorldPackets::CompactArray<int32>(); - - for (size_t i = 0; mask != 0; mask >>= 1, ++i) + if (uint32 mask = item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK)) { - if ((mask & 1) != 0) - Modifications->Insert(i, item->GetModifier(ItemModifier(i))); + Modifications = boost::in_place(); + + for (size_t i = 0; mask != 0; mask >>= 1, ++i) + if ((mask & 1) != 0) + Modifications->Insert(i, item->GetModifier(ItemModifier(i))); } } @@ -216,6 +215,17 @@ void WorldPackets::Item::ItemInstance::Initialize(::VoidStorageItem const* voidI ItemID = voidItem->ItemEntry; RandomPropertiesID = voidItem->ItemRandomPropertyId; RandomPropertiesSeed = voidItem->ItemSuffixFactor; + if (voidItem->ItemUpgradeId) + { + Modifications = boost::in_place(); + Modifications->Insert(ITEM_MODIFIER_UPGRADE_ID, voidItem->ItemUpgradeId); + } + + if (!voidItem->BonusListIDs.empty()) + { + ItemBonus = boost::in_place(); + ItemBonus->BonusListIDs = voidItem->BonusListIDs; + } } WorldPacket const* WorldPackets::Item::InventoryChangeFailure::Write() diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 9fa6e7f29ec..f7aebeb411b 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -585,8 +585,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ? AND account = ?", CONNECTION_ASYNC); // Void Storage - PrepareStatement(CHAR_SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor, upgradeId, bonusListIDs FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor, upgradeId, bonusListIDs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_CHAR_GUID, "DELETE FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM character_void_storage WHERE slot = ? AND playerGuid = ?", CONNECTION_ASYNC); |