diff options
| author | Roc13x <roc13x@gmail.com> | 2018-04-28 12:40:00 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2018-04-28 14:40:00 +0300 |
| commit | b9b661da08b22a5d070eff9d2032dfd993a8b009 (patch) | |
| tree | e94014906f8041391dafc6a6ebb7c365d224e59b /src/server/game/Entities/Item | |
| parent | 45b2492aa0e5da95a8d9ae1483dbcd717898008c (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.cpp | 71 | ||||
| -rw-r--r-- | src/server/game/Entities/Item/Item.h | 7 |
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); |
