Core/Loot: Move loot rolls from Group to Loot
Port From (https://github.com/TrinityCore/TrinityCore/commit/3ef5079feeedfdafc9d3c1d9f865e96dbc77ecc8)
This commit is contained in:
+1
-661
@@ -532,9 +532,6 @@ namespace Game.Groups
|
||||
}
|
||||
}
|
||||
|
||||
if (m_maxEnchantingLevel < player.GetSkillValue(SkillType.Enchanting))
|
||||
m_maxEnchantingLevel = player.GetSkillValue(SkillType.Enchanting);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -603,33 +600,6 @@ namespace Game.Groups
|
||||
DelinkMember(guid);
|
||||
}
|
||||
|
||||
// Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
|
||||
if (!player || player.GetSkillValue(SkillType.Enchanting) != 0)
|
||||
ResetMaxEnchantingLevel();
|
||||
|
||||
// Remove player from loot rolls
|
||||
foreach (var roll in RollId)
|
||||
{
|
||||
if (!roll.playerVote.ContainsKey(guid))
|
||||
continue;
|
||||
|
||||
var vote = roll.playerVote[guid];
|
||||
if (vote == RollType.Greed || vote == RollType.Disenchant)
|
||||
--roll.totalGreed;
|
||||
else if (vote == RollType.Need)
|
||||
--roll.totalNeed;
|
||||
else if (vote == RollType.Pass)
|
||||
--roll.totalPass;
|
||||
|
||||
if (vote != RollType.NotValid)
|
||||
--roll.totalPlayersRolling;
|
||||
|
||||
roll.playerVote.Remove(guid);
|
||||
|
||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
||||
CountTheRoll(roll, null);
|
||||
}
|
||||
|
||||
// Update subgroups
|
||||
var slot = _getMemberSlot(guid);
|
||||
if (slot != null)
|
||||
@@ -829,7 +799,7 @@ namespace Game.Groups
|
||||
|
||||
_homebindIfInstance(player);
|
||||
}
|
||||
RollId.Clear();
|
||||
|
||||
m_memberSlots.Clear();
|
||||
|
||||
RemoveAllInvites();
|
||||
@@ -862,541 +832,6 @@ namespace Game.Groups
|
||||
Global.GroupMgr.RemoveGroup(this);
|
||||
}
|
||||
|
||||
void SendLootStartRollToPlayer(uint countDown, uint mapId, Player p, bool canNeed, Roll r)
|
||||
{
|
||||
StartLootRoll startLootRoll = new();
|
||||
startLootRoll.LootObj = r.GetTarget().GetGUID();
|
||||
startLootRoll.MapID = (int)mapId;
|
||||
startLootRoll.RollTime = countDown;
|
||||
startLootRoll.ValidRolls = r.rollTypeMask;
|
||||
if (!canNeed)
|
||||
startLootRoll.ValidRolls &= ~RollMask.Need;
|
||||
startLootRoll.Method = GetLootMethod();
|
||||
r.FillPacket(startLootRoll.Item);
|
||||
|
||||
ItemDisenchantLootRecord disenchant = r.GetItemDisenchantLoot(p);
|
||||
if (disenchant != null)
|
||||
if (m_maxEnchantingLevel >= disenchant.SkillRequired)
|
||||
startLootRoll.ValidRolls |= RollMask.Disenchant;
|
||||
|
||||
p.SendPacket(startLootRoll);
|
||||
}
|
||||
|
||||
void SendLootRoll(ObjectGuid playerGuid, int rollNumber, RollType rollType, Roll roll, bool autoPass = false)
|
||||
{
|
||||
LootRollBroadcast lootRoll = new();
|
||||
lootRoll.LootObj = roll.GetTarget().GetGUID();
|
||||
lootRoll.Player = playerGuid;
|
||||
lootRoll.Roll = rollNumber;
|
||||
lootRoll.RollType = rollType;
|
||||
lootRoll.Autopassed = autoPass;
|
||||
roll.FillPacket(lootRoll.Item);
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
Player p = Global.ObjAccessor.FindConnectedPlayer(pair.Key);
|
||||
if (!p || !p.GetSession())
|
||||
continue;
|
||||
|
||||
if (pair.Value != RollType.NotValid)
|
||||
p.SendPacket(lootRoll);
|
||||
}
|
||||
}
|
||||
|
||||
void SendLootRollWon(ObjectGuid winnerGuid, int rollNumber, RollType rollType, Roll roll)
|
||||
{
|
||||
LootRollWon lootRollWon = new();
|
||||
lootRollWon.LootObj = roll.GetTarget().GetGUID();
|
||||
lootRollWon.Winner = winnerGuid;
|
||||
lootRollWon.Roll = rollNumber;
|
||||
lootRollWon.RollType = rollType;
|
||||
roll.FillPacket(lootRollWon.Item);
|
||||
lootRollWon.MainSpec = true; // offspec rolls not implemented
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
Player p = Global.ObjAccessor.FindConnectedPlayer(pair.Key);
|
||||
if (!p || !p.GetSession())
|
||||
continue;
|
||||
|
||||
if (pair.Value != RollType.NotValid)
|
||||
p.SendPacket(lootRollWon);
|
||||
}
|
||||
}
|
||||
|
||||
void SendLootAllPassed(Roll roll)
|
||||
{
|
||||
LootAllPassed lootAllPassed = new();
|
||||
lootAllPassed.LootObj = roll.GetTarget().GetGUID();
|
||||
roll.FillPacket(lootAllPassed.Item);
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
Player player = Global.ObjAccessor.FindConnectedPlayer(pair.Key);
|
||||
if (!player || !player.GetSession())
|
||||
continue;
|
||||
|
||||
if (pair.Value != RollType.NotValid)
|
||||
player.SendPacket(lootAllPassed);
|
||||
}
|
||||
}
|
||||
|
||||
void SendLootRollsComplete(Roll roll)
|
||||
{
|
||||
LootRollsComplete lootRollsComplete = new();
|
||||
lootRollsComplete.LootObj = roll.GetTarget().GetGUID();
|
||||
lootRollsComplete.LootListID = (byte)(roll.itemSlot + 1);
|
||||
|
||||
foreach (var pair in roll.playerVote)
|
||||
{
|
||||
Player player = Global.ObjAccessor.FindConnectedPlayer(pair.Key);
|
||||
if (!player || !player.GetSession())
|
||||
continue;
|
||||
|
||||
if (pair.Value != RollType.NotValid)
|
||||
player.SendPacket(lootRollsComplete);
|
||||
}
|
||||
}
|
||||
|
||||
// notify group members which player is the allowed looter for the given creature
|
||||
public void SendLooter(Creature creature, Player groupLooter)
|
||||
{
|
||||
Cypher.Assert(creature);
|
||||
|
||||
LootList lootList = new();
|
||||
lootList.Owner = creature.GetGUID();
|
||||
lootList.LootObj = creature.loot.GetGUID();
|
||||
|
||||
if (creature.loot.GetLootMethod() == LootMethod.MasterLoot && creature.loot.HasOverThresholdItem())
|
||||
lootList.Master = GetMasterLooterGuid();
|
||||
|
||||
if (groupLooter)
|
||||
lootList.RoundRobinWinner = groupLooter.GetGUID();
|
||||
|
||||
BroadcastPacket(lootList, false);
|
||||
}
|
||||
|
||||
public bool CanRollOnItem(LootItem item, Player player)
|
||||
{
|
||||
// Players can't roll on unique items if they already reached the maximum quantity of that item
|
||||
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
|
||||
if (proto == null)
|
||||
return false;
|
||||
|
||||
uint itemCount = player.GetItemCount(item.itemid);
|
||||
if (proto.GetMaxCount() > 0 && itemCount >= proto.GetMaxCount())
|
||||
return false;
|
||||
|
||||
if (!item.AllowedForPlayer(player))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GroupLoot(Loot loot, WorldObject lootedObject)
|
||||
{
|
||||
byte itemSlot = 0;
|
||||
for (var i = 0; i < loot.items.Count; ++i, ++itemSlot)
|
||||
{
|
||||
LootItem lootItem = loot.items[i];
|
||||
if (lootItem.freeforall)
|
||||
continue;
|
||||
|
||||
ItemTemplate item = Global.ObjectMgr.GetItemTemplate(lootItem.itemid);
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
//roll for over-threshold item if it's one-player loot
|
||||
if (item.GetQuality() >= m_lootThreshold)
|
||||
{
|
||||
Roll r = new(lootItem);
|
||||
|
||||
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next())
|
||||
{
|
||||
Player playerToRoll = refe.GetSource();
|
||||
if (!playerToRoll || playerToRoll.GetSession() == null)
|
||||
continue;
|
||||
|
||||
if (playerToRoll.IsAtGroupRewardDistance(lootedObject))
|
||||
{
|
||||
r.totalPlayersRolling++;
|
||||
RollType vote = playerToRoll.GetPassOnGroupLoot() ? RollType.Pass : RollType.NotEmitedYet;
|
||||
if (!CanRollOnItem(lootItem, playerToRoll))
|
||||
{
|
||||
vote = RollType.Pass;
|
||||
r.totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
|
||||
}
|
||||
|
||||
r.playerVote[playerToRoll.GetGUID()] = vote;
|
||||
}
|
||||
}
|
||||
|
||||
if (r.totalPlayersRolling > 0)
|
||||
{
|
||||
r.SetLoot(loot);
|
||||
r.itemSlot = itemSlot;
|
||||
|
||||
if (item.HasFlag(ItemFlags2.CanOnlyRollGreed))
|
||||
r.rollTypeMask &= ~RollMask.Need;
|
||||
|
||||
loot.items[itemSlot].is_blocked = true;
|
||||
|
||||
//Broadcast Pass and Send Rollstart
|
||||
foreach (var pair in r.playerVote)
|
||||
{
|
||||
Player p = Global.ObjAccessor.FindPlayer(pair.Key);
|
||||
if (!p || p.GetSession() == null)
|
||||
continue;
|
||||
|
||||
if (pair.Value == RollType.Pass)
|
||||
SendLootRoll(p.GetGUID(), -1, RollType.Pass, r, true);
|
||||
else
|
||||
SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r);
|
||||
}
|
||||
|
||||
RollId.Add(r);
|
||||
Creature creature = lootedObject.ToCreature();
|
||||
GameObject go = lootedObject.ToGameObject();
|
||||
if (creature)
|
||||
{
|
||||
creature.m_groupLootTimer = 60000;
|
||||
creature.lootingGroupLowGUID = GetGUID();
|
||||
}
|
||||
else if (go)
|
||||
{
|
||||
go.m_groupLootTimer = 60000;
|
||||
go.lootingGroupLowGUID = GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
lootItem.is_underthreshold = true;
|
||||
}
|
||||
|
||||
foreach (var i in loot.quest_items)
|
||||
{
|
||||
if (!i.follow_loot_rules)
|
||||
continue;
|
||||
|
||||
ItemTemplate item = Global.ObjectMgr.GetItemTemplate(i.itemid);
|
||||
Roll r = new(i);
|
||||
|
||||
for (var refe = GetFirstMember(); refe != null; refe = refe.Next())
|
||||
{
|
||||
Player playerToRoll = refe.GetSource();
|
||||
if (!playerToRoll || playerToRoll.GetSession() == null)
|
||||
continue;
|
||||
|
||||
if (playerToRoll.IsAtGroupRewardDistance(lootedObject))
|
||||
{
|
||||
r.totalPlayersRolling++;
|
||||
RollType vote = RollType.NotEmitedYet;
|
||||
if (!CanRollOnItem(i, playerToRoll))
|
||||
{
|
||||
vote = RollType.Pass;
|
||||
++r.totalPass;
|
||||
}
|
||||
r.playerVote[playerToRoll.GetGUID()] = vote;
|
||||
}
|
||||
}
|
||||
|
||||
if (r.totalPlayersRolling > 0)
|
||||
{
|
||||
r.SetLoot(loot);
|
||||
r.itemSlot = itemSlot;
|
||||
|
||||
loot.quest_items[itemSlot - loot.items.Count].is_blocked = true;
|
||||
|
||||
//Broadcast Pass and Send Rollstart
|
||||
foreach (var pair in r.playerVote)
|
||||
{
|
||||
Player p = Global.ObjAccessor.FindPlayer(pair.Key);
|
||||
if (!p || p.GetSession() == null)
|
||||
continue;
|
||||
|
||||
if (pair.Value == RollType.Pass)
|
||||
SendLootRoll(p.GetGUID(), -1, RollType.Pass, r, true);
|
||||
else
|
||||
SendLootStartRollToPlayer(60000, lootedObject.GetMapId(), p, p.CanRollForItemInLFG(item, lootedObject) == InventoryResult.Ok, r);
|
||||
}
|
||||
|
||||
RollId.Add(r);
|
||||
|
||||
Creature creature = lootedObject.ToCreature();
|
||||
GameObject go = lootedObject.ToGameObject();
|
||||
if (creature)
|
||||
{
|
||||
creature.m_groupLootTimer = 60000;
|
||||
creature.lootingGroupLowGUID = GetGUID();
|
||||
}
|
||||
else if (go)
|
||||
{
|
||||
go.m_groupLootTimer = 60000;
|
||||
go.lootingGroupLowGUID = GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void MasterLoot(Loot loot, WorldObject pLootedObject)
|
||||
{
|
||||
MasterLootCandidateList masterLootCandidateList = new();
|
||||
masterLootCandidateList.LootObj = loot.GetGUID();
|
||||
|
||||
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next())
|
||||
{
|
||||
Player looter = refe.GetSource();
|
||||
if (!looter.IsInWorld)
|
||||
continue;
|
||||
|
||||
if (looter.IsAtGroupRewardDistance(pLootedObject))
|
||||
masterLootCandidateList.Players.Add(looter.GetGUID());
|
||||
}
|
||||
|
||||
masterLootCandidateList.Write();
|
||||
|
||||
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next())
|
||||
{
|
||||
Player looter = refe.GetSource();
|
||||
if (looter.IsAtGroupRewardDistance(pLootedObject))
|
||||
looter.SendPacket(masterLootCandidateList);
|
||||
}
|
||||
}
|
||||
|
||||
public void CountRollVote(ObjectGuid playerGuid, ObjectGuid lootObjectGuid, byte lootListId, RollType choice)
|
||||
{
|
||||
var roll = GetRoll(lootObjectGuid, lootListId);
|
||||
if (roll == null)
|
||||
return;
|
||||
|
||||
// this condition means that player joins to the party after roll begins
|
||||
if (!roll.playerVote.ContainsKey(playerGuid))
|
||||
return;
|
||||
|
||||
if (roll.GetLoot() != null)
|
||||
if (roll.GetLoot().items.Empty())
|
||||
return;
|
||||
|
||||
RollType rollType = RollType.MaxTypes;
|
||||
switch (choice)
|
||||
{
|
||||
case RollType.Pass: // Player choose pass
|
||||
SendLootRoll(playerGuid, -1, RollType.Pass, roll);
|
||||
++roll.totalPass;
|
||||
rollType = RollType.Pass;
|
||||
break;
|
||||
case RollType.Need: // player choose Need
|
||||
SendLootRoll(playerGuid, 0, RollType.Need, roll);
|
||||
++roll.totalNeed;
|
||||
rollType = RollType.Need;
|
||||
break;
|
||||
case RollType.Greed: // player choose Greed
|
||||
SendLootRoll(playerGuid, -7, RollType.Greed, roll);
|
||||
++roll.totalGreed;
|
||||
rollType = RollType.Greed;
|
||||
break;
|
||||
case RollType.Disenchant: // player choose Disenchant
|
||||
SendLootRoll(playerGuid, -8, RollType.Disenchant, roll);
|
||||
++roll.totalGreed;
|
||||
rollType = RollType.Disenchant;
|
||||
break;
|
||||
}
|
||||
|
||||
roll.playerVote[playerGuid] = rollType;
|
||||
|
||||
if (roll.totalPass + roll.totalNeed + roll.totalGreed >= roll.totalPlayersRolling)
|
||||
CountTheRoll(roll, null);
|
||||
}
|
||||
|
||||
public void EndRoll(Loot pLoot, Map allowedMap)
|
||||
{
|
||||
foreach (var roll in RollId.ToList())
|
||||
{
|
||||
if (roll.GetLoot() == pLoot)
|
||||
{
|
||||
CountTheRoll(roll, allowedMap); //i don't have to edit player votes, who didn't vote ... he will pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CountTheRoll(Roll roll, Map allowedMap)
|
||||
{
|
||||
if (!roll.IsValid()) // is loot already deleted ?
|
||||
{
|
||||
RollId.Remove(roll);
|
||||
return;
|
||||
}
|
||||
|
||||
//end of the roll
|
||||
if (roll.totalNeed > 0)
|
||||
{
|
||||
if (!roll.playerVote.Empty())
|
||||
{
|
||||
byte maxresul = 0;
|
||||
ObjectGuid maxguid = ObjectGuid.Empty;
|
||||
Player player;
|
||||
|
||||
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)
|
||||
{
|
||||
maxguid = pair.Key;
|
||||
maxresul = randomN;
|
||||
}
|
||||
}
|
||||
|
||||
if (!maxguid.IsEmpty())
|
||||
{
|
||||
SendLootRollWon(maxguid, maxresul, RollType.Need, roll);
|
||||
player = Global.ObjAccessor.FindConnectedPlayer(maxguid);
|
||||
|
||||
if (player && player.GetSession())
|
||||
{
|
||||
player.UpdateCriteria(CriteriaType.RollNeed, roll.itemid, maxresul);
|
||||
|
||||
List<ItemPosCount> dest = new();
|
||||
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;
|
||||
roll.GetLoot().NotifyItemRemoved(roll.itemSlot, allowedMap);
|
||||
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
|
||||
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;
|
||||
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))
|
||||
{
|
||||
--roll.totalGreed;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!maxguid.IsEmpty())
|
||||
{
|
||||
SendLootRollWon(maxguid, maxresul, rollVote, roll);
|
||||
player = Global.ObjAccessor.FindConnectedPlayer(maxguid);
|
||||
|
||||
if (player && player.GetSession() != null)
|
||||
{
|
||||
player.UpdateCriteria(CriteriaType.RollGreed, 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();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
{
|
||||
item.is_looted = true;
|
||||
roll.GetLoot().NotifyItemRemoved(roll.itemSlot, allowedMap);
|
||||
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, allowedMap);
|
||||
roll.GetLoot().unlootedCount--;
|
||||
player.UpdateCriteria(CriteriaType.CastSpell, 13262); // Disenchant
|
||||
|
||||
ItemDisenchantLootRecord disenchant = roll.GetItemDisenchantLoot(player);
|
||||
|
||||
List<ItemPosCount> dest = new();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, roll.itemid, item.count);
|
||||
if (msg == InventoryResult.Ok)
|
||||
player.AutoStoreLoot(disenchant.Id, LootStorage.Disenchant, ItemContext.None, true);
|
||||
else // If the player's inventory is full, send the disenchant result in a mail.
|
||||
{
|
||||
Loot loot = new(allowedMap, roll.GetLoot().GetOwnerGUID(), LootType.Disenchanting, roll.GetLoot().GetLootMethod());
|
||||
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, lootItem.context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
roll.totalGreed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// remove is_blocked so that the item is lootable by all players
|
||||
LootItem item = roll.itemSlot >= roll.GetLoot().items.Count ? roll.GetLoot().quest_items[roll.itemSlot - roll.GetLoot().items.Count] : roll.GetLoot().items[roll.itemSlot];
|
||||
item.is_blocked = false;
|
||||
}
|
||||
|
||||
SendLootRollsComplete(roll);
|
||||
|
||||
RollId.Remove(roll);
|
||||
}
|
||||
|
||||
public void SetTargetIcon(byte symbol, ObjectGuid target, ObjectGuid changedBy, sbyte partyIndex)
|
||||
{
|
||||
if (symbol >= MapConst.TargetIconsCount)
|
||||
@@ -2238,18 +1673,6 @@ namespace Game.Groups
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetMaxEnchantingLevel()
|
||||
{
|
||||
m_maxEnchantingLevel = 0;
|
||||
Player member;
|
||||
foreach (var memberSlot in m_memberSlots)
|
||||
{
|
||||
member = Global.ObjAccessor.FindPlayer(memberSlot.guid);
|
||||
if (member && m_maxEnchantingLevel < member.GetSkillValue(SkillType.Enchanting))
|
||||
m_maxEnchantingLevel = member.GetSkillValue(SkillType.Enchanting);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLootMethod(LootMethod method)
|
||||
{
|
||||
m_lootMethod = method;
|
||||
@@ -2466,8 +1889,6 @@ namespace Game.Groups
|
||||
return GetMembersCount() > 0;
|
||||
}
|
||||
|
||||
public bool IsRollLootActive() { return !RollId.Empty(); }
|
||||
|
||||
public ObjectGuid GetLeaderGUID()
|
||||
{
|
||||
return m_leaderGuid;
|
||||
@@ -2623,15 +2044,6 @@ namespace Game.Groups
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
Roll GetRoll(ObjectGuid lootObjectGuid, byte lootListId)
|
||||
{
|
||||
foreach (var roll in RollId)
|
||||
if (roll.IsValid() && roll.GetTarget().GetGUID() == lootObjectGuid && roll.itemSlot == lootListId)
|
||||
return roll;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void LinkMember(GroupReference pRef)
|
||||
{
|
||||
m_memberMgr.InsertFirst(pRef);
|
||||
@@ -2761,11 +2173,9 @@ namespace Game.Groups
|
||||
ItemQuality m_lootThreshold;
|
||||
ObjectGuid m_looterGuid;
|
||||
ObjectGuid m_masterLooterGuid;
|
||||
List<Roll> RollId = new();
|
||||
Dictionary<Difficulty, Dictionary<uint, InstanceBind>> m_boundInstances = new();
|
||||
byte[] m_subGroupsCounts;
|
||||
ObjectGuid m_guid;
|
||||
uint m_maxEnchantingLevel;
|
||||
uint m_dbStoreId;
|
||||
bool _isLeaderOffline;
|
||||
TimeTracker _leaderOfflineTimer = new();
|
||||
@@ -2784,76 +2194,6 @@ namespace Game.Groups
|
||||
}
|
||||
}
|
||||
|
||||
public class Roll : LootValidatorRef
|
||||
{
|
||||
public Roll(LootItem li)
|
||||
{
|
||||
itemid = li.itemid;
|
||||
itemRandomBonusListId = li.randomBonusListId;
|
||||
itemCount = li.count;
|
||||
rollTypeMask = RollMask.AllNoDisenchant;
|
||||
}
|
||||
|
||||
public void SetLoot(Loot pLoot)
|
||||
{
|
||||
Link(pLoot, this);
|
||||
}
|
||||
|
||||
public Loot GetLoot()
|
||||
{
|
||||
return GetTarget();
|
||||
}
|
||||
|
||||
public override void TargetObjectBuildLink()
|
||||
{
|
||||
// called from link()
|
||||
GetTarget().AddLootValidatorRef(this);
|
||||
}
|
||||
|
||||
public void FillPacket(LootItemData lootItem)
|
||||
{
|
||||
lootItem.UIType = (totalPlayersRolling > totalNeed + totalGreed + totalPass) ? LootSlotType.RollOngoing : LootSlotType.AllowLoot;
|
||||
lootItem.Quantity = itemCount;
|
||||
lootItem.LootListID = (byte)(itemSlot + 1);
|
||||
|
||||
LootItem lootItemInSlot = GetTarget().GetItemInSlot(itemSlot);
|
||||
if (lootItemInSlot != null)
|
||||
{
|
||||
lootItem.CanTradeToTapList = lootItemInSlot.allowedGUIDs.Count > 1;
|
||||
lootItem.Loot = new ItemInstance(lootItemInSlot);
|
||||
}
|
||||
}
|
||||
|
||||
public ItemDisenchantLootRecord GetItemDisenchantLoot(Player player)
|
||||
{
|
||||
LootItem lootItemInSlot = GetTarget().GetItemInSlot(itemSlot);
|
||||
if (lootItemInSlot != null)
|
||||
{
|
||||
ItemInstance itemInstance = new(lootItemInSlot);
|
||||
BonusData bonusData = new(itemInstance);
|
||||
if (!bonusData.CanDisenchant)
|
||||
return null;
|
||||
|
||||
ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(itemid);
|
||||
uint itemLevel = Item.GetItemLevel(itemTemplate, bonusData, player.GetLevel(), 0, 0, 0, 0, false, 0);
|
||||
return Item.GetDisenchantLoot(itemTemplate, (uint)bonusData.Quality, itemLevel);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public uint itemid;
|
||||
public uint itemRandomBonusListId;
|
||||
public byte itemCount;
|
||||
public Dictionary<ObjectGuid, RollType> playerVote = new();
|
||||
public byte totalPlayersRolling;
|
||||
public byte totalNeed;
|
||||
public byte totalGreed;
|
||||
public byte totalPass;
|
||||
public byte itemSlot;
|
||||
public RollMask rollTypeMask;
|
||||
}
|
||||
|
||||
public class MemberSlot
|
||||
{
|
||||
public ObjectGuid guid;
|
||||
|
||||
Reference in New Issue
Block a user