aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Item
diff options
context:
space:
mode:
authorRoc13x <roc13x@gmail.com>2018-04-28 12:40:00 +0100
committerShauren <shauren.trinity@gmail.com>2018-04-28 14:40:00 +0300
commitb9b661da08b22a5d070eff9d2032dfd993a8b009 (patch)
treee94014906f8041391dafc6a6ebb7c365d224e59b /src/server/game/Entities/Item
parent45b2492aa0e5da95a8d9ae1483dbcd717898008c (diff)
Core/Items: Add loot scaling support (#21853)
* Implement ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED. * Fix auctionhouse search with scaled items. * Fix RequiredLevel enforcement for scaled items. * Fix item enchants not scaling properly with bonuses.
Diffstat (limited to 'src/server/game/Entities/Item')
-rw-r--r--src/server/game/Entities/Item/Item.cpp71
-rw-r--r--src/server/game/Entities/Item/Item.h7
2 files changed, 60 insertions, 18 deletions
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);