*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:
megamage
2009-03-23 20:13:37 -06:00
parent dcb08352e7
commit f18a9c916d
6 changed files with 116 additions and 41 deletions
+9 -4
View File
@@ -166,19 +166,24 @@ 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
View File
@@ -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,15 +156,17 @@ 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
+42
View File
@@ -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 ) );
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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();