Core/Misc: Fix various crashes, also related to multithreading
Port From (https://github.com/TrinityCore/TrinityCore/commit/ad008c43b75080ec59aa973f1e2e4424332c34a4)
This commit is contained in:
@@ -271,14 +271,14 @@ namespace Game.AI
|
||||
{
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||
{
|
||||
Player Target = refe.GetSource();
|
||||
if (!Target || !group.SameSubGroup(owner.ToPlayer(), Target))
|
||||
Player target = refe.GetSource();
|
||||
if (!target || !target.IsInMap(owner) || !group.SameSubGroup(owner.ToPlayer(), target))
|
||||
continue;
|
||||
|
||||
if (Target.GetGUID() == owner.GetGUID())
|
||||
if (target.GetGUID() == owner.GetGUID())
|
||||
continue;
|
||||
|
||||
m_AllySet.Add(Target.GetGUID());
|
||||
m_AllySet.Add(target.GetGUID());
|
||||
}
|
||||
}
|
||||
else //remove group
|
||||
|
||||
@@ -115,7 +115,8 @@ namespace Game.AI
|
||||
{
|
||||
Player member = groupRef.GetSource();
|
||||
if (member)
|
||||
member.FailQuest(m_pQuestForEscort.Id);
|
||||
if (member.IsInMap(player))
|
||||
member.FailQuest(m_pQuestForEscort.Id);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -153,7 +153,8 @@ namespace Game.AI
|
||||
{
|
||||
Player member = groupRef.GetSource();
|
||||
if (member)
|
||||
member.FailQuest(m_pQuestForFollow.Id);
|
||||
if (member.IsInMap(player))
|
||||
member.FailQuest(m_pQuestForFollow.Id);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -343,8 +344,7 @@ namespace Game.AI
|
||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||
{
|
||||
Player member = groupRef.GetSource();
|
||||
|
||||
if (member && member.IsAlive() && me.IsWithinDistInMap(member, 100.0f))
|
||||
if (member && me.IsWithinDistInMap(member, 100.0f) && member.IsAlive())
|
||||
{
|
||||
Log.outDebug(LogFilter.Scripts, "FollowerAI GetLeader changed and returned new leader.");
|
||||
m_uiLeaderGUID = member.GetGUID();
|
||||
|
||||
@@ -249,6 +249,8 @@ namespace Game.AI
|
||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||
{
|
||||
Player groupGuy = groupRef.GetSource();
|
||||
if (!groupGuy.IsInMap(player))
|
||||
continue;
|
||||
|
||||
if (!fail && groupGuy.IsAtGroupRewardDistance(me) && !groupGuy.GetCorpse())
|
||||
groupGuy.AreaExploredOrEventHappens(mEscortQuestID);
|
||||
@@ -402,8 +404,7 @@ namespace Game.AI
|
||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||
{
|
||||
Player groupGuy = groupRef.GetSource();
|
||||
|
||||
if (me.GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
|
||||
if (groupGuy.IsInMap(player) && me.GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2614,7 +2614,8 @@ namespace Game.AI
|
||||
{
|
||||
Player member = groupRef.GetSource();
|
||||
if (member)
|
||||
l.Add(member);
|
||||
if (member.IsInMap(player))
|
||||
l.Add(member);
|
||||
}
|
||||
}
|
||||
// We still add the player to the list if there is no group. If we do
|
||||
@@ -2838,7 +2839,8 @@ namespace Game.AI
|
||||
{
|
||||
Player recipient = refe.GetSource();
|
||||
if (recipient)
|
||||
l.Add(recipient);
|
||||
if (recipient.IsInMap(me))
|
||||
l.Add(recipient);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -239,6 +239,10 @@ namespace Game.Combat
|
||||
{
|
||||
return threatContainer.empty();
|
||||
}
|
||||
public bool areThreatListsEmpty()
|
||||
{
|
||||
return threatContainer.empty() && threatOfflineContainer.empty();
|
||||
}
|
||||
|
||||
public HostileReference getCurrentVictim()
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
+110
-80
@@ -560,7 +560,7 @@ namespace Game.Groups
|
||||
roll.playerVote.Remove(guid);
|
||||
|
||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
||||
CountTheRoll(roll);
|
||||
CountTheRoll(roll, null);
|
||||
}
|
||||
|
||||
// Update subgroups
|
||||
@@ -1110,21 +1110,21 @@ namespace Game.Groups
|
||||
}
|
||||
|
||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
||||
CountTheRoll(roll);
|
||||
CountTheRoll(roll, null);
|
||||
}
|
||||
|
||||
public void EndRoll(Loot pLoot)
|
||||
public void EndRoll(Loot pLoot, Map allowedMap)
|
||||
{
|
||||
foreach (var roll in RollId)
|
||||
{
|
||||
if (roll.getLoot() == pLoot)
|
||||
{
|
||||
CountTheRoll(roll); //i don't have to edit player votes, who didn't vote ... he will pass
|
||||
CountTheRoll(roll, allowedMap); //i don't have to edit player votes, who didn't vote ... he will pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CountTheRoll(Roll roll)
|
||||
void CountTheRoll(Roll roll, Map allowedMap)
|
||||
{
|
||||
if (!roll.isValid()) // is loot already deleted ?
|
||||
{
|
||||
@@ -1138,13 +1138,21 @@ namespace Game.Groups
|
||||
if (!roll.playerVote.Empty())
|
||||
{
|
||||
byte maxresul = 0;
|
||||
ObjectGuid maxguid = roll.playerVote.First().Key;
|
||||
ObjectGuid maxguid = ObjectGuid.Empty;
|
||||
Player player = null;
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
if (pair.Value != RollType.Need)
|
||||
continue;
|
||||
|
||||
player = Global.ObjAccessor.FindPlayer(pair.Key);
|
||||
if (!player || (allowedMap != null && player.GetMap() != allowedMap))
|
||||
{
|
||||
--roll.totalNeed;
|
||||
continue;
|
||||
}
|
||||
|
||||
byte randomN = (byte)RandomHelper.IRand(1, 100);
|
||||
SendLootRoll(pair.Key, randomN, RollType.Need, roll);
|
||||
if (maxresul < randomN)
|
||||
@@ -1153,66 +1161,18 @@ namespace Game.Groups
|
||||
maxresul = randomN;
|
||||
}
|
||||
}
|
||||
SendLootRollWon(maxguid, maxresul, RollType.Need, roll);
|
||||
Player player = Global.ObjAccessor.FindPlayer(maxguid);
|
||||
|
||||
if (player && player.GetSession() != null)
|
||||
if (!maxguid.IsEmpty())
|
||||
{
|
||||
player.UpdateCriteria(CriteriaTypes.RollNeedOnLoot, roll.itemid, maxresul);
|
||||
SendLootRollWon(maxguid, maxresul, RollType.Need, roll);
|
||||
player = Global.ObjAccessor.FindConnectedPlayer(maxguid);
|
||||
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
LootItem item = (roll.itemSlot >= roll.getLoot().items.Count ? roll.getLoot().quest_items[roll.itemSlot - roll.getLoot().items.Count] : roll.getLoot().items[roll.itemSlot]);
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
if (player && player.GetSession())
|
||||
{
|
||||
item.is_looted = true;
|
||||
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
||||
roll.getLoot().unlootedCount--;
|
||||
player.StoreNewItem(dest, roll.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.is_blocked = false;
|
||||
item.rollWinnerGUID = player.GetGUID();
|
||||
player.SendEquipError(msg, null, null, roll.itemid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (roll.totalGreed > 0)
|
||||
{
|
||||
if (!roll.playerVote.Empty())
|
||||
{
|
||||
byte maxresul = 0;
|
||||
ObjectGuid maxguid = roll.playerVote.First().Key;
|
||||
RollType rollVote = RollType.NotValid;
|
||||
player.UpdateCriteria(CriteriaTypes.RollNeedOnLoot, roll.itemid, maxresul);
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
if (pair.Value != RollType.Greed && pair.Value != RollType.Disenchant)
|
||||
continue;
|
||||
|
||||
byte randomN = (byte)RandomHelper.IRand(1, 100);
|
||||
SendLootRoll(pair.Key, randomN, pair.Value, roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
maxguid = pair.Key;
|
||||
maxresul = randomN;
|
||||
rollVote = pair.Value;
|
||||
}
|
||||
}
|
||||
SendLootRollWon(maxguid, maxresul, rollVote, roll);
|
||||
Player player = Global.ObjAccessor.FindPlayer(maxguid);
|
||||
|
||||
if (player && player.GetSession() != null)
|
||||
{
|
||||
player.UpdateCriteria(CriteriaTypes.RollGreedOnLoot, roll.itemid, maxresul);
|
||||
|
||||
LootItem item = roll.itemSlot >= roll.getLoot().items.Count ? roll.getLoot().quest_items[roll.itemSlot - roll.getLoot().items.Count] : roll.getLoot().items[roll.itemSlot];
|
||||
|
||||
if (rollVote == RollType.Greed)
|
||||
{
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
LootItem item = (roll.itemSlot >= roll.getLoot().items.Count ? roll.getLoot().quest_items[roll.itemSlot - roll.getLoot().items.Count] : roll.getLoot().items[roll.itemSlot]);
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
@@ -1228,37 +1188,107 @@ namespace Game.Groups
|
||||
player.SendEquipError(msg, null, null, roll.itemid);
|
||||
}
|
||||
}
|
||||
else if (rollVote == RollType.Disenchant)
|
||||
}
|
||||
else
|
||||
roll.totalNeed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (roll.totalNeed == 0 && roll.totalGreed > 0) // if (roll->totalNeed == 0 && ...), not else if, because numbers can be modified above if player is on a different map
|
||||
{
|
||||
if (!roll.playerVote.Empty())
|
||||
{
|
||||
byte maxresul = 0;
|
||||
ObjectGuid maxguid = ObjectGuid.Empty;
|
||||
Player player = null;
|
||||
RollType rollVote = RollType.NotValid;
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
if (pair.Value != RollType.Greed && pair.Value != RollType.Disenchant)
|
||||
continue;
|
||||
|
||||
player = Global.ObjAccessor.FindPlayer(pair.Key);
|
||||
if (!player || (allowedMap != null && player.GetMap() != allowedMap))
|
||||
{
|
||||
item.is_looted = true;
|
||||
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
||||
roll.getLoot().unlootedCount--;
|
||||
player.UpdateCriteria(CriteriaTypes.CastSpell, 13262); // Disenchant
|
||||
--roll.totalGreed;
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemDisenchantLootRecord disenchant = roll.GetItemDisenchantLoot(player);
|
||||
byte randomN = (byte)RandomHelper.IRand(1, 100);
|
||||
SendLootRoll(pair.Key, randomN, pair.Value, roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
maxguid = pair.Key;
|
||||
maxresul = randomN;
|
||||
rollVote = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
player.AutoStoreLoot(disenchant.Id, LootStorage.Disenchant, true);
|
||||
else // If the player's inventory is full, send the disenchant result in a mail.
|
||||
if (!maxguid.IsEmpty())
|
||||
{
|
||||
SendLootRollWon(maxguid, maxresul, rollVote, roll);
|
||||
player = Global.ObjAccessor.FindConnectedPlayer(maxguid);
|
||||
|
||||
if (player && player.GetSession() != null)
|
||||
{
|
||||
player.UpdateCriteria(CriteriaTypes.RollGreedOnLoot, roll.itemid, maxresul);
|
||||
|
||||
LootItem item = roll.itemSlot >= roll.getLoot().items.Count ? roll.getLoot().quest_items[roll.itemSlot - roll.getLoot().items.Count] : roll.getLoot().items[roll.itemSlot];
|
||||
|
||||
if (rollVote == RollType.Greed)
|
||||
{
|
||||
Loot loot = new Loot();
|
||||
loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true);
|
||||
|
||||
uint max_slot = loot.GetMaxSlotInLootFor(player);
|
||||
for (uint i = 0; i < max_slot; ++i)
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
LootItem lootItem = loot.LootItemInSlot(i, player);
|
||||
player.SendEquipError(msg, null, null, lootItem.itemid);
|
||||
player.SendItemRetrievalMail(lootItem.itemid, lootItem.count);
|
||||
item.is_looted = true;
|
||||
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
||||
roll.getLoot().unlootedCount--;
|
||||
player.StoreNewItem(dest, roll.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.is_blocked = false;
|
||||
item.rollWinnerGUID = player.GetGUID();
|
||||
player.SendEquipError(msg, null, null, roll.itemid);
|
||||
}
|
||||
}
|
||||
else if (rollVote == RollType.Disenchant)
|
||||
{
|
||||
item.is_looted = true;
|
||||
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
||||
roll.getLoot().unlootedCount--;
|
||||
player.UpdateCriteria(CriteriaTypes.CastSpell, 13262); // Disenchant
|
||||
|
||||
ItemDisenchantLootRecord disenchant = roll.GetItemDisenchantLoot(player);
|
||||
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
player.AutoStoreLoot(disenchant.Id, LootStorage.Disenchant, true);
|
||||
else // If the player's inventory is full, send the disenchant result in a mail.
|
||||
{
|
||||
Loot loot = new Loot();
|
||||
loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true);
|
||||
|
||||
uint max_slot = loot.GetMaxSlotInLootFor(player);
|
||||
for (uint i = 0; i < max_slot; ++i)
|
||||
{
|
||||
LootItem lootItem = loot.LootItemInSlot(i, player);
|
||||
player.SendEquipError(msg, null, null, lootItem.itemid);
|
||||
player.SendItemRetrievalMail(lootItem.itemid, lootItem.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
roll.totalGreed = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (roll.totalNeed == 0 && roll.totalGreed == 0) // if, not else, because numbers can be modified above if player is on a different map
|
||||
{
|
||||
SendLootAllPassed(roll);
|
||||
|
||||
|
||||
@@ -228,7 +228,8 @@ namespace Game.Loots
|
||||
{
|
||||
Player player = refe.GetSource();
|
||||
if (player) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
|
||||
FillNotNormalLootFor(player, player.IsAtGroupRewardDistance(lootOwner));
|
||||
if (player.IsInMap(lootOwner))
|
||||
FillNotNormalLootFor(player, player.IsAtGroupRewardDistance(lootOwner));
|
||||
}
|
||||
|
||||
for (byte i = 0; i < items.Count; ++i)
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace Game.Maps
|
||||
creature.RemoveAllDynObjects();
|
||||
creature.RemoveAllAreaTriggers();
|
||||
|
||||
if (creature.IsInCombat())
|
||||
if (creature.IsInCombat() || !creature.GetThreatManager().areThreatListsEmpty())
|
||||
{
|
||||
creature.CombatStop();
|
||||
creature.DeleteThreatList();
|
||||
|
||||
Reference in New Issue
Block a user