154 lines
No EOL
4.4 KiB
C#
154 lines
No EOL
4.4 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using PhoenixLib.Events;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Inventory;
|
|
using WingsEmu.Game.Inventory.Event;
|
|
using WingsEmu.Game.Items;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Packets.Enums;
|
|
|
|
namespace WingsEmu.Plugins.BasicImplementations.Inventory;
|
|
|
|
public class InventoryRemoveItemEventHandler : IAsyncEventProcessor<InventoryRemoveItemEvent>
|
|
{
|
|
public async Task HandleAsync(InventoryRemoveItemEvent e, CancellationToken cancellation)
|
|
{
|
|
IClientSession session = e.Sender;
|
|
int itemVnum = e.ItemVnum;
|
|
short amount = e.Amount;
|
|
InventoryItem inventoryItem = e.InventoryItem;
|
|
bool sendPackets = e.SendPackets;
|
|
|
|
if (inventoryItem == null) // find item by vnum
|
|
{
|
|
if (!session.PlayerEntity.HasItem(itemVnum, amount))
|
|
{
|
|
return;
|
|
}
|
|
|
|
short toRemove = amount;
|
|
foreach (InventoryItem invItem in session.PlayerEntity.GetAllPlayerInventoryItems())
|
|
{
|
|
if (toRemove <= 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
GameItemInstance item = invItem?.ItemInstance;
|
|
if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (item.GameItem.Id != itemVnum)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (item.Amount - toRemove <= 0)
|
|
{
|
|
toRemove = (short)(toRemove - item.Amount);
|
|
item.Amount = 0;
|
|
}
|
|
else
|
|
{
|
|
item.Amount -= toRemove;
|
|
toRemove -= amount;
|
|
}
|
|
|
|
if (item.Amount > 0)
|
|
{
|
|
if (sendPackets)
|
|
{
|
|
session.SendInventoryAddPacket(invItem);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (!session.PlayerEntity.RemoveItemFromSlotAndType(invItem.Slot, invItem.InventoryType, out InventoryItem removedItemAmount))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
await session.EmitEventAsync(new InventoryItemDeletedEvent
|
|
{
|
|
ItemInstance = removedItemAmount.ItemInstance,
|
|
ItemAmount = toRemove
|
|
});
|
|
|
|
if (sendPackets)
|
|
{
|
|
session.SendInventoryRemovePacket(removedItemAmount);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
inventoryItem.ItemInstance.Amount -= amount;
|
|
if (inventoryItem.ItemInstance.Amount > 0)
|
|
{
|
|
if (sendPackets)
|
|
{
|
|
session.SendInventoryAddPacket(inventoryItem);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
bool shouldResetStats = false;
|
|
if (e.IsEquipped)
|
|
{
|
|
if (e.InventoryItem.ItemInstance.GameItem.EquipmentSlot == EquipmentType.Amulet)
|
|
{
|
|
await session.EmitEventAsync(new InventoryTakeOffItemEvent(e.InventoryItem.Slot)
|
|
{
|
|
ForceToRandomSlot = true
|
|
});
|
|
shouldResetStats = true;
|
|
}
|
|
|
|
if (e.InventoryItem.ItemInstance.GameItem.EquipmentSlot != EquipmentType.Amulet
|
|
&& (e.InventoryItem.ItemInstance.ItemDeleteTime == null || e.InventoryItem.ItemInstance.ItemDeleteTime < DateTime.UtcNow))
|
|
{
|
|
await session.EmitEventAsync(new InventoryTakeOffItemEvent(e.InventoryItem.Slot)
|
|
{
|
|
ForceToRandomSlot = true
|
|
});
|
|
shouldResetStats = true;
|
|
}
|
|
}
|
|
|
|
if (!session.PlayerEntity.RemoveItemFromSlotAndType(inventoryItem.Slot, inventoryItem.InventoryType, out InventoryItem itemBySlot))
|
|
{
|
|
return;
|
|
}
|
|
|
|
await session.EmitEventAsync(new InventoryItemDeletedEvent
|
|
{
|
|
ItemInstance = itemBySlot.ItemInstance,
|
|
ItemAmount = amount
|
|
});
|
|
|
|
if (sendPackets)
|
|
{
|
|
session.SendInventoryRemovePacket(itemBySlot);
|
|
}
|
|
|
|
if (!e.IsEquipped && !shouldResetStats)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!sendPackets)
|
|
{
|
|
return;
|
|
}
|
|
|
|
session.SendEmptyAmuletBuffPacket();
|
|
session.RefreshStatChar();
|
|
}
|
|
} |