185 lines
7.0 KiB
C#
185 lines
7.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 = GInterface246;
|
|
using LightsState = GStruct155;
|
|
using ResourceCache = GClass1977;
|
|
|
|
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 != EItemViewType.Inventory)
|
|
{
|
|
yield break;
|
|
}
|
|
{
|
|
var component = item.GetItemComponent<FireModeComponent>();
|
|
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<LightComponent>();
|
|
if (component != null)
|
|
{
|
|
// Turn on/off
|
|
yield return new CustomInteraction()
|
|
{
|
|
Caption = () => (component.IsActive ? "TurnOff" : "TurnOn").Localized(),
|
|
Icon = () => ResourceCache.Pop<Sprite>(IconsPrefix + (component.IsActive ? "TurnOff" : "TurnOn")),
|
|
Action = () =>
|
|
{
|
|
Singleton<GUISounds>.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<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)
|
|
{
|
|
foreach (var lightMode in Enumerable.Range(0, component.GetModesCount()))
|
|
{
|
|
Add(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)
|
|
{
|
|
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<TacticalComboVisualController>())
|
|
{
|
|
if (ReferenceEquals(tcvc.LightMod, component))
|
|
{
|
|
tcvc.UpdateBeams();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |