Core/Auras:
Fix a crash with spell 33499 - BIG thanks to Shauren for finding the reason of this crash Corrections in managing stacked auras which change unit model.
This commit is contained in:
@@ -14212,6 +14212,40 @@ void Unit::SetDisplayId(uint32 modelId)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RestoreDisplayId()
|
||||
{
|
||||
AuraEffect* handledAura = NULL;
|
||||
// try to receive model from transform auras
|
||||
Unit::AuraEffectList const& transforms = GetAuraEffectsByType(SPELL_AURA_TRANSFORM);
|
||||
if (!transforms.empty())
|
||||
{
|
||||
// iterate over already applied transform auras - from newest to oldest
|
||||
for (Unit::AuraEffectList::const_reverse_iterator i = transforms.rbegin(); i != transforms.rend(); ++i)
|
||||
{
|
||||
if (AuraApplication const * aurApp = (*i)->GetBase()->GetApplicationOfTarget(GetGUID()))
|
||||
{
|
||||
if (aurApp->IsPositive())
|
||||
handledAura = (*i);
|
||||
// prefer negative auras
|
||||
else
|
||||
{
|
||||
handledAura = (*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// transform aura was found
|
||||
if (handledAura)
|
||||
handledAura->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
|
||||
// we've found shapeshift
|
||||
else if (uint32 modelId = GetModelForForm(GetShapeshiftForm()))
|
||||
SetDisplayId(modelId);
|
||||
// no auras found - set modelid to default
|
||||
else
|
||||
SetDisplayId(GetNativeDisplayId());
|
||||
}
|
||||
|
||||
void Unit::ClearComboPointHolders()
|
||||
{
|
||||
while (!m_ComboPointHolders.empty())
|
||||
|
||||
@@ -1858,6 +1858,7 @@ class Unit : public WorldObject
|
||||
uint32 GetDisplayId() { return GetUInt32Value(UNIT_FIELD_DISPLAYID); }
|
||||
void SetDisplayId(uint32 modelId);
|
||||
uint32 GetNativeDisplayId() { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); }
|
||||
void RestoreDisplayId();
|
||||
void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); }
|
||||
void setTransForm(uint32 spellid) { m_transform = spellid;}
|
||||
uint32 getTransForm() const { return m_transform;}
|
||||
|
||||
@@ -3052,33 +3052,33 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 m
|
||||
|
||||
modelid = target->GetModelForForm(form);
|
||||
|
||||
// remove polymorph before changing display id to keep new display id
|
||||
switch (form)
|
||||
{
|
||||
case FORM_CAT:
|
||||
case FORM_TREE:
|
||||
case FORM_TRAVEL:
|
||||
case FORM_AQUA:
|
||||
case FORM_BEAR:
|
||||
case FORM_DIREBEAR:
|
||||
case FORM_FLIGHT_EPIC:
|
||||
case FORM_FLIGHT:
|
||||
case FORM_MOONKIN:
|
||||
{
|
||||
// remove movement affects
|
||||
target->RemoveMovementImpairingAuras();
|
||||
|
||||
// and polymorphic affects
|
||||
if (target->IsPolymorphed())
|
||||
target->RemoveAurasDueToSpell(target->getTransForm());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (apply)
|
||||
{
|
||||
// remove polymorph before changing display id to keep new display id
|
||||
switch (form)
|
||||
{
|
||||
case FORM_CAT:
|
||||
case FORM_TREE:
|
||||
case FORM_TRAVEL:
|
||||
case FORM_AQUA:
|
||||
case FORM_BEAR:
|
||||
case FORM_DIREBEAR:
|
||||
case FORM_FLIGHT_EPIC:
|
||||
case FORM_FLIGHT:
|
||||
case FORM_MOONKIN:
|
||||
{
|
||||
// remove movement affects
|
||||
target->RemoveMovementImpairingAuras();
|
||||
|
||||
// and polymorphic affects
|
||||
if (target->IsPolymorphed())
|
||||
target->RemoveAurasDueToSpell(target->getTransForm());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// remove other shapeshift before applying a new one
|
||||
target->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT, 0, GetBase());
|
||||
|
||||
@@ -3140,33 +3140,17 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 m
|
||||
}
|
||||
else
|
||||
{
|
||||
target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE);
|
||||
if (target->getClass() == CLASS_DRUID)
|
||||
target->setPowerType(POWER_MANA);
|
||||
target->SetShapeshiftForm(FORM_NONE);
|
||||
// reset model id if no other auras present
|
||||
// may happen when aura is applied on linked event on aura removal
|
||||
if (!target->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
|
||||
{
|
||||
target->SetShapeshiftForm(FORM_NONE);
|
||||
if (target->getClass() == CLASS_DRUID)
|
||||
target->setPowerType(POWER_MANA);
|
||||
}
|
||||
|
||||
if (modelid > 0)
|
||||
{
|
||||
// re-aplly some from still active with preference negative cases
|
||||
Unit::AuraEffectList const& otherTransforms = target->GetAuraEffectsByType(SPELL_AURA_TRANSFORM);
|
||||
if (!otherTransforms.empty())
|
||||
{
|
||||
// look for other transform auras
|
||||
AuraEffect* handledAura = *otherTransforms.begin();
|
||||
for (Unit::AuraEffectList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
|
||||
{
|
||||
// negative auras are preferred
|
||||
if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
|
||||
{
|
||||
handledAura = *i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
handledAura->HandleEffect(target, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
|
||||
}
|
||||
else
|
||||
target->SetDisplayId(target->GetNativeDisplayId());
|
||||
}
|
||||
target->RestoreDisplayId();
|
||||
|
||||
switch (form)
|
||||
{
|
||||
@@ -3268,73 +3252,70 @@ void AuraEffect::HandleAuraTransform(AuraApplication const * aurApp, uint8 mode,
|
||||
|
||||
if (apply)
|
||||
{
|
||||
// special case (spell specific functionality)
|
||||
if (GetMiscValue() == 0)
|
||||
// update active transform spell only when transform or shapeshift not set or not overwriting negative by positive case
|
||||
if ((!target->getTransForm() && !target->GetShapeshiftForm()) || !IsPositiveSpell(GetId()) || IsPositiveSpell(target->getTransForm()))
|
||||
{
|
||||
// player applied only
|
||||
if (target->GetTypeId() != TYPEID_PLAYER || target->GetModelForForm(target->GetShapeshiftForm()))
|
||||
return;
|
||||
|
||||
switch (GetId())
|
||||
// special case (spell specific functionality)
|
||||
if (GetMiscValue() == 0)
|
||||
{
|
||||
// Orb of Deception
|
||||
case 16739:
|
||||
switch (GetId())
|
||||
{
|
||||
uint32 orb_model = target->GetNativeDisplayId();
|
||||
switch(orb_model)
|
||||
// Orb of Deception
|
||||
case 16739:
|
||||
{
|
||||
// Troll Female
|
||||
case 1479: target->SetDisplayId(10134); break;
|
||||
// Troll Male
|
||||
case 1478: target->SetDisplayId(10135); break;
|
||||
// Tauren Male
|
||||
case 59: target->SetDisplayId(10136); break;
|
||||
// Human Male
|
||||
case 49: target->SetDisplayId(10137); break;
|
||||
// Human Female
|
||||
case 50: target->SetDisplayId(10138); break;
|
||||
// Orc Male
|
||||
case 51: target->SetDisplayId(10139); break;
|
||||
// Orc Female
|
||||
case 52: target->SetDisplayId(10140); break;
|
||||
// Dwarf Male
|
||||
case 53: target->SetDisplayId(10141); break;
|
||||
// Dwarf Female
|
||||
case 54: target->SetDisplayId(10142); break;
|
||||
// NightElf Male
|
||||
case 55: target->SetDisplayId(10143); break;
|
||||
// NightElf Female
|
||||
case 56: target->SetDisplayId(10144); break;
|
||||
// Undead Female
|
||||
case 58: target->SetDisplayId(10145); break;
|
||||
// Undead Male
|
||||
case 57: target->SetDisplayId(10146); break;
|
||||
// Tauren Female
|
||||
case 60: target->SetDisplayId(10147); break;
|
||||
// Gnome Male
|
||||
case 1563: target->SetDisplayId(10148); break;
|
||||
// Gnome Female
|
||||
case 1564: target->SetDisplayId(10149); break;
|
||||
// BloodElf Female
|
||||
case 15475: target->SetDisplayId(17830); break;
|
||||
// BloodElf Male
|
||||
case 15476: target->SetDisplayId(17829); break;
|
||||
// Dranei Female
|
||||
case 16126: target->SetDisplayId(17828); break;
|
||||
// Dranei Male
|
||||
case 16125: target->SetDisplayId(17827); break;
|
||||
default: break;
|
||||
uint32 orb_model = target->GetNativeDisplayId();
|
||||
switch(orb_model)
|
||||
{
|
||||
// Troll Female
|
||||
case 1479: target->SetDisplayId(10134); break;
|
||||
// Troll Male
|
||||
case 1478: target->SetDisplayId(10135); break;
|
||||
// Tauren Male
|
||||
case 59: target->SetDisplayId(10136); break;
|
||||
// Human Male
|
||||
case 49: target->SetDisplayId(10137); break;
|
||||
// Human Female
|
||||
case 50: target->SetDisplayId(10138); break;
|
||||
// Orc Male
|
||||
case 51: target->SetDisplayId(10139); break;
|
||||
// Orc Female
|
||||
case 52: target->SetDisplayId(10140); break;
|
||||
// Dwarf Male
|
||||
case 53: target->SetDisplayId(10141); break;
|
||||
// Dwarf Female
|
||||
case 54: target->SetDisplayId(10142); break;
|
||||
// NightElf Male
|
||||
case 55: target->SetDisplayId(10143); break;
|
||||
// NightElf Female
|
||||
case 56: target->SetDisplayId(10144); break;
|
||||
// Undead Female
|
||||
case 58: target->SetDisplayId(10145); break;
|
||||
// Undead Male
|
||||
case 57: target->SetDisplayId(10146); break;
|
||||
// Tauren Female
|
||||
case 60: target->SetDisplayId(10147); break;
|
||||
// Gnome Male
|
||||
case 1563: target->SetDisplayId(10148); break;
|
||||
// Gnome Female
|
||||
case 1564: target->SetDisplayId(10149); break;
|
||||
// BloodElf Female
|
||||
case 15475: target->SetDisplayId(17830); break;
|
||||
// BloodElf Male
|
||||
case 15476: target->SetDisplayId(17829); break;
|
||||
// Dranei Female
|
||||
case 16126: target->SetDisplayId(17828); break;
|
||||
// Dranei Male
|
||||
case 16125: target->SetDisplayId(17827); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// Murloc costume
|
||||
case 42365: target->SetDisplayId(21723); break;
|
||||
default: break;
|
||||
}
|
||||
// Murloc costume
|
||||
case 42365: target->SetDisplayId(21723); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!target->GetModelForForm(target->GetShapeshiftForm()))
|
||||
else
|
||||
{
|
||||
CreatureInfo const * ci = ObjectMgr::GetCreatureTemplate(GetMiscValue());
|
||||
if (!ci)
|
||||
@@ -3362,11 +3343,8 @@ void AuraEffect::HandleAuraTransform(AuraApplication const * aurApp, uint8 mode,
|
||||
target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update active transform spell only not set or not overwriting negative by positive case
|
||||
if (!target->getTransForm() || !IsPositiveSpell(GetId()) || IsPositiveSpell(target->getTransForm()))
|
||||
target->setTransForm(GetId());
|
||||
}
|
||||
|
||||
// polymorph case
|
||||
if ((mode & AURA_EFFECT_HANDLE_REAL) && target->GetTypeId() == TYPEID_PLAYER && target->IsPolymorphed())
|
||||
@@ -3386,28 +3364,7 @@ void AuraEffect::HandleAuraTransform(AuraApplication const * aurApp, uint8 mode,
|
||||
// HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true) will reapply it if need
|
||||
target->setTransForm(0);
|
||||
|
||||
if (!target->GetModelForForm(target->GetShapeshiftForm()))
|
||||
{
|
||||
// re-aplly some from still active with preference negative cases
|
||||
Unit::AuraEffectList const& otherTransforms = target->GetAuraEffectsByType(SPELL_AURA_TRANSFORM);
|
||||
if (!otherTransforms.empty())
|
||||
{
|
||||
// look for other transform auras
|
||||
AuraEffect* handledAura = *otherTransforms.begin();
|
||||
for (Unit::AuraEffectList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
|
||||
{
|
||||
// negative auras are preferred
|
||||
if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
|
||||
{
|
||||
handledAura = *i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
handledAura->HandleEffect(target, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
|
||||
}
|
||||
else
|
||||
target->SetDisplayId(target->GetNativeDisplayId());
|
||||
}
|
||||
target->RestoreDisplayId();
|
||||
|
||||
// Dragonmaw Illusion (restore mount model)
|
||||
if (GetId() == 42016 && target->GetMountID() == 16314)
|
||||
|
||||
Reference in New Issue
Block a user