diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Guilds/Guild.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Guilds/GuildMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/TradeHandler.cpp | 6 |
8 files changed, 62 insertions, 34 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 9027b3f575a..1981ffbfcec 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -26,7 +26,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() "ii.durability, ii.playedTime, ii.text, ii.upgradeId, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.bonusListIDs, " \ "iit.itemModifiedAppearanceAllSpecs, iit.itemModifiedAppearanceSpec1, iit.itemModifiedAppearanceSpec2, iit.itemModifiedAppearanceSpec3, iit.itemModifiedAppearanceSpec4, " \ "iit.spellItemEnchantmentAllSpecs, iit.spellItemEnchantmentSpec1, iit.spellItemEnchantmentSpec2, iit.spellItemEnchantmentSpec3, iit.spellItemEnchantmentSpec4, " \ - "ig.gemItemId1, ig.gemBonuses1, ig.gemContext1, ig.gemItemId2, ig.gemBonuses2, ig.gemContext2, ig.gemItemId3, ig.gemBonuses3, ig.gemContext3, " \ + "ig.gemItemId1, ig.gemBonuses1, ig.gemContext1, ig.gemScalingLevel1, ig.gemItemId2, ig.gemBonuses2, ig.gemContext2, ig.gemScalingLevel2, ig.gemItemId3, ig.gemBonuses3, ig.gemContext3, ig.gemScalingLevel3, " \ "im.fixedScalingLevel, im.artifactKnowledgeLevel" PrepareStatement(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC); @@ -172,7 +172,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ?, upgradeId = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEM_INSTANCE_GEMS, "INSERT INTO item_instance_gems (itemGuid, gemItemId1, gemBonuses1, gemContext1, gemItemId2, gemBonuses2, gemContext2, gemItemId3, gemBonuses3, gemContext3) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_ITEM_INSTANCE_GEMS, "INSERT INTO item_instance_gems (itemGuid, gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE_GEMS, "DELETE FROM item_instance_gems WHERE itemGuid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_ITEM_INSTANCE_GEMS_BY_OWNER, "DELETE iig FROM item_instance_gems iig LEFT JOIN item_instance ii ON iig.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_ITEM_INSTANCE_TRANSMOG, "INSERT INTO item_instance_transmog (itemGuid, itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, " diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5c018966f0a..abc7e526f30 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -446,31 +446,35 @@ void Item::SaveToDB(SQLTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_INSTANCE_GEMS); stmt->setUInt64(0, GetGUID().GetCounter()); uint32 i = 0; + uint32 const gemFields = 4; for (ItemDynamicFieldGems const& gemData : GetGems()) { if (gemData.ItemId) { - stmt->setUInt32(1 + i * MAX_GEM_SOCKETS, gemData.ItemId); + stmt->setUInt32(1 + i * gemFields, gemData.ItemId); std::ostringstream gemBonusListIDs; for (uint16 bonusListID : gemData.BonusListIDs) if (bonusListID) gemBonusListIDs << bonusListID << ' '; - stmt->setString(2 + i * MAX_GEM_SOCKETS, gemBonusListIDs.str()); - stmt->setUInt8(3 + i * MAX_GEM_SOCKETS, gemData.Context); + stmt->setString(2 + i * gemFields, gemBonusListIDs.str()); + stmt->setUInt8(3 + i * gemFields, gemData.Context); + stmt->setUInt32(4 + i * gemFields, m_gemScalingLevels[i]); } else { - stmt->setUInt32(1 + i * MAX_GEM_SOCKETS, 0); - stmt->setString(2 + i * MAX_GEM_SOCKETS, ""); - stmt->setUInt8(3 + i * MAX_GEM_SOCKETS, 0); + stmt->setUInt32(1 + i * gemFields, 0); + stmt->setString(2 + i * gemFields, ""); + stmt->setUInt8(3 + i * gemFields, 0); + stmt->setUInt32(4 + i * gemFields, 0); } ++i; } for (; i < MAX_GEM_SOCKETS; ++i) { - stmt->setUInt32(1 + i * MAX_GEM_SOCKETS, 0); - stmt->setString(2 + i * MAX_GEM_SOCKETS, ""); - stmt->setUInt8(3 + i * MAX_GEM_SOCKETS, 0); + stmt->setUInt32(1 + i * gemFields, 0); + stmt->setString(2 + i * gemFields, ""); + stmt->setUInt8(3 + i * gemFields, 0); + stmt->setUInt32(4 + i * gemFields, 0); } trans->Append(stmt); } @@ -621,8 +625,10 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie // itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, // 24 25 26 27 28 // spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, - // 29 30 31 32 33 34 35 36 37 38 39 - // gemItemId1, gemBonuses1, gemContext1, gemItemId2, gemBonuses2, gemContext2, gemItemId3, gemBonuses3, gemContext3, fixedScalingLevel, artifactKnowledgeLevel FROM item_instance + // 29 30 31 32 33 34 35 36 37 38 39 40 + // gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3 + // 41 42 + // fixedScalingLevel, artifactKnowledgeLevel FROM item_instance // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB @@ -736,24 +742,25 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, fields[27].GetUInt32()); SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, fields[28].GetUInt32()); + uint32 const gemFields = 4; ItemDynamicFieldGems gemData[MAX_GEM_SOCKETS]; memset(gemData, 0, sizeof(gemData)); for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i) { - gemData[i].ItemId = fields[29 + i * MAX_GEM_SOCKETS].GetUInt32(); - Tokenizer gemBonusListIDs(fields[30 + i * MAX_GEM_SOCKETS].GetString(), ' '); + gemData[i].ItemId = fields[29 + i * gemFields].GetUInt32(); + Tokenizer gemBonusListIDs(fields[30 + i * gemFields].GetString(), ' '); uint32 b = 0; for (char const* token : gemBonusListIDs) if (uint32 bonusListID = atoul(token)) gemData[i].BonusListIDs[b++] = bonusListID; - gemData[i].Context = fields[31 + i * MAX_GEM_SOCKETS].GetUInt8(); + gemData[i].Context = fields[31 + i * gemFields].GetUInt8(); if (gemData[i].ItemId) - SetGem(i, &gemData[i]); + SetGem(i, &gemData[i], fields[32 + i * gemFields].GetUInt32()); } - SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, fields[38].GetUInt32()); - SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[39].GetUInt32()); + SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, fields[41].GetUInt32()); + SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[42].GetUInt32()); if (need_save) // normal item changed state set not work at loading { @@ -1238,9 +1245,10 @@ ItemDynamicFieldGems const* Item::GetGem(uint16 slot) const return GetDynamicStructuredValue<ItemDynamicFieldGems>(ITEM_DYNAMIC_FIELD_GEMS, slot); } -void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem) +void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem, uint32 gemScalingLevel) { ASSERT(slot < MAX_GEM_SOCKETS); + m_gemScalingLevels[slot] = gemScalingLevel; _bonusData.GemItemLevelBonus[slot] = 0; if (ItemTemplate const* gemTemplate = sObjectMgr->GetItemTemplate(gem->ItemId)) { @@ -1255,6 +1263,11 @@ void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem) for (ItemBonusEntry const* itemBonus : *bonuses) gemBonus.AddBonus(itemBonus->Type, itemBonus->Value); + uint32 gemBaseItemLevel = gemTemplate->GetBaseItemLevel(); + if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(gemBonus.ScalingStatDistribution)) + if (uint32 scaledIlvl = uint32(sDB2Manager.GetCurveValueAt(ssd->ItemLevelCurveID, gemScalingLevel))) + gemBaseItemLevel = scaledIlvl; + for (uint32 i = 0; i < MAX_ITEM_ENCHANTMENT_EFFECTS; ++i) { switch (gemEnchant->Effect[i]) @@ -1269,7 +1282,7 @@ void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem) } case ITEM_ENCHANTMENT_TYPE_BONUS_LIST_CURVE: { - if (uint32 bonusListId = sDB2Manager.GetItemBonusListForItemLevelDelta(int16(sDB2Manager.GetCurveValueAt(CURVE_ID_ARTIFACT_RELIC_ITEM_LEVEL_BONUS, gemTemplate->GetBaseItemLevel() + gemBonus.ItemLevelBonus)))) + if (uint32 bonusListId = sDB2Manager.GetItemBonusListForItemLevelDelta(int16(sDB2Manager.GetCurveValueAt(CURVE_ID_ARTIFACT_RELIC_ITEM_LEVEL_BONUS, gemBaseItemLevel + gemBonus.ItemLevelBonus)))) if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListId)) for (ItemBonusEntry const* itemBonus : *bonuses) if (itemBonus->Type == ITEM_BONUS_ITEM_LEVEL) diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 969aafcafa0..6fdc8e212b4 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -407,7 +407,7 @@ class TC_GAME_API Item : public Object uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);} DynamicFieldStructuredView<ItemDynamicFieldGems> GetGems() const; ItemDynamicFieldGems const* GetGem(uint16 slot) const; - void SetGem(uint16 slot, ItemDynamicFieldGems const* gem); + void SetGem(uint16 slot, ItemDynamicFieldGems const* gem, uint32 gemScalingLevel); std::string const& GetText() const { return m_text; } void SetText(std::string const& text) { m_text = text; } @@ -530,5 +530,6 @@ class TC_GAME_API Item : public Object GuidSet allowedGUIDs; ObjectGuid m_childItem; std::unordered_map<uint32, uint16> m_artifactPowerIdToIndex; + std::array<uint32, MAX_ITEM_PROTO_SOCKETS> m_gemScalingLevels; }; #endif diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a6e526a1984..9e16805ef0d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18006,8 +18006,18 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti // itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, // 24 25 26 27 28 // spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, - // 29 30 31 32 33 34 35 36 37 40 41 - // gemItemId1, gemBonuses1, gemContext1, gemItemId2, gemBonuses2, gemContext2, gemItemId3, gemBonuses3, gemContext3, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC + // 29 30 31 32 33 34 35 36 37 38 39 40 + // gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3 + // 41 42 43 44 + // fixedScalingLevel, artifactKnowledgeLevel, bag, slot + // FROM character_inventory ci + // JOIN item_instance ii ON ci.item = ii.guid + // LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid + // LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid + // LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid + // WHERE ci.guid = ? + // ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC + //NOTE: ORDER BY ii.flags & 0x80000 makes child items load last - they need their parents to be already loaded //NOTE: the "order by `bag`" is important because it makes sure //the bagMap is filled before items in the bags are loaded @@ -18061,8 +18071,8 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti if (item->GetTemplate()->GetArtifactID() && artifactDataItr != artifactData.end()) item->LoadArtifactData(std::get<0>(artifactDataItr->second), std::get<1>(artifactDataItr->second), std::get<2>(artifactDataItr->second)); - ObjectGuid bagGuid = fields[40].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[40].GetUInt64()) : ObjectGuid::Empty; - uint8 slot = fields[41].GetUInt8(); + ObjectGuid bagGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[43].GetUInt64()) : ObjectGuid::Empty; + uint8 slot = fields[44].GetUInt8(); GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item); GetSession()->GetCollectionMgr()->AddItemAppearance(item); @@ -18403,7 +18413,7 @@ void Player::_LoadMailedItems(Mail* mail) Item* item = NewItemOrBag(proto); - ObjectGuid ownerGuid = fields[40].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[40].GetUInt64()) : ObjectGuid::Empty; + ObjectGuid ownerGuid = fields[43].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[43].GetUInt64()) : ObjectGuid::Empty; if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry)) { TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: " UI64FMTD ") in mail (%u) doesn't exist, deleted from mail.", itemGuid, mail->messageID); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index aedccd5ab56..47900f87afd 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -368,7 +368,7 @@ void Guild::BankTab::LoadFromDB(Field* fields) bool Guild::BankTab::LoadItemFromDB(Field* fields) { - uint8 slotId = fields[42].GetUInt8(); + uint8 slotId = fields[45].GetUInt8(); ObjectGuid::LowType itemGuid = fields[0].GetUInt64(); uint32 itemEntry = fields[1].GetUInt32(); if (slotId >= GUILD_BANK_MAX_SLOTS) @@ -2394,7 +2394,7 @@ void Guild::LoadBankTabFromDB(Field* fields) bool Guild::LoadBankItemFromDB(Field* fields) { - uint8 tabId = fields[41].GetUInt8(); + uint8 tabId = fields[44].GetUInt8(); if (tabId >= _GetPurchasedTabsSize()) { TC_LOG_ERROR("guild", "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped.", diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 00cf52ef92f..151429ebb9b 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -425,7 +425,7 @@ void GuildMgr::LoadGuilds() do { Field* fields = result->Fetch(); - uint64 guildId = fields[40].GetUInt64(); + uint64 guildId = fields[43].GetUInt64(); if (Guild* guild = GetGuildById(guildId)) guild->LoadBankItemFromDB(fields); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index eabaad75ac6..762caac0381 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1052,7 +1052,11 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) { if (gems[i]) { - itemTarget->SetGem(i, &gemData[i]); + uint32 gemScalingLevel = _player->getLevel(); + if (uint32 fixedLevel = gems[i]->GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL)) + gemScalingLevel = fixedLevel; + + itemTarget->SetGem(i, &gemData[i], gemScalingLevel); if (gemProperties[i] && gemProperties[i]->EnchantID) itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), gemProperties[i]->EnchantID, 0, 0, _player->GetGUID()); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 6987c1bbaad..ff756682501 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -79,17 +79,17 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) tradeItem.Unwrapped->MaxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); tradeItem.Unwrapped->Durability = item->GetUInt32Value(ITEM_FIELD_DURABILITY); - uint8 i = 0; + uint8 g = 0; for (ItemDynamicFieldGems const& gemData : item->GetGems()) { if (gemData.ItemId) { WorldPackets::Item::ItemGemData gem; - gem.Slot = i; + gem.Slot = g; gem.Item.Initialize(&gemData); tradeItem.Unwrapped->Gems.push_back(gem); } - ++i; + ++g; } } |