[9894] Move GetCastingTimeForBonus and some other code to GetSpellCastTimeForBonus.

Important changes:

* Chaged way caluclation "-5% of total per any additional effect" to percent
  apply instead use raw value that correct only for 3500 cast time spells.
* GetSpellCastTimeForBonus result now alwasy not applied to creature casted spells
  Before it not applied only to instant spells. Please test if this ok in all cases.
* Leech effect modify spell casting time move into GetCastingTimeForBonus and then called
  also for melee spells. But only creature spells exist with melee class damage and its
  not affected by GetCastingTimeForBonus anyway now.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
nos4r2zod 2010-05-15 05:23:51 +04:00 committed by VladimirMangos
parent 34a1cc31d0
commit 4951f846dd
5 changed files with 157 additions and 153 deletions

View file

@ -9187,21 +9187,16 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
if (uint16 DotTicks = GetSpellAuraMaxTicks(spellProto))
DoneAdvertisedBenefit = DoneAdvertisedBenefit / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
{
if (spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
(spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA &&
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
}
}
DoneTotal += int32(DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage);
// Not apply this to creature casted spells
float coeff;
if (GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
DoneTotal += int32(DoneAdvertisedBenefit * coeff * DotFactor * LvlPenalty * SpellModSpellDamage);
}
float tmpDamage = (int32(pdamage) + DoneTotal * int32(stack)) * DoneTotalMod;
@ -9294,21 +9289,16 @@ uint32 Unit::SpellDamageBonusTaken(Unit *pCaster, SpellEntry const *spellProto,
if (uint16 DotTicks = GetSpellAuraMaxTicks(spellProto))
TakenAdvertisedBenefit = TakenAdvertisedBenefit / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
{
if (spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
(spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA &&
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
}
}
TakenTotal+= int32(TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty);
// Not apply this to creature casted spells
float coeff;
if (pCaster->GetTypeId()==TYPEID_UNIT && !((Creature*)pCaster)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
TakenTotal+= int32(TakenAdvertisedBenefit * coeff * DotFactor * LvlPenalty);
}
float tmpDamage = (int32(pdamage) + TakenTotal * int32(stack)) * TakenTotalMod;
@ -9744,20 +9734,16 @@ uint32 Unit::SpellHealingBonusDone(Unit *pVictim, SpellEntry const *spellProto,
if(DotTicks)
DoneAdvertisedBenefit = DoneAdvertisedBenefit / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
{
if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
{
CastingTime /= 2;
break;
}
}
DoneTotal += int32(DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage * 1.88f);
// Not apply this to creature casted spells
float coeff;
if (GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
DoneTotal += int32(DoneAdvertisedBenefit * coeff * DotFactor * LvlPenalty * SpellModSpellDamage * 1.88f);
}
// use float as more appropriate for negative values and percent applying
@ -9827,20 +9813,16 @@ uint32 Unit::SpellHealingBonusTaken(Unit *pCaster, SpellEntry const *spellProto,
if(DotTicks)
TakenAdvertisedBenefit = TakenAdvertisedBenefit / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
{
if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
{
CastingTime /= 2;
break;
}
}
TakenTotal += int32(TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * 1.88f);
// Not apply this to creature casted spells
float coeff;
if (GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
TakenTotal += int32(TakenAdvertisedBenefit * coeff * DotFactor * LvlPenalty * 1.88f);
}
AuraList const& mHealingGet= GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
@ -10249,10 +10231,16 @@ uint32 Unit::MeleeDamageBonusDone(Unit *pVictim, uint32 pdamage,WeaponAttackType
if(DotTicks)
DoneFlat = DoneFlat / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
DoneFlat *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
// Not apply this to creature casted spells
float coeff;
if (GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
DoneFlat *= coeff * DotFactor * LvlPenalty;
}
}
// weapon damage based spells
@ -10403,10 +10391,16 @@ uint32 Unit::MeleeDamageBonusTaken(Unit *pCaster, uint32 pdamage,WeaponAttackTyp
if(DotTicks)
TakenFlat = TakenFlat / DotTicks;
}
// Distribute Damage over multiple effects, reduce by AoE
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
TakenFlat*= (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
// Not apply this to creature casted spells
float coeff;
if (pCaster->GetTypeId()==TYPEID_UNIT && !((Creature*)pCaster)->isPet())
coeff = 1.0f;
else
coeff = GetSpellCastTimeForBonus(spellProto, damagetype) / 3500.0f;
TakenFlat*= coeff * DotFactor * LvlPenalty;
}
}
@ -13253,96 +13247,6 @@ void Unit::ApplyCastTimePercentMod(float val, bool apply )
ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-val,apply);
}
uint32 Unit::GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime )
{
// Not apply this to creature casted spells with casttime==0
if(CastingTime==0 && GetTypeId()==TYPEID_UNIT && !((Creature*)this)->isPet())
return 3500;
if (CastingTime > 7000) CastingTime = 7000;
if (CastingTime < 1500) CastingTime = 1500;
if(damagetype == DOT && !IsChanneledSpell(spellProto))
CastingTime = 3500;
int32 overTime = 0;
uint8 effects = 0;
bool DirectDamage = false;
bool AreaEffect = false;
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
{
switch (spellProto->Effect[i])
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
case SPELL_EFFECT_POWER_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
++effects;
break;
}
default:
break;
}
if (IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetA[i])) || IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetB[i])))
AreaEffect = true;
}
// 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(spellProto);
if (OriginalCastTime > 7000) OriginalCastTime = 7000;
if (OriginalCastTime < 1500) OriginalCastTime = 1500;
// Portion to Over Time
float PtOT = (overTime / 15000.0f) / ((overTime / 15000.0f) + (OriginalCastTime / 3500.0f));
if (damagetype == DOT)
CastingTime = uint32(CastingTime * PtOT);
else if (PtOT < 1.0f)
CastingTime = uint32(CastingTime * (1 - PtOT));
else
CastingTime = 0;
}
// Area Effect Spells receive only half of bonus
if (AreaEffect)
CastingTime /= 2;
// -5% of total per any additional effect
for (uint8 i = 0; i < effects; ++i)
{
if (CastingTime > 175)
{
CastingTime -= 175;
}
else
{
CastingTime = 0;
break;
}
}
return CastingTime;
}
void Unit::UpdateAuraForGroup(uint8 slot)
{
if(GetTypeId() == TYPEID_PLAYER)