using System.Linq; using System.Threading; using System.Threading.Tasks; using PhoenixLib.Events; using PhoenixLib.Logging; using WingsAPI.Game.Extensions.ItemExtension.Inventory; using WingsEmu.DTOs.Items; using WingsEmu.Game; using WingsEmu.Game._enum; using WingsEmu.Game._i18n; using WingsEmu.Game.Characters.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; using WingsEmu.Packets.Enums.Chat; namespace WingsEmu.Plugins.BasicImplementations.Event.Items; public class ItemSumEventHandler : IAsyncEventProcessor { private readonly IGameLanguageService _gameLanguage; private readonly ItemSumConfiguration _itemSumConfiguration; private readonly IRandomGenerator _randomGenerator; public ItemSumEventHandler(IRandomGenerator randomGenerator, IGameLanguageService gameLanguage, ItemSumConfiguration itemSumConfiguration) { _randomGenerator = randomGenerator; _gameLanguage = gameLanguage; _itemSumConfiguration = itemSumConfiguration; } public async Task HandleAsync(ItemSumEvent e, CancellationToken cancellation) { IClientSession session = e.Sender; if (e.LeftItem.ItemInstance.Type != ItemInstanceType.WearableInstance) { return; } if (e.RightItem.ItemInstance.Type != ItemInstanceType.WearableInstance) { return; } GameItemInstance leftItem = e.LeftItem.ItemInstance; GameItemInstance rightItem = e.RightItem.ItemInstance; const int sandVnum = (int)ItemVnums.DONA_RIVER_SAND; int totalUpgrade = leftItem.Upgrade + rightItem.Upgrade; // They are the same item if (leftItem == rightItem) { return; } // Items aren't compatible to sum if (totalUpgrade >= 6) { Log.Debug($"[ITEM_SUM] Sum total of {totalUpgrade.ToString()}"); return; } // Neither gloves or boots if ((rightItem.GameItem.EquipmentSlot != EquipmentType.Gloves || leftItem.GameItem.EquipmentSlot != EquipmentType.Gloves) && (leftItem.GameItem.EquipmentSlot != EquipmentType.Boots || rightItem.GameItem.EquipmentSlot != EquipmentType.Boots)) { Log.Debug("[ITEM_SUM] At least one of the items is neither boots or gloves."); return; } // They aren't the same type of equipment if (rightItem.GameItem.EquipmentSlot != leftItem.GameItem.EquipmentSlot) { Log.Debug("[ITEM_SUM] They are not the same type of equipment."); return; } ItemSumMats itemSumMats = _itemSumConfiguration.FirstOrDefault(i => i.SumUpgrade == totalUpgrade); if (itemSumMats == null) { return; } // No money if (session.PlayerEntity.Gold < itemSumMats.Gold) { Log.Debug($"[ITEM_SUM] Not enough gold. Required: {itemSumMats.Gold.ToString()}"); return; } // No sand if (!session.PlayerEntity.HasItem(sandVnum, (short)itemSumMats.RiverSand)) { Log.Debug($"[ITEM_SUM] Not enough sand. Required: {itemSumMats.RiverSand.ToString()}"); return; } await session.RemoveItemFromInventory(sandVnum, (short)itemSumMats.RiverSand); session.PlayerEntity.Gold -= itemSumMats.Gold; InventoryItem rightItemToRemove = session.PlayerEntity.GetItemBySlotAndType(e.RightItem.Slot, e.RightItem.InventoryType); InventoryItem leftItemInstance = session.PlayerEntity.GetItemBySlotAndType(e.LeftItem.Slot, e.LeftItem.InventoryType); ; int rnd = _randomGenerator.RandomNumber(); if (rnd < itemSumMats.SuccessChance) { await session.EmitEventAsync(new ItemSummedEvent { LeftItem = leftItem, RightItem = rightItem, Succeed = true, SumLevel = itemSumMats.SumUpgrade }); leftItem.Upgrade += (byte)(rightItem.Upgrade + 1); leftItem.DarkResistance += (short)(rightItem.DarkResistance + rightItem.GameItem.DarkResistance); leftItem.LightResistance += (short)(rightItem.LightResistance + rightItem.GameItem.LightResistance); leftItem.WaterResistance += (short)(rightItem.WaterResistance + rightItem.GameItem.WaterResistance); leftItem.FireResistance += (short)(rightItem.FireResistance + rightItem.GameItem.FireResistance); await session.RemoveItemFromInventory(item: rightItemToRemove); session.SendPdtiPacket(PdtiType.ResistancesAreFused, leftItem.ItemVNum, 1, e.RightItem.Slot, leftItem.Upgrade, 0); session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SUM_MESSAGE_SUCCESS, session.UserLanguage), MsgMessageType.Middle); session.SendChatMessage(_gameLanguage.GetLanguage(GameDialogKey.SUM_MESSAGE_SUCCESS, session.UserLanguage), ChatMessageColorType.Green); session.BroadcastEffectInRange(EffectType.UpgradeSuccess); session.SendSound(SoundType.CRAFTING_SUCCESS); session.SendInventoryAddPacket(leftItemInstance); } else { session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SUM_MESSAGE_FAILED, session.UserLanguage), MsgMessageType.Middle); session.SendChatMessage(_gameLanguage.GetLanguage(GameDialogKey.SUM_MESSAGE_FAILED, session.UserLanguage), ChatMessageColorType.Red); session.SendSound(SoundType.CRAFTING_FAILED); await session.RemoveItemFromInventory(item: rightItemToRemove); await session.RemoveItemFromInventory(item: leftItemInstance); await session.EmitEventAsync(new ItemSummedEvent { LeftItem = leftItem, RightItem = rightItem, Succeed = false, SumLevel = itemSumMats.SumUpgrade }); } session.PlayerEntity.BroadcastEndDancingGuriPacket(); session.RefreshGold(); session.SendShopEndPacket(ShopEndType.Npc); } }