Core/Loot: Simplify loot containers
Port From (https://github.com/TrinityCore/TrinityCore/commit/c00e2e4851498aa04ac1d8ff13a0759b245df72b)
This commit is contained in:
@@ -58,17 +58,6 @@ namespace Framework.Constants
|
|||||||
JunkFish = 0x8000
|
JunkFish = 0x8000
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PermissionTypes
|
|
||||||
{
|
|
||||||
All = 0,
|
|
||||||
Group = 1,
|
|
||||||
Master = 2,
|
|
||||||
Restricted = 3,
|
|
||||||
RoundRobin = 4,
|
|
||||||
Owner = 5,
|
|
||||||
None = 6
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum LootType
|
public enum LootType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ namespace Framework.Constants
|
|||||||
/// Loot Const
|
/// Loot Const
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaxNRLootItems = 18;
|
public const int MaxNRLootItems = 18;
|
||||||
public const int MaxNRQuestItems = 32;
|
|
||||||
public const int PlayerCorpseLootEntry = 1;
|
public const int PlayerCorpseLootEntry = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -340,11 +340,6 @@ namespace Game.Chat
|
|||||||
foreach (LootItem item in loot.items)
|
foreach (LootItem item in loot.items)
|
||||||
if (!item.is_looted)
|
if (!item.is_looted)
|
||||||
_ShowLootEntry(handler, item.itemid, item.count);
|
_ShowLootEntry(handler, item.itemid, item.count);
|
||||||
|
|
||||||
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel, "Quest items", loot.quest_items.Count);
|
|
||||||
foreach (LootItem item in loot.quest_items)
|
|
||||||
if (!item.is_looted)
|
|
||||||
_ShowLootEntry(handler, item.itemid, item.count);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -353,23 +348,11 @@ namespace Game.Chat
|
|||||||
if (!item.is_looted && !item.freeforall && item.conditions.Empty())
|
if (!item.is_looted && !item.freeforall && item.conditions.Empty())
|
||||||
_ShowLootEntry(handler, item.itemid, item.count);
|
_ShowLootEntry(handler, item.itemid, item.count);
|
||||||
|
|
||||||
if (!loot.GetPlayerQuestItems().Empty())
|
|
||||||
{
|
|
||||||
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel2, "Per-player quest items");
|
|
||||||
_IterateNotNormalLootMap(handler, loot.GetPlayerQuestItems(), loot.quest_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!loot.GetPlayerFFAItems().Empty())
|
if (!loot.GetPlayerFFAItems().Empty())
|
||||||
{
|
{
|
||||||
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel2, "FFA items per allowed player");
|
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel2, "FFA items per allowed player");
|
||||||
_IterateNotNormalLootMap(handler, loot.GetPlayerFFAItems(), loot.items);
|
_IterateNotNormalLootMap(handler, loot.GetPlayerFFAItems(), loot.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loot.GetPlayerNonQuestNonFFAConditionalItems().Empty())
|
|
||||||
{
|
|
||||||
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel2, "Per-player conditional items");
|
|
||||||
_IterateNotNormalLootMap(handler, loot.GetPlayerNonQuestNonFFAConditionalItems(), loot.items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -565,7 +548,7 @@ namespace Game.Chat
|
|||||||
|
|
||||||
foreach (var it in list)
|
foreach (var it in list)
|
||||||
{
|
{
|
||||||
LootItem item = items[it.index];
|
LootItem item = items[it.LootListId];
|
||||||
if (!it.is_looted && !item.is_looted)
|
if (!it.is_looted && !item.is_looted)
|
||||||
_ShowLootEntry(handler, item.itemid, item.count, true);
|
_ShowLootEntry(handler, item.itemid, item.count, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5956,7 +5956,7 @@ namespace Game.Entities
|
|||||||
public void SetLootGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LootTargetGUID), guid); }
|
public void SetLootGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LootTargetGUID), guid); }
|
||||||
public void StoreLootItem(ObjectGuid lootWorldObjectGuid, byte lootSlot, Loot loot, AELootResult aeResult = null)
|
public void StoreLootItem(ObjectGuid lootWorldObjectGuid, byte lootSlot, Loot loot, AELootResult aeResult = null)
|
||||||
{
|
{
|
||||||
LootItem item = loot.LootItemInSlot(lootSlot, this, out NotNormalLootItem qitem, out NotNormalLootItem ffaitem, out NotNormalLootItem conditem);
|
LootItem item = loot.LootItemInSlot(lootSlot, this, out NotNormalLootItem ffaItem);
|
||||||
if (item == null || item.is_looted)
|
if (item == null || item.is_looted)
|
||||||
{
|
{
|
||||||
SendEquipError(InventoryResult.LootGone);
|
SendEquipError(InventoryResult.LootGone);
|
||||||
@@ -5969,8 +5969,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// questitems use the blocked field for other purposes
|
if (item.is_blocked)
|
||||||
if (qitem == null && item.is_blocked)
|
|
||||||
{
|
{
|
||||||
SendLootReleaseAll();
|
SendLootReleaseAll();
|
||||||
return;
|
return;
|
||||||
@@ -5988,31 +5987,14 @@ namespace Game.Entities
|
|||||||
if (msg == InventoryResult.Ok)
|
if (msg == InventoryResult.Ok)
|
||||||
{
|
{
|
||||||
Item newitem = StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
Item newitem = StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
|
||||||
if (qitem != null)
|
if (ffaItem != null)
|
||||||
{
|
{
|
||||||
qitem.is_looted = true;
|
//freeforall case, notify only one player of the removal
|
||||||
//freeforall is 1 if everyone's supposed to get the quest item.
|
ffaItem.is_looted = true;
|
||||||
if (item.freeforall || loot.GetPlayerQuestItems().Count == 1)
|
SendNotifyLootItemRemoved(loot.GetGUID(), loot.GetOwnerGUID(), lootSlot);
|
||||||
SendNotifyLootItemRemoved(loot.GetGUID(), loot.GetOwnerGUID(), lootSlot);
|
|
||||||
else
|
|
||||||
loot.NotifyQuestItemRemoved(qitem.index, GetMap());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ffaitem != null)
|
|
||||||
{
|
|
||||||
//freeforall case, notify only one player of the removal
|
|
||||||
ffaitem.is_looted = true;
|
|
||||||
SendNotifyLootItemRemoved(loot.GetGUID(), loot.GetOwnerGUID(), lootSlot);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//not freeforall, notify everyone
|
|
||||||
if (conditem != null)
|
|
||||||
conditem.is_looted = true;
|
|
||||||
loot.NotifyItemRemoved(lootSlot, GetMap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else //not freeforall, notify everyone
|
||||||
|
loot.NotifyItemRemoved(lootSlot, GetMap());
|
||||||
|
|
||||||
//if only one person is supposed to loot the item, then set it to looted
|
//if only one person is supposed to loot the item, then set it to looted
|
||||||
if (!item.freeforall)
|
if (!item.freeforall)
|
||||||
@@ -6122,7 +6104,6 @@ namespace Game.Entities
|
|||||||
Session.DoLootReleaseAll();
|
Session.DoLootReleaseAll();
|
||||||
|
|
||||||
Loot loot;
|
Loot loot;
|
||||||
PermissionTypes permission = PermissionTypes.All;
|
|
||||||
|
|
||||||
Log.outDebug(LogFilter.Loot, "Player.SendLoot");
|
Log.outDebug(LogFilter.Loot, "Player.SendLoot");
|
||||||
if (guid.IsGameObject())
|
if (guid.IsGameObject())
|
||||||
@@ -6217,31 +6198,6 @@ namespace Game.Entities
|
|||||||
|
|
||||||
go.SetLootState(LootState.Activated, this);
|
go.SetLootState(LootState.Activated, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (go.GetLootState() == LootState.Activated)
|
|
||||||
{
|
|
||||||
Group group = GetGroup();
|
|
||||||
if (group)
|
|
||||||
{
|
|
||||||
switch (loot.GetLootMethod())
|
|
||||||
{
|
|
||||||
case LootMethod.MasterLoot:
|
|
||||||
permission = group.GetMasterLooterGuid() == GetGUID() ? PermissionTypes.Master : PermissionTypes.Restricted;
|
|
||||||
break;
|
|
||||||
case LootMethod.RoundRobin:
|
|
||||||
permission = PermissionTypes.RoundRobin;
|
|
||||||
break;
|
|
||||||
case LootMethod.FreeForAll:
|
|
||||||
permission = PermissionTypes.All;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
permission = PermissionTypes.Group;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
permission = PermissionTypes.All;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (guid.IsItem())
|
else if (guid.IsItem())
|
||||||
{
|
{
|
||||||
@@ -6253,8 +6209,6 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
permission = PermissionTypes.Owner;
|
|
||||||
|
|
||||||
loot = item.GetLootForPlayer(this);
|
loot = item.GetLootForPlayer(this);
|
||||||
|
|
||||||
// If item doesn't already have loot, attempt to load it. If that
|
// If item doesn't already have loot, attempt to load it. If that
|
||||||
@@ -6300,11 +6254,6 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
loot = bones.GetLootForPlayer(this);
|
loot = bones.GetLootForPlayer(this);
|
||||||
|
|
||||||
if (bones.lootRecipient != null && bones.lootRecipient != this)
|
|
||||||
permission = PermissionTypes.None;
|
|
||||||
else
|
|
||||||
permission = PermissionTypes.Owner;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -6343,7 +6292,6 @@ namespace Game.Entities
|
|||||||
uint a = RandomHelper.URand(0, creature.GetLevel() / 2);
|
uint a = RandomHelper.URand(0, creature.GetLevel() / 2);
|
||||||
uint b = RandomHelper.URand(0, GetLevel() / 2);
|
uint b = RandomHelper.URand(0, GetLevel() / 2);
|
||||||
loot.gold = (uint)(10 * (a + b) * WorldConfig.GetFloatValue(WorldCfg.RateDropMoney));
|
loot.gold = (uint)(10 * (a + b) * WorldConfig.GetFloatValue(WorldCfg.RateDropMoney));
|
||||||
permission = PermissionTypes.Owner;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -6373,76 +6321,38 @@ namespace Game.Entities
|
|||||||
if (loot.loot_type == LootType.Skinning)
|
if (loot.loot_type == LootType.Skinning)
|
||||||
{
|
{
|
||||||
loot_type = LootType.Skinning;
|
loot_type = LootType.Skinning;
|
||||||
permission = creature.GetLootRecipientGUID() == GetGUID() ? PermissionTypes.Owner : PermissionTypes.None;
|
|
||||||
}
|
}
|
||||||
else if (loot_type == LootType.Skinning)
|
else if (loot_type == LootType.Skinning)
|
||||||
{
|
{
|
||||||
loot.Clear();
|
loot.Clear();
|
||||||
loot.FillLoot(creature.GetCreatureTemplate().SkinLootId, LootStorage.Skinning, this, true);
|
loot.FillLoot(creature.GetCreatureTemplate().SkinLootId, LootStorage.Skinning, this, true);
|
||||||
permission = PermissionTypes.Owner;
|
|
||||||
|
|
||||||
// Set new loot recipient
|
// Set new loot recipient
|
||||||
creature.SetLootRecipient(this, false);
|
creature.SetLootRecipient(this, false);
|
||||||
}
|
}
|
||||||
// set group rights only for loot_type != LOOT_SKINNING
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (creature.GetLootRecipientGroup())
|
|
||||||
{
|
|
||||||
Group group = GetGroup();
|
|
||||||
if (group == creature.GetLootRecipientGroup())
|
|
||||||
{
|
|
||||||
switch (loot.GetLootMethod())
|
|
||||||
{
|
|
||||||
case LootMethod.MasterLoot:
|
|
||||||
permission = PermissionTypes.Master;
|
|
||||||
break;
|
|
||||||
case LootMethod.FreeForAll:
|
|
||||||
permission = PermissionTypes.All;
|
|
||||||
break;
|
|
||||||
case LootMethod.RoundRobin:
|
|
||||||
permission = PermissionTypes.RoundRobin;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
permission = PermissionTypes.Group;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
permission = PermissionTypes.None;
|
|
||||||
}
|
|
||||||
else if (creature.GetLootRecipient() == this)
|
|
||||||
permission = PermissionTypes.Owner;
|
|
||||||
else
|
|
||||||
permission = PermissionTypes.None;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permission != PermissionTypes.None)
|
|
||||||
{
|
|
||||||
if (!guid.IsItem() && !aeLooting)
|
|
||||||
SetLootGUID(guid);
|
|
||||||
|
|
||||||
LootResponse packet = new();
|
if (!guid.IsItem() && !aeLooting)
|
||||||
packet.Owner = guid;
|
SetLootGUID(guid);
|
||||||
packet.LootObj = loot.GetGUID();
|
|
||||||
packet.LootMethod = loot.GetLootMethod();
|
|
||||||
packet.AcquireReason = (byte)SharedConst.GetLootTypeForClient(loot_type);
|
|
||||||
packet.Acquired = true; // false == No Loot (this too^^)
|
|
||||||
packet.AELooting = aeLooting;
|
|
||||||
loot.BuildLootResponse(packet, this, permission);
|
|
||||||
SendPacket(packet);
|
|
||||||
|
|
||||||
// add 'this' player as one of the players that are looting 'loot'
|
LootResponse packet = new();
|
||||||
loot.OnLootOpened(GetMap(), GetGUID());
|
packet.Owner = guid;
|
||||||
m_AELootView[loot.GetGUID()] = loot;
|
packet.LootObj = loot.GetGUID();
|
||||||
|
packet.LootMethod = loot.GetLootMethod();
|
||||||
|
packet.AcquireReason = (byte)SharedConst.GetLootTypeForClient(loot_type);
|
||||||
|
packet.Acquired = true; // false == No Loot (this too^^)
|
||||||
|
packet.AELooting = aeLooting;
|
||||||
|
loot.BuildLootResponse(packet, this);
|
||||||
|
SendPacket(packet);
|
||||||
|
|
||||||
if (loot_type == LootType.Corpse && !guid.IsItem())
|
// add 'this' player as one of the players that are looting 'loot'
|
||||||
SetUnitFlag(UnitFlags.Looting);
|
loot.OnLootOpened(GetMap(), GetGUID());
|
||||||
}
|
m_AELootView[loot.GetGUID()] = loot;
|
||||||
else
|
|
||||||
SendLootError(loot != null ? loot.GetGUID() : ObjectGuid.Empty, guid, LootError.DidntKill);
|
if (loot_type == LootType.Corpse && !guid.IsItem())
|
||||||
|
SetUnitFlag(UnitFlags.Looting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendLootError(ObjectGuid lootObj, ObjectGuid owner, LootError error)
|
public void SendLootError(ObjectGuid lootObj, ObjectGuid owner, LootError error)
|
||||||
@@ -6462,12 +6372,12 @@ namespace Game.Entities
|
|||||||
SendPacket(packet);
|
SendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendNotifyLootItemRemoved(ObjectGuid lootObj, ObjectGuid owner, byte lootSlot)
|
public void SendNotifyLootItemRemoved(ObjectGuid lootObj, ObjectGuid owner, byte lootListId)
|
||||||
{
|
{
|
||||||
LootRemoved packet = new();
|
LootRemoved packet = new();
|
||||||
packet.LootObj = lootObj;
|
packet.LootObj = lootObj;
|
||||||
packet.Owner = owner;
|
packet.Owner = owner;
|
||||||
packet.LootListID = (byte)(lootSlot + 1);
|
packet.LootListID = lootListId;
|
||||||
SendPacket(packet);
|
SendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3138,7 +3138,6 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
case LootMethod.PersonalLoot:// @todo implement personal loot (http://wow.gamepedia.com/Loot#Personal_Loot)
|
case LootMethod.PersonalLoot:// @todo implement personal loot (http://wow.gamepedia.com/Loot#Personal_Loot)
|
||||||
return false;
|
return false;
|
||||||
case LootMethod.MasterLoot:
|
|
||||||
case LootMethod.FreeForAll:
|
case LootMethod.FreeForAll:
|
||||||
return true;
|
return true;
|
||||||
case LootMethod.RoundRobin:
|
case LootMethod.RoundRobin:
|
||||||
@@ -3148,10 +3147,11 @@ namespace Game.Entities
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
return loot.HasItemFor(this);
|
return loot.HasItemFor(this);
|
||||||
|
case LootMethod.MasterLoot:
|
||||||
case LootMethod.GroupLoot:
|
case LootMethod.GroupLoot:
|
||||||
case LootMethod.NeedBeforeGreed:
|
case LootMethod.NeedBeforeGreed:
|
||||||
// may only loot if the player is the loot roundrobin player
|
// may only loot if the player is the loot roundrobin player
|
||||||
// or item over threshold (so roll(s) can be launched)
|
// or item over threshold (so roll(s) can be launched or to preview master looted items)
|
||||||
// or if there are free/quest/conditional item for the player
|
// or if there are free/quest/conditional item for the player
|
||||||
if (loot.roundRobinPlayer.IsEmpty() || loot.roundRobinPlayer == GetGUID())
|
if (loot.roundRobinPlayer.IsEmpty() || loot.roundRobinPlayer == GetGUID())
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
player.StoreLootItem(lguid, (byte)(req.LootListID - 1), loot, aeResult);
|
player.StoreLootItem(lguid, req.LootListID, loot, aeResult);
|
||||||
|
|
||||||
// If player is removing the last LootItem, delete the empty container.
|
// If player is removing the last LootItem, delete the empty container.
|
||||||
if (loot.IsLooted() && lguid.IsItem())
|
if (loot.IsLooted() && lguid.IsItem())
|
||||||
@@ -412,14 +412,13 @@ namespace Game
|
|||||||
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot)
|
if (loot == null || loot.GetLootMethod() != LootMethod.MasterLoot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
byte slotid = (byte)(req.LootListID - 1);
|
if (req.LootListID >= loot.items.Count)
|
||||||
if (slotid >= loot.items.Count + loot.quest_items.Count)
|
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Loot, $"MasterLootItem: Player {GetPlayer().GetName()} might be using a hack! (slot {slotid}, size {loot.items.Count})");
|
Log.outDebug(LogFilter.Loot, $"MasterLootItem: Player {GetPlayer().GetName()} might be using a hack! (slot {req.LootListID}, size {loot.items.Count})");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LootItem item = slotid >= loot.items.Count ? loot.quest_items[slotid - loot.items.Count] : loot.items[slotid];
|
LootItem item = loot.items[req.LootListID];
|
||||||
|
|
||||||
List<ItemPosCount> dest = new();
|
List<ItemPosCount> dest = new();
|
||||||
InventoryResult msg = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count);
|
InventoryResult msg = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count);
|
||||||
@@ -445,7 +444,7 @@ namespace Game
|
|||||||
item.count = 0;
|
item.count = 0;
|
||||||
item.is_looted = true;
|
item.is_looted = true;
|
||||||
|
|
||||||
loot.NotifyItemRemoved(slotid, GetPlayer().GetMap());
|
loot.NotifyItemRemoved(req.LootListID, GetPlayer().GetMap());
|
||||||
--loot.unlootedCount;
|
--loot.unlootedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +460,7 @@ namespace Game
|
|||||||
[WorldPacketHandler(ClientOpcodes.LootRoll)]
|
[WorldPacketHandler(ClientOpcodes.LootRoll)]
|
||||||
void HandleLootRoll(LootRollPacket packet)
|
void HandleLootRoll(LootRollPacket packet)
|
||||||
{
|
{
|
||||||
LootRoll lootRoll = GetPlayer().GetLootRoll(packet.LootObj, (byte)(packet.LootListID - 1));
|
LootRoll lootRoll = GetPlayer().GetLootRoll(packet.LootObj, packet.LootListID);
|
||||||
if (lootRoll == null)
|
if (lootRoll == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
+147
-524
@@ -108,6 +108,73 @@ namespace Game.Loots
|
|||||||
allowedGUIDs.Add(player.GetGUID());
|
allowedGUIDs.Add(player.GetGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LootSlotType? GetUiTypeForPlayer(Player player, Loot loot)
|
||||||
|
{
|
||||||
|
if (is_looted)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!allowedGUIDs.Contains(player.GetGUID()))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (freeforall)
|
||||||
|
{
|
||||||
|
var ffaItems = loot.GetPlayerFFAItems().LookupByKey(player.GetGUID());
|
||||||
|
if (ffaItems != null)
|
||||||
|
{
|
||||||
|
var ffaItemItr = ffaItems.Find(ffaItem => ffaItem.LootListId == LootListId);
|
||||||
|
if (ffaItemItr != null && !ffaItemItr.is_looted)
|
||||||
|
return loot.GetLootMethod() == LootMethod.FreeForAll ? LootSlotType.Owner : LootSlotType.AllowLoot;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needs_quest && !follow_loot_rules)
|
||||||
|
return loot.GetLootMethod() == LootMethod.FreeForAll ? LootSlotType.Owner : LootSlotType.AllowLoot;
|
||||||
|
|
||||||
|
switch (loot.GetLootMethod())
|
||||||
|
{
|
||||||
|
case LootMethod.FreeForAll:
|
||||||
|
return LootSlotType.Owner;
|
||||||
|
case LootMethod.RoundRobin:
|
||||||
|
if (!loot.roundRobinPlayer.IsEmpty() && loot.roundRobinPlayer != player.GetGUID())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return LootSlotType.AllowLoot;
|
||||||
|
case LootMethod.MasterLoot:
|
||||||
|
if (is_underthreshold)
|
||||||
|
{
|
||||||
|
if (!loot.roundRobinPlayer.IsEmpty() && loot.roundRobinPlayer != player.GetGUID())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return LootSlotType.AllowLoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loot.GetLootMasterGUID() == player.GetGUID() ? LootSlotType.Master : LootSlotType.Locked;
|
||||||
|
case LootMethod.GroupLoot:
|
||||||
|
case LootMethod.NeedBeforeGreed:
|
||||||
|
if (is_underthreshold)
|
||||||
|
if (!loot.roundRobinPlayer.IsEmpty() && loot.roundRobinPlayer != player.GetGUID())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (is_blocked)
|
||||||
|
return LootSlotType.RollOngoing;
|
||||||
|
|
||||||
|
if (rollWinnerGUID.IsEmpty()) // all passed
|
||||||
|
return LootSlotType.AllowLoot;
|
||||||
|
|
||||||
|
if (rollWinnerGUID == player.GetGUID())
|
||||||
|
return LootSlotType.Owner;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case LootMethod.PersonalLoot:
|
||||||
|
return LootSlotType.Owner;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ObjectGuid> GetAllowedLooters() { return allowedGUIDs; }
|
public List<ObjectGuid> GetAllowedLooters() { return allowedGUIDs; }
|
||||||
|
|
||||||
public uint itemid;
|
public uint itemid;
|
||||||
@@ -130,18 +197,18 @@ namespace Game.Loots
|
|||||||
|
|
||||||
public class NotNormalLootItem
|
public class NotNormalLootItem
|
||||||
{
|
{
|
||||||
public byte index; // position in quest_items or items;
|
public byte LootListId; // position in quest_items or items;
|
||||||
public bool is_looted;
|
public bool is_looted;
|
||||||
|
|
||||||
public NotNormalLootItem()
|
public NotNormalLootItem()
|
||||||
{
|
{
|
||||||
index = 0;
|
LootListId = 0;
|
||||||
is_looted = false;
|
is_looted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotNormalLootItem(byte _index, bool _islooted = false)
|
public NotNormalLootItem(byte _index, bool _islooted = false)
|
||||||
{
|
{
|
||||||
index = _index;
|
LootListId = _index;
|
||||||
is_looted = _islooted;
|
is_looted = _islooted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +234,6 @@ namespace Game.Loots
|
|||||||
bool m_isStarted;
|
bool m_isStarted;
|
||||||
LootItem m_lootItem;
|
LootItem m_lootItem;
|
||||||
Loot m_loot;
|
Loot m_loot;
|
||||||
uint m_lootListId;
|
|
||||||
RollMask m_voteMask;
|
RollMask m_voteMask;
|
||||||
DateTime m_endTime = DateTime.MinValue;
|
DateTime m_endTime = DateTime.MinValue;
|
||||||
|
|
||||||
@@ -347,7 +413,7 @@ namespace Game.Loots
|
|||||||
void FillPacket(LootItemData lootItem)
|
void FillPacket(LootItemData lootItem)
|
||||||
{
|
{
|
||||||
lootItem.Quantity = m_lootItem.count;
|
lootItem.Quantity = m_lootItem.count;
|
||||||
lootItem.LootListID = (byte)(m_lootListId + 1);
|
lootItem.LootListID = (byte)m_lootItem.LootListId;
|
||||||
lootItem.CanTradeToTapList = m_lootItem.allowedGUIDs.Count > 1;
|
lootItem.CanTradeToTapList = m_lootItem.allowedGUIDs.Count > 1;
|
||||||
lootItem.Loot = new(m_lootItem);
|
lootItem.Loot = new(m_lootItem);
|
||||||
}
|
}
|
||||||
@@ -367,7 +433,6 @@ namespace Game.Loots
|
|||||||
m_lootItem = loot.items[(int)lootListId];
|
m_lootItem = loot.items[(int)lootListId];
|
||||||
|
|
||||||
m_loot = loot;
|
m_loot = loot;
|
||||||
m_lootListId = lootListId;
|
|
||||||
m_lootItem.is_blocked = true; // block the item while rolling
|
m_lootItem.is_blocked = true; // block the item while rolling
|
||||||
|
|
||||||
uint playerCount = 0;
|
uint playerCount = 0;
|
||||||
@@ -469,7 +534,7 @@ namespace Game.Loots
|
|||||||
|
|
||||||
public bool IsLootItem(ObjectGuid lootObject, uint lootListId)
|
public bool IsLootItem(ObjectGuid lootObject, uint lootListId)
|
||||||
{
|
{
|
||||||
return m_loot.GetGUID() == lootObject && m_lootListId == lootListId;
|
return m_loot.GetGUID() == lootObject && m_lootItem.LootListId == lootListId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -560,8 +625,7 @@ namespace Game.Loots
|
|||||||
loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true, false, LootModes.Default, ItemContext.None);
|
loot.FillLoot(disenchant.Id, LootStorage.Disenchant, player, true, false, LootModes.Default, ItemContext.None);
|
||||||
if (!loot.AutoStore(player, ItemConst.NullBag, ItemConst.NullSlot, true))
|
if (!loot.AutoStore(player, ItemConst.NullBag, ItemConst.NullSlot, true))
|
||||||
{
|
{
|
||||||
uint maxSlot = loot.GetMaxSlotInLootFor(player);
|
for (uint i = 0; i < loot.items.Count; ++i)
|
||||||
for (uint i = 0; i < maxSlot; ++i)
|
|
||||||
{
|
{
|
||||||
LootItem disenchantLoot = loot.LootItemInSlot(i, player);
|
LootItem disenchantLoot = loot.LootItemInSlot(i, player);
|
||||||
if (disenchantLoot != null)
|
if (disenchantLoot != null)
|
||||||
@@ -572,7 +636,7 @@ namespace Game.Loots
|
|||||||
m_loot.NotifyItemRemoved((byte)m_lootItem.LootListId, m_map);
|
m_loot.NotifyItemRemoved((byte)m_lootItem.LootListId, m_map);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player.StoreLootItem(m_loot.GetOwnerGUID(), (byte)m_lootListId, m_loot);
|
player.StoreLootItem(m_loot.GetOwnerGUID(), (byte)m_lootItem.LootListId, m_loot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isStarted = false;
|
m_isStarted = false;
|
||||||
@@ -593,7 +657,7 @@ namespace Game.Loots
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inserts the item into the loot (called by LootTemplate processors)
|
// Inserts the item into the loot (called by LootTemplate processors)
|
||||||
public void AddItem(LootStoreItem item, Player player)
|
public void AddItem(LootStoreItem item)
|
||||||
{
|
{
|
||||||
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
|
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
|
||||||
if (proto == null)
|
if (proto == null)
|
||||||
@@ -602,68 +666,36 @@ namespace Game.Loots
|
|||||||
uint count = RandomHelper.URand(item.mincount, item.maxcount);
|
uint count = RandomHelper.URand(item.mincount, item.maxcount);
|
||||||
uint stacks = (uint)(count / proto.GetMaxStackSize() + (Convert.ToBoolean(count % proto.GetMaxStackSize()) ? 1 : 0));
|
uint stacks = (uint)(count / proto.GetMaxStackSize() + (Convert.ToBoolean(count % proto.GetMaxStackSize()) ? 1 : 0));
|
||||||
|
|
||||||
List<LootItem> lootItems = item.needs_quest ? quest_items : items;
|
for (uint i = 0; i < stacks && items.Count < SharedConst.MaxNRLootItems; ++i)
|
||||||
uint limit = (uint)(item.needs_quest ? SharedConst.MaxNRQuestItems : SharedConst.MaxNRLootItems);
|
|
||||||
|
|
||||||
for (uint i = 0; i < stacks && lootItems.Count < limit; ++i)
|
|
||||||
{
|
{
|
||||||
LootItem generatedLoot = new(item);
|
LootItem generatedLoot = new(item);
|
||||||
generatedLoot.context = _itemContext;
|
generatedLoot.context = _itemContext;
|
||||||
generatedLoot.count = (byte)Math.Min(count, proto.GetMaxStackSize());
|
generatedLoot.count = (byte)Math.Min(count, proto.GetMaxStackSize());
|
||||||
generatedLoot.LootListId = (uint)lootItems.Count;
|
generatedLoot.LootListId = (uint)items.Count;
|
||||||
if (_itemContext != 0)
|
if (_itemContext != 0)
|
||||||
{
|
{
|
||||||
List<uint> bonusListIDs = Global.DB2Mgr.GetDefaultItemBonusTree(generatedLoot.itemid, _itemContext);
|
List<uint> bonusListIDs = Global.DB2Mgr.GetDefaultItemBonusTree(generatedLoot.itemid, _itemContext);
|
||||||
generatedLoot.BonusListIDs.AddRange(bonusListIDs);
|
generatedLoot.BonusListIDs.AddRange(bonusListIDs);
|
||||||
}
|
}
|
||||||
lootItems.Add(generatedLoot);
|
|
||||||
|
items.Add(generatedLoot);
|
||||||
count -= proto.GetMaxStackSize();
|
count -= proto.GetMaxStackSize();
|
||||||
|
|
||||||
// In some cases, a dropped item should be visible/lootable only for some players in group
|
|
||||||
bool canSeeItemInLootWindow = false;
|
|
||||||
Group group = player.GetGroup();
|
|
||||||
if (group != null)
|
|
||||||
{
|
|
||||||
for (GroupReference itr = group.GetFirstMember(); itr != null; itr = itr.Next())
|
|
||||||
{
|
|
||||||
Player member = itr.GetSource();
|
|
||||||
if (member != null)
|
|
||||||
if (generatedLoot.AllowedForPlayer(member))
|
|
||||||
canSeeItemInLootWindow = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (generatedLoot.AllowedForPlayer(player))
|
|
||||||
canSeeItemInLootWindow = true;
|
|
||||||
|
|
||||||
if (!canSeeItemInLootWindow)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// non-conditional one-player only items are counted here,
|
|
||||||
// free for all items are counted in FillFFALoot(),
|
|
||||||
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
|
|
||||||
if (!item.needs_quest && item.conditions.Empty() && !proto.HasFlag(ItemFlags.MultiDrop))
|
|
||||||
++unlootedCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AutoStore(Player player, byte bag, byte slot, bool broadcast, bool createdByPlayer = false)
|
public bool AutoStore(Player player, byte bag, byte slot, bool broadcast, bool createdByPlayer = false)
|
||||||
{
|
{
|
||||||
bool allLooted = true;
|
bool allLooted = true;
|
||||||
uint max_slot = GetMaxSlotInLootFor(player);
|
for (uint i = 0; i < items.Count; ++i)
|
||||||
for (uint i = 0; i < max_slot; ++i)
|
|
||||||
{
|
{
|
||||||
NotNormalLootItem qitem = null;
|
LootItem lootItem = LootItemInSlot(i, player, out NotNormalLootItem ffaitem);
|
||||||
NotNormalLootItem ffaitem = null;
|
|
||||||
NotNormalLootItem conditem = null;
|
|
||||||
|
|
||||||
LootItem lootItem = LootItemInSlot(i, player, out qitem, out ffaitem, out conditem);
|
|
||||||
if (lootItem == null || lootItem.is_looted)
|
if (lootItem == null || lootItem.is_looted)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!lootItem.AllowedForPlayer(player))
|
if (!lootItem.AllowedForPlayer(player))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (qitem == null && lootItem.is_blocked)
|
if (lootItem.is_blocked)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// dont allow protected item to be looted by someone else
|
// dont allow protected item to be looted by someone else
|
||||||
@@ -683,12 +715,8 @@ namespace Game.Loots
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qitem != null)
|
if (ffaitem != null)
|
||||||
qitem.is_looted = true;
|
|
||||||
else if (ffaitem != null)
|
|
||||||
ffaitem.is_looted = true;
|
ffaitem.is_looted = true;
|
||||||
else if (conditem != null)
|
|
||||||
conditem.is_looted = true;
|
|
||||||
|
|
||||||
if (!lootItem.freeforall)
|
if (!lootItem.freeforall)
|
||||||
lootItem.is_looted = true;
|
lootItem.is_looted = true;
|
||||||
@@ -703,14 +731,10 @@ namespace Game.Loots
|
|||||||
return allLooted;
|
return allLooted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LootItem GetItemInSlot(uint lootSlot)
|
public LootItem GetItemInSlot(uint lootListId)
|
||||||
{
|
{
|
||||||
if (lootSlot < items.Count)
|
if (lootListId < items.Count)
|
||||||
return items[(int)lootSlot];
|
return items[(int)lootListId];
|
||||||
|
|
||||||
lootSlot -= (uint)items.Count;
|
|
||||||
if (lootSlot < quest_items.Count)
|
|
||||||
return quest_items[(int)lootSlot];
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -732,7 +756,7 @@ namespace Game.Loots
|
|||||||
|
|
||||||
_itemContext = context;
|
_itemContext = context;
|
||||||
|
|
||||||
tab.Process(this, store.IsRatesAllowed(), (byte)lootMode, 0, lootOwner); // Processing is done there, callback via Loot.AddItem()
|
tab.Process(this, store.IsRatesAllowed(), (byte)lootMode, 0); // Processing is done there, callback via Loot.AddItem()
|
||||||
|
|
||||||
// Setting access rights for group loot case
|
// Setting access rights for group loot case
|
||||||
Group group = lootOwner.GetGroup();
|
Group group = lootOwner.GetGroup();
|
||||||
@@ -748,8 +772,11 @@ namespace Game.Loots
|
|||||||
FillNotNormalLootFor(player);
|
FillNotNormalLootFor(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void processLootItem(LootItem item)
|
foreach (LootItem item in items)
|
||||||
{
|
{
|
||||||
|
if (!item.follow_loot_rules || item.freeforall)
|
||||||
|
continue;
|
||||||
|
|
||||||
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
|
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item.itemid);
|
||||||
if (proto != null)
|
if (proto != null)
|
||||||
{
|
{
|
||||||
@@ -771,22 +798,6 @@ namespace Game.Loots
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
foreach (LootItem item in items)
|
|
||||||
{
|
|
||||||
if (item.freeforall)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
processLootItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (LootItem item in quest_items)
|
|
||||||
{
|
|
||||||
if (!item.follow_loot_rules)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
processLootItem(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ... for personal loot
|
// ... for personal loot
|
||||||
@@ -808,142 +819,43 @@ namespace Game.Loots
|
|||||||
ObjectGuid plguid = player.GetGUID();
|
ObjectGuid plguid = player.GetGUID();
|
||||||
_allowedLooters.Add(plguid);
|
_allowedLooters.Add(plguid);
|
||||||
|
|
||||||
var questItemList = PlayerQuestItems.LookupByKey(plguid);
|
List<NotNormalLootItem> ffaItems = new();
|
||||||
if (questItemList.Empty())
|
|
||||||
FillQuestLoot(player);
|
|
||||||
|
|
||||||
questItemList = PlayerFFAItems.LookupByKey(plguid);
|
foreach (LootItem item in items)
|
||||||
if (questItemList.Empty())
|
|
||||||
FillFFALoot(player);
|
|
||||||
|
|
||||||
questItemList = PlayerNonQuestNonFFAConditionalItems.LookupByKey(plguid);
|
|
||||||
if (questItemList.Empty())
|
|
||||||
FillNonQuestNonFFAConditionalLoot(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NotNormalLootItem> FillFFALoot(Player player)
|
|
||||||
{
|
|
||||||
List<NotNormalLootItem> ql = new();
|
|
||||||
|
|
||||||
for (byte i = 0; i < items.Count; ++i)
|
|
||||||
{
|
{
|
||||||
LootItem item = items[i];
|
if (!item.AllowedForPlayer(player))
|
||||||
if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player))
|
continue;
|
||||||
|
|
||||||
|
if (item.freeforall)
|
||||||
{
|
{
|
||||||
ql.Add(new NotNormalLootItem(i));
|
ffaItems.Add(new NotNormalLootItem((byte)item.LootListId));
|
||||||
|
++unlootedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!item.is_counted)
|
||||||
|
{
|
||||||
|
item.is_counted = true;
|
||||||
++unlootedCount;
|
++unlootedCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ql.Empty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
|
if (!ffaItems.Empty())
|
||||||
PlayerFFAItems[player.GetGUID()] = ql;
|
PlayerFFAItems[player.GetGUID()] = ffaItems;
|
||||||
return ql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<NotNormalLootItem> FillQuestLoot(Player player)
|
public void NotifyItemRemoved(byte lootListId, Map map)
|
||||||
{
|
|
||||||
if (items.Count == SharedConst.MaxNRLootItems)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<NotNormalLootItem> ql = new();
|
|
||||||
|
|
||||||
for (byte i = 0; i < quest_items.Count; ++i)
|
|
||||||
{
|
|
||||||
LootItem item = quest_items[i];
|
|
||||||
|
|
||||||
if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player.GetGroup() && ((GetLootMethod() == LootMethod.MasterLoot && player.GetGroup().GetMasterLooterGuid() == player.GetGUID()) || GetLootMethod() != LootMethod.MasterLoot))))
|
|
||||||
{
|
|
||||||
item.AddAllowedLooter(player);
|
|
||||||
|
|
||||||
ql.Add(new NotNormalLootItem(i));
|
|
||||||
|
|
||||||
// quest items get blocked when they first appear in a
|
|
||||||
// player's quest vector
|
|
||||||
//
|
|
||||||
// increase once if one looter only, looter-times if free for all
|
|
||||||
if (item.freeforall || !item.is_blocked)
|
|
||||||
++unlootedCount;
|
|
||||||
if (!player.GetGroup() || GetLootMethod() != LootMethod.GroupLoot && GetLootMethod() != LootMethod.RoundRobin)
|
|
||||||
item.is_blocked = true;
|
|
||||||
|
|
||||||
if (items.Count + ql.Count == SharedConst.MaxNRLootItems)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ql.Empty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PlayerQuestItems[player.GetGUID()] = ql;
|
|
||||||
return ql;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NotNormalLootItem> FillNonQuestNonFFAConditionalLoot(Player player)
|
|
||||||
{
|
|
||||||
List<NotNormalLootItem> ql = new();
|
|
||||||
|
|
||||||
for (byte i = 0; i < items.Count; ++i)
|
|
||||||
{
|
|
||||||
LootItem item = items[i];
|
|
||||||
if (!item.is_looted && !item.freeforall && item.AllowedForPlayer(player))
|
|
||||||
{
|
|
||||||
item.AddAllowedLooter(player);
|
|
||||||
if (!item.conditions.Empty())
|
|
||||||
{
|
|
||||||
ql.Add(new NotNormalLootItem(i));
|
|
||||||
if (!item.is_counted)
|
|
||||||
{
|
|
||||||
++unlootedCount;
|
|
||||||
item.is_counted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ql.Empty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PlayerNonQuestNonFFAConditionalItems[player.GetGUID()] = ql;
|
|
||||||
return ql;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyItemRemoved(byte lootIndex, Map map)
|
|
||||||
{
|
{
|
||||||
// notify all players that are looting this that the item was removed
|
// notify all players that are looting this that the item was removed
|
||||||
// convert the index to the slot the player sees
|
// convert the index to the slot the player sees
|
||||||
for (int i = 0; i < PlayersLooting.Count; ++i)
|
for (int i = 0; i < PlayersLooting.Count; ++i)
|
||||||
{
|
{
|
||||||
Player player = Global.ObjAccessor.GetPlayer(map, PlayersLooting[i]);
|
LootItem item = items[lootListId];
|
||||||
if (player != null)
|
if (!item.GetAllowedLooters().Contains(PlayersLooting[i]))
|
||||||
player.SendNotifyLootItemRemoved(GetGUID(), GetOwnerGUID(), lootIndex);
|
continue;
|
||||||
else
|
|
||||||
PlayersLooting.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyQuestItemRemoved(byte questIndex, Map map)
|
|
||||||
{
|
|
||||||
// when a free for all questitem is looted
|
|
||||||
// all players will get notified of it being removed
|
|
||||||
// (other questitems can be looted by each group member)
|
|
||||||
// bit inefficient but isn't called often
|
|
||||||
for (var i = 0; i < PlayersLooting.Count; ++i)
|
|
||||||
{
|
|
||||||
Player player = Global.ObjAccessor.GetPlayer(map, PlayersLooting[i]);
|
Player player = Global.ObjAccessor.GetPlayer(map, PlayersLooting[i]);
|
||||||
if (player)
|
if (player)
|
||||||
{
|
player.SendNotifyLootItemRemoved(GetGUID(), GetOwnerGUID(), lootListId);
|
||||||
var pql = PlayerQuestItems.LookupByKey(player.GetGUID());
|
|
||||||
if (!pql.Empty())
|
|
||||||
{
|
|
||||||
byte j;
|
|
||||||
for (j = 0; j < pql.Count; ++j)
|
|
||||||
if (pql[j].index == questIndex)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (j < pql.Count)
|
|
||||||
player.SendNotifyLootItemRemoved(GetGUID(), GetOwnerGUID(), (byte)(items.Count + j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
PlayersLooting.RemoveAt(i);
|
PlayersLooting.RemoveAt(i);
|
||||||
}
|
}
|
||||||
@@ -979,8 +891,7 @@ namespace Game.Loots
|
|||||||
maxEnchantingSkill = Math.Max(maxEnchantingSkill, allowedLooter.GetSkillValue(SkillType.Enchanting));
|
maxEnchantingSkill = Math.Max(maxEnchantingSkill, allowedLooter.GetSkillValue(SkillType.Enchanting));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint lootListId = 0;
|
for (uint lootListId = 0; lootListId < items.Count; ++lootListId)
|
||||||
for (; lootListId < items.Count; ++lootListId)
|
|
||||||
{
|
{
|
||||||
LootItem item = items[(int)lootListId];
|
LootItem item = items[(int)lootListId];
|
||||||
if (!item.is_blocked)
|
if (!item.is_blocked)
|
||||||
@@ -991,18 +902,6 @@ namespace Game.Loots
|
|||||||
if (!lootRoll.TryToStart(map, this, lootListId, maxEnchantingSkill))
|
if (!lootRoll.TryToStart(map, this, lootListId, maxEnchantingSkill))
|
||||||
_rolls.Remove(lootListId);
|
_rolls.Remove(lootListId);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; lootListId - items.Count < quest_items.Count; ++lootListId)
|
|
||||||
{
|
|
||||||
LootItem item = quest_items[(int)lootListId - items.Count];
|
|
||||||
if (!item.is_blocked)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LootRoll lootRoll = new();
|
|
||||||
var inserted = _rolls.TryAdd(lootListId, lootRoll);
|
|
||||||
if (!lootRoll.TryToStart(map, this, lootListId, maxEnchantingSkill))
|
|
||||||
_rolls.Remove(lootListId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_lootMethod == LootMethod.MasterLoot)
|
else if (_lootMethod == LootMethod.MasterLoot)
|
||||||
{
|
{
|
||||||
@@ -1036,66 +935,27 @@ namespace Game.Loots
|
|||||||
|
|
||||||
public LootItem LootItemInSlot(uint lootSlot, Player player)
|
public LootItem LootItemInSlot(uint lootSlot, Player player)
|
||||||
{
|
{
|
||||||
return LootItemInSlot(lootSlot, player, out _, out _, out _);
|
return LootItemInSlot(lootSlot, player, out _);
|
||||||
}
|
}
|
||||||
public LootItem LootItemInSlot(uint lootSlot, Player player, out NotNormalLootItem qitem, out NotNormalLootItem ffaitem, out NotNormalLootItem conditem)
|
public LootItem LootItemInSlot(uint lootListId, Player player, out NotNormalLootItem ffaItem)
|
||||||
{
|
{
|
||||||
qitem = null;
|
ffaItem = null;
|
||||||
ffaitem = null;
|
|
||||||
conditem = null;
|
|
||||||
|
|
||||||
LootItem item = null;
|
LootItem item = items[(int)lootListId];
|
||||||
bool is_looted = true;
|
bool is_looted = item.is_looted;
|
||||||
if (lootSlot >= items.Count)
|
|
||||||
|
if (item.freeforall)
|
||||||
{
|
{
|
||||||
int questSlot = (int)(lootSlot - items.Count);
|
var itemList = PlayerFFAItems.LookupByKey(player.GetGUID());
|
||||||
var questItems = PlayerQuestItems.LookupByKey(player.GetGUID());
|
if (itemList != null)
|
||||||
if (!questItems.Empty())
|
|
||||||
{
|
{
|
||||||
NotNormalLootItem qitem2 = questItems[questSlot];
|
foreach (NotNormalLootItem notNormalLootItem in itemList)
|
||||||
if (qitem2 != null)
|
|
||||||
{
|
{
|
||||||
qitem = qitem2;
|
if (notNormalLootItem.LootListId == lootListId)
|
||||||
item = quest_items[qitem2.index];
|
|
||||||
is_looted = qitem2.is_looted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = items[(int)lootSlot];
|
|
||||||
is_looted = item.is_looted;
|
|
||||||
if (item.freeforall)
|
|
||||||
{
|
|
||||||
var questItemList = PlayerFFAItems.LookupByKey(player.GetGUID());
|
|
||||||
if (!questItemList.Empty())
|
|
||||||
{
|
|
||||||
foreach (var c in questItemList)
|
|
||||||
{
|
{
|
||||||
if (c.index == lootSlot)
|
is_looted = notNormalLootItem.is_looted;
|
||||||
{
|
ffaItem = notNormalLootItem;
|
||||||
NotNormalLootItem ffaitem2 = c;
|
break;
|
||||||
ffaitem = ffaitem2;
|
|
||||||
is_looted = ffaitem2.is_looted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!item.conditions.Empty())
|
|
||||||
{
|
|
||||||
var questItemList = PlayerNonQuestNonFFAConditionalItems.LookupByKey(player.GetGUID());
|
|
||||||
if (!questItemList.Empty())
|
|
||||||
{
|
|
||||||
foreach (var iter in questItemList)
|
|
||||||
{
|
|
||||||
if (iter.index == lootSlot)
|
|
||||||
{
|
|
||||||
NotNormalLootItem conditem2 = iter;
|
|
||||||
conditem = conditem2;
|
|
||||||
is_looted = conditem2.is_looted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1107,12 +967,6 @@ namespace Game.Loots
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetMaxSlotInLootFor(Player player)
|
|
||||||
{
|
|
||||||
var questItemList = PlayerQuestItems.LookupByKey(player.GetGUID());
|
|
||||||
return (uint)(items.Count + questItemList.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if there is any item that is lootable for any player (not quest item, FFA or conditional)
|
// return true if there is any item that is lootable for any player (not quest item, FFA or conditional)
|
||||||
public bool HasItemForAll()
|
public bool HasItemForAll()
|
||||||
{
|
{
|
||||||
@@ -1121,7 +975,7 @@ namespace Game.Loots
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
foreach (LootItem item in items)
|
foreach (LootItem item in items)
|
||||||
if (!item.is_looted && !item.freeforall && item.conditions.Empty())
|
if (!item.is_looted && item.follow_loot_rules && !item.freeforall && item.conditions.Empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1130,40 +984,17 @@ namespace Game.Loots
|
|||||||
// return true if there is any FFA, quest or conditional item for the player.
|
// return true if there is any FFA, quest or conditional item for the player.
|
||||||
public bool HasItemFor(Player player)
|
public bool HasItemFor(Player player)
|
||||||
{
|
{
|
||||||
var lootPlayerQuestItems = GetPlayerQuestItems();
|
// quest items
|
||||||
var q_list = lootPlayerQuestItems.LookupByKey(player.GetGUID());
|
foreach (LootItem lootItem in items)
|
||||||
if (!q_list.Empty())
|
if (!lootItem.is_looted && !lootItem.follow_loot_rules && lootItem.GetAllowedLooters().Contains(player.GetGUID()))
|
||||||
{
|
return true;
|
||||||
foreach (var qi in q_list)
|
|
||||||
{
|
|
||||||
LootItem item = quest_items[qi.index];
|
|
||||||
if (!qi.is_looted && !item.is_looted)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lootPlayerFFAItems = GetPlayerFFAItems();
|
var ffaItems = GetPlayerFFAItems().LookupByKey(player.GetGUID());
|
||||||
var ffa_list = lootPlayerFFAItems.LookupByKey(player.GetGUID());
|
if (ffaItems != null)
|
||||||
if (!ffa_list.Empty())
|
|
||||||
{
|
{
|
||||||
foreach (var fi in ffa_list)
|
bool hasFfaItem = ffaItems.Any(ffaItem => !ffaItem.is_looted);
|
||||||
{
|
if (hasFfaItem)
|
||||||
LootItem item = items[fi.index];
|
return true;
|
||||||
if (!fi.is_looted && !item.is_looted)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
|
|
||||||
var conditional_list = lootPlayerNonQuestNonFFAConditionalItems.LookupByKey(player.GetGUID());
|
|
||||||
if (!conditional_list.Empty())
|
|
||||||
{
|
|
||||||
foreach (var ci in conditional_list)
|
|
||||||
{
|
|
||||||
LootItem item = items[ci.index];
|
|
||||||
if (!ci.is_looted && !item.is_looted)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1181,231 +1012,29 @@ namespace Game.Loots
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BuildLootResponse(LootResponse packet, Player viewer, PermissionTypes permission)
|
public void BuildLootResponse(LootResponse packet, Player viewer)
|
||||||
{
|
{
|
||||||
if (permission == PermissionTypes.None)
|
|
||||||
return;
|
|
||||||
|
|
||||||
packet.Coins = gold;
|
packet.Coins = gold;
|
||||||
|
|
||||||
switch (permission)
|
foreach (LootItem item in items)
|
||||||
{
|
{
|
||||||
case PermissionTypes.Group:
|
var uiType = item.GetUiTypeForPlayer(viewer, this);
|
||||||
case PermissionTypes.Master:
|
if (!uiType.HasValue)
|
||||||
case PermissionTypes.Restricted:
|
continue;
|
||||||
{
|
|
||||||
// if you are not the round-robin group looter, you can only see
|
|
||||||
// blocked rolled items and quest items, and !ffa items
|
|
||||||
for (byte i = 0; i < items.Count; ++i)
|
|
||||||
{
|
|
||||||
if (!items[i].is_looted && !items[i].freeforall && items[i].conditions.Empty() && items[i].AllowedForPlayer(viewer))
|
|
||||||
{
|
|
||||||
LootSlotType slot_type;
|
|
||||||
|
|
||||||
if (items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold
|
LootItemData lootItem = new();
|
||||||
{
|
lootItem.LootListID = (byte)item.LootListId;
|
||||||
switch (permission)
|
lootItem.UIType = uiType.Value;
|
||||||
{
|
lootItem.Quantity = item.count;
|
||||||
case PermissionTypes.Group:
|
lootItem.Loot = new(item);
|
||||||
slot_type = LootSlotType.RollOngoing;
|
packet.Items.Add(lootItem);
|
||||||
break;
|
|
||||||
case PermissionTypes.Master:
|
|
||||||
{
|
|
||||||
if (viewer.GetGroup() && viewer.GetGroup().GetMasterLooterGuid() == viewer.GetGUID())
|
|
||||||
slot_type = LootSlotType.Master;
|
|
||||||
else
|
|
||||||
slot_type = LootSlotType.Locked;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PermissionTypes.Restricted:
|
|
||||||
slot_type = LootSlotType.Locked;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (roundRobinPlayer.IsEmpty() || viewer.GetGUID() == roundRobinPlayer || !items[i].is_underthreshold)
|
|
||||||
{
|
|
||||||
// no round robin owner or he has released the loot
|
|
||||||
// or it IS the round robin group owner
|
|
||||||
// => item is lootable
|
|
||||||
slot_type = LootSlotType.AllowLoot;
|
|
||||||
}
|
|
||||||
else if (!items[i].rollWinnerGUID.IsEmpty())
|
|
||||||
{
|
|
||||||
if (items[i].rollWinnerGUID == viewer.GetGUID())
|
|
||||||
slot_type = LootSlotType.Owner;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// item shall not be displayed.
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(i + 1);
|
|
||||||
lootItem.UIType = slot_type;
|
|
||||||
lootItem.Quantity = items[i].count;
|
|
||||||
lootItem.Loot = new ItemInstance(items[i]);
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PermissionTypes.RoundRobin:
|
|
||||||
{
|
|
||||||
for (var i = 0; i < items.Count; ++i)
|
|
||||||
{
|
|
||||||
if (!items[i].is_looted && !items[i].freeforall && items[i].conditions.Empty() && items[i].AllowedForPlayer(viewer))
|
|
||||||
{
|
|
||||||
if (!roundRobinPlayer.IsEmpty() && viewer.GetGUID() != roundRobinPlayer)
|
|
||||||
// item shall not be displayed.
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(i + 1);
|
|
||||||
lootItem.UIType = LootSlotType.AllowLoot;
|
|
||||||
lootItem.Quantity = items[i].count;
|
|
||||||
lootItem.Loot = new(items[i]);
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PermissionTypes.All:
|
|
||||||
case PermissionTypes.Owner:
|
|
||||||
{
|
|
||||||
for (byte i = 0; i < items.Count; ++i)
|
|
||||||
{
|
|
||||||
if (!items[i].is_looted && !items[i].freeforall && items[i].conditions.Empty() && items[i].AllowedForPlayer(viewer))
|
|
||||||
{
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(i + 1);
|
|
||||||
lootItem.UIType = (permission == PermissionTypes.Owner ? LootSlotType.Owner : LootSlotType.AllowLoot);
|
|
||||||
lootItem.Quantity = items[i].count;
|
|
||||||
lootItem.Loot = new ItemInstance(items[i]);
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LootSlotType slotType = permission == PermissionTypes.Owner ? LootSlotType.Owner : LootSlotType.AllowLoot;
|
|
||||||
var lootPlayerQuestItems = GetPlayerQuestItems();
|
|
||||||
var q_list = lootPlayerQuestItems.LookupByKey(viewer.GetGUID());
|
|
||||||
if (!q_list.Empty())
|
|
||||||
{
|
|
||||||
for (var i = 0; i < q_list.Count; ++i)
|
|
||||||
{
|
|
||||||
NotNormalLootItem qi = q_list[i];
|
|
||||||
LootItem item = quest_items[qi.index];
|
|
||||||
if (!qi.is_looted && !item.is_looted)
|
|
||||||
{
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(items.Count + i + 1);
|
|
||||||
lootItem.Quantity = item.count;
|
|
||||||
lootItem.Loot = new ItemInstance(item);
|
|
||||||
|
|
||||||
switch (permission)
|
|
||||||
{
|
|
||||||
case PermissionTypes.Master:
|
|
||||||
lootItem.UIType = LootSlotType.Master;
|
|
||||||
break;
|
|
||||||
case PermissionTypes.Restricted:
|
|
||||||
lootItem.UIType = item.is_blocked ? LootSlotType.Locked : LootSlotType.AllowLoot;
|
|
||||||
break;
|
|
||||||
case PermissionTypes.Group:
|
|
||||||
case PermissionTypes.RoundRobin:
|
|
||||||
if (!item.is_blocked)
|
|
||||||
lootItem.UIType = LootSlotType.AllowLoot;
|
|
||||||
else
|
|
||||||
lootItem.UIType = LootSlotType.RollOngoing;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
lootItem.UIType = slotType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lootPlayerFFAItems = GetPlayerFFAItems();
|
|
||||||
var ffa_list = lootPlayerFFAItems.LookupByKey(viewer.GetGUID());
|
|
||||||
if (!ffa_list.Empty())
|
|
||||||
{
|
|
||||||
foreach (var fi in ffa_list)
|
|
||||||
{
|
|
||||||
LootItem item = items[fi.index];
|
|
||||||
if (!fi.is_looted && !item.is_looted)
|
|
||||||
{
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(fi.index + 1);
|
|
||||||
lootItem.UIType = slotType;
|
|
||||||
lootItem.Quantity = item.count;
|
|
||||||
lootItem.Loot = new ItemInstance(item);
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems();
|
|
||||||
var conditional_list = lootPlayerNonQuestNonFFAConditionalItems.LookupByKey(viewer.GetGUID());
|
|
||||||
if (!conditional_list.Empty())
|
|
||||||
{
|
|
||||||
foreach (var ci in conditional_list)
|
|
||||||
{
|
|
||||||
LootItem item = items[ci.index];
|
|
||||||
if (!ci.is_looted && !item.is_looted)
|
|
||||||
{
|
|
||||||
LootItemData lootItem = new();
|
|
||||||
lootItem.LootListID = (byte)(ci.index + 1);
|
|
||||||
lootItem.Quantity = item.count;
|
|
||||||
lootItem.Loot = new ItemInstance(item);
|
|
||||||
|
|
||||||
if (item.follow_loot_rules)
|
|
||||||
{
|
|
||||||
switch (permission)
|
|
||||||
{
|
|
||||||
case PermissionTypes.Master:
|
|
||||||
lootItem.UIType = LootSlotType.Master;
|
|
||||||
break;
|
|
||||||
case PermissionTypes.Restricted:
|
|
||||||
lootItem.UIType = item.is_blocked ? LootSlotType.Locked : LootSlotType.AllowLoot;
|
|
||||||
break;
|
|
||||||
case PermissionTypes.Group:
|
|
||||||
case PermissionTypes.RoundRobin:
|
|
||||||
if (!item.is_blocked)
|
|
||||||
lootItem.UIType = LootSlotType.AllowLoot;
|
|
||||||
else
|
|
||||||
lootItem.UIType = LootSlotType.RollOngoing;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
lootItem.UIType = slotType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lootItem.UIType = slotType;
|
|
||||||
|
|
||||||
packet.Items.Add(lootItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
PlayerQuestItems.Clear();
|
|
||||||
|
|
||||||
PlayerFFAItems.Clear();
|
PlayerFFAItems.Clear();
|
||||||
|
|
||||||
PlayerNonQuestNonFFAConditionalItems.Clear();
|
|
||||||
|
|
||||||
foreach (ObjectGuid playerGuid in PlayersLooting)
|
foreach (ObjectGuid playerGuid in PlayersLooting)
|
||||||
{
|
{
|
||||||
Player player = Global.ObjAccessor.FindConnectedPlayer(playerGuid);
|
Player player = Global.ObjAccessor.FindConnectedPlayer(playerGuid);
|
||||||
@@ -1415,7 +1044,6 @@ namespace Game.Loots
|
|||||||
|
|
||||||
PlayersLooting.Clear();
|
PlayersLooting.Clear();
|
||||||
items.Clear();
|
items.Clear();
|
||||||
quest_items.Clear();
|
|
||||||
gold = 0;
|
gold = 0;
|
||||||
unlootedCount = 0;
|
unlootedCount = 0;
|
||||||
roundRobinPlayer = ObjectGuid.Empty;
|
roundRobinPlayer = ObjectGuid.Empty;
|
||||||
@@ -1458,12 +1086,9 @@ namespace Game.Loots
|
|||||||
|
|
||||||
public ObjectGuid GetLootMasterGUID() { return _lootMaster; }
|
public ObjectGuid GetLootMasterGUID() { return _lootMaster; }
|
||||||
|
|
||||||
public MultiMap<ObjectGuid, NotNormalLootItem> GetPlayerQuestItems() { return PlayerQuestItems; }
|
|
||||||
public MultiMap<ObjectGuid, NotNormalLootItem> GetPlayerFFAItems() { return PlayerFFAItems; }
|
public MultiMap<ObjectGuid, NotNormalLootItem> GetPlayerFFAItems() { return PlayerFFAItems; }
|
||||||
public MultiMap<ObjectGuid, NotNormalLootItem> GetPlayerNonQuestNonFFAConditionalItems() { return PlayerNonQuestNonFFAConditionalItems; }
|
|
||||||
|
|
||||||
public List<LootItem> items = new();
|
public List<LootItem> items = new();
|
||||||
public List<LootItem> quest_items = new();
|
|
||||||
public uint gold;
|
public uint gold;
|
||||||
public byte unlootedCount;
|
public byte unlootedCount;
|
||||||
public ObjectGuid roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released.
|
public ObjectGuid roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released.
|
||||||
@@ -1471,9 +1096,7 @@ namespace Game.Loots
|
|||||||
public byte maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3)
|
public byte maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3)
|
||||||
|
|
||||||
List<ObjectGuid> PlayersLooting = new();
|
List<ObjectGuid> PlayersLooting = new();
|
||||||
MultiMap<ObjectGuid, NotNormalLootItem> PlayerQuestItems = new();
|
|
||||||
MultiMap<ObjectGuid, NotNormalLootItem> PlayerFFAItems = new();
|
MultiMap<ObjectGuid, NotNormalLootItem> PlayerFFAItems = new();
|
||||||
MultiMap<ObjectGuid, NotNormalLootItem> PlayerNonQuestNonFFAConditionalItems = new();
|
|
||||||
|
|
||||||
// Loot GUID
|
// Loot GUID
|
||||||
ObjectGuid _guid;
|
ObjectGuid _guid;
|
||||||
|
|||||||
@@ -707,7 +707,7 @@ namespace Game.Loots
|
|||||||
Entries.Add(item);
|
Entries.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(Loot loot, bool rate, ushort lootMode, byte groupId, Player player)
|
public void Process(Loot loot, bool rate, ushort lootMode, byte groupId)
|
||||||
{
|
{
|
||||||
if (groupId != 0) // Group reference uses own processing of the group
|
if (groupId != 0) // Group reference uses own processing of the group
|
||||||
{
|
{
|
||||||
@@ -717,7 +717,7 @@ namespace Game.Loots
|
|||||||
if (Groups[groupId - 1] == null)
|
if (Groups[groupId - 1] == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Groups[groupId - 1].Process(loot, lootMode, player);
|
Groups[groupId - 1].Process(loot, lootMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,17 +738,17 @@ namespace Game.Loots
|
|||||||
|
|
||||||
uint maxcount = (uint)(item.maxcount * WorldConfig.GetFloatValue(WorldCfg.RateDropItemReferencedAmount));
|
uint maxcount = (uint)(item.maxcount * WorldConfig.GetFloatValue(WorldCfg.RateDropItemReferencedAmount));
|
||||||
for (uint loop = 0; loop < maxcount; ++loop) // Ref multiplicator
|
for (uint loop = 0; loop < maxcount; ++loop) // Ref multiplicator
|
||||||
Referenced.Process(loot, rate, lootMode, item.groupid, player);
|
Referenced.Process(loot, rate, lootMode, item.groupid);
|
||||||
}
|
}
|
||||||
else // Plain entries (not a reference, not grouped)
|
else // Plain entries (not a reference, not grouped)
|
||||||
loot.AddItem(item, player); // Chance is already checked, just add
|
loot.AddItem(item); // Chance is already checked, just add
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now processing groups
|
// Now processing groups
|
||||||
foreach (var group in Groups.Values)
|
foreach (var group in Groups.Values)
|
||||||
{
|
{
|
||||||
if (group != null)
|
if (group != null)
|
||||||
group.Process(loot, lootMode, player);
|
group.Process(loot, lootMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void CopyConditions(List<Condition> conditions)
|
public void CopyConditions(List<Condition> conditions)
|
||||||
@@ -971,11 +971,11 @@ namespace Game.Loots
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Process(Loot loot, ushort lootMode, Player player)
|
public void Process(Loot loot, ushort lootMode)
|
||||||
{
|
{
|
||||||
LootStoreItem item = Roll(loot, lootMode);
|
LootStoreItem item = Roll(loot, lootMode);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
loot.AddItem(item, player);
|
loot.AddItem(item);
|
||||||
}
|
}
|
||||||
float RawTotalChance()
|
float RawTotalChance()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ namespace Game.Mails
|
|||||||
// can be empty
|
// can be empty
|
||||||
mailLoot.FillLoot(m_mailTemplateId, LootStorage.Mail, receiver, true, true, LootModes.Default, ItemContext.None);
|
mailLoot.FillLoot(m_mailTemplateId, LootStorage.Mail, receiver, true, true, LootModes.Default, ItemContext.None);
|
||||||
|
|
||||||
uint max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
|
for (uint i = 0; m_items.Count < SharedConst.MaxMailItems && i < mailLoot.items.Count; ++i)
|
||||||
for (uint i = 0; m_items.Count < SharedConst.MaxMailItems && i < max_slot; ++i)
|
|
||||||
{
|
{
|
||||||
LootItem lootitem = mailLoot.LootItemInSlot(i, receiver);
|
LootItem lootitem = mailLoot.LootItemInSlot(i, receiver);
|
||||||
if (lootitem != null)
|
if (lootitem != null)
|
||||||
|
|||||||
Reference in New Issue
Block a user