Index: game/Unit.cpp =================================================================== --- game/Unit.cpp (revision 5362) +++ game/Unit.cpp (working copy) @@ -6376,6 +6376,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<School)); @@ -6385,13 +6386,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; @@ -6470,9 +6574,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 @@ -9051,3 +9238,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; +} +