206 lines
8.8 KiB
C#
206 lines
8.8 KiB
C#
using EFT.InventoryLogic;
|
|
using EFT.UI;
|
|
using JetBrains.Annotations;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
using DynamicInteraction = GClass2815;
|
|
using EmptyInteractions = GClass2816<System.Enum>;
|
|
|
|
namespace IcyClawz.CustomInteractions
|
|
{
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public interface ICustomInteractionsProvider { } // Do not implement this directly
|
|
|
|
public interface IItemCustomInteractionsProvider : ICustomInteractionsProvider
|
|
{
|
|
IEnumerable<CustomInteraction> GetCustomInteractions(ItemUiContext uiContext, EItemViewType viewType, Item item);
|
|
}
|
|
|
|
public static class CustomInteractionsManager
|
|
{
|
|
internal static readonly List<ICustomInteractionsProvider> Providers = new List<ICustomInteractionsProvider>();
|
|
|
|
public static void Register(ICustomInteractionsProvider provider)
|
|
{
|
|
if (!Providers.Contains(provider))
|
|
{
|
|
Providers.Add(provider);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CustomInteraction
|
|
{
|
|
internal readonly CustomInteractionImpl Impl;
|
|
|
|
public CustomInteraction()
|
|
{
|
|
Impl = new CustomInteractionImpl();
|
|
}
|
|
|
|
public Func<string> Caption { get => Impl.Caption; set => Impl.Caption = value; }
|
|
public Func<Sprite> Icon { get => Impl.Icon; set => Impl.Icon = value; }
|
|
public Action Action { get => Impl.Action; set => Impl.Action = value; }
|
|
public Func<CustomSubInteractions> SubMenu { get => Impl.SubMenu; set => Impl.SubMenu = value; }
|
|
public Func<bool> Enabled { get => Impl.Enabled; set => Impl.Enabled = value; }
|
|
public Func<string> Error { get => Impl.Error; set => Impl.Error = value; }
|
|
}
|
|
|
|
internal sealed class CustomInteractionImpl : DynamicInteraction
|
|
{
|
|
public CustomInteractionImpl()
|
|
: base(UnityEngine.Random.Range(0, int.MaxValue).ToString("x4")) { }
|
|
|
|
public Func<string> Caption { get; set; }
|
|
public new Func<Sprite> Icon { get; set; }
|
|
public Action Action { get => action_0; set => action_0 = value; }
|
|
public Func<CustomSubInteractions> SubMenu { get; set; }
|
|
public Func<bool> Enabled { get; set; }
|
|
public Func<string> Error { get; set; }
|
|
|
|
public bool IsInteractive() =>
|
|
Enabled?.Invoke() ?? true;
|
|
}
|
|
|
|
public abstract class CustomSubInteractions
|
|
{
|
|
internal readonly CustomSubInteractionsImpl Impl;
|
|
|
|
public CustomSubInteractions(ItemUiContext uiContext)
|
|
{
|
|
Impl = new CustomSubInteractionsImpl(uiContext);
|
|
}
|
|
|
|
public bool ExaminationRequired { get => Impl._ExaminationRequired; set => Impl._ExaminationRequired = value; }
|
|
|
|
public void Add(CustomInteraction customInteraction) =>
|
|
Impl.AddCustomInteraction(customInteraction);
|
|
|
|
public void Remove(CustomInteraction customInteraction) =>
|
|
Impl.RemoveCustomInteraction(customInteraction);
|
|
|
|
public void CallRedraw() =>
|
|
Impl.CallRedraw();
|
|
|
|
public void CallRedraw(string templateId) =>
|
|
Impl.CallRedraw(templateId);
|
|
}
|
|
|
|
internal sealed class CustomSubInteractionsImpl : EmptyInteractions
|
|
{
|
|
public CustomSubInteractionsImpl(ItemUiContext uiContext)
|
|
: base(uiContext) { }
|
|
|
|
public IEnumerable<CustomInteractionImpl> CustomInteractions => DynamicInteractions.OfType<CustomInteractionImpl>();
|
|
|
|
public bool _ExaminationRequired { get; set; } = true;
|
|
|
|
public override bool ExaminationRequired => _ExaminationRequired;
|
|
|
|
public override bool HasIcons => CustomInteractions.Any(customInteraction => customInteraction.Icon != null);
|
|
|
|
public void CallRedraw() =>
|
|
itemUiContext_0.RedrawContextMenus(null);
|
|
}
|
|
|
|
internal static class AbstractInteractionsExtensions
|
|
{
|
|
private static Dictionary<string, DynamicInteraction> GetDynamicInteractions<T>(this GClass2816<T> instance) where T : Enum =>
|
|
typeof(GClass2816<T>).GetField("dictionary_1", BindingFlags.NonPublic | BindingFlags.Instance)
|
|
.GetValue(instance) as Dictionary<string, DynamicInteraction>;
|
|
|
|
public static void AddCustomInteraction<T>(this GClass2816<T> instance, CustomInteraction customInteraction) where T : Enum =>
|
|
instance.GetDynamicInteractions()[customInteraction.Impl.Key] = customInteraction.Impl;
|
|
|
|
public static void RemoveCustomInteraction<T>(this GClass2816<T> instance, CustomInteraction customInteraction) where T : Enum =>
|
|
instance.GetDynamicInteractions().Remove(customInteraction.Impl.Key);
|
|
}
|
|
|
|
internal static class InteractionButtonsContainerExtensions
|
|
{
|
|
private static readonly FieldInfo ButtonsContainerField =
|
|
typeof(InteractionButtonsContainer).GetField("_buttonsContainer", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static RectTransform GetButtonsContainer(this InteractionButtonsContainer instance) =>
|
|
ButtonsContainerField.GetValue(instance) as RectTransform;
|
|
|
|
private static readonly FieldInfo ButtonTemplateField =
|
|
typeof(InteractionButtonsContainer).GetField("_buttonTemplate", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static SimpleContextMenuButton GetButtonTemplate(this InteractionButtonsContainer instance) =>
|
|
ButtonTemplateField.GetValue(instance) as SimpleContextMenuButton;
|
|
|
|
private static readonly FieldInfo CurrentButtonField =
|
|
typeof(InteractionButtonsContainer).GetField("simpleContextMenuButton_0", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static void SetCurrentButton(this InteractionButtonsContainer instance, SimpleContextMenuButton button) =>
|
|
CurrentButtonField.SetValue(instance, button);
|
|
|
|
private static readonly MethodInfo CreateButtonMethod =
|
|
typeof(InteractionButtonsContainer).GetMethod("method_1", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static SimpleContextMenuButton CreateButton(this InteractionButtonsContainer instance,
|
|
string key, string caption, SimpleContextMenuButton template, RectTransform container,
|
|
[CanBeNull] Sprite sprite, [CanBeNull] Action onButtonClicked, [CanBeNull] Action onMouseHover,
|
|
bool subMenu = false, bool autoClose = true) =>
|
|
(SimpleContextMenuButton)CreateButtonMethod.Invoke(instance, new object[] {
|
|
key, caption, template, container, sprite, onButtonClicked, onMouseHover, subMenu, autoClose
|
|
});
|
|
|
|
private static readonly MethodInfo CloseSubMenuMethod =
|
|
typeof(InteractionButtonsContainer).GetMethod("method_4", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static void CloseSubMenu(this InteractionButtonsContainer instance) =>
|
|
CloseSubMenuMethod.Invoke(instance, null);
|
|
|
|
private static readonly MethodInfo AddButtonMethod =
|
|
typeof(InteractionButtonsContainer).GetMethod("method_5", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
|
|
private static void AddButton(this InteractionButtonsContainer instance, SimpleContextMenuButton button) =>
|
|
AddButtonMethod.Invoke(instance, new object[] { button });
|
|
|
|
public static void AddCustomButton(this InteractionButtonsContainer instance, CustomInteractionImpl customInteractionImpl)
|
|
{
|
|
bool isInteractive = customInteractionImpl.IsInteractive();
|
|
SimpleContextMenuButton button = null;
|
|
button = instance.CreateButton(
|
|
customInteractionImpl.Key,
|
|
customInteractionImpl.Caption?.Invoke() ?? string.Empty,
|
|
instance.GetButtonTemplate(),
|
|
instance.GetButtonsContainer(),
|
|
customInteractionImpl.Icon?.Invoke(),
|
|
() =>
|
|
{
|
|
if (isInteractive)
|
|
{
|
|
customInteractionImpl.Execute();
|
|
}
|
|
},
|
|
() =>
|
|
{
|
|
instance.SetCurrentButton(button);
|
|
instance.CloseSubMenu();
|
|
if (isInteractive)
|
|
{
|
|
var subMenu = customInteractionImpl.SubMenu?.Invoke();
|
|
if (subMenu != null)
|
|
{
|
|
instance.SetSubInteractions(subMenu.Impl);
|
|
}
|
|
}
|
|
},
|
|
customInteractionImpl.SubMenu != null,
|
|
false
|
|
);
|
|
button.SetButtonInteraction(
|
|
(isInteractive, customInteractionImpl.Error?.Invoke() ?? string.Empty)
|
|
);
|
|
instance.AddButton(button);
|
|
}
|
|
}
|
|
} |