Core/Misc: Fix various crashes, also related to multithreading (#19012)

* When iterating groups we have to either do it not in multithreaded context (map updates) or start with checking maps (they are guaranteed to change in single thread update).
* Properly clear ComboPoint references on player remove 
* remove some possible references item may have when it is deleted during save. 
* Also clear all hostile references when unit is removed from map.
This commit is contained in:
xinef1 authored and Aokromes committed 2017-02-05 01:58:11 +01:00
1 parent a76da51e7f
commit 2c05a59815
20 files changed
+175 -126

No files matched your search

+8 -8
View File
@@ -8551,12 +8551,12 @@ Unit* Unit::GetNextRandomRaidMemberOrPet(float radius)
if (Player* Target = itr->GetSource())
{
// IsHostileTo check duel and controlled by enemy
if (Target != this && Target->IsAlive() && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target))
if (Target != this && IsWithinDistInMap(Target, radius) && Target->IsAlive() && !IsHostileTo(Target))
nearMembers.push_back(Target);
// Push player's pet to vector
if (Unit* pet = Target->GetGuardianPet())
if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
if (pet != this && IsWithinDistInMap(pet, radius) && pet->IsAlive() && !IsHostileTo(pet))
nearMembers.push_back(pet);
}
@@ -12245,7 +12245,7 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
CombatStop();
ClearComboPointHolders();
DeleteThreatList();
getHostileRefManager().setOnlineOfflineState(false);
getHostileRefManager().deleteReferences();
GetMotionMaster()->Clear(false); // remove different non-standard movement generators.
}
@@ -14918,23 +14918,23 @@ void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap)
Player* Target = itr->GetSource();
// IsHostileTo check duel and controlled by enemy
if (Target && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
if (Target && Target->IsInMap(owner) && Target->GetSubGroup() == subgroup && !IsHostileTo(Target))
{
if (Target->IsAlive() && IsInMap(Target))
if (Target->IsAlive())
TagUnitMap.push_back(Target);
if (Guardian* pet = Target->GetGuardianPet())
if (pet->IsAlive() && IsInMap(Target))
if (pet->IsAlive())
TagUnitMap.push_back(pet);
}
}
}
else
{
if (owner->IsAlive() && (owner == this || IsInMap(owner)))
if ((owner == this || IsInMap(owner)) && owner->IsAlive())
TagUnitMap.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
if (pet->IsAlive() && (pet == this || IsInMap(pet)))
if ((pet == this || IsInMap(pet)) && pet->IsAlive())
TagUnitMap.push_back(pet);
}
}