mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-17 05:19:40 -04:00
Core/Auras:
- Use safer order of calls in AuraEffect handlers (unit modification goes before any calls which may result in linked events execution) - Allow manual removal of further effects of an aura during aura removal (so Unit::RemoveAurasByType works well in such situations)
This commit is contained in:
@@ -3277,6 +3277,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
|
||||
ASSERT(aurApp);
|
||||
ASSERT(!aurApp->GetRemoveMode());
|
||||
ASSERT(aurApp->GetTarget() == this);
|
||||
|
||||
aurApp->SetRemoveMode(removeMode);
|
||||
Aura * aura = aurApp->GetBase();
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Aura %u now is remove mode %d", aura->GetId(), removeMode);
|
||||
@@ -3573,9 +3574,22 @@ void Unit::RemoveAura(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemov
|
||||
|
||||
void Unit::RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode)
|
||||
{
|
||||
ASSERT(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
|
||||
// we've special situation here, RemoveAura called while during aura removal
|
||||
// this kind of call is needed only when aura effect removal handler
|
||||
// or event triggered by it expects to remove
|
||||
// not yet removed effects of an aura
|
||||
if(aurApp->GetRemoveMode())
|
||||
{
|
||||
// remove remaining effects of an aura
|
||||
for (uint8 itr = 0 ; itr < MAX_SPELL_EFFECTS; ++itr)
|
||||
{
|
||||
if (aurApp->HasEffect(itr))
|
||||
aurApp->_HandleEffect(itr, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// no need to remove
|
||||
if (aurApp->GetRemoveMode() || aurApp->GetBase()->IsRemoved())
|
||||
if (aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) != aurApp || aurApp->GetBase()->IsRemoved())
|
||||
return;
|
||||
uint32 spellId = aurApp->GetBase()->GetId();
|
||||
for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
|
||||
@@ -3596,8 +3610,6 @@ void Unit::RemoveAura(Aura * aura, AuraRemoveMode mode)
|
||||
return;
|
||||
if (AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID()))
|
||||
RemoveAura(aurApp, mode);
|
||||
else
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode)
|
||||
@@ -11909,27 +11921,14 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * s
|
||||
|
||||
void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
|
||||
|
||||
if (mount)
|
||||
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount);
|
||||
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT);
|
||||
|
||||
// unsummon pet
|
||||
if (Player* plr = ToPlayer())
|
||||
{
|
||||
Pet* pet = plr->GetPet();
|
||||
if (pet)
|
||||
{
|
||||
Battleground *bg = ToPlayer()->GetBattleground();
|
||||
// don't unsummon pet in arena but SetFlag UNIT_FLAG_STUNNED to disable pet's interface
|
||||
if (bg && bg->isArena())
|
||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
else
|
||||
plr->UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
// mount as a vehicle
|
||||
if (VehicleId)
|
||||
{
|
||||
if (CreateVehicleKit(VehicleId, creatureEntry))
|
||||
@@ -11949,8 +11948,21 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
GetVehicleKit()->InstallAllAccessories(false);
|
||||
}
|
||||
}
|
||||
|
||||
// unsummon pet
|
||||
Pet* pet = plr->GetPet();
|
||||
if (pet)
|
||||
{
|
||||
Battleground *bg = ToPlayer()->GetBattleground();
|
||||
// don't unsummon pet in arena but SetFlag UNIT_FLAG_STUNNED to disable pet's interface
|
||||
if (bg && bg->isArena())
|
||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
else
|
||||
plr->UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
}
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
|
||||
}
|
||||
|
||||
void Unit::Unmount()
|
||||
@@ -11958,8 +11970,6 @@ void Unit::Unmount()
|
||||
if (!IsMounted())
|
||||
return;
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_MOUNTED);
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT);
|
||||
|
||||
@@ -11967,6 +11977,20 @@ void Unit::Unmount()
|
||||
data.appendPackGUID(GetGUID());
|
||||
SendMessageToSet(&data, true);
|
||||
|
||||
// unmount as a vehicle
|
||||
if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
|
||||
{
|
||||
// Send other players that we are no longer a vehicle
|
||||
WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
|
||||
data.appendPackGUID(GetGUID());
|
||||
data << uint32(0);
|
||||
this->ToPlayer()->SendMessageToSet(&data, true);
|
||||
// Remove vehicle from player
|
||||
RemoveVehicleKit();
|
||||
}
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_MOUNTED);
|
||||
|
||||
// only resummon old pet if the player is already added to a map
|
||||
// this prevents adding a pet to a not created map which would otherwise cause a crash
|
||||
// (it could probably happen when logging in after a previous crash)
|
||||
@@ -11980,16 +12004,6 @@ void Unit::Unmount()
|
||||
else
|
||||
this->ToPlayer()->ResummonPetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
|
||||
{
|
||||
// Send other players that we are no longer a vehicle
|
||||
WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, 8+4);
|
||||
data.appendPackGUID(GetGUID());
|
||||
data << uint32(0);
|
||||
this->ToPlayer()->SendMessageToSet(&data, true);
|
||||
// Remove vehicle class from player
|
||||
RemoveVehicleKit();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::SetInCombatWith(Unit* enemy)
|
||||
@@ -15522,7 +15536,7 @@ void Unit::SetStunned(bool apply)
|
||||
{
|
||||
SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
CastStop();
|
||||
|
||||
// AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
||||
|
||||
// Creature specific
|
||||
@@ -15535,6 +15549,8 @@ void Unit::SetStunned(bool apply)
|
||||
data.append(GetPackGUID());
|
||||
data << uint32(0);
|
||||
SendMessageToSet(&data, true);
|
||||
|
||||
CastStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2766,6 +2766,7 @@ void AuraEffect::HandleModInvisibilityDetect(AuraApplication const * aurApp, uin
|
||||
target->m_invisibilityDetect.AddValue(type, -GetAmount());
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -2779,12 +2780,6 @@ void AuraEffect::HandleModInvisibility(AuraApplication const * aurApp, uint8 mod
|
||||
|
||||
if (apply)
|
||||
{
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
// drop flag at invisibiliy in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
|
||||
// apply glow vision
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
|
||||
@@ -2822,6 +2817,12 @@ void AuraEffect::HandleModInvisibility(AuraApplication const * aurApp, uint8 mod
|
||||
target->m_invisibility.AddValue(type, -GetAmount());
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
if (apply && (mode & AURA_EFFECT_HANDLE_REAL))
|
||||
{
|
||||
// drop flag at invisibiliy in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -2846,6 +2847,7 @@ void AuraEffect::HandleModStealthDetect(AuraApplication const * aurApp, uint8 mo
|
||||
target->m_stealthDetect.AddValue(type, -GetAmount());
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -2859,16 +2861,6 @@ void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bo
|
||||
|
||||
if (apply)
|
||||
{
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
// drop flag at stealth in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
target->m_stealth.AddFlag( type);
|
||||
target->m_stealth.AddValue(type, GetAmount());
|
||||
|
||||
@@ -2890,6 +2882,12 @@ void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bo
|
||||
}
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
if (apply && (mode & AURA_EFFECT_HANDLE_REAL))
|
||||
{
|
||||
// drop flag at stealth in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -2906,6 +2904,7 @@ void AuraEffect::HandleModStealthLevel(AuraApplication const * aurApp, uint8 mod
|
||||
else
|
||||
target->m_stealth.AddValue(type, -GetAmount());
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -2936,6 +2935,7 @@ void AuraEffect::HandleSpiritOfRedemption(AuraApplication const * aurApp, uint8
|
||||
}
|
||||
// die at aura end
|
||||
else if (target->isAlive())
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->setDeathState(JUST_DIED);
|
||||
}
|
||||
|
||||
@@ -2980,21 +2980,11 @@ void AuraEffect::HandlePhase(AuraApplication const * aurApp, uint8 mode, bool ap
|
||||
for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
newPhase |= (*itr)->GetMiscValue();
|
||||
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
if (Player* player = target->ToPlayer())
|
||||
{
|
||||
if (!newPhase)
|
||||
newPhase = PHASEMASK_NORMAL;
|
||||
|
||||
// drop flag at invisible in bg
|
||||
if (player->InBattleground())
|
||||
if (Battleground *bg = player->GetBattleground())
|
||||
bg->EventPlayerDroppedFlag(player);
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
// GM-mode have mask 0xFFFFFFFF
|
||||
if (player->isGameMaster())
|
||||
newPhase = 0xFFFFFFFF;
|
||||
@@ -3015,6 +3005,14 @@ void AuraEffect::HandlePhase(AuraApplication const * aurApp, uint8 mode, bool ap
|
||||
target->SetPhaseMask(newPhase, false);
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
if (apply && (mode & AURA_EFFECT_HANDLE_REAL))
|
||||
{
|
||||
// drop flag at invisibiliy in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
|
||||
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
|
||||
if (target->IsVisible())
|
||||
target->UpdateObjectVisibility();
|
||||
@@ -3254,7 +3252,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 m
|
||||
{
|
||||
if (Item *pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
|
||||
{
|
||||
target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetTemplate(), NULL, apply);
|
||||
target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetTemplate(), NULL, apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3626,22 +3624,18 @@ void AuraEffect::HandleModUnattackable(AuraApplication const * aurApp, uint8 mod
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if (apply)
|
||||
{
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
target->CombatStop();
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (aurApp->GetRemoveMode())
|
||||
return;
|
||||
}
|
||||
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
|
||||
else if (target->HasAuraType(SPELL_AURA_MOD_UNATTACKABLE))
|
||||
if (!apply && target->HasAuraType(SPELL_AURA_MOD_UNATTACKABLE))
|
||||
return;
|
||||
|
||||
target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, apply);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
if (apply && (mode & AURA_EFFECT_HANDLE_REAL))
|
||||
{
|
||||
target->CombatStop();
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModDisarm(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -3715,6 +3709,8 @@ void AuraEffect::HandleAuraModSilence(AuraApplication const * aurApp, uint8 mode
|
||||
if (apply)
|
||||
{
|
||||
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
|
||||
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
|
||||
if (Spell* spell = target->GetCurrentSpell(CurrentSpellTypes(i)))
|
||||
@@ -3862,6 +3858,7 @@ void AuraEffect::HandleAuraModStalked(AuraApplication const * aurApp, uint8 mode
|
||||
target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
@@ -3993,7 +3990,7 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const * aurApp, uint8 mod
|
||||
|
||||
if (Player *plr = target->m_movedPlayer)
|
||||
{
|
||||
// allow fly
|
||||
// allow flying
|
||||
WorldPacket data;
|
||||
if (apply)
|
||||
data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
|
||||
@@ -4012,7 +4009,7 @@ void AuraEffect::HandleAuraWaterWalk(AuraApplication const * aurApp, uint8 mode,
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
{
|
||||
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
|
||||
if (target->HasAuraType(GetAuraType()))
|
||||
@@ -4036,7 +4033,7 @@ void AuraEffect::HandleAuraFeatherFall(AuraApplication const * aurApp, uint8 mod
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
{
|
||||
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
|
||||
if (target->HasAuraType(GetAuraType()))
|
||||
@@ -4064,7 +4061,7 @@ void AuraEffect::HandleAuraHover(AuraApplication const * aurApp, uint8 mode, boo
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
{
|
||||
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
|
||||
if (target->HasAuraType(GetAuraType()))
|
||||
@@ -4217,8 +4214,7 @@ void AuraEffect::HandlePreventFleeing(AuraApplication const * aurApp, uint8 mode
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
Unit::AuraEffectList const& fearAuras = target->GetAuraEffectsByType(SPELL_AURA_MOD_FEAR);
|
||||
if (!fearAuras.empty())
|
||||
if (target->HasAuraType(SPELL_AURA_MOD_FEAR))
|
||||
target->SetControlled(!(apply), UNIT_STAT_FLEEING);
|
||||
}
|
||||
|
||||
@@ -4234,6 +4230,8 @@ void AuraEffect::HandleModPossess(AuraApplication const * aurApp, uint8 mode, bo
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
Unit * caster = GetCaster();
|
||||
|
||||
// no support for posession AI yet
|
||||
if (caster && caster->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
HandleModCharm(aurApp, mode, apply);
|
||||
@@ -4354,10 +4352,9 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const * aurApp, uint8
|
||||
if (caster->GetTypeId() == TYPEID_UNIT)
|
||||
caster->ToCreature()->RemoveCorpse();
|
||||
}
|
||||
|
||||
caster->_ExitVehicle();
|
||||
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
|
||||
caster->RemoveAurasDueToSpell(GetId());
|
||||
caster->_ExitVehicle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4485,16 +4482,17 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const * aurApp, uint
|
||||
if (GetMiscValue() & (1<<9))
|
||||
immunity_list.push_back(SPELL_AURA_MOD_FEAR);
|
||||
|
||||
// must be last due to Bladestorm
|
||||
if (GetMiscValue() & (1<<7))
|
||||
// an exception for Bladestorm
|
||||
if ((GetMiscValue() & (1<<7)) && (GetId() != 46924))
|
||||
immunity_list.push_back(SPELL_AURA_MOD_DISARM);
|
||||
|
||||
// TODO: figure out a better place to put this...
|
||||
// apply immunities
|
||||
for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply);
|
||||
|
||||
// Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
|
||||
// however not all mechanic specified in immunity
|
||||
if (apply && GetId() == 46924)
|
||||
{
|
||||
immunity_list.pop_back(); // delete Disarm
|
||||
target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
|
||||
target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
|
||||
}
|
||||
@@ -4502,13 +4500,6 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const * aurApp, uint
|
||||
if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
|
||||
for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
|
||||
target->RemoveAurasByType(*iter);
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModMechanicImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -4567,8 +4558,10 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const * aurApp, uin
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, GetMiscValue(), apply);
|
||||
|
||||
// when removing flag aura, handle flag drop
|
||||
if (!(apply) && target->GetTypeId() == TYPEID_PLAYER
|
||||
if (!apply && target->GetTypeId() == TYPEID_PLAYER
|
||||
&& (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION))
|
||||
{
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -4582,11 +4575,6 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const * aurApp, uin
|
||||
sOutdoorPvPMgr->HandleDropFlag((Player*)target, GetSpellProto()->Id);
|
||||
}
|
||||
}
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, GetMiscValue(), apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModStateImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -4596,14 +4584,10 @@ void AuraEffect::HandleAuraModStateImmunity(AuraApplication const * aurApp, uint
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if ((apply) && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
|
||||
target->RemoveAurasByType(AuraType(GetMiscValue()), 0 , GetBase());
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_STATE, GetMiscValue(), apply);
|
||||
|
||||
if (apply && GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
|
||||
target->RemoveAurasByType(AuraType(GetMiscValue()), 0 , GetBase());
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -4613,15 +4597,30 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const * aurApp, uin
|
||||
|
||||
Unit * target = aurApp->GetTarget();
|
||||
|
||||
if ((apply) && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
target->ApplySpellImmune(GetId(), IMMUNITY_SCHOOL, GetMiscValue(), (apply));
|
||||
|
||||
if (GetSpellProto()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
if (apply)
|
||||
target->AddUnitState(UNIT_STAT_ISOLATED);
|
||||
else
|
||||
{
|
||||
bool banishFound = false;
|
||||
Unit::AuraEffectList const& banishAuras = target->GetAuraEffectsByType(GetAuraType());
|
||||
for (Unit::AuraEffectList::const_iterator i = banishAuras.begin(); i != banishAuras.end(); ++i)
|
||||
if ((*i)->GetSpellProto()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
banishFound = true;
|
||||
break;
|
||||
}
|
||||
if (!banishFound)
|
||||
target->ClearUnitState(UNIT_STAT_ISOLATED);
|
||||
}
|
||||
}
|
||||
|
||||
if (apply && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
|
||||
// remove all flag auras (they are positive, but they must be removed when you are immune)
|
||||
if (GetSpellProto()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY
|
||||
&& GetSpellProto()->AttributesEx2 & SPELL_ATTR2_DAMAGE_REDUCED_SHIELD)
|
||||
@@ -4648,29 +4647,6 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const * aurApp, uin
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
if (GetSpellProto()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
if (apply)
|
||||
target->AddUnitState(UNIT_STAT_ISOLATED);
|
||||
else
|
||||
{
|
||||
bool banishFound = false;
|
||||
Unit::AuraEffectList const& banishAuras = target->GetAuraEffectsByType(GetAuraType());
|
||||
for (Unit::AuraEffectList::const_iterator i = banishAuras.begin(); i != banishAuras.end(); ++i)
|
||||
if ((*i)->GetSpellProto()->Mechanic == MECHANIC_BANISH)
|
||||
{
|
||||
banishFound = true;
|
||||
break;
|
||||
}
|
||||
if (!banishFound)
|
||||
target->ClearUnitState(UNIT_STAT_ISOLATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModDmgImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -5763,6 +5739,18 @@ void AuraEffect::HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, boo
|
||||
|
||||
Unit * caster = GetCaster();
|
||||
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
// pet auras
|
||||
if (PetAura const* petSpell = sSpellMgr->GetPetAura(GetId(), m_effIndex))
|
||||
{
|
||||
if (apply)
|
||||
target->AddPetAura(petSpell);
|
||||
else
|
||||
target->RemovePetAura(petSpell);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
// AT APPLY
|
||||
@@ -6338,22 +6326,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, boo
|
||||
// break;
|
||||
break;
|
||||
}
|
||||
|
||||
// stop handling the effect if it was removed by linked event
|
||||
if (apply && aurApp->GetRemoveMode())
|
||||
return;
|
||||
|
||||
if (mode & AURA_EFFECT_HANDLE_REAL)
|
||||
{
|
||||
// pet auras
|
||||
if (PetAura const* petSpell = sSpellMgr->GetPetAura(GetId(), m_effIndex))
|
||||
{
|
||||
if (apply)
|
||||
target->AddPetAura(petSpell);
|
||||
else
|
||||
target->RemovePetAura(petSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleChannelDeathItem(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -6361,7 +6333,7 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const * aurApp, uint8 mo
|
||||
if (!(mode & AURA_EFFECT_HANDLE_REAL))
|
||||
return;
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
{
|
||||
Unit * caster = GetCaster();
|
||||
|
||||
@@ -6435,7 +6407,7 @@ void AuraEffect::HandleBindSight(AuraApplication const * aurApp, uint8 mode, boo
|
||||
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
caster->ToPlayer()->SetViewpoint(target, (apply));
|
||||
caster->ToPlayer()->SetViewpoint(target, apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleForceReaction(AuraApplication const * aurApp, uint8 mode, bool apply) const
|
||||
@@ -6471,7 +6443,7 @@ void AuraEffect::HandleAuraEmpathy(AuraApplication const * aurApp, uint8 mode, b
|
||||
if (target->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
if (!(apply))
|
||||
if (!apply)
|
||||
{
|
||||
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
|
||||
if (target->HasAuraType(GetAuraType()))
|
||||
@@ -6632,6 +6604,7 @@ void AuraEffect::HandleAuraModFakeInebriation(AuraApplication const * aurApp, ui
|
||||
target->m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK);
|
||||
}
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ class AuraApplication
|
||||
friend void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask);
|
||||
friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
|
||||
friend void Unit::_ApplyAuraEffect(Aura * aura, uint8 effIndex);
|
||||
friend void Unit::RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode);
|
||||
friend AuraApplication * Unit::_CreateAuraApplication(Aura * aura, uint8 effMask);
|
||||
private:
|
||||
Unit * const m_target;
|
||||
|
||||
@@ -460,13 +460,13 @@ class AuraScript : public _SpellScript
|
||||
// AuraScript interface
|
||||
// hooks to which you can attach your functions
|
||||
//
|
||||
// executed when periodic aura effect is applied with specified mode to target
|
||||
// executed when aura effect is applied with specified mode to target
|
||||
// example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectApplyHandler> OnEffectApply;
|
||||
#define AuraEffectApplyFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
|
||||
|
||||
// executed when periodic aura effect is removed with specified mode from target
|
||||
// executed when aura effect is removed with specified mode from target
|
||||
// example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
// where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectApplyHandler> OnEffectRemove;
|
||||
|
||||
Reference in New Issue
Block a user