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())
|
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||||
{
|
{
|
||||||
Player Target = refe.GetSource();
|
Player target = refe.GetSource();
|
||||||
if (!Target || !group.SameSubGroup(owner.ToPlayer(), Target))
|
if (!target || !target.IsInMap(owner) || !group.SameSubGroup(owner.ToPlayer(), target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Target.GetGUID() == owner.GetGUID())
|
if (target.GetGUID() == owner.GetGUID())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_AllySet.Add(Target.GetGUID());
|
m_AllySet.Add(target.GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //remove group
|
else //remove group
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
Player member = groupRef.GetSource();
|
Player member = groupRef.GetSource();
|
||||||
if (member)
|
if (member)
|
||||||
member.FailQuest(m_pQuestForEscort.Id);
|
if (member.IsInMap(player))
|
||||||
|
member.FailQuest(m_pQuestForEscort.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
Player member = groupRef.GetSource();
|
Player member = groupRef.GetSource();
|
||||||
if (member)
|
if (member)
|
||||||
member.FailQuest(m_pQuestForFollow.Id);
|
if (member.IsInMap(player))
|
||||||
|
member.FailQuest(m_pQuestForFollow.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -343,8 +344,7 @@ namespace Game.AI
|
|||||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||||
{
|
{
|
||||||
Player member = groupRef.GetSource();
|
Player member = groupRef.GetSource();
|
||||||
|
if (member && me.IsWithinDistInMap(member, 100.0f) && member.IsAlive())
|
||||||
if (member && member.IsAlive() && me.IsWithinDistInMap(member, 100.0f))
|
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Scripts, "FollowerAI GetLeader changed and returned new leader.");
|
Log.outDebug(LogFilter.Scripts, "FollowerAI GetLeader changed and returned new leader.");
|
||||||
m_uiLeaderGUID = member.GetGUID();
|
m_uiLeaderGUID = member.GetGUID();
|
||||||
|
|||||||
@@ -249,6 +249,8 @@ namespace Game.AI
|
|||||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||||
{
|
{
|
||||||
Player groupGuy = groupRef.GetSource();
|
Player groupGuy = groupRef.GetSource();
|
||||||
|
if (!groupGuy.IsInMap(player))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!fail && groupGuy.IsAtGroupRewardDistance(me) && !groupGuy.GetCorpse())
|
if (!fail && groupGuy.IsAtGroupRewardDistance(me) && !groupGuy.GetCorpse())
|
||||||
groupGuy.AreaExploredOrEventHappens(mEscortQuestID);
|
groupGuy.AreaExploredOrEventHappens(mEscortQuestID);
|
||||||
@@ -402,8 +404,7 @@ namespace Game.AI
|
|||||||
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.next())
|
||||||
{
|
{
|
||||||
Player groupGuy = groupRef.GetSource();
|
Player groupGuy = groupRef.GetSource();
|
||||||
|
if (groupGuy.IsInMap(player) && me.GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
|
||||||
if (me.GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2614,7 +2614,8 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
Player member = groupRef.GetSource();
|
Player member = groupRef.GetSource();
|
||||||
if (member)
|
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
|
// 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();
|
Player recipient = refe.GetSource();
|
||||||
if (recipient)
|
if (recipient)
|
||||||
l.Add(recipient);
|
if (recipient.IsInMap(me))
|
||||||
|
l.Add(recipient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -239,6 +239,10 @@ namespace Game.Combat
|
|||||||
{
|
{
|
||||||
return threatContainer.empty();
|
return threatContainer.empty();
|
||||||
}
|
}
|
||||||
|
public bool areThreatListsEmpty()
|
||||||
|
{
|
||||||
|
return threatContainer.empty() && threatOfflineContainer.empty();
|
||||||
|
}
|
||||||
|
|
||||||
public HostileReference getCurrentVictim()
|
public HostileReference getCurrentVictim()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -400,7 +400,8 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
||||||
if (group)
|
if (group)
|
||||||
group.EndRoll(loot);
|
group.EndRoll(loot, GetMap());
|
||||||
|
|
||||||
m_groupLootTimer = 0;
|
m_groupLootTimer = 0;
|
||||||
lootingGroupLowGUID.Clear();
|
lootingGroupLowGUID.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -668,7 +668,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
Group group = Global.GroupMgr.GetGroupByGUID(lootingGroupLowGUID);
|
||||||
if (group)
|
if (group)
|
||||||
group.EndRoll(loot);
|
group.EndRoll(loot, GetMap());
|
||||||
|
|
||||||
m_groupLootTimer = 0;
|
m_groupLootTimer = 0;
|
||||||
lootingGroupLowGUID.Clear();
|
lootingGroupLowGUID.Clear();
|
||||||
@@ -1396,7 +1396,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (!slot.Value.IsEmpty())
|
if (!slot.Value.IsEmpty())
|
||||||
{
|
{
|
||||||
Player ChairUser = Global.ObjAccessor.FindPlayer(slot.Value);
|
Player ChairUser = Global.ObjAccessor.GetPlayer(this, slot.Value);
|
||||||
if (ChairUser != null)
|
if (ChairUser != null)
|
||||||
if (ChairUser.IsSitState() && ChairUser.GetStandState() != UnitStandStateType.Sit && ChairUser.GetExactDist2d(x_i, y_i) < 0.1f)
|
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.
|
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();
|
Player member = refe.GetSource();
|
||||||
if (member)
|
if (member)
|
||||||
{
|
{
|
||||||
if (member.IsAlive() && member.IsAtGroupRewardDistance(_victim))
|
if (_killer == member || (member.IsAtGroupRewardDistance(_victim) && member.IsAlive()))
|
||||||
{
|
{
|
||||||
uint lvl = member.getLevel();
|
uint lvl = member.getLevel();
|
||||||
// 2.1. _count - number of alive group members within reward distance;
|
// 2.1. _count - number of alive group members within reward distance;
|
||||||
@@ -254,7 +254,8 @@ namespace Game.Entities
|
|||||||
Player member = refe.GetSource();
|
Player member = refe.GetSource();
|
||||||
if (member)
|
if (member)
|
||||||
{
|
{
|
||||||
if (member.IsAtGroupRewardDistance(_victim))
|
// Killer may not be at reward distance, check directly
|
||||||
|
if (_killer == member || member.IsAtGroupRewardDistance(_victim))
|
||||||
{
|
{
|
||||||
_RewardPlayer(member, isDungeon);
|
_RewardPlayer(member, isDungeon);
|
||||||
member.UpdateCriteria(CriteriaTypes.SpecialPvpKill, 1, 0, 0, _victim);
|
member.UpdateCriteria(CriteriaTypes.SpecialPvpKill, 1, 0, 0, _victim);
|
||||||
|
|||||||
@@ -1525,6 +1525,10 @@ namespace Game.Entities
|
|||||||
stmt.AddValue(2, GetGUID().GetCounter());
|
stmt.AddValue(2, GetGUID().GetCounter());
|
||||||
trans.Append(stmt);
|
trans.Append(stmt);
|
||||||
|
|
||||||
|
RemoveTradeableItem(item);
|
||||||
|
RemoveEnchantmentDurationsReferences(item);
|
||||||
|
RemoveItemDurations(item);
|
||||||
|
|
||||||
// also THIS item should be somewhere else, cheat attempt
|
// 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
|
item.FSetState(ItemUpdateState.Removed); // we are IN updateQueue right now, can't use SetState which modifies the queue
|
||||||
DeleteRefundReference(item.GetGUID());
|
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.
|
// @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())
|
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;
|
return PartyResult.PartyLfgBootInCombat;
|
||||||
|
|
||||||
/* Missing support for these types
|
/* Missing support for these types
|
||||||
@@ -192,15 +192,13 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public bool IsAtGroupRewardDistance(WorldObject pRewardSource)
|
public bool IsAtGroupRewardDistance(WorldObject pRewardSource)
|
||||||
{
|
{
|
||||||
if (!pRewardSource)
|
if (!pRewardSource || !IsInMap(pRewardSource))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldObject player = GetCorpse();
|
WorldObject player = GetCorpse();
|
||||||
if (!player || IsAlive())
|
if (!player || IsAlive())
|
||||||
player = this;
|
player = this;
|
||||||
|
|
||||||
if (player.GetMapId() != pRewardSource.GetMapId() || player.GetInstanceId() != pRewardSource.GetInstanceId())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (player.GetMap().IsDungeon())
|
if (player.GetMap().IsDungeon())
|
||||||
return true;
|
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)
|
public void RemoveArenaEnchantments(EnchantmentSlot slot)
|
||||||
{
|
{
|
||||||
// remove enchantments from equipped items first to clean up the m_enchantDuration list
|
// 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)
|
// from spell cases (m_lastPotionId set in Spell.SendSpellCooldown)
|
||||||
else
|
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;
|
m_lastPotionId = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -862,6 +862,7 @@ namespace Game.Entities
|
|||||||
StopCastingCharm();
|
StopCastingCharm();
|
||||||
StopCastingBindSight();
|
StopCastingBindSight();
|
||||||
UnsummonPetTemporaryIfAny();
|
UnsummonPetTemporaryIfAny();
|
||||||
|
ClearComboPoints();
|
||||||
Global.OutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
Global.OutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||||
Global.BattleFieldMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
Global.BattleFieldMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||||
}
|
}
|
||||||
@@ -7031,15 +7032,13 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool IsAtRecruitAFriendDistance(WorldObject pOther)
|
bool IsAtRecruitAFriendDistance(WorldObject pOther)
|
||||||
{
|
{
|
||||||
if (!pOther)
|
if (!pOther || !IsInMap(pOther))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldObject player = GetCorpse();
|
WorldObject player = GetCorpse();
|
||||||
if (!player || IsAlive())
|
if (!player || IsAlive())
|
||||||
player = this;
|
player = this;
|
||||||
|
|
||||||
if (player.GetMapId() != pOther.GetMapId() || player.GetInstanceId() != pOther.GetInstanceId())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return pOther.GetDistance(player) <= WorldConfig.GetFloatValue(WorldCfg.MaxRecruitAFriendDistance);
|
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())
|
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||||
{
|
{
|
||||||
Player target = refe.GetSource();
|
Player target = refe.GetSource();
|
||||||
if (target && group.SameSubGroup(owner, target))
|
if (target && target.IsInMap(owner) && group.SameSubGroup(owner, target))
|
||||||
target.RemoveAurasDueToSpell(GetSpell(), GetGUID());
|
target.RemoveAurasDueToSpell(GetSpell(), GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1741,17 +1741,17 @@ namespace Game.Entities
|
|||||||
|
|
||||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||||
{
|
{
|
||||||
Player Target = refe.GetSource();
|
Player target = refe.GetSource();
|
||||||
if (Target)
|
if (target)
|
||||||
{
|
{
|
||||||
// IsHostileTo check duel and controlled by enemy
|
// 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.Add(Target);
|
nearMembers.Add(target);
|
||||||
|
|
||||||
// Push player's pet to vector
|
// Push player's pet to vector
|
||||||
Unit pet = Target.GetGuardianPet();
|
Unit pet = target.GetGuardianPet();
|
||||||
if (pet)
|
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);
|
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
|
m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map.RemoveAllObjectsInRemoveList
|
||||||
CombatStop();
|
CombatStop();
|
||||||
DeleteThreatList();
|
DeleteThreatList();
|
||||||
getHostileRefManager().setOnlineOfflineState(false);
|
getHostileRefManager().deleteReferences();
|
||||||
GetMotionMaster().Clear(false); // remove different non-standard movement generators.
|
GetMotionMaster().Clear(false); // remove different non-standard movement generators.
|
||||||
}
|
}
|
||||||
public override void CleanupsBeforeDelete(bool finalCleanup = true)
|
public override void CleanupsBeforeDelete(bool finalCleanup = true)
|
||||||
|
|||||||
+110
-80
@@ -560,7 +560,7 @@ namespace Game.Groups
|
|||||||
roll.playerVote.Remove(guid);
|
roll.playerVote.Remove(guid);
|
||||||
|
|
||||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
||||||
CountTheRoll(roll);
|
CountTheRoll(roll, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update subgroups
|
// Update subgroups
|
||||||
@@ -1110,21 +1110,21 @@ namespace Game.Groups
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
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)
|
foreach (var roll in RollId)
|
||||||
{
|
{
|
||||||
if (roll.getLoot() == pLoot)
|
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 ?
|
if (!roll.isValid()) // is loot already deleted ?
|
||||||
{
|
{
|
||||||
@@ -1138,13 +1138,21 @@ namespace Game.Groups
|
|||||||
if (!roll.playerVote.Empty())
|
if (!roll.playerVote.Empty())
|
||||||
{
|
{
|
||||||
byte maxresul = 0;
|
byte maxresul = 0;
|
||||||
ObjectGuid maxguid = roll.playerVote.First().Key;
|
ObjectGuid maxguid = ObjectGuid.Empty;
|
||||||
|
Player player = null;
|
||||||
|
|
||||||
foreach (var pair in roll.playerVote)
|
foreach (var pair in roll.playerVote)
|
||||||
{
|
{
|
||||||
if (pair.Value != RollType.Need)
|
if (pair.Value != RollType.Need)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
player = Global.ObjAccessor.FindPlayer(pair.Key);
|
||||||
|
if (!player || (allowedMap != null && player.GetMap() != allowedMap))
|
||||||
|
{
|
||||||
|
--roll.totalNeed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
byte randomN = (byte)RandomHelper.IRand(1, 100);
|
byte randomN = (byte)RandomHelper.IRand(1, 100);
|
||||||
SendLootRoll(pair.Key, randomN, RollType.Need, roll);
|
SendLootRoll(pair.Key, randomN, RollType.Need, roll);
|
||||||
if (maxresul < randomN)
|
if (maxresul < randomN)
|
||||||
@@ -1153,66 +1161,18 @@ namespace Game.Groups
|
|||||||
maxresul = randomN;
|
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>();
|
if (player && player.GetSession())
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
item.is_looted = true;
|
player.UpdateCriteria(CriteriaTypes.RollNeedOnLoot, roll.itemid, maxresul);
|
||||||
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;
|
|
||||||
|
|
||||||
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>();
|
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);
|
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||||
if (msg == InventoryResult.Ok)
|
if (msg == InventoryResult.Ok)
|
||||||
{
|
{
|
||||||
@@ -1228,37 +1188,107 @@ namespace Game.Groups
|
|||||||
player.SendEquipError(msg, null, null, roll.itemid);
|
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.totalGreed;
|
||||||
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
continue;
|
||||||
roll.getLoot().unlootedCount--;
|
}
|
||||||
player.UpdateCriteria(CriteriaTypes.CastSpell, 13262); // Disenchant
|
|
||||||
|
|
||||||
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>();
|
if (!maxguid.IsEmpty())
|
||||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
{
|
||||||
if (msg == InventoryResult.Ok)
|
SendLootRollWon(maxguid, maxresul, rollVote, roll);
|
||||||
player.AutoStoreLoot(disenchant.Id, LootStorage.Disenchant, true);
|
player = Global.ObjAccessor.FindConnectedPlayer(maxguid);
|
||||||
else // If the player's inventory is full, send the disenchant result in a mail.
|
|
||||||
|
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();
|
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||||
loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true);
|
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||||
|
if (msg == InventoryResult.Ok)
|
||||||
uint max_slot = loot.GetMaxSlotInLootFor(player);
|
|
||||||
for (uint i = 0; i < max_slot; ++i)
|
|
||||||
{
|
{
|
||||||
LootItem lootItem = loot.LootItemInSlot(i, player);
|
item.is_looted = true;
|
||||||
player.SendEquipError(msg, null, null, lootItem.itemid);
|
roll.getLoot().NotifyItemRemoved(roll.itemSlot);
|
||||||
player.SendItemRetrievalMail(lootItem.itemid, lootItem.count);
|
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);
|
SendLootAllPassed(roll);
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,8 @@ namespace Game.Loots
|
|||||||
{
|
{
|
||||||
Player player = refe.GetSource();
|
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
|
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)
|
for (byte i = 0; i < items.Count; ++i)
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ namespace Game.Maps
|
|||||||
creature.RemoveAllDynObjects();
|
creature.RemoveAllDynObjects();
|
||||||
creature.RemoveAllAreaTriggers();
|
creature.RemoveAllAreaTriggers();
|
||||||
|
|
||||||
if (creature.IsInCombat())
|
if (creature.IsInCombat() || !creature.GetThreatManager().areThreatListsEmpty())
|
||||||
{
|
{
|
||||||
creature.CombatStop();
|
creature.CombatStop();
|
||||||
creature.DeleteThreatList();
|
creature.DeleteThreatList();
|
||||||
|
|||||||
Reference in New Issue
Block a user