aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp122
-rw-r--r--src/server/game/Spells/Spell.h7
-rw-r--r--src/server/game/Spells/SpellInfo.cpp112
-rw-r--r--src/server/game/Spells/SpellInfo.h2
5 files changed, 82 insertions, 163 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index a45c8a84ab4..3ed8cc430de 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -563,7 +563,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
AuraEffect::AuraEffect(Aura* base, uint32 effIndex, int32 *baseAmount, Unit* caster) :
m_base(base), m_spellInfo(base->GetSpellInfo()),
_effectInfo(base->GetSpellEffectInfo(effIndex)),
-m_baseAmount(baseAmount ? *baseAmount : base->GetSpellEffectInfo(effIndex)->BasePoints),
+m_baseAmount(baseAmount ? *baseAmount : _effectInfo->CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemLevel())),
m_damage(0), m_critChance(0.0f), m_donePct(1.0f),
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
m_canBeRecalculated(true), m_isPeriodic(false)
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2ef7508616b..09d994e985d 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -491,7 +491,7 @@ void SpellCastTargets::OutDebug() const
TC_LOG_DEBUG("spells", "pitch: %f", m_pitch);
}
-SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto)
+SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto, Unit const* caster)
{
// todo 6.x
SpellEffectInfoVector effects = proto->GetEffectsForDifficulty(diff);
@@ -499,8 +499,9 @@ SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto)
memset(EffectBasePoints, 0, sizeof(EffectBasePoints));
for (SpellEffectInfo const* effect : effects)
if (effect)
- EffectBasePoints[effect->EffectIndex] = effect->BasePoints;
+ EffectBasePoints[effect->EffectIndex] = effect->CalcBaseValue(caster, nullptr, -1);
+ CustomBasePointsMask = 0;
MaxAffectedTargets = proto->MaxAffectedTargets;
RadiusMod = 1.0f;
AuraStackAmount = 1;
@@ -521,7 +522,7 @@ protected:
Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) :
m_spellInfo(info), m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster),
-m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo))
+m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo, caster))
{
_effects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficultyID());
@@ -537,7 +538,6 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo))
m_delayAtDamageCount = 0;
m_applyMultiplierMask = 0;
- m_auraScaleMask = 0;
memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
// Get data for type of attack
@@ -791,31 +791,6 @@ void Spell::SelectSpellTargets()
}
}
}
- else if (m_auraScaleMask)
- {
- bool checkLvl = !m_UniqueTargetInfo.empty();
- for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();)
- {
- // remove targets which did not pass min level check
- if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask)
- {
- // Do not check for selfcast
- if (!ihit->scaleAura && ihit->targetGUID != m_caster->GetGUID())
- {
- ihit = m_UniqueTargetInfo.erase(ihit);
- continue;
- }
- }
-
- ++ihit;
- }
-
- if (checkLvl && m_UniqueTargetInfo.empty())
- {
- SendCastResult(SPELL_FAILED_LOWLEVEL);
- finish(false);
- }
- }
}
if (m_targets.HasDst())
@@ -2132,13 +2107,6 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
if (targetGUID == ihit->targetGUID) // Found in list
{
ihit->effectMask |= effectMask; // Immune effects removed from mask
- ihit->scaleAura = false;
- if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
- {
- SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
- if (uint32(target->GetLevelForTarget(m_caster) + 10) >= auraSpell->SpellLevel)
- ihit->scaleAura = true;
- }
return;
}
}
@@ -2153,13 +2121,6 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.alive = target->IsAlive();
targetInfo.damage = 0;
targetInfo.crit = false;
- targetInfo.scaleAura = false;
- if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
- {
- SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
- if (uint32(target->GetLevelForTarget(m_caster) + 10) >= auraSpell->SpellLevel)
- targetInfo.scaleAura = true;
- }
// Calculate hit result
if (m_originalCaster)
@@ -2402,7 +2363,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER)
enablePvP = true; // Decide on PvP flagging now, but act on it later.
- SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
+ SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask);
if (missInfo2 != SPELL_MISS_NONE)
{
@@ -2595,7 +2556,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
}
}
-SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleAura)
+SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask)
{
if (!unit || !effectMask)
return SPELL_MISS_EVADE;
@@ -2680,34 +2641,19 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
if (aura_effmask)
{
- // Select rank for aura with level requirements only in specific cases
- // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
- SpellInfo const* aurSpellInfo = m_spellInfo;
- int32 basePoints[MAX_SPELL_EFFECTS];
- if (scaleAura)
- {
- aurSpellInfo = m_spellInfo->GetAuraRankForLevel(unitTarget->getLevel());
- ASSERT(aurSpellInfo);
- for (SpellEffectInfo const* effect : aurSpellInfo->GetEffectsForDifficulty(0))
- {
- basePoints[effect->EffectIndex] = effect->BasePoints;
- if (SpellEffectInfo const* myEffect = GetEffect(effect->EffectIndex))
- {
- if (myEffect->Effect != effect->Effect)
- {
- aurSpellInfo = m_spellInfo;
- break;
- }
- }
- }
- }
-
if (m_originalCaster)
{
+ int32 basePoints[MAX_SPELL_EFFECTS];
+ for (SpellEffectInfo const* auraSpellEffect : GetEffects())
+ if (auraSpellEffect)
+ basePoints[auraSpellEffect->EffectIndex] = (m_spellValue->CustomBasePointsMask & (1 << auraSpellEffect->EffectIndex)) ?
+ m_spellValue->EffectBasePoints[auraSpellEffect->EffectIndex] :
+ auraSpellEffect->CalcBaseValue(m_originalCaster, unit, m_castItemLevel);
+
bool refresh = false;
bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
- m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, m_castId, effectMask, unit,
- m_originalCaster, (aurSpellInfo == m_spellInfo) ? m_spellValue->EffectBasePoints : basePoints,
+ m_spellAura = Aura::TryRefreshStackOrCreate(m_spellInfo, m_castId, effectMask, unit,
+ m_originalCaster, basePoints,
m_CastItem, ObjectGuid::Empty, &refresh, resetPeriodicTimer, ObjectGuid::Empty, m_castItemLevel);
if (m_spellAura)
{
@@ -2722,7 +2668,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
// Now Reduce spell duration using data received at spell hit
int32 duration = m_spellAura->GetMaxDuration();
- float diminishMod = unit->ApplyDiminishingToDuration(aurSpellInfo, duration, m_originalCaster, diminishLevel);
+ float diminishMod = unit->ApplyDiminishingToDuration(m_spellInfo, duration, m_originalCaster, diminishLevel);
// unit is immune to aura if it was diminished to 0 duration
if (diminishMod == 0.0f)
@@ -2743,13 +2689,13 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
if (AuraApplication* aurApp = m_spellAura->GetApplicationOfTarget(m_originalCaster->GetGUID()))
positive = aurApp->IsPositive();
- duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
+ duration = m_originalCaster->ModSpellDuration(m_spellInfo, unit, duration, positive, effectMask);
if (duration > 0)
{
// Haste modifies duration of channeled spells
if (m_spellInfo->IsChanneled())
- m_originalCaster->ModSpellDurationTime(aurSpellInfo, duration, this);
+ m_originalCaster->ModSpellDurationTime(m_spellInfo, duration, this);
else if (m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION))
{
int32 origDuration = duration;
@@ -2954,27 +2900,6 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
InitExplicitTargets(*targets);
- // Fill aura scaling information
- if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))
- {
- for (SpellEffectInfo const* effect : GetEffects())
- {
- if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
- {
- // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
- if (m_spellInfo->IsPositiveEffect(effect->EffectIndex))
- {
- m_auraScaleMask |= (1 << effect->EffectIndex);
- if (m_spellValue->EffectBasePoints[effect->EffectIndex] != effect->BasePoints)
- {
- m_auraScaleMask = 0;
- break;
- }
- }
- }
- }
- }
-
m_spellState = SPELL_STATE_PREPARING;
if (triggeredByAura)
@@ -6036,7 +5961,8 @@ SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
int32 Spell::CalculateDamage(uint8 i, Unit const* target, float* var /*= nullptr*/) const
{
- return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i], var, m_castItemLevel);
+ bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << i));
+ return m_caster->CalculateSpellDamage(target, m_spellInfo, i, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[i], var, m_castItemLevel);
}
bool Spell::CanAutoCast(Unit* target)
@@ -7282,7 +7208,7 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
skillId = SkillByLockType(LockType(lockInfo->Index[j]));
- if (skillId != SKILL_NONE || lockInfo->Index[j] == LOCKTYPE_PICKLOCK)
+ if (skillId != SKILL_NONE || lockInfo->Index[j] == LOCKTYPE_LOCKPICKING)
{
reqSkillValue = lockInfo->Skill[j];
@@ -7290,7 +7216,7 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
skillValue = 0;
if (!m_CastItem && m_caster->GetTypeId() == TYPEID_PLAYER)
skillValue = m_caster->ToPlayer()->GetSkillValue(skillId);
- else if (lockInfo->Index[j] == LOCKTYPE_PICKLOCK)
+ else if (lockInfo->Index[j] == LOCKTYPE_LOCKPICKING)
skillValue = m_caster->getLevel() * 5;
// skill bonus provided by casting spell (mostly item spells)
@@ -7317,8 +7243,8 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
{
if (mod < SPELLVALUE_BASE_POINT_END)
{
- if (SpellEffectInfo const* effect = GetEffect(mod))
- m_spellValue->EffectBasePoints[mod] = effect->CalcBaseValue(value);
+ m_spellValue->EffectBasePoints[mod] = value;
+ m_spellValue->CustomBasePointsMask |= 1 << mod;
return;
}
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 88ca04bd7a8..cd4f3f51a08 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -295,8 +295,9 @@ class TC_GAME_API SpellCastTargets
struct SpellValue
{
- explicit SpellValue(Difficulty diff, SpellInfo const* proto);
+ explicit SpellValue(Difficulty diff, SpellInfo const* proto, Unit const* caster);
int32 EffectBasePoints[MAX_SPELL_EFFECTS];
+ uint32 CustomBasePointsMask;
uint32 MaxAffectedTargets;
float RadiusMod;
uint8 AuraStackAmount;
@@ -787,7 +788,6 @@ class TC_GAME_API Spell
bool processed;
bool alive;
bool crit;
- bool scaleAura;
};
std::vector<TargetInfo> m_UniqueTargetInfo;
uint32 m_channelTargetEffectMask; // Mask req. alive targets
@@ -816,7 +816,7 @@ class TC_GAME_API Spell
void AddDestTarget(SpellDestination const& dest, uint32 effIndex);
void DoAllEffectOnTarget(TargetInfo* target);
- SpellMissInfo DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleAura);
+ SpellMissInfo DoSpellHitOnUnit(Unit* unit, uint32 effectMask);
void DoTriggersOnSpellHit(Unit* unit, uint32 effMask);
void DoAllEffectOnTarget(GOTargetInfo* target);
void DoAllEffectOnTarget(ItemTargetInfo* target);
@@ -883,7 +883,6 @@ class TC_GAME_API Spell
SpellInfo const* m_triggeredByAuraSpell;
bool m_skipCheck;
- uint32 m_auraScaleMask;
std::unique_ptr<PathGenerator> m_preGeneratedPath;
std::vector<SpellLogEffectPowerDrainParams> _powerDrainTargets[MAX_SPELL_EFFECTS];
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index cc39622cc41..d1ae93cd318 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -461,12 +461,59 @@ bool SpellEffectInfo::IsUnitOwnedAuraEffect() const
int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, int32 itemLevel /*= -1*/) const
{
float basePointsPerLevel = RealPointsPerLevel;
- int32 basePoints = bp ? *bp : BasePoints;
+ // TODO: this needs to be a float, not rounded
+ int32 basePoints = CalcBaseValue(caster, target, itemLevel);
+ float value = bp ? *bp : basePoints;
float comboDamage = PointsPerResource;
+ if (Scaling.Variance)
+ {
+ float delta = fabs(Scaling.Variance * 0.5f);
+ float valueVariance = frand(-delta, delta);
+ value += basePoints * valueVariance;
+
+ if (variance)
+ *variance = valueVariance;
+ }
+
// base amount modification based on spell lvl vs caster lvl
if (Scaling.Coefficient != 0.0f)
{
+ if (Scaling.ResourceCoefficient)
+ comboDamage = Scaling.ResourceCoefficient * value;
+ }
+ else
+ {
+ if (GetScalingExpectedStat() == ExpectedStatType::None)
+ {
+ int32 level = caster ? int32(caster->getLevel()) : 0;
+ if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
+ level = int32(_spellInfo->MaxLevel);
+ level -= int32(_spellInfo->BaseLevel);
+ if (level < 0)
+ level = 0;
+ value += level * basePointsPerLevel;
+ }
+ }
+
+ // random damage
+ if (caster)
+ {
+ // bonus amount from combo points
+ if (caster->m_playerMovingMe && comboDamage)
+ if (uint32 comboPoints = caster->m_playerMovingMe->GetComboPoints())
+ value += comboDamage * comboPoints;
+
+ value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
+ }
+
+ return int32(round(value));
+}
+
+int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, int32 itemLevel) const
+{
+ if (Scaling.Coefficient != 0.0f)
+ {
uint32 level = _spellInfo->SpellLevel;
if (target && _spellInfo->IsPositiveEffect(EffectIndex) && (Effect == SPELL_EFFECT_APPLY_AURA))
level = target->getLevel();
@@ -520,25 +567,11 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
if (value != 0.0f && value < 1.0f)
value = 1.0f;
- if (Scaling.Variance)
- {
- float delta = fabs(Scaling.Variance * 0.5f);
- float valueVariance = frand(-delta, delta);
- value += value * valueVariance;
-
- if (variance)
- *variance = valueVariance;
- }
-
- basePoints = int32(round(value));
-
- if (Scaling.ResourceCoefficient)
- comboDamage = Scaling.ResourceCoefficient * value;
+ return int32(round(value));
}
else
{
- int32 level = caster ? int32(caster->getLevel()) : 0;
- float value = basePoints;
+ float value = BasePoints;
ExpectedStatType stat = GetScalingExpectedStat();
if (stat != ExpectedStatType::None)
{
@@ -546,51 +579,12 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
stat = ExpectedStatType::CreatureAutoAttackDps;
// TODO - add expansion and content tuning id args?
- value = sDB2Manager.EvaluateExpectedStat(stat, level, -2, 0, CLASS_NONE) * value / 100.0f;
- }
-
- if (Scaling.Variance)
- {
- float delta = fabs(Scaling.Variance * 0.5f);
- float valueVariance = frand(-delta, delta);
- value += value * valueVariance;
-
- if (variance)
- *variance = valueVariance;
+ int32 level = caster ? int32(caster->getLevel()) : 1;
+ value = sDB2Manager.EvaluateExpectedStat(stat, level, -2, 0, CLASS_NONE) * BasePoints / 100.0f;
}
- if (stat == ExpectedStatType::None)
- {
- if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
- level = int32(_spellInfo->MaxLevel);
- level -= int32(_spellInfo->BaseLevel);
- if (level < 0)
- level = 0;
- value += level * basePointsPerLevel;
- }
-
- basePoints = int32(round(value));
+ return int32(round(value));
}
-
- float value = float(basePoints);
-
- // random damage
- if (caster)
- {
- // bonus amount from combo points
- if (caster->m_playerMovingMe && comboDamage)
- if (uint32 comboPoints = caster->m_playerMovingMe->GetComboPoints())
- value += comboDamage * comboPoints;
-
- value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
- }
-
- return int32(value);
-}
-
-int32 SpellEffectInfo::CalcBaseValue(int32 value) const
-{
- return value;
}
float SpellEffectInfo::CalcValueMultiplier(Unit* caster, Spell* spell) const
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index d1f8c40bb4b..0e04e33937d 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -368,7 +368,7 @@ public:
bool IsUnitOwnedAuraEffect() const;
int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, int32 itemLevel = -1) const;
- int32 CalcBaseValue(int32 value) const;
+ int32 CalcBaseValue(Unit const* caster, Unit const* target, int32 itemLevel) const;
float CalcValueMultiplier(Unit* caster, Spell* spell = NULL) const;
float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const;