using Comfort.Common; using EFT; using EFT.InventoryLogic; using EFT.UI; using IcyClawz.CustomInteractions; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using ILightTemplate = GInterface310; using GlobalEvents = GClass3040; namespace IcyClawz.ItemContextMenuExt; internal static class PlayerExtensions { private static readonly FieldInfo InventoryControllerField = typeof(Player).GetField("_inventoryController", BindingFlags.NonPublic | BindingFlags.Instance); public static InventoryControllerClass GetInventoryController(this Player player) => InventoryControllerField.GetValue(player) as InventoryControllerClass; } internal static class LightComponentExtensions { public static int GetModesCount(this LightComponent component) => ((ILightTemplate)component.Item.Template).ModesCount; } internal sealed class CustomInteractionsProvider : IItemCustomInteractionsProvider { internal const string IconsPrefix = "Characteristics/Icons/"; internal static StaticIcons StaticIcons => EFTHardSettings.Instance.StaticIcons; public IEnumerable GetCustomInteractions(ItemUiContext uiContext, EItemViewType viewType, Item item) { if (viewType is not EItemViewType.Inventory) yield break; FireModeComponent fireModeComponent = item.GetItemComponent(); if (fireModeComponent is not null) { // Firing mode yield return new() { Caption = () => "Firing mode", Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.Weapon), SubMenu = () => new FireModeSubMenu(uiContext, fireModeComponent), Enabled = () => fireModeComponent.AvailableEFireModes.Length > 1, Error = () => "This weapon is incapable of selective fire", }; yield break; } LightComponent lightComponent = item.GetItemComponent(); if (lightComponent is not null) { // Turn on/off yield return new() { Caption = () => (lightComponent.IsActive ? "TurnOff" : "TurnOn").Localized(), Icon = () => CacheResourcesPopAbstractClass.Pop(IconsPrefix + (lightComponent.IsActive ? "TurnOff" : "TurnOn")), Action = () => { Singleton.Instance.PlayUISound(EUISoundType.MenuContextMenu); ComponentUtils.SetLightState(lightComponent, !lightComponent.IsActive, lightComponent.SelectedMode); GlobalEvents.RequestGlobalRedraw(); }, }; // Switch mode yield return new() { Caption = () => "Switch mode", Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState), SubMenu = () => new LightModeSubMenu(uiContext, lightComponent), Enabled = () => lightComponent.GetModesCount() > 1, Error = () => "This device has no alternative modes", }; yield break; } } } internal class FireModeSubMenu : CustomSubInteractions { public FireModeSubMenu(ItemUiContext uiContext, FireModeComponent component) : base(uiContext) { AddRange(component.AvailableEFireModes.Select(fireMode => new CustomInteraction() { Caption = () => fireMode.ToString().Localized(), Action = () => { Singleton.Instance.PlayUISound(EUISoundType.MenuContextMenu); ComponentUtils.SetFireMode(component, fireMode); }, Enabled = () => fireMode != component.FireMode, })); } } internal class LightModeSubMenu : CustomSubInteractions { public LightModeSubMenu(ItemUiContext uiContext, LightComponent component) : base(uiContext) { AddRange(Enumerable.Range(0, component.GetModesCount()).Select(lightMode => new CustomInteraction() { Caption = () => $"Mode {lightMode + 1}", Action = () => { Singleton.Instance.PlayUISound(EUISoundType.MenuContextMenu); ComponentUtils.SetLightState(component, component.IsActive, lightMode); }, Enabled = () => lightMode != component.SelectedMode, })); } } internal static class ComponentUtils { public static void SetFireMode(FireModeComponent component, Weapon.EFireMode fireMode) { Player player = GamePlayerOwner.MyPlayer; if (player is not null && player.HandsController is Player.FirearmController fc && component.Item == fc.Item) { if (fc.Item.MalfState.State is Weapon.EMalfunctionState.None) fc.ChangeFireMode(fireMode); else { fc.FirearmsAnimator.MisfireSlideUnknown(false); player.GetInventoryController().ExamineMalfunction(fc.Item, false); } return; } component.SetFireMode(fireMode); } public static void SetLightState(LightComponent component, bool isActive, int lightMode) { Player player = GamePlayerOwner.MyPlayer; if (player is not null && player.HandsController is Player.FirearmController fc && component.Item.IsChildOf(fc.Item)) { fc.SetLightsState([new() { Id = component.Item.Id, IsActive = isActive, LightMode = lightMode }]); return; } component.IsActive = isActive; component.SelectedMode = lightMode; if (player is not null) { foreach (TacticalComboVisualController tcvc in player.GetComponentsInChildren()) { if (ReferenceEquals(tcvc.LightMod, component)) { tcvc.UpdateBeams(); break; } } } } }