*Update spellmod system
*Implement SPELL_ATTR_EX6_IGNORE_CASTER_AURAS *Fix some bugs with traps proc flags --HG-- branch : trunk
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-1
@@ -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";
|
||||
|
||||
+65
-30
@@ -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->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)
|
||||
// Mod out of charges
|
||||
if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end())
|
||||
return false;
|
||||
}
|
||||
else if(mod->lastAffected != FindCurrentSpellBySpellId(spellInfo->Id))
|
||||
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,16 +17082,46 @@ 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
|
||||
// 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
|
||||
|
||||
+20
-19
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+76
-35
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
+22
-2
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
+1
-1
@@ -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); }
|
||||
|
||||
+6
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user