aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp2
-rw-r--r--src/server/game/DataStores/DBCEnums.h36
-rw-r--r--src/server/game/Entities/Item/Item.cpp71
-rw-r--r--src/server/game/Entities/Item/Item.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp7
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp4
6 files changed, 86 insertions, 41 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index cc0f56a3ce4..3c9cebc3950 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -704,7 +704,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::Aucti
if (quality != 0xffffffff && proto->GetQuality() != quality)
continue;
- if (levelmin != 0 && (proto->GetBaseRequiredLevel() < levelmin || (levelmax != 0 && proto->GetBaseRequiredLevel() > levelmax)))
+ if (levelmin != 0 && (item->GetRequiredLevel() < levelmin || (levelmax != 0 && item->GetRequiredLevel() > levelmax)))
continue;
if (usable && player->CanUseItem(item) != EQUIP_ERR_OK)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 92b8d0128c4..7807bb5538e 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -714,24 +714,24 @@ enum ItemExtendedCostFlags
enum ItemBonusType
{
- ITEM_BONUS_ITEM_LEVEL = 1,
- ITEM_BONUS_STAT = 2,
- ITEM_BONUS_QUALITY = 3,
- ITEM_BONUS_DESCRIPTION = 4,
- ITEM_BONUS_SUFFIX = 5,
- ITEM_BONUS_SOCKET = 6,
- ITEM_BONUS_APPEARANCE = 7,
- ITEM_BONUS_REQUIRED_LEVEL = 8,
- ITEM_BONUS_DISPLAY_TOAST_METHOD = 9,
- ITEM_BONUS_REPAIR_COST_MULTIPLIER = 10,
- ITEM_BONUS_SCALING_STAT_DISTRIBUTION = 11,
- ITEM_BONUS_DISENCHANT_LOOT_ID = 12,
- ITEM_BONUS_SCALING_STAT_DISTRIBUTION_2 = 13,
- ITEM_BONUS_ITEM_LEVEL_CAN_INCREASE = 14, // Displays a + next to item level indicating it can warforge
- ITEM_BONUS_RANDOM_ENCHANTMENT = 15, // Responsible for showing "<Random additional stats>" or "+%d Rank Random Minor Trait" in the tooltip before item is obtained
- ITEM_BONUS_BONDING = 16,
- ITEM_BONUS_RELIC_TYPE = 17,
- ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18
+ ITEM_BONUS_ITEM_LEVEL = 1,
+ ITEM_BONUS_STAT = 2,
+ ITEM_BONUS_QUALITY = 3,
+ ITEM_BONUS_DESCRIPTION = 4,
+ ITEM_BONUS_SUFFIX = 5,
+ ITEM_BONUS_SOCKET = 6,
+ ITEM_BONUS_APPEARANCE = 7,
+ ITEM_BONUS_REQUIRED_LEVEL = 8,
+ ITEM_BONUS_DISPLAY_TOAST_METHOD = 9,
+ ITEM_BONUS_REPAIR_COST_MULTIPLIER = 10,
+ ITEM_BONUS_SCALING_STAT_DISTRIBUTION = 11,
+ ITEM_BONUS_DISENCHANT_LOOT_ID = 12,
+ ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED = 13,
+ ITEM_BONUS_ITEM_LEVEL_CAN_INCREASE = 14, // Displays a + next to item level indicating it can warforge
+ ITEM_BONUS_RANDOM_ENCHANTMENT = 15, // Responsible for showing "<Random additional stats>" or "+%d Rank Random Minor Trait" in the tooltip before item is obtained
+ ITEM_BONUS_BONDING = 16,
+ ITEM_BONUS_RELIC_TYPE = 17,
+ ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18
};
enum ItemLimitCategoryMode
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6f2526de7de..71bc71f9430 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -684,18 +684,6 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetUInt32Value(ITEM_FIELD_FLAGS, itemFlags);
- _LoadIntoDataField(fields[8].GetString(), ITEM_FIELD_ENCHANTMENT, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
- m_randomEnchantment.Type = ItemRandomEnchantmentType(fields[9].GetUInt8());
- m_randomEnchantment.Id = fields[10].GetUInt32();
- if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Property)
- SetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, m_randomEnchantment.Id);
- else if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Suffix)
- {
- SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(m_randomEnchantment.Id));
- // recalculate suffix factor
- UpdateItemSuffixFactor();
- }
-
uint32 durability = fields[11].GetUInt16();
SetUInt32Value(ITEM_FIELD_DURABILITY, durability);
// update max durability (and durability) if need
@@ -771,6 +759,19 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, fields[43].GetUInt32());
SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[44].GetUInt32());
+ // Enchants must be loaded after all other bonus/scaling data
+ _LoadIntoDataField(fields[8].GetString(), ITEM_FIELD_ENCHANTMENT, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
+ m_randomEnchantment.Type = ItemRandomEnchantmentType(fields[9].GetUInt8());
+ m_randomEnchantment.Id = fields[10].GetUInt32();
+ if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Property)
+ SetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, m_randomEnchantment.Id);
+ else if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Suffix)
+ {
+ SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(m_randomEnchantment.Id));
+ // recalculate suffix factor
+ UpdateItemSuffixFactor();
+ }
+
// Remove bind flag for items vs BIND_NONE set
if (IsSoulBound() && GetBonding() == BIND_NONE)
{
@@ -892,7 +893,7 @@ ItemTemplate const* Item::GetTemplate() const
return sObjectMgr->GetItemTemplate(GetEntry());
}
-Player* Item::GetOwner()const
+Player* Item::GetOwner() const
{
return ObjectAccessor::FindPlayer(GetOwnerGUID());
}
@@ -947,7 +948,15 @@ void Item::SetItemRandomProperties(ItemRandomEnchantmentId const& randomPropId)
void Item::UpdateItemSuffixFactor()
{
- uint32 suffixFactor = GenerateEnchSuffixFactor(GetEntry());
+ if (!GetTemplate()->GetRandomSuffix())
+ return;
+
+ uint32 suffixFactor = 0;
+ if (Player* owner = GetOwner())
+ suffixFactor = GetRandomPropertyPoints(GetItemLevel(owner), GetQuality(), GetTemplate()->GetInventoryType(), GetTemplate()->GetSubClass());
+ else
+ suffixFactor = GenerateEnchSuffixFactor(GetEntry());
+
if (GetItemSuffixFactor() == suffixFactor)
return;
SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, suffixFactor);
@@ -2555,6 +2564,33 @@ void Item::GiveArtifactXp(uint64 amount, Item* sourceItem, uint32 artifactCatego
SetState(ITEM_CHANGED, owner);
}
+void Item::SetFixedLevel(uint8 level)
+{
+ if (!_bonusData.HasFixedLevel || GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL))
+ return;
+
+ if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(_bonusData.ScalingStatDistribution))
+ {
+ level = std::min(std::max(int32(level), ssd->MinLevel), ssd->MaxLevel);
+
+ if (SandboxScalingEntry const* sandbox = sSandboxScalingStore.LookupEntry(_bonusData.SandboxScalingId))
+ if ((sandbox->Flags & 2 || sandbox->MinLevel || sandbox->MaxLevel) && !(sandbox->Flags & 4))
+ level = std::min(std::max(int32(level), sandbox->MinLevel), sandbox->MaxLevel);
+
+ SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, level);
+ }
+}
+
+int32 Item::GetRequiredLevel() const
+{
+ if (_bonusData.RequiredLevelOverride)
+ return _bonusData.RequiredLevelOverride;
+ else if (_bonusData.HasFixedLevel)
+ return GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL);
+ else
+ return _bonusData.RequiredLevel;
+}
+
void BonusData::Initialize(ItemTemplate const* proto)
{
Quality = proto->GetQuality();
@@ -2588,6 +2624,8 @@ void BonusData::Initialize(ItemTemplate const* proto)
SandboxScalingId = 0;
RelicType = -1;
HasItemLevelBonus = false;
+ HasFixedLevel = false;
+ RequiredLevelOverride = 0;
_state.AppearanceModPriority = std::numeric_limits<int32>::max();
_state.ScalingStatDistributionPriority = std::numeric_limits<int32>::max();
@@ -2667,12 +2705,13 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
RepairCostMultiplier *= static_cast<float>(values[0]) * 0.01f;
break;
case ITEM_BONUS_SCALING_STAT_DISTRIBUTION:
- case ITEM_BONUS_SCALING_STAT_DISTRIBUTION_2:
+ case ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED:
if (values[1] < _state.ScalingStatDistributionPriority)
{
ScalingStatDistribution = static_cast<uint32>(values[0]);
SandboxScalingId = static_cast<uint32>(values[2]);
_state.ScalingStatDistributionPriority = values[1];
+ HasFixedLevel = type == ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED;
}
break;
case ITEM_BONUS_BONDING:
@@ -2682,7 +2721,7 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
RelicType = values[0];
break;
case ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL:
- RequiredLevel = values[0];
+ RequiredLevelOverride = values[0];
break;
}
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index ed3abe13c50..d795983b4ed 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -92,7 +92,9 @@ struct BonusData
int32 GemRelicType[MAX_ITEM_PROTO_SOCKETS];
uint16 GemRelicRankBonus[MAX_ITEM_PROTO_SOCKETS];
int32 RelicType;
+ int32 RequiredLevelOverride;
bool HasItemLevelBonus;
+ bool HasFixedLevel;
void Initialize(ItemTemplate const* proto);
void Initialize(WorldPackets::Item::ItemInstance const& itemInstance);
@@ -142,7 +144,7 @@ class TC_GAME_API Item : public Object
ObjectGuid GetOwnerGUID() const { return GetGuidValue(ITEM_FIELD_OWNER); }
void SetOwnerGUID(ObjectGuid guid) { SetGuidValue(ITEM_FIELD_OWNER, guid); }
- Player* GetOwner()const;
+ Player* GetOwner() const;
ItemBondingType GetBonding() const { return _bonusData.Bonding; }
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, val); }
@@ -264,7 +266,7 @@ class TC_GAME_API Item : public Object
uint32 GetItemLevel(Player const* owner) const;
static uint32 GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bonusData, uint32 level, uint32 fixedLevel, uint32 upgradeId,
uint32 minItemLevel, uint32 minItemLevelCutoff, uint32 maxItemLevel, bool pvpBonus);
- int32 GetRequiredLevel() const { return _bonusData.RequiredLevel; }
+ int32 GetRequiredLevel() const;
int32 GetItemStatType(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_STATS); return _bonusData.ItemStatType[index]; }
int32 GetItemStatValue(uint32 index, Player const* owner) const;
SocketColor GetSocketColor(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_SOCKETS); return SocketColor(_bonusData.SocketColor[index]); }
@@ -278,6 +280,7 @@ class TC_GAME_API Item : public Object
uint32 GetScalingStatDistribution() const { return _bonusData.ScalingStatDistribution; }
ItemDisenchantLootEntry const* GetDisenchantLoot(Player const* owner) const;
static ItemDisenchantLootEntry const* GetDisenchantLoot(ItemTemplate const* itemTemplate, uint32 quality, uint32 itemLevel);
+ void SetFixedLevel(uint8 level);
// Item Refund system
void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = nullptr, bool addToCollection = true);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 531b3bb16a0..d02a812bbb8 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -11570,6 +11570,9 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
if (pItem->IsBindedNotWith(this))
return EQUIP_ERR_NOT_OWNER;
+ if (getLevel() < pItem->GetRequiredLevel())
+ return EQUIP_ERR_CANT_EQUIP_LEVEL_I;
+
InventoryResult res = CanUseItem(pProto);
if (res != EQUIP_ERR_OK)
return res;
@@ -11744,7 +11747,6 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
UpdateCriteria(CRITERIA_TYPE_OWN_ITEM, itemId, 1);
item->SetFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_NEW_ITEM);
- item->SetItemRandomProperties(randomPropertyId);
if (uint32 upgradeID = sDB2Manager.GetRulesetItemUpgrade(itemId))
item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, upgradeID);
@@ -11755,6 +11757,9 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
item = StoreItem(pos, item, update);
+ item->SetFixedLevel(getLevel());
+ item->SetItemRandomProperties(randomPropertyId);
+
if (allowedLooters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound())
{
item->SetSoulboundTradeable(allowedLooters);
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index ce83e861e6d..0ba24d95ac9 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -529,9 +529,7 @@ void WorldSession::HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet)
{
_player->ModifyMoney(-(int32)price);
_player->RemoveItemFromBuyBackSlot(packet.Slot, false);
- _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
- _player->UpdateCriteria(CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
- _player->StoreItem(dest, pItem, true);
+ _player->MoveItemToInventory(dest, pItem, true);
}
else
_player->SendEquipError(msg, pItem, NULL);