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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user