Core/Items: Fixed item level increases of gems with bonuses that give them scaling stat distribution
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
|
||||
ALTER TABLE `item_instance_gems`
|
||||
CHANGE `gemItemId1` `gemItemId1` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `gemBonuses1` `gemBonuses1` text,
|
||||
ADD `gemScalingLevel1` int(10) unsigned NOT NULL DEFAULT '0' AFTER `gemContext1`,
|
||||
CHANGE `gemItemId2` `gemItemId2` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
CHANGE `gemBonuses2` `gemBonuses2` text,
|
||||
ADD `gemScalingLevel2` int(10) unsigned NOT NULL DEFAULT '0' AFTER `gemBonuses2`,
|
||||
CHANGE `gemItemId3` `gemItemId3` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
CHANGE `gemBonuses3` `gemBonuses3` text,
|
||||
ADD `gemScalingLevel3` int(10) unsigned NOT NULL DEFAULT '0' AFTER `gemContext3`;
|
||||
@@ -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, "
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user