mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[10076] Fixed crash at remove from world pet under SPELL_AURA_MOD_POSSESS_PET
* Prevent crash at camera list update at attempt increment end() iterator. * Properly do unapply SPELL_AURA_MOD_POSSESS_PET (GetPet() can return NULL at call, and not need checked) * Propertly call unapply at delete auras cases for auras that set player-caster mover pointer.
This commit is contained in:
parent
81851074ad
commit
3e210228f9
4 changed files with 50 additions and 21 deletions
|
|
@ -80,8 +80,16 @@ class MANGOS_DLL_SPEC ViewPoint
|
||||||
void CameraCall(void (Camera::*handler)())
|
void CameraCall(void (Camera::*handler)())
|
||||||
{
|
{
|
||||||
if (!m_cameras.empty())
|
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)();
|
((*m_camera_iter)->*handler)();
|
||||||
|
|
||||||
|
// can be end() after handler
|
||||||
|
if (m_camera_iter == m_cameras.end())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -3710,36 +3710,40 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
||||||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Pet *pet = caster->GetPet();
|
Unit* target = GetTarget();
|
||||||
if(!pet || pet != GetTarget())
|
if (target->GetTypeId() != TYPEID_UNIT)
|
||||||
return;
|
return;
|
||||||
|
Creature* pet = (Creature*)target; // not need more stricted type check
|
||||||
|
|
||||||
Player* p_caster = (Player*)caster;
|
Player* p_caster = (Player*)caster;
|
||||||
Camera& camera = p_caster->GetCamera();
|
Camera& camera = p_caster->GetCamera();
|
||||||
|
|
||||||
if(apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
|
||||||
camera.SetView(pet);
|
camera.SetView(pet);
|
||||||
}
|
p_caster->SetCharm(pet);
|
||||||
else
|
p_caster->SetClientControl(pet, 1);
|
||||||
{
|
((Player*)caster)->SetMover(pet);
|
||||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
|
||||||
camera.ResetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
p_caster->SetCharm(apply ? pet : NULL);
|
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
p_caster->SetClientControl(pet, apply ? 1 : 0);
|
|
||||||
((Player*)caster)->SetMover(apply ? pet : NULL);
|
|
||||||
|
|
||||||
if(apply)
|
|
||||||
{
|
|
||||||
pet->StopMoving();
|
pet->StopMoving();
|
||||||
pet->GetMotionMaster()->Clear();
|
pet->GetMotionMaster()->Clear(false);
|
||||||
pet->GetMotionMaster()->MoveIdle();
|
pet->GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
else
|
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->AttackStop();
|
||||||
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||||
pet->AddSplineFlag(SPLINEFLAG_WALKMODE);
|
pet->AddSplineFlag(SPLINEFLAG_WALKMODE);
|
||||||
|
|
@ -8272,9 +8276,13 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real)
|
||||||
if(!Real)
|
if(!Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
|
||||||
|
return;
|
||||||
|
Vehicle* vehicle = (Vehicle*)target;
|
||||||
|
|
||||||
Unit *player = GetCaster();
|
Unit *player = GetCaster();
|
||||||
Vehicle *vehicle = dynamic_cast<Vehicle*>(GetTarget());
|
if(!player || player->GetTypeId() != TYPEID_PLAYER)
|
||||||
if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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
|
// 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);
|
Aur->ApplyModifier(false,true);
|
||||||
|
|
||||||
if (Aur->_RemoveAura())
|
if (Aur->_RemoveAura())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10075"
|
#define REVISION_NR "10076"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue