mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
Apply procPatch
This commit is contained in:
parent
bdf7fb8394
commit
4a07c0c6c2
9 changed files with 2298 additions and 421 deletions
|
|
@ -4727,6 +4727,7 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType)
|
||||||
|
|
||||||
void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence)
|
void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence)
|
||||||
{
|
{
|
||||||
|
/* Not need, this checked on call this func from trigger system
|
||||||
switch(outcome)
|
switch(outcome)
|
||||||
{
|
{
|
||||||
case MELEE_HIT_CRIT:
|
case MELEE_HIT_CRIT:
|
||||||
|
|
@ -4739,7 +4740,7 @@ void Player::UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHi
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
uint32 plevel = getLevel(); // if defense than pVictim == attacker
|
uint32 plevel = getLevel(); // if defense than pVictim == attacker
|
||||||
uint32 greylevel = MaNGOS::XP::GetGrayLevel(plevel);
|
uint32 greylevel = MaNGOS::XP::GetGrayLevel(plevel);
|
||||||
uint32 moblevel = pVictim->getLevelForTarget(this);
|
uint32 moblevel = pVictim->getLevelForTarget(this);
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
||||||
m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
|
m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set health leech amount to zero
|
||||||
|
m_healthLeech = 0;
|
||||||
|
|
||||||
if(originalCasterGUID)
|
if(originalCasterGUID)
|
||||||
m_originalCasterGUID = originalCasterGUID;
|
m_originalCasterGUID = originalCasterGUID;
|
||||||
|
|
@ -666,6 +668,77 @@ void Spell::FillTargetMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spell::prepareDataForTriggerSystem()
|
||||||
|
{
|
||||||
|
//==========================================================================================
|
||||||
|
// Now fill data for trigger system, need know:
|
||||||
|
// Ñan spell trigger another or not ( m_canTrigger )
|
||||||
|
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
|
||||||
|
//==========================================================================================
|
||||||
|
|
||||||
|
// Fill flag can spell trigger or not
|
||||||
|
if (!m_IsTriggeredSpell)
|
||||||
|
m_canTrigger = true; // Normal cast - can trigger
|
||||||
|
else if (!m_triggeredByAuraSpell)
|
||||||
|
m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
|
||||||
|
else // Exceptions (some periodic triggers)
|
||||||
|
{
|
||||||
|
m_canTrigger = false; // Triggered spells can`t trigger another
|
||||||
|
switch (m_spellInfo->SpellFamilyName)
|
||||||
|
{
|
||||||
|
case SPELLFAMILY_MAGE: // Arcane Missles triggers need do it
|
||||||
|
if (m_spellInfo->SpellFamilyFlags & 0x0000000000200000LL) m_canTrigger = true;
|
||||||
|
break;
|
||||||
|
case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it
|
||||||
|
if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true;
|
||||||
|
break;
|
||||||
|
case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
|
||||||
|
if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true;
|
||||||
|
break;
|
||||||
|
case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it
|
||||||
|
if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Do not trigger from item cast spell
|
||||||
|
if (m_CastItem)
|
||||||
|
m_canTrigger = false;
|
||||||
|
|
||||||
|
// Get data for type of attack and fill base info for trigger
|
||||||
|
switch (m_spellInfo->DmgClass)
|
||||||
|
{
|
||||||
|
case SPELL_DAMAGE_CLASS_MELEE:
|
||||||
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT;
|
||||||
|
m_procVictim = PROC_FLAG_TAKEN_MELEE_SPELL_HIT;
|
||||||
|
break;
|
||||||
|
case SPELL_DAMAGE_CLASS_RANGED:
|
||||||
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
|
||||||
|
m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
|
||||||
|
{
|
||||||
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
|
||||||
|
m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
|
||||||
|
}
|
||||||
|
else if (m_spellInfo->Id == 5019) // Wands
|
||||||
|
{
|
||||||
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
|
||||||
|
m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
|
||||||
|
m_procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Hunter traps spells (for Entrapment trigger)
|
||||||
|
// Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap ....
|
||||||
|
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL)
|
||||||
|
m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION;
|
||||||
|
}
|
||||||
|
|
||||||
void Spell::CleanupTargetList()
|
void Spell::CleanupTargetList()
|
||||||
{
|
{
|
||||||
m_UniqueTargetInfo.clear();
|
m_UniqueTargetInfo.clear();
|
||||||
|
|
@ -821,7 +894,7 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
|
||||||
target.effectMask = 1<<effIndex;
|
target.effectMask = 1<<effIndex;
|
||||||
m_UniqueItemInfo.push_back(target);
|
m_UniqueItemInfo.push_back(target);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 block, uint32 absorb, bool crit)
|
void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 block, uint32 absorb, bool crit)
|
||||||
{
|
{
|
||||||
// Do triggers depends from hit result (triggers on hit do in effects)
|
// Do triggers depends from hit result (triggers on hit do in effects)
|
||||||
|
|
@ -897,7 +970,7 @@ void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask da
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||||
{
|
{
|
||||||
|
|
@ -914,11 +987,27 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Get original caster (if exist) and calculate damage/healing from him data
|
||||||
|
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
||||||
|
|
||||||
|
// Skip if m_originalCaster not avaiable
|
||||||
|
if (!caster)
|
||||||
|
return;
|
||||||
|
|
||||||
SpellMissInfo missInfo = target->missCondition;
|
SpellMissInfo missInfo = target->missCondition;
|
||||||
// Need init unitTarget by default unit (can changed in code on reflect)
|
// Need init unitTarget by default unit (can changed in code on reflect)
|
||||||
// Or on missInfo!=SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
|
// Or on missInfo!=SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
|
||||||
unitTarget = unit;
|
unitTarget = unit;
|
||||||
|
|
||||||
|
// Reset damage/healing counter
|
||||||
|
m_damage = 0;
|
||||||
|
m_healing = 0;
|
||||||
|
|
||||||
|
// Fill base trigger info
|
||||||
|
uint32 procAttacker = m_procAttacker;
|
||||||
|
uint32 procVictim = m_procVictim;
|
||||||
|
uint32 procEx = PROC_EX_NONE;
|
||||||
|
|
||||||
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
|
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
|
||||||
DoSpellHitOnUnit(unit, mask);
|
DoSpellHitOnUnit(unit, mask);
|
||||||
else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
|
else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
|
||||||
|
|
@ -927,9 +1016,103 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||||
DoSpellHitOnUnit(m_caster, mask);
|
DoSpellHitOnUnit(m_caster, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do triggers only on miss/resist/parry/dodge
|
// All calculated do it!
|
||||||
if (missInfo!=SPELL_MISS_NONE)
|
// Do healing and triggers
|
||||||
doTriggers(missInfo);
|
if (m_healing)
|
||||||
|
{
|
||||||
|
bool crit = caster->isSpellCrit(NULL, m_spellInfo, m_spellSchoolMask);
|
||||||
|
uint32 addhealth = m_healing;
|
||||||
|
if (crit)
|
||||||
|
{
|
||||||
|
procEx |= PROC_EX_CRITICAL_HIT;
|
||||||
|
addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
procEx |= PROC_EX_NORMAL_HIT;
|
||||||
|
|
||||||
|
caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, crit);
|
||||||
|
|
||||||
|
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||||
|
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
|
||||||
|
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
|
||||||
|
|
||||||
|
int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
|
||||||
|
|
||||||
|
unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
|
||||||
|
if(caster->GetTypeId()==TYPEID_PLAYER)
|
||||||
|
if(BattleGround *bg = ((Player*)caster)->GetBattleGround())
|
||||||
|
bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
|
||||||
|
}
|
||||||
|
// Do damage and triggers
|
||||||
|
else if (m_damage)
|
||||||
|
{
|
||||||
|
// Fill base damage struct (unitTarget - is real spell target)
|
||||||
|
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
||||||
|
|
||||||
|
// Add bonuses and fill damageInfo struct
|
||||||
|
caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo);
|
||||||
|
|
||||||
|
// Send log damage message to client
|
||||||
|
caster->SendSpellNonMeleeDamageLog(&damageInfo);
|
||||||
|
|
||||||
|
procEx = createProcExtendMask(&damageInfo, missInfo);
|
||||||
|
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
|
||||||
|
|
||||||
|
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||||
|
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
|
||||||
|
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
|
||||||
|
|
||||||
|
caster->DealSpellDamage(&damageInfo, true);
|
||||||
|
|
||||||
|
// Shadow Word: Death - deals damage equal to damage done to caster if victim is not killed
|
||||||
|
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL &&
|
||||||
|
caster != unitTarget && unitTarget->isAlive())
|
||||||
|
{
|
||||||
|
// Redirect damage to caster if victim Alive
|
||||||
|
damageInfo.target = caster;
|
||||||
|
damageInfo.absorb = 0;
|
||||||
|
damageInfo.resist = 0;
|
||||||
|
damageInfo.blocked = 0;
|
||||||
|
// Send log damage message to client
|
||||||
|
caster->SendSpellNonMeleeDamageLog(&damageInfo);
|
||||||
|
caster->DealSpellDamage(&damageInfo, true);
|
||||||
|
}
|
||||||
|
// Judgement of Blood
|
||||||
|
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153)
|
||||||
|
{
|
||||||
|
int32 damagePoint = damageInfo.damage * 33 / 100;
|
||||||
|
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
|
||||||
|
}
|
||||||
|
// Bloodthirst
|
||||||
|
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
|
||||||
|
{
|
||||||
|
uint32 BTAura = 0;
|
||||||
|
switch(m_spellInfo->Id)
|
||||||
|
{
|
||||||
|
case 23881: BTAura = 23885; break;
|
||||||
|
case 23892: BTAura = 23886; break;
|
||||||
|
case 23893: BTAura = 23887; break;
|
||||||
|
case 23894: BTAura = 23888; break;
|
||||||
|
case 25251: BTAura = 25252; break;
|
||||||
|
case 30335: BTAura = 30339; break;
|
||||||
|
default:
|
||||||
|
sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (BTAura)
|
||||||
|
m_caster->CastSpell(m_caster,BTAura,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Passive spell hits/misses or active spells only misses (only triggers)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fill base damage struct (unitTarget - is real spell target)
|
||||||
|
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
||||||
|
procEx = createProcExtendMask(&damageInfo, missInfo);
|
||||||
|
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
|
||||||
|
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
|
||||||
|
caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo);
|
||||||
|
}
|
||||||
|
|
||||||
// Call scripted function for AI if this spell is casted upon a creature (except pets)
|
// Call scripted function for AI if this spell is casted upon a creature (except pets)
|
||||||
if(IS_CREATURE_GUID(target->targetGUID))
|
if(IS_CREATURE_GUID(target->targetGUID))
|
||||||
|
|
@ -1951,6 +2134,9 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare data for triggers
|
||||||
|
prepareDataForTriggerSystem();
|
||||||
|
|
||||||
// calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
|
// calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
|
||||||
m_casttime = GetSpellCastTime(m_spellInfo, this);
|
m_casttime = GetSpellCastTime(m_spellInfo, this);
|
||||||
|
|
||||||
|
|
@ -2096,15 +2282,6 @@ void Spell::cast(bool skipCheck)
|
||||||
SendCastResult(castResult);
|
SendCastResult(castResult);
|
||||||
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
|
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
|
||||||
|
|
||||||
// Pass cast spell event to handler (not send triggered by aura spells)
|
|
||||||
if (m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_RANGED && !m_triggeredByAuraSpell)
|
|
||||||
{
|
|
||||||
m_caster->ProcDamageAndSpell(m_targets.getUnitTarget(), PROC_FLAG_CAST_SPELL, PROC_FLAG_NONE, 0, SPELL_SCHOOL_MASK_NONE, m_spellInfo, m_IsTriggeredSpell);
|
|
||||||
|
|
||||||
// update pointers base at GUIDs to prevent access to non-existed already object
|
|
||||||
UpdatePointers(); // pointers can be invalidate at triggered spell casting
|
|
||||||
}
|
|
||||||
|
|
||||||
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
|
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
|
||||||
if (m_spellInfo->speed > 0.0f)
|
if (m_spellInfo->speed > 0.0f)
|
||||||
{
|
{
|
||||||
|
|
@ -2516,6 +2693,13 @@ void Spell::finish(bool ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heal caster for all health leech from all targets
|
||||||
|
if (m_healthLeech)
|
||||||
|
{
|
||||||
|
m_caster->ModifyHealth(m_healthLeech);
|
||||||
|
m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(m_healthLeech));
|
||||||
|
}
|
||||||
|
|
||||||
if (IsMeleeAttackResetSpell())
|
if (IsMeleeAttackResetSpell())
|
||||||
{
|
{
|
||||||
m_caster->resetAttackTimer(BASE_ATTACK);
|
m_caster->resetAttackTimer(BASE_ATTACK);
|
||||||
|
|
@ -3478,8 +3662,9 @@ uint8 Spell::CanCast(bool strict)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uint8 castResult = CheckRange(strict))
|
if(!m_triggeredByAuraSpell)
|
||||||
return castResult;
|
if(uint8 castResult = CheckRange(strict))
|
||||||
|
return castResult;
|
||||||
|
|
||||||
{
|
{
|
||||||
if(uint8 castResult = CheckPower())
|
if(uint8 castResult = CheckPower())
|
||||||
|
|
|
||||||
|
|
@ -453,10 +453,18 @@ class Spell
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
GameObject* focusObject;
|
GameObject* focusObject;
|
||||||
|
|
||||||
|
// Damage and healing in effects need just calculate
|
||||||
|
int32 m_damage; // Damge in effects count here
|
||||||
|
int32 m_healing; // Healing in effects count here
|
||||||
|
int32 m_healthLeech; // Health leech in effects for all targets count here
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// Spell trigger system
|
// Spell trigger system
|
||||||
//******************************************
|
//******************************************
|
||||||
void doTriggers(SpellMissInfo missInfo, uint32 damage=0, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NONE, uint32 block=0, uint32 absorb=0, bool crit=false);
|
bool m_canTrigger; // Can start trigger (m_IsTriggeredSpell can`t use for this)
|
||||||
|
uint32 m_procAttacker; // Attacker trigger flags
|
||||||
|
uint32 m_procVictim; // Victim trigger flags
|
||||||
|
void prepareDataForTriggerSystem();
|
||||||
|
|
||||||
//*****************************************
|
//*****************************************
|
||||||
// Spell target subsystem
|
// Spell target subsystem
|
||||||
|
|
|
||||||
|
|
@ -253,8 +253,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
||||||
&Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
|
&Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::GiveXP
|
||||||
&Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
|
&Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
|
||||||
&Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
|
&Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
|
||||||
&Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::DoAttackDamage
|
&Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
|
||||||
&Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::DoAttackDamage
|
&Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
|
||||||
&Aura::HandleNULL, //205 vulnerable to school dmg?
|
&Aura::HandleNULL, //205 vulnerable to school dmg?
|
||||||
&Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
|
&Aura::HandleNULL, //206 SPELL_AURA_MOD_SPEED_MOUNTED
|
||||||
&Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
|
&Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
|
||||||
|
|
@ -5610,11 +5610,15 @@ void Aura::PeriodicTick()
|
||||||
Unit* target = m_target; // aura can be deleted in DealDamage
|
Unit* target = m_target; // aura can be deleted in DealDamage
|
||||||
SpellEntry const* spellProto = GetSpellProto();
|
SpellEntry const* spellProto = GetSpellProto();
|
||||||
|
|
||||||
pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
|
// Set trigger flag
|
||||||
|
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
|
||||||
|
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
|
||||||
|
pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
|
||||||
|
if (pdamage)
|
||||||
|
procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
|
||||||
|
pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
|
||||||
|
|
||||||
// DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura)
|
pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, true);
|
||||||
|
|
||||||
pCaster->ProcDamageAndSpell(target, PROC_FLAG_NONE, PROC_FLAG_TAKE_DAMAGE, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), GetSpellSchoolMask(spellProto), spellProto);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_PERIODIC_LEECH:
|
case SPELL_AURA_PERIODIC_LEECH:
|
||||||
|
|
@ -5723,11 +5727,15 @@ void Aura::PeriodicTick()
|
||||||
SpellEntry const* spellProto = GetSpellProto();
|
SpellEntry const* spellProto = GetSpellProto();
|
||||||
float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
|
float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
|
||||||
|
|
||||||
uint32 new_damage = pCaster->DealDamage(m_target, (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist), &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false);
|
// Set trigger flag
|
||||||
|
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
|
||||||
|
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
|
||||||
|
pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
|
||||||
|
if (pdamage)
|
||||||
|
procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
|
||||||
|
pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
|
||||||
|
int32 new_damage = pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, false);
|
||||||
|
|
||||||
// DO NOT ACCESS MEMBERS OF THE AURA FROM NOW ON (DealDamage can delete aura)
|
|
||||||
|
|
||||||
pCaster->ProcDamageAndSpell(target, PROC_FLAG_HEALED, PROC_FLAG_TAKE_DAMAGE, new_damage, GetSpellSchoolMask(spellProto), spellProto);
|
|
||||||
if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
|
if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
|
||||||
{
|
{
|
||||||
for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
|
for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
|
||||||
|
|
@ -5828,9 +5836,11 @@ void Aura::PeriodicTick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HEAL;
|
||||||
|
uint32 procVictim = 0;//ROC_FLAG_ON_TAKE_PERIODIC | PROC_FLAG_TAKEN_HEAL;
|
||||||
// ignore item heals
|
// ignore item heals
|
||||||
if(procSpell && !haveCastItem)
|
// if(procSpell && !haveCastItem)
|
||||||
pCaster->ProcDamageAndSpell(target,PROC_FLAG_NONE, PROC_FLAG_HEALED, pdamage, SPELL_SCHOOL_MASK_NONE, spellProto);
|
// pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_PERIODIC_MANA_LEECH:
|
case SPELL_AURA_PERIODIC_MANA_LEECH:
|
||||||
|
|
@ -5989,8 +5999,22 @@ void Aura::PeriodicTick()
|
||||||
|
|
||||||
gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
|
gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
|
||||||
|
|
||||||
|
SpellEntry const* spellProto = GetSpellProto();
|
||||||
//maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
|
//maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
|
||||||
pCaster->SpellNonMeleeDamageLog(m_target, GetId(), gain);
|
SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
|
||||||
|
pCaster->CalculateSpellDamage(&damageInfo, gain, spellProto);
|
||||||
|
pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
|
||||||
|
|
||||||
|
// Set trigger flag
|
||||||
|
uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT;
|
||||||
|
uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT;
|
||||||
|
uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE);
|
||||||
|
if (damageInfo.damage)
|
||||||
|
procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
|
||||||
|
|
||||||
|
pCaster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
|
||||||
|
|
||||||
|
pCaster->DealSpellDamage(&damageInfo, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Here tick dummy auras
|
// Here tick dummy auras
|
||||||
|
|
|
||||||
|
|
@ -541,61 +541,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(damage >= 0)
|
if(damage >= 0)
|
||||||
{
|
m_damage+= damage;
|
||||||
uint32 finalDamage;
|
|
||||||
if(m_originalCaster) // m_caster only passive source of cast
|
|
||||||
finalDamage = m_originalCaster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true);
|
|
||||||
else
|
|
||||||
finalDamage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true);
|
|
||||||
|
|
||||||
// post effects
|
|
||||||
switch(m_spellInfo->SpellFamilyName)
|
|
||||||
{
|
|
||||||
case SPELLFAMILY_WARRIOR:
|
|
||||||
{
|
|
||||||
// Bloodthirst
|
|
||||||
if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
|
|
||||||
{
|
|
||||||
uint32 BTAura = 0;
|
|
||||||
switch(m_spellInfo->Id)
|
|
||||||
{
|
|
||||||
case 23881: BTAura = 23885; break;
|
|
||||||
case 23892: BTAura = 23886; break;
|
|
||||||
case 23893: BTAura = 23887; break;
|
|
||||||
case 23894: BTAura = 23888; break;
|
|
||||||
case 25251: BTAura = 25252; break;
|
|
||||||
case 30335: BTAura = 30339; break;
|
|
||||||
default:
|
|
||||||
sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BTAura)
|
|
||||||
m_caster->CastSpell(m_caster,BTAura,true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPELLFAMILY_PRIEST:
|
|
||||||
{
|
|
||||||
// Shadow Word: Death
|
|
||||||
if(finalDamage > 0 && (m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL) && unitTarget->isAlive())
|
|
||||||
// deals damage equal to damage done to caster if victim is not killed
|
|
||||||
m_caster->SpellNonMeleeDamageLog( m_caster, m_spellInfo->Id, finalDamage, m_IsTriggeredSpell, false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPELLFAMILY_PALADIN:
|
|
||||||
{
|
|
||||||
// Judgement of Blood
|
|
||||||
if(finalDamage > 0 && (m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL) && m_spellInfo->SpellIconID==153)
|
|
||||||
{
|
|
||||||
int32 damagePoint = finalDamage * 33 / 100;
|
|
||||||
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1355,7 +1301,7 @@ void Spell::EffectDummy(uint32 i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found)
|
if(found)
|
||||||
m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_IsTriggeredSpell, true);
|
m_damage+= damage;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Kill command
|
// Kill command
|
||||||
|
|
@ -2308,7 +2254,7 @@ void Spell::EffectPowerBurn(uint32 i)
|
||||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
|
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
|
||||||
|
|
||||||
new_damage = int32(new_damage*multiplier);
|
new_damage = int32(new_damage*multiplier);
|
||||||
m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage, m_IsTriggeredSpell, true);
|
m_damage+=new_damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectHeal( uint32 /*i*/ )
|
void Spell::EffectHeal( uint32 /*i*/ )
|
||||||
|
|
@ -2376,27 +2322,7 @@ void Spell::EffectHeal( uint32 /*i*/ )
|
||||||
else
|
else
|
||||||
addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
|
addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
|
||||||
|
|
||||||
bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask, m_attackType);
|
m_healing+=addhealth;
|
||||||
if (crit)
|
|
||||||
addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, unitTarget);
|
|
||||||
caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, crit);
|
|
||||||
|
|
||||||
int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
|
|
||||||
unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
|
|
||||||
|
|
||||||
if(caster->GetTypeId()==TYPEID_PLAYER)
|
|
||||||
if(BattleGround *bg = ((Player*)caster)->GetBattleGround())
|
|
||||||
bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
|
|
||||||
|
|
||||||
// ignore item heals
|
|
||||||
if(m_CastItem)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 procHealer = PROC_FLAG_HEAL;
|
|
||||||
if (crit)
|
|
||||||
procHealer |= PROC_FLAG_CRIT_HEAL;
|
|
||||||
|
|
||||||
m_caster->ProcDamageAndSpell(unitTarget,procHealer,PROC_FLAG_HEALED,addhealth,SPELL_SCHOOL_MASK_NONE,m_spellInfo,m_IsTriggeredSpell);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2473,6 +2399,8 @@ void Spell::EffectHealthLeech(uint32 i)
|
||||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(new_damage));
|
m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(new_damage));
|
||||||
}
|
}
|
||||||
|
// m_healthLeech+=tmpvalue;
|
||||||
|
// m_damage+=new_damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::DoCreateItem(uint32 i, uint32 itemtype)
|
void Spell::DoCreateItem(uint32 i, uint32 itemtype)
|
||||||
|
|
@ -4317,35 +4245,9 @@ void Spell::EffectWeaponDmg(uint32 i)
|
||||||
// prevent negative damage
|
// prevent negative damage
|
||||||
uint32 eff_damage = uint32(bonus > 0 ? bonus : 0);
|
uint32 eff_damage = uint32(bonus > 0 ? bonus : 0);
|
||||||
|
|
||||||
const uint32 nohitMask = HITINFO_ABSORB | HITINFO_RESIST | HITINFO_MISS;
|
// Add melee damage bonuses (also check for negative)
|
||||||
|
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
|
||||||
uint32 hitInfo = 0;
|
m_damage+= eff_damage;
|
||||||
VictimState victimState = VICTIMSTATE_NORMAL;
|
|
||||||
uint32 blocked_dmg = 0;
|
|
||||||
uint32 absorbed_dmg = 0;
|
|
||||||
uint32 resisted_dmg = 0;
|
|
||||||
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
|
|
||||||
|
|
||||||
m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, m_spellSchoolMask, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, m_attackType, m_spellInfo, m_IsTriggeredSpell);
|
|
||||||
|
|
||||||
if ((hitInfo & nohitMask) && m_attackType != RANGED_ATTACK) // not send ranged miss/etc
|
|
||||||
m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, m_spellSchoolMask, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg);
|
|
||||||
|
|
||||||
bool criticalhit = (hitInfo & HITINFO_CRITICALHIT);
|
|
||||||
m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, m_spellSchoolMask, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit);
|
|
||||||
|
|
||||||
if (eff_damage > (absorbed_dmg + resisted_dmg + blocked_dmg))
|
|
||||||
{
|
|
||||||
eff_damage -= (absorbed_dmg + resisted_dmg + blocked_dmg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cleanDamage.damage += eff_damage;
|
|
||||||
eff_damage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPELL_SCHOOL_NORMAL use for weapon-like threat and rage calculation
|
|
||||||
m_caster->DealDamage(unitTarget, eff_damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, true);
|
|
||||||
|
|
||||||
// Hemorrhage
|
// Hemorrhage
|
||||||
if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & 0x2000000))
|
if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & 0x2000000))
|
||||||
|
|
@ -4409,10 +4311,7 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
|
||||||
|
|
||||||
uint32 heal = m_caster->GetMaxHealth();
|
uint32 heal = m_caster->GetMaxHealth();
|
||||||
|
|
||||||
int32 gain = unitTarget->ModifyHealth(heal);
|
m_healing+=heal;
|
||||||
unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
|
|
||||||
|
|
||||||
m_caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, heal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectInterruptCast(uint32 /*i*/)
|
void Spell::EffectInterruptCast(uint32 /*i*/)
|
||||||
|
|
|
||||||
|
|
@ -530,6 +530,17 @@ bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellI
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId)
|
||||||
|
{
|
||||||
|
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
|
||||||
|
if (!spellproto) return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
if (spellproto->EffectApplyAuraName[i] == auraType)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
|
uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
|
||||||
{
|
{
|
||||||
// talents that learn spells can have stance requirements that need ignore
|
// talents that learn spells can have stance requirements that need ignore
|
||||||
|
|
@ -806,8 +817,8 @@ void SpellMgr::LoadSpellProcEvents()
|
||||||
|
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
|
||||||
// 0 1 2 3 4 5 6 7 8
|
// 0 1 2 3 4 5 6 7 8
|
||||||
QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, Category, SkillID, SpellFamilyName, SpellFamilyMask, procFlags, ppmRate, cooldown FROM spell_proc_event");
|
QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
|
||||||
if( !result )
|
if( !result )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -821,7 +832,7 @@ void SpellMgr::LoadSpellProcEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
barGoLink bar( result->GetRowCount() );
|
barGoLink bar( result->GetRowCount() );
|
||||||
|
uint32 customProc = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
|
|
@ -830,7 +841,8 @@ void SpellMgr::LoadSpellProcEvents()
|
||||||
|
|
||||||
uint16 entry = fields[0].GetUInt16();
|
uint16 entry = fields[0].GetUInt16();
|
||||||
|
|
||||||
if (!sSpellStore.LookupEntry(entry))
|
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
|
||||||
|
if (!spell)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Spell %u listed in `spell_proc_event` does not exist", entry);
|
sLog.outErrorDb("Spell %u listed in `spell_proc_event` does not exist", entry);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -839,23 +851,35 @@ void SpellMgr::LoadSpellProcEvents()
|
||||||
SpellProcEventEntry spe;
|
SpellProcEventEntry spe;
|
||||||
|
|
||||||
spe.schoolMask = fields[1].GetUInt32();
|
spe.schoolMask = fields[1].GetUInt32();
|
||||||
spe.category = fields[2].GetUInt32();
|
spe.spellFamilyName = fields[2].GetUInt32();
|
||||||
spe.skillId = fields[3].GetUInt32();
|
spe.spellFamilyMask = fields[3].GetUInt64();
|
||||||
spe.spellFamilyName = fields[4].GetUInt32();
|
spe.procFlags = fields[4].GetUInt32();
|
||||||
spe.spellFamilyMask = fields[5].GetUInt64();
|
spe.procEx = fields[5].GetUInt32();
|
||||||
spe.procFlags = fields[6].GetUInt32();
|
spe.ppmRate = fields[6].GetFloat();
|
||||||
spe.ppmRate = fields[7].GetFloat();
|
spe.customChance = fields[7].GetFloat();
|
||||||
spe.cooldown = fields[8].GetUInt32();
|
spe.cooldown = fields[8].GetUInt32();
|
||||||
|
|
||||||
mSpellProcEventMap[entry] = spe;
|
mSpellProcEventMap[entry] = spe;
|
||||||
|
|
||||||
|
if (spell->procFlags==0)
|
||||||
|
{
|
||||||
|
if (spe.procFlags == 0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Spell %u listed in `spell_proc_event` probally not triggered spell", entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
customProc++;
|
||||||
|
}
|
||||||
++count;
|
++count;
|
||||||
} while( result->NextRow() );
|
} while( result->NextRow() );
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString( ">> Loaded %u spell proc event conditions", count );
|
if (customProc)
|
||||||
|
sLog.outString( ">> Loaded %u custom spell proc event conditions +%u custom", count, customProc );
|
||||||
|
else
|
||||||
|
sLog.outString( ">> Loaded %u spell proc event conditions", count );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event)
|
// Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event)
|
||||||
|
|
@ -887,6 +911,7 @@ void SpellMgr::LoadSpellProcEvents()
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags )
|
bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags )
|
||||||
{
|
{
|
||||||
if((procFlags & spellProcEvent->procFlags) == 0)
|
if((procFlags & spellProcEvent->procFlags) == 0)
|
||||||
|
|
@ -925,6 +950,73 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spell
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
|
||||||
|
{
|
||||||
|
// No extra req need
|
||||||
|
uint32 procEvent_procEx = PROC_EX_NONE;
|
||||||
|
|
||||||
|
// check prockFlags for condition
|
||||||
|
if((procFlags & EventProcFlag) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Always trigger for this
|
||||||
|
if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL_AND_GET_XP))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (spellProcEvent) // Exist event data
|
||||||
|
{
|
||||||
|
// Store extra req
|
||||||
|
procEvent_procEx = spellProcEvent->procEx;
|
||||||
|
|
||||||
|
// For melee triggers
|
||||||
|
if (procSpell == NULL)
|
||||||
|
{
|
||||||
|
// Check (if set) for school (melee attack have Normal school)
|
||||||
|
if(spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // For spells need check school/spell family/family mask
|
||||||
|
{
|
||||||
|
// Check (if set) for school
|
||||||
|
if(spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check (if set) for spellFamilyName
|
||||||
|
if(spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// spellFamilyName is Ok need check for spellFamilyMask if present
|
||||||
|
if(spellProcEvent->spellFamilyMask)
|
||||||
|
{
|
||||||
|
if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)
|
||||||
|
return false;
|
||||||
|
active = true; // Spell added manualy -> so its active spell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for extra req (if none) and hit/crit
|
||||||
|
if (procEvent_procEx == PROC_EX_NONE)
|
||||||
|
{
|
||||||
|
// No extra req, so can trigger only for active (damage/healing present) and hit/crit
|
||||||
|
if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && active)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else // Passive spells hits here only if resist/reflect/immune/evade
|
||||||
|
{
|
||||||
|
// Exist req for PROC_EX_EX_TRIGGER_ALWAYS
|
||||||
|
if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
|
||||||
|
return true;
|
||||||
|
// Passive spells can`t trigger if need hit
|
||||||
|
if ((procEvent_procEx & PROC_EX_NORMAL_HIT) && !active)
|
||||||
|
return false;
|
||||||
|
// Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
|
||||||
|
if (procEvent_procEx & procExtra)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SpellMgr::LoadSpellElixirs()
|
void SpellMgr::LoadSpellElixirs()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,8 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB);
|
||||||
bool IsSingleTargetSpell(SpellEntry const *spellInfo);
|
bool IsSingleTargetSpell(SpellEntry const *spellInfo);
|
||||||
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
|
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
|
||||||
|
|
||||||
|
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
|
||||||
|
|
||||||
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
|
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
|
||||||
|
|
||||||
inline bool IsAreaEffectTarget( Targets target )
|
inline bool IsAreaEffectTarget( Targets target )
|
||||||
|
|
@ -441,50 +443,86 @@ typedef std::map<uint32, uint64> SpellAffectMap;
|
||||||
// Spell proc event related declarations (accessed using SpellMgr functions)
|
// Spell proc event related declarations (accessed using SpellMgr functions)
|
||||||
enum ProcFlags
|
enum ProcFlags
|
||||||
{
|
{
|
||||||
PROC_FLAG_NONE = 0x00000000, // None
|
PROC_FLAG_NONE = 0x00000000,
|
||||||
PROC_FLAG_HIT_MELEE = 0x00000001, // On melee hit
|
|
||||||
PROC_FLAG_STRUCK_MELEE = 0x00000002, // On being struck melee
|
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
|
||||||
PROC_FLAG_KILL_XP_GIVER = 0x00000004, // On kill target giving XP or honor
|
PROC_FLAG_KILL_AND_GET_XP = 0x00000002, // 01 Kill that yields experience or honor
|
||||||
PROC_FLAG_SPECIAL_DROP = 0x00000008, //
|
|
||||||
PROC_FLAG_DODGE = 0x00000010, // On dodge melee attack
|
PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee attack
|
||||||
PROC_FLAG_PARRY = 0x00000020, // On parry melee attack
|
PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee strike hit
|
||||||
PROC_FLAG_BLOCK = 0x00000040, // On block attack
|
|
||||||
PROC_FLAG_TOUCH = 0x00000080, // On being touched (for bombs, probably?)
|
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
|
||||||
PROC_FLAG_TARGET_LOW_HEALTH = 0x00000100, // On deal damage to enemy with 20% or less health
|
PROC_FLAG_TAKEN_MELEE_SPELL_HIT = 0x00000020, // 05 Taken damage by Spell that use melee weapon
|
||||||
PROC_FLAG_LOW_HEALTH = 0x00000200, // On health dropped below 20%
|
|
||||||
PROC_FLAG_STRUCK_RANGED = 0x00000400, // On being struck ranged
|
PROC_FLAG_SUCCESSFUL_RANGED_HIT = 0x00000040, // 06 Successful Ranged attack (all ranged attack deal as spell so newer set :( )
|
||||||
PROC_FLAG_HIT_SPECIAL = 0x00000800, // (!)Removed, may be reassigned in future
|
PROC_FLAG_TAKEN_RANGED_HIT = 0x00000080, // 07 Taken damage from ranged attack (all ranged attack deal as spell so newer set :( )
|
||||||
PROC_FLAG_CRIT_MELEE = 0x00001000, // On crit melee
|
|
||||||
PROC_FLAG_STRUCK_CRIT_MELEE = 0x00002000, // On being critically struck in melee
|
PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT = 0x00000100, // 08 Successful Ranged attack by Spell that use ranged weapon
|
||||||
PROC_FLAG_CAST_SPELL = 0x00004000, // On cast spell
|
PROC_FLAG_TAKEN_RANGED_SPELL_HIT = 0x00000200, // 09 Taken damage by Spell that use ranged weapon
|
||||||
PROC_FLAG_TAKE_DAMAGE = 0x00008000, // On take damage
|
|
||||||
PROC_FLAG_CRIT_SPELL = 0x00010000, // On crit spell
|
PROC_FLAG_SUCCESSFUL_POSITIVE_AOE_HIT = 0x00000400, // 10 Successful AoE (not 100% shure unused)
|
||||||
PROC_FLAG_HIT_SPELL = 0x00020000, // On hit spell
|
PROC_FLAG_TAKEN_POSITIVE_AOE = 0x00000800, // 11 Taken AoE (not 100% shure unused)
|
||||||
PROC_FLAG_STRUCK_CRIT_SPELL = 0x00040000, // On being critically struck by a spell
|
|
||||||
PROC_FLAG_HIT_RANGED = 0x00080000, // On getting ranged hit
|
PROC_FLAG_SUCCESSFUL_AOE_SPELL_HIT = 0x00001000, // 12 Successful AoE damage spell hit (not 100% shure unused)
|
||||||
PROC_FLAG_STRUCK_SPELL = 0x00100000, // On being struck by a spell
|
PROC_FLAG_TAKEN_AOE_SPELL_HIT = 0x00002000, // 13 Taken AoE damage spell hit (not 100% shure unused)
|
||||||
PROC_FLAG_TRAP = 0x00200000, // On trap activation (?)
|
|
||||||
PROC_FLAG_CRIT_RANGED = 0x00400000, // On getting ranged crit
|
PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL = 0x00004000, // 14 Successful cast positive spell (by default only on healing)
|
||||||
PROC_FLAG_STRUCK_CRIT_RANGED = 0x00800000, // On being critically struck by a ranged attack
|
PROC_FLAG_TAKEN_POSITIVE_SPELL = 0x00008000, // 15 Taken positive spell hit (by default only on healing)
|
||||||
PROC_FLAG_RESIST_SPELL = 0x01000000, // On resist enemy spell
|
|
||||||
PROC_FLAG_TARGET_RESISTS = 0x02000000, // On enemy resisted spell
|
PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT = 0x00010000, // 16 Successful negative spell cast (by default only on damage)
|
||||||
PROC_FLAG_TARGET_DODGE_OR_PARRY = 0x04000000, // On enemy dodges/parries
|
PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT = 0x00020000, // 17 Taken negative spell (by default only on damage)
|
||||||
PROC_FLAG_HEAL = 0x08000000, // On heal
|
|
||||||
PROC_FLAG_CRIT_HEAL = 0x10000000, // On critical healing effect
|
PROC_FLAG_ON_DO_PERIODIC = 0x00040000, // 18 Successful do periodic (damage / healing, determined from 14-17 flags)
|
||||||
PROC_FLAG_HEALED = 0x20000000, // On healing
|
PROC_FLAG_ON_TAKE_PERIODIC = 0x00080000, // 19 Taken spell periodic (damage / healing, determined from 14-17 flags)
|
||||||
PROC_FLAG_TARGET_BLOCK = 0x40000000, // On enemy blocks
|
|
||||||
PROC_FLAG_MISS = 0x80000000 // On miss melee attack
|
PROC_FLAG_TAKEN_ANY_DAMAGE = 0x00100000, // 20 Taken any damage
|
||||||
|
PROC_FLAG_ON_TRAP_ACTIVATION = 0x00200000, // 21 On trap activation
|
||||||
|
|
||||||
|
PROC_FLAG_TAKEN_OFFHAND_HIT = 0x00400000, // 22 Taken off-hand melee attacks(not used)
|
||||||
|
PROC_FLAG_SUCCESSFUL_OFFHAND_HIT = 0x00800000 // 23 Successful off-hand melee attacks
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT | \
|
||||||
|
PROC_FLAG_TAKEN_MELEE_HIT | \
|
||||||
|
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \
|
||||||
|
PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \
|
||||||
|
PROC_FLAG_SUCCESSFUL_RANGED_HIT | \
|
||||||
|
PROC_FLAG_TAKEN_RANGED_HIT | \
|
||||||
|
PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT | \
|
||||||
|
PROC_FLAG_TAKEN_RANGED_SPELL_HIT)
|
||||||
|
|
||||||
|
enum ProcFlagsEx
|
||||||
|
{
|
||||||
|
PROC_EX_NONE = 0x0000000, // If none can tigger on Hit/Crit only (passive spells MUST defined by SpellFamily flag)
|
||||||
|
PROC_EX_NORMAL_HIT = 0x0000001, // If set only from normal hit (only damage spells)
|
||||||
|
PROC_EX_CRITICAL_HIT = 0x0000002,
|
||||||
|
PROC_EX_MISS = 0x0000004,
|
||||||
|
PROC_EX_RESIST = 0x0000008,
|
||||||
|
PROC_EX_DODGE = 0x0000010,
|
||||||
|
PROC_EX_PARRY = 0x0000020,
|
||||||
|
PROC_EX_BLOCK = 0x0000040,
|
||||||
|
PROC_EX_EVADE = 0x0000080,
|
||||||
|
PROC_EX_IMMUNE = 0x0000100,
|
||||||
|
PROC_EX_DEFLECT = 0x0000200,
|
||||||
|
PROC_EX_ABSORB = 0x0000400,
|
||||||
|
PROC_EX_REFLECT = 0x0000800,
|
||||||
|
PROC_EX_INTERRUPT = 0x0001000, // Melle hit result can be Interrupt (not used)
|
||||||
|
PROC_EX_RESERVED1 = 0x0002000,
|
||||||
|
PROC_EX_RESERVED2 = 0x0004000,
|
||||||
|
PROC_EX_RESERVED3 = 0x0008000,
|
||||||
|
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges
|
||||||
|
PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000 // If set trigger always but only one time
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpellProcEventEntry
|
struct SpellProcEventEntry
|
||||||
{
|
{
|
||||||
uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
|
uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2
|
||||||
uint32 category; // if nonzero - match proc condition based on candidate spell's category
|
|
||||||
uint32 skillId; // if nonzero - for matching proc condition based on candidate spell's skillId from SkillLineAbility.dbc (Shadow Bolt = Destruction)
|
|
||||||
uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
|
uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value
|
||||||
uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
|
uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do)
|
||||||
uint32 procFlags; // bitmask for matching proc event
|
uint32 procFlags; // bitmask for matching proc event
|
||||||
|
uint32 procEx; // proc Extend info (see ProcFlagsEx)
|
||||||
float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
|
float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc
|
||||||
|
float customChance; // Owerride chance (in most cases for debug only)
|
||||||
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
|
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -683,7 +721,7 @@ class SpellMgr
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags );
|
static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
|
||||||
|
|
||||||
// Spell target coordinates
|
// Spell target coordinates
|
||||||
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
|
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
|
||||||
|
|
|
||||||
2014
src/game/Unit.cpp
2014
src/game/Unit.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -578,6 +578,50 @@ struct CleanDamage
|
||||||
MeleeHitOutcome hitOutCome;
|
MeleeHitOutcome hitOutCome;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Struct for use in Unit::CalculateMeleeDamage
|
||||||
|
// Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode
|
||||||
|
struct CalcDamageInfo
|
||||||
|
{
|
||||||
|
Unit *attacker; // Attacker
|
||||||
|
Unit *target; // Target for damage
|
||||||
|
uint32 damageSchoolMask;
|
||||||
|
uint32 damage;
|
||||||
|
uint32 absorb;
|
||||||
|
uint32 resist;
|
||||||
|
uint32 blocked_amount;
|
||||||
|
uint32 HitInfo;
|
||||||
|
uint32 TargetState;
|
||||||
|
// Helper
|
||||||
|
WeaponAttackType attackType; //
|
||||||
|
uint32 procAttacker;
|
||||||
|
uint32 procVictim;
|
||||||
|
uint32 procEx;
|
||||||
|
uint32 cleanDamage; // Used only fo rage calcultion
|
||||||
|
MeleeHitOutcome hitOutCome; // TODO: remove this field (need use TargetState)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode
|
||||||
|
struct SpellNonMeleeDamage{
|
||||||
|
SpellNonMeleeDamage(Unit *_attacker, Unit *_target, uint32 _SpellID, uint32 _schoolMask) :
|
||||||
|
attacker(_attacker), target(_target), SpellID(_SpellID), damage(0), schoolMask(_schoolMask),
|
||||||
|
absorb(0), resist(0), phusicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) {}
|
||||||
|
Unit *target;
|
||||||
|
Unit *attacker;
|
||||||
|
uint32 SpellID;
|
||||||
|
uint32 damage;
|
||||||
|
uint32 schoolMask;
|
||||||
|
uint32 absorb;
|
||||||
|
uint32 resist;
|
||||||
|
bool phusicalLog;
|
||||||
|
bool unused;
|
||||||
|
uint32 blocked;
|
||||||
|
uint32 HitInfo;
|
||||||
|
// Used for help
|
||||||
|
uint32 cleanDamage;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition);
|
||||||
|
|
||||||
struct UnitActionBarEntry
|
struct UnitActionBarEntry
|
||||||
{
|
{
|
||||||
uint32 Type;
|
uint32 Type;
|
||||||
|
|
@ -684,6 +728,8 @@ enum ReactiveType
|
||||||
// delay time next attack to prevent client attack animation problems
|
// delay time next attack to prevent client attack animation problems
|
||||||
#define ATTACK_DISPLAY_DELAY 200
|
#define ATTACK_DISPLAY_DELAY 200
|
||||||
|
|
||||||
|
struct SpellProcEventEntry; // used only privately
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC Unit : public WorldObject
|
class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -834,15 +880,23 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
|
|
||||||
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||||
uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
|
uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
|
||||||
void DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit = false, bool isTriggeredSpell = false);
|
|
||||||
void DoAttackDamage(Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false);
|
|
||||||
|
|
||||||
void CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted = NULL, bool isTriggeredSpell = false);
|
void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL);
|
||||||
void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage = 0, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NONE, SpellEntry const *procSpell = NULL, bool isTriggeredSpell = false, WeaponAttackType attType = BASE_ATTACK);
|
void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage );
|
||||||
|
|
||||||
void HandleEmoteCommand(uint32 anim_id);
|
void HandleEmoteCommand(uint32 anim_id);
|
||||||
void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false );
|
void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false );
|
||||||
|
|
||||||
float MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const;
|
float MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const;
|
||||||
|
|
||||||
|
void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType = BASE_ATTACK);
|
||||||
|
void DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss);
|
||||||
|
|
||||||
|
void CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK);
|
||||||
|
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss);
|
||||||
|
|
||||||
|
float MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell);
|
||||||
|
SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
||||||
SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell);
|
||||||
SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false);
|
SpellMissInfo SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool canReflect = false);
|
||||||
|
|
||||||
|
|
@ -857,7 +911,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
|
uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
|
||||||
float GetWeaponProcChance() const;
|
float GetWeaponProcChance() const;
|
||||||
float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;
|
float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;
|
||||||
MeleeHitOutcome RollPhysicalOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo);
|
|
||||||
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const;
|
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const;
|
||||||
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const;
|
MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted ) const;
|
||||||
|
|
||||||
|
|
@ -931,7 +985,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
|
|
||||||
void DeMorph();
|
void DeMorph();
|
||||||
|
|
||||||
|
void SendAttackStateUpdate(CalcDamageInfo *damageInfo);
|
||||||
void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
|
void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
|
||||||
|
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log);
|
||||||
void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
|
void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
|
||||||
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
|
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
|
||||||
|
|
||||||
|
|
@ -1178,7 +1234,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
|
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
|
||||||
uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
|
uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
|
||||||
uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
|
uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
|
||||||
bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType);
|
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 SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
|
uint32 SpellCriticalBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
|
||||||
|
|
||||||
void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; }
|
void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; }
|
||||||
|
|
@ -1316,12 +1373,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
|
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
|
||||||
void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
|
void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
|
||||||
|
|
||||||
void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask );
|
bool IsTriggeredAtSpellProcEvent( Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
|
||||||
bool IsTriggeredAtSpellProcEvent( SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown );
|
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||||
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown);
|
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||||
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, uint32 cooldown);
|
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
|
||||||
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown);
|
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
|
||||||
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown);
|
|
||||||
bool HandleMeandingAuraProc(Aura* triggeredByAura);
|
bool HandleMeandingAuraProc(Aura* triggeredByAura);
|
||||||
|
|
||||||
uint32 m_state; // Even derived shouldn't modify
|
uint32 m_state; // Even derived shouldn't modify
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue