using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using ModdingUtils.Utils; using NoxyRadialMenu.UI; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyVersion("0.0.0.0")] namespace NoxyRadialMenu { [BepInPlugin("com.noxy.rounds.radialmenu", "Noxy Radial Menu", "1.0.0")] [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.0"; public static RadialMenuPlugin instance; private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown instance = this; Harmony val = new Harmony("com.noxy.rounds.radialmenu"); val.PatchAll(); GameObject val2 = new GameObject("NoxyRadialMenuManager"); Object.DontDestroyOnLoad((Object)(object)val2); val2.AddComponent(); } } } namespace NoxyRadialMenu.UI { public class RadialMenuManager : MonoBehaviour { private GameObject canvasObj; private Canvas canvas; private GraphicRaycaster raycaster; private GameObject menuContainer; private List slices = new List(); private List sliceImages = new List(); private List sliceTexts = new List(); public bool isOpen = false; public bool isApplyingCards = false; private List selectedIndices = new List(); private int maxSelections = 1; private int hoveredIndex = -1; private List currentOptions; private List currentlyAppliedCards = new List(); private Dictionary cardMapping = new Dictionary(); private bool hasBuiltCardMapping = false; public static bool IsMenuEnabled = false; private Coroutine activeCoroutine; public static RadialMenuManager Instance { get; private set; } private void Awake() { Instance = this; CreateCanvas(); CreateMenuContainer(); menuContainer.SetActive(false); } private void CreateCanvas() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) canvasObj = new GameObject("NoxyRadialMenuCanvas"); canvasObj.transform.SetParent(((Component)this).transform); canvas = canvasObj.AddComponent(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 1000; CanvasScaler val = canvasObj.AddComponent(); val.uiScaleMode = (ScaleMode)1; val.referenceResolution = new Vector2(1920f, 1080f); raycaster = canvasObj.AddComponent(); } private void CreateMenuContainer() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) menuContainer = new GameObject("MenuContainer"); menuContainer.transform.SetParent(canvasObj.transform, false); RectTransform val = menuContainer.AddComponent(); val.anchorMin = new Vector2(0.5f, 0.5f); val.anchorMax = new Vector2(0.5f, 0.5f); val.pivot = new Vector2(0.5f, 0.5f); val.anchoredPosition = Vector2.zero; val.sizeDelta = new Vector2(800f, 800f); } private void ClearSlices() { foreach (GameObject slice in slices) { Object.Destroy((Object)(object)slice); } slices.Clear(); sliceImages.Clear(); sliceTexts.Clear(); } private void CreatePizzaSlices(List options) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_008f: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) ClearSlices(); if (options != null && options.Count != 0) { int count = options.Count; float num = 360f / (float)count; Sprite sprite = CreateCircleSprite(256); for (int i = 0; i < count; i++) { GameObject val = new GameObject("Slice_" + i); val.transform.SetParent(menuContainer.transform, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(600f, 600f); float num2 = 0f - (float)i * num + num / 2f; ((Transform)val2).localRotation = Quaternion.Euler(0f, 0f, num2); Image val3 = val.AddComponent(); val3.sprite = sprite; val3.type = (Type)3; val3.fillMethod = (FillMethod)4; val3.fillOrigin = 2; val3.fillAmount = 1f / (float)count; ((Graphic)val3).color = new Color(0.1f, 0.1f, 0.1f, 0.9f); GameObject val4 = new GameObject("Text"); val4.transform.SetParent(val.transform, false); RectTransform val5 = val4.AddComponent(); val5.sizeDelta = new Vector2(200f, 50f); float num3 = 200f; float num4 = num / 2f * ((float)Math.PI / 180f); val5.anchoredPosition = new Vector2(Mathf.Sin(num4) * num3, Mathf.Cos(num4) * num3); ((Transform)val5).localRotation = Quaternion.Euler(0f, 0f, 0f - num2); Text val6 = val4.AddComponent(); val6.text = options[i]; val6.font = Resources.GetBuiltinResource("Arial.ttf"); val6.alignment = (TextAnchor)4; ((Graphic)val6).color = Color.white; val6.fontSize = 24; slices.Add(val); sliceImages.Add(val3); sliceTexts.Add(val6); } } } private void BuildCardMapping() { if (hasBuiltCardMapping) { return; } hasBuiltCardMapping = true; cardMapping.Clear(); CardInfo[] array = Resources.FindObjectsOfTypeAll(); foreach (CardInfo val in array) { string text = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); if (text.StartsWith("__JJK Cursed Techniques__")) { string key = text.Replace("__JJK Cursed Techniques__", ""); if (!cardMapping.ContainsKey(key)) { cardMapping.Add(key, text); } } } Debug.Log((object)("[NoxyRadialMenu] Dynamically loaded " + cardMapping.Count + " JJK cards.")); } private void Update() { if (Input.GetKeyDown((KeyCode)118) && !isOpen && !isApplyingCards && IsMenuEnabled) { BuildCardMapping(); List list = new List(cardMapping.Keys); list.Sort(); OpenMenu(list, 2); } else if (Input.GetKeyUp((KeyCode)118) && isOpen) { CloseMenu(); } if (isOpen) { HandleMouseSelection(); if (Input.GetMouseButtonDown(0) && hoveredIndex != -1) { ToggleSelection(hoveredIndex); } } } public void OpenMenu(List options, int maxAllowed = 1) { maxSelections = maxAllowed; currentOptions = options; selectedIndices.RemoveAll((int i) => i >= options.Count); hoveredIndex = -1; CreatePizzaSlices(options); isOpen = true; menuContainer.SetActive(true); UpdateHighlights(); } public List CloseMenu() { isOpen = false; isApplyingCards = true; menuContainer.SetActive(false); List list = new List(selectedIndices); Debug.Log((object)("[NoxyRadialMenu] Selected Slots: " + string.Join(", ", list))); if (activeCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(activeCoroutine); } activeCoroutine = ((MonoBehaviour)this).StartCoroutine(ApplyCardsCoroutine(list)); return list; } private Player GetLocalPlayer() { foreach (Player player in PlayerManager.instance.players) { if (player.data.view.IsMine) { return player; } } return null; } private IEnumerator ApplyCardsCoroutine(List selectedSlots) { Player localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null) { Debug.LogError((object)"[NoxyRadialMenu] No local player found!"); isApplyingCards = false; yield break; } Debug.Log((object)("[NoxyRadialMenu] Local player found: " + localPlayer.playerID)); List selectedCardNames = new List(); foreach (int selectedSlot in selectedSlots) { if (selectedSlot >= 0 && selectedSlot < currentOptions.Count) { string key = currentOptions[selectedSlot]; if (cardMapping.ContainsKey(key)) { selectedCardNames.Add(cardMapping[key]); } } } Debug.Log((object)"[NoxyRadialMenu] Diffing current deck against new selections..."); List cardsToPurge = new List(); foreach (CardInfo currentCard in localPlayer.data.currentCards) { if ((Object)(object)currentCard != (Object)null && ((Object)((Component)currentCard).gameObject).name.Contains("__JJK Cursed Techniques__")) { string text = ((Object)((Component)currentCard).gameObject).name.Replace("(Clone)", "").Trim(); if (selectedCardNames.Contains(text)) { selectedCardNames.Remove(text); Debug.Log((object)("[NoxyRadialMenu] Keeping existing card: " + text)); } else if (!cardsToPurge.Contains(currentCard)) { cardsToPurge.Add(currentCard); } } } bool purgingYuta = false; foreach (CardInfo item in cardsToPurge) { if (((Object)((Component)item).gameObject).name.Contains("Rika Copy")) { purgingYuta = true; break; } } if (purgingYuta) { Component component = ((Component)localPlayer).GetComponent("YutaCopyBehaviour"); MonoBehaviour val = (MonoBehaviour)(object)((component is MonoBehaviour) ? component : null); if ((Object)(object)val != (Object)null) { FieldInfo field = ((object)val).GetType().GetField("copiedCardInfo"); if (field != null) { object? value = field.GetValue(val); CardInfo val2 = (CardInfo)((value is CardInfo) ? value : null); if ((Object)(object)val2 != (Object)null && !cardsToPurge.Contains(val2)) { Debug.Log((object)"[NoxyRadialMenu] Purging Yuta's Copied Card along with Rika Copy."); cardsToPurge.Add(val2); field.SetValue(val, null); } } } } Debug.Log((object)("[NoxyRadialMenu] Found " + cardsToPurge.Count + " cards to purge.")); foreach (CardInfo card in cardsToPurge) { Debug.Log((object)("[NoxyRadialMenu] Purging card: " + ((Object)card).name)); try { Cards.instance.RemoveCardFromPlayer(localPlayer, card, (SelectionType)2); } catch (Exception ex) { Debug.LogWarning((object)("[NoxyRadialMenu] Failed to purge card: " + ex.Message)); } yield return (object)new WaitForSecondsRealtime(0.6f); } foreach (string cardObjName in selectedCardNames) { Debug.Log((object)("[NoxyRadialMenu] Searching for NEW card: " + cardObjName)); CardInfo cardToGive = null; CardInfo[] array = Resources.FindObjectsOfTypeAll(); foreach (CardInfo current3 in array) { if (((Object)((Component)current3).gameObject).name.Replace("(Clone)", "").Trim() == cardObjName) { cardToGive = current3; break; } } if ((Object)(object)cardToGive != (Object)null) { Debug.Log((object)("[NoxyRadialMenu] Found card! Applying: " + cardObjName)); Cards.instance.AddCardToPlayer(localPlayer, cardToGive, false, "", 0f, 0f, true); yield return (object)new WaitForEndOfFrame(); } else { Debug.LogError((object)("[NoxyRadialMenu] Card not found via FindObjectsOfTypeAll: " + cardObjName)); } } isApplyingCards = false; } private void ToggleSelection(int index) { if (selectedIndices.Contains(index)) { selectedIndices.Remove(index); } else { if (selectedIndices.Count >= maxSelections) { selectedIndices.RemoveAt(0); } selectedIndices.Add(index); } UpdateHighlights(); } private void HandleMouseSelection() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(Input.mousePosition); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f); Vector2 val3 = val - val2; if (((Vector2)(ref val3)).magnitude < 50f) { if (hoveredIndex != -1) { hoveredIndex = -1; UpdateHighlights(); } return; } float num = Mathf.Atan2(val3.x, val3.y) * 57.29578f; if (num < 0f) { num += 360f; } int count = slices.Count; float num2 = 360f / (float)count; float num3 = (num + num2 / 2f) % 360f; int num4 = Mathf.FloorToInt(num3 / num2); if (num4 != hoveredIndex) { hoveredIndex = num4; UpdateHighlights(); } } private void UpdateHighlights() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < sliceImages.Count; i++) { bool flag = selectedIndices.Contains(i); bool flag2 = i == hoveredIndex; if (flag) { ((Graphic)sliceImages[i]).color = new Color(0.6f, 0f, 1f, 1f); slices[i].transform.localScale = new Vector3(1.15f, 1.15f, 1.15f); } else if (flag2) { ((Graphic)sliceImages[i]).color = new Color(0.4f, 0f, 0.6f, 1f); slices[i].transform.localScale = new Vector3(1.05f, 1.05f, 1.05f); } else { ((Graphic)sliceImages[i]).color = new Color(0.1f, 0.1f, 0.1f, 0.9f); slices[i].transform.localScale = Vector3.one; } } } private Sprite CreateCircleSprite(int radius) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) int num = radius * 2; Texture2D val = new Texture2D(num, num, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[num * num]; Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); Color32 val3 = default(Color32); ((Color32)(ref val3))..ctor((byte)0, (byte)0, (byte)0, (byte)0); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num2 = j - radius; float num3 = i - radius; if (num2 * num2 + num3 * num3 <= (float)(radius * radius)) { array[i * num + j] = val2; } else { array[i * num + j] = val3; } } } val.SetPixels32(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f)); } } }