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 = GInterface252; using LightsState = GStruct154; using ResourceCache = GClass2076; 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 != EItemViewType.Inventory) { yield break; } { var component = item.GetItemComponent(); if (component != null) { // Firing mode yield return new CustomInteraction() { Caption = () => "Firing mode", Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.Weapon), SubMenu = () => new FireModeSubMenu(uiContext, component), Enabled = () => component.AvailableEFireModes.Length > 1, Error = () => "This weapon is incapable of selective fire" }; yield break; } } { var component = item.GetItemComponent(); if (component != null) { // Turn on/off yield return new CustomInteraction() { Caption = () => (component.IsActive ? "TurnOff" : "TurnOn").Localized(), Icon = () => ResourceCache.Pop(IconsPrefix + (component.IsActive ? "TurnOff" : "TurnOn")), Action = () => { Singleton.Instance.PlayUISound(EUISoundType.MenuContextMenu); ComponentUtils.SetLightState(component, !component.IsActive, component.SelectedMode); uiContext.RedrawContextMenus(new[] { item.TemplateId }); } }; // Switch mode yield return new CustomInteraction() { Caption = () => "Switch mode", Icon = () => StaticIcons.GetAttributeIcon(EItemAttributeId.EncodeState), SubMenu = () => new LightModeSubMenu(uiContext, component), Enabled = () => component.GetModesCount() > 1, Error = () => "This device has no alternative modes" }; yield break; } } } } internal class FireModeSubMenu : CustomSubInteractions { public FireModeSubMenu(ItemUiContext uiContext, FireModeComponent component) : base(uiContext) { foreach (var fireMode in component.AvailableEFireModes) { Add(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) { foreach (var lightMode in Enumerable.Range(0, component.GetModesCount())) { Add(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) { var player = GamePlayerOwner.MyPlayer; if (player != null && player.HandsController is Player.FirearmController fc && component.Item == fc.Item) { if (fc.Item.MalfState.State == 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) { var player = GamePlayerOwner.MyPlayer; if (player != null && player.HandsController is Player.FirearmController fc && component.Item.IsChildOf(fc.Item)) { var state = new LightsState { Id = component.Item.Id, IsActive = isActive, LightMode = lightMode }; fc.SetLightsState(new[] { state }); return; } component.IsActive = isActive; component.SelectedMode = lightMode; if (player != null) { foreach (var tcvc in player.GetComponentsInChildren()) { if (ReferenceEquals(tcvc.LightMod, component)) { tcvc.UpdateBeams(); break; } } } } } }