--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-17 16:40:40 -05:00
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'),
( 40616, 41625, 1, 'Fel Rage Aura'),
( 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
( 44869, 44866, 1, 'Spectral Blast Portal'),
# (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),
(31569, 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),
(31801, 0, 0, 0, 0, 0, 0, 0, 20, 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),
(33757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3),
(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),
(33882, 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)
{
if(AISpellInfo[*i].condition == AICOND_AGGRO)
me->CastSpell(who, *i, true);
me->CastSpell(who, *i, false);
else if(AISpellInfo[*i].condition == AICOND_COMBAT)
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_delayAtDamageCount = 0;
m_canTrigger=true;
m_applyMultiplierMask = 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:
// an spell trigger another or not ( m_canTrigger )
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
// can spell trigger another or not ( m_canTrigger )
// 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
switch (m_spellInfo->DmgClass)
{
@@ -973,15 +999,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Fill base trigger info
uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim;
uint32 procEx = m_triggeredByAuraSpell
&& !(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;
uint32 procEx = m_procEx;
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
// 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;
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
prepareDataForTriggerSystem();
prepareDataForTriggerSystem(triggeredByAura);
// Set combo point requirement
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; }
void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; }
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; }
void SetDelayStart(uint64 m_time) { m_delayStart = m_time; }
uint64 GetDelayMoment() const { return m_delayMoment; }
@@ -552,7 +552,9 @@ class Spell
//******************************************
uint32 m_procAttacker; // Attacker trigger flags
uint32 m_procVictim; // Victim trigger flags
void prepareDataForTriggerSystem();
uint32 m_procEx;
bool m_canTrigger;
void prepareDataForTriggerSystem(AuraEffect * triggeredByAura);
//*****************************************
// 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) :
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_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);
@@ -613,6 +613,8 @@ Unit* AreaAuraEffect::GetFormalCaster() const
void Aura::Update(uint32 diff)
{
// Reset can proc requirement-prevent use of outdated value
m_canProc = true;
if (m_duration > 0)
{
m_duration -= diff;
@@ -1837,7 +1839,7 @@ void AuraEffect::TriggerSpell()
// Doom
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);
return;
}
@@ -1867,9 +1869,9 @@ void AuraEffect::TriggerSpell()
{
// cast 24 spells 34269-34289, 34314-34316
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)
caster->CastSpell(m_target,spell_id,true);
caster->CastSpell(m_target,spell_id,true, NULL, this);
return;
}
// // Gravity Lapse
@@ -1951,7 +1953,7 @@ void AuraEffect::TriggerSpell()
// Eye of Grillok
case 38495:
{
m_target->CastSpell(m_target, 38530, true);
m_target->CastSpell(m_target, 38530, true, NULL, this);
return;
}
// Absorb Eye of Grillok (Zezzak's Shard)
@@ -1960,7 +1962,7 @@ void AuraEffect::TriggerSpell()
if(m_target->GetTypeId() != TYPEID_UNIT)
return;
caster->CastSpell(caster, 38495, true);
caster->CastSpell(caster, 38495, true, NULL, this);
Creature* creatureTarget = (Creature*)m_target;
@@ -2198,7 +2200,7 @@ void AuraEffect::TriggerSpell()
}
if(all)
caster->CastSpell(caster,38437,true);
caster->CastSpell(caster,38437,true, NULL, this);
else
caster->RemoveAurasDueToSpell(38437);
return;
@@ -2278,7 +2280,7 @@ void AuraEffect::TriggerSpell()
// Curse of the Plaguebringer (22/15)
case 29213:
case 54835:
caster->CastSpell(m_target, trigger_spell_id, true);
caster->CastSpell(m_target, trigger_spell_id, true, NULL, this);
return;
}
}
@@ -4244,10 +4246,10 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real, bool /*changeA
{
if(apply)
{
m_target->CastSpell(m_target,24395,true);
m_target->CastSpell(m_target,24396,true);
m_target->CastSpell(m_target,24397,true);
m_target->CastSpell(m_target,26592,true);
m_target->CastSpell(m_target,24395,true, NULL, this);
m_target->CastSpell(m_target,24396,true, NULL, this);
m_target->CastSpell(m_target,24397,true, NULL, this);
m_target->CastSpell(m_target,26592,true, NULL, this);
}
else
{
+6 -1
View File
@@ -107,6 +107,8 @@ class TRINITY_DLL_SPEC Aura
bool IsRemoved() const { return m_isRemoved; }
void SetUpdated(bool val) { m_updated = val; }
bool CanProc(){return m_canProc;}
void SetCanProc(bool val){ m_canProc = val; }
bool IsPersistent() const;
bool IsAreaAura() 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_auraLevel; // Aura level (store caster level for correct show level dep amount)
uint8 m_procCharges; // Aura charges (0 for infinite)
uint32 m_procDamage; // used in aura proc code
uint8 m_stackAmount; // Aura stack amount
uint32 m_auraStateMask;
AuraEffect * m_partAuras[3];
uint32 m_procDamage; // used in aura proc code
bool m_canProc:1;
bool m_isDeathPersist:1;
bool m_isRemovedOnShapeLost: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();
Unit* GetFormalCaster() const;
uint64 const& GetFormalCasterGUID() const { return m_formalCasterGUID; }
void Update(uint32 diff);
private:
float m_radius;
+9
View File
@@ -1222,6 +1222,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
if((procFlags & EventProcFlag) == 0)
return false;
bool hasFamilyMask = false;
/* Check Periodic Auras
* 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)
return false;
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
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_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_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_HOT = 0x2000000, // 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 \
(PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE)
+12 -18
View File
@@ -1046,7 +1046,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
return;
}
if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem())
if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && IsControlledByPlayer())
if (Unit * owner = GetOwner())
originalCaster=owner->GetGUID();
@@ -4236,7 +4236,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
// Remove totem at next update if totem looses its aura
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);
}
@@ -5571,7 +5571,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
if(!pVictim || !pVictim->isAlive())
return false;
pVictim->CastSpell(pVictim, 60946,true);
pVictim->CastSpell(pVictim, 60946,true, castItem, triggeredByAura);
return true;
}
// Improved Fear (Rank 2)
@@ -5579,7 +5579,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
if(!pVictim || !pVictim->isAlive())
return false;
pVictim->CastSpell(pVictim, 60947,true);
pVictim->CastSpell(pVictim, 60947,true, castItem, triggeredByAura);
return true;
}
// Shadowflame (Voidheart Raiment set bonus)
@@ -5711,7 +5711,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
if(!pVictim || !pVictim->isAlive())
return false;
pVictim->CastSpell(pVictim, 59980,true);
pVictim->CastSpell(pVictim, 59980,true, castItem, triggeredByAura);
return true;
}
// Psychic Horror (Rank 2)
@@ -5719,7 +5719,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
if(!pVictim || !pVictim->isAlive())
return false;
pVictim->CastSpell(pVictim, 59981,true);
pVictim->CastSpell(pVictim, 59981,true, castItem, triggeredByAura);
return true;
}
// Glyph of Dispel Magic
@@ -6038,7 +6038,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
target = this;
triggered_spell_id = 31930;
// replenishment
CastSpell(this,57669,true);
CastSpell(this,57669,true, castItem, triggeredByAura);
break;
}
// Sanctified Wrath
@@ -6869,8 +6869,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// Set trigger spell id, target, custom basepoints
uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
if(procSpell && procSpell->Id == trigger_spell_id)
return false;
Unit* target = NULL;
int32 basepoints0 = 0;
@@ -8502,8 +8500,6 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
if(Unit* magnet = (*itr)->IsAreaAura() ? ((AreaAuraEffect*)(*itr))->GetFormalCaster():(*itr)->GetCaster() )
if(magnet->isAlive())
{
if (Aura * aur = magnet->GetAura((*itr)->GetId(),(*itr)->GetCasterGUID()))
aur->DropAuraCharge();
return magnet;
}
}
@@ -12003,7 +11999,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr)
{
ProcTriggeredData triggerData(itr->second);
if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent))
continue;
for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i)
@@ -12017,6 +12012,10 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL)
continue;
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)
@@ -12832,11 +12831,6 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
if (!EventProcFlag)
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
if (procExtra & PROC_EX_INTERNAL_TRIGGERED)
{
@@ -13027,7 +13021,7 @@ void Unit::SetToNotify()
void Unit::Kill(Unit *pVictim, bool durabilityLoss)
{
// Prevent killing unit twice (and giving reward from kill twice)
if (!pVictim->isAlive())
if (!pVictim->GetHealth())
return;
pVictim->SetHealth(0);
+1
View File
@@ -1659,6 +1659,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void _DeleteAuras();
void _UpdateAutoRepeatSpell();
bool m_AutoRepeatFirstCast;
uint32 m_attackTimer[MAX_ATTACK];