mirror of
https://github.com/mangosfour/server.git
synced 2025-12-28 22:37:04 +00:00
Use spell_bonus_data table for store custom damage/healing bonus coefficients
Big thanks ApoC for help create table. Fixed bonuses for stacked periodic Warning need test all coefficients for correct bonus amount. TODO: use this table for absorb bonus calculation use this table for melee spells AP bonuses use chain multipler in final damage/heal amount Signed-off-by: DiSlord <dislord@nomail.com>
This commit is contained in:
parent
6d9a099a19
commit
4ecfbcc2f5
13 changed files with 711 additions and 402 deletions
|
|
@ -303,6 +303,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||
{ "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
|
||||
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
|
||||
{ "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
|
||||
{ "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
|
||||
{ "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
|
||||
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
|
||||
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ class ChatHandler
|
|||
bool HandleReloadSpellElixirCommand(const char* args);
|
||||
bool HandleReloadSpellLearnSpellCommand(const char* args);
|
||||
bool HandleReloadSpellProcEventCommand(const char* args);
|
||||
bool HandleReloadSpellBonusesCommand(const char* args);
|
||||
bool HandleReloadSpellScriptTargetCommand(const char* args);
|
||||
bool HandleReloadSpellScriptsCommand(const char* args);
|
||||
bool HandleReloadSpellTargetPositionCommand(const char* args);
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
|
|||
HandleReloadSpellElixirCommand("a");
|
||||
HandleReloadSpellLearnSpellCommand("a");
|
||||
HandleReloadSpellProcEventCommand("a");
|
||||
HandleReloadSpellBonusesCommand("a");
|
||||
HandleReloadSpellScriptTargetCommand("a");
|
||||
HandleReloadSpellTargetPositionCommand("a");
|
||||
HandleReloadSpellThreatsCommand("a");
|
||||
|
|
@ -460,6 +461,14 @@ bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading Spell Bonus Data..." );
|
||||
spellmgr.LoadSpellBonusess();
|
||||
SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading SpellsScriptTarget..." );
|
||||
|
|
|
|||
|
|
@ -2055,7 +2055,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
{
|
||||
// prevent double apply bonuses
|
||||
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
|
||||
m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
|
||||
m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2252,7 +2252,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
if ( caster )
|
||||
// prevent double apply bonuses
|
||||
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
|
||||
m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
|
||||
m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -4240,29 +4240,6 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// Consecration
|
||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
|
||||
{
|
||||
// ($m1+0.04*$SPH+0.04*$AP)
|
||||
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
|
||||
caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
|
||||
m_modifier.m_amount += int32(0.04f*holy + 0.04f*ap);
|
||||
return;
|
||||
}
|
||||
// Seal of Vengeance 0.013*$SPH+0.025*$AP per tick (also can stack)
|
||||
if(m_spellProto->SpellFamilyFlags & 0x0000080000000000LL)
|
||||
{
|
||||
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
|
||||
caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
|
||||
m_modifier.m_amount += int32((0.013f*holy + 0.025f*ap) * GetStackAmount());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -5619,7 +5596,7 @@ void Aura::PeriodicTick()
|
|||
pdamage = pdamageReductedArmor;
|
||||
}
|
||||
|
||||
pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
|
||||
pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
|
||||
|
||||
// Curse of Agony damage-per-tick calculation
|
||||
if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
|
||||
|
|
@ -5705,7 +5682,7 @@ void Aura::PeriodicTick()
|
|||
pdamage = pdamageReductedArmor;
|
||||
}
|
||||
|
||||
pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
|
||||
pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
|
||||
|
||||
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
|
||||
// Reduce dot damage from resilience for players
|
||||
|
|
@ -5749,7 +5726,7 @@ void Aura::PeriodicTick()
|
|||
if(Player *modOwner = pCaster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
|
||||
|
||||
uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
|
||||
uint32 heal = pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, GetStackAmount());
|
||||
|
||||
int32 gain = pCaster->ModifyHealth(heal);
|
||||
pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
|
||||
|
|
@ -5778,7 +5755,7 @@ void Aura::PeriodicTick()
|
|||
else
|
||||
pdamage = amount;
|
||||
|
||||
pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
|
||||
pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
|
||||
|
||||
sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
|
||||
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
if(stacks)
|
||||
damage += damage * stacks * 10 /100;
|
||||
}
|
||||
// Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
|
||||
// Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - ranged sdb for future
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
|
|
@ -575,15 +575,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.07f) + int32(holy * 7 / 100);
|
||||
}
|
||||
// Exorcism ($m1+0.15*$SPH+0.15*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
// Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP)
|
||||
// Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
|
|
@ -591,14 +583,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
// Holy Wrath ($m1+0.07*$SPH+0.07*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0020000000000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2466,14 +2450,14 @@ void Spell::EffectHeal( uint32 /*i*/ )
|
|||
idx++;
|
||||
}
|
||||
|
||||
int32 tickheal = caster->SpellHealingBonus(targetAura->GetSpellProto(), targetAura->GetModifier()->m_amount, DOT, unitTarget);
|
||||
int32 tickheal = caster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), targetAura->GetModifier()->m_amount, DOT);
|
||||
int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx];
|
||||
unitTarget->RemoveAurasDueToSpell(targetAura->GetId());
|
||||
|
||||
addhealth += tickheal * tickcount;
|
||||
}
|
||||
else
|
||||
addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
|
||||
addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
|
||||
|
||||
m_healing+=addhealth;
|
||||
}
|
||||
|
|
@ -2514,7 +2498,7 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )
|
|||
if (!caster)
|
||||
return;
|
||||
|
||||
uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget);
|
||||
uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);
|
||||
caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
|
||||
unitTarget->ModifyHealth( int32(damage) );
|
||||
}
|
||||
|
|
@ -2545,7 +2529,7 @@ void Spell::EffectHealthLeech(uint32 i)
|
|||
|
||||
if(m_caster->isAlive())
|
||||
{
|
||||
new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster);
|
||||
new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL);
|
||||
|
||||
m_caster->ModifyHealth(new_damage);
|
||||
|
||||
|
|
|
|||
|
|
@ -834,7 +834,7 @@ void SpellMgr::LoadSpellProcEvents()
|
|||
|
||||
bar.step();
|
||||
|
||||
uint16 entry = fields[0].GetUInt16();
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
|
||||
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
|
||||
if (!spell)
|
||||
|
|
@ -878,6 +878,50 @@ void SpellMgr::LoadSpellProcEvents()
|
|||
sLog.outString( ">> Loaded %u extra spell proc event conditions", count );
|
||||
}
|
||||
|
||||
void SpellMgr::LoadSpellBonusess()
|
||||
{
|
||||
mSpellBonusMap.clear(); // need for reload case
|
||||
uint32 count = 0;
|
||||
// 0 1 2 3
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus FROM spell_bonus_data");
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar( 1 );
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u spell bonus data", count);
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
bar.step();
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
|
||||
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
|
||||
if (!spell)
|
||||
{
|
||||
sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
SpellBonusEntry sbe;
|
||||
|
||||
sbe.direct_damage = fields[1].GetFloat();
|
||||
sbe.dot_damage = fields[2].GetFloat();
|
||||
sbe.ap_bonus = fields[3].GetFloat();
|
||||
|
||||
mSpellBonusMap[entry] = sbe;
|
||||
} while( result->NextRow() );
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u extra spell bonus data", count);
|
||||
}
|
||||
|
||||
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
|
||||
{
|
||||
// No extra req need
|
||||
|
|
|
|||
|
|
@ -580,7 +580,15 @@ struct SpellProcEventEntry
|
|||
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
|
||||
};
|
||||
|
||||
struct SpellBonusEntry
|
||||
{
|
||||
float direct_damage;
|
||||
float dot_damage;
|
||||
float ap_bonus;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
|
||||
typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
|
||||
|
||||
#define ELIXIR_BATTLE_MASK 0x1
|
||||
#define ELIXIR_GUARDIAN_MASK 0x2
|
||||
|
|
@ -786,6 +794,23 @@ class SpellMgr
|
|||
|
||||
static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
|
||||
|
||||
// Spell bonus data
|
||||
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
|
||||
{
|
||||
// Lookup data
|
||||
SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
|
||||
if( itr != mSpellBonusMap.end( ) )
|
||||
return &itr->second;
|
||||
// Not found, try lookup for 1 spell rank if exist
|
||||
if (uint32 rank_1 = GetFirstSpellInChain(spellId))
|
||||
{
|
||||
SpellBonusMap::const_iterator itr = mSpellBonusMap.find(rank_1);
|
||||
if( itr != mSpellBonusMap.end( ) )
|
||||
return &itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Spell target coordinates
|
||||
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
|
||||
{
|
||||
|
|
@ -954,6 +979,7 @@ class SpellMgr
|
|||
void LoadSpellAffects();
|
||||
void LoadSpellElixirs();
|
||||
void LoadSpellProcEvents();
|
||||
void LoadSpellBonusess();
|
||||
void LoadSpellTargetPositions();
|
||||
void LoadSpellThreats();
|
||||
void LoadSkillLineAbilityMap();
|
||||
|
|
@ -970,6 +996,7 @@ class SpellMgr
|
|||
SpellAffectMap mSpellAffectMap;
|
||||
SpellElixirMap mSpellElixirs;
|
||||
SpellProcEventMap mSpellProcEventMap;
|
||||
SpellBonusMap mSpellBonusMap;
|
||||
SkillLineAbilityMap mSkillLineAbilityMap;
|
||||
SpellPetAuraMap mSpellPetAuraMap;
|
||||
PetLevelupSpellMap mPetLevelupSpellMap;
|
||||
|
|
|
|||
|
|
@ -7361,7 +7361,7 @@ void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Po
|
|||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype)
|
||||
uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
|
||||
{
|
||||
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
|
||||
return pdamage;
|
||||
|
|
@ -7571,23 +7571,15 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
|||
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
|
||||
|
||||
// .. taken pct: dummy auras
|
||||
AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
|
||||
if (pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
switch((*i)->GetSpellProto()->SpellIconID)
|
||||
//Cheat Death
|
||||
if (Aura *dummy = pVictim->GetDummyAura(45182))
|
||||
{
|
||||
//Cheat Death
|
||||
case 2109:
|
||||
if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) )
|
||||
{
|
||||
if(pVictim->GetTypeId() != TYPEID_PLAYER)
|
||||
continue;
|
||||
float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
|
||||
if (mod < (*i)->GetModifier()->m_amount)
|
||||
mod = (*i)->GetModifier()->m_amount;
|
||||
TakenTotalMod *= (mod+100.0f)/100.0f;
|
||||
}
|
||||
break;
|
||||
float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
|
||||
if (mod < dummy->GetModifier()->m_amount)
|
||||
mod = dummy->GetModifier()->m_amount;
|
||||
TakenTotalMod *= (mod+100.0f)/100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7607,274 +7599,93 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
|||
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
|
||||
}
|
||||
|
||||
// Damage Done from spell damage bonus
|
||||
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
|
||||
|
||||
// Taken/Done fixed damage bonus auras
|
||||
int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
|
||||
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
|
||||
|
||||
// Pets just add their bonus damage to their spell damage
|
||||
// note that their spell damage is just gain of their own auras
|
||||
if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
|
||||
DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage();
|
||||
|
||||
// Damage over Time spells bonus calculation
|
||||
float DotFactor = 1.0f;
|
||||
if(damagetype == DOT)
|
||||
{
|
||||
int32 DotDuration = GetSpellDuration(spellProto);
|
||||
// 200% limit
|
||||
if(DotDuration > 0)
|
||||
{
|
||||
if(DotDuration > 30000) DotDuration = 30000;
|
||||
if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
|
||||
int x = 0;
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
|
||||
{
|
||||
x = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int DotTicks = 6;
|
||||
if(spellProto->EffectAmplitude[x] != 0)
|
||||
DotTicks = DotDuration / spellProto->EffectAmplitude[x];
|
||||
if(DotTicks)
|
||||
{
|
||||
DoneAdvertisedBenefit /= DotTicks;
|
||||
TakenAdvertisedBenefit /= DotTicks;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Distribute Damage over multiple effects, reduce by AoE
|
||||
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 < 3; ++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;
|
||||
}
|
||||
}
|
||||
|
||||
switch(spellProto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_MAGE:
|
||||
// Ignite - do not modify, it is (8*Rank)% damage of procing Spell
|
||||
if(spellProto->Id==12654)
|
||||
{
|
||||
return pdamage;
|
||||
}
|
||||
// Ice Lance
|
||||
else if((spellProto->SpellFamilyFlags & 0x20000LL) && spellProto->SpellIconID == 186)
|
||||
{
|
||||
CastingTime /= 3; // applied 1/3 bonuses in case generic target
|
||||
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.0f : 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_WARLOCK:
|
||||
// Life Tap
|
||||
if((spellProto->SpellFamilyFlags & 0x40000LL) && spellProto->SpellIconID == 208)
|
||||
{
|
||||
CastingTime = 2800; // 80% from +shadow damage
|
||||
DoneTotalMod = 1.0f;
|
||||
TakenTotalMod = 1.0f;
|
||||
}
|
||||
// Dark Pact
|
||||
else if((spellProto->SpellFamilyFlags & 0x80000000LL) && spellProto->SpellIconID == 154 && GetPetGUID())
|
||||
{
|
||||
CastingTime = 3360; // 96% from +shadow damage
|
||||
DoneTotalMod = 1.0f;
|
||||
TakenTotalMod = 1.0f;
|
||||
}
|
||||
// Soul Fire - 115% of Fire Damage
|
||||
else if((spellProto->SpellFamilyFlags & 0x8000000000LL) && spellProto->SpellIconID == 184)
|
||||
{
|
||||
CastingTime = 4025;
|
||||
}
|
||||
// Curse of Agony - 120% of Shadow Damage
|
||||
else if((spellProto->SpellFamilyFlags & 0x0000000400LL) && spellProto->SpellIconID == 544)
|
||||
{
|
||||
DotFactor = 1.2f;
|
||||
}
|
||||
// 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
|
||||
}
|
||||
// Unstable Affliction - 180%
|
||||
else if (spellProto->Id == 31117 && spellProto->SpellIconID == 232)
|
||||
{
|
||||
CastingTime = 6300;
|
||||
}
|
||||
// Corruption 93%
|
||||
else if ((spellProto->SpellFamilyFlags & 0x2LL) && spellProto->SpellIconID == 313)
|
||||
{
|
||||
DotFactor = 0.93f;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_PALADIN:
|
||||
// Consecration - 95% of Holy Damage
|
||||
if((spellProto->SpellFamilyFlags & 0x20LL) && spellProto->SpellIconID == 51)
|
||||
{
|
||||
DotFactor = 0.95f;
|
||||
CastingTime = 3500;
|
||||
}
|
||||
// Judgement of Righteousness - 32%
|
||||
else if (spellProto->SpellFamilyFlags & 0x0000000000000400LL)
|
||||
{
|
||||
CastingTime = 1120;
|
||||
}
|
||||
// Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications
|
||||
else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292)
|
||||
{
|
||||
DotFactor = 0.17f;
|
||||
CastingTime = 3500;
|
||||
}
|
||||
// Holy shield - 5% of Holy Damage
|
||||
else if ((spellProto->SpellFamilyFlags & 0x4000000000LL) && spellProto->SpellIconID == 453)
|
||||
{
|
||||
CastingTime = 175;
|
||||
}
|
||||
// Blessing of Sanctuary - 0%
|
||||
else if ((spellProto->SpellFamilyFlags & 0x10000000LL) && spellProto->SpellIconID == 29)
|
||||
{
|
||||
CastingTime = 0;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
// totem attack
|
||||
if (spellProto->SpellFamilyFlags & 0x000040000000LL)
|
||||
{
|
||||
if (spellProto->SpellIconID == 33) // Fire Nova totem attack must be 21.4%(untested)
|
||||
CastingTime = 749; // ignore CastingTime and use as modifier
|
||||
else if (spellProto->SpellIconID == 680) // Searing Totem attack 8%
|
||||
CastingTime = 280; // ignore CastingTime and use as modifier
|
||||
else if (spellProto->SpellIconID == 37) // Magma totem attack must be 6.67%(untested)
|
||||
CastingTime = 234; // ignore CastingTimePenalty and use as modifier
|
||||
}
|
||||
// Lightning Shield (and proc shield from T2 8 pieces bonus ) 33% per charge
|
||||
else if( (spellProto->SpellFamilyFlags & 0x00000000400LL) || spellProto->Id == 23552)
|
||||
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;
|
||||
}
|
||||
// Shadowguard - 28% per charge
|
||||
else if ((spellProto->SpellFamilyFlags & 0x2000000LL) && spellProto->SpellIconID == 19)
|
||||
{
|
||||
CastingTime = 980;
|
||||
}
|
||||
// Touch of Weakeness - 10%
|
||||
else if ((spellProto->SpellFamilyFlags & 0x80000LL) && spellProto->SpellIconID == 1591)
|
||||
{
|
||||
CastingTime = 350;
|
||||
}
|
||||
// Reflective Shield (back damage) - 0% (other spells fit to check not have damage effects/auras)
|
||||
else if (spellProto->SpellFamilyFlags == 0 && spellProto->SpellIconID == 566)
|
||||
{
|
||||
CastingTime = 0;
|
||||
}
|
||||
// Holy Nova - 14%
|
||||
else if ((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 1874)
|
||||
{
|
||||
CastingTime = 500;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_DRUID:
|
||||
// Hurricane triggered spell
|
||||
if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220)
|
||||
{
|
||||
CastingTime = 500;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
case SPELLFAMILY_HUNTER:
|
||||
case SPELLFAMILY_ROGUE:
|
||||
CastingTime = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
float LvlPenalty = CalculateLevelPenalty(spellProto);
|
||||
|
||||
// Spellmod SpellDamage
|
||||
float SpellModSpellDamage = 100.0f;
|
||||
|
||||
if(Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
|
||||
|
||||
SpellModSpellDamage /= 100.0f;
|
||||
|
||||
float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
|
||||
float TakenActualBenefit = TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
|
||||
// Check for table values
|
||||
SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
|
||||
if (bonus)
|
||||
{
|
||||
float coeff;
|
||||
if (damagetype == DOT)
|
||||
coeff = bonus->dot_damage * LvlPenalty * stack;
|
||||
else
|
||||
coeff = bonus->direct_damage * LvlPenalty * stack;
|
||||
if (bonus->ap_bonus)
|
||||
coeff*=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
DoneTotal += DoneAdvertisedBenefit * coeff * SpellModSpellDamage;
|
||||
TakenTotal+= TakenAdvertisedBenefit * coeff;
|
||||
}
|
||||
// Default calculation
|
||||
else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
|
||||
{
|
||||
// Damage Done from spell damage bonus
|
||||
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
|
||||
// Damage over Time spells bonus calculation
|
||||
float DotFactor = 1.0f;
|
||||
if(damagetype == DOT)
|
||||
{
|
||||
int32 DotDuration = GetSpellDuration(spellProto);
|
||||
// 200% limit
|
||||
if(DotDuration > 0)
|
||||
{
|
||||
if(DotDuration > 30000) DotDuration = 30000;
|
||||
if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
|
||||
int x = 0;
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
|
||||
{
|
||||
x = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int DotTicks = 6;
|
||||
if(spellProto->EffectAmplitude[x] != 0)
|
||||
DotTicks = DotDuration / spellProto->EffectAmplitude[x];
|
||||
if(DotTicks)
|
||||
{
|
||||
DoneAdvertisedBenefit /= DotTicks*stack;
|
||||
TakenAdvertisedBenefit /= DotTicks*stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Distribute Damage over multiple effects, reduce by AoE
|
||||
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 < 3; ++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 += DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage;
|
||||
TakenTotal+= TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
|
||||
}
|
||||
|
||||
float tmpDamage = (float(pdamage)+DoneActualBenefit + DoneTotal)*DoneTotalMod;
|
||||
float tmpDamage = (pdamage + DoneTotal) * DoneTotalMod;
|
||||
// apply spellmod to Done damage (flat and pct)
|
||||
if(Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
|
||||
|
||||
tmpDamage = (tmpDamage + TakenActualBenefit + TakenTotal)*TakenTotalMod;
|
||||
tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod;
|
||||
|
||||
return tmpDamage > 0 ? uint32(tmpDamage) : 0;
|
||||
}
|
||||
|
|
@ -8101,21 +7912,18 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 dama
|
|||
return damage;
|
||||
}
|
||||
|
||||
uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim)
|
||||
uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
|
||||
{
|
||||
// No heal amount for this class spells
|
||||
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
|
||||
return healamount;
|
||||
|
||||
// For totems get healing bonus from owner (statue isn't totem in fact)
|
||||
if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
|
||||
if(Unit* owner = GetOwner())
|
||||
return owner->SpellHealingBonus(spellProto, healamount, damagetype, pVictim);
|
||||
return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack);
|
||||
|
||||
// Healing Done
|
||||
|
||||
// These Spells are doing fixed amount of healing (TODO found less hack-like check)
|
||||
if (spellProto->Id == 15290 || spellProto->Id == 39373 ||
|
||||
spellProto->Id == 33778 || spellProto->Id == 379 ||
|
||||
spellProto->Id == 38395 || spellProto->Id == 40972)
|
||||
return healamount;
|
||||
|
||||
// Taken/Done total percent damage auras
|
||||
float DoneTotalMod = 1.0f;
|
||||
float TakenTotalMod = 1.0f;
|
||||
|
|
@ -8208,25 +8016,51 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
|
|||
}
|
||||
}
|
||||
|
||||
// Taken/Done fixed damage bonus auras
|
||||
int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
|
||||
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
|
||||
if (DoneAdvertisedBenefit != 0 && TakenAdvertisedBenefit!=0)
|
||||
|
||||
float LvlPenalty = CalculateLevelPenalty(spellProto);
|
||||
// Spellmod SpellDamage
|
||||
float SpellModSpellDamage = 100.0f;
|
||||
if(Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, SpellModSpellDamage);
|
||||
SpellModSpellDamage /= 100.0f;
|
||||
|
||||
// Check for table values
|
||||
SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
|
||||
if (bonus)
|
||||
{
|
||||
// Healing over Time spells
|
||||
float coeff;
|
||||
if (damagetype == DOT)
|
||||
coeff = bonus->dot_damage * LvlPenalty * stack;
|
||||
else
|
||||
coeff = bonus->direct_damage * LvlPenalty * stack;
|
||||
if (bonus->ap_bonus)
|
||||
coeff*=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
DoneTotal += DoneAdvertisedBenefit * coeff * SpellModSpellDamage;
|
||||
TakenTotal+= TakenAdvertisedBenefit * coeff;
|
||||
}
|
||||
// Default calculation
|
||||
else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
|
||||
{
|
||||
// Damage Done from spell damage bonus
|
||||
uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
|
||||
// Damage over Time spells bonus calculation
|
||||
float DotFactor = 1.0f;
|
||||
if(damagetype == DOT)
|
||||
{
|
||||
int32 DotDuration = GetSpellDuration(spellProto);
|
||||
// 200% limit
|
||||
if(DotDuration > 0)
|
||||
{
|
||||
// 200% limit
|
||||
if(DotDuration > 30000) DotDuration = 30000;
|
||||
if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
|
||||
int x = 0;
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
|
||||
spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
|
||||
{
|
||||
x = j;
|
||||
|
|
@ -8243,85 +8077,20 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
|
|||
}
|
||||
}
|
||||
}
|
||||
uint32 CastingTime = GetSpellCastTime(spellProto);
|
||||
|
||||
// distribute healing to all effects, reduce AoE damage
|
||||
// Distribute Damage over multiple effects, reduce by AoE
|
||||
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
|
||||
|
||||
// 0% bonus for damage and healing spells for leech spells from healing bonus
|
||||
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
|
||||
for(int j = 0; j < 3; ++j)
|
||||
{
|
||||
if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
|
||||
spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
|
||||
{
|
||||
CastingTime = 0;
|
||||
CastingTime /= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception
|
||||
switch (spellProto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
// Healing stream from totem (add 6% per tick from hill bonus owner)
|
||||
// Possibly need do it on apply dummy aura
|
||||
if (spellProto->Id == 52042)
|
||||
CastingTime = 210;
|
||||
break;
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
// Earth Shield 30% per charge
|
||||
if (spellProto->SpellFamilyFlags & 0x40000000000LL)
|
||||
CastingTime = 1050;
|
||||
break;
|
||||
case SPELLFAMILY_DRUID:
|
||||
// Lifebloom
|
||||
if (spellProto->SpellFamilyFlags & 0x1000000000LL)
|
||||
{
|
||||
CastingTime = damagetype == DOT ? 3500 : 1200;
|
||||
DotFactor = damagetype == DOT ? 0.519f : 1.0f;
|
||||
}
|
||||
// Tranquility triggered spell
|
||||
else if (spellProto->SpellFamilyFlags & 0x80LL)
|
||||
CastingTime = 667;
|
||||
// Rejuvenation
|
||||
else if (spellProto->SpellFamilyFlags & 0x10LL)
|
||||
DotFactor = 0.845f;
|
||||
// Regrowth
|
||||
else if (spellProto->SpellFamilyFlags & 0x40LL)
|
||||
{
|
||||
DotFactor = damagetype == DOT ? 0.705f : 1.0f;
|
||||
CastingTime = damagetype == DOT ? 3500 : 1010;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_PRIEST:
|
||||
// Holy Nova - 14%
|
||||
if ((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 1874)
|
||||
CastingTime = 500;
|
||||
break;
|
||||
case SPELLFAMILY_PALADIN:
|
||||
// Seal and Judgement of Light
|
||||
if ( spellProto->SpellFamilyFlags & 0x100040000LL )
|
||||
CastingTime = 0;
|
||||
break;
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
case SPELLFAMILY_ROGUE:
|
||||
case SPELLFAMILY_HUNTER:
|
||||
CastingTime = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
float LvlPenalty = CalculateLevelPenalty(spellProto);
|
||||
|
||||
// Spellmod SpellDamage
|
||||
float SpellModSpellDamage = 100.0f;
|
||||
|
||||
if(Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
|
||||
|
||||
SpellModSpellDamage /= 100.0f;
|
||||
|
||||
DoneTotal += (float)DoneAdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
|
||||
TakenTotal += (float)TakenAdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
|
||||
DoneTotal += DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage * 1.88f;
|
||||
TakenTotal+= TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * 1.88f;
|
||||
}
|
||||
|
||||
// use float as more appropriate for negative values and percent applying
|
||||
|
|
|
|||
|
|
@ -1293,8 +1293,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
|
||||
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
|
||||
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask 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 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1);
|
||||
uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
|
||||
bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK);
|
||||
bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK);
|
||||
uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,9 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Spell Proc Event conditions..." );
|
||||
spellmgr.LoadSpellProcEvents();
|
||||
|
||||
sLog.outString( "Loading Spell Bonus Data..." );
|
||||
spellmgr.LoadSpellBonusess();
|
||||
|
||||
sLog.outString( "Loading Aggro Spells Definitions...");
|
||||
spellmgr.LoadSpellThreats();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue