aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrozen4 <frozen4@163.com>2016-06-21 20:33:51 +0200
committerShauren <shauren.trinity@gmail.com>2016-06-21 20:33:51 +0200
commited00534e7c311530e5fbb1ffb567d9459ff4c1f0 (patch)
tree5a234b348c9eaff312b80fd3bf2a4fed5a6ee309
parent5f2c62392cadc3b87816a5330bbd573e95c9326c (diff)
Core/Items: Implemented item upgrades
Closes #17432
-rw-r--r--sql/updates/hotfixes/6.x/2016_06_21_00_hotfixes.sql27
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp11
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h8
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp17
-rw-r--r--src/server/game/DataStores/DB2Stores.h4
-rw-r--r--src/server/game/DataStores/DB2Structure.h18
-rw-r--r--src/server/game/DataStores/DB2fmt.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp62
-rw-r--r--src/server/game/Server/Packets/ItemPackets.cpp17
-rw-r--r--src/server/game/Server/Packets/ItemPackets.h24
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp3
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h1
-rw-r--r--src/server/game/Server/WorldSession.h2
14 files changed, 194 insertions, 5 deletions
diff --git a/sql/updates/hotfixes/6.x/2016_06_21_00_hotfixes.sql b/sql/updates/hotfixes/6.x/2016_06_21_00_hotfixes.sql
new file mode 100644
index 00000000000..e2ca7d2ce65
--- /dev/null
+++ b/sql/updates/hotfixes/6.x/2016_06_21_00_hotfixes.sql
@@ -0,0 +1,27 @@
+--
+-- Table structure for table `item_upgrade`
+--
+DROP TABLE IF EXISTS `item_upgrade`;
+CREATE TABLE `item_upgrade` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemUpgradePathID` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemLevelBonus` int(10) unsigned NOT NULL DEFAULT '0',
+ `PrevItemUpgradeID` int(10) unsigned NOT NULL DEFAULT '0',
+ `CurrencyID` int(10) unsigned NOT NULL DEFAULT '0',
+ `CurrencyCost` int(10) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `ruleset_item_upgrade`
+--
+DROP TABLE IF EXISTS `ruleset_item_upgrade`;
+CREATE TABLE `ruleset_item_upgrade` (
+ `ID` int(10) unsigned NOT NULL DEFAULT '0',
+ `RulesetID` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemUpgradeID` int(10) unsigned NOT NULL DEFAULT '0',
+ `ItemID` int(10) unsigned NOT NULL DEFAULT '0',
+ `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`ID`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 6749300000b..c6b03dbf385 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
- // DO NOT EDIT!
- // Autogenerated from DB2Structure.h
+// DO NOT EDIT!
+// Autogenerated from DB2Structure.h
#include "HotfixDatabase.h"
@@ -300,6 +300,10 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// ItemToBattlePetSpecies.db2
PrepareStatement(HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES, "SELECT ID, BattlePetSpeciesID FROM item_to_battle_pet_species ORDER BY ID DESC", CONNECTION_SYNCH);
+ // ItemUpgrade.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_UPGRADE, "SELECT ID, ItemUpgradePathID, ItemLevelBonus, PrevItemUpgradeID, CurrencyID, CurrencyCost"
+ " FROM item_upgrade ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ItemXBonusTree.db2
PrepareStatement(HOTFIX_SEL_ITEM_X_BONUS_TREE, "SELECT ID, ItemID, BonusTreeID FROM item_x_bonus_tree ORDER BY ID DESC", CONNECTION_SYNCH);
@@ -383,6 +387,9 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// QuestXp.db2
PrepareStatement(HOTFIX_SEL_QUEST_XP, "SELECT ID, Exp1, Exp2, Exp3, Exp4, Exp5, Exp6, Exp7, Exp8, Exp9, Exp10 FROM quest_xp ORDER BY ID DESC", CONNECTION_SYNCH);
+ // RulesetItemUpgrade.db2
+ PrepareStatement(HOTFIX_SEL_RULESET_ITEM_UPGRADE, "SELECT ID, RulesetID, ItemUpgradeID, ItemID FROM ruleset_item_upgrade ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ScalingStatDistribution.db2
PrepareStatement(HOTFIX_SEL_SCALING_STAT_DISTRIBUTION, "SELECT ID, MinLevel, MaxLevel, ItemLevelCurveID FROM scaling_stat_distribution"
" ORDER BY ID DESC", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 999c9316dad..cb45187e275 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
- // DO NOT EDIT!
- // Autogenerated from DB2Structure.h
+// DO NOT EDIT!
+// Autogenerated from DB2Structure.h
#ifndef _HOTFIXDATABASE_H
#define _HOTFIXDATABASE_H
@@ -174,6 +174,8 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES,
+ HOTFIX_SEL_ITEM_UPGRADE,
+
HOTFIX_SEL_ITEM_X_BONUS_TREE,
HOTFIX_SEL_KEY_CHAIN,
@@ -217,6 +219,8 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_QUEST_XP,
+ HOTFIX_SEL_RULESET_ITEM_UPGRADE,
+
HOTFIX_SEL_SCALING_STAT_DISTRIBUTION,
HOTFIX_SEL_SOUND_ENTRIES,
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 2fd9c22b080..f706e52330d 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -83,6 +83,7 @@ DB2Storage<ItemSparseEntry> sItemSparseStore("Item-sparse.db
DB2Storage<ItemSpecEntry> sItemSpecStore("ItemSpec.db2", ItemSpecFormat, HOTFIX_SEL_ITEM_SPEC);
DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore("ItemSpecOverride.db2", ItemSpecOverrideFormat, HOTFIX_SEL_ITEM_SPEC_OVERRIDE);
DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore("ItemToBattlePetSpecies.db2", ItemToBattlePetSpeciesFormat, HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES);
+DB2Storage<ItemUpgradeEntry> sItemUpgradeStore("ItemUpgrade.db2", ItemUpgradeEntryFormat, HOTFIX_SEL_ITEM_UPGRADE);
DB2Storage<ItemXBonusTreeEntry> sItemXBonusTreeStore("ItemXBonusTree.db2", ItemXBonusTreeFormat, HOTFIX_SEL_ITEM_X_BONUS_TREE);
DB2Storage<KeyChainEntry> sKeyChainStore("KeyChain.db2", KeyChainFormat, HOTFIX_SEL_KEY_CHAIN);
DB2Storage<MailTemplateEntry> sMailTemplateStore("MailTemplate.db2", MailTemplateFormat, HOTFIX_SEL_MAIL_TEMPLATE);
@@ -102,6 +103,7 @@ DB2Storage<QuestPackageItemEntry> sQuestPackageItemStore("QuestPac
DB2Storage<QuestSortEntry> sQuestSortStore("QuestSort.db2", QuestSortFormat, HOTFIX_SEL_QUEST_SORT);
DB2Storage<QuestV2Entry> sQuestV2Store("QuestV2.db2", QuestV2Format, HOTFIX_SEL_QUEST_V2);
DB2Storage<QuestXPEntry> sQuestXPStore("QuestXP.db2", QuestXPFormat, HOTFIX_SEL_QUEST_XP);
+DB2Storage<RulesetItemUpgradeEntry> sRulesetItemUpgradeStore("RulesetItemUpgrade.db2", RulesetItemUpgradeEntryFormat, HOTFIX_SEL_RULESET_ITEM_UPGRADE);
DB2Storage<ScalingStatDistributionEntry> sScalingStatDistributionStore("ScalingStatDistribution.db2", ScalingStatDistributionFormat, HOTFIX_SEL_SCALING_STAT_DISTRIBUTION);
DB2Storage<SoundEntriesEntry> sSoundEntriesStore("SoundEntries.db2", SoundEntriesFormat, HOTFIX_SEL_SOUND_ENTRIES);
DB2Storage<SpecializationSpellsEntry> sSpecializationSpellsStore("SpecializationSpells.db2", SpecializationSpellsFormat, HOTFIX_SEL_SPECIALIZATION_SPELLS);
@@ -265,6 +267,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sItemSpecStore);
LOAD_DB2(sItemStore);
LOAD_DB2(sItemToBattlePetSpeciesStore);
+ LOAD_DB2(sItemUpgradeStore);
LOAD_DB2(sItemXBonusTreeStore);
LOAD_DB2(sKeyChainStore);
LOAD_DB2(sMailTemplateStore);
@@ -284,6 +287,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
LOAD_DB2(sQuestSortStore);
LOAD_DB2(sQuestV2Store);
LOAD_DB2(sQuestXPStore);
+ LOAD_DB2(sRulesetItemUpgradeStore);
LOAD_DB2(sScalingStatDistributionStore);
LOAD_DB2(sSoundEntriesStore);
LOAD_DB2(sSpecializationSpellsStore);
@@ -424,6 +428,10 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
for (QuestPackageItemEntry const* questPackageItem : sQuestPackageItemStore)
_questPackages[questPackageItem->QuestPackageID].push_back(questPackageItem);
+ for (RulesetItemUpgradeEntry const* rulesetItemUpgrade : sRulesetItemUpgradeStore)
+ if (rulesetItemUpgrade->RulesetID == 1) // xref to Cfg_Regions.db2, RulesetID column. 1 is the value for EU region we send hardcoded in SMSG_INITIAL_SETUP, possible other value for RulesetID is 2 in korean region
+ _rulesetItemUpgrade[rulesetItemUpgrade->ItemID] = rulesetItemUpgrade->ItemUpgradeID;
+
for (SpecializationSpellsEntry const* specSpells : sSpecializationSpellsStore)
_specializationSpellsBySpec[specSpells->SpecID].push_back(specSpells);
@@ -809,6 +817,15 @@ std::set<uint32> DB2Manager::GetPhasesForGroup(uint32 group) const
return std::set<uint32>();
}
+uint32 DB2Manager::GetRulesetItemUpgrade(uint32 itemId) const
+{
+ auto itr = _rulesetItemUpgrade.find(itemId);
+ if (itr != _rulesetItemUpgrade.end())
+ return itr->second;
+
+ return 0;
+}
+
std::vector<SpecializationSpellsEntry const*> const* DB2Manager::GetSpecializationSpells(uint32 specId) const
{
auto itr = _specializationSpellsBySpec.find(specId);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index b42d1dd8bab..b7201f7d47d 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -76,6 +76,7 @@ TC_GAME_API extern DB2Storage<ItemSparseEntry> sItemSparseS
TC_GAME_API extern DB2Storage<ItemSpecEntry> sItemSpecStore;
TC_GAME_API extern DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore;
TC_GAME_API extern DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore;
+TC_GAME_API extern DB2Storage<ItemUpgradeEntry> sItemUpgradeStore;
TC_GAME_API extern DB2Storage<MailTemplateEntry> sMailTemplateStore;
TC_GAME_API extern DB2Storage<ModifierTreeEntry> sModifierTreeStore;
TC_GAME_API extern DB2Storage<MountCapabilityEntry> sMountCapabilityStore;
@@ -158,6 +159,7 @@ public:
typedef std::array<std::vector<boost::regex>, TOTAL_LOCALES + 1> NameValidationRegexContainer;
typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer;
typedef std::unordered_map<uint32, std::vector<QuestPackageItemEntry const*>> QuestPackageItemContainer;
+ typedef std::unordered_map<uint32, uint32> RulesetItemUpgradeContainer;
typedef std::unordered_map<uint32, std::vector<SpecializationSpellsEntry const*>> SpecializationSpellsContainer;
typedef std::unordered_map<uint32, std::vector<SpellPowerEntry const*>> SpellPowerContainer;
typedef std::unordered_map<uint32, std::unordered_map<uint32, std::vector<SpellPowerEntry const*>>> SpellPowerDifficultyContainer;
@@ -192,6 +194,7 @@ public:
std::vector<QuestPackageItemEntry const*> const* GetQuestPackageItems(uint32 questPackageID) const;
uint32 GetQuestUniqueBitFlag(uint32 questId);
std::set<uint32> GetPhasesForGroup(uint32 group) const;
+ uint32 GetRulesetItemUpgrade(uint32 itemId) const;
std::vector<SpecializationSpellsEntry const*> const* GetSpecializationSpells(uint32 specId) const;
std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const;
std::vector<SpellProcsPerMinuteModEntry const*> GetSpellProcsPerMinuteMods(uint32 spellprocsPerMinuteId) const;
@@ -217,6 +220,7 @@ private:
NameGenContainer _nameGenData;
NameValidationRegexContainer _nameValidators;
PhaseGroupContainer _phasesByGroup;
+ RulesetItemUpgradeContainer _rulesetItemUpgrade;
QuestPackageItemContainer _questPackages;
SpecializationSpellsContainer _specializationSpellsBySpec;
SpellPowerContainer _spellPowers;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index daebcf7375f..685b186f92d 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -879,6 +879,16 @@ struct ItemToBattlePetSpeciesEntry
uint32 BattlePetSpeciesID; // 1
};
+struct ItemUpgradeEntry
+{
+ uint32 ID; // 0
+ uint32 ItemUpgradePathID; // 1
+ uint32 ItemLevelBonus; // 2
+ uint32 PrevItemUpgradeID; // 3
+ uint32 CurrencyID; // 4
+ uint32 CurrencyCost; // 5
+};
+
struct ItemXBonusTreeEntry
{
uint32 ID; // 0
@@ -1103,6 +1113,14 @@ struct QuestXPEntry
uint32 Exp[10]; // 1
};
+struct RulesetItemUpgradeEntry
+{
+ uint32 ID; // 0
+ uint32 RulesetID; // 1
+ uint32 ItemUpgradeID; // 2
+ uint32 ItemID; // 3
+};
+
struct ScalingStatDistributionEntry
{
uint32 ID; // 0
diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h
index 2a64a2d4eb5..ea5ef297b3c 100644
--- a/src/server/game/DataStores/DB2fmt.h
+++ b/src/server/game/DataStores/DB2fmt.h
@@ -77,6 +77,7 @@ char const ItemSparseFormat[] = "niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
char const ItemSpecFormat[] = "niiiiii";
char const ItemSpecOverrideFormat[] = "nii";
char const ItemToBattlePetSpeciesFormat[] = "ni";
+char const ItemUpgradeEntryFormat[] = "niiiii";
char const ItemXBonusTreeFormat[] = "nii";
char const KeyChainFormat[] = "nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
char const MailTemplateFormat[] = "ns";
@@ -96,6 +97,7 @@ char const QuestPackageItemfmt[] = "niiii";
char const QuestSortFormat[] = "ns";
char const QuestV2Format[] = "ni";
char const QuestXPFormat[] = "niiiiiiiiii";
+char const RulesetItemUpgradeEntryFormat[] = "niii";
char const ScalingStatDistributionFormat[] = "niii";
char const SoundEntriesFormat[] = "nisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiififfiifffffii";
char const SpecializationSpellsFormat[] = "niiiis";
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index c28d2884a01..50b0a3dd69f 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -11038,6 +11038,9 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
if (randomPropertyId)
item->SetItemRandomProperties(randomPropertyId);
+ if (uint32 upgradeID = sDB2Manager.GetRulesetItemUpgrade(itemId))
+ item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, upgradeID);
+
for (int32 bonusListID : bonusListIDs)
item->AddBonuses(bonusListID);
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 8c7f8190e09..6eab4072491 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -1292,3 +1292,65 @@ void WorldSession::HandleUseCritterItem(WorldPackets::Item::UseCritterItem& useC
GetBattlePetMgr()->AddPet(battlePetSpecies->ID, battlePetSpecies->CreatureID, BattlePetMgr::RollPetBreed(battlePetSpecies->ID), BattlePetMgr::GetDefaultPetQuality(battlePetSpecies->ID));
_player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
}
+
+void WorldSession::HandleUpgradeItem(WorldPackets::Item::UpgradeItem& upgradeItem)
+{
+ WorldPackets::Item::ItemUpgradeResult itemUpgradeResult;
+ if (!_player->GetNPCIfCanInteractWith(upgradeItem.ItemMaster, UNIT_NPC_FLAG_ITEM_UPGRADE_MASTER))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleUpgradeItems - %s not found or player can't interact with it.", upgradeItem.ItemMaster.ToString().c_str());
+ itemUpgradeResult.Success = false;
+ SendPacket(itemUpgradeResult.Write());
+ return;
+ }
+
+ Item* item = _player->GetItemByGuid(upgradeItem.ItemGUID);
+ if (!item)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleUpgradeItems: Item %s not found!", upgradeItem.ItemGUID.ToString().c_str());
+ itemUpgradeResult.Success = false;
+ SendPacket(itemUpgradeResult.Write());
+ return;
+ }
+
+ ItemUpgradeEntry const* itemUpgradeEntry = sItemUpgradeStore.LookupEntry(upgradeItem.UpgradeID);
+ if (!itemUpgradeEntry)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleUpgradeItems - ItemUpgradeEntry (%u) not found.", upgradeItem.UpgradeID);
+ itemUpgradeResult.Success = false;
+ SendPacket(itemUpgradeResult.Write());
+ return;
+ }
+
+ // Check if player has enough currency
+ if (!_player->HasCurrency(itemUpgradeEntry->CurrencyID, itemUpgradeEntry->CurrencyCost))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleUpgradeItems - Player has not enougth currency (ID: %u, Cost: %u) not found.", itemUpgradeEntry->CurrencyID, itemUpgradeEntry->CurrencyCost);
+ itemUpgradeResult.Success = false;
+ SendPacket(itemUpgradeResult.Write());
+ return;
+ }
+
+ uint32 currentUpgradeId = item->GetModifier(ITEM_MODIFIER_UPGRADE_ID);
+ if (currentUpgradeId != itemUpgradeEntry->PrevItemUpgradeID)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleUpgradeItems - ItemUpgradeEntry (%u) is not related to this ItemUpgradePath (%u).", itemUpgradeEntry->ID, currentUpgradeId);
+ itemUpgradeResult.Success = false;
+ SendPacket(itemUpgradeResult.Write());
+ return;
+ }
+
+ itemUpgradeResult.Success = true;
+ SendPacket(itemUpgradeResult.Write());
+
+ if (item->IsEquipped())
+ _player->_ApplyItemBonuses(item, item->GetSlot(), false);
+
+ item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, itemUpgradeEntry->ID);
+
+ if (item->IsEquipped())
+ _player->_ApplyItemBonuses(item, item->GetSlot(), true);
+
+ item->SetState(ITEM_CHANGED, _player);
+ _player->ModifyCurrency(itemUpgradeEntry->CurrencyID, -int32(itemUpgradeEntry->CurrencyCost));
+}
diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp
index e627d80fdea..8ac3e947135 100644
--- a/src/server/game/Server/Packets/ItemPackets.cpp
+++ b/src/server/game/Server/Packets/ItemPackets.cpp
@@ -529,6 +529,15 @@ void WorldPackets::Item::UseCritterItem::Read()
_worldPacket >> ItemGuid;
}
+void WorldPackets::Item::UpgradeItem::Read()
+{
+ _worldPacket >> ItemMaster;
+ _worldPacket >> ItemGUID;
+ _worldPacket >> UpgradeID;
+ _worldPacket >> ContainerSlot;
+ _worldPacket >> Slot;
+}
+
void WorldPackets::Item::SocketGems::Read()
{
_worldPacket >> ItemGuid;
@@ -544,3 +553,11 @@ WorldPacket const* WorldPackets::Item::SocketGemsResult::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Item::ItemUpgradeResult::Write()
+{
+ _worldPacket.WriteBit(Success);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h
index 833d1bd9261..ad821682f9c 100644
--- a/src/server/game/Server/Packets/ItemPackets.h
+++ b/src/server/game/Server/Packets/ItemPackets.h
@@ -502,6 +502,30 @@ namespace WorldPackets
ObjectGuid ItemGuid;
};
+ class UpgradeItem final : public ClientPacket
+ {
+ public:
+ UpgradeItem(WorldPacket&& packet) : ClientPacket(CMSG_UPGRADE_ITEM, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid ItemMaster;
+ ObjectGuid ItemGUID;
+ int32 ContainerSlot = 0;
+ int32 UpgradeID = 0;
+ int32 Slot = 0;
+ };
+
+ class ItemUpgradeResult final : public ServerPacket
+ {
+ public:
+ ItemUpgradeResult() : ServerPacket(SMSG_ITEM_UPGRADE_RESULT, 1) { }
+
+ WorldPacket const* Write() override;
+
+ bool Success = false;
+ };
+
class SocketGems final : public ClientPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index a284d874191..fc1501b6894 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -774,7 +774,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Token::UpdateListedAuctionableTokens, &WorldSession::HandleUpdateListedAuctionableTokens);
DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_COUNT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_UPGRADE_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_UPGRADE_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_UPGRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::UpgradeItem, &WorldSession::HandleUpgradeItem);
DEFINE_HANDLER(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_USE_CRITTER_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::UseCritterItem, &WorldSession::HandleUseCritterItem);
DEFINE_HANDLER(CMSG_USE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::UseEquipmentSet, &WorldSession::HandleUseEquipmentSet);
@@ -1228,6 +1228,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PURCHASE_REFUND_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_UPGRADE_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARN_TALENT_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 37f8500fe84..5e428ec9a4d 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1644,6 +1644,7 @@ enum OpcodeServer : uint32
// Opcodes that are not generated automatically
SMSG_ACCOUNT_HEIRLOOM_UPDATE = 0x254B, // no client handler
+ SMSG_ITEM_UPGRADE_RESULT = 0x25DB, // no client handler
SMSG_COMPRESSED_PACKET = 0x2FCF,
SMSG_MULTIPLE_PACKETS = 0x2FCE,
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 26e8329ee9c..0e2ecee911f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -371,6 +371,7 @@ namespace WorldPackets
class CancelTempEnchantment;
class TransmogrifyItems;
class UseCritterItem;
+ class UpgradeItem;
class SocketGems;
struct ItemInstance;
}
@@ -1426,6 +1427,7 @@ class TC_GAME_API WorldSession
void HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet);
void HandleWrapItem(WorldPackets::Item::WrapItem& packet);
void HandleUseCritterItem(WorldPackets::Item::UseCritterItem& packet);
+ void HandleUpgradeItem(WorldPackets::Item::UpgradeItem& packet);
void HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet);
void HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& packet);