using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModdingUtils.Utils;
using NoxyRadialMenu.UI;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace NoxyRadialMenu
{
[BepInPlugin("com.noxy.rounds.radialmenu", "Noxy Radial Menu", "1.0.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class RadialMenuPlugin : BaseUnityPlugin
{
private const string ModId = "com.noxy.rounds.radialmenu";
private const string ModName = "Noxy Radial Menu";
public const string Version = "1.0.6";
public static RadialMenuPlugin instance;
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
instance = this;
new Harmony("com.noxy.rounds.radialmenu").PatchAll();
GameObject val = new GameObject("NoxyRadialMenuManager");
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<RadialMenuManager>();
}
}
}
namespace NoxyRadialMenu.UI
{
public class RadialMenuManager : MonoBehaviour
{
private const int PageSize = 8;
private GameObject canvasObj;
private GameObject menuContainer;
private Text statusText;
private Sprite cachedCircleSprite;
private readonly List<GameObject> slices = new List<GameObject>();
private readonly List<Image> sliceImages = new List<Image>();
private readonly List<int> selectedIndices = new List<int>();
private readonly Dictionary<string, CardInfo> cardMapping = new Dictionary<string, CardInfo>(StringComparer.Ordinal);
private List<string> currentOptions = new List<string>();
private int hoveredIndex = -1;
private int maxSelections = 1;
private int page;
private Coroutine activeCoroutine;
public bool isOpen;
public bool isApplyingCards;
public static bool IsMenuEnabled;
public static RadialMenuManager Instance { get; private set; }
private void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
canvasObj = new GameObject("NoxyRadialMenuCanvas", new Type[1] { typeof(RectTransform) });
canvasObj.transform.SetParent(((Component)this).transform, false);
Canvas obj = canvasObj.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 1000;
CanvasScaler obj2 = canvasObj.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, 1080f);
obj2.matchWidthOrHeight = 0.5f;
menuContainer = new GameObject("MenuContainer", new Type[1] { typeof(RectTransform) });
menuContainer.transform.SetParent(canvasObj.transform, false);
RectTransform val = (RectTransform)menuContainer.transform;
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(0.5f, 0.5f);
val.pivot = val2;
Vector2 anchorMin = (val.anchorMax = val2);
val.anchorMin = anchorMin;
val.sizeDelta = new Vector2(800f, 800f);
statusText = CreateText(menuContainer.transform, "Status", new Vector2(0f, -365f), new Vector2(760f, 80f), 18);
menuContainer.SetActive(false);
}
private static Text CreateText(Transform parent, string name, Vector2 position, Vector2 size, int fontSize)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
val.transform.SetParent(parent, false);
RectTransform val2 = (RectTransform)val.transform;
val2.anchoredPosition = position;
val2.sizeDelta = size;
Text obj = val.AddComponent<Text>();
obj.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
obj.alignment = (TextAnchor)4;
obj.fontSize = fontSize;
((Graphic)obj).color = Color.white;
((Graphic)obj).raycastTarget = false;
obj.supportRichText = false;
obj.resizeTextForBestFit = true;
obj.resizeTextMinSize = 12;
obj.resizeTextMaxSize = fontSize;
return obj;
}
private static Type JjkCardType(CardInfo card)
{
if (!((Object)(object)card == (Object)null))
{
return (from c in ((Component)card).GetComponents<Component>()
where (Object)(object)c != (Object)null
select ((object)c).GetType()).FirstOrDefault((Type t) => t.Assembly.GetName().Name == "JJKCardsMod" && t.Namespace == "JJKCardsMod.Cards" && t.Name.EndsWith("Card", StringComparison.Ordinal));
}
return null;
}
private static string CardId(CardInfo card)
{
object obj = JjkCardType(card)?.FullName;
if (obj == null)
{
if (!((Object)(object)card == (Object)null))
{
return ((Object)((Component)card).gameObject).name.Replace("(Clone)", "").Trim();
}
obj = "";
}
return (string)obj;
}
private static bool IsTechnique(CardInfo card)
{
Type type = JjkCardType(card);
if (type == null)
{
return false;
}
Type type2 = type;
while (type2 != null)
{
if (type2.FullName == "JJKCardsMod.Cards.BaseCharacterCard")
{
return false;
}
type2 = type2.BaseType;
}
return true;
}
private void BuildCardMapping()
{
cardMapping.Clear();
IOrderedEnumerable<CardInfo> orderedEnumerable = (from c in Resources.FindObjectsOfTypeAll<CardInfo>()
where (Object)(object)c != (Object)null
orderby ((Object)((Component)c).gameObject).name.EndsWith("(Clone)", StringComparison.Ordinal)
select c).ThenBy<CardInfo, string>(CardId, StringComparer.Ordinal);
HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
foreach (CardInfo item in orderedEnumerable)
{
string text = CardId(item);
if (IsTechnique(item) && hashSet.Add(text))
{
string text2 = (string.IsNullOrWhiteSpace(item.cardName) ? text : item.cardName);
string text3 = text2;
if (cardMapping.ContainsKey(text3))
{
text3 = text2 + " [" + text + "]";
}
while (cardMapping.ContainsKey(text3))
{
text3 += "*";
}
cardMapping.Add(text3, item);
}
}
}
private void Update()
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
if (isOpen && (!IsMenuEnabled || Input.GetKeyDown((KeyCode)27)))
{
CancelMenu();
return;
}
if (Input.GetKeyDown((KeyCode)118) && !isOpen && !isApplyingCards && IsMenuEnabled)
{
BuildCardMapping();
OpenMenu(cardMapping.Keys.OrderBy<string, string>((string k) => k, StringComparer.Ordinal).ToList(), 2);
}
if (isOpen)
{
float y = Input.mouseScrollDelta.y;
if (y != 0f)
{
ChangePage((!(y > 0f)) ? 1 : (-1));
}
HandleMouseSelection();
if (Input.GetMouseButtonDown(0) && hoveredIndex >= 0)
{
ToggleSelection(hoveredIndex);
}
if (Input.GetKeyUp((KeyCode)118))
{
CloseMenu();
}
}
}
public void OpenMenu(List<string> options, int maxAllowed = 1)
{
if (!isApplyingCards)
{
CancelMenu();
if (options != null && options.Count != 0)
{
currentOptions = new List<string>(options);
maxSelections = Math.Max(1, Math.Min(maxAllowed, options.Count));
page = 0;
isOpen = true;
menuContainer.SetActive(true);
CreatePizzaSlices();
}
}
}
public void CancelMenu()
{
isOpen = false;
hoveredIndex = -1;
selectedIndices.Clear();
if ((Object)(object)menuContainer != (Object)null)
{
menuContainer.SetActive(false);
}
}
public List<int> CloseMenu()
{
List<int> list = new List<int>();
if (!isOpen || isApplyingCards)
{
return list;
}
if (hoveredIndex >= 0 && hoveredIndex < currentOptions.Count)
{
list.AddRange(selectedIndices);
if (list.Count == 0)
{
list.Add(hoveredIndex);
}
}
CancelMenu();
if (list.Count != 0)
{
isApplyingCards = true;
activeCoroutine = ((MonoBehaviour)this).StartCoroutine(ApplySafely(list));
}
return list;
}
private void ChangePage(int direction)
{
int num = (currentOptions.Count + 8 - 1) / 8;
if (num > 1)
{
page = ((page + direction) % num + num) % num;
hoveredIndex = -1;
CreatePizzaSlices();
}
}
private void CreatePizzaSlices()
{
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Expected O, but got Unknown
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
foreach (GameObject slice in slices)
{
slice.SetActive(false);
Object.Destroy((Object)(object)slice);
}
slices.Clear();
sliceImages.Clear();
int num = Math.Min(8, currentOptions.Count - page * 8);
if (num > 0)
{
float num2 = 360f / (float)num;
for (int i = 0; i < num; i++)
{
GameObject val = new GameObject("Slice_" + i, new Type[1] { typeof(RectTransform) });
val.transform.SetParent(menuContainer.transform, false);
RectTransform val2 = (RectTransform)val.transform;
val2.sizeDelta = new Vector2(600f, 600f);
((Transform)val2).localRotation = Quaternion.Euler(0f, 0f, (float)(-i) * num2 + num2 / 2f);
Image val3 = val.AddComponent<Image>();
val3.sprite = CircleSprite();
val3.type = (Type)3;
val3.fillMethod = (FillMethod)4;
val3.fillOrigin = 2;
val3.fillClockwise = true;
val3.fillAmount = 1f / (float)num;
((Graphic)val3).raycastTarget = false;
float num3 = (float)i * num2 * ((float)Math.PI / 180f);
Text obj = CreateText(val.transform, "Title", Vector2.zero, new Vector2(130f, 58f), 18);
((Transform)((Graphic)obj).rectTransform).position = menuContainer.transform.TransformPoint(new Vector3(Mathf.Sin(num3) * 210f, Mathf.Cos(num3) * 210f, 0f));
((Transform)((Graphic)obj).rectTransform).rotation = menuContainer.transform.rotation;
obj.text = currentOptions[page * 8 + i];
slices.Add(val);
sliceImages.Add(val3);
}
UpdateHighlights();
}
}
private void HandleMouseSelection()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
Vector2 hover = default(Vector2);
if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)menuContainer.transform, Vector2.op_Implicit(Input.mousePosition), (Camera)null, ref hover))
{
SetHover(hover);
}
}
private void SetHover(Vector2 local)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
hoveredIndex = -1;
if (slices.Count != 0 && ((Vector2)(ref local)).magnitude >= 50f)
{
float num = 360f / (float)slices.Count;
float num2 = (Mathf.Atan2(local.x, local.y) * 57.29578f + 360f + num / 2f) % 360f;
hoveredIndex = page * 8 + Math.Min(slices.Count - 1, Mathf.FloorToInt(num2 / num));
}
UpdateHighlights();
}
private void ToggleSelection(int index)
{
if (index < 0 || index >= currentOptions.Count)
{
return;
}
if (!selectedIndices.Remove(index))
{
if (selectedIndices.Count >= maxSelections)
{
selectedIndices.RemoveAt(0);
}
selectedIndices.Add(index);
}
UpdateHighlights();
}
private void UpdateHighlights()
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < sliceImages.Count; i++)
{
int num = page * 8 + i;
((Graphic)sliceImages[i]).color = (selectedIndices.Contains(num) ? new Color(0.6f, 0f, 1f, 0.95f) : ((num == hoveredIndex) ? new Color(0.4f, 0f, 0.6f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.9f)));
}
if ((Object)(object)statusText != (Object)null)
{
statusText.text = $"{page + 1}/{Math.Max(1, (currentOptions.Count + 8 - 1) / 8)} | Selected {selectedIndices.Count}/{maxSelections}\nScroll: page Click: select Release V: apply Center / Esc: cancel";
}
}
private Player GetLocalPlayer()
{
if ((Object)(object)PlayerManager.instance == (Object)null || PlayerManager.instance.players == null)
{
return null;
}
return ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && (Object)(object)p.data != (Object)null && (Object)(object)p.data.view != (Object)null && p.data.view.IsMine));
}
private static List<CardInfo> CardsToPurge(IEnumerable<CardInfo> deck, IEnumerable<CardInfo> desired)
{
HashSet<string> ids = new HashSet<string>(desired.Select(CardId), StringComparer.Ordinal);
return deck.Where((CardInfo c) => IsTechnique(c) && !ids.Contains(CardId(c))).ToList();
}
private IEnumerator ApplySafely(List<int> selection)
{
IEnumerator operation = ApplyCardsCoroutine(selection);
try
{
while (true)
{
object current;
try
{
if (!operation.MoveNext())
{
break;
}
current = operation.Current;
}
catch (Exception ex)
{
Debug.LogError("[NoxyRadialMenu] Card swap failed: " + ex);
break;
}
yield return current;
}
}
finally
{
RadialMenuManager radialMenuManager = this;
(operation as IDisposable)?.Dispose();
radialMenuManager.isApplyingCards = false;
radialMenuManager.activeCoroutine = null;
}
}
private IEnumerator ApplyCardsCoroutine(List<int> selection)
{
Player player = GetLocalPlayer();
if ((Object)(object)player == (Object)null || player.data.currentCards == null || Cards.instance == null)
{
yield break;
}
List<CardInfo> desired = new List<CardInfo>();
foreach (int item in selection)
{
if (item >= 0 && item < currentOptions.Count && cardMapping.TryGetValue(currentOptions[item], out var value) && !((Object)(object)value == (Object)null))
{
if (!desired.Contains(value))
{
desired.Add(value);
}
continue;
}
yield break;
}
if (desired.Count == 0)
{
yield break;
}
List<CardInfo> list = CardsToPurge(player.data.currentCards, desired);
Component component = ((Component)player).GetComponent("YutaCopyBehaviour");
FieldInfo fieldInfo = (((Object)(object)component == (Object)null) ? null : ((object)component).GetType().GetField("copiedCardInfo", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
object? obj = fieldInfo?.GetValue(component);
CardInfo val = (CardInfo)((obj is CardInfo) ? obj : null);
HashSet<int> hashSet = new HashSet<int>();
if (list.Any((CardInfo c) => JjkCardType(c)?.Name == "YutaCopyCard") && (Object)(object)val != (Object)null)
{
int num = player.data.currentCards.LastIndexOf(val);
if (num >= 0)
{
hashSet.Add(num);
}
fieldInfo.SetValue(component, null);
}
for (int num2 = 0; num2 < player.data.currentCards.Count; num2++)
{
CardInfo val2 = player.data.currentCards[num2];
if ((Object)(object)val2 != (Object)null && list.Contains(val2))
{
hashSet.Add(num2);
}
}
if (hashSet.Count > 0)
{
Cards.instance.RemoveCardsFromPlayer(player, hashSet.ToArray());
yield return (object)new WaitForSecondsRealtime(0.6f);
}
foreach (CardInfo card in desired)
{
if (!((Object)(object)player == (Object)null) && !((Object)(object)player.data == (Object)null))
{
if (!player.data.currentCards.Any((CardInfo c) => CardId(c) == CardId(card)))
{
Cards.instance.AddCardToPlayer(player, card, false, "", 0f, 0f, true);
yield return null;
}
continue;
}
yield break;
}
}
private Sprite CircleSprite()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)cachedCircleSprite != (Object)null)
{
return cachedCircleSprite;
}
Texture2D val = new Texture2D(512, 512, (TextureFormat)4, false);
Color32[] array = (Color32[])(object)new Color32[262144];
for (int i = 0; i < 512; i++)
{
for (int j = 0; j < 512; j++)
{
array[i * 512 + j] = (((j - 256) * (j - 256) + (i - 256) * (i - 256) <= 65536) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : new Color32((byte)0, (byte)0, (byte)0, (byte)0));
}
}
val.SetPixels32(array);
val.Apply(false, true);
cachedCircleSprite = Sprite.Create(val, new Rect(0f, 0f, 512f, 512f), new Vector2(0.5f, 0.5f));
return cachedCircleSprite;
}
private void OnDisable()
{
CancelMenu();
if (activeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(activeCoroutine);
}
activeCoroutine = null;
isApplyingCards = false;
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
if ((Object)(object)cachedCircleSprite != (Object)null)
{
Object.Destroy((Object)(object)cachedCircleSprite.texture);
Object.Destroy((Object)(object)cachedCircleSprite);
}
}
}
}