mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-19 22:49:39 -04:00
Core/Items: restore heirloom armor stat scaling
This commit is contained in:
@@ -55,7 +55,7 @@ CREATE TABLE `scaling_stat_values` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Charlevel` int(11) NOT NULL DEFAULT '0',
|
||||
`WeaponDPS1H` int(11) NOT NULL DEFAULT '0',
|
||||
`WeaponDPS2h` int(11) NOT NULL DEFAULT '0',
|
||||
`WeaponDPS2H` int(11) NOT NULL DEFAULT '0',
|
||||
`SpellcasterDPS1H` int(11) NOT NULL DEFAULT '0',
|
||||
`SpellcasterDPS2H` int(11) NOT NULL DEFAULT '0',
|
||||
`RangedDPS` int(11) NOT NULL DEFAULT '0',
|
||||
@@ -63,7 +63,7 @@ CREATE TABLE `scaling_stat_values` (
|
||||
`SpellPower` int(11) NOT NULL DEFAULT '0',
|
||||
`ShoulderBudget` int(11) NOT NULL DEFAULT '0',
|
||||
`TrinketBudget` int(11) NOT NULL DEFAULT '0',
|
||||
`WeaponBudget` int(11) NOT NULL DEFAULT '0',
|
||||
`WeaponBudget1H` int(11) NOT NULL DEFAULT '0',
|
||||
`PrimaryBudget` int(11) NOT NULL DEFAULT '0',
|
||||
`RangedBudget` int(11) NOT NULL DEFAULT '0',
|
||||
`TertiaryBudget` int(11) NOT NULL DEFAULT '0',
|
||||
|
||||
@@ -1327,8 +1327,8 @@ void HotfixDatabaseConnection::DoPrepareStatements()
|
||||
PREPARE_MAX_ID_STMT(HOTFIX_SEL_SCALING_STAT_DISTRIBUTION, "SELECT MAX(ID) + 1 FROM scaling_stat_distribution", CONNECTION_SYNCH);
|
||||
|
||||
// ScalingStatValues.db2
|
||||
PrepareStatement(HOTFIX_SEL_SCALING_STAT_VALUES, "SELECT ID, Charlevel, WeaponDPS1H, WeaponDPS2h, SpellcasterDPS1H, SpellcasterDPS2H, RangedDPS, "
|
||||
"WandDPS, SpellPower, ShoulderBudget, TrinketBudget, WeaponBudget, PrimaryBudget, RangedBudget, TertiaryBudget, ClothShoulderArmor, "
|
||||
PrepareStatement(HOTFIX_SEL_SCALING_STAT_VALUES, "SELECT ID, Charlevel, WeaponDPS1H, WeaponDPS2H, SpellcasterDPS1H, SpellcasterDPS2H, RangedDPS, "
|
||||
"WandDPS, SpellPower, ShoulderBudget, TrinketBudget, WeaponBudget1H, PrimaryBudget, RangedBudget, TertiaryBudget, ClothShoulderArmor, "
|
||||
"LeatherShoulderArmor, MailShoulderArmor, PlateShoulderArmor, ClothCloakArmor, ClothChestArmor, LeatherChestArmor, MailChestArmor, "
|
||||
"PlateChestArmor FROM scaling_stat_values WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
|
||||
PREPARE_MAX_ID_STMT(HOTFIX_SEL_SCALING_STAT_VALUES, "SELECT MAX(ID) + 1 FROM scaling_stat_values", CONNECTION_SYNCH);
|
||||
|
||||
@@ -410,7 +410,7 @@ bool CriteriaData::Meets(uint32 criteriaId, Player const* source, WorldObject co
|
||||
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!itemTemplate)
|
||||
return false;
|
||||
return itemTemplate->GetBaseItemLevel() >= EquippedItem.ItemLevel && itemTemplate->GetQuality() >= EquippedItem.Quality;
|
||||
return itemTemplate->GetItemLevel() >= EquippedItem.ItemLevel && itemTemplate->GetQuality() >= EquippedItem.Quality;
|
||||
}
|
||||
case CRITERIA_DATA_TYPE_MAP_ID:
|
||||
return source->GetMapId() == Map.Id;
|
||||
@@ -1718,7 +1718,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
{
|
||||
// miscValue1 is itemid
|
||||
ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1));
|
||||
if (!item || item->GetBaseItemLevel() < reqValue)
|
||||
if (!item || item->GetItemLevel() < reqValue)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ AuctionsBucketKey AuctionsBucketKey::ForItem(Item const* item)
|
||||
|
||||
AuctionsBucketKey AuctionsBucketKey::ForCommodity(ItemTemplate const* itemTemplate)
|
||||
{
|
||||
return { itemTemplate->GetId(), uint16(itemTemplate->GetBaseItemLevel()), 0, 0 };
|
||||
return { itemTemplate->GetId(), uint16(itemTemplate->GetItemLevel()), 0, 0 };
|
||||
}
|
||||
|
||||
void AuctionsBucketData::BuildBucketInfo(WorldPackets::AuctionHouse::BucketInfo* bucketInfo, Player const* player) const
|
||||
@@ -884,7 +884,7 @@ void AuctionHouseObject::AddAuction(CharacterDatabaseTransaction trans, AuctionP
|
||||
break;
|
||||
case ITEM_CLASS_GEM:
|
||||
case ITEM_CLASS_ITEM_ENHANCEMENT:
|
||||
bucket->SortLevel = itemTemplate->GetBaseItemLevel();
|
||||
bucket->SortLevel = itemTemplate->GetItemLevel();
|
||||
break;
|
||||
case ITEM_CLASS_CONSUMABLE:
|
||||
bucket->SortLevel = std::max<uint8>(1, bucket->RequiredLevel);
|
||||
|
||||
@@ -232,10 +232,10 @@ bool AuctionBotSeller::Initialize()
|
||||
case ITEM_CLASS_WEAPON:
|
||||
{
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() < value)
|
||||
if (prototype->GetItemLevel() < value)
|
||||
continue;
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() > value)
|
||||
if (prototype->GetItemLevel() > value)
|
||||
continue;
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL))
|
||||
if (prototype->GetBaseRequiredLevel() < static_cast<int32>(value))
|
||||
@@ -316,10 +316,10 @@ bool AuctionBotSeller::Initialize()
|
||||
case ITEM_CLASS_TRADE_GOODS:
|
||||
{
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() < value)
|
||||
if (prototype->GetItemLevel() < value)
|
||||
continue;
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() > value)
|
||||
if (prototype->GetItemLevel() > value)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@@ -327,10 +327,10 @@ bool AuctionBotSeller::Initialize()
|
||||
case ITEM_CLASS_QUIVER:
|
||||
{
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() < value)
|
||||
if (prototype->GetItemLevel() < value)
|
||||
continue;
|
||||
if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL))
|
||||
if (prototype->GetBaseItemLevel() > value)
|
||||
if (prototype->GetItemLevel() > value)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@@ -602,7 +602,7 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
|
||||
else
|
||||
{
|
||||
float divisor = ((itemProto->GetClass() == ITEM_CLASS_WEAPON || itemProto->GetClass() == ITEM_CLASS_ARMOR) ? 284.0f : 80.0f);
|
||||
float tempLevel = (itemProto->GetBaseItemLevel() == 0 ? 1.0f : itemProto->GetBaseItemLevel());
|
||||
float tempLevel = (itemProto->GetItemLevel() == 0 ? 1.0f : itemProto->GetItemLevel());
|
||||
float tempQuality = (itemProto->GetQuality() == 0 ? 1.0f : itemProto->GetQuality());
|
||||
|
||||
buyPrice = tempLevel * tempQuality * static_cast<float>(GetBuyModifier(itemProto))* tempLevel / divisor;
|
||||
|
||||
@@ -478,6 +478,7 @@ namespace
|
||||
std::unordered_set<uint8> _spellFamilyNames;
|
||||
SpellProcsPerMinuteModContainer _spellProcsPerMinuteMods;
|
||||
std::unordered_map<int32, std::vector<SpellVisualMissileEntry const*>> _spellVisualMissilesBySet;
|
||||
std::unordered_map<uint32, ScalingStatValuesEntry const*> _scalingStatValuesByLevel;
|
||||
TalentsByPosition _talentsByPosition;
|
||||
std::unordered_map<std::pair<uint32, uint32>, TaxiPathEntry const*> _taxiPaths;
|
||||
ToyItemIdsContainer _toys;
|
||||
@@ -1341,6 +1342,9 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
|
||||
for (SpellVisualMissileEntry const* spellVisualMissile : sSpellVisualMissileStore)
|
||||
_spellVisualMissilesBySet[spellVisualMissile->SpellVisualMissileSetID].push_back(spellVisualMissile);
|
||||
|
||||
for (ScalingStatValuesEntry const* scalingStatValue : sScalingStatValuesStore)
|
||||
_scalingStatValuesByLevel[scalingStatValue->Charlevel] = scalingStatValue;
|
||||
|
||||
for (TalentEntry const* talentInfo : sTalentStore)
|
||||
{
|
||||
ASSERT(talentInfo->ClassID < MAX_CLASSES);
|
||||
@@ -3051,3 +3055,8 @@ std::vector<ItemEffectEntry const*> const* DB2Manager::GetItemEffectsForItemId(u
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_itemEffectsByItemId, itemId);
|
||||
}
|
||||
|
||||
ScalingStatValuesEntry const* DB2Manager::GetScalingStatValuesForLevel(uint32 characterLevel) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_scalingStatValuesByLevel, characterLevel);
|
||||
}
|
||||
|
||||
@@ -499,6 +499,7 @@ public:
|
||||
bool IsUiMapPhase(uint32 phaseId) const;
|
||||
WMOAreaTableEntry const* GetWMOAreaTable(int32 rootId, int32 adtId, int32 groupId) const;
|
||||
std::vector<ItemEffectEntry const*> const* GetItemEffectsForItemId(uint32 itemId) const;
|
||||
ScalingStatValuesEntry const* GetScalingStatValuesForLevel(uint32 characterLevel) const;
|
||||
|
||||
private:
|
||||
friend class DB2HotfixGeneratorBase;
|
||||
|
||||
@@ -3168,7 +3168,7 @@ struct ScalingStatValuesEntry
|
||||
uint32 ID;
|
||||
int32 Charlevel;
|
||||
int32 WeaponDPS1H;
|
||||
int32 WeaponDPS2h;
|
||||
int32 WeaponDPS2H;
|
||||
int32 SpellcasterDPS1H;
|
||||
int32 SpellcasterDPS2H;
|
||||
int32 RangedDPS;
|
||||
@@ -3176,7 +3176,7 @@ struct ScalingStatValuesEntry
|
||||
int32 SpellPower;
|
||||
int32 ShoulderBudget;
|
||||
int32 TrinketBudget;
|
||||
int32 WeaponBudget;
|
||||
int32 WeaponBudget1H;
|
||||
int32 PrimaryBudget;
|
||||
int32 RangedBudget;
|
||||
int32 TertiaryBudget;
|
||||
@@ -3189,6 +3189,68 @@ struct ScalingStatValuesEntry
|
||||
int32 LeatherChestArmor;
|
||||
int32 MailChestArmor;
|
||||
int32 PlateChestArmor;
|
||||
|
||||
int32 getssdMultiplier(uint32 mask) const
|
||||
{
|
||||
if (mask & 0x4001F)
|
||||
{
|
||||
if (mask & 0x00000001) return ShoulderBudget;
|
||||
if (mask & 0x00000002) return TrinketBudget;
|
||||
if (mask & 0x00000004) return WeaponBudget1H;
|
||||
if (mask & 0x00000008) return PrimaryBudget;
|
||||
if (mask & 0x00000010) return RangedBudget;
|
||||
if (mask & 0x00040000) return TertiaryBudget;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 getArmorMod(uint32 mask) const
|
||||
{
|
||||
if (mask & 0x00F001E0)
|
||||
{
|
||||
if (mask & 0x00000020) return ClothShoulderArmor;
|
||||
if (mask & 0x00000040) return LeatherShoulderArmor;
|
||||
if (mask & 0x00000080) return MailShoulderArmor;
|
||||
if (mask & 0x00000100) return PlateShoulderArmor;
|
||||
|
||||
if (mask & 0x00080000) return ClothCloakArmor;
|
||||
if (mask & 0x00100000) return ClothChestArmor;
|
||||
if (mask & 0x00200000) return LeatherChestArmor;
|
||||
if (mask & 0x00400000) return MailChestArmor;
|
||||
if (mask & 0x00800000) return PlateChestArmor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 getDPSMod(uint32 mask) const
|
||||
{
|
||||
if (mask & 0x7E00)
|
||||
{
|
||||
if (mask & 0x00000200) return WeaponDPS1H;
|
||||
if (mask & 0x00000400) return WeaponDPS2H;
|
||||
if (mask & 0x00000800) return SpellcasterDPS1H;
|
||||
if (mask & 0x00001000) return SpellcasterDPS2H;
|
||||
if (mask & 0x00002000) return RangedDPS;
|
||||
if (mask & 0x00004000) return WandDPS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isTwoHand(uint32 mask) const
|
||||
{
|
||||
if (mask & 0x7E00)
|
||||
{
|
||||
if (mask & 0x00000400) return true;
|
||||
if (mask & 0x00001000) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 getSpellBonus(uint32 mask) const
|
||||
{
|
||||
if (mask & 0x00008000) return SpellPower;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneScriptEntry
|
||||
|
||||
@@ -1139,7 +1139,7 @@ void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem, uint32 gemScalin
|
||||
BonusData gemBonus;
|
||||
gemBonus.Initialize(gemTemplate);
|
||||
|
||||
uint32 gemBaseItemLevel = gemTemplate->GetBaseItemLevel();
|
||||
uint32 gemBaseItemLevel = gemTemplate->GetItemLevel();
|
||||
if (gemBonus.PlayerLevelToItemLevelCurveId)
|
||||
if (uint32 scaledIlvl = uint32(sDB2Manager.GetCurveValueAt(gemBonus.PlayerLevelToItemLevelCurveId, gemScalingLevel)))
|
||||
gemBaseItemLevel = scaledIlvl;
|
||||
@@ -1564,16 +1564,7 @@ bool Item::HasStats() const
|
||||
ItemTemplate const* proto = GetTemplate();
|
||||
Player const* owner = GetOwner();
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
if ((owner ? GetItemStatValue(i, owner) : proto->GetStatPercentEditor(i)) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Item::HasStats(WorldPackets::Item::ItemInstance const& /*itemInstance*/, BonusData const* bonus)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
if (bonus->ItemStatBonusAmount[i] != 0)
|
||||
if (proto->GetStatModifierBonusAmount(i) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1895,7 +1886,7 @@ uint32 Item::GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bon
|
||||
if (!itemTemplate)
|
||||
return MIN_ITEM_LEVEL;
|
||||
|
||||
uint32 itemLevel = itemTemplate->GetBaseItemLevel();
|
||||
uint32 itemLevel = itemTemplate->GetItemLevel();
|
||||
|
||||
if (bonusData.PlayerLevelToItemLevelCurveId)
|
||||
{
|
||||
@@ -1929,12 +1920,6 @@ uint32 Item::GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bon
|
||||
return std::min(std::max(itemLevel, uint32(MIN_ITEM_LEVEL)), uint32(MAX_ITEM_LEVEL));
|
||||
}
|
||||
|
||||
float Item::GetItemStatValue(uint32 index, Player const* owner) const
|
||||
{
|
||||
ASSERT(index < MAX_ITEM_PROTO_STATS);
|
||||
return static_cast<float>(_bonusData.ItemStatBonusAmount[index]);
|
||||
}
|
||||
|
||||
ItemDisenchantLootEntry const* Item::GetDisenchantLoot(Player const* owner) const
|
||||
{
|
||||
if (!_bonusData.CanDisenchant)
|
||||
@@ -2150,11 +2135,6 @@ void BonusData::Initialize(ItemTemplate const* proto)
|
||||
Quality = proto->GetQuality();
|
||||
ItemLevelBonus = 0;
|
||||
RequiredLevel = proto->GetBaseRequiredLevel();
|
||||
for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
ItemStatType[i] = proto->GetStatModifierBonusStat(i);
|
||||
|
||||
for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
ItemStatBonusAmount[i] = proto->GetStatModifierBonusAmount(i);
|
||||
|
||||
for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
ItemStatSocketCostMultiplier[i] = proto->GetStatPercentageOfSocket(i);
|
||||
|
||||
@@ -70,8 +70,6 @@ struct BonusData
|
||||
uint32 Quality;
|
||||
int32 ItemLevelBonus;
|
||||
int32 RequiredLevel;
|
||||
int32 ItemStatType[MAX_ITEM_PROTO_STATS];
|
||||
int32 ItemStatBonusAmount[MAX_ITEM_PROTO_STATS];
|
||||
float ItemStatSocketCostMultiplier[MAX_ITEM_PROTO_STATS];
|
||||
uint32 SocketColor[MAX_ITEM_PROTO_SOCKETS];
|
||||
ItemBondingType Bonding;
|
||||
@@ -274,8 +272,6 @@ class TC_GAME_API Item : public Object
|
||||
static uint32 GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bonusData, uint32 level, uint32 fixedLevel,
|
||||
uint32 minItemLevel, uint32 minItemLevelCutoff, uint32 maxItemLevel, bool pvpBonus);
|
||||
int32 GetRequiredLevel() const;
|
||||
int32 GetItemStatType(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_STATS); return _bonusData.ItemStatType[index]; }
|
||||
float GetItemStatValue(uint32 index, Player const* owner) const;
|
||||
SocketColor GetSocketColor(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_SOCKETS); return SocketColor(_bonusData.SocketColor[index]); }
|
||||
uint32 GetAppearanceModId() const { return m_itemData->ItemAppearanceModID; }
|
||||
void SetAppearanceModId(uint32 appearanceModId) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), appearanceModId); }
|
||||
@@ -338,7 +334,6 @@ class TC_GAME_API Item : public Object
|
||||
|
||||
bool IsValidTransmogrificationTarget() const;
|
||||
bool HasStats() const;
|
||||
static bool HasStats(WorldPackets::Item::ItemInstance const& itemInstance, BonusData const* bonus);
|
||||
static bool CanTransmogrifyItemWithItem(Item const* item, ItemModifiedAppearanceEntry const* itemModifiedAppearance);
|
||||
uint32 GetBuyPrice(Player const* owner, bool& standardPrice) const;
|
||||
static uint32 GetBuyPrice(ItemTemplate const* proto, uint32 quality, uint32 itemLevel, bool& standardPrice);
|
||||
|
||||
@@ -786,7 +786,7 @@ struct TC_GAME_API ItemTemplate
|
||||
InventoryType GetInventoryType() const { return InventoryType(ExtendedData->InventoryType); }
|
||||
int32 GetAllowableClass() const { return ExtendedData->AllowableClass; }
|
||||
Trinity::RaceMask<int64> GetAllowableRace() const { return ExtendedData->AllowableRace; }
|
||||
uint32 GetBaseItemLevel() const { return ExtendedData->ItemLevel; }
|
||||
uint32 GetItemLevel() const { return ExtendedData->ItemLevel; }
|
||||
int32 GetBaseRequiredLevel() const { return ExtendedData->RequiredLevel; }
|
||||
uint32 GetRequiredSkill() const { return ExtendedData->RequiredSkill; }
|
||||
uint32 GetRequiredSkillRank() const { return ExtendedData->RequiredSkillRank; }
|
||||
@@ -826,6 +826,8 @@ struct TC_GAME_API ItemTemplate
|
||||
uint8 GetRequiredExpansion() const { return ExtendedData->ExpansionID; }
|
||||
int16 GetResistance(SpellSchools school) const { return ExtendedData->Resistances[school]; }
|
||||
int16 GetShieldBlockValue(uint32 itemLevel) const;
|
||||
uint16 GetScalingStatDistributionID() const { return ExtendedData->ScalingStatDistributionID; }
|
||||
int32 GetScalingStatValue() const { return BasicData->ScalingStatValue; }
|
||||
|
||||
uint32 MaxDurability;
|
||||
std::vector<ItemEffectEntry const*> Effects;
|
||||
|
||||
@@ -7705,7 +7705,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
||||
|
||||
//---------------------------------------------------------//
|
||||
|
||||
void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras /*= true*/)
|
||||
void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras /*= true*/, bool onlyForScalingItems /*= false*/)
|
||||
{
|
||||
if (slot >= INVENTORY_SLOT_BAG_END || !item)
|
||||
return;
|
||||
@@ -7723,7 +7723,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemA
|
||||
if (item->GetSocketColor(0)) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items
|
||||
CorrectMetaGemEnchants(slot, apply);
|
||||
|
||||
_ApplyItemBonuses(item, slot, apply);
|
||||
_ApplyItemBonuses(item, slot, apply, onlyForScalingItems);
|
||||
ApplyItemEquipSpell(item, apply);
|
||||
if (updateItemAuras)
|
||||
{
|
||||
@@ -7739,28 +7739,45 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemA
|
||||
TC_LOG_DEBUG("entities.player.items", "Player::_ApplyItemMods: completed");
|
||||
}
|
||||
|
||||
void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
|
||||
void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply, bool onlyForScalingItems /*= false*/)
|
||||
{
|
||||
ItemTemplate const* proto = item->GetTemplate();
|
||||
if (slot >= INVENTORY_SLOT_BAG_END || !proto)
|
||||
return;
|
||||
|
||||
uint32 itemLevel = item->GetItemLevel(this);
|
||||
ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(proto->GetScalingStatDistributionID());
|
||||
ScalingStatValuesEntry const* ssv = proto->GetScalingStatValue() != 0 ? sDB2Manager.GetScalingStatValuesForLevel(std::clamp<uint32>(GetLevel(), ssd->MinLevel, ssd->MaxLevel)) : nullptr;
|
||||
|
||||
float combatRatingMultiplier = 1.0f;
|
||||
//if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(itemLevel))
|
||||
// combatRatingMultiplier = GetIlvlStatMultiplier(ratingMult, proto->GetInventoryType());
|
||||
if (onlyForScalingItems && (!ssd || !ssv))
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
{
|
||||
int32 statType = item->GetItemStatType(i);
|
||||
if (statType == -1)
|
||||
continue;
|
||||
int32 statType = 0;
|
||||
int32 val = 0;
|
||||
|
||||
if (ssd && ssv)
|
||||
{
|
||||
statType = ssd->StatID[i];
|
||||
if (statType == -1)
|
||||
continue;
|
||||
|
||||
val = (ssv->getssdMultiplier(proto->GetScalingStatValue()) * ssd->Bonus[i]) / 10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
statType = proto->GetStatModifierBonusStat(i);
|
||||
if (statType == -1)
|
||||
continue;
|
||||
|
||||
val = proto->GetStatModifierBonusAmount(i);
|
||||
}
|
||||
|
||||
float val = item->GetItemStatValue(i, this);
|
||||
if (val == 0)
|
||||
continue;
|
||||
|
||||
float const combatRatingMultiplier = 1.0f;
|
||||
|
||||
switch (statType)
|
||||
{
|
||||
case ITEM_MOD_MANA:
|
||||
@@ -7982,11 +7999,24 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Spell Power from ScalingStatValue if set
|
||||
if (ssv)
|
||||
if (int32 spellbonus = ssv->getSpellBonus(proto->GetScalingStatValue()))
|
||||
ApplySpellPowerBonus(spellbonus, apply);
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
{
|
||||
SpellSchools school = SpellSchools(i);
|
||||
int16 resistance = proto->GetResistance(school);
|
||||
if (school == SPELL_SCHOOL_NORMAL && ssv)
|
||||
if (uint32 ssvarmor = ssv->getArmorMod(proto->GetScalingStatValue()))
|
||||
resistance = ssvarmor;
|
||||
|
||||
if (int16 resistance = proto->GetResistance(SpellSchools(i)))
|
||||
HandleStatFlatModifier(UnitMods(UNIT_MOD_ARMOR + i), BASE_VALUE, float(resistance), apply);
|
||||
}
|
||||
|
||||
if (int16 shieldBlockValue = proto->GetShieldBlockValue(itemLevel))
|
||||
if (int16 shieldBlockValue = proto->GetShieldBlockValue(proto->GetItemLevel()))
|
||||
if (proto->GetClass() == ITEM_CLASS_ARMOR && proto->GetSubClass() == ITEM_SUBCLASS_ARMOR_SHIELD)
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ShieldBlock), apply ? shieldBlockValue : 0);
|
||||
|
||||
@@ -8611,7 +8641,7 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply)
|
||||
if (!CanUseAttackType(Player::GetAttackBySlot(i, m_items[i]->GetTemplate()->GetInventoryType())))
|
||||
continue;
|
||||
|
||||
_ApplyItemMods(m_items[i], i, apply);
|
||||
_ApplyItemMods(m_items[i], i, apply, true);
|
||||
|
||||
// Update item sets for heirlooms
|
||||
if (sDB2Manager.GetHeirloomByItemId(m_items[i]->GetEntry()) && m_items[i]->GetTemplate()->GetItemSet())
|
||||
@@ -22355,7 +22385,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
|
||||
|
||||
if (crItem->maxcount != 0) // bought
|
||||
{
|
||||
if (pProto->GetQuality() > ITEM_QUALITY_EPIC || (pProto->GetQuality() == ITEM_QUALITY_EPIC && pProto->GetBaseItemLevel() >= MinNewsItemLevel))
|
||||
if (pProto->GetQuality() > ITEM_QUALITY_EPIC || (pProto->GetQuality() == ITEM_QUALITY_EPIC && pProto->GetItemLevel() >= MinNewsItemLevel))
|
||||
if (Guild* guild = GetGuild())
|
||||
guild->AddGuildNews(GUILD_NEWS_ITEM_PURCHASED, GetGUID(), 0, item);
|
||||
|
||||
|
||||
@@ -2286,11 +2286,11 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
bool CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect const* aurEff) const override;
|
||||
|
||||
void _ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras = true);
|
||||
void _ApplyItemMods(Item* item, uint8 slot, bool apply, bool updateItemAuras = true, bool onlyForScalingItems = false);
|
||||
void _RemoveAllItemMods();
|
||||
void _ApplyAllItemMods();
|
||||
void _ApplyAllLevelScaleItemMods(bool apply);
|
||||
void _ApplyItemBonuses(Item* item, uint8 slot, bool apply);
|
||||
void _ApplyItemBonuses(Item* item, uint8 slot, bool apply, bool onlyForScalingItems = false);
|
||||
void _ApplyWeaponDamage(uint8 slot, Item* item, bool apply);
|
||||
bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) const;
|
||||
void ToggleMetaGemsActive(uint8 exceptslot, bool apply);
|
||||
|
||||
@@ -6098,7 +6098,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
|
||||
if (!pet->HaveInDiet(foodItem->GetTemplate()))
|
||||
return SPELL_FAILED_WRONG_PET_FOOD;
|
||||
|
||||
if (foodItem->GetTemplate()->GetBaseItemLevel() + 30 <= pet->GetLevel())
|
||||
if (foodItem->GetTemplate()->GetItemLevel() + 30 <= pet->GetLevel())
|
||||
return SPELL_FAILED_FOOD_LOWLEVEL;
|
||||
|
||||
if (m_caster->ToPlayer()->IsInCombat() || pet->IsInCombat())
|
||||
@@ -7564,9 +7564,9 @@ SpellCastResult Spell::CheckItems(int32* param1 /*= nullptr*/, int32* param2 /*=
|
||||
// Apply item level restriction if the enchanting spell has max level restrition set
|
||||
if (m_CastItem && m_spellInfo->MaxLevel > 0)
|
||||
{
|
||||
if (item->GetTemplate()->GetBaseItemLevel() < (uint32)m_CastItem->GetTemplate()->GetBaseRequiredLevel())
|
||||
if (item->GetTemplate()->GetItemLevel() < (uint32)m_CastItem->GetTemplate()->GetBaseRequiredLevel())
|
||||
return SPELL_FAILED_LOWLEVEL;
|
||||
if (item->GetTemplate()->GetBaseItemLevel() > m_spellInfo->MaxLevel)
|
||||
if (item->GetTemplate()->GetItemLevel() > m_spellInfo->MaxLevel)
|
||||
return SPELL_FAILED_HIGHLEVEL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3491,7 +3491,7 @@ void Spell::EffectFeedPet()
|
||||
ExecuteLogEffectDestroyItem(SpellEffectName(effectInfo->Effect), foodItem->GetEntry());
|
||||
|
||||
int32 pct;
|
||||
int32 levelDiff = int32(pet->GetLevel()) - int32(foodItem->GetTemplate()->GetBaseItemLevel());
|
||||
int32 levelDiff = int32(pet->GetLevel()) - int32(foodItem->GetTemplate()->GetItemLevel());
|
||||
if (levelDiff >= 30)
|
||||
return;
|
||||
else if (levelDiff >= 20)
|
||||
|
||||
Reference in New Issue
Block a user