*Allow unit has multiple controlling auras. (Fix the bug that unit cannot be feared if stunned. Hope this will not break all controlling spells)

--HG--
branch : trunk
This commit is contained in:
megamage
2008-12-09 20:28:59 -06:00
parent 20947a4c73
commit b5d1418b0c
3 changed files with 209 additions and 102 deletions
+9 -93
View File
@@ -3040,7 +3040,8 @@ void Aura::HandleModConfuse(bool apply, bool Real)
if(!Real)
return;
m_target->SetConfused(apply, GetCasterGUID(), GetId());
//m_target->SetConfused(apply, GetCasterGUID(), GetId());
m_target->SetControlled(apply, UNIT_STAT_CONFUSED);
}
void Aura::HandleModFear(bool apply, bool Real)
@@ -3048,7 +3049,8 @@ void Aura::HandleModFear(bool apply, bool Real)
if (!Real)
return;
m_target->SetFeared(apply, GetCasterGUID(), GetId());
//m_target->SetFeared(apply, GetCasterGUID(), GetId());
m_target->SetControlled(apply, UNIT_STAT_FLEEING);
}
void Aura::HandleFeignDeath(bool apply, bool Real)
@@ -3146,46 +3148,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
if(!Real)
return;
if (apply)
{
m_target->addUnitState(UNIT_STAT_STUNNED);
m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0);
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0);
// Creature specific
if(m_target->GetTypeId() != TYPEID_PLAYER)
((Creature*)m_target)->StopMoving();
else
m_target->SetUnitMovementFlags(0); //Clear movement flags
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
data.append(m_target->GetPackGUID());
data << uint32(0);
m_target->SendMessageToSet(&data,true);
}
else
{
// Real remove called after current aura remove from lists, check if other similar auras active
if(m_target->HasAuraType(SPELL_AURA_MOD_STUN))
return;
m_target->clearUnitState(UNIT_STAT_STUNNED);
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
if(!m_target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
{
if(m_target->getVictim() && m_target->isAlive())
m_target->SetUInt64Value(UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
data.append(m_target->GetPackGUID());
data << uint32(0);
m_target->SendMessageToSet(&data,true);
}
}
m_target->SetControlled(apply, UNIT_STAT_STUNNED);
}
void Aura::HandleModStealth(bool apply, bool Real)
@@ -3355,55 +3318,7 @@ void Aura::HandleAuraModRoot(bool apply, bool Real)
if(!Real)
return;
uint32 apply_stat = UNIT_STAT_ROOT;
if (apply)
{
m_target->addUnitState(UNIT_STAT_ROOT);
m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0);
// probably wrong
m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
//Save last orientation
if( m_target->getVictim() )
m_target->SetOrientation(m_target->GetAngle(m_target->getVictim()));
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
data.append(m_target->GetPackGUID());
data << (uint32)2;
m_target->SendMessageToSet(&data,true);
//Clear unit movement flags
m_target->SetUnitMovementFlags(0);
}
else
((Creature *)m_target)->StopMoving();
}
else
{
// Real remove called after current aura remove from lists, check if other similar auras active
if(m_target->HasAuraType(SPELL_AURA_MOD_ROOT))
return;
m_target->clearUnitState(UNIT_STAT_ROOT);
// probably wrong
m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16));
if(!m_target->hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect
{
if(m_target->getVictim() && m_target->isAlive())
m_target->SetUInt64Value (UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() );
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
data.append(m_target->GetPackGUID());
data << (uint32)2;
m_target->SendMessageToSet(&data,true);
}
}
}
m_target->SetControlled(apply, UNIT_STAT_ROOT);
}
void Aura::HandleAuraModSilence(bool apply, bool Real)
@@ -6231,10 +6146,11 @@ void Aura::HandlePreventFleeing(bool apply, bool Real)
Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
if( !fearAuras.empty() )
{
if (apply)
m_target->SetControlled(!apply, UNIT_STAT_FLEEING);
/*if (apply)
m_target->SetFeared(false, fearAuras.front()->GetCasterGUID());
else
m_target->SetFeared(true);
m_target->SetFeared(true);*/
}
}
+195 -7
View File
@@ -9260,13 +9260,6 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
if (!spellInfo)
return false;
//FIX ME this hack: don't get feared if stunned
if (spellInfo->Mechanic == MECHANIC_FEAR )
{
if ( hasUnitState(UNIT_STAT_STUNNED) )
return true;
}
SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
if(itr->type == spellInfo->Dispel)
@@ -11844,6 +11837,7 @@ void Unit::StopMoving()
SendMessageToSet(&data,false);
}
/*
void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
{
if( apply )
@@ -11912,6 +11906,7 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
if(GetTypeId() == TYPEID_PLAYER)
((Player*)this)->SetClientControl(this, !apply);
}
*/
bool Unit::IsSitState() const
{
@@ -12646,4 +12641,197 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
bg->HandleKillUnit((Creature*)pVictim, player);
}
}
}
void Unit::SetControlled(bool apply, UnitState state)
{
if(apply)
{
if(hasUnitState(state))
return;
addUnitState(state);
switch(state)
{
case UNIT_STAT_STUNNED:
SetStunned(true);
break;
case UNIT_STAT_ROOT:
if(!hasUnitState(UNIT_STAT_STUNNED))
SetRooted(true);
break;
case UNIT_STAT_CONFUSED:
if(!hasUnitState(UNIT_STAT_STUNNED))
SetConfused(true);
break;
case UNIT_STAT_FLEEING:
if(!hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
SetFeared(true);
break;
default:
break;
}
}
else
{
switch(state)
{
case UNIT_STAT_STUNNED: if(HasAuraType(SPELL_AURA_MOD_STUN)) return;
else(SetStunned(false));
case UNIT_STAT_ROOT: if(HasAuraType(SPELL_AURA_MOD_ROOT)) return;
else(SetRooted(false));
case UNIT_STAT_CONFUSED:if(HasAuraType(SPELL_AURA_MOD_CONFUSE)) return;
else(SetConfused(false));
case UNIT_STAT_FLEEING: if(HasAuraType(SPELL_AURA_MOD_FEAR)) return;
else(SetFeared(false));
default: return;
}
clearUnitState(state);
if(hasUnitState(UNIT_STAT_STUNNED))
SetStunned(true);
else
{
if(hasUnitState(UNIT_STAT_ROOT))
SetRooted(true);
if(hasUnitState(UNIT_STAT_CONFUSED))
SetConfused(true);
else if(hasUnitState(UNIT_STAT_FLEEING))
SetFeared(true);
}
}
}
void Unit::SetStunned(bool apply)
{
if(apply)
{
SetUInt64Value(UNIT_FIELD_TARGET, 0);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
CastStop();
// Creature specific
if(GetTypeId() != TYPEID_PLAYER)
((Creature*)this)->StopMoving();
else
SetUnitMovementFlags(0); //Clear movement flags
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
data.append(GetPackGUID());
data << uint32(0);
SendMessageToSet(&data,true);
}
else
{
if(isAlive() && getVictim())
SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID());
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
if(!hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
{
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
data.append(GetPackGUID());
data << uint32(0);
SendMessageToSet(&data,true);
}
}
}
void Unit::SetRooted(bool apply)
{
uint32 apply_stat = UNIT_STAT_ROOT;
if(apply)
{
SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); // probably wrong
if(GetTypeId() == TYPEID_PLAYER)
{
SetUnitMovementFlags(0);
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
data.append(GetPackGUID());
data << (uint32)2;
SendMessageToSet(&data,true);
}
else
((Creature *)this)->StopMoving();
}
else
{
RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); // probably wrong
if(!hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect
{
if(GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
data.append(GetPackGUID());
data << (uint32)2;
SendMessageToSet(&data,true);
}
}
}
}
void Unit::SetFeared(bool apply)
{
if(apply)
{
if(HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
return;
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
CastStop();
//GetMotionMaster()->MovementExpired(false);
Unit *caster = NULL;
Unit::AuraList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR);
if(!fearAuras.empty())
caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing
}
else
{
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
GetMotionMaster()->MovementExpired(false);
if( GetTypeId() != TYPEID_PLAYER && isAlive() )
{
// restore appropriate movement generator
if(getVictim())
GetMotionMaster()->MoveChase(getVictim());
else
GetMotionMaster()->Initialize();
}
}
if (GetTypeId() == TYPEID_PLAYER)
((Player*)this)->SetClientControl(this, !apply);
}
void Unit::SetConfused(bool apply)
{
if(apply)
{
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
CastStop();
GetMotionMaster()->MoveConfused();
}
else
{
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
GetMotionMaster()->MovementExpired(false);
if( GetTypeId() != TYPEID_PLAYER && isAlive() )
{
// restore appropriate movement generator
if(getVictim())
GetMotionMaster()->MoveChase(getVictim());
else
GetMotionMaster()->Initialize();
}
}
if(GetTypeId() == TYPEID_PLAYER)
((Player*)this)->SetClientControl(this, !apply);
}
+5 -2
View File
@@ -1348,8 +1348,11 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; }
void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; }
void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
void SetControlled(bool apply, UnitState state);
void SetFeared(bool apply/*, uint64 casterGUID = 0, uint32 spellID = 0*/);
void SetConfused(bool apply/*, uint64 casterGUID = 0, uint32 spellID = 0*/);
void SetStunned(bool apply);
void SetRooted(bool apply);
void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }