*Update proc system.

--HG--
branch : trunk
This commit is contained in:
QAston
2009-05-17 18:00:33 +02:00
parent d2ef2c0500
commit 7c6757d7ee
11 changed files with 85 additions and 51 deletions
+2
View File
@@ -0,0 +1,2 @@
DELETE FROM spell_linked_spell WHERE `spell_trigger` IN (38528);
DELETE FROM spell_proc_event WHERE `entry` IN (31785, 33776);
-6
View File
@@ -104,10 +104,6 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comm
( 40604, 40616, 1, 'Fel Rage Aura'), ( 40604, 40616, 1, 'Fel Rage Aura'),
( 40616, 41625, 1, 'Fel Rage Aura'), ( 40616, 41625, 1, 'Fel Rage Aura'),
( 41292, 42017, 2, 'Aura of Suffering'), ( 41292, 42017, 2, 'Aura of Suffering'),
-- hyjal mount
( 38528,-31984, 2, 'Protection of Elune - Finger of Death'),
( 38528,-32111, 2, 'Protection of Elune - Finger of Death'),
( 38528,-32124, 2, 'Protection of Elune - Denouement Wisp'),
-- sunwell -- sunwell
( 44869, 44866, 1, 'Spectral Blast Portal'), ( 44869, 44866, 1, 'Spectral Blast Portal'),
# (44869, 46648, 1, 'Spectral Blast Visual'), cause severe lag seems should be casted by go # (44869, 46648, 1, 'Spectral Blast Visual'), cause severe lag seems should be casted by go
@@ -920,7 +916,6 @@ INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `Spell
(31394, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0), (31394, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(31569, 0, 3, 65536, 0, 0, 0, 0, 0, 0, 0), (31569, 0, 3, 65536, 0, 0, 0, 0, 0, 0, 0),
(31570, 0, 3, 65536, 0, 0, 0, 0, 0, 0, 0), (31570, 0, 3, 65536, 0, 0, 0, 0, 0, 0, 0),
(31785, 0, 0, 0, 0, 0, 34816, 0, 0, 0, 0),
(31794, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0), (31794, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0),
(31801, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0), (31801, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0),
(31833, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0), (31833, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0),
@@ -974,7 +969,6 @@ INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `Spell
(33746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10), (33746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10),
(33757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3), (33757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3),
(33759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10), (33759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10),
(33776, 0, 0, 0, 0, 0, 34816, 0, 0, 0, 0),
(33881, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0), (33881, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0),
(33882, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0), (33882, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0),
(33883, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0), (33883, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0),
+1 -1
View File
@@ -67,7 +67,7 @@ void SpellAI::EnterCombat(Unit *who)
for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i)
{ {
if(AISpellInfo[*i].condition == AICOND_AGGRO) if(AISpellInfo[*i].condition == AICOND_AGGRO)
me->CastSpell(who, *i, true); me->CastSpell(who, *i, false);
else if(AISpellInfo[*i].condition == AICOND_COMBAT) else if(AISpellInfo[*i].condition == AICOND_COMBAT)
events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown);
} }
+33 -9
View File
@@ -364,6 +364,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_delayStart = 0; m_delayStart = 0;
m_delayAtDamageCount = 0; m_delayAtDamageCount = 0;
m_canTrigger=true;
m_applyMultiplierMask = 0; m_applyMultiplierMask = 0;
m_effectMask = 0; m_effectMask = 0;
@@ -723,14 +725,38 @@ void Spell::FillTargetMap()
} }
} }
void Spell::prepareDataForTriggerSystem() void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
{ {
//========================================================================================== //==========================================================================================
// Now fill data for trigger system, need know: // Now fill data for trigger system, need know:
// an spell trigger another or not ( m_canTrigger ) // can spell trigger another or not ( m_canTrigger )
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim) // Create base triggers flags for Attacker and Victim ( m_procAttacker, m_procVictim and m_procEx)
//========================================================================================== //==========================================================================================
/*
Effects which are result of aura proc from triggered spell cannot proc
to prevent chain proc of these spells
*/
if (triggeredByAura && !triggeredByAura->GetParentAura()->CanProc())
{
m_canTrigger=false;
}
m_procEx = (m_IsTriggeredSpell)
&& !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER)
&& !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2)
? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE;
if (m_IsTriggeredSpell && (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2 | SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER))
m_procEx |= PROC_EX_INTERNAL_CANT_PROC;
// Totem casts require spellfamilymask defined in spell_proc_event to proc
if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isTotem() && m_caster->IsControlledByPlayer())
{
m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY;
}
// Get data for type of attack and fill base info for trigger // Get data for type of attack and fill base info for trigger
switch (m_spellInfo->DmgClass) switch (m_spellInfo->DmgClass)
{ {
@@ -973,15 +999,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Fill base trigger info // Fill base trigger info
uint32 procAttacker = m_procAttacker; uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim; uint32 procVictim = m_procVictim;
uint32 procEx = m_triggeredByAuraSpell uint32 procEx = m_procEx;
&& !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER)
&& !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2)
? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE;
m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
//Spells with this flag cannot trigger if effect is casted on self //Spells with this flag cannot trigger if effect is casted on self
// Slice and Dice, relentless strikes, eviscerate // Slice and Dice, relentless strikes, eviscerate
bool canEffectTrigger = (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST | SPELL_ATTR_EX4_UNK4) ? m_caster!=unitTarget : true); bool canEffectTrigger = m_canTrigger && (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST | SPELL_ATTR_EX4_UNK4) ? m_caster!=unitTarget : true);
Unit * spellHitTarget = NULL; Unit * spellHitTarget = NULL;
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
@@ -2327,7 +2351,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura
} }
// Prepare data for triggers // Prepare data for triggers
prepareDataForTriggerSystem(); prepareDataForTriggerSystem(triggeredByAura);
// Set combo point requirement // Set combo point requirement
if (m_IsTriggeredSpell || m_CastItem || m_caster->GetTypeId()!=TYPEID_PLAYER) if (m_IsTriggeredSpell || m_CastItem || m_caster->GetTypeId()!=TYPEID_PLAYER)
+4 -2
View File
@@ -458,7 +458,7 @@ class Spell
bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; }
void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; }
bool IsInterruptable() const { return !m_executedCurrently; } bool IsInterruptable() const { return !m_executedCurrently; }
void SetExecutedCurrently(bool yes) { m_executedCurrently = yes; } void SetExecutedCurrently(bool yes) {m_executedCurrently = yes;}
uint64 GetDelayStart() const { return m_delayStart; } uint64 GetDelayStart() const { return m_delayStart; }
void SetDelayStart(uint64 m_time) { m_delayStart = m_time; } void SetDelayStart(uint64 m_time) { m_delayStart = m_time; }
uint64 GetDelayMoment() const { return m_delayMoment; } uint64 GetDelayMoment() const { return m_delayMoment; }
@@ -552,7 +552,9 @@ class Spell
//****************************************** //******************************************
uint32 m_procAttacker; // Attacker trigger flags uint32 m_procAttacker; // Attacker trigger flags
uint32 m_procVictim; // Victim trigger flags uint32 m_procVictim; // Victim trigger flags
void prepareDataForTriggerSystem(); uint32 m_procEx;
bool m_canTrigger;
void prepareDataForTriggerSystem(AuraEffect * triggeredByAura);
//***************************************** //*****************************************
// Spell target subsystem // Spell target subsystem
+14 -12
View File
@@ -346,7 +346,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem, Unit * formalCaster) : Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem, Unit * formalCaster) :
m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
m_timeCla(1000), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE), m_timeCla(1000), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false) m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false), m_canProc(true)
{ {
assert(target); assert(target);
@@ -613,6 +613,8 @@ Unit* AreaAuraEffect::GetFormalCaster() const
void Aura::Update(uint32 diff) void Aura::Update(uint32 diff)
{ {
// Reset can proc requirement-prevent use of outdated value
m_canProc = true;
if (m_duration > 0) if (m_duration > 0)
{ {
m_duration -= diff; m_duration -= diff;
@@ -1837,7 +1839,7 @@ void AuraEffect::TriggerSpell()
// Doom // Doom
case 31347: case 31347:
{ {
m_target->CastSpell(m_target,31350,true); m_target->CastSpell(m_target,31350,true, NULL, this);
m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
return; return;
} }
@@ -1867,9 +1869,9 @@ void AuraEffect::TriggerSpell()
{ {
// cast 24 spells 34269-34289, 34314-34316 // cast 24 spells 34269-34289, 34314-34316
for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id) for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
caster->CastSpell(m_target,spell_id,true); caster->CastSpell(m_target,spell_id,true, NULL, this);
for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id) for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
caster->CastSpell(m_target,spell_id,true); caster->CastSpell(m_target,spell_id,true, NULL, this);
return; return;
} }
// // Gravity Lapse // // Gravity Lapse
@@ -1951,7 +1953,7 @@ void AuraEffect::TriggerSpell()
// Eye of Grillok // Eye of Grillok
case 38495: case 38495:
{ {
m_target->CastSpell(m_target, 38530, true); m_target->CastSpell(m_target, 38530, true, NULL, this);
return; return;
} }
// Absorb Eye of Grillok (Zezzak's Shard) // Absorb Eye of Grillok (Zezzak's Shard)
@@ -1960,7 +1962,7 @@ void AuraEffect::TriggerSpell()
if(m_target->GetTypeId() != TYPEID_UNIT) if(m_target->GetTypeId() != TYPEID_UNIT)
return; return;
caster->CastSpell(caster, 38495, true); caster->CastSpell(caster, 38495, true, NULL, this);
Creature* creatureTarget = (Creature*)m_target; Creature* creatureTarget = (Creature*)m_target;
@@ -2198,7 +2200,7 @@ void AuraEffect::TriggerSpell()
} }
if(all) if(all)
caster->CastSpell(caster,38437,true); caster->CastSpell(caster,38437,true, NULL, this);
else else
caster->RemoveAurasDueToSpell(38437); caster->RemoveAurasDueToSpell(38437);
return; return;
@@ -2278,7 +2280,7 @@ void AuraEffect::TriggerSpell()
// Curse of the Plaguebringer (22/15) // Curse of the Plaguebringer (22/15)
case 29213: case 29213:
case 54835: case 54835:
caster->CastSpell(m_target, trigger_spell_id, true); caster->CastSpell(m_target, trigger_spell_id, true, NULL, this);
return; return;
} }
} }
@@ -4244,10 +4246,10 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real, bool /*changeA
{ {
if(apply) if(apply)
{ {
m_target->CastSpell(m_target,24395,true); m_target->CastSpell(m_target,24395,true, NULL, this);
m_target->CastSpell(m_target,24396,true); m_target->CastSpell(m_target,24396,true, NULL, this);
m_target->CastSpell(m_target,24397,true); m_target->CastSpell(m_target,24397,true, NULL, this);
m_target->CastSpell(m_target,26592,true); m_target->CastSpell(m_target,26592,true, NULL, this);
} }
else else
{ {
+6 -1
View File
@@ -107,6 +107,8 @@ class TRINITY_DLL_SPEC Aura
bool IsRemoved() const { return m_isRemoved; } bool IsRemoved() const { return m_isRemoved; }
void SetUpdated(bool val) { m_updated = val; } void SetUpdated(bool val) { m_updated = val; }
bool CanProc(){return m_canProc;}
void SetCanProc(bool val){ m_canProc = val; }
bool IsPersistent() const; bool IsPersistent() const;
bool IsAreaAura() const; bool IsAreaAura() const;
bool IsAuraType(AuraType type) const; bool IsAuraType(AuraType type) const;
@@ -152,11 +154,13 @@ class TRINITY_DLL_SPEC Aura
uint8 m_auraFlags; // Aura info flag (for send data to client) uint8 m_auraFlags; // Aura info flag (for send data to client)
uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount) uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
uint8 m_procCharges; // Aura charges (0 for infinite) uint8 m_procCharges; // Aura charges (0 for infinite)
uint32 m_procDamage; // used in aura proc code
uint8 m_stackAmount; // Aura stack amount uint8 m_stackAmount; // Aura stack amount
uint32 m_auraStateMask; uint32 m_auraStateMask;
AuraEffect * m_partAuras[3]; AuraEffect * m_partAuras[3];
uint32 m_procDamage; // used in aura proc code
bool m_canProc:1;
bool m_isDeathPersist:1; bool m_isDeathPersist:1;
bool m_isRemovedOnShapeLost:1; bool m_isRemovedOnShapeLost:1;
bool m_isPassive:1; bool m_isPassive:1;
@@ -396,6 +400,7 @@ class TRINITY_DLL_SPEC AreaAuraEffect : public AuraEffect
AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster=NULL, Item * castItem=NULL, Unit * formalCaster=NULL); AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster=NULL, Item * castItem=NULL, Unit * formalCaster=NULL);
~AreaAuraEffect(); ~AreaAuraEffect();
Unit* GetFormalCaster() const; Unit* GetFormalCaster() const;
uint64 const& GetFormalCasterGUID() const { return m_formalCasterGUID; }
void Update(uint32 diff); void Update(uint32 diff);
private: private:
float m_radius; float m_radius;
+9
View File
@@ -1222,6 +1222,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
if((procFlags & EventProcFlag) == 0) if((procFlags & EventProcFlag) == 0)
return false; return false;
bool hasFamilyMask = false;
/* Check Periodic Auras /* Check Periodic Auras
* Both hots and dots can trigger if spell has no PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL * Both hots and dots can trigger if spell has no PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL
@@ -1288,10 +1290,17 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0) if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
return false; return false;
active = true; // Spell added manualy -> so its active spell active = true; // Spell added manualy -> so its active spell
hasFamilyMask = true;
} }
} }
} }
if (procExtra & PROC_EX_INTERNAL_REQ_FAMILY)
{
if (!hasFamilyMask)
return false;
}
// Check for extra req (if none) and hit/crit // Check for extra req (if none) and hit/crit
if (procEvent_procEx == PROC_EX_NONE) if (procEvent_procEx == PROC_EX_NONE)
{ {
+3 -2
View File
@@ -467,11 +467,12 @@ enum ProcFlagsEx
PROC_EX_AURA_REMOVE_DESTROY = 0x0002000, // aura absorb destroy or dispel PROC_EX_AURA_REMOVE_DESTROY = 0x0002000, // aura absorb destroy or dispel
PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges 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 (not used) PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used)
PROC_EX_INTERNAL_CANT_PROC = 0x0800000,
PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use
PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use
PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use
PROC_EX_INTERNAL_ITEM_CAST = 0x8000000 PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 // Only for internal use
}; };
#define AURA_REMOVE_PROC_EX_MASK \ #define AURA_REMOVE_PROC_EX_MASK \
(PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE) (PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE)
+12 -18
View File
@@ -1043,7 +1043,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
return; return;
} }
if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()) if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && IsControlledByPlayer())
if (Unit * owner = GetOwner()) if (Unit * owner = GetOwner())
originalCaster=owner->GetGUID(); originalCaster=owner->GetGUID();
@@ -4233,7 +4233,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
// Remove totem at next update if totem looses its aura // Remove totem at next update if totem looses its aura
if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID()==Aur->GetCasterGUID()) if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID()==Aur->GetCasterGUID())
{ {
if (((Totem*)this)->GetSpell()==Aur->GetId()) if (((Totem*)this)->GetSpell()==Aur->GetId() && ((Totem*)this)->GetTotemType()==TOTEM_PASSIVE)
((Totem*)this)->setDeathState(JUST_DIED); ((Totem*)this)->setDeathState(JUST_DIED);
} }
@@ -5568,7 +5568,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{ {
if(!pVictim || !pVictim->isAlive()) if(!pVictim || !pVictim->isAlive())
return false; return false;
pVictim->CastSpell(pVictim, 60946,true); pVictim->CastSpell(pVictim, 60946,true, castItem, triggeredByAura);
return true; return true;
} }
// Improved Fear (Rank 2) // Improved Fear (Rank 2)
@@ -5576,7 +5576,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{ {
if(!pVictim || !pVictim->isAlive()) if(!pVictim || !pVictim->isAlive())
return false; return false;
pVictim->CastSpell(pVictim, 60947,true); pVictim->CastSpell(pVictim, 60947,true, castItem, triggeredByAura);
return true; return true;
} }
// Shadowflame (Voidheart Raiment set bonus) // Shadowflame (Voidheart Raiment set bonus)
@@ -5708,7 +5708,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{ {
if(!pVictim || !pVictim->isAlive()) if(!pVictim || !pVictim->isAlive())
return false; return false;
pVictim->CastSpell(pVictim, 59980,true); pVictim->CastSpell(pVictim, 59980,true, castItem, triggeredByAura);
return true; return true;
} }
// Psychic Horror (Rank 2) // Psychic Horror (Rank 2)
@@ -5716,7 +5716,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{ {
if(!pVictim || !pVictim->isAlive()) if(!pVictim || !pVictim->isAlive())
return false; return false;
pVictim->CastSpell(pVictim, 59981,true); pVictim->CastSpell(pVictim, 59981,true, castItem, triggeredByAura);
return true; return true;
} }
// Glyph of Dispel Magic // Glyph of Dispel Magic
@@ -6035,7 +6035,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
target = this; target = this;
triggered_spell_id = 31930; triggered_spell_id = 31930;
// replenishment // replenishment
CastSpell(this,57669,true); CastSpell(this,57669,true, castItem, triggeredByAura);
break; break;
} }
// Sanctified Wrath // Sanctified Wrath
@@ -6866,8 +6866,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// Set trigger spell id, target, custom basepoints // Set trigger spell id, target, custom basepoints
uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
if(procSpell && procSpell->Id == trigger_spell_id)
return false;
Unit* target = NULL; Unit* target = NULL;
int32 basepoints0 = 0; int32 basepoints0 = 0;
@@ -8499,8 +8497,6 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
if(Unit* magnet = (*itr)->IsAreaAura() ? ((AreaAuraEffect*)(*itr))->GetFormalCaster():(*itr)->GetCaster() ) if(Unit* magnet = (*itr)->IsAreaAura() ? ((AreaAuraEffect*)(*itr))->GetFormalCaster():(*itr)->GetCaster() )
if(magnet->isAlive()) if(magnet->isAlive())
{ {
if (Aura * aur = magnet->GetAura((*itr)->GetId(),(*itr)->GetCasterGUID()))
aur->DropAuraCharge();
return magnet; return magnet;
} }
} }
@@ -11990,7 +11986,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr) for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr)
{ {
ProcTriggeredData triggerData(itr->second); ProcTriggeredData triggerData(itr->second);
if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent)) if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent))
continue; continue;
for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i) for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i)
@@ -12004,6 +11999,10 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL) if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL)
continue; continue;
triggerData.effMask |= 1<<i; triggerData.effMask |= 1<<i;
if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC))
itr->second->SetCanProc(false);
else
itr->second->SetCanProc(true);
} }
} }
if (triggerData.effMask) if (triggerData.effMask)
@@ -12818,11 +12817,6 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
if (!EventProcFlag) if (!EventProcFlag)
return false; return false;
// Do not proc spells for totem if aura does not require family to proc
if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->IsControlledByPlayer())
if (!spellProcEvent || !spellProcEvent->spellFamilyName)
return false;
// Additional checks for triggered spells // Additional checks for triggered spells
if (procExtra & PROC_EX_INTERNAL_TRIGGERED) if (procExtra & PROC_EX_INTERNAL_TRIGGERED)
{ {
@@ -13013,7 +13007,7 @@ void Unit::SetToNotify()
void Unit::Kill(Unit *pVictim, bool durabilityLoss) void Unit::Kill(Unit *pVictim, bool durabilityLoss)
{ {
// Prevent killing unit twice (and giving reward from kill twice) // Prevent killing unit twice (and giving reward from kill twice)
if (!pVictim->isAlive()) if (!pVictim->GetHealth())
return; return;
pVictim->SetHealth(0); pVictim->SetHealth(0);
+1
View File
@@ -1659,6 +1659,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void _DeleteAuras(); void _DeleteAuras();
void _UpdateAutoRepeatSpell(); void _UpdateAutoRepeatSpell();
bool m_AutoRepeatFirstCast; bool m_AutoRepeatFirstCast;
uint32 m_attackTimer[MAX_ATTACK]; uint32 m_attackTimer[MAX_ATTACK];