diff options
-rw-r--r-- | src/server/game/DataStores/GameTables.h | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 82 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 2 |
5 files changed, 34 insertions, 64 deletions
diff --git a/src/server/game/DataStores/GameTables.h b/src/server/game/DataStores/GameTables.h index abe5f5f47a4..ab4f7a18470 100644 --- a/src/server/game/DataStores/GameTables.h +++ b/src/server/game/DataStores/GameTables.h @@ -265,8 +265,8 @@ struct GtSpellScalingEntry float Warlock = 0.0f; float Monk = 0.0f; float Druid = 0.0f; - float Unknown1 = 0.0f; - float Unknown2 = 0.0f; + float Item = 0.0f; + float Consumable = 0.0f; }; struct GtTeamContributionPointsEntry @@ -375,6 +375,11 @@ inline float GetSpellScalingColumnForClass(GtSpellScalingEntry const* row, int32 return row->Monk; case CLASS_DRUID: return row->Druid; + case -1: + case -7: + return row->Item; + case -2: + return row->Consumable; default: break; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f417ca9222b..b0feff8a6f2 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6715,7 +6715,7 @@ int32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, int3 // Default calculation if (DoneAdvertisedBenefit) { - float coeff = spellEffectInfo.BonusCoefficient * spellProto->CalcSpellScalingMultiplier(this, false); + float coeff = spellEffectInfo.BonusCoefficient * spellProto->GetSpellScalingMultiplier(GetLevel(), false); if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; @@ -7202,7 +7202,7 @@ int32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, int // Default calculation if (DoneAdvertisedBenefit) { - float coeff = spellEffectInfo.BonusCoefficient; + float coeff = spellEffectInfo.BonusCoefficient * spellProto->GetSpellScalingMultiplier(GetLevel(), false);; if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 1357fa0c69f..e028c429532 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -165,6 +165,7 @@ enum Classes : uint8 // max+1 for player class #define MAX_CLASSES 15 +constexpr uint32 MAX_CLASS_ID = CLASS_DRUID; #define CLASSMASK_ALL_PLAYABLE \ ((1<<(CLASS_WARRIOR-1)) | \ diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7b72873c585..feb0c51c1c2 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -514,15 +514,6 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 *variance = valueVariance; } - // roll in a range <1;EffectDieSides> as of patch 3.3.3 - if (DieSides) - { - if (DieSides == 1) - value += DieSides; - else - value += (DieSides >= 1) ? irand(1, DieSides) : irand(DieSides, 1); - } - // base amount modification based on spell lvl vs caster lvl if (Scaling.Coefficient != 0.0f) { @@ -543,6 +534,16 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 level = 0; value += level * basePointsPerLevel; } + + if (DieSides) + { + // roll in a range <1;EffectDieSides> as of patch 3.3.3 + + if (DieSides == 1) + value += DieSides; + else + value += (DieSides >= 1) ? irand(1, DieSides) : irand(DieSides, 1); + } } // random damage @@ -560,7 +561,7 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 return int32(round(value)); } -int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 /*itemId*/, int32 itemLevel) const +int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 /*itemId*/, int32 /*itemLevel*/) const { if (Scaling.Coefficient != 0.0f) { @@ -586,50 +587,13 @@ int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* targ if (!_spellInfo->Scaling.Class) return 0; - uint32 effectiveItemLevel = itemLevel != -1 ? uint32(itemLevel) : 1u; - if (_spellInfo->Scaling.ScalesFromItemLevel || _spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL)) - { - if (_spellInfo->Scaling.ScalesFromItemLevel) - effectiveItemLevel = _spellInfo->Scaling.ScalesFromItemLevel; - - /* - if (_spellInfo->Scaling.Class == -8 || _spellInfo->Scaling.Class == -9) - { - RandPropPointsEntry const* randPropPoints = sRandPropPointsStore.LookupEntry(effectiveItemLevel); - if (!randPropPoints) - randPropPoints = sRandPropPointsStore.AssertEntry(sRandPropPointsStore.GetNumRows() - 1); - - value = _spellInfo->Scaling.Class == -8 ? randPropPoints->DamageReplaceStatF : randPropPoints->DamageSecondaryF; - } - else - */ - value = GetRandomPropertyPoints(effectiveItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0); - } - else - value = GetSpellScalingColumnForClass(sSpellScalingGameTable.GetRow(level), _spellInfo->Scaling.Class); - - /* - if (Scaling.Class == -7) - if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel)) - if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId)) - value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType)); - - if (Scaling.Class == -6) - if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(effectiveItemLevel)) - if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId)) - value *= GetIlvlStatMultiplier(staminaMult, InventoryType(itemSparse->InventoryType)); - */ - - if (static_cast<int32>(level) < _spellInfo->Scaling.CastTimeMaxLevel && _spellInfo->Scaling.CastTimeMax) - value *= float(_spellInfo->Scaling.CastTimeMin + (level - 1) * (_spellInfo->Scaling.CastTimeMax - _spellInfo->Scaling.CastTimeMin) / (_spellInfo->Scaling.CastTimeMaxLevel - 1)) / float(_spellInfo->Scaling.CastTimeMax); - - if (static_cast<int32>(level) < _spellInfo->Scaling.NerfMaxLevel) - value *= ((((1.0 - _spellInfo->Scaling.NerfFactor) * (level - 1)) / (_spellInfo->Scaling.NerfMaxLevel - 1)) + _spellInfo->Scaling.NerfFactor); + value = GetSpellScalingColumnForClass(sSpellScalingGameTable.GetRow(level), _spellInfo->Scaling.Class); + value *= _spellInfo->GetSpellScalingMultiplier(level, false); } value *= Scaling.Coefficient; - if (value > 0.0f && value < 1.0f) - value = 1.0f; + if (value > 0.0f) + value = std::max(value, 1.0f); return int32(round(value)); } @@ -3947,6 +3911,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, break; case POWER_MANA: powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct)); + powerCost = CalculatePct(powerCost, GetSpellScalingMultiplier(unitCaster->GetLevel(), true) * 100.f); break; case POWER_ALTERNATE_POWER: TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type POWER_ALTERNATE_POWER in spell {}", Id); @@ -4242,27 +4207,26 @@ float SpellInfo::CalcProcPPM(Unit* caster, int32 itemLevel) const return ppm; } -float SpellInfo::CalcSpellScalingMultiplier(WorldObject const* caster, bool isPowerCostRelated /*= false*/) const +// Based on client function (build 4.4.0.54737) +float SpellInfo::GetSpellScalingMultiplier(int32 targetLevel, bool isPowerCostRelated /*= false*/) const { - if (!caster || !caster->IsUnit() || Scaling.Class == 0) + if (targetLevel <= 0 || Scaling.Class == 0) return 1.f; float multiplier = 1.f; float scalingMultiplier = 1.f; - uint8 casterLevel = caster->ToUnit()->GetLevel(); - - if (casterLevel < Scaling.CastTimeMaxLevel && Scaling.CastTimeMax) + if (targetLevel < Scaling.CastTimeMaxLevel && Scaling.CastTimeMax) { - int32 castTime = Scaling.CastTimeMin + ((casterLevel - 1) * (Scaling.CastTimeMax - Scaling.CastTimeMin)) / (Scaling.CastTimeMaxLevel - 1); + int32 castTime = Scaling.CastTimeMin + ((targetLevel - 1) * (Scaling.CastTimeMax - Scaling.CastTimeMin)) / (Scaling.CastTimeMaxLevel - 1); multiplier = castTime / (float)Scaling.CastTimeMax; scalingMultiplier = castTime / (float)Scaling.CastTimeMax; } if (!isPowerCostRelated) { - if (casterLevel < Scaling.NerfMaxLevel) - scalingMultiplier = ((((1.f - Scaling.NerfFactor) * (casterLevel - 1)) / (Scaling.NerfMaxLevel - 1)) + Scaling.NerfFactor) * multiplier; + if (targetLevel < Scaling.NerfMaxLevel) + scalingMultiplier = ((((1.f - Scaling.NerfFactor) * (targetLevel - 1)) / (Scaling.NerfMaxLevel - 1)) + Scaling.NerfFactor) * multiplier; } return scalingMultiplier; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index f531c93387a..12958bd4c9c 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -559,7 +559,7 @@ class TC_GAME_API SpellInfo float CalcProcPPM(Unit* caster, int32 itemLevel) const; - float CalcSpellScalingMultiplier(WorldObject const* caster, bool isPowerCostRelated /*= false*/) const; + float GetSpellScalingMultiplier(int32 targetLevel, bool isPowerCostRelated /*= false*/) const; bool IsRanked() const; uint8 GetRank() const; |