Skip to content

Commit

Permalink
Core/Auras:
Browse files Browse the repository at this point in the history
 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.
  • Loading branch information
QAston committed Dec 31, 2010
1 parent 72a115f commit 42d3130
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 133 deletions.
34 changes: 34 additions & 0 deletions src/server/game/Entities/Unit/Unit.cpp
Expand Up @@ -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())
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Entities/Unit/Unit.h
Expand Up @@ -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;}
Expand Down
223 changes: 90 additions & 133 deletions src/server/game/Spells/Auras/SpellAuraEffects.cpp
Expand Up @@ -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)
if (apply)
{
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 polymorph before changing display id to keep new display id
switch (form)
{
// remove movement affects
target->RemoveMovementImpairingAuras();
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;
// and polymorphic affects
if (target->IsPolymorphed())
target->RemoveAurasDueToSpell(target->getTransForm());
break;
}
default:
break;
}
default:
break;
}

if (apply)
{
// remove other shapeshift before applying a new one
target->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT, 0, GetBase());

Expand Down Expand Up @@ -3140,34 +3140,18 @@ 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);

if (modelid > 0)
// 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))
{
// 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->SetShapeshiftForm(FORM_NONE);
if (target->getClass() == CLASS_DRUID)
target->setPowerType(POWER_MANA);
}

if (modelid > 0)
target->RestoreDisplayId();

switch (form)
{
// Nordrassil Harness - bonus
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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())
Expand All @@ -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)
Expand Down

0 comments on commit 42d3130

Please sign in to comment.