diff options
author | megamage <none@none> | 2009-03-23 20:13:37 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-03-23 20:13:37 -0600 |
commit | f18a9c916d23c96c013f702aaec6b2c539ceb273 (patch) | |
tree | 9e1858c39f31538d2fa0c101d4b3911c811e822a /src | |
parent | dcb08352e7420b6a1277dfa5de359d2f19651cd9 (diff) |
*Fix some crashes possibly related to vehicles.
*Fix a bug that client crashes when seer is far away from caster.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Creature.cpp | 21 | ||||
-rw-r--r-- | src/game/GridNotifiers.cpp | 32 | ||||
-rw-r--r-- | src/game/Object.cpp | 42 | ||||
-rw-r--r-- | src/game/Object.h | 3 | ||||
-rw-r--r-- | src/game/Player.cpp | 20 | ||||
-rw-r--r-- | src/game/Unit.cpp | 39 |
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(); |