aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp6
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp14
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h8
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp4
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp1
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h57
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp4
-rw-r--r--src/server/game/DataStores/DB2Stores.h2
-rw-r--r--src/server/game/DataStores/DB2Structure.h17
-rw-r--r--src/server/game/Entities/Item/Item.cpp119
-rw-r--r--src/server/game/Entities/Item/Item.h1
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp165
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp66
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Guilds/Guild.cpp4
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp20
-rw-r--r--src/server/game/Handlers/LootHandler.cpp2
-rw-r--r--src/server/game/Handlers/VoidStorageHandler.cpp2
-rw-r--r--src/server/game/Loot/Loot.cpp7
-rw-r--r--src/server/game/Loot/Loot.h2
-rw-r--r--src/server/game/Server/Packets/ItemPacketsCommon.cpp6
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/World/World.cpp3
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp4
-rw-r--r--src/server/scripts/World/item_scripts.cpp4
26 files changed, 423 insertions, 105 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 1462006e552..1a69c73fd21 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -24,7 +24,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS);
#define SelectItemInstanceContent "ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomBonusListId, " \
- "ii.durability, ii.playedTime, ii.createTime, ii.text, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.context, ii.bonusListIDs, " \
+ "ii.durability, ii.playedTime, ii.createTime, ii.text, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.context, ii.bonusListIDs, ii.randomPropertiesId, " \
"iit.itemModifiedAppearanceAllSpecs, iit.itemModifiedAppearanceSpec1, iit.itemModifiedAppearanceSpec2, iit.itemModifiedAppearanceSpec3, iit.itemModifiedAppearanceSpec4, iit.itemModifiedAppearanceSpec5, " \
"iit.spellItemEnchantmentAllSpecs, iit.spellItemEnchantmentSpec1, iit.spellItemEnchantmentSpec2, iit.spellItemEnchantmentSpec3, iit.spellItemEnchantmentSpec4, iit.spellItemEnchantmentSpec5, " \
"iit.secondaryItemModifiedAppearanceAllSpecs, iit.secondaryItemModifiedAppearanceSpec1, iit.secondaryItemModifiedAppearanceSpec2, iit.secondaryItemModifiedAppearanceSpec3, iit.secondaryItemModifiedAppearanceSpec4, iit.secondaryItemModifiedAppearanceSpec5, " \
@@ -192,8 +192,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_INVENTORY_ITEM, "REPLACE INTO character_inventory (guid, bag, slot, item) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomBonusListId = ?, durability = ?, playedTime = ?, createTime = ?, text = ?, battlePetSpeciesId = ?, battlePetBreedData = ?, battlePetLevel = ?, battlePetDisplayId = ?, context = ?, bonusListIDs = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, randomPropertiesId, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomBonusListId = ?, durability = ?, playedTime = ?, createTime = ?, text = ?, battlePetSpeciesId = ?, battlePetBreedData = ?, battlePetLevel = ?, battlePetDisplayId = ?, context = ?, bonusListIDs = ?, randomPropertiesId = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? 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);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 9fb645bc571..d79d35a1d97 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -722,6 +722,20 @@ void HotfixDatabaseConnection::DoPrepareStatements()
PrepareStatement(HOTFIX_SEL_ITEM_PRICE_BASE, "SELECT ID, ItemLevel, Armor, Weapon FROM item_price_base WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
PREPARE_MAX_ID_STMT(HOTFIX_SEL_ITEM_PRICE_BASE, "SELECT MAX(ID) + 1 FROM item_price_base", CONNECTION_SYNCH);
+ // ItemRandomProperties.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, Name, Enchantment1, Enchantment2, Enchantment3, Enchantment4, Enchantment5"
+ " FROM item_random_properties WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
+ PREPARE_MAX_ID_STMT(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT MAX(ID) + 1 FROM item_random_properties", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, Name_lang FROM item_random_properties_locale WHERE (`VerifiedBuild` > 0) = ?"
+ " AND locale = ?", CONNECTION_SYNCH);
+
+ // ItemRandomSuffix.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_RANDOM_SUFFIX, "SELECT ID, Name, Enchantment1, Enchantment2, Enchantment3, Enchantment4, Enchantment5, "
+ "AllocationPct1, AllocationPct2, AllocationPct3, AllocationPct4, AllocationPct5 FROM item_random_suffix WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
+ PREPARE_MAX_ID_STMT(HOTFIX_SEL_ITEM_RANDOM_SUFFIX, "SELECT MAX(ID) + 1 FROM item_random_suffix", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_RANDOM_SUFFIX, "SELECT ID, Name_lang FROM item_random_suffix_locale WHERE (`VerifiedBuild` > 0) = ?"
+ " AND locale = ?", CONNECTION_SYNCH);
+
// ItemReforge.db2
PrepareStatement(HOTFIX_SEL_ITEM_REFORGE, "SELECT ID, SourceStat, SourceMultiplier, TargetStat, TargetMultiplier, LegacyItemReforgeID"
" FROM item_reforge WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index b28d27eadc4..2e064748e4a 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -422,6 +422,14 @@ enum HotfixDatabaseStatements : uint32
HOTFIX_SEL_ITEM_PRICE_BASE,
HOTFIX_SEL_ITEM_PRICE_BASE_MAX_ID,
+ HOTFIX_SEL_ITEM_RANDOM_PROPERTIES,
+ HOTFIX_SEL_ITEM_RANDOM_PROPERTIES_MAX_ID,
+ HOTFIX_SEL_ITEM_RANDOM_PROPERTIES_LOCALE,
+
+ HOTFIX_SEL_ITEM_RANDOM_SUFFIX,
+ HOTFIX_SEL_ITEM_RANDOM_SUFFIX_MAX_ID,
+ HOTFIX_SEL_ITEM_RANDOM_SUFFIX_LOCALE,
+
HOTFIX_SEL_ITEM_REFORGE,
HOTFIX_SEL_ITEM_REFORGE_MAX_ID,
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 1e512a98a97..bcbb5c4ad26 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -528,12 +528,12 @@ void AuctionHouseMgr::LoadAuctions()
}
Item* item = NewItemOrBag(proto);
- if (!item->LoadFromDB(itemGuid, ObjectGuid::Create<HighGuid::Player>(fields[53].GetUInt64()), fields, itemEntry))
+ if (!item->LoadFromDB(itemGuid, ObjectGuid::Create<HighGuid::Player>(fields[54].GetUInt64()), fields, itemEntry))
{
delete item;
continue;
}
- uint32 auctionId = fields[54].GetUInt32();
+ uint32 auctionId = fields[55].GetUInt32();
itemsByAuction[auctionId].push_back(item);
++count;
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
index 478e7e19b55..cd8b1fc6ad9 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -868,6 +868,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
// Update the just created item so that if it needs random properties it has them.
// Ex: Notched Shortsword of Stamina will only generate as a Notched Shortsword without this.
item->SetItemRandomBonusList(GenerateItemRandomBonusListId(itemId));
+ item->SetItemRandomEnchantment(GenerateItemRandomPropertiesId(itemId));
uint32 buyoutPrice;
uint32 bidPrice = 0;
diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h
index 3d3a3ea7604..523f029f80d 100644
--- a/src/server/game/DataStores/DB2LoadInfo.h
+++ b/src/server/game/DataStores/DB2LoadInfo.h
@@ -2265,6 +2265,43 @@ struct ItemPriceBaseLoadInfo
static constexpr DB2LoadInfo Instance{ Fields, 4, &ItemPriceBaseMeta::Instance, HOTFIX_SEL_ITEM_PRICE_BASE };
};
+struct ItemRandomPropertiesLoadInfo
+{
+ static constexpr DB2FieldMeta Fields[7] =
+ {
+ { false, FT_INT, "ID" },
+ { false, FT_STRING, "Name" },
+ { true, FT_INT, "Enchantment1" },
+ { true, FT_INT, "Enchantment2" },
+ { true, FT_INT, "Enchantment3" },
+ { true, FT_INT, "Enchantment4" },
+ { true, FT_INT, "Enchantment5" },
+ };
+
+ static constexpr DB2LoadInfo Instance{ Fields, 7, &ItemRandomPropertiesMeta::Instance, HOTFIX_SEL_ITEM_RANDOM_PROPERTIES };
+};
+
+struct ItemRandomSuffixLoadInfo
+{
+ static constexpr DB2FieldMeta Fields[12] =
+ {
+ { false, FT_INT, "ID" },
+ { false, FT_STRING, "Name" },
+ { true, FT_INT, "Enchantment1" },
+ { true, FT_INT, "Enchantment2" },
+ { true, FT_INT, "Enchantment3" },
+ { true, FT_INT, "Enchantment4" },
+ { true, FT_INT, "Enchantment5" },
+ { true, FT_INT, "AllocationPct1" },
+ { true, FT_INT, "AllocationPct2" },
+ { true, FT_INT, "AllocationPct3" },
+ { true, FT_INT, "AllocationPct4" },
+ { true, FT_INT, "AllocationPct5" },
+ };
+
+ static constexpr DB2LoadInfo Instance{ Fields, 12, &ItemRandomSuffixMeta::Instance, HOTFIX_SEL_ITEM_RANDOM_SUFFIX };
+};
+
struct ItemReforgeLoadInfo
{
static constexpr DB2FieldMeta Fields[6] =
@@ -3720,16 +3757,6 @@ struct ScalingStatDistributionLoadInfo
{ false, FT_SHORT, "PlayerLevelToItemLevelCurveID" },
{ true, FT_INT, "Minlevel" },
{ true, FT_INT, "Maxlevel" },
- { true, FT_INT, "StatID1" },
- { true, FT_INT, "StatID2" },
- { true, FT_INT, "StatID3" },
- { true, FT_INT, "StatID4" },
- { true, FT_INT, "StatID5" },
- { true, FT_INT, "StatID6" },
- { true, FT_INT, "StatID7" },
- { true, FT_INT, "StatID8" },
- { true, FT_INT, "StatID9" },
- { true, FT_INT, "StatID10" },
{ true, FT_INT, "Bonus1" },
{ true, FT_INT, "Bonus2" },
{ true, FT_INT, "Bonus3" },
@@ -3740,6 +3767,16 @@ struct ScalingStatDistributionLoadInfo
{ true, FT_INT, "Bonus8" },
{ true, FT_INT, "Bonus9" },
{ true, FT_INT, "Bonus10" },
+ { true, FT_INT, "StatID1" },
+ { true, FT_INT, "StatID2" },
+ { true, FT_INT, "StatID3" },
+ { true, FT_INT, "StatID4" },
+ { true, FT_INT, "StatID5" },
+ { true, FT_INT, "StatID6" },
+ { true, FT_INT, "StatID7" },
+ { true, FT_INT, "StatID8" },
+ { true, FT_INT, "StatID9" },
+ { true, FT_INT, "StatID10" },
};
static constexpr DB2LoadInfo Instance{ Fields, 24, &ScalingStatDistributionMeta::Instance, HOTFIX_SEL_SCALING_STAT_DISTRIBUTION };
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 7cd81ae8799..8462613d4ce 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -157,6 +157,8 @@ DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore("It
DB2Storage<ItemModifiedAppearanceExtraEntry> sItemModifiedAppearanceExtraStore("ItemModifiedAppearanceExtra.db2", &ItemModifiedAppearanceExtraLoadInfo::Instance);
DB2Storage<ItemNameDescriptionEntry> sItemNameDescriptionStore("ItemNameDescription.db2", &ItemNameDescriptionLoadInfo::Instance);
DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore("ItemPriceBase.db2", &ItemPriceBaseLoadInfo::Instance);
+DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore("ItemRandomProperties.db2", &ItemRandomPropertiesLoadInfo::Instance);
+DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore("ItemRandomSuffix.db2", &ItemRandomSuffixLoadInfo::Instance);
DB2Storage<ItemReforgeEntry> sItemReforgeStore("ItemReforge.db2", &ItemReforgeLoadInfo::Instance);
DB2Storage<ItemSearchNameEntry> sItemSearchNameStore("ItemSearchName.db2", &ItemSearchNameLoadInfo::Instance);
DB2Storage<ItemSetEntry> sItemSetStore("ItemSet.db2", &ItemSetLoadInfo::Instance);
@@ -662,6 +664,8 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
LOAD_DB2(sItemModifiedAppearanceExtraStore);
LOAD_DB2(sItemNameDescriptionStore);
LOAD_DB2(sItemPriceBaseStore);
+ LOAD_DB2(sItemRandomPropertiesStore);
+ LOAD_DB2(sItemRandomSuffixStore);
LOAD_DB2(sItemReforgeStore);
LOAD_DB2(sItemSearchNameStore);
LOAD_DB2(sItemSetStore);
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 34803198506..e46fe813214 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -128,6 +128,8 @@ TC_GAME_API extern DB2Storage<ItemLimitCategoryEntry> sItemLimitCa
TC_GAME_API extern DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore;
TC_GAME_API extern DB2Storage<ItemModifiedAppearanceExtraEntry> sItemModifiedAppearanceExtraStore;
TC_GAME_API extern DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore;
+TC_GAME_API extern DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
+TC_GAME_API extern DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore;
TC_GAME_API extern DB2Storage<ItemReforgeEntry> sItemReforgeStore;
TC_GAME_API extern DB2Storage<ItemSearchNameEntry> sItemSearchNameStore;
TC_GAME_API extern DB2Storage<ItemSetEntry> sItemSetStore;
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 836163b7f3b..56d713c1a68 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -1912,6 +1912,23 @@ struct ItemPriceBaseEntry
float Weapon;
};
+// structure for ItemRandomProperties.db2
+struct ItemRandomPropertiesEntry
+{
+ uint32 ID;
+ LocalizedString Name;
+ std::array<int32, 5> Enchantment;
+};
+
+// structure for ItemRandomSuffix.db2
+struct ItemRandomSuffixEntry
+{
+ uint32 ID;
+ LocalizedString Name;
+ std::array<int32, 5> Enchantment;
+ std::array<int32, 5> AllocationPct;
+};
+
// structure for ItemReforge.db2
struct ItemReforgeEntry
{
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index dae8436cbe3..7c6f7de62ef 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -489,6 +489,7 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
bonusListIDs << bonusListID << ' ';
stmt->setString(++index, bonusListIDs.str());
+ stmt->setInt32(++index, m_itemData->RandomPropertiesID);
stmt->setUInt64(++index, GetGUID().GetCounter());
trans->Append(stmt);
@@ -670,19 +671,19 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
- // 14 15 16 17 18 19
- // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 20 21 22 23 24 25
+ // 14 15 16 17 18 19 20
+ // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, randomPropertiesId,
+ // 21 22 23 24 25 26
// itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
- // 26 27 28 29 30 31
+ // 27 28 29 30 31 32
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
- // 32 33 34
+ // 33 34 35
// secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
- // 35 36 37
+ // 36 37 38
// secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
- // 38 39 40 41 42 43 44 45 46 47 48 49
+ // 39 40 41 42 43 44 45 46 47 48 49 50
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 50 51 52
+ // 51 52 53
// fixedScalingLevel, artifactKnowledgeLevel, itemReforgeId FROM item_instance
// create item before any checks for store correct guid
@@ -761,52 +762,59 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
bonusListIDs.push_back(*bonusListID);
SetBonuses(std::move(bonusListIDs));
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::RandomPropertiesID), fields[20].GetInt32());
+ if (m_itemData->RandomPropertiesID < 0)
+ {
+ int32 propertySeed = static_cast<int32>(GenerateEnchSuffixFactor(GetEntry()));
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::PropertySeed), propertySeed);
+ }
+
// load charges after bonuses, they can add more item effects
std::vector<std::string_view> tokens = Trinity::Tokenize(fields[6].GetStringView(), ' ', false);
for (uint8 i = 0; i < m_itemData->SpellCharges.size() && i < _bonusData.EffectCount && i < tokens.size(); ++i)
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::SpellCharges, i), Trinity::StringTo<int32>(tokens[i]).value_or(0));
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, fields[20].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, fields[21].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, fields[22].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, fields[23].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, fields[24].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_5, fields[25].GetUInt32());
-
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, fields[26].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, fields[27].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, fields[28].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, fields[29].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, fields[30].GetUInt32());
- SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_5, fields[31].GetUInt32());
-
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, fields[32].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, fields[33].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, fields[34].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, fields[35].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, fields[36].GetUInt32());
- SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_5, fields[37].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, fields[21].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, fields[22].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_2, fields[23].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_3, fields[24].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_4, fields[25].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_5, fields[26].GetUInt32());
+
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_ALL_SPECS, fields[27].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_1, fields[28].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_2, fields[29].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_3, fields[30].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_4, fields[31].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION_SPEC_5, fields[32].GetUInt32());
+
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_ALL_SPECS, fields[33].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_1, fields[34].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_2, fields[35].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_3, fields[36].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_4, fields[37].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TRANSMOG_SECONDARY_APPEARANCE_SPEC_5, fields[38].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[38 + i * gemFields].GetUInt32();
- std::vector<std::string_view> gemBonusListIDs = Trinity::Tokenize(fields[39 + i * gemFields].GetStringView(), ' ', false);
+ gemData[i].ItemId = fields[39 + i * gemFields].GetUInt32();
+ std::vector<std::string_view> gemBonusListIDs = Trinity::Tokenize(fields[40 + i * gemFields].GetStringView(), ' ', false);
uint32 b = 0;
for (std::string_view token : gemBonusListIDs)
if (Optional<uint16> bonusListID = Trinity::StringTo<uint16>(token))
gemData[i].BonusListIDs[b++] = *bonusListID;
- gemData[i].Context = fields[40 + i * gemFields].GetUInt8();
+ gemData[i].Context = fields[41 + i * gemFields].GetUInt8();
if (gemData[i].ItemId)
- SetGem(i, &gemData[i], fields[41 + i * gemFields].GetUInt32());
+ SetGem(i, &gemData[i], fields[42 + i * gemFields].GetUInt32());
}
- SetModifier(ITEM_MODIFIER_TIMEWALKER_LEVEL, fields[50].GetUInt32());
- SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[51].GetUInt32());
- SetModifier(ITEM_MODIFIER_REFORGE, fields[52].GetUInt32());
+ SetModifier(ITEM_MODIFIER_TIMEWALKER_LEVEL, fields[51].GetUInt32());
+ SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[52].GetUInt32());
+ SetModifier(ITEM_MODIFIER_REFORGE, fields[53].GetUInt32());
// Enchants must be loaded after all other bonus/scaling data
std::vector<std::string_view> enchantmentTokens = Trinity::Tokenize(fields[8].GetStringView(), ' ', false);
@@ -914,6 +922,47 @@ void Item::SetItemRandomBonusList(ItemRandomBonusListId bonusListId)
AddBonuses(bonusListId);
}
+void Item::SetItemRandomEnchantment(ItemRandomPropertiesId randomPropertiesId)
+{
+ if (!randomPropertiesId)
+ return;
+
+ if (randomPropertiesId > 0)
+ {
+ // > 0 implies it's a random properties Id
+ if (ItemRandomPropertiesEntry const* randomProperties = sItemRandomPropertiesStore.LookupEntry(randomPropertiesId))
+ {
+ if (m_itemData->RandomPropertiesID != randomPropertiesId)
+ {
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::RandomPropertiesID), randomPropertiesId);
+ SetState(ITEM_CHANGED, GetOwner());
+ }
+
+ for (uint16 i = PROP_ENCHANTMENT_SLOT_0; i <= PROP_ENCHANTMENT_SLOT_4; ++i)
+ SetEnchantment(EnchantmentSlot(i), randomProperties->Enchantment[i - PROP_ENCHANTMENT_SLOT_0], 0, 0);
+ }
+ }
+ else
+ {
+ // < 0 implies it's a random Suffix
+ if (ItemRandomSuffixEntry const* randomSuffix = sItemRandomSuffixStore.LookupEntry(std::abs(randomPropertiesId)))
+ {
+ if (m_itemData->RandomPropertiesID != randomPropertiesId)
+ {
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::RandomPropertiesID), randomPropertiesId);
+ int32 propertySeed = static_cast<int32>(GenerateEnchSuffixFactor(GetEntry()));
+ if (m_itemData->PropertySeed != propertySeed)
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::PropertySeed), propertySeed);
+
+ SetState(ITEM_CHANGED, GetOwner());
+ }
+
+ for (uint16 i = PROP_ENCHANTMENT_SLOT_0; i <= PROP_ENCHANTMENT_SLOT_4; ++i)
+ SetEnchantment(EnchantmentSlot(i), randomSuffix->Enchantment[i - PROP_ENCHANTMENT_SLOT_0], 0, 0);
+ }
+ }
+}
+
void Item::SetState(ItemUpdateState state, Player* forplayer)
{
if (uState == ITEM_NEW && state == ITEM_REMOVED)
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 7b3f18c4dff..6ed742ef011 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -237,6 +237,7 @@ class TC_GAME_API Item : public Object
ItemRandomBonusListId GetItemRandomBonusListId() const { return m_randomBonusListId; }
void SetItemRandomBonusList(ItemRandomBonusListId bonusListId);
+ void SetItemRandomEnchantment(ItemRandomPropertiesId randomEnchantmentId);
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster = ObjectGuid::Empty);
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player* owner);
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
index 224a8cc6001..df142c97c8a 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
@@ -27,6 +27,12 @@
#include <list>
#include <vector>
+enum class ItemRandomEnchantmentType : uint8
+{
+ Property = 0,
+ Suffix = 1
+};
+
namespace
{
struct RandomBonusListIds
@@ -35,14 +41,22 @@ namespace
std::vector<double> Chances;
};
- std::unordered_map<uint32, RandomBonusListIds> _storage;
+ struct RandomEnchantmentIds
+ {
+ std::vector<int32> EnchantmentIDs;
+ std::vector<double> Chances;
+ };
+
+ std::unordered_map<uint32, RandomBonusListIds> _bonusListStorage;
+ std::unordered_map<uint32, RandomEnchantmentIds> _randomPropertiesStorage;
+ std::unordered_map<uint32, RandomEnchantmentIds> _randomSuffixStorage;
}
void LoadItemRandomBonusListTemplates()
{
uint32 oldMSTime = getMSTime();
- _storage.clear();
+ _bonusListStorage.clear();
// 0 1 2
QueryResult result = WorldDatabase.Query("SELECT Id, BonusListID, Chance FROM item_random_bonus_list_template");
@@ -61,7 +75,7 @@ void LoadItemRandomBonusListTemplates()
if (ItemBonusMgr::GetItemBonuses(bonusListId).empty())
{
- TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} doesn't have exist in ItemBonus.db2", bonusListId, id);
+ TC_LOG_ERROR("sql.sql", "Bonus list {} used in `item_random_bonus_list_template` by id {} doesn't exist in ItemBonus.db2", bonusListId, id);
continue;
}
@@ -71,7 +85,7 @@ void LoadItemRandomBonusListTemplates()
continue;
}
- RandomBonusListIds& ids = _storage[id];
+ RandomBonusListIds& ids = _bonusListStorage[id];
ids.BonusListIDs.push_back(bonusListId);
ids.Chances.push_back(chance);
@@ -84,6 +98,86 @@ void LoadItemRandomBonusListTemplates()
TC_LOG_INFO("server.loading", ">> Loaded 0 Random item bonus list definitions. DB table `item_random_bonus_list_template` is empty.");
}
+void LoadItemRandomEnchantmentsTemplates()
+{
+ uint32 oldMSTime = getMSTime();
+
+ _randomPropertiesStorage.clear();
+ _randomSuffixStorage.clear();
+
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT Id, EnchantmentType, EnchantmentId, Chance FROM item_random_enchantment_template");
+
+ if (result)
+ {
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 Id = fields[0].GetUInt32();
+ ItemRandomEnchantmentType enchantmentType = static_cast<ItemRandomEnchantmentType>(fields[1].GetUInt8());
+ uint32 enchantmentId = fields[2].GetUInt32();
+ float chance = fields[3].GetFloat();
+
+ switch (enchantmentType)
+ {
+ case ItemRandomEnchantmentType::Property:
+ if (!sItemRandomPropertiesStore.HasRecord(enchantmentId))
+ {
+ TC_LOG_ERROR("sql.sql", "Random properties Id {} for Id {} defined in `item_random_enchantment_template` doesn't exist in ItemRandomProperties.db2", enchantmentId, Id);
+ continue;
+ }
+ break;
+ case ItemRandomEnchantmentType::Suffix:
+ if (!sItemRandomSuffixStore.HasRecord(enchantmentId))
+ {
+ TC_LOG_ERROR("sql.sql", "Random suffix Id {} for Id {} defined in `item_random_enchantment_template` doesn't exist in ItemRandomSuffix.db2", enchantmentId, Id);
+ continue;
+ }
+ break;
+ default:
+ TC_LOG_ERROR("sql.sql", "Invalid random enchantment type specified in `item_random_enchantment_template` table for `Id` {} `EnchantmentId` {}", Id, enchantmentId);
+ break;
+ }
+
+ if (chance < 0.000001f || chance > 100.0f)
+ {
+ TC_LOG_ERROR("sql.sql", "Random enchantment Id {} used in `item_random_enchantment_template` by Id {} and Type {} has an invalid chance {}", enchantmentId, Id, AsUnderlyingType(enchantmentType), chance);
+ continue;
+ }
+
+ switch (enchantmentType)
+ {
+ case ItemRandomEnchantmentType::Property:
+ {
+ RandomEnchantmentIds& randomProperties = _randomPropertiesStorage[Id];
+ randomProperties.EnchantmentIDs.push_back(enchantmentId);
+ randomProperties.Chances.push_back(chance);
+ break;
+ }
+ case ItemRandomEnchantmentType::Suffix:
+ {
+ RandomEnchantmentIds& randomSuffix = _randomSuffixStorage[Id];
+ randomSuffix.EnchantmentIDs.push_back(enchantmentId);
+ randomSuffix.Chances.push_back(chance);
+ break;
+ }
+ default:
+ break;
+ }
+
+ ++count;
+
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded {} Random item random enchantment definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
+ else
+ TC_LOG_INFO("server.loading", ">> Loaded 0 Random item random enchantment definitions. DB table `item_random_enchantment_template` is empty.");
+
+}
+
ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
@@ -94,8 +188,8 @@ ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
if (!itemProto->RandomBonusListTemplateId)
return 0;
- auto tab = _storage.find(itemProto->RandomBonusListTemplateId);
- if (tab == _storage.end())
+ auto tab = _bonusListStorage.find(itemProto->RandomBonusListTemplateId);
+ if (tab == _bonusListStorage.end())
{
TC_LOG_ERROR("sql.sql", "Item RandomBonusListTemplateId id #{} used in `item_template_addon` but it does not have records in `item_random_bonus_list_template` table.", itemProto->RandomBonusListTemplateId);
return 0;
@@ -104,9 +198,64 @@ ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id)
return *Trinity::Containers::SelectRandomWeightedContainerElement(tab->second.BonusListIDs, std::span(tab->second.Chances));
}
-TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
+TC_GAME_API ItemRandomPropertiesId GenerateItemRandomPropertiesId(uint32 item_id)
+{
+ ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
+ if (!itemProto)
+ return 0;
+
+ uint16 randomSelect = itemProto->GetRandomSelect();
+ uint16 randomSuffix = itemProto->GetItemRandomSuffixGroupID();
+
+ if (!randomSelect && !randomSuffix)
+ return 0;
+
+ // An item cannot have random properties and suffix at the same time
+ if (randomSelect && randomSuffix)
+ {
+ TC_LOG_ERROR("sql.sql", "Item (Id: {} has RandomSelect and ItemRandomSuffixGroupID values which is not allowed!", itemProto->GetId());
+ return 0;
+ }
+
+ if (randomSelect)
+ {
+ auto tab = _randomPropertiesStorage.find(randomSelect);
+ if (tab == _randomPropertiesStorage.end())
+ {
+ TC_LOG_ERROR("sql.sql", "RandomSelect Id {} used does not have any data defined in `item_random_enchantment_template`tabel.", itemProto->GetRandomSelect());
+ return 0;
+ }
+
+ return *Trinity::Containers::SelectRandomWeightedContainerElement(tab->second.EnchantmentIDs, std::span(tab->second.Chances));
+ }
+
+ if (randomSuffix)
+ {
+ auto tab = _randomSuffixStorage.find(randomSuffix);
+ if (tab == _randomSuffixStorage.end())
+ {
+ TC_LOG_ERROR("sql.sql", "RandomSuffixGroup Id {} used does not have any data defined in `item_random_enchantment_template`tabel.", itemProto->GetRandomSelect());
+ return 0;
+ }
+
+ return -*Trinity::Containers::SelectRandomWeightedContainerElement(tab->second.EnchantmentIDs, std::span(tab->second.Chances));
+ }
+
+ return 0;
+}
+
+TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id)
+{
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item_id);
+ if (!proto || !proto->GetItemRandomSuffixGroupID())
+ return 0;
+
+ return GetRandomPropertyPoints(proto->GetBaseItemLevel(), proto->GetQuality(), proto->GetInventoryType(), proto->GetSubClass());
+}
+
+TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
{
- uint32 propIndex;
+ uint32 propIndex = 0;
switch (inventoryType)
{
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.h b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
index 5c8f524a125..73fa04535a0 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.h
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
@@ -21,9 +21,13 @@
#include "Common.h"
using ItemRandomBonusListId = uint32;
+using ItemRandomPropertiesId = int32;
TC_GAME_API void LoadItemRandomBonusListTemplates();
+TC_GAME_API void LoadItemRandomEnchantmentsTemplates();
TC_GAME_API ItemRandomBonusListId GenerateItemRandomBonusListId(uint32 item_id);
-TC_GAME_API float GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subclass);
+TC_GAME_API ItemRandomPropertiesId GenerateItemRandomPropertiesId(uint32 item_id);
+TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id);
+TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subclass);
#endif
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 295656bce9e..1f068a0ef96 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -585,7 +585,7 @@ bool Player::StoreNewItemInBestSlots(uint32 itemId, uint32 amount, ItemContext c
InventoryResult msg = CanStoreNewItem(INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, itemId, amount);
if (msg == EQUIP_ERR_OK)
{
- StoreNewItem(sDest, itemId, true, GenerateItemRandomBonusListId(itemId), GuidSet(), context);
+ StoreNewItem(sDest, itemId, true, GenerateItemRandomBonusListId(itemId), GenerateItemRandomPropertiesId(itemId), GuidSet(), context);
return true; // stored
}
@@ -3526,7 +3526,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
do
{
Field* fields = resultItems->Fetch();
- uint64 mailId = fields[54].GetUInt64();
+ uint64 mailId = fields[55].GetUInt64();
if (Item* mailItem = _LoadMailedItem(playerguid, nullptr, mailId, nullptr, fields))
itemsByMail[mailId].push_back(mailItem);
@@ -10685,7 +10685,7 @@ InventoryResult Player::CanRollNeedForItem(ItemTemplate const* proto, Map const*
}
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case.
-Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId /*= 0*/,
+Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId /*= 0*/, ItemRandomPropertiesId randomEnchantmentId /*= 0*/,
GuidSet const& allowedLooters /*= GuidSet()*/, ItemContext context /*= ItemContext::NONE*/,
std::vector<int32> const* bonusListIDs /*= std::vector<int32>()*/, bool addToCollection /*= true*/)
{
@@ -10703,6 +10703,7 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
item->SetFixedLevel(GetLevel());
item->SetItemRandomBonusList(randomBonusListId);
+ item->SetItemRandomEnchantment(randomEnchantmentId);
item->SetCreatePlayedTime(GetTotalPlayedTime());
item = StoreItem(pos, item, update);
@@ -10738,7 +10739,7 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
{
ItemPosCountVec childDest;
CanStoreItem_InInventorySlots(CHILD_EQUIPMENT_SLOT_START, CHILD_EQUIPMENT_SLOT_END, childDest, childTemplate, count, false, nullptr, NULL_BAG, NULL_SLOT);
- if (Item* childItem = StoreNewItem(childDest, childTemplate->GetId(), update, {}, {}, context, nullptr, addToCollection))
+ if (Item* childItem = StoreNewItem(childDest, childTemplate->GetId(), update, {}, {}, {}, context, nullptr, addToCollection))
{
childItem->SetCreator(item->GetGUID());
childItem->SetItemFlag(ITEM_FIELD_FLAG_CHILD);
@@ -12917,8 +12918,23 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
for (int s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s)
{
uint32 enchant_display_type = pEnchant->Effect[s];
- uint32 enchant_amount = pEnchant->EffectPointsMin[s];
uint32 enchant_spell_id = pEnchant->EffectArg[s];
+ uint32 enchant_amount = pEnchant->EffectPointsMin[s];;
+
+ if (enchant_amount == 0 && slot >= PROP_ENCHANTMENT_SLOT_0 && slot <= PROP_ENCHANTMENT_SLOT_4)
+ {
+ if (ItemRandomSuffixEntry const* suffix = sItemRandomSuffixStore.LookupEntry(std::abs(item->m_itemData->RandomPropertiesID)))
+ {
+ for (size_t i = 0; i < suffix->Enchantment.size(); ++i)
+ {
+ if (suffix->Enchantment[i] == static_cast<int32>(enchant_id))
+ {
+ enchant_amount = suffix->AllocationPct[i] * item->m_itemData->PropertySeed / 10000;
+ break;
+ }
+ }
+ }
+ }
switch (enchant_display_type)
{
@@ -14223,7 +14239,7 @@ void Player::RewardQuestPackage(uint32 questPackageId, ItemContext context, uint
ItemPosCountVec dest;
if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemQuantity) == EQUIP_ERR_OK)
{
- Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, GenerateItemRandomBonusListId(questPackageItem->ItemID), {}, context);
+ Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, GenerateItemRandomBonusListId(questPackageItem->ItemID), GenerateItemRandomPropertiesId(questPackageItem->ItemID), {}, context);
SendNewItem(item, questPackageItem->ItemQuantity, true, false);
}
}
@@ -14242,7 +14258,7 @@ void Player::RewardQuestPackage(uint32 questPackageId, ItemContext context, uint
ItemPosCountVec dest;
if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemQuantity) == EQUIP_ERR_OK)
{
- Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, GenerateItemRandomBonusListId(questPackageItem->ItemID), {}, context);
+ Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, GenerateItemRandomBonusListId(questPackageItem->ItemID), GenerateItemRandomPropertiesId(questPackageItem->ItemID), {}, context);
SendNewItem(item, questPackageItem->ItemQuantity, true, false);
}
}
@@ -14302,7 +14318,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
ItemPosCountVec dest;
if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, quest->RewardItemCount[i]) == EQUIP_ERR_OK)
{
- Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), {}, ItemContext::Quest_Reward);
+ Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GenerateItemRandomPropertiesId(itemId), {}, ItemContext::Quest_Reward);
SendNewItem(item, quest->RewardItemCount[i], true, false);
}
else if (quest->IsDFQuest())
@@ -14347,7 +14363,7 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew
ItemPosCountVec dest;
if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, rewardId, quest->RewardChoiceItemCount[i]) == EQUIP_ERR_OK)
{
- Item* item = StoreNewItem(dest, rewardId, true, GenerateItemRandomBonusListId(rewardId), {}, ItemContext::Quest_Reward);
+ Item* item = StoreNewItem(dest, rewardId, true, GenerateItemRandomBonusListId(rewardId), GenerateItemRandomPropertiesId(rewardId), {}, ItemContext::Quest_Reward);
SendNewItem(item, quest->RewardChoiceItemCount[i], true, false);
}
}
@@ -17855,21 +17871,21 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
- // 14 15 16 17 18 19
- // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 20 21 22 23 24 25
+ // 14 15 16 17 18 19 20
+ // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, randomPropertiesId,
+ // 21 22 23 24 25 26
// itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
- // 26 27 28 29 30 31
+ // 27 28 29 30 31 32
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
- // 32 33 34
+ // 33 34 35
// secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
- // 35 36 37
+ // 36 37 38
// secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
- // 38 39 40 41 42 43 44 45 46 47 48 49
+ // 39 40 41 42 43 44 45 46 47 48 49 50
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 50 51 52
+ // 51 52 53
// fixedScalingLevel, artifactKnowledgeLevel, itemReforgeId FROM item_instance
- // 53 54
+ // 54 55
// bag, slot
// FROM character_inventory ci
// JOIN item_instance ii ON ci.item = ii.guid
@@ -17901,8 +17917,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
Field* fields = result->Fetch();
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
{
- ObjectGuid bagGuid = fields[53].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[53].GetUInt64()) : ObjectGuid::Empty;
- uint8 slot = fields[54].GetUInt8();
+ ObjectGuid bagGuid = fields[54].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[53].GetUInt64()) : ObjectGuid::Empty;
+ uint8 slot = fields[55].GetUInt8();
GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
GetSession()->GetCollectionMgr()->AddItemAppearance(item);
@@ -18233,7 +18249,7 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint
Item* item = NewItemOrBag(proto);
- ObjectGuid ownerGuid = fields[53].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[53].GetUInt64()) : ObjectGuid::Empty;
+ ObjectGuid ownerGuid = fields[54].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[54].GetUInt64()) : ObjectGuid::Empty;
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
{
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: {}) in mail ({}) doesn't exist, deleted from mail.", itemGuid, mailId);
@@ -18302,7 +18318,7 @@ void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mail
do
{
Field* fields = mailItemsResult->Fetch();
- uint64 mailId = fields[54].GetUInt64();
+ uint64 mailId = fields[55].GetUInt64();
_LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], fields);
} while (mailItemsResult->NextRow());
}
@@ -21924,7 +21940,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
}
Item* it = bStore ?
- StoreNewItem(vDest, item, true, GenerateItemRandomBonusListId(item), {}, ItemContext::Vendor, &crItem->BonusListIDs, false) :
+ StoreNewItem(vDest, item, true, GenerateItemRandomBonusListId(item), GenerateItemRandomPropertiesId(item), {}, ItemContext::Vendor, &crItem->BonusListIDs, false) :
EquipNewItem(uiDest, item, ItemContext::Vendor, true);
if (it)
{
@@ -25573,7 +25589,7 @@ void Player::StoreLootItem(ObjectGuid lootWorldObjectGuid, uint8 lootSlot, Loot*
return;
}
- Item* newitem = StoreNewItem(dest, item->itemid, true, item->randomBonusListId, item->GetAllowedLooters(), item->context);
+ Item* newitem = StoreNewItem(dest, item->itemid, true, item->randomBonusListId, item->randomPropertiesId, item->GetAllowedLooters(), item->context);
if (sObjectMgr->GetItemTemplate(item->itemid))
if (newitem->GetQuality() > ITEM_QUALITY_EPIC || (newitem->GetQuality() == ITEM_QUALITY_EPIC && newitem->GetItemLevel(this) >= MinNewsItemLevel))
@@ -26658,7 +26674,7 @@ bool Player::AddItem(uint32 itemId, uint32 count)
return false;
}
- Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId));
+ Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GenerateItemRandomPropertiesId(itemId));
if (item)
SendNewItem(item, count, true, false);
else
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 698d8eff36c..32ba39828c5 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1403,7 +1403,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem, bool skipRequiredLevelCheck = false) const;
InventoryResult CanRollNeedForItem(ItemTemplate const* item, Map const* map, bool restrictOnlyLfg) const;
- Item* StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId = 0, GuidSet const& allowedLooters = GuidSet(),
+ Item* StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, ItemRandomBonusListId randomBonusListId = 0, ItemRandomPropertiesId randomEnchantmentId = 0, GuidSet const& allowedLooters = GuidSet(),
ItemContext context = ItemContext::NONE, std::vector<int32> const* bonusListIDs = nullptr, bool addToCollection = true);
Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update);
Item* EquipNewItem(uint16 pos, uint32 item, ItemContext context, bool update);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index ac91cf6a929..809b6ad42a7 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -377,7 +377,7 @@ void Guild::BankTab::LoadFromDB(Field* fields)
bool Guild::BankTab::LoadItemFromDB(Field* fields)
{
- uint8 slotId = fields[55].GetUInt8();
+ uint8 slotId = fields[56].GetUInt8();
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
uint32 itemEntry = fields[1].GetUInt32();
if (slotId >= GUILD_BANK_MAX_SLOTS)
@@ -2640,7 +2640,7 @@ void Guild::LoadBankTabFromDB(Field* fields)
bool Guild::LoadBankItemFromDB(Field* fields)
{
- uint8 tabId = fields[54].GetUInt8();
+ uint8 tabId = fields[55].GetUInt8();
if (tabId >= _GetPurchasedTabsSize())
{
TC_LOG_ERROR("guild", "Invalid tab for item (GUID: {}, id: #{}) in guild bank, skipped.",
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index a086a9f7c45..ba6ba74ac65 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -403,21 +403,21 @@ void GuildMgr::LoadGuilds()
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomBonusListId, durability, playedTime, createTime, text,
- // 14 15 16 17 18 19
- // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs,
- // 20 21 22 23 24 25
+ // 14 15 16 17 18 19 20
+ // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, context, bonusListIDs, randomPropertiesId,
+ // 21 22 23 24 25 26
// itemModifiedAppearanceAllSpecs, itemModifiedAppearanceSpec1, itemModifiedAppearanceSpec2, itemModifiedAppearanceSpec3, itemModifiedAppearanceSpec4, itemModifiedAppearanceSpec5,
- // 26 27 28 29 30 31
+ // 27 28 29 30 31 32
// spellItemEnchantmentAllSpecs, spellItemEnchantmentSpec1, spellItemEnchantmentSpec2, spellItemEnchantmentSpec3, spellItemEnchantmentSpec4, spellItemEnchantmentSpec5,
- // 32 33 34
+ // 33 34 35
// secondaryItemModifiedAppearanceAllSpecs, secondaryItemModifiedAppearanceSpec1, secondaryItemModifiedAppearanceSpec2,
- // 35 36 37
+ // 36 37 38
// secondaryItemModifiedAppearanceSpec3, secondaryItemModifiedAppearanceSpec4, secondaryItemModifiedAppearanceSpec5,
- // 38 39 40 41 42 43 44 45 46 47 48 49
+ // 39 40 41 42 43 44 45 46 47 48 49 50
// gemItemId1, gemBonuses1, gemContext1, gemScalingLevel1, gemItemId2, gemBonuses2, gemContext2, gemScalingLevel2, gemItemId3, gemBonuses3, gemContext3, gemScalingLevel3
- // 50 51 52
+ // 51 52 53
// fixedScalingLevel, artifactKnowledgeLevel, itemReforgeId
- // 53 54 55
+ // 54 55 56
// guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS));
@@ -431,7 +431,7 @@ void GuildMgr::LoadGuilds()
do
{
Field* fields = result->Fetch();
- uint64 guildId = fields[53].GetUInt64();
+ uint64 guildId = fields[54].GetUInt64();
if (Guild* guild = GetGuildById(guildId))
guild->LoadBankItemFromDB(fields);
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 8b70eaf7571..65bb92b8580 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -470,7 +470,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPackets::Loot::MasterLootItem
}
// now move item from loot to target inventory
- Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, &item.BonusListIDs);
+ Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.randomPropertiesId, item.GetAllowedLooters(), item.context, &item.BonusListIDs);
aeResult.Add(newitem, item.count, loot->loot_type, loot->GetDungeonEncounterId());
// mark as looted
diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp
index cafa7070c3e..79c1ca2522c 100644
--- a/src/server/game/Handlers/VoidStorageHandler.cpp
+++ b/src/server/game/Handlers/VoidStorageHandler.cpp
@@ -187,7 +187,7 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor
return;
}
- Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->RandomBonusListId, GuidSet(), itemVS->Context, &itemVS->BonusListIDs);
+ Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->RandomBonusListId, {}, GuidSet(), itemVS->Context, &itemVS->BonusListIDs);
item->SetCreator(itemVS->CreatorGuid);
item->SetBinding(true);
GetCollectionMgr()->AddItemAppearance(item);
diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp
index 37012bc23f7..df0110210c9 100644
--- a/src/server/game/Loot/Loot.cpp
+++ b/src/server/game/Loot/Loot.cpp
@@ -47,6 +47,11 @@ LootItem::LootItem(LootStoreItem const& li) : itemid(li.itemid), conditions(li.c
case LootStoreItem::Type::Item:
{
randomBonusListId = GenerateItemRandomBonusListId(itemid);
+ randomPropertiesId = GenerateItemRandomPropertiesId(itemid);
+ if (randomPropertiesId < 0)
+ if (int32 propertySeed = static_cast<int32>(GenerateEnchSuffixFactor(itemid)))
+ randomPropertiesSeed = propertySeed;
+
type = LootItemType::Item;
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid);
freeforall = proto && proto->HasFlag(ITEM_FLAG_MULTI_DROP);
@@ -975,7 +980,7 @@ bool Loot::AutoStore(Player* player, uint8 bag, uint8 slot, bool broadcast, bool
continue;
}
- if (Item* pItem = player->StoreNewItem(dest, lootItem->itemid, true, lootItem->randomBonusListId, GuidSet(), lootItem->context, &lootItem->BonusListIDs))
+ if (Item* pItem = player->StoreNewItem(dest, lootItem->itemid, true, lootItem->randomBonusListId, lootItem->randomPropertiesId, GuidSet(), lootItem->context, &lootItem->BonusListIDs))
{
player->SendNewItem(pItem, lootItem->count, false, createdByPlayer, broadcast, GetDungeonEncounterId());
player->ApplyItemLootedSpell(pItem, true);
diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h
index 9e5703aa8c6..dae5899b302 100644
--- a/src/server/game/Loot/Loot.h
+++ b/src/server/game/Loot/Loot.h
@@ -178,6 +178,8 @@ struct TC_GAME_API LootItem
uint32 itemid = 0;
uint32 LootListId = 0;
ItemRandomBonusListId randomBonusListId = 0;
+ ItemRandomPropertiesId randomPropertiesId = 0;
+ int32 randomPropertiesSeed = 0;
std::vector<int32> BonusListIDs;
ItemContext context = ItemContext::NONE;
ConditionsReference conditions; // additional loot condition
diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.cpp b/src/server/game/Server/Packets/ItemPacketsCommon.cpp
index 961b387f8fd..5cc7ac1b958 100644
--- a/src/server/game/Server/Packets/ItemPacketsCommon.cpp
+++ b/src/server/game/Server/Packets/ItemPacketsCommon.cpp
@@ -57,6 +57,9 @@ void ItemInstance::Initialize(::Item const* item)
ItemBonus->Context = item->GetContext();
}
+ RandomPropertiesID = item->m_itemData->RandomPropertiesID;
+ RandomPropertiesSeed = item->m_itemData->PropertySeed;
+
for (UF::ItemMod mod : item->m_itemData->Modifiers->Values)
Modifications.Values.emplace_back(mod.Value, ItemModifier(mod.Type));
}
@@ -87,6 +90,9 @@ void ItemInstance::Initialize(::LootItem const& lootItem)
if (lootItem.randomBonusListId)
ItemBonus->BonusListIDs.push_back(lootItem.randomBonusListId);
}
+
+ RandomPropertiesID = lootItem.randomPropertiesId;
+ RandomPropertiesSeed = lootItem.randomPropertiesSeed;
}
void ItemInstance::Initialize(::VoidStorageItem const* voidItem)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 64519264db8..8e10a21c7bf 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1370,7 +1370,7 @@ void Spell::DoCreateItem(uint32 itemId, ItemContext context /*= ItemContext::NON
if (num_to_add)
{
// create the new item and store it
- Item* pItem = player->StoreNewItem(dest, newitemid, true, GenerateItemRandomBonusListId(newitemid), GuidSet(), context, bonusListIDs);
+ Item* pItem = player->StoreNewItem(dest, newitemid, true, GenerateItemRandomBonusListId(newitemid), GenerateItemRandomPropertiesId(newitemid), GuidSet(), context, bonusListIDs);
// was it successful? return error if not
if (!pItem)
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index dafe66aa451..babecd2bc40 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1931,6 +1931,9 @@ bool World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Random item bonus list definitions...");
LoadItemRandomBonusListTemplates();
+ TC_LOG_INFO("server.loading", "Loading Random item enchantment definitions...");
+ LoadItemRandomEnchantmentsTemplates();
+
TC_LOG_INFO("server.loading", "Loading Disables"); // must be before loading quests and items
DisableMgr::LoadDisables();
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index c9dda180791..e661af2dbeb 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1254,7 +1254,7 @@ public:
return false;
}
- Item* item = playerTarget->StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GuidSet(), itemContext,
+ Item* item = playerTarget->StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GenerateItemRandomPropertiesId(itemId), GuidSet(), itemContext,
bonusListIDs.empty() ? nullptr : &bonusListIDs);
// remove binding (let GM give it to another player later)
@@ -1348,7 +1348,7 @@ public:
bonusListIDsForItem.insert(bonusListIDsForItem.begin(), contextBonuses.begin(), contextBonuses.end());
}
- Item* item = playerTarget->StoreNewItem(dest, itemTemplatePair.first, true, {}, GuidSet(), itemContext,
+ Item* item = playerTarget->StoreNewItem(dest, itemTemplatePair.first, true, {}, {}, GuidSet(), itemContext,
bonusListIDsForItem.empty() ? nullptr : &bonusListIDsForItem);
if (!item)
continue;
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index 861fbc00a43..c37baad08ae 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -118,7 +118,7 @@ public:
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 39883, 1); // Cracked Egg
if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, 39883, true, GenerateItemRandomBonusListId(39883));
+ player->StoreNewItem(dest, 39883, true, GenerateItemRandomBonusListId(39883), GenerateItemRandomPropertiesId(39883));
return true;
}
@@ -138,7 +138,7 @@ public:
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 44718, 1); // Ripe Disgusting Jar
if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, 44718, true, GenerateItemRandomBonusListId(44718));
+ player->StoreNewItem(dest, 44718, true, GenerateItemRandomBonusListId(44718), GenerateItemRandomPropertiesId(44718));
return true;
}