Core/Items: Add loot scaling support

This commit is contained in:
hondacrx
2018-04-28 11:38:00 -04:00
parent 1106aa3659
commit fc237004f2
8 changed files with 886 additions and 23 deletions
+1 -1
View File
@@ -543,7 +543,7 @@ namespace Game
if (quality != 0xffffffff && (uint)proto.GetQuality() != quality)
continue;
if (levelmin != 0 && (proto.GetBaseRequiredLevel() < levelmin || (levelmax != 0x00 && proto.GetBaseRequiredLevel() > levelmax)))
if (levelmin != 0 && (item.GetRequiredLevel() < levelmin || (levelmax != 0 && item.GetRequiredLevel() > levelmax)))
continue;
if (usable && player.CanUseItem(item) != InventoryResult.Ok)
+60 -16
View File
@@ -429,18 +429,6 @@ namespace Game.Entities
SetUInt32Value(ItemFields.Flags, itemFlags);
_LoadIntoDataField(fields.Read<string>(8), (uint)ItemFields.Enchantment, (uint)EnchantmentSlot.Max * (uint)EnchantmentOffset.Max);
m_randomEnchantment.Type = (ItemRandomEnchantmentType)fields.Read<byte>(9);
m_randomEnchantment.Id = fields.Read<uint>(10);
if (m_randomEnchantment.Type == ItemRandomEnchantmentType.Property)
SetUInt32Value(ItemFields.RandomPropertiesId, m_randomEnchantment.Id);
else if (m_randomEnchantment.Type == ItemRandomEnchantmentType.Suffix)
{
SetInt32Value(ItemFields.RandomPropertiesId, -(int)m_randomEnchantment.Id);
// recalculate suffix factor
UpdateItemSuffixFactor();
}
uint durability = fields.Read<uint>(11);
SetUInt32Value(ItemFields.Durability, durability);
// update max durability (and durability) if need
@@ -518,6 +506,19 @@ namespace Game.Entities
SetModifier(ItemModifier.ScalingStatDistributionFixedLevel, fields.Read<uint>(43));
SetModifier(ItemModifier.ArtifactKnowledgeLevel, fields.Read<uint>(44));
// Enchants must be loaded after all other bonus/scaling data
_LoadIntoDataField(fields.Read<string>(8), (uint)ItemFields.Enchantment, (uint)EnchantmentSlot.Max * (uint)EnchantmentOffset.Max);
m_randomEnchantment.Type = (ItemRandomEnchantmentType)fields.Read<byte>(9);
m_randomEnchantment.Id = fields.Read<uint>(10);
if (m_randomEnchantment.Type == ItemRandomEnchantmentType.Property)
SetUInt32Value(ItemFields.RandomPropertiesId, m_randomEnchantment.Id);
else if (m_randomEnchantment.Type == ItemRandomEnchantmentType.Suffix)
{
SetInt32Value(ItemFields.RandomPropertiesId, -(int)m_randomEnchantment.Id);
// recalculate suffix factor
UpdateItemSuffixFactor();
}
// Remove bind flag for items vs NO_BIND set
if (IsSoulBound() && GetBonding() == ItemBondingType.None)
{
@@ -699,9 +700,19 @@ namespace Game.Entities
void UpdateItemSuffixFactor()
{
uint suffixFactor = ItemEnchantment.GenerateEnchSuffixFactor(GetEntry());
if (GetTemplate().GetRandomSuffix() == 0)
return;
uint suffixFactor = 0;
Player owner = GetOwner();
if (owner)
suffixFactor = ItemEnchantment.GetRandomPropertyPoints(GetItemLevel(owner), GetQuality(), GetTemplate().GetInventoryType(), GetTemplate().GetSubClass());
else
suffixFactor = ItemEnchantment.GenerateEnchSuffixFactor(GetEntry());
if (GetItemSuffixFactor() == suffixFactor)
return;
SetUInt32Value(ItemFields.PropertySeed, suffixFactor);
}
@@ -2388,6 +2399,35 @@ namespace Game.Entities
SetState(ItemUpdateState.Changed, owner);
}
public void SetFixedLevel(uint level)
{
if (!_bonusData.HasFixedLevel || GetModifier(ItemModifier.ScalingStatDistributionFixedLevel) != 0)
return;
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(_bonusData.ScalingStatDistribution);
if (ssd != null)
{
level = Math.Min(Math.Max(level, ssd.MinLevel), ssd.MaxLevel);
SandboxScalingRecord sandbox = CliDB.SandboxScalingStorage.LookupByKey(_bonusData.SandboxScalingId);
if (sandbox != null)
if ((sandbox.Flags.HasAnyFlag(2u) || sandbox.MinLevel != 0 || sandbox.MaxLevel != 0) && !sandbox.Flags.HasAnyFlag(4u))
level = Math.Min(Math.Max(level, sandbox.MinLevel), sandbox.MaxLevel);
SetModifier(ItemModifier.ScalingStatDistributionFixedLevel, level);
}
}
public int GetRequiredLevel()
{
if (_bonusData.RequiredLevelOverride != 0)
return _bonusData.RequiredLevelOverride;
else if (_bonusData.HasFixedLevel)
return (int)GetModifier(ItemModifier.ScalingStatDistributionFixedLevel);
else
return _bonusData.RequiredLevel;
}
public static void AddItemsSetItem(Player player, Item item)
{
ItemTemplate proto = item.GetTemplate();
@@ -2582,7 +2622,6 @@ namespace Game.Entities
public bool IsConjuredConsumable() { return GetTemplate().IsConjuredConsumable(); }
public bool IsRangedWeapon() { return GetTemplate().IsRangedWeapon(); }
public ItemQuality GetQuality() { return _bonusData.Quality; }
public int GetRequiredLevel() { return _bonusData.RequiredLevel; }
public int GetItemStatType(uint index)
{
Contract.Assert(index < ItemConst.MaxStats);
@@ -2793,6 +2832,8 @@ namespace Game.Entities
ScalingStatDistribution = proto.GetScalingStatDistribution();
RelicType = -1;
HasItemLevelBonus = false;
HasFixedLevel = false;
RequiredLevelOverride = 0;
_state.AppearanceModPriority = int.MaxValue;
_state.ScalingStatDistributionPriority = int.MaxValue;
@@ -2873,12 +2914,13 @@ namespace Game.Entities
RepairCostMultiplier *= Convert.ToSingle(values[0]) * 0.01f;
break;
case ItemBonusType.ScalingStatDistribution:
case ItemBonusType.ScalingStatDistribution2:
case ItemBonusType.ScalingStatDistributionFixed:
if (values[1] < _state.ScalingStatDistributionPriority)
{
ScalingStatDistribution = (uint)values[0];
SandboxScalingId = (uint)values[2];
_state.ScalingStatDistributionPriority = values[1];
HasFixedLevel = type == ItemBonusType.ScalingStatDistributionFixed;
}
break;
case ItemBonusType.Bounding:
@@ -2888,7 +2930,7 @@ namespace Game.Entities
RelicType = values[0];
break;
case ItemBonusType.OverrideRequiredLevel:
RequiredLevel = values[0];
RequiredLevelOverride = values[0];
break;
}
}
@@ -2911,7 +2953,9 @@ namespace Game.Entities
public int[] GemRelicType = new int[ItemConst.MaxGemSockets];
public ushort[] GemRelicRankBonus = new ushort[ItemConst.MaxGemSockets];
public int RelicType;
public int RequiredLevelOverride;
public bool HasItemLevelBonus;
public bool HasFixedLevel;
State _state;
struct State
+6 -1
View File
@@ -1274,7 +1274,6 @@ namespace Game.Entities
UpdateCriteria(CriteriaTypes.OwnItem, itemId, 1);
item.SetFlag(ItemFields.Flags, ItemFieldFlags.NewItem);
item.SetItemRandomProperties(randomPropertyId);
uint upgradeID = Global.DB2Mgr.GetRulesetItemUpgrade(itemId);
if (upgradeID != 0)
@@ -1289,6 +1288,9 @@ namespace Game.Entities
item = StoreItem(pos, item, update);
item.SetFixedLevel(getLevel());
item.SetItemRandomProperties(randomPropertyId);
if (allowedLooters != null && allowedLooters.Count > 1 && item.GetTemplate().GetMaxStackSize() == 1 && item.IsSoulBound())
{
item.SetSoulboundTradeable(allowedLooters);
@@ -1414,6 +1416,9 @@ namespace Game.Entities
if (pItem.IsBindedNotWith(this))
return InventoryResult.NotOwner;
if (getLevel() < pItem.GetRequiredLevel())
return InventoryResult.CantEquipLevelI;
InventoryResult res = CanUseItem(pProto);
if (res != InventoryResult.Ok)
return res;
+1 -3
View File
@@ -520,9 +520,7 @@ namespace Game
{
_player.ModifyMoney(-price);
_player.RemoveItemFromBuyBackSlot(packet.Slot, false);
_player.ItemAddedQuestCheck(pItem.GetEntry(), pItem.GetCount());
_player.UpdateCriteria(CriteriaTypes.ReceiveEpicItem, pItem.GetEntry(), pItem.GetCount());
_player.StoreItem(dest, pItem, true);
_player.MoveItemToInventory(dest, pItem, true);
}
else
_player.SendEquipError(msg, pItem);