rendered paste bodyIndex: game/Unit.cpp
===================================================================
--- game/Unit.cpp (revision 5328)
+++ game/Unit.cpp (working copy)
@@ -6321,6 +6321,7 @@
uint32 CastingTime = GetSpellCastTime(sCastTimesStore.LookupEntry(spellProto->CastingTimeIndex));
if (CastingTime > 7000) CastingTime = 7000; // Plus Damage efficient maximum 200% ( 7.0 seconds )
if (CastingTime < 1500) CastingTime = 1500;
+ bool Channeled = (bool)(spellProto->ChannelInterruptFlags);
// Taken/Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonus((int32)(1<<spellProto->School));
@@ -6330,13 +6331,14 @@
float DotFactor = 1.0f;
if(damagetype == DOT)
{
- CastingTime = 3500;
+ if ( !Channeled )
+ CastingTime = 3500;
int32 DotDuration = GetSpellDuration(spellProto);
// 200% limit
if(DotDuration > 0)
{
if(DotDuration > 30000) DotDuration = 30000;
- DotFactor = DotDuration / 15000.0f;
+ if(!Channeled) DotFactor = DotDuration / 15000.0f;
int x = 0;
for(int j = 0; j < 3; j++)
if(spellProto->Effect[j] == 6) x = j;
@@ -6387,10 +6389,55 @@
TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break;
}
}
+
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// Exceptions
switch(spellProto->SpellFamilyName)
{
+ case SPELLFAMILY_PALADIN:
+ // Consecration - 95% of Holy Damage
+ if((spellProto->SpellFamilyFlags & 0x20LL) && spellProto->SpellIconID == 51)
+ {
+ DotFactor = 0.95f;
+ CastingTime = 3500;
+ }
+ // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed
+ else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25)
+ {
+ Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
+ float wspeed = GetAttackTime(BASE_ATTACK)/1000;
+
+ if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON)
+ CastingTime = (uint32)wspeed*3500*0.102f;
+ else
+ CastingTime = (uint32)wspeed*3500*0.098f;
+ }
+ // Judgement of Righteousness - 73%
+ else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25)
+ {
+ CastingTime = 2555;
+ }
+ // Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications
+ else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2040)
+ {
+ DotFactor = 0.136;
+ CastingTime = 3500;
+ }
+ // Seal of Command - 20% of Done Holy Damage, 29% of Taken Holy Damage
+ else if (spellProto->Id == 20424)
+ {
+ CastingTime = 3500;
+ DoneTotalMod = 0.2f;
+ TakenTotalMod = 0.29f;
+ }
+ // Holy shield - 5% of Holy Damage
+ else if ((spellProto->SpellFamilyFlags & 0x4000000000LL) && spellProto->SpellIconID == 453)
+ {
+ CastingTime = 175;
+ }
+ break;
case SPELLFAMILY_WARLOCK:
// Life Tap
if((spellProto->SpellFamilyFlags & 0x40000LL) && spellProto->SpellIconID == 208)
@@ -6406,6 +6453,46 @@
DoneTotalMod = 1.0f;
TakenTotalMod = 1.0f;
}
+ // Soul Fire - 115% of Fire Damage
+ else if((spellProto->SpellFamilyFlags & 0x8000000000LL) && spellProto->SpellIconID == 184)
+ {
+ CastingTime = 4025;
+ }
+ // Death Coil - 21.4% of Shadow Damage
+ else if((spellProto->SpellFamilyFlags & 0x80000LL) && spellProto->SpellIconID == 88)
+ {
+ CastingTime = 749;
+ }
+ // Curse of Agony - 120% of Shadow Damage
+ else if((spellProto->SpellFamilyFlags & 0x0000000400LL) && spellProto->SpellIconID == 544)
+ {
+ DotFactor = 1.2f;
+ }
+ // Siphon Life - 100% of Shadow Damage
+ else if((spellProto->SpellFamilyFlags & 0x0100000000LL) && spellProto->SpellIconID == 152)
+ {
+ DotFactor = 1.0f;
+ }
+ // Drain Life
+ else if((spellProto->SpellFamilyFlags & 0x8LL) && spellProto->SpellIconID == 546)
+ {
+ CastingTime = 2500;
+ }
+ // Drain Mana - 0% of Shadow Damage
+ else if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 548)
+ {
+ CastingTime = 0;
+ }
+ // Drain Soul 214.3%
+ else if ((spellProto->SpellFamilyFlags & 0x4000LL) && spellProto->SpellIconID == 113 )
+ {
+ CastingTime = 7500;
+ }
+ // Hellfire
+ else if ((spellProto->SpellFamilyFlags & 0x40LL) && spellProto->SpellIconID == 937)
+ {
+ CastingTime = damagetype == DOT ? 5000 : 500; // self damage seems to be so
+ }
break;
case SPELLFAMILY_MAGE:
// Ice Lance
@@ -6415,9 +6502,33 @@
if(pVictim->isFrozen()) // and compensate this for frozen target.
TakenTotalMod *= 3.0f;
}
+ // Pyroblast - 115% of Fire Damage, DoT - 20% of Fire Damage
+ else if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 184 )
+ {
+ DotFactor = damagetype == DOT ? 0.2f : 1.0f;
+ CastingTime = damagetype == DOT ? 3500 : 4025;
+ }
+ // Fireball - 100% of Fire Damage, DoT - 0% of Fire Damage
+ else if((spellProto->SpellFamilyFlags & 0x1LL) && spellProto->SpellIconID == 185)
+ {
+ CastingTime = 3500;
+ DotFactor = damagetype == DOT ? 0 : 1.0f;
+ }
// Molten armor
else if (spellProto->SpellFamilyFlags & 0x0000000800000000LL)
+ {
CastingTime = 0;
+ }
+ // Arcane Missiles triggered spell
+ else if ((spellProto->SpellFamilyFlags & 0x200000LL) && spellProto->SpellIconID == 225)
+ {
+ CastingTime = 1000;
+ }
+ // Blizzard triggered spell
+ else if ((spellProto->SpellFamilyFlags & 0x80080LL) && spellProto->SpellIconID == 285)
+ {
+ CastingTime = 500;
+ }
break;
case SPELLFAMILY_SHAMAN:
// totem attack
@@ -6434,6 +6545,33 @@
else if (spellProto->SpellFamilyFlags & 000000400LL)
CastingTime = 1155; // ignore CastingTimePenalty and use as modifier
break;
+ case SPELLFAMILY_PRIEST:
+ // Mana Burn - 0% of Shadow Damage
+ if((spellProto->SpellFamilyFlags & 0x10LL) && spellProto->SpellIconID == 212)
+ {
+ CastingTime = 0;
+ }
+ // Mind Flay - 59% of Shadow Damage
+ else if((spellProto->SpellFamilyFlags & 0x800000LL) && spellProto->SpellIconID == 548)
+ {
+ CastingTime = 2065;
+ }
+ // Holy Fire - 86.71%, DoT - 16.5%
+ else if ((spellProto->SpellFamilyFlags & 0x100000LL) && spellProto->SpellIconID == 156)
+ {
+ DotFactor = damagetype == DOT ? 0.165f : 1.0f;
+ CastingTime = damagetype == DOT ? 3500 : 3035;
+ }
+ break;
+ case SPELLFAMILY_DRUID:
+ // Hurricane triggered spell
+ if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220)
+ {
+ CastingTime = 500;
+ }
+ break;
+ default:
+ break;
}
// Level Factor
@@ -6680,6 +6818,10 @@
AdvertisedBenefit /= DotTicks;
}
}
+
+ // distribute healing to all effects, reduce AoE damage
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+
// Exception
switch (spellProto->SpellFamilyName)
{
@@ -8991,3 +9133,107 @@
else
ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-val,apply);
}
+
+
+uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime )
+{
+ int32 overTime=0;
+ bool DirectDamage=false;
+ bool AreaEffect=false;
+
+ for ( uint32 i=0; i<3;i++)
+ {
+ switch ( spellProto->Effect[i] )
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_MANA_DRAIN:
+ case SPELL_EFFECT_HEALTH_LEECH:
+ case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE:
+ case SPELL_EFFECT_POWER_BURN:
+ case SPELL_EFFECT_HEAL:
+ DirectDamage = true;
+ break;
+ case SPELL_EFFECT_APPLY_AURA:
+ switch ( spellProto->EffectApplyAuraName[i] )
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_PERIODIC_LEECH:
+ if ( GetSpellDuration(spellProto) )
+ overTime = GetSpellDuration(spellProto);
+ break;
+ default:
+ // -5% per additional effect
+ CastingTime *= 0.95f;
+ break;
+ }
+ default:
+ break;
+ }
+
+ switch (spellProto->EffectImplicitTargetA[i])
+ {
+ case TARGET_AREAEFFECT_CUSTOM:
+ case TARGET_ALL_ENEMY_IN_AREA:
+ case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
+ case TARGET_ALL_PARTY_AROUND_CASTER:
+ case TARGET_ALL_AROUND_CASTER:
+ case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
+ case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
+ case TARGET_ALL_PARTY:
+ case TARGET_ALL_PARTY_AROUND_CASTER_2:
+ case TARGET_AREAEFFECT_PARTY:
+ case TARGET_AREAEFFECT_CUSTOM_2:
+ case TARGET_AREAEFFECT_PARTY_AND_CLASS:
+ AreaEffect = true;
+ break;
+ default:
+ break;
+ }
+
+ switch (spellProto->EffectImplicitTargetB[i])
+ {
+ case TARGET_AREAEFFECT_CUSTOM:
+ case TARGET_ALL_ENEMY_IN_AREA:
+ case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
+ case TARGET_ALL_PARTY_AROUND_CASTER:
+ case TARGET_ALL_AROUND_CASTER:
+ case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
+ case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
+ case TARGET_ALL_PARTY:
+ case TARGET_ALL_PARTY_AROUND_CASTER_2:
+ case TARGET_AREAEFFECT_PARTY:
+ case TARGET_AREAEFFECT_CUSTOM_2:
+ case TARGET_AREAEFFECT_PARTY_AND_CLASS:
+ AreaEffect = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Combined Spells with Both Over Time and Direct Damage
+ if ( overTime > 0 && CastingTime > 0 && DirectDamage )
+ {
+ // mainly for DoTs which are 3500 here otherwise
+ uint32 OriginalCastTime = GetSpellCastTime(sCastTimesStore.LookupEntry(spellProto->CastingTimeIndex));
+ if (OriginalCastTime > 7000) OriginalCastTime = 7000;
+ if (OriginalCastTime < 1500) OriginalCastTime = 1500;
+ // Portion to Over Time
+ float PtOT = (overTime / 15000.f) / ((overTime / 15000.f) + (OriginalCastTime / 3500.f));
+
+ if ( damagetype == DOT )
+ CastingTime *= PtOT;
+ else if ( PtOT < 1 )
+ CastingTime *= 1 - PtOT;
+ else
+ CastingTime = 0;
+ }
+
+ // Area Effect Spells recieve only half of bonus
+ if ( AreaEffect )
+ CastingTime *= 0.5f;
+
+ return CastingTime;
+}
+
Index: game/Unit.h
===================================================================
--- game/Unit.h (revision 5328)
+++ game/Unit.h (working copy)
@@ -962,6 +962,7 @@
int32 SpellBaseHealingBonusForVictim(int32 SchoolMask, Unit *pVictim);
uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
+ uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime );
bool SpellCriticalBonus(SpellEntry const *spellProto, uint32 *damage, Unit *pVictim);
void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL);
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);