using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WingsAPI.Game.Extensions.ItemExtension.Inventory; using WingsAPI.Packets.Enums.Shells; using WingsEmu.DTOs.Items; using WingsEmu.Game; using WingsEmu.Game._i18n; using WingsEmu.Game._ItemUsage; using WingsEmu.Game._ItemUsage.Event; using WingsEmu.Game.Extensions; using WingsEmu.Game.Inventory; using WingsEmu.Game.Items; using WingsEmu.Game.Networking; using WingsEmu.Packets.Enums; using WingsEmu.Packets.Enums.Chat; namespace WingsEmu.Plugins.BasicImplementations.ItemUsage.Etc.Magical; public class ShellItemHandler : IItemHandler { private static readonly ShellEffectType[] _mainWeaponShells = { ShellEffectType.AntiMagicDisorder, ShellEffectType.GainMoreXP, ShellEffectType.GainMoreCXP, ShellEffectType.GainMoreGold }; private readonly IGameLanguageService _gameLanguage; private readonly IRandomGenerator _randomGenerator; public ShellItemHandler(IGameLanguageService gameLanguage, IRandomGenerator randomGenerator) { _gameLanguage = gameLanguage; _randomGenerator = randomGenerator; } public ItemType ItemType => ItemType.Shell; public long[] Effects => new long[] { 0 }; public async Task HandleAsync(IClientSession session, InventoryUseItemEvent e) { InventoryItem inv = e.Item; string[] packetsplit = e.Packet; if (packetsplit == null) { return; } if (e?.Item == null) { return; } if (inv.ItemInstance.EquipmentOptions == null || !inv.ItemInstance.EquipmentOptions.Any()) { session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_MUST_BE_IDENTIFIED, session.UserLanguage), MsgMessageType.Middle); return; } if (packetsplit.Length < 9) { // MODIFIED PACKET return; } if (!short.TryParse(packetsplit[9], out short eqSlot) || !Enum.TryParse(packetsplit[8], out InventoryType eqType)) { return; } if (!int.TryParse(packetsplit[6], out int requestType)) { return; } GameItemInstance shell = inv.ItemInstance; InventoryItem eq = session.PlayerEntity.GetItemBySlotAndType(eqSlot, eqType); if (eq == null) { // PACKET MODIFIED return; } if (eq.ItemInstance.Type != ItemInstanceType.WearableInstance) { return; } GameItemInstance itemInstance = eq.ItemInstance; if (itemInstance.GameItem.ItemType != ItemType.Armor && shell.GameItem.ItemSubType == 1) { // ARMOR SHELL ONLY APPLY ON ARMORS session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_FOR_ARMOR_ONLY, session.UserLanguage), MsgMessageType.Middle); return; } if (itemInstance.GameItem.ItemType != ItemType.Weapon && shell.GameItem.ItemSubType == 0) { // WEAPON SHELL ONLY APPLY ON WEAPONS session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_FOR_WEAPON_ONLY, session.UserLanguage), MsgMessageType.Middle); return; } switch (requestType) { case 0: session.SendPacket(itemInstance.EquipmentOptions?.Count > 0 ? $"qna #u_i^1^{session.PlayerEntity.Id}^{(short)inv.ItemInstance.GameItem.Type}^{inv.Slot}^1^1^{(short)eqType}^{eqSlot} {_gameLanguage.GetLanguage(GameDialogKey.SHELLS_DIALOG_REPLACE_OPTIONS, session.UserLanguage)}" : $"qna #u_i^1^{session.PlayerEntity.Id}^{(short)inv.ItemInstance.GameItem.Type}^{inv.Slot}^1^1^{(short)eqType}^{eqSlot} {_gameLanguage.GetLanguage(GameDialogKey.SHELLS_DIALOG_ADD_OPTIONS, session.UserLanguage)}"); break; case 1: if (shell.EquipmentOptions == null) { // SHELL NOT IDENTIFIED return; } if (itemInstance.BoundCharacterId != session.PlayerEntity.Id && itemInstance.BoundCharacterId != null) { // NEED TO PERFUME STUFF BEFORE CHANGING SHELL session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELL_SHOUTMESSAGE_NEED_PERFUM_TO_CHANGE_SHELL, session.UserLanguage), MsgMessageType.Middle); return; } if (itemInstance.Rarity < shell.Rarity) { // RARITY TOO HIGH ON SHELL session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_RARITY_TOO_HIGH, session.UserLanguage), MsgMessageType.Middle); return; } if (itemInstance.GameItem.IsHeroic) { // ITEM IS HEROIC session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.GAMBLING_MESSAGE_ITEM_IS_HEROIC, session.UserLanguage), MsgMessageType.Middle); return; } if (itemInstance.GameItem.LevelMinimum < shell.Upgrade) { // SHELL LEVEL TOO HIGH session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_LEVEL_TOO_HIGH, session.UserLanguage), MsgMessageType.Middle); return; } if (itemInstance.EquipmentOptions != null && itemInstance.EquipmentOptions.Any() && _randomGenerator.RandomNumber() > 50) { // BREAK BECAUSE DIDN'T USE MAGIC ERASER session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_BROKEN, session.UserLanguage), MsgMessageType.Middle); await session.RemoveItemFromInventory(item: inv); return; } // If it's second weapon - remove all (Main Weapon) shells if (itemInstance.GameItem.EquipmentSlot == EquipmentType.SecondaryWeapon) { var toRemove = new List(); foreach (EquipmentOptionDTO i in shell.EquipmentOptions) { if (i == null) { continue; } var type = (ShellEffectType)i.Type; if (!_mainWeaponShells.Contains(type)) { continue; } toRemove.Add(i); } foreach (EquipmentOptionDTO remove in toRemove) { shell.EquipmentOptions.Remove(remove); } } itemInstance.EquipmentOptions?.Clear(); itemInstance.EquipmentOptions ??= new List(); foreach (EquipmentOptionDTO i in shell.EquipmentOptions) { session.SendGuriPacket(17, 1, session.PlayerEntity.Id); session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.SHELLS_SHOUTMESSAGE_OPTION_SET, session.UserLanguage), MsgMessageType.Middle); itemInstance.EquipmentOptions.Add(i); } itemInstance.BoundCharacterId = session.PlayerEntity.Id; itemInstance.ShellRarity = shell.Rarity; await session.RemoveItemFromInventory(item: inv); break; } } }