Permalink
Browse files

Spell damage reduction is now working properly, no flaws have been no…

…ticed, yet.
  • Loading branch information...
neo-mat committed Feb 2, 2012
2 parents 664a466 + b5d7d58 commit 1542910d40f38edc4a23250c72eb2f97c762e678
Showing with 68 additions and 51 deletions.
  1. +10 −6 src/arcemu-world/Object.cpp
  2. +7 −3 src/arcemu-world/SpellAuras.cpp
  3. +49 −41 src/arcemu-world/Unit.cpp
  4. +2 −1 src/arcemu-world/Unit.h
@@ -1669,19 +1669,20 @@ void Object::SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage
//------------------------------by stats----------------------------------------------------
if(IsUnit() && !static_damage)
{
Unit* caster = TO_UNIT(this);
Unit* caster = TO< Unit* >(this);
caster->RemoveAurasByInterruptFlag(AURA_INTERRUPT_ON_START_ATTACK);
res += caster->GetSpellDmgBonus(pVictim, spellInfo, (int)res, false);
// this calculates whole dmg with all bonuses / mods
res = static_cast< float >(caster->GetSpellDmgBonus(pVictim, spellInfo, damage, false));
if(res < 0)
res = 0;
if(res < 0.0f)
res = 0.0f;
}
//==========================================================================================
//==============================Post +SpellDamage Bonus Modifications=======================
//==========================================================================================
if(res > 0 && !(spellInfo->AttributesExB & ATTRIBUTESEXB_CANT_CRIT))
if(res > 0.0f && !(spellInfo->AttributesExB & ATTRIBUTESEXB_CANT_CRIT))
{
critical = this->IsCriticalDamageForSpell(pVictim, spellInfo);
@@ -1718,10 +1719,13 @@ void Object::SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage
}
}
//==========================================================================================
//==========================================================================================
//==============================Post Roll Calculations======================================
//==========================================================================================
//------------------------------damage reduction--------------------------------------------
if( this->IsUnit() )
res += TO< Unit* >(this)->CalcSpellDamageReduction(pVictim, spellInfo, res);
//------------------------------absorption--------------------------------------------------
uint32 ress = (uint32)res;
uint32 abs_dmg = pVictim->AbsorbDamage(spellInfo->School, &ress);
@@ -1816,12 +1816,16 @@ void Aura::EventPeriodicDamage(uint32 amount)
amp = event_GetEventPeriod(EVENT_AURA_PERIODIC_DAMAGE);
if(GetDuration() && GetSpellProto()->NameHash != SPELL_HASH_IGNITE) //static damage for Ignite. Need to be reworked when "static DoTs" will be implemented
{
bonus += c->GetSpellDmgBonus(m_target, m_spellProto, amount, true) * amp / GetDuration();
res += static_cast< float >( bonus );
res += bonus;
// damage taken is reduced after bonus damage is calculated and added
res += c->CalcSpellDamageReduction(m_target, m_spellProto, res);
}
if(res < 0)
res = 0;
if(res < 0.0f)
res = 0.0f;
else
{
float summaryPCTmod = 1.0f;
View
@@ -308,7 +308,6 @@ Unit::Unit()
HealTakenMod[i] = 0;
HealTakenPctMod[i] = 0;
DamageTakenMod[i] = 0;
DamageDoneModPCT[i] = 0;
SchoolCastPrevent[i] = 0;
DamageTakenPctMod[i] = 0;
SpellCritChanceSchool[i] = 0;
@@ -3604,7 +3603,6 @@ void Unit::Strike(Unit* pVictim, uint32 weapon_damage_type, SpellEntry* ability,
dmg.full_damage += float2int32(dmg.full_damage * pVictim->DamageTakenPctMod[ dmg.school_type ]);
dmg.full_damage += float2int32(dmg.full_damage * DamageDoneModPCT[dmg.school_type]);
if(dmg.school_type != SCHOOL_NORMAL)
dmg.full_damage += float2int32(dmg.full_damage * (GetDamageDonePctMod(dmg.school_type) - 1));
@@ -5121,7 +5119,7 @@ void Unit::castSpell(Spell* pSpell)
int32 Unit::GetSpellDmgBonus(Unit* pVictim, SpellEntry* spellInfo, int32 base_dmg, bool isdot)
{
int32 plus_damage = 0;
float plus_damage = 0.0f;
Unit* caster = this;
uint32 school = spellInfo->School;
@@ -5144,7 +5142,7 @@ int32 Unit::GetSpellDmgBonus(Unit* pVictim, SpellEntry* spellInfo, int32 base_dm
//------------------------------by school---------------------------------------------------
plus_damage += caster->GetDamageDoneMod(school);
plus_damage += pVictim->DamageTakenMod[school];
plus_damage += static_cast< int32 >( base_dmg * (caster->GetDamageDonePctMod(school)-1) ); //value is initialized with 1
//------------------------------by victim type----------------------------------------------
if(!pVictim->IsPlayer() && caster->IsPlayer())
plus_damage += TO< Player* >(caster)->IncreaseDamageByType[TO_CREATURE(pVictim)->GetCreatureInfo()->Type];
@@ -5153,81 +5151,91 @@ int32 Unit::GetSpellDmgBonus(Unit* pVictim, SpellEntry* spellInfo, int32 base_dm
//==========================================================================================
//------------------------------by cast duration--------------------------------------------
float dmgdoneaffectperc = 1.0f;
if(spellInfo->Dspell_coef_override >= 0 && !isdot)
plus_damage = float2int32(plus_damage * spellInfo->Dspell_coef_override);
else if(spellInfo->OTspell_coef_override >= 0 && isdot)
plus_damage = float2int32(plus_damage * spellInfo->OTspell_coef_override);
else
// do not execute this if plus dmg is 0 or lower
if( plus_damage > 0.0f )
{
//Bonus to DD part
if(spellInfo->fixed_dddhcoef >= 0 && !isdot)
plus_damage = float2int32(plus_damage * spellInfo->fixed_dddhcoef);
//Bonus to DoT part
else if(spellInfo->fixed_hotdotcoef >= 0 && isdot)
if( spellInfo->Dspell_coef_override >= 0 && !isdot )
plus_damage = plus_damage * spellInfo->Dspell_coef_override;
else if( spellInfo->OTspell_coef_override >= 0 && isdot )
plus_damage = plus_damage * spellInfo->OTspell_coef_override;
else
{
plus_damage = float2int32(plus_damage * spellInfo->fixed_hotdotcoef);
if(caster->IsPlayer())
//Bonus to DD part
if( spellInfo->fixed_dddhcoef >= 0 && !isdot )
plus_damage = plus_damage * spellInfo->fixed_dddhcoef;
//Bonus to DoT part
else if( spellInfo->fixed_hotdotcoef >= 0 && isdot )
{
int durmod = 0;
SM_FIValue(caster->SM_FDur, &durmod, spellInfo->SpellGroupType);
plus_damage += plus_damage * durmod / 15000;
plus_damage = plus_damage * spellInfo->fixed_hotdotcoef;
if(caster->IsPlayer())
{
int32 durmod = 0;
SM_FIValue( caster->SM_FDur, &durmod, spellInfo->SpellGroupType );
plus_damage += static_cast< float >( plus_damage * durmod / 15000 );
}
}
//In case we dont fit in previous cases do old thing
else
{
plus_damage = plus_damage * spellInfo->casttime_coef;
float td = static_cast< float >( GetDuration( dbcSpellDuration.LookupEntry( spellInfo->DurationIndex ) ) );
if( spellInfo->NameHash == SPELL_HASH_MOONFIRE
|| spellInfo->NameHash == SPELL_HASH_IMMOLATE
|| spellInfo->NameHash == SPELL_HASH_ICE_LANCE
|| spellInfo->NameHash == SPELL_HASH_PYROBLAST )
plus_damage = plus_damage * ( 1.0f - ( ( td / 15000.0f ) / ( ( td / 15000.0f ) + dmgdoneaffectperc ) ) );
}
}
//In case we dont fit in previous cases do old thing
else
{
plus_damage = float2int32(plus_damage * spellInfo->casttime_coef);
float td = float(GetDuration(dbcSpellDuration.LookupEntry(spellInfo->DurationIndex)));
if(spellInfo->NameHash == SPELL_HASH_MOONFIRE || spellInfo->NameHash == SPELL_HASH_IMMOLATE || spellInfo->NameHash == SPELL_HASH_ICE_LANCE || spellInfo->NameHash == SPELL_HASH_PYROBLAST)
plus_damage = float2int32(plus_damage * (1.0f - ((td / 15000.0f) / ((td / 15000.0f) + dmgdoneaffectperc))));
}
}
//------------------------------by downranking----------------------------------------------
//DOT-DD (Moonfire-Immolate-IceLance-Pyroblast)(Hack Fix)
if(spellInfo->baseLevel > 0 && spellInfo->maxLevel > 0)
if( spellInfo->baseLevel > 0 && spellInfo->maxLevel > 0 )
{
float downrank1 = 1.0f;
if(spellInfo->baseLevel < 20)
downrank1 = 1.0f - (20.0f - float(spellInfo->baseLevel)) * 0.0375f;
float downrank2 = (spellInfo->maxLevel + 5.0f) / TO< Player* >(caster)->getLevel();
float downrank2 = static_cast< float >( (spellInfo->maxLevel + 5.0f) / TO< Player* >(caster)->getLevel() );
if(downrank2 >= 1 || downrank2 < 0)
downrank2 = 1.0f;
dmgdoneaffectperc *= downrank1 * downrank2;
}
//==========================================================================================
//==============================Bonus Adding To Main Damage=================================
//==========================================================================================
int32 bonus_damage = float2int32(plus_damage * dmgdoneaffectperc);
if((pVictim->HasAuraWithMechanics(MECHANIC_ENSNARED) || pVictim->HasAuraWithMechanics(MECHANIC_DAZED)) && caster->IsPlayer())
bonus_damage += TO< Player* >(caster)->m_IncreaseDmgSnaredSlowed;
plus_damage += static_cast< float >(TO< Player* >(caster)->m_IncreaseDmgSnaredSlowed);
if(spellInfo->SpellGroupType)
{
int32 bonus_damage = 0;
SM_FIValue(caster->SM_FPenalty, &bonus_damage, spellInfo->SpellGroupType);
SM_FIValue(caster->SM_FDamageBonus, &bonus_damage, spellInfo->SpellGroupType);
int dmg_bonus_pct = 0;
int32 dmg_bonus_pct = 0;
SM_FIValue(caster->SM_PPenalty, &dmg_bonus_pct, spellInfo->SpellGroupType);
SM_FIValue(caster->SM_PDamageBonus, &dmg_bonus_pct, spellInfo->SpellGroupType);
bonus_damage += (base_dmg + bonus_damage) * dmg_bonus_pct / 100;
plus_damage += static_cast< float >( (base_dmg + bonus_damage) * dmg_bonus_pct / 100 );
}
//------------------------------by school----------------------------------------------
float summaryPCTmod = caster->GetDamageDonePctMod(school) - 1; //value is initialized with 1
summaryPCTmod += pVictim->DamageTakenPctMod[school];
summaryPCTmod += caster->DamageDoneModPCT[school]; // BURLEX FIX ME
summaryPCTmod += pVictim->ModDamageTakenByMechPCT[spellInfo->MechanicsType];
int32 res = (int32)((base_dmg + bonus_damage) * summaryPCTmod + bonus_damage);
if(res < 0)
res = 0;
int32 res = static_cast< int32 >( (base_dmg * dmgdoneaffectperc) + plus_damage );
return res;
}
float Unit::CalcSpellDamageReduction(Unit* victim, SpellEntry* spell, float res)
{
float reduced_damage = 0;
reduced_damage += static_cast< float >( victim->DamageTakenMod[spell->School] );
reduced_damage += res * victim->DamageTakenPctMod[spell->School];
reduced_damage += res * victim->ModDamageTakenByMechPCT[spell->MechanicsType];
return reduced_damage;
}
void Unit::InterruptSpell()
{
if(m_currentSpell)
View
@@ -1236,6 +1236,8 @@ class SERVER_DECL Unit : public Object
//caller is the caster
int32 GetSpellDmgBonus(Unit* pVictim, SpellEntry* spellInfo, int32 base_dmg, bool isdot);
float CalcSpellDamageReduction(Unit* victim, SpellEntry* spell, float res);
uint32 m_addDmgOnce;
uint32 m_ObjectSlots[4];
uint32 m_triggerSpell;
@@ -1303,7 +1305,6 @@ class SERVER_DECL Unit : public Object
virtual int32 GetDamageDoneMod(uint32 school) { return 0; }
virtual float GetDamageDonePctMod(uint32 school) { return 0; }
float DamageDoneModPCT[SCHOOL_COUNT];
int32 DamageTakenMod[SCHOOL_COUNT];
float DamageTakenPctMod[SCHOOL_COUNT];
float DamageTakenPctModOnHP35;

3 comments on commit 1542910

@MesoX

This comment has been minimized.

Show comment
Hide comment
@MesoX

MesoX Feb 2, 2012

Contributor

Hah, nice to see part of my work in ArcEmu finally :P :D

Contributor

MesoX replied Feb 2, 2012

Hah, nice to see part of my work in ArcEmu finally :P :D

@neo-mat

This comment has been minimized.

Show comment
Hide comment
@neo-mat

neo-mat Feb 2, 2012

Member

Well if you wudn't touch it, I doubt anyone would have looked into that for long time. Nobody is dare to touch Unit.cpp because it's really weird place, just like dark side of youtube where you can watch some mexicans dancing and singing for 10 hours...

Member

neo-mat replied Feb 2, 2012

Well if you wudn't touch it, I doubt anyone would have looked into that for long time. Nobody is dare to touch Unit.cpp because it's really weird place, just like dark side of youtube where you can watch some mexicans dancing and singing for 10 hours...

@MesoX

This comment has been minimized.

Show comment
Hide comment
@MesoX

MesoX Feb 2, 2012

Contributor

It was like pain in ass doing it, I've spent like 3 weeks on it and still wasn't complete. But thanks you finished it.

Contributor

MesoX replied Feb 2, 2012

It was like pain in ass doing it, I've spent like 3 weeks on it and still wasn't complete. But thanks you finished it.

Please sign in to comment.