diff options
author | QAston <none@none> | 2009-06-06 08:27:36 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-06-06 08:27:36 +0200 |
commit | 39548d6822ce2a8cea49e4467f8329335aa0d85d (patch) | |
tree | ca1055ea31b1b8b994c693ab713626a3d00c405c /src/game | |
parent | 00582cf9d4bebbf812f2cccb14be8dce288c2f07 (diff) |
*Update spellmod system
*Implement SPELL_ATTR_EX6_IGNORE_CASTER_AURAS
*Fix some bugs with traps proc flags
--HG--
branch : trunk
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/DBCStructure.h | 2 | ||||
-rw-r--r-- | src/game/DBCfmt.h | 2 | ||||
-rw-r--r-- | src/game/Player.cpp | 105 | ||||
-rw-r--r-- | src/game/Player.h | 39 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 6 | ||||
-rw-r--r-- | src/game/Spell.cpp | 111 | ||||
-rw-r--r-- | src/game/Spell.h | 5 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 24 | ||||
-rw-r--r-- | src/game/SpellAuras.h | 2 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 4 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 2 | ||||
-rw-r--r-- | src/game/Unit.cpp | 8 | ||||
-rw-r--r-- | src/game/Unit.h | 2 |
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); } |