*Fix some crashes possibly related to vehicles.
*Fix a bug that client crashes when seer is far away from caster. --HG-- branch : trunk
This commit is contained in:
@@ -166,20 +166,25 @@ Creature::~Creature()
|
|||||||
void Creature::AddToWorld()
|
void Creature::AddToWorld()
|
||||||
{
|
{
|
||||||
///- Register the creature for guid lookup
|
///- Register the creature for guid lookup
|
||||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
if(!IsInWorld())
|
||||||
|
{
|
||||||
|
ObjectAccessor::Instance().AddObject(this);
|
||||||
Unit::AddToWorld();
|
Unit::AddToWorld();
|
||||||
SearchFormation();
|
SearchFormation();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::RemoveFromWorld()
|
void Creature::RemoveFromWorld()
|
||||||
|
{
|
||||||
|
///- Remove the creature from the accessor
|
||||||
|
if(IsInWorld())
|
||||||
{
|
{
|
||||||
if(m_formationID)
|
if(m_formationID)
|
||||||
formation_mgr.DestroyGroup(m_formationID, GetGUID());
|
formation_mgr.DestroyGroup(m_formationID, GetGUID());
|
||||||
|
ObjectAccessor::Instance().RemoveObject(this);
|
||||||
///- Remove the creature from the accessor
|
|
||||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::SearchFormation()
|
void Creature::SearchFormation()
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-10
@@ -110,14 +110,15 @@ Deliverer::Visit(PlayerMapType &m)
|
|||||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
|
if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
|
||||||
{
|
{
|
||||||
// Send packet to all who are sharing the player's vision
|
// Send packet to all who are sharing the player's vision
|
||||||
if (!iter->getSource()->GetSharedVisionList().empty())
|
if (!iter->getSource()->GetSharedVisionList().empty())
|
||||||
{
|
{
|
||||||
SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
|
SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
|
||||||
for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
|
for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
|
||||||
SendPacket(*it);
|
if((*i)->m_seer == iter->getSource())
|
||||||
|
SendPacket(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitObject(iter->getSource());
|
VisitObject(iter->getSource());
|
||||||
@@ -133,14 +134,15 @@ Deliverer::Visit(CreatureMapType &m)
|
|||||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)
|
if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
|
||||||
{
|
{
|
||||||
// Send packet to all who are sharing the creature's vision
|
// Send packet to all who are sharing the creature's vision
|
||||||
if (!iter->getSource()->GetSharedVisionList().empty())
|
if (!iter->getSource()->GetSharedVisionList().empty())
|
||||||
{
|
{
|
||||||
SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
|
SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
|
||||||
for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
|
for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
|
||||||
SendPacket(*it);
|
if((*i)->m_seer == iter->getSource())
|
||||||
|
SendPacket(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,16 +156,18 @@ Deliverer::Visit(DynamicObjectMapType &m)
|
|||||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
|
||||||
|
{
|
||||||
if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
|
if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
|
||||||
{
|
{
|
||||||
// Send packet back to the caster if the caster has vision of dynamic object
|
// Send packet back to the caster if the caster has vision of dynamic object
|
||||||
Player* caster = (Player*)iter->getSource()->GetCaster();
|
Player* caster = (Player*)iter->getSource()->GetCaster();
|
||||||
if (caster && caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
|
if (caster && caster->m_seer == iter->getSource())
|
||||||
(!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist))
|
|
||||||
SendPacket(caster);
|
SendPacket(caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Deliverer::SendPacket(Player* plr)
|
Deliverer::SendPacket(Player* plr)
|
||||||
|
|||||||
@@ -864,6 +864,48 @@ void Object::SetUInt64Value( uint16 index, const uint64 &value )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object::AddUInt64Value(uint16 index, const uint64 &value)
|
||||||
|
{
|
||||||
|
ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , true ) );
|
||||||
|
if(value && !*((uint64*)&(m_uint32Values[index])))
|
||||||
|
{
|
||||||
|
m_uint32Values[ index ] = *((uint32*)&value);
|
||||||
|
m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
|
||||||
|
|
||||||
|
if(m_inWorld)
|
||||||
|
{
|
||||||
|
if(!m_objectUpdated)
|
||||||
|
{
|
||||||
|
ObjectAccessor::Instance().AddUpdateObject(this);
|
||||||
|
m_objectUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::RemoveUInt64Value(uint16 index, const uint64 &value)
|
||||||
|
{
|
||||||
|
ASSERT( index + 1 < m_valuesCount || PrintIndexError( index , true ) );
|
||||||
|
if(value && *((uint64*)&(m_uint32Values[index])) == value)
|
||||||
|
{
|
||||||
|
m_uint32Values[ index ] = 0;
|
||||||
|
m_uint32Values[ index + 1 ] = 0;
|
||||||
|
|
||||||
|
if(m_inWorld)
|
||||||
|
{
|
||||||
|
if(!m_objectUpdated)
|
||||||
|
{
|
||||||
|
ObjectAccessor::Instance().AddUpdateObject(this);
|
||||||
|
m_objectUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Object::SetFloatValue( uint16 index, float value )
|
void Object::SetFloatValue( uint16 index, float value )
|
||||||
{
|
{
|
||||||
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
|
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
|
||||||
|
|||||||
@@ -215,6 +215,9 @@ class TRINITY_DLL_SPEC Object
|
|||||||
void SetStatFloatValue( uint16 index, float value);
|
void SetStatFloatValue( uint16 index, float value);
|
||||||
void SetStatInt32Value( uint16 index, int32 value);
|
void SetStatInt32Value( uint16 index, int32 value);
|
||||||
|
|
||||||
|
bool AddUInt64Value( uint16 index, const uint64 &value );
|
||||||
|
bool RemoveUInt64Value( uint16 index, const uint64 &value );
|
||||||
|
|
||||||
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
|
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
|
||||||
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
|
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
|
||||||
void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
|
void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
|
||||||
|
|||||||
+14
-6
@@ -1895,6 +1895,15 @@ void Player::RemoveFromWorld()
|
|||||||
///- It will crash when updating the ObjectAccessor
|
///- It will crash when updating the ObjectAccessor
|
||||||
///- The player should only be removed when logging out
|
///- The player should only be removed when logging out
|
||||||
Unit::RemoveFromWorld();
|
Unit::RemoveFromWorld();
|
||||||
|
|
||||||
|
if(m_uint32Values)
|
||||||
|
{
|
||||||
|
if(GetUInt64Value(PLAYER_FARSIGHT))
|
||||||
|
{
|
||||||
|
sLog.outCrash("Player %s has viewpoint when removed from world", GetName());
|
||||||
|
CreateViewpoint(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker )
|
void Player::RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker )
|
||||||
@@ -17038,7 +17047,7 @@ void Player::StopCastingCharm()
|
|||||||
|
|
||||||
if(GetCharmGUID())
|
if(GetCharmGUID())
|
||||||
{
|
{
|
||||||
sLog.outError("CRASH ALARM! Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
|
sLog.outCrash("Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18439,7 +18448,7 @@ void Player::ReportedAfkBy(Player* reporter)
|
|||||||
bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
|
bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
|
||||||
{
|
{
|
||||||
// Always can see self
|
// Always can see self
|
||||||
if (m_mover == u)
|
if (m_mover == u || this == u)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// phased visibility (both must phased in same way)
|
// phased visibility (both must phased in same way)
|
||||||
@@ -20097,13 +20106,12 @@ void Player::CreateViewpoint(WorldObject* target)
|
|||||||
sLog.outDebug("Player::CreateViewpoint: Player %s create seer %u (TypeId: %u).", GetName(), target->GetEntry(), target->GetTypeId());
|
sLog.outDebug("Player::CreateViewpoint: Player %s create seer %u (TypeId: %u).", GetName(), target->GetEntry(), target->GetTypeId());
|
||||||
|
|
||||||
StopCastingBindSight();
|
StopCastingBindSight();
|
||||||
if(GetUInt64Value(PLAYER_FARSIGHT))
|
if(!AddUInt64Value(PLAYER_FARSIGHT, target->GetGUID()))
|
||||||
{
|
{
|
||||||
sLog.outError("Player::CreateViewpoint: Player %s cannot remove current viewpoint!", GetName());
|
sLog.outError("Player::CreateViewpoint: Player %s cannot remove current viewpoint!", GetName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetUInt64Value(PLAYER_FARSIGHT, target->GetGUID());
|
|
||||||
if(target->isType(TYPEMASK_UNIT))
|
if(target->isType(TYPEMASK_UNIT))
|
||||||
((Unit*)target)->AddPlayerToVision(this);
|
((Unit*)target)->AddPlayerToVision(this);
|
||||||
}
|
}
|
||||||
@@ -20205,11 +20213,12 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
|||||||
if(!veSeat)
|
if(!veSeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vehicle->SetCharmerGUID(GetGUID());
|
|
||||||
vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||||
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||||
vehicle->setFaction(getFaction());
|
vehicle->setFaction(getFaction());
|
||||||
|
|
||||||
|
StopCastingCharm();
|
||||||
|
StopCastingBindSight();
|
||||||
SetCharm(vehicle, true); // charm
|
SetCharm(vehicle, true); // charm
|
||||||
SetMover(vehicle);
|
SetMover(vehicle);
|
||||||
|
|
||||||
@@ -20245,7 +20254,6 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
|||||||
|
|
||||||
void Player::ExitVehicle(Vehicle *vehicle)
|
void Player::ExitVehicle(Vehicle *vehicle)
|
||||||
{
|
{
|
||||||
vehicle->SetCharmerGUID(0);
|
|
||||||
vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||||
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||||
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
||||||
|
|||||||
+26
-13
@@ -5046,10 +5046,10 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||||||
if (!Aur)
|
if (!Aur)
|
||||||
return false;
|
return false;
|
||||||
// Remove aura mods
|
// Remove aura mods
|
||||||
Aur->ApplyModifier(false,true);
|
Aur->ApplyModifier(false);
|
||||||
Aur->GetModifier()->m_amount += spelldmg * triggerAmount / 100;
|
Aur->GetModifier()->m_amount += spelldmg * triggerAmount / 100;
|
||||||
// Apply extended aura mods
|
// Apply extended aura mods
|
||||||
Aur->ApplyModifier(true,true);
|
Aur->ApplyModifier(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Eye for an Eye
|
// Eye for an Eye
|
||||||
@@ -8318,8 +8318,7 @@ void Unit::SetPet(Creature* pet, bool apply)
|
|||||||
{
|
{
|
||||||
if(apply)
|
if(apply)
|
||||||
{
|
{
|
||||||
if(!GetPetGUID())
|
AddUInt64Value(UNIT_FIELD_SUMMON, pet->GetGUID());
|
||||||
SetUInt64Value(UNIT_FIELD_SUMMON, pet->GetGUID());
|
|
||||||
m_Controlled.insert(pet);
|
m_Controlled.insert(pet);
|
||||||
|
|
||||||
// FIXME: hack, speed must be set only at follow
|
// FIXME: hack, speed must be set only at follow
|
||||||
@@ -8337,7 +8336,7 @@ void Unit::SetPet(Creature* pet, bool apply)
|
|||||||
{
|
{
|
||||||
if((*itr)->GetOwnerGUID() == GetGUID())
|
if((*itr)->GetOwnerGUID() == GetGUID())
|
||||||
{
|
{
|
||||||
SetUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID());
|
AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8350,16 +8349,26 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
|||||||
{
|
{
|
||||||
if(GetTypeId() == TYPEID_PLAYER)
|
if(GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
if(GetCharmGUID())
|
if(!AddUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
|
||||||
sLog.outError("Player %s is trying to charm unit %u, but he already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
sLog.outCrash("Player %s is trying to charm unit %u, but it already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||||
SetUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!charm->AddUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
||||||
|
sLog.outCrash("Unit %u is being charmed, but it already has a charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
|
||||||
|
|
||||||
m_Controlled.insert(charm);
|
m_Controlled.insert(charm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(GetTypeId() == TYPEID_PLAYER)
|
if(GetTypeId() == TYPEID_PLAYER)
|
||||||
SetUInt64Value(UNIT_FIELD_CHARM, 0);
|
{
|
||||||
|
if(!RemoveUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
|
||||||
|
sLog.outCrash("Player %s is trying to uncharm unit %u, but it has another charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!charm->RemoveUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
||||||
|
sLog.outCrash("Unit %u is being uncharmed, but it has another charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
|
||||||
|
|
||||||
m_Controlled.erase(charm);
|
m_Controlled.erase(charm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8400,9 +8409,9 @@ void Unit::RemoveAllControlled()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(GetPetGUID())
|
if(GetPetGUID())
|
||||||
sLog.outError("Unit %u is not able to release its summon %u", GetEntry(), GetPetGUID());
|
sLog.outCrash("Unit %u is not able to release its summon %u", GetEntry(), GetPetGUID());
|
||||||
if(GetCharmGUID())
|
if(GetCharmGUID())
|
||||||
sLog.outError("Unit %u is not able to release its charm %u", GetEntry(), GetCharmGUID());
|
sLog.outCrash("Unit %u is not able to release its charm %u", GetEntry(), GetCharmGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
|
Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
|
||||||
@@ -13080,18 +13089,23 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
|
|||||||
|
|
||||||
// Charmer stop charming
|
// Charmer stop charming
|
||||||
if(charmer->GetTypeId() == TYPEID_PLAYER)
|
if(charmer->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
((Player*)charmer)->StopCastingCharm();
|
((Player*)charmer)->StopCastingCharm();
|
||||||
|
((Player*)charmer)->StopCastingBindSight();
|
||||||
|
}
|
||||||
|
|
||||||
// Charmed stop charming
|
// Charmed stop charming
|
||||||
if(GetTypeId() == TYPEID_PLAYER)
|
if(GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
((Player*)this)->StopCastingCharm();
|
((Player*)this)->StopCastingCharm();
|
||||||
|
((Player*)this)->StopCastingBindSight();
|
||||||
|
}
|
||||||
|
|
||||||
// StopCastingCharm may remove a possessed pet?
|
// StopCastingCharm may remove a possessed pet?
|
||||||
if(!IsInWorld())
|
if(!IsInWorld())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Set charmed
|
// Set charmed
|
||||||
SetCharmerGUID(charmer->GetGUID());
|
|
||||||
setFaction(charmer->getFaction());
|
setFaction(charmer->getFaction());
|
||||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||||
charmer->SetCharm(this, true);
|
charmer->SetCharm(this, true);
|
||||||
@@ -13169,7 +13183,6 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
|
|||||||
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
|
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
|
||||||
getHostilRefManager().deleteReferences();
|
getHostilRefManager().deleteReferences();
|
||||||
DeleteThreatList();
|
DeleteThreatList();
|
||||||
SetCharmerGUID(0);
|
|
||||||
RestoreFaction();
|
RestoreFaction();
|
||||||
GetMotionMaster()->InitDefault();
|
GetMotionMaster()->InitDefault();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user