aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQAston <none@none>2009-06-06 08:27:36 +0200
committerQAston <none@none>2009-06-06 08:27:36 +0200
commit39548d6822ce2a8cea49e4467f8329335aa0d85d (patch)
treeca1055ea31b1b8b994c693ab713626a3d00c405c
parent00582cf9d4bebbf812f2cccb14be8dce288c2f07 (diff)
*Update spellmod system
*Implement SPELL_ATTR_EX6_IGNORE_CASTER_AURAS *Fix some bugs with traps proc flags --HG-- branch : trunk
-rw-r--r--src/game/DBCStructure.h2
-rw-r--r--src/game/DBCfmt.h2
-rw-r--r--src/game/Player.cpp105
-rw-r--r--src/game/Player.h39
-rw-r--r--src/game/SharedDefines.h6
-rw-r--r--src/game/Spell.cpp111
-rw-r--r--src/game/Spell.h5
-rw-r--r--src/game/SpellAuras.cpp24
-rw-r--r--src/game/SpellAuras.h2
-rw-r--r--src/game/SpellMgr.cpp4
-rw-r--r--src/game/SpellMgr.h2
-rw-r--r--src/game/Unit.cpp8
-rw-r--r--src/game/Unit.h2
13 files changed, 209 insertions, 103 deletions
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index c4e3d9e9578..e6ab168d852 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1326,7 +1326,7 @@ struct SpellEntry
uint32 AttributesEx3; // 7 m_attributesExC
uint32 AttributesEx4; // 8 m_attributesExD
uint32 AttributesEx5; // 9 m_attributesExE
- //uint32 AttributesEx6; // 10 m_attributesExF not used
+ uint32 AttributesEx6; // 10 m_attributesExF
uint32 Stances; // 11 m_shapeshiftMask
uint32 StancesNot; // 12 m_shapeshiftExclude
uint32 Targets; // 13 m_targets
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index 56f70d31a5d..e4bef193dd1 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -86,7 +86,7 @@ const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellCastTimefmt[]="nixx";
const char SpellDurationfmt[]="niii";
-const char SpellEntryfmt[]="niiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiix";
+const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiix";
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixx";
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 131d21910bf..f7b312fe465 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -275,7 +275,7 @@ std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi)
UpdateMask Player::updateVisualBits;
-Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
+Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this) , m_spellModTakingSpell(NULL)
{
m_speakTime = 0;
m_speakCount = 0;
@@ -320,8 +320,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
clearResurrectRequestData();
- m_SpellModRemoveCount = 0;
-
memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT);
m_social = NULL;
@@ -1134,6 +1132,10 @@ void Player::Update( uint32 p_time )
m_nextMailDelivereTime = 0;
}
+ // If this is set during update SetSpellModTakingSpell call is missing somewhere in the code
+ // Having this would prevent more aura charges to be dropped, so let's crash
+ assert (!m_spellModTakingSpell);
+
Unit::Update( p_time );
time_t now = time (NULL);
@@ -16983,22 +16985,14 @@ void Player::SendRemoveControlBar()
GetSession()->SendPacket(&data);
}
-bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)
+bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell * spell)
{
- if (!mod || !spellInfo)
- return false;
+ if (!mod || !spellInfo)
+ return false;
- if(mod->charges == -1 && mod->lastAffected ) // marked as expired but locked until spell casting finish
- {
- // prevent apply to any spell except spell that trigger expire
- if(spell)
- {
- if(mod->lastAffected != spell)
- return false;
- }
- else if(mod->lastAffected != FindCurrentSpellBySpellId(spellInfo->Id))
- return false;
- }
+ // Mod out of charges
+ if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end())
+ return false;
return spellmgr.IsAffectedByMod(spellInfo, mod);
}
@@ -17036,8 +17030,6 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
m_spellMods[mod->op].push_back(mod);
else
{
- if (mod->charges == -1)
- --m_SpellModRemoveCount;
m_spellMods[mod->op].remove(mod);
delete mod;
}
@@ -17046,7 +17038,7 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
// Restore spellmods in case of failed cast
void Player::RestoreSpellMods(Spell const* spell)
{
- if(!spell || (m_SpellModRemoveCount == 0))
+ if (!spell || spell->m_appliedMods.empty())
return;
for(int i=0;i<MAX_SPELLMOD;++i)
@@ -17055,21 +17047,34 @@ void Player::RestoreSpellMods(Spell const* spell)
{
SpellModifier *mod = *itr;
- if (mod && mod->charges == -1 && mod->lastAffected == spell)
- {
- mod->lastAffected = NULL;
+ // spellmods without aura set cannot be charged
+ if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges())
+ continue;
+
+ // check if mod affected this spell
+ Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura);
+ if (iterMod == spell->m_appliedMods.end())
+ continue;
+
+ // remove from list
+ spell->m_appliedMods.erase(iterMod);
+
+ // add mod charges back to mod
+ if (mod->charges == -1)
mod->charges = 1;
- m_SpellModRemoveCount--;
- }
+ else
+ mod->charges++;
+ assert (mod->ownerAura->GetAuraCharges() <=charges);
}
}
}
-void Player::RemoveSpellMods(Spell const* spell)
+void Player::RemoveSpellMods(Spell * spell)
{
- if(!spell || (m_SpellModRemoveCount == 0))
+ if (!spell || spell->m_appliedMods.empty())
return;
+ std::set <uint32> checkedSpells;
for(int i=0;i<MAX_SPELLMOD;++i)
{
for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();)
@@ -17077,18 +17082,48 @@ void Player::RemoveSpellMods(Spell const* spell)
SpellModifier *mod = *itr;
++itr;
- if (mod && mod->charges == -1 && (mod->lastAffected == spell || mod->lastAffected==NULL))
- {
- RemoveAurasDueToSpell(mod->spellId, 0, AURA_REMOVE_BY_EXPIRE);
- if (m_spellMods[i].empty())
- break;
- else
- itr = m_spellMods[i].begin();
- }
+ // spellmods without aura set cannot be charged
+ if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges())
+ continue;
+
+ // check if mod affected this spell
+ Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura);
+ if (iterMod == spell->m_appliedMods.end())
+ continue;
+
+ // remove from list
+ spell->m_appliedMods.erase(iterMod);
+
+ if (mod->ownerAura->DropAuraCharge())
+ itr = m_spellMods[i].begin();
+ }
+ }
+}
+
+void Player::DropModCharge(SpellModifier * mod, Spell * spell)
+{
+ if (spell && mod->ownerAura && mod->charges > 0 )
+ {
+ --mod->charges;
+ if (mod->charges == 0)
+ {
+ mod->charges = -1;
}
+ spell->m_appliedMods.insert(mod->ownerAura);
}
}
+void Player::SetSpellModTakingSpell(Spell * spell, bool apply)
+{
+ if (!spell || (m_spellModTakingSpell && m_spellModTakingSpell != spell))
+ return;
+
+ if (apply)
+ m_spellModTakingSpell = spell;
+ else
+ m_spellModTakingSpell = NULL;
+}
+
// send Proficiency
void Player::SendProficiency(uint8 pr1, uint32 pr2)
{
diff --git a/src/game/Player.h b/src/game/Player.h
index 79c5adc00c1..5e6a3af709e 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -97,7 +97,7 @@ struct PlayerSpell
// Spell modifier (used for modify other spells)
struct SpellModifier
{
- SpellModifier() : charges(0), lastAffected(NULL) {}
+ SpellModifier(Aura * _ownerAura = NULL) : charges(0), ownerAura(_ownerAura) {}
SpellModOp op : 8;
SpellModType type : 8;
int16 charges : 16;
@@ -1389,10 +1389,12 @@ class TRINITY_DLL_SPEC Player : public Unit
PlayerSpellMap & GetSpellMap() { return m_spells; }
void AddSpellMod(SpellModifier* mod, bool apply);
- bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
- template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
- void RemoveSpellMods(Spell const* spell);
- void RestoreSpellMods(Spell const* spell);
+ bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell * spell = NULL);
+ template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell * spell = NULL);
+ void RemoveSpellMods(Spell * spell);
+ void RestoreSpellMods(Spell * spell);
+ void DropModCharge(SpellModifier * mod, Spell * spell);
+ void SetSpellModTakingSpell(Spell* spell, bool apply);
bool HasSpellCooldown(uint32 spell_id) const
{
@@ -2200,7 +2202,8 @@ class TRINITY_DLL_SPEC Player : public Unit
uint16 m_baseManaRegen;
SpellModList m_spellMods[MAX_SPELLMOD];
- int32 m_SpellModRemoveCount;
+ Spell * m_spellModTakingSpell; // Spell for which charges are dropped in spell::finish
+
EnchantDurationList m_enchantDuration;
ItemDurationList m_itemDuration;
@@ -2328,16 +2331,25 @@ void AddItemsSetItem(Player*player,Item *item);
void RemoveItemsSetItem(Player*player,ItemPrototype const *proto);
// "the bodies of template functions must be made available in a header file"
-template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell)
+template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell * spell)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo) return 0;
int32 totalpct = 0;
int32 totalflat = 0;
+
+ // Drop charges for triggering spells instead of triggered ones
+ if (m_spellModTakingSpell)
+ spell = m_spellModTakingSpell;
+
for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr)
{
SpellModifier *mod = *itr;
+ // Charges can be set only for mods with auras
+ if (!mod->ownerAura)
+ assert(mod->charges==0);
+
if(!IsAffectedBySpellmod(spellInfo,mod,spell))
continue;
if (mod->type == SPELLMOD_FLAT)
@@ -2355,18 +2367,7 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas
totalpct += mod->value;
}
- if (mod->charges > 0 )
- {
- --mod->charges;
- if (mod->charges == 0)
- {
- mod->charges = -1;
- mod->lastAffected = spell;
- if(!mod->lastAffected)
- mod->lastAffected = FindCurrentSpellBySpellId(spellId);
- ++m_SpellModRemoveCount;
- }
- }
+ DropModCharge(mod, spell);
}
float diff = (float)basevalue*(float)totalpct/100.0f + (float)totalflat;
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 62d04b81646..44654fb1b0b 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -306,7 +306,7 @@ enum SpellCategory
#define SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT 0x00080000 // 19 does not necessarly need shapeshift
#define SPELL_ATTR_EX2_UNK20 0x00100000 // 20
#define SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD 0x00200000 // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure!
-#define SPELL_ATTR_EX2_UNK22 0x00400000 // 22 spell can trigger even if triggered
+#define SPELL_ATTR_EX2_UNK22 0x00400000 // 22
#define SPELL_ATTR_EX2_UNK23 0x00800000 // 23 Only mage Arcane Concentration have this flag
#define SPELL_ATTR_EX2_UNK24 0x01000000 // 24
#define SPELL_ATTR_EX2_UNK25 0x02000000 // 25
@@ -324,7 +324,7 @@ enum SpellCategory
#define SPELL_ATTR_EX3_UNK4 0x00000010 // 4 Druid Rebirth only this spell have this flag
#define SPELL_ATTR_EX3_UNK5 0x00000020 // 5
#define SPELL_ATTR_EX3_UNK6 0x00000040 // 6
-#define SPELL_ATTR_EX3_UNK7 0x00000080 // 7
+#define SPELL_ATTR_EX3_UNK7 0x00000080 // 7 separate stack for every caster
#define SPELL_ATTR_EX3_PLAYERS_ONLY 0x00000100 // 8 Player only?
#define SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2 0x00000200 // 9 triggered from effect?
#define SPELL_ATTR_EX3_MAIN_HAND 0x00000400 // 10 Main hand weapon required
@@ -418,7 +418,7 @@ enum SpellCategory
#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag
#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3
-#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2
+#define SPELL_ATTR_EX6_IGNORE_CASTER_AURAS 0x00000004 // 2
#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3
#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4
#define SPELL_ATTR_EX6_UNK5 0x00000020 // 5
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index a7e7212f9e9..f7fb0137c78 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -733,32 +733,6 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
// 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()->GetTarget()->CanProc())
- {
- m_canTrigger=false;
- }
-
- m_procEx = (m_IsTriggeredSpell)
- && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER)
- && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2)
- ? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE;
-
- if (m_IsTriggeredSpell &&
- (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER ||
- m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2))
- 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)
{
@@ -797,10 +771,36 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
}
break;
}
+ m_procEx= PROC_EX_NONE;
+
// 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[1] & 0x00002000 || m_spellInfo->SpellFamilyFlags[0] & 0x1C))
- m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION;
+ {
+ m_procAttacker = PROC_FLAG_ON_TRAP_ACTIVATION;
+ }
+ else
+ {
+ /*
+ Effects which are result of aura proc from triggered spell cannot proc
+ to prevent chain proc of these spells
+ */
+ if (triggeredByAura && !triggeredByAura->GetParentAura()->GetTarget()->CanProc())
+ {
+ m_canTrigger=false;
+ }
+
+ if (m_IsTriggeredSpell &&
+ (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER ||
+ m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2))
+ m_procEx |= PROC_EX_INTERNAL_CANT_PROC | PROC_EX_INTERNAL_TRIGGERED;
+
+ // 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;
+ }
+ }
}
void Spell::CleanupTargetList()
@@ -2514,6 +2514,12 @@ void Spell::cancel()
SendChannelUpdate(0);
SendInterrupted(0);
SendCastResult(SPELL_FAILED_INTERRUPTED);
+
+ // spell is canceled-take mods and clear list
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_caster)->RemoveSpellMods(this);
+
+ m_appliedMods.clear();
} break;
default:
@@ -2548,6 +2554,12 @@ void Spell::cast(bool skipCheck)
if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster)
m_caster->SetInFront(m_targets.getUnitTarget());
+ // Should this be done for original caster?
+ if (m_caster->GetTypeId()==TYPEID_PLAYER)
+ {
+ // Set spell which will drop charges for triggered cast spells
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, true);
+ }
// triggered cast called from Spell::prepare where it was already checked
if(!m_IsTriggeredSpell || !skipCheck)
@@ -2673,6 +2685,9 @@ void Spell::cast(bool skipCheck)
m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true);
}
+ if (m_caster->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, false);
+
SetExecutedCurrently(false);
}
@@ -2717,6 +2732,10 @@ void Spell::handle_immediate()
uint64 Spell::handle_delayed(uint64 t_offset)
{
UpdatePointers();
+
+ if (m_caster->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, true);
+
uint64 next_time = 0;
if (!m_immediateHandled)
@@ -2750,6 +2769,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
next_time = ighit->timeDelay;
}
}
+
// All targets passed - need finish phase
if (next_time == 0)
{
@@ -2763,6 +2783,9 @@ uint64 Spell::handle_delayed(uint64 t_offset)
}
else
{
+ if (m_caster->GetTypeId()==TYPEID_PLAYER)
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, false);
+
// spell is unfinished, return next execution time
return next_time;
}
@@ -2996,7 +3019,12 @@ void Spell::finish(bool ok)
{
//restore spell mods
if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
((Player*)m_caster)->RestoreSpellMods(this);
+ // cleanup after mod system
+ // triggered spell pointer can be not removed in some cases
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, false);
+ }
return;
}
@@ -3013,10 +3041,6 @@ void Spell::finish(bool ok)
}
}
- //remove spell mods
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_caster)->RemoveSpellMods(this);
-
// Okay to remove extra attacks
if(IsSpellHaveEffect(m_spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS))
m_caster->m_extraAttacks = 0;
@@ -3036,13 +3060,27 @@ void Spell::finish(bool ok)
// potions disabled by client, send event "not in combat" if need
if (!m_triggeredByAuraSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
((Player*)m_caster)->UpdatePotionCooldown(this);
+ // triggered spell pointer can be not set in some cases
+ // this is needed for proper apply of triggered spell mods
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, true);
+ }
+
// call triggered spell only at successful cast (after clear combo points -> for add some if need)
// I assume what he means is that some triggered spells may add combo points
if(!m_TriggerSpells.empty())
TriggerSpell();
+ // Take mods after trigger spell (needed for 14177 to affect 48664)
+ // mods are taken only on succesfull cast and independantly from targets of the spell
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)m_caster)->RemoveSpellMods(this);
+ ((Player*)m_caster)->SetSpellModTakingSpell(this, false);
+ }
+
// Stop Attack for some spells
if( m_spellInfo->Attributes & SPELL_ATTR_STOP_ATTACK_TARGET )
m_caster->AttackStop();
@@ -4797,10 +4835,8 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
SpellCastResult Spell::CheckCasterAuras() const
{
- // Flag drop spells totally immuned to caster auras
- // FIXME: find more nice check for all totally immuned spells
- // AttributesEx3 & 0x10000000?
- if(m_spellInfo->Id == 23336 || m_spellInfo->Id == 23334 || m_spellInfo->Id == 34991)
+ // spells totally immuned to caster auras ( wsg flag drop, give marks etc
+ if(m_spellInfo->AttributesEx6& SPELL_ATTR_EX6_IGNORE_CASTER_AURAS)
return SPELL_CAST_OK;
uint8 school_immune = 0;
@@ -5863,8 +5899,13 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time)
}
else
{
+ // Set last not triggered spell for apply spellmods
+ ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, true);
// do the action (pass spell to channeling state)
m_Spell->handle_immediate();
+
+ // And remove after effect handling
+ ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, false);
}
// event will be re-added automatically at the end of routine)
}
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 7d9163f4a0b..5edb414e6ec 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -366,6 +366,8 @@ class Spell
void EffectTitanGrip(uint32 i);
void EffectEnchantItemPrismatic(uint32 i);
+ typedef std::set<Aura *> UsedSpellMods;
+
Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL, bool skipCheck = false );
~Spell();
@@ -445,6 +447,8 @@ class Spell
uint32 m_preCastSpell;
SpellCastTargets m_targets;
+ UsedSpellMods m_appliedMods;
+
int32 GetCastTime() const { return m_casttime; }
bool IsAutoRepeat() const { return m_autoRepeat; }
void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
@@ -453,6 +457,7 @@ class Spell
{
return m_spellInfo->Attributes & SPELL_ATTR_ON_NEXT_SWING;
}
+ bool IsTriggered() const {return m_IsTriggeredSpell;};
bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; }
bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); }
bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && /*IsRangedSpell() &&*/ !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT); }
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 0d4606e6e84..dae7436e599 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -623,6 +623,8 @@ Unit* AuraEffect::GetSource() const
void Aura::Update(uint32 diff)
{
+ // TODO: store pointer to caster in aura class for update/mod handling code
+
if (m_duration > 0)
{
m_duration -= diff;
@@ -666,9 +668,23 @@ void Aura::Update(uint32 diff)
}
}
+ // Apply charged spellmods for channeled auras
+ // used for example when triggered spell of spell:10 is modded
+ Spell * modSpell = NULL;
+ Unit* caster = NULL;
+ if (IS_PLAYER_GUID(GetCasterGUID())
+ {
+ caster = GetCaster();
+ modSpell = ((Player*)caster)->FindCurrentSpellBySpellId(GetId());
+ if (caster)
+ ((Player*)caster)->SetSpellModTakingSpell(modSpell, true);
+ }
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_partAuras[i])
m_partAuras[i]->Update(diff);
+
+ if (caster)
+ ((Player*)caster)->SetSpellModTakingSpell(modSpell, false);
}
void AuraEffect::Update(uint32 diff)
@@ -1295,15 +1311,19 @@ void Aura::SetAuraCharges(uint8 charges)
SendAuraUpdate();
}
-void Aura::DropAuraCharge()
+bool Aura::DropAuraCharge()
{
if(m_procCharges) //auras without charges always have charge = 0
{
if(--m_procCharges) // Send charge change
SendAuraUpdate();
else // Last charge dropped
+ {
m_target->RemoveAura(this, AURA_REMOVE_BY_EXPIRE);
+ return true;
+ }
}
+ return false;
}
bool Aura::IsPersistent() const
@@ -1533,7 +1553,7 @@ void AuraEffect::HandleAddModifier(bool apply, bool Real, bool changeAmount)
if (apply)
{
- SpellModifier *mod = new SpellModifier;
+ SpellModifier *mod = new SpellModifier(GetParentAura());
mod->op = SpellModOp(modOp);
mod->value = m_amount;
mod->type = SpellModType(m_auraName); // SpellModType value == spell aura types
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 579794e3da2..ed6bb37fe2a 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -77,7 +77,7 @@ class TRINITY_DLL_SPEC Aura
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
uint8 GetAuraCharges() const { return m_procCharges; }
void SetAuraCharges(uint8 charges);
- void DropAuraCharge();
+ bool DropAuraCharge();
void SetProcDamage(uint32 val) { m_procDamage = val; }
uint32 GetProcDamage() const { return m_procDamage; }
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 99c113a5eb5..bed5ffc4d89 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -279,7 +279,7 @@ bool GetDispelChance(Unit* caster, uint32 spellId)
return !roll_chance_i(miss_chance);
}
-uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
+uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell * spell)
{
SpellCastTimesEntry const *spellCastTimeEntry = sSpellCastTimesStore.LookupEntry(spellInfo->CastingTimeIndex);
@@ -1309,7 +1309,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
}
// Always trigger for this
- if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
+ if (procFlags & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
return true;
if (spellProcEvent) // Exist event data
{
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 13973e25120..fcb3bea8294 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -158,7 +158,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId);
// Different spell properties
inline float GetSpellRadiusForHostile(SpellRadiusEntry const *radius) { return (radius ? radius->radiusHostile : 0); }
inline float GetSpellRadiusForFriend(SpellRadiusEntry const *radius) { return (radius ? radius->radiusFriend : 0); }
-uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
+uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell * spell = NULL);
bool GetDispelChance(Unit* caster, uint32 spellId);
inline float GetSpellMinRangeForHostile(SpellRangeEntry const *range) { return (range ? range->minRangeHostile : 0); }
inline float GetSpellMaxRangeForHostile(SpellRangeEntry const *range) { return (range ? range->maxRangeHostile : 0); }
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 914842ffab8..e6caa000532 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -7568,7 +7568,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
case 56453:
{
// Proc only from trap activation (from periodic proc another aura of this spell)
- if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount))
+ if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION))
return false;
break;
}
@@ -11065,7 +11065,7 @@ int32 Unit::ModSpellDuration(SpellEntry const* spellProto, Unit const* target, i
return duration>0 ? duration : 0;
}
-void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell)
+void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell * spell)
{
if (!spellProto || castTime<0)
return;
@@ -12359,6 +12359,10 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID())
continue;
break;
+ /*case SPELL_AURA_ADD_FLAT_MODIFIER:
+ case SPELL_AURA_ADD_PCT_MODIFIER:
+ // HandleSpellModAuraProc
+ break;*/
default:
// nothing do, just charges counter
break;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index ea934356842..febb4040213 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1643,7 +1643,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target);
int32 CalcSpellDuration(SpellEntry const* spellProto);
int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive);
- void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell const * spell=NULL);
+ void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell * spell=NULL);
float CalculateLevelPenalty(SpellEntry const* spellProto) const;
void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }