*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()
|
||||
{
|
||||
///- Register the creature for guid lookup
|
||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
||||
if(!IsInWorld())
|
||||
{
|
||||
ObjectAccessor::Instance().AddObject(this);
|
||||
Unit::AddToWorld();
|
||||
SearchFormation();
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the creature from the accessor
|
||||
if(IsInWorld())
|
||||
{
|
||||
if(m_formationID)
|
||||
formation_mgr.DestroyGroup(m_formationID, GetGUID());
|
||||
|
||||
///- Remove the creature from the accessor
|
||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
Unit::RemoveFromWorld();
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::SearchFormation()
|
||||
{
|
||||
|
||||
+14
-10
@@ -110,14 +110,15 @@ Deliverer::Visit(PlayerMapType &m)
|
||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||
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
|
||||
if (!iter->getSource()->GetSharedVisionList().empty())
|
||||
{
|
||||
SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
|
||||
for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
|
||||
SendPacket(*it);
|
||||
SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
|
||||
for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
|
||||
if((*i)->m_seer == iter->getSource())
|
||||
SendPacket(*i);
|
||||
}
|
||||
|
||||
VisitObject(iter->getSource());
|
||||
@@ -133,14 +134,15 @@ Deliverer::Visit(CreatureMapType &m)
|
||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||
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
|
||||
if (!iter->getSource()->GetSharedVisionList().empty())
|
||||
{
|
||||
SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin();
|
||||
for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it)
|
||||
SendPacket(*it);
|
||||
SharedVisionList::const_iterator i = iter->getSource()->GetSharedVisionList().begin();
|
||||
for ( ; i != iter->getSource()->GetSharedVisionList().end(); ++i)
|
||||
if((*i)->m_seer == iter->getSource())
|
||||
SendPacket(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,16 +156,18 @@ Deliverer::Visit(DynamicObjectMapType &m)
|
||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
||||
continue;
|
||||
|
||||
if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
|
||||
{
|
||||
if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
|
||||
{
|
||||
// Send packet back to the caster if the caster has vision of dynamic object
|
||||
Player* caster = (Player*)iter->getSource()->GetCaster();
|
||||
if (caster && caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() &&
|
||||
(!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist))
|
||||
if (caster && caster->m_seer == iter->getSource())
|
||||
SendPacket(caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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 )
|
||||
{
|
||||
ASSERT( index < m_valuesCount || PrintIndexError( index , true ) );
|
||||
|
||||
@@ -215,6 +215,9 @@ class TRINITY_DLL_SPEC Object
|
||||
void SetStatFloatValue( uint16 index, float 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 ApplyModInt32Value(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
|
||||
///- The player should only be removed when logging out
|
||||
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 )
|
||||
@@ -17038,7 +17047,7 @@ void Player::StopCastingCharm()
|
||||
|
||||
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
|
||||
{
|
||||
// Always can see self
|
||||
if (m_mover == u)
|
||||
if (m_mover == u || this == u)
|
||||
return true;
|
||||
|
||||
// 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());
|
||||
|
||||
StopCastingBindSight();
|
||||
if(GetUInt64Value(PLAYER_FARSIGHT))
|
||||
if(!AddUInt64Value(PLAYER_FARSIGHT, target->GetGUID()))
|
||||
{
|
||||
sLog.outError("Player::CreateViewpoint: Player %s cannot remove current viewpoint!", GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
SetUInt64Value(PLAYER_FARSIGHT, target->GetGUID());
|
||||
if(target->isType(TYPEMASK_UNIT))
|
||||
((Unit*)target)->AddPlayerToVision(this);
|
||||
}
|
||||
@@ -20205,11 +20213,12 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
||||
if(!veSeat)
|
||||
return;
|
||||
|
||||
vehicle->SetCharmerGUID(GetGUID());
|
||||
vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
vehicle->setFaction(getFaction());
|
||||
|
||||
StopCastingCharm();
|
||||
StopCastingBindSight();
|
||||
SetCharm(vehicle, true); // charm
|
||||
SetMover(vehicle);
|
||||
|
||||
@@ -20245,7 +20254,6 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
||||
|
||||
void Player::ExitVehicle(Vehicle *vehicle)
|
||||
{
|
||||
vehicle->SetCharmerGUID(0);
|
||||
vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
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)
|
||||
return false;
|
||||
// Remove aura mods
|
||||
Aur->ApplyModifier(false,true);
|
||||
Aur->ApplyModifier(false);
|
||||
Aur->GetModifier()->m_amount += spelldmg * triggerAmount / 100;
|
||||
// Apply extended aura mods
|
||||
Aur->ApplyModifier(true,true);
|
||||
Aur->ApplyModifier(true);
|
||||
break;
|
||||
}
|
||||
// Eye for an Eye
|
||||
@@ -8318,8 +8318,7 @@ void Unit::SetPet(Creature* pet, bool apply)
|
||||
{
|
||||
if(apply)
|
||||
{
|
||||
if(!GetPetGUID())
|
||||
SetUInt64Value(UNIT_FIELD_SUMMON, pet->GetGUID());
|
||||
AddUInt64Value(UNIT_FIELD_SUMMON, pet->GetGUID());
|
||||
m_Controlled.insert(pet);
|
||||
|
||||
// FIXME: hack, speed must be set only at follow
|
||||
@@ -8337,7 +8336,7 @@ void Unit::SetPet(Creature* pet, bool apply)
|
||||
{
|
||||
if((*itr)->GetOwnerGUID() == GetGUID())
|
||||
{
|
||||
SetUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID());
|
||||
AddUInt64Value(UNIT_FIELD_SUMMON, (*itr)->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -8350,16 +8349,26 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(GetCharmGUID())
|
||||
sLog.outError("Player %s is trying to charm unit %u, but he already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||
SetUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID());
|
||||
if(!AddUInt64Value(UNIT_FIELD_CHARM, charm->GetGUID()))
|
||||
sLog.outCrash("Player %s is trying to charm unit %u, but it already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -8400,9 +8409,9 @@ void Unit::RemoveAllControlled()
|
||||
}
|
||||
}
|
||||
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())
|
||||
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)
|
||||
@@ -13080,18 +13089,23 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
|
||||
|
||||
// Charmer stop charming
|
||||
if(charmer->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)charmer)->StopCastingCharm();
|
||||
((Player*)charmer)->StopCastingBindSight();
|
||||
}
|
||||
|
||||
// Charmed stop charming
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)this)->StopCastingCharm();
|
||||
((Player*)this)->StopCastingBindSight();
|
||||
}
|
||||
|
||||
// StopCastingCharm may remove a possessed pet?
|
||||
if(!IsInWorld())
|
||||
return;
|
||||
|
||||
// Set charmed
|
||||
SetCharmerGUID(charmer->GetGUID());
|
||||
setFaction(charmer->getFaction());
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
charmer->SetCharm(this, true);
|
||||
@@ -13169,7 +13183,6 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
|
||||
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
|
||||
getHostilRefManager().deleteReferences();
|
||||
DeleteThreatList();
|
||||
SetCharmerGUID(0);
|
||||
RestoreFaction();
|
||||
GetMotionMaster()->InitDefault();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user