diff options
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 23 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 6 | ||||
-rwxr-xr-x | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 16 |
3 files changed, 32 insertions, 13 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b1c96166c1c..198f890fb9d 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15275,7 +15275,7 @@ void Unit::SetConfused(bool apply) this->ToPlayer()->SetClientControl(this, !apply); } -bool Unit::SetCharmedBy(Unit* charmer, CharmType type) +bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const * aurApp) { if (!charmer) return false; @@ -15336,6 +15336,11 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) return false; } + // charm is set by aura, and aura effect remove handler was called during apply handler execution + // prevent undefined behaviour + if (aurApp && aurApp->GetRemoveMode()) + return false; + // Set charmed Map* pMap = GetMap(); if (!IsVehicle() || (IsVehicle() && pMap && !pMap->IsBattleground())) @@ -15355,6 +15360,11 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) this->ToPlayer()->SetClientControl(this, 0); } + // charm is set by aura, and aura effect remove handler was called during apply handler execution + // prevent undefined behaviour + if (aurApp && aurApp->GetRemoveMode()) + return false; + // Pets already have a properly initialized CharmInfo, don't overwrite it. if (type != CHARM_TYPE_VEHICLE && !GetCharmInfo()) { @@ -16308,7 +16318,7 @@ bool Unit::CheckPlayerCondition(Player* pPlayer) } } -void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, bool byAura) +void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, AuraApplication const * aurApp) { if (!isAlive() || GetVehicleKit() == vehicle) return; @@ -16320,7 +16330,7 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, bool byAura) if (seatId >= 0 && seatId != GetTransSeat()) { sLog->outDebug("EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId); - ChangeSeat(seatId, byAura); + ChangeSeat(seatId, bool(aurApp)); } return; } @@ -16347,9 +16357,14 @@ void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId, bool byAura) bg->EventPlayerDroppedFlag(plr); } + // vehicle is applied by aura, and aura effect remove handler was called during apply handler execution + // prevent undefined behaviour + if (aurApp && aurApp->GetRemoveMode()) + return; + ASSERT(!m_vehicle); m_vehicle = vehicle; - if (!m_vehicle->AddPassenger(this, seatId, byAura)) + if (!m_vehicle->AddPassenger(this, seatId, bool(aurApp))) { m_vehicle = NULL; return; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index d9c9acdfa5f..0f074e50a47 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1564,7 +1564,7 @@ class Unit : public WorldObject void RemoveAllMinionsByEntry(uint32 entry); void SetCharm(Unit* target, bool apply); Unit* GetNextRandomRaidMemberOrPet(float radius); - bool SetCharmedBy(Unit* charmer, CharmType type); + bool SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const * aurApp = NULL); void RemoveCharmedBy(Unit* charmer); void RestoreFaction(); @@ -2028,8 +2028,8 @@ class Unit : public WorldObject bool m_ControlledByPlayer; bool CheckPlayerCondition(Player* pPlayer); - void EnterVehicle(Unit *base, int8 seatId = -1, bool byAura = false) { EnterVehicle(base->GetVehicleKit(), seatId, byAura); } - void EnterVehicle(Vehicle *vehicle, int8 seatId = -1, bool byAura = false); + void EnterVehicle(Unit *base, int8 seatId = -1, AuraApplication const * aurApp = NULL) { EnterVehicle(base->GetVehicleKit(), seatId, aurApp); } + void EnterVehicle(Vehicle *vehicle, int8 seatId = -1, AuraApplication const * aurApp = NULL); void ExitVehicle(); void ChangeSeat(int8 seatId, bool next = true, bool byAura = false); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e82083a469e..a584f382a74 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3837,7 +3837,7 @@ void AuraEffect::HandleAuraModSkill(AuraApplication const * aurApp, uint8 /*mode if (target->GetTypeId() != TYPEID_PLAYER) return; - uint32 prot = GetSpellProto()->EffectMiscValue[m_effIndex]; + uint32 prot = GetMiscValue(); int32 points = GetAmount(); target->ToPlayer()->ModifySkillBonus(prot,((apply) ? points: -points),GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT); @@ -4174,7 +4174,7 @@ void AuraEffect::HandleModPossess(AuraApplication const * aurApp, uint8 mode, bo } if (apply) - target->SetCharmedBy(caster, CHARM_TYPE_POSSESS); + target->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp); else target->RemoveCharmedBy(caster); } @@ -4204,7 +4204,7 @@ void AuraEffect::HandleModPossessPet(AuraApplication const * aurApp, uint8 mode, if (caster->ToPlayer()->GetPet() != pet) return; - pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS); + pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp); } else { @@ -4236,7 +4236,7 @@ void AuraEffect::HandleModCharm(AuraApplication const * aurApp, uint8 mode, bool Unit * caster = GetCaster(); if (apply) - target->SetCharmedBy(caster, CHARM_TYPE_CHARM); + target->SetCharmedBy(caster, CHARM_TYPE_CHARM, aurApp); else target->RemoveCharmedBy(caster); } @@ -4251,7 +4251,7 @@ void AuraEffect::HandleCharmConvert(AuraApplication const * aurApp, uint8 mode, Unit * caster = GetCaster(); if (apply) - target->SetCharmedBy(caster, CHARM_TYPE_CONVERT); + target->SetCharmedBy(caster, CHARM_TYPE_CONVERT, aurApp); else target->RemoveCharmedBy(caster); } @@ -4277,7 +4277,7 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const * aurApp, uint8 if (apply) { - caster->EnterVehicle(target->GetVehicleKit(), m_amount - 1, true); + caster->EnterVehicle(target->GetVehicleKit(), m_amount - 1, aurApp); } else { @@ -4436,6 +4436,10 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const * aurApp, uint 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); } |