Skip to content

Commit

Permalink
[8635] Rewrote bonus damage claculation
Browse files Browse the repository at this point in the history
* calculation depends on the damageClass now
  ->SPELL_DAMAGE_CLASS_RANGED & SPELL_DAMAGE_CLASS_MELEE use MeleeDamageBonus()
  ->SPELL_DAMAGE_CLASS_MAGIC & SPELL_DAMAGE_CLASS_RANGED use SpellDamageBonus()
* changes/improvements in MeleeDamageBonus:
  -> improved criterions to apply bonuses
  -> implemented scaling of FLAT damage Bonus for non weapon damage based spells
  -> support of DOT's
  -> added pet's bonus damage for non weapon based spells
* general cleanup in CalculateSpellDamage() and MeleeDamageBonus()
* implemented global helper functions GetWeaponAttackType() and GetAuraTicks() in SpellMgr

Signed-off-by: ApoC <apoc@nymfe.net>
  • Loading branch information
pasdVn authored and apoc committed Oct 13, 2009
1 parent 9be5f7c commit e6e7363
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 280 deletions.
9 changes: 9 additions & 0 deletions src/game/SharedDefines.h
Expand Up @@ -1004,6 +1004,15 @@ enum SpellImmunity

#define MAX_SPELL_IMMUNITY 6

enum WeaponAttackType
{
BASE_ATTACK = 0,
OFF_ATTACK = 1,
RANGED_ATTACK = 2
};

#define MAX_ATTACK 3

enum Targets
{
TARGET_SELF = 1,
Expand Down
22 changes: 2 additions & 20 deletions src/game/Spell.cpp
Expand Up @@ -351,25 +351,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_applyMultiplierMask = 0;

// Get data for type of attack
switch (m_spellInfo->DmgClass)
{
case SPELL_DAMAGE_CLASS_MELEE:
if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
m_attackType = OFF_ATTACK;
else
m_attackType = BASE_ATTACK;
break;
case SPELL_DAMAGE_CLASS_RANGED:
m_attackType = RANGED_ATTACK;
break;
default:
// Wands
if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
m_attackType = RANGED_ATTACK;
else
m_attackType = BASE_ATTACK;
break;
}
m_attackType = GetWeaponAttackType(m_spellInfo);

m_spellSchoolMask = GetSpellSchoolMask(info); // Can be override for some spell (wand shoot for example)

Expand Down Expand Up @@ -997,7 +979,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);

// Add bonuses and fill damageInfo struct
caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo);
caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo, m_attackType);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);

// Send log damage message to client
Expand Down
16 changes: 12 additions & 4 deletions src/game/SpellAuras.cpp
Expand Up @@ -6281,18 +6281,26 @@ void Aura::PeriodicTick()
{
pdamage = amount;

// SpellDamageBonus for magic spells
if(GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_NONE || GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
// MeleeDamagebonus for weapon based spells
else
{
WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto());
pdamage = pCaster->MeleeDamageBonus(m_target, pdamage, attackType, GetSpellProto(), DOT, GetStackAmount());
}

// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
{
uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}

pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());

// Curse of Agony damage-per-tick calculation
if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544)
{
Expand Down
6 changes: 1 addition & 5 deletions src/game/SpellEffects.cpp
Expand Up @@ -4609,11 +4609,7 @@ void Spell::EffectWeaponDmg(uint32 i)
bonus = int32(bonus*totalDamagePercentMod);

// prevent negative damage
uint32 eff_damage = uint32(bonus > 0 ? bonus : 0);

// Add melee damage bonuses (also check for negative)
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
m_damage+= eff_damage;
m_damage+= uint32(bonus > 0 ? bonus : 0);

// Hemorrhage
if (m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x2000000)))
Expand Down
54 changes: 54 additions & 0 deletions src/game/SpellMgr.cpp
Expand Up @@ -90,6 +90,60 @@ uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
return (castTime > 0) ? uint32(castTime) : 0;
}

uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo)
{
int32 DotDuration = GetSpellDuration(spellInfo);
if(DotDuration == 0)
return 1;

// 200% limit
if(DotDuration > 30000)
DotDuration = 30000;

int j = 0;
for( ; j < 3; j++)
{
if( spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
{
break;
}
}

if(spellInfo->EffectAmplitude[j] != 0)
return DotDuration / spellInfo->EffectAmplitude[j];

return 6;
}

WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo)
{
if(!spellInfo)
return BASE_ATTACK;

switch (spellInfo->DmgClass)
{
case SPELL_DAMAGE_CLASS_MELEE:
if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
return OFF_ATTACK;
else
return BASE_ATTACK;
break;
case SPELL_DAMAGE_CLASS_RANGED:
return RANGED_ATTACK;
break;
default:
// Wands
if (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
return RANGED_ATTACK;
else
return BASE_ATTACK;
break;
}
}

bool IsPassiveSpell(uint32 spellId)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
Expand Down
2 changes: 2 additions & 0 deletions src/game/SpellMgr.h
Expand Up @@ -125,6 +125,8 @@ inline float GetSpellMaxRange(SpellRangeEntry const *range, bool friendly = fals
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
int32 GetSpellDuration(SpellEntry const *spellInfo);
int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo);
WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo);

inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
{
Expand Down

3 comments on commit e6e7363

@przemratajczak
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! at last, thx

@goldberg002
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!!!! :D

@nowonshere
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WoW! This is a great patch, thanks to you guys! ;)

Please sign in to comment.