diff --git a/src/game/Camera.h b/src/game/Camera.h index a28d71c30..98431be04 100644 --- a/src/game/Camera.h +++ b/src/game/Camera.h @@ -80,8 +80,16 @@ class MANGOS_DLL_SPEC ViewPoint void CameraCall(void (Camera::*handler)()) { if (!m_cameras.empty()) - for(m_camera_iter = m_cameras.begin(); m_camera_iter!=m_cameras.end(); ++m_camera_iter) + { + for(m_camera_iter = m_cameras.begin(); m_camera_iter != m_cameras.end(); ++m_camera_iter) + { ((*m_camera_iter)->*handler)(); + + // can be end() after handler + if (m_camera_iter == m_cameras.end()) + break; + } + } } public: diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8ff7d2f10..533c09805 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3710,36 +3710,40 @@ void Aura::HandleModPossessPet(bool apply, bool Real) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - Pet *pet = caster->GetPet(); - if(!pet || pet != GetTarget()) + Unit* target = GetTarget(); + if (target->GetTypeId() != TYPEID_UNIT) return; + Creature* pet = (Creature*)target; // not need more stricted type check Player* p_caster = (Player*)caster; Camera& camera = p_caster->GetCamera(); - if(apply) + if (apply) { - pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); camera.SetView(pet); - } - else - { - pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - camera.ResetView(); - } + p_caster->SetCharm(pet); + p_caster->SetClientControl(pet, 1); + ((Player*)caster)->SetMover(pet); - p_caster->SetCharm(apply ? pet : NULL); - p_caster->SetClientControl(pet, apply ? 1 : 0); - ((Player*)caster)->SetMover(apply ? pet : NULL); + pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - if(apply) - { pet->StopMoving(); - pet->GetMotionMaster()->Clear(); + pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); } else { + camera.ResetView(); + p_caster->SetCharm(NULL); + p_caster->SetClientControl(pet, 0); + p_caster->SetMover(NULL); + + // on delete only do caster related effects + if(m_removeMode == AURA_REMOVE_BY_DELETE) + return; + + pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); pet->AddSplineFlag(SPLINEFLAG_WALKMODE); @@ -8272,9 +8276,13 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real) if(!Real) return; + Unit* target = GetTarget(); + if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle()) + return; + Vehicle* vehicle = (Vehicle*)target; + Unit *player = GetCaster(); - Vehicle *vehicle = dynamic_cast(GetTarget()); - if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle) + if(!player || player->GetTypeId() != TYPEID_PLAYER) return; if (apply) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9f22d733c..81f6db4d0 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4511,7 +4511,20 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); // some auras also need to apply modifier (on caster) on remove - if (mode != AURA_REMOVE_BY_DELETE || Aur->GetModifier()->m_auraname == SPELL_AURA_MOD_POSSESS) + if (mode == AURA_REMOVE_BY_DELETE) + { + switch (Aur->GetModifier()->m_auraname) + { + // need properly undo any auras with player-caster mover set (or will crash at next caster move packet) + case SPELL_AURA_MOD_POSSESS: + case SPELL_AURA_MOD_POSSESS_PET: + case SPELL_AURA_CONTROL_VEHICLE: + Aur->ApplyModifier(false,true); + break; + default: break; + } + } + else Aur->ApplyModifier(false,true); if (Aur->_RemoveAura()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index dfa86d1f4..c40f920e0 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10075" + #define REVISION_NR "10076" #endif // __REVISION_NR_H__