Core/Misc: Fix various crashes, also related to multithreading
Port From (https://github.com/TrinityCore/TrinityCore/commit/ad008c43b75080ec59aa973f1e2e4424332c34a4)
This commit is contained in:
@@ -400,7 +400,8 @@ namespace Game.Entities
|
||||
{
|
||||
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
||||
if (group)
|
||||
group.EndRoll(loot);
|
||||
group.EndRoll(loot, GetMap());
|
||||
|
||||
m_groupLootTimer = 0;
|
||||
lootingGroupLowGUID.Clear();
|
||||
}
|
||||
|
||||
@@ -668,7 +668,7 @@ namespace Game.Entities
|
||||
{
|
||||
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
||||
if (group)
|
||||
group.EndRoll(loot);
|
||||
group.EndRoll(loot, GetMap());
|
||||
|
||||
m_groupLootTimer = 0;
|
||||
lootingGroupLowGUID.Clear();
|
||||
@@ -1396,7 +1396,7 @@ namespace Game.Entities
|
||||
|
||||
if (!slot.Value.IsEmpty())
|
||||
{
|
||||
Player ChairUser = Global.ObjAccessor.FindPlayer(slot.Value);
|
||||
Player ChairUser = Global.ObjAccessor.GetPlayer(this, slot.Value);
|
||||
if (ChairUser != null)
|
||||
if (ChairUser.IsSitState() && ChairUser.GetStandState() != UnitStandStateType.Sit && ChairUser.GetExactDist2d(x_i, y_i) < 0.1f)
|
||||
continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser.getStandState() != UNIT_STAND_STATE_SIT check is required.
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Game.Entities
|
||||
Player member = refe.GetSource();
|
||||
if (member)
|
||||
{
|
||||
if (member.IsAlive() && member.IsAtGroupRewardDistance(_victim))
|
||||
if (_killer == member || (member.IsAtGroupRewardDistance(_victim) && member.IsAlive()))
|
||||
{
|
||||
uint lvl = member.getLevel();
|
||||
// 2.1. _count - number of alive group members within reward distance;
|
||||
@@ -254,7 +254,8 @@ namespace Game.Entities
|
||||
Player member = refe.GetSource();
|
||||
if (member)
|
||||
{
|
||||
if (member.IsAtGroupRewardDistance(_victim))
|
||||
// Killer may not be at reward distance, check directly
|
||||
if (_killer == member || member.IsAtGroupRewardDistance(_victim))
|
||||
{
|
||||
_RewardPlayer(member, isDungeon);
|
||||
member.UpdateCriteria(CriteriaTypes.SpecialPvpKill, 1, 0, 0, _victim);
|
||||
|
||||
@@ -1525,6 +1525,10 @@ namespace Game.Entities
|
||||
stmt.AddValue(2, GetGUID().GetCounter());
|
||||
trans.Append(stmt);
|
||||
|
||||
RemoveTradeableItem(item);
|
||||
RemoveEnchantmentDurationsReferences(item);
|
||||
RemoveItemDurations(item);
|
||||
|
||||
// also THIS item should be somewhere else, cheat attempt
|
||||
item.FSetState(ItemUpdateState.Removed); // we are IN updateQueue right now, can't use SetState which modifies the queue
|
||||
DeleteRefundReference(item.GetGUID());
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Game.Entities
|
||||
|
||||
// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
|
||||
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.next())
|
||||
if (refe.GetSource() && refe.GetSource().IsInCombat())
|
||||
if (refe.GetSource() && refe.GetSource().IsInMap(this) && refe.GetSource().IsInCombat())
|
||||
return PartyResult.PartyLfgBootInCombat;
|
||||
|
||||
/* Missing support for these types
|
||||
@@ -192,15 +192,13 @@ namespace Game.Entities
|
||||
|
||||
public bool IsAtGroupRewardDistance(WorldObject pRewardSource)
|
||||
{
|
||||
if (!pRewardSource)
|
||||
if (!pRewardSource || !IsInMap(pRewardSource))
|
||||
return false;
|
||||
|
||||
WorldObject player = GetCorpse();
|
||||
if (!player || IsAlive())
|
||||
player = this;
|
||||
|
||||
if (player.GetMapId() != pRewardSource.GetMapId() || player.GetInstanceId() != pRewardSource.GetInstanceId())
|
||||
return false;
|
||||
|
||||
if (player.GetMap().IsDungeon())
|
||||
return true;
|
||||
|
||||
|
||||
@@ -967,6 +967,16 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveEnchantmentDurationsReferences(Item item)
|
||||
{
|
||||
foreach (var enchantDuration in m_enchantDuration)
|
||||
{
|
||||
if (enchantDuration.item == item)
|
||||
m_enchantDuration.Remove(enchantDuration);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveArenaEnchantments(EnchantmentSlot slot)
|
||||
{
|
||||
// remove enchantments from equipped items first to clean up the m_enchantDuration list
|
||||
@@ -1043,7 +1053,12 @@ namespace Game.Entities
|
||||
}
|
||||
// from spell cases (m_lastPotionId set in Spell.SendSpellCooldown)
|
||||
else
|
||||
GetSpellHistory().SendCooldownEvent(spell.m_spellInfo, m_lastPotionId, spell);
|
||||
{
|
||||
if (spell.IsIgnoringCooldowns())
|
||||
return;
|
||||
else
|
||||
GetSpellHistory().SendCooldownEvent(spell.m_spellInfo, m_lastPotionId, spell);
|
||||
}
|
||||
|
||||
m_lastPotionId = 0;
|
||||
}
|
||||
|
||||
@@ -862,6 +862,7 @@ namespace Game.Entities
|
||||
StopCastingCharm();
|
||||
StopCastingBindSight();
|
||||
UnsummonPetTemporaryIfAny();
|
||||
ClearComboPoints();
|
||||
Global.OutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
Global.BattleFieldMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
}
|
||||
@@ -7031,15 +7032,13 @@ namespace Game.Entities
|
||||
|
||||
bool IsAtRecruitAFriendDistance(WorldObject pOther)
|
||||
{
|
||||
if (!pOther)
|
||||
if (!pOther || !IsInMap(pOther))
|
||||
return false;
|
||||
|
||||
WorldObject player = GetCorpse();
|
||||
if (!player || IsAlive())
|
||||
player = this;
|
||||
|
||||
if (player.GetMapId() != pOther.GetMapId() || player.GetInstanceId() != pOther.GetInstanceId())
|
||||
return false;
|
||||
|
||||
return pOther.GetDistance(player) <= WorldConfig.GetFloatValue(WorldCfg.MaxRecruitAFriendDistance);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Game.Entities
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||
{
|
||||
Player target = refe.GetSource();
|
||||
if (target && group.SameSubGroup(owner, target))
|
||||
if (target && target.IsInMap(owner) && group.SameSubGroup(owner, target))
|
||||
target.RemoveAurasDueToSpell(GetSpell(), GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1741,17 +1741,17 @@ namespace Game.Entities
|
||||
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||
{
|
||||
Player Target = refe.GetSource();
|
||||
if (Target)
|
||||
Player target = refe.GetSource();
|
||||
if (target)
|
||||
{
|
||||
// IsHostileTo check duel and controlled by enemy
|
||||
if (Target != this && Target.IsAlive() && IsWithinDistInMap(Target, radius) && !IsHostileTo(Target))
|
||||
nearMembers.Add(Target);
|
||||
if (target != this && IsWithinDistInMap(target, radius) && target.IsAlive() && !IsHostileTo(target))
|
||||
nearMembers.Add(target);
|
||||
|
||||
// Push player's pet to vector
|
||||
Unit pet = Target.GetGuardianPet();
|
||||
Unit pet = target.GetGuardianPet();
|
||||
if (pet)
|
||||
if (pet != this && pet.IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet))
|
||||
if (pet != this && IsWithinDistInMap(pet, radius) && pet.IsAlive() && !IsHostileTo(pet))
|
||||
nearMembers.Add(pet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ namespace Game.Entities
|
||||
m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map.RemoveAllObjectsInRemoveList
|
||||
CombatStop();
|
||||
DeleteThreatList();
|
||||
getHostileRefManager().setOnlineOfflineState(false);
|
||||
getHostileRefManager().deleteReferences();
|
||||
GetMotionMaster().Clear(false); // remove different non-standard movement generators.
|
||||
}
|
||||
public override void CleanupsBeforeDelete(bool finalCleanup = true)
|
||||
|
||||
Reference in New Issue
Block a user