aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-03-23 20:13:37 -0600
committermegamage <none@none>2009-03-23 20:13:37 -0600
commitf18a9c916d23c96c013f702aaec6b2c539ceb273 (patch)
tree9e1858c39f31538d2fa0c101d4b3911c811e822a
parentdcb08352e7420b6a1277dfa5de359d2f19651cd9 (diff)
*Fix some crashes possibly related to vehicles.
*Fix a bug that client crashes when seer is far away from caster. --HG-- branch : trunk
-rw-r--r--src/game/Creature.cpp21
-rw-r--r--src/game/GridNotifiers.cpp32
-rw-r--r--src/game/Object.cpp42
-rw-r--r--src/game/Object.h3
-rw-r--r--src/game/Player.cpp20
-rw-r--r--src/game/Unit.cpp39
6 files changed, 116 insertions, 41 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index edf32d19cf2..a2dc9a4d41a 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -166,19 +166,24 @@ Creature::~Creature()
void Creature::AddToWorld()
{
///- Register the creature for guid lookup
- if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
- Unit::AddToWorld();
- SearchFormation();
+ if(!IsInWorld())
+ {
+ ObjectAccessor::Instance().AddObject(this);
+ Unit::AddToWorld();
+ SearchFormation();
+ }
}
void Creature::RemoveFromWorld()
{
- if(m_formationID)
- formation_mgr.DestroyGroup(m_formationID, GetGUID());
-
///- Remove the creature from the accessor
- if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
- Unit::RemoveFromWorld();
+ if(IsInWorld())
+ {
+ if(m_formationID)
+ formation_mgr.DestroyGroup(m_formationID, GetGUID());
+ ObjectAccessor::Instance().RemoveObject(this);
+ Unit::RemoveFromWorld();
+ }
}
void Creature::SearchFormation()
diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp
index 86f4be9adc6..a244e950dad 100644
--- a/src/game/GridNotifiers.cpp
+++ b/src/game/GridNotifiers.cpp
@@ -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,13 +156,15 @@ Deliverer::Visit(DynamicObjectMapType &m)
if(!iter->getSource()->InSamePhase(i_phaseMask))
continue;
- if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID()))
+ if (!i_dist || iter->getSource()->GetDistance(&i_source) < i_dist)
{
- // 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))
- SendPacket(caster);
+ 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->m_seer == iter->getSource())
+ SendPacket(caster);
+ }
}
}
}
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index b17f905b7dd..d84e2b7c07e 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -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 ) );
diff --git a/src/game/Object.h b/src/game/Object.h
index b42fb9c4be7..f40b05f351b 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -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);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 364fea07cce..49ba06eb6db 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -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);
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 4d79049cb5e..1850f9f1eeb 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -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();