168 lines
6.0 KiB
C#
168 lines
6.0 KiB
C#
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<CustomInteraction> GetCustomInteractions(ItemUiContext uiContext, EItemViewType viewType, Item item)
|
|
{
|
|
if (viewType is not EItemViewType.Inventory)
|
|
yield break;
|
|
|
|
FireModeComponent fireModeComponent = item.GetItemComponent<FireModeComponent>();
|
|
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<LightComponent>();
|
|
if (lightComponent is not null)
|
|
{
|
|
// Turn on/off
|
|
yield return new()
|
|
{
|
|
Caption = () => (lightComponent.IsActive ? "TurnOff" : "TurnOn").Localized(),
|
|
Icon = () => CacheResourcesPopAbstractClass.Pop<Sprite>(IconsPrefix + (lightComponent.IsActive ? "TurnOff" : "TurnOn")),
|
|
Action = () =>
|
|
{
|
|
Singleton<GUISounds>.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<GUISounds>.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<GUISounds>.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 not Weapon.EMalfunctionState.None)
|
|
{
|
|
fc.FirearmsAnimator.MisfireSlideUnknown(false);
|
|
player.GetInventoryController().ExamineMalfunction(fc.Item, false);
|
|
return;
|
|
}
|
|
|
|
fc.ChangeFireMode(fireMode);
|
|
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<TacticalComboVisualController>())
|
|
{
|
|
if (ReferenceEquals(tcvc.LightMod, component))
|
|
{
|
|
tcvc.UpdateBeams();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |