Decompiled source of RoundsTheGathering v2.0.0
DeckBuilder.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using DeckBuilder.CardDelete; using DeckBuilder.Cards; using DeckBuilder.Data; using DeckBuilder.GameIntegration; using DeckBuilder.Networking; using DeckBuilder.UI; using HarmonyLib; using InfoOverhaul.Delta; using Microsoft.CodeAnalysis; using ModdingUtils.Utils; using Photon.Pun; using RarityLib.Utils; using TMPro; using UnboundLib; using UnboundLib.Cards; using UnboundLib.GameModes; using UnboundLib.Networking; using UnboundLib.Utils; using UnboundLib.Utils.UI; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyCompany("DeckBuilder")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+146ac727a7fc6b83f382d57f53cce40478349c58")] [assembly: AssemblyProduct("DeckBuilder Mod for ROUNDS")] [assembly: AssemblyTitle("DeckBuilder")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 DeckBuilder { public static class CardPrerequisiteRegistry { private static readonly Dictionary<string, string> _prerequisites = new Dictionary<string, string>(); public static int Count => _prerequisites.Count; public static void RegisterPrerequisite(string cardName, string requiredCardName) { if (!string.IsNullOrEmpty(cardName) && !string.IsNullOrEmpty(requiredCardName)) { _prerequisites[cardName] = requiredCardName; } } public static bool HasPrerequisite(string cardName) { if (!string.IsNullOrEmpty(cardName)) { return _prerequisites.ContainsKey(cardName); } return false; } public static string GetPrerequisite(string cardName) { if (string.IsNullOrEmpty(cardName) || !_prerequisites.TryGetValue(cardName, out var value)) { return null; } return value; } public static bool IsUnlocked(string cardName, ICollection<string> ownedCardNames) { string prerequisite = GetPrerequisite(cardName); if (string.IsNullOrEmpty(prerequisite)) { return true; } return ownedCardNames?.Contains(prerequisite) ?? false; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("DeckBuilder", "DeckBuilder Mod for ROUNDS", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static string PluginDirectory { get; private set; } private void Awake() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0076: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? ""; RTGLog.Section("Plugin Awake"); new Harmony("DeckBuilder").PatchAll(); ((Component)this).gameObject.AddComponent<DeckManager>(); ((Component)this).gameObject.AddComponent<CardDeleteManager>(); ((Component)this).gameObject.AddComponent<DeckHUDOverlay>(); GameObject val = new GameObject("RTG_UIRoot"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<DeckSelectorScreen>(); val.AddComponent<CreateDeckScreen>(); val.AddComponent<DeckEditorScreen>(); val.AddComponent<DeckBuilderUiInputLock>(); val.AddComponent<CardBarSelectorUI>(); RTGLog.Line("Plugin DeckBuilder loaded."); } private void Start() { DeckBuilderCardRegistrar.RegisterAll(); } } internal static class RTGLog { private const string Sep = "====================="; public static void Section(string title) { Plugin.Logger.LogInfo((object)"====================="); Plugin.Logger.LogInfo((object)("[DeckBuilder] " + title)); Plugin.Logger.LogInfo((object)"====================="); } public static void Line(string message) { Plugin.Logger.LogInfo((object)("[DeckBuilder] " + message)); } public static void Warn(string message) { Plugin.Logger.LogWarning((object)("[DeckBuilder] " + message)); } public static void Error(string message) { Plugin.Logger.LogError((object)("[DeckBuilder] " + message)); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "DeckBuilder"; public const string PLUGIN_NAME = "DeckBuilder Mod for ROUNDS"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace DeckBuilder.UI { public class CreateDeckScreen : MonoBehaviour { public static CreateDeckScreen instance; private Canvas _canvas; private TMP_InputField _nameField; private TMP_InputField _maxSizeField; private Button _createBtn; private TextMeshProUGUI _errorText; public bool IsOpen { get { if ((Object)(object)_canvas != (Object)null) { return ((Component)_canvas).gameObject.activeInHierarchy; } return false; } } private void Awake() { instance = this; BuildUI(); } private void BuildUI() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Expected O, but got Unknown //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Expected O, but got Unknown _canvas = UIHelper.CreateFullscreenCanvas("RTG_CreateDeckScreen", 210); UIHelper.CreateDimmedBackground(((Component)_canvas).transform); Transform transform = ((Component)_canvas).transform; Vector2 anchorMin = new Vector2(0.28f, 0.12f); Vector2 anchorMax = new Vector2(0.72f, 0.88f); Color? bg = new Color(0.08f, 0.08f, 0.12f, 1f); RectTransform parent = UIHelper.CreatePanel(transform, "Panel", anchorMin, anchorMax, default(Vector2), default(Vector2), bg); UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "Title", new Vector2(0f, 0.88f), Vector2.one), "TitleText", "Create New Deck", 34, (TextAlignmentOptions)514); UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "NameLabel", new Vector2(0.05f, 0.74f), new Vector2(0.95f, 0.82f)), "Lbl", "Deck Name", 22, (TextAlignmentOptions)4097); _nameField = UIHelper.CreateInputField((Transform)(object)parent, "NameField", "Enter deck name...", Vector2.zero, Vector2.zero, 22, (ContentType)0); RectTransform component = ((Component)_nameField).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.05f, 0.61f); component.anchorMax = new Vector2(0.95f, 0.73f); Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; ((UnityEvent<string>)(object)_nameField.onValueChanged).AddListener((UnityAction<string>)delegate { Validate(); }); UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "SizeLabel", new Vector2(0.05f, 0.48f), new Vector2(0.95f, 0.57f)), "Lbl", "Max Deck Size (default 50)", 22, (TextAlignmentOptions)4097); _maxSizeField = UIHelper.CreateInputField((Transform)(object)parent, "MaxSizeField", "50", Vector2.zero, Vector2.zero, 22, (ContentType)2); RectTransform component2 = ((Component)_maxSizeField).GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.05f, 0.35f); component2.anchorMax = new Vector2(0.95f, 0.47f); offsetMin = (component2.offsetMax = Vector2.zero); component2.offsetMin = offsetMin; _maxSizeField.text = "50"; ((UnityEvent<string>)(object)_maxSizeField.onValueChanged).AddListener((UnityAction<string>)delegate { Validate(); }); RectTransform parent2 = UIHelper.CreatePanel((Transform)(object)parent, "ErrorPanel", new Vector2(0.05f, 0.26f), new Vector2(0.95f, 0.34f)); _errorText = UIHelper.CreateText((Transform)(object)parent2, "ErrorText", "", 18, (TextAlignmentOptions)514, (Color?)new Color(1f, 0.35f, 0.35f)); _createBtn = AnchorButton(parent, "CreateBtn", "Create Deck!", new Vector2(0.12f, 0.12f), new Vector2(0.88f, 0.24f), new Color(0.15f, 0.5f, 0.15f), 26); ((UnityEvent)_createBtn.onClick).AddListener(new UnityAction(OnCreateClicked)); ((UnityEvent)AnchorButton(parent, "BackBtn", "Back", new Vector2(0.05f, 0.02f), new Vector2(0.4f, 0.1f), new Color(0.3f, 0.3f, 0.3f), 20).onClick).AddListener(new UnityAction(OnBackClicked)); Validate(); ((Component)_canvas).gameObject.SetActive(false); } private static Button AnchorButton(RectTransform parent, string name, string label, Vector2 anchorMin, Vector2 anchorMax, Color bgColor, int fontSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) //IL_0086: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = bgColor; Button obj2 = val.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val2; ColorBlock colors = default(ColorBlock); ((ColorBlock)(ref colors)).normalColor = bgColor; ((ColorBlock)(ref colors)).highlightedColor = bgColor * 1.3f; ((ColorBlock)(ref colors)).pressedColor = bgColor * 0.7f; ((ColorBlock)(ref colors)).disabledColor = new Color(0.25f, 0.25f, 0.25f, 0.6f); ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((ColorBlock)(ref colors)).fadeDuration = 0.1f; ((Selectable)obj2).colors = colors; GameObject val3 = new GameObject("Label"); val3.transform.SetParent(val.transform, false); RectTransform obj3 = val3.AddComponent<RectTransform>(); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; offsetMin = (obj3.offsetMax = Vector2.zero); obj3.offsetMin = offsetMin; TextMeshProUGUI obj4 = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj4).text = label; ((TMP_Text)obj4).fontSize = fontSize; ((TMP_Text)obj4).alignment = (TextAlignmentOptions)514; ((Graphic)obj4).color = Color.white; return obj2; } public void Show() { RTGLog.Section("CreateDeckScreen — Show"); _nameField.text = ""; _maxSizeField.text = "50"; ((TMP_Text)_errorText).text = ""; Validate(); ((Component)_canvas).gameObject.SetActive(true); } public void Hide() { RTGLog.Section("CreateDeckScreen — Hide"); ((Component)_canvas).gameObject.SetActive(false); } private void Validate() { string deckName = _nameField.text.Trim(); bool flag = deckName.Length > 0; bool flag2 = DeckManager.instance?.AllDecks.Find((DeckData d) => d.name == deckName) == null; int result; bool flag3 = int.TryParse(_maxSizeField.text, out result) && result >= 1; string text = ""; if (deckName.Length > 0 && !flag2) { text = "A deck with this name already exists."; } else if (_maxSizeField.text.Length > 0 && !flag3) { text = "Max size must be a number ≥ 1."; } ((TMP_Text)_errorText).text = text; ((Selectable)_createBtn).interactable = flag && flag2 && flag3; } private void OnCreateClicked() { string text = _nameField.text.Trim(); int result; int num = (int.TryParse(_maxSizeField.text, out result) ? result : 50); RTGLog.Section("CreateDeckScreen — Create Deck '" + text + "'"); RTGLog.Line($"maxSize={num}"); DeckData deck = DeckManager.instance.CreateDeck(text, num); Hide(); DeckEditorScreen.instance?.Open(deck); } private void OnBackClicked() { RTGLog.Section("CreateDeckScreen — Back"); Hide(); DeckSelectorScreen.instance?.Show(); } } public class DeckEditorScreen : MonoBehaviour { public static DeckEditorScreen instance; private const string MyDeckCategory = "My Deck"; private const string AllCardsCategory = "All Cards"; private const string SearchResultsCategory = "Search Results"; private const int CardsPerPage = 50; private const int MinSearchLength = 3; private static readonly Color PageIdleColor = new Color(0.15f, 0.15f, 0.22f); private static readonly Color PageSelectedColor = Color.white; private static readonly Color PageHoverColor = new Color(0.35f, 0.55f, 1f); private static readonly Color PagePressedColor = new Color(0.25f, 0.45f, 0.9f); private static readonly Color PageSelectedTextColor = new Color(0.1f, 0.1f, 0.15f); private static readonly Color PageIdleTextColor = Color.white; private DeckData _deck; private string _currentCategory; private int _currentPage; private string _searchQuery = ""; private bool _isSearchActive; private List<CardInfo> _cachedCategoryCards = new List<CardInfo>(); private Canvas _canvas; private TMP_InputField _searchField; private TextMeshProUGUI _deckCountText; private Transform _cardGridContent; private Transform _categoryButtonParent; private Transform _pageButtonParent; private ScrollRect _cardScrollRect; private readonly List<Button> _categoryButtons = new List<Button>(); private readonly List<string> _categoryButtonNames = new List<string>(); private readonly List<Button> _pageButtons = new List<Button>(); private GameObject _maxSizeModal; private TMP_InputField _maxSizeModalField; private TextMeshProUGUI _maxSizeModalError; private readonly List<GameObject> _cardRows = new List<GameObject>(); public bool IsOpen { get { if ((Object)(object)_canvas != (Object)null) { return ((Component)_canvas).gameObject.activeInHierarchy; } return false; } } private void Awake() { instance = this; BuildUI(); } public void Open(DeckData deck) { RTGLog.Section("DeckEditorScreen — Open deck '" + deck?.name + "'"); _deck = deck; ClearSearch(); ((Component)_canvas).gameObject.SetActive(true); BuildCategoryButtons(); ShowCategory("All Cards"); } private void OnDisable() { RTGLog.Section("DeckEditorScreen — OnDisable (close)"); if (_deck == null) { RTGLog.Line("No deck loaded — nothing to save."); } else if (_deck.TotalCount <= _deck.maxSize) { DeckManager.instance?.Save(); RTGLog.Line($"Auto-saved '{_deck.name}' ({_deck.TotalCount}/{_deck.maxSize} cards)."); } else { RTGLog.Warn($"Deck over limit ({_deck.TotalCount}/{_deck.maxSize}) — NOT saved."); } } private void BuildUI() { //IL_005e: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Expected O, but got Unknown //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Expected O, but got Unknown //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Expected O, but got Unknown //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_058a: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Expected O, but got Unknown _canvas = UIHelper.CreateFullscreenCanvas("RTG_DeckEditorScreen", 220); UIHelper.CreateDimmedBackground(((Component)_canvas).transform); RectTransform parent = UIHelper.CreateStretchPanel(((Component)_canvas).transform, "Outer", 20f, 20f, 20f, 20f, (Color?)new Color(0.06f, 0.06f, 0.09f, 0.97f)); Vector2 anchorMin = new Vector2(0f, 0.92f); Vector2 one = Vector2.one; Color? bg = new Color(0.1f, 0.1f, 0.15f, 0.95f); RectTransform parent2 = UIHelper.CreatePanel((Transform)(object)parent, "TopBar", anchorMin, one, default(Vector2), default(Vector2), bg); _searchField = UIHelper.CreateInputField((Transform)(object)parent2, "SearchField", "Search cards (3+ chars)...", Vector2.zero, Vector2.zero, 20, (ContentType)0); RectTransform component = ((Component)_searchField).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.01f, 0.15f); component.anchorMax = new Vector2(0.35f, 0.85f); Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; ((UnityEvent<string>)(object)_searchField.onValueChanged).AddListener((UnityAction<string>)OnSearchChanged); _deckCountText = UIHelper.CreateText((Transform)(object)parent2, "DeckCountText", "Cards in Deck: 0", 22, (TextAlignmentOptions)4097); RectTransform component2 = ((Component)_deckCountText).GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.36f, 0f); component2.anchorMax = new Vector2(0.65f, 1f); offsetMin = (component2.offsetMax = Vector2.zero); component2.offsetMin = offsetMin; Button obj = UIHelper.CreateButton((Transform)(object)parent2, "ChangeSizeBtn", "Change Max Size", Vector2.zero, Vector2.zero, 18, (Color?)new Color(0.35f, 0.2f, 0.05f), (Color?)null); RectTransform component3 = ((Component)obj).GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0.66f, 0.1f); component3.anchorMax = new Vector2(0.85f, 0.9f); offsetMin = (component3.offsetMax = Vector2.zero); component3.offsetMin = offsetMin; ((UnityEvent)obj.onClick).AddListener(new UnityAction(OpenMaxSizeModal)); Button obj2 = UIHelper.CreateButton((Transform)(object)parent2, "CloseBtn", "Close", Vector2.zero, Vector2.zero, 18, (Color?)new Color(0.45f, 0.1f, 0.1f), (Color?)null); RectTransform component4 = ((Component)obj2).GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.87f, 0.1f); component4.anchorMax = new Vector2(0.99f, 0.9f); offsetMin = (component4.offsetMax = Vector2.zero); component4.offsetMin = offsetMin; ((UnityEvent)obj2.onClick).AddListener(new UnityAction(CloseScreen)); Vector2 zero5 = Vector2.zero; Vector2 anchorMax = new Vector2(0.18f, 0.92f); bg = new Color(0.08f, 0.08f, 0.12f, 0.9f); RectTransform component5 = BuildScrollRect((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "LeftPanel", zero5, anchorMax, default(Vector2), default(Vector2), bg), "CategoryScroll", out _categoryButtonParent).GetComponent<RectTransform>(); component5.anchorMin = Vector2.zero; component5.anchorMax = Vector2.one; offsetMin = (component5.offsetMax = Vector2.zero); component5.offsetMin = offsetMin; ((object)((Component)((Component)_categoryButtonParent).GetComponent<RectTransform>()).GetComponent<VerticalLayoutGroup>())?.GetType(); VerticalLayoutGroup obj3 = ((Component)_categoryButtonParent).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 4f; ((LayoutGroup)obj3).padding = new RectOffset(4, 4, 4, 4); Vector2 anchorMin2 = new Vector2(0.19f, 0f); Vector2 anchorMax2 = new Vector2(1f, 0.92f); bg = new Color(0.05f, 0.05f, 0.08f, 1f); RectTransform parent3 = UIHelper.CreatePanel((Transform)(object)parent, "RightPanel", anchorMin2, anchorMax2, default(Vector2), default(Vector2), bg); Vector2 anchorMin3 = new Vector2(0f, 0f); Vector2 anchorMax3 = new Vector2(1f, 0.07f); bg = new Color(0.08f, 0.08f, 0.12f, 0.95f); RectTransform val = UIHelper.CreatePanel((Transform)(object)parent3, "PageBar", anchorMin3, anchorMax3, default(Vector2), default(Vector2), bg); GameObject val2 = new GameObject("PageContent"); val2.transform.SetParent(((Component)val).transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.pivot = new Vector2(0f, 0.5f); val3.offsetMin = new Vector2(8f, 4f); val3.offsetMax = new Vector2(-8f, -4f); _pageButtonParent = (Transform)(object)val3; HorizontalLayoutGroup obj4 = val2.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 6f; ((LayoutGroup)obj4).padding = new RectOffset(4, 4, 0, 0); ((LayoutGroup)obj4).childAlignment = (TextAnchor)3; GameObject val4 = BuildScrollRect((Transform)(object)parent3, "CardScroll", out _cardGridContent); RectTransform component6 = val4.GetComponent<RectTransform>(); component6.anchorMin = new Vector2(0f, 0.07f); component6.anchorMax = Vector2.one; offsetMin = (component6.offsetMax = Vector2.zero); component6.offsetMin = offsetMin; GridLayoutGroup obj5 = ((Component)_cardGridContent).gameObject.AddComponent<GridLayoutGroup>(); obj5.cellSize = new Vector2(220f, 300f); obj5.spacing = new Vector2(10f, 10f); ((LayoutGroup)obj5).padding = new RectOffset(10, 10, 10, 10); obj5.startCorner = (Corner)0; obj5.startAxis = (Axis)0; ((LayoutGroup)obj5).childAlignment = (TextAnchor)0; obj5.constraint = (Constraint)0; _cardScrollRect = val4.GetComponent<ScrollRect>(); BuildMaxSizeModal((Transform)(object)parent); ((Component)_canvas).gameObject.SetActive(false); } private static GameObject BuildScrollRect(Transform parent, string name, out Transform content, bool horizontal = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; ScrollRect obj2 = val.AddComponent<ScrollRect>(); obj2.horizontal = horizontal; obj2.vertical = !horizontal; obj2.movementType = (MovementType)2; obj2.scrollSensitivity = 80f; GameObject val2 = new GameObject("Viewport"); val2.transform.SetParent(val.transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; offsetMin = (val3.offsetMax = Vector2.zero); val3.offsetMin = offsetMin; val3.pivot = (horizontal ? new Vector2(0f, 0.5f) : new Vector2(0f, 1f)); ((Graphic)val2.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.01f); val2.AddComponent<Mask>().showMaskGraphic = false; obj2.viewport = val3; GameObject val4 = new GameObject("Content"); val4.transform.SetParent(val2.transform, false); RectTransform val5 = val4.AddComponent<RectTransform>(); if (horizontal) { val5.anchorMin = new Vector2(0f, 0f); val5.anchorMax = new Vector2(0f, 1f); val5.pivot = new Vector2(0f, 0.5f); } else { val5.anchorMin = new Vector2(0f, 1f); val5.anchorMax = new Vector2(1f, 1f); val5.pivot = new Vector2(0f, 1f); } val5.sizeDelta = Vector2.zero; val5.anchoredPosition = Vector2.zero; ContentSizeFitter val6 = val4.AddComponent<ContentSizeFitter>(); if (horizontal) { val6.horizontalFit = (FitMode)2; val6.verticalFit = (FitMode)0; } else { val6.horizontalFit = (FitMode)0; val6.verticalFit = (FitMode)2; } obj2.content = val5; content = (Transform)(object)val5; return val; } private void BuildCategoryButtons() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) RTGLog.Section("DeckEditorScreen — BuildCategoryButtons"); foreach (Transform item in _categoryButtonParent) { Object.Destroy((Object)(object)((Component)item).gameObject); } _categoryButtons.Clear(); _categoryButtonNames.Clear(); RTGLog.Line($"CardManager.categories.Count = {CardManager.categories.Count}"); if (CardManager.categories.Count == 0) { RTGLog.Warn("No categories found in CardManager!"); } AddCategoryButton("My Deck"); AddCategoryButton("All Cards"); foreach (string category in CardManager.categories) { AddCategoryButton(category); } Canvas.ForceUpdateCanvases(); Transform categoryButtonParent = _categoryButtonParent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((categoryButtonParent is RectTransform) ? categoryButtonParent : null)); RTGLog.Line($"Built {_categoryButtons.Count} category button(s)."); } private void AddCategoryButton(string cat) { RTGLog.Line(" Adding category button: '" + cat + "'"); string captured = cat; Button item = CreateCategoryButton(_categoryButtonParent, cat, delegate { ShowCategory(captured); }); _categoryButtons.Add(item); _categoryButtonNames.Add(cat); } private void ShowCategory(string category) { RTGLog.Section("DeckEditorScreen — ShowCategory '" + category + "'"); if (_isSearchActive && category != "Search Results") { ClearSearch(); } _isSearchActive = false; _currentCategory = category; _currentPage = 0; _cachedCategoryCards = GetCardsForCategory(category); RTGLog.Line($"Resolved {_cachedCategoryCards.Count} card(s) for category '{category}'."); UpdateCategoryButtonStyles(); RebuildPageButtons(); ShowPage(0); } private void ShowPage(int page) { int pageCount = GetPageCount(); _currentPage = Mathf.Clamp(page, 0, Mathf.Max(0, pageCount - 1)); ClearCardRows(); if (_cachedCategoryCards.Count == 0) { RTGLog.Warn("No cards found for category '" + _currentCategory + "'."); UpdatePageButtonStyles(); UpdateDeckCountDisplay(); return; } int num = _currentPage * 50; int num2 = Mathf.Min(num + 50, _cachedCategoryCards.Count); int num3 = 0; for (int i = num; i < num2; i++) { CardInfo val = _cachedCategoryCards[i]; if (!((Object)(object)val == (Object)null)) { BuildCardRow(val); num3++; } } RTGLog.Line($"Built {num3} card row(s) for '{_currentCategory}' page {_currentPage + 1}/{pageCount}."); if ((Object)(object)_cardScrollRect != (Object)null) { _cardScrollRect.verticalNormalizedPosition = 1f; } Canvas.ForceUpdateCanvases(); Transform cardGridContent = _cardGridContent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((cardGridContent is RectTransform) ? cardGridContent : null)); UpdatePageButtonStyles(); UpdateDeckCountDisplay(); } private void ClearCardRows() { foreach (GameObject cardRow in _cardRows) { if ((Object)(object)cardRow != (Object)null) { Object.DestroyImmediate((Object)(object)cardRow); } } _cardRows.Clear(); } private int GetPageCount() { if (_cachedCategoryCards.Count != 0) { return Mathf.CeilToInt((float)_cachedCategoryCards.Count / 50f); } return 1; } private void RebuildPageButtons() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item2 in _pageButtonParent) { Object.Destroy((Object)(object)((Component)item2).gameObject); } _pageButtons.Clear(); int pageCount = GetPageCount(); for (int i = 0; i < pageCount; i++) { int pageIndex = i; string label = (i + 1).ToString(); Button item = CreatePageButton(_pageButtonParent, label, pageIndex); _pageButtons.Add(item); } Canvas.ForceUpdateCanvases(); Transform pageButtonParent = _pageButtonParent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((pageButtonParent is RectTransform) ? pageButtonParent : null)); } private Button CreateCategoryButton(Transform parent, string label, Action onClick) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Cat_" + label); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(1f, 1f); obj.pivot = new Vector2(0.5f, 1f); obj.sizeDelta = new Vector2(0f, 44f); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = PageIdleColor; ((Graphic)val2).raycastTarget = true; Button val3 = val.AddComponent<Button>(); ((Selectable)val3).targetGraphic = (Graphic)(object)val2; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { onClick(); }); LayoutElement obj2 = val.AddComponent<LayoutElement>(); obj2.preferredHeight = 44f; obj2.minHeight = 44f; obj2.flexibleHeight = 0f; AddNavButtonLabel(val.transform, label, 18, (TextAlignmentOptions)514); return val3; } private Button CreatePageButton(Transform parent, string label, int pageIndex) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Page_" + label); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 0f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 0.5f); obj.sizeDelta = new Vector2(40f, 0f); Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = PageIdleColor; ((Graphic)val2).raycastTarget = true; Button val3 = val.AddComponent<Button>(); ((Selectable)val3).targetGraphic = (Graphic)(object)val2; ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { ShowPage(pageIndex); }); LayoutElement obj2 = val.AddComponent<LayoutElement>(); obj2.preferredWidth = 40f; obj2.minWidth = 40f; obj2.flexibleWidth = 0f; AddNavButtonLabel(val.transform, label, 18, (TextAlignmentOptions)514); return val3; } private static void AddNavButtonLabel(Transform parent, string text, int fontSize, TextAlignmentOptions alignment) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) GameObject val = new GameObject("Label"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj2).text = text; ((TMP_Text)obj2).fontSize = fontSize; ((TMP_Text)obj2).alignment = alignment; ((Graphic)obj2).color = PageIdleTextColor; ((Graphic)obj2).raycastTarget = false; } private void UpdateCategoryButtonStyles() { for (int i = 0; i < _categoryButtons.Count; i++) { Button val = _categoryButtons[i]; if (!((Object)(object)val == (Object)null)) { bool selected = !_isSearchActive && i < _categoryButtonNames.Count && _categoryButtonNames[i] == _currentCategory; ApplyNavButtonStyle(val, selected); } } } private void UpdatePageButtonStyles() { for (int i = 0; i < _pageButtons.Count; i++) { Button val = _pageButtons[i]; if (!((Object)(object)val == (Object)null)) { bool selected = i == _currentPage; ApplyNavButtonStyle(val, selected); } } } private static void ApplyNavButtonStyle(Button btn, bool selected) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Image component = ((Component)btn).GetComponent<Image>(); if (!((Object)(object)component == (Object)null)) { Color val = (selected ? PageSelectedColor : PageIdleColor); Color highlightedColor = (selected ? PageSelectedColor : PageHoverColor); Color pressedColor = (Color)(selected ? new Color(0.9f, 0.9f, 0.9f) : PagePressedColor); ((Graphic)component).color = val; ColorBlock colors = default(ColorBlock); ((ColorBlock)(ref colors)).normalColor = val; ((ColorBlock)(ref colors)).highlightedColor = highlightedColor; ((ColorBlock)(ref colors)).pressedColor = pressedColor; ((ColorBlock)(ref colors)).disabledColor = new Color(0.3f, 0.3f, 0.3f, 0.5f); ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((ColorBlock)(ref colors)).fadeDuration = 0.08f; ((Selectable)btn).colors = colors; TextMeshProUGUI componentInChildren = ((Component)btn).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = (selected ? PageSelectedTextColor : PageIdleTextColor); } } } private List<CardInfo> GetCardsForCategory(string category) { if (category == "My Deck") { return GetMyDeckCards(); } if (category == "All Cards") { return GetAllCardsAlphabetical(); } string[] cardsInCategory = CardManager.GetCardsInCategory(category); if (cardsInCategory == null || cardsInCategory.Length == 0) { return new List<CardInfo>(); } List<CardInfo> list = new List<CardInfo>(cardsInCategory.Length); string[] array = cardsInCategory; for (int i = 0; i < array.Length; i++) { CardInfo cardInfoWithName = CardManager.GetCardInfoWithName(array[i]); if ((Object)(object)cardInfoWithName != (Object)null) { list.Add(cardInfoWithName); } } SortCardsAlphabeticalThenRarity(list); return list; } private List<CardInfo> GetAllCardsAlphabetical() { List<CardInfo> list = new List<CardInfo>(CardManager.cards.Count); foreach (string key in CardManager.cards.Keys) { CardInfo cardInfoWithName = CardManager.GetCardInfoWithName(key); if ((Object)(object)cardInfoWithName != (Object)null) { list.Add(cardInfoWithName); } } SortCardsAlphabeticalThenRarity(list); return list; } private List<CardInfo> GetMyDeckCards() { List<CardInfo> list = new List<CardInfo>(); if (_deck?.cards == null) { return list; } foreach (CardEntry card in _deck.cards) { if (card != null && card.count > 0 && !string.IsNullOrEmpty(card.cardObjectName)) { CardInfo cardInfoWithName = CardManager.GetCardInfoWithName(card.cardObjectName); if ((Object)(object)cardInfoWithName != (Object)null) { list.Add(cardInfoWithName); } } } SortCardsAlphabeticalThenRarity(list); return list; } private void RefreshMyDeckViewIfActive() { if (!(_currentCategory != "My Deck")) { _cachedCategoryCards = GetMyDeckCards(); int pageCount = GetPageCount(); if (_currentPage >= pageCount) { _currentPage = Mathf.Max(0, pageCount - 1); } RebuildPageButtons(); ShowPage(_currentPage); } } private void OnSearchChanged(string query) { _searchQuery = query?.Trim() ?? ""; if (_searchQuery.Length >= 3) { _isSearchActive = true; _currentCategory = "Search Results"; _currentPage = 0; _cachedCategoryCards = SearchCards(_searchQuery); RTGLog.Line($"Search '{_searchQuery}' found {_cachedCategoryCards.Count} card(s)."); UpdateCategoryButtonStyles(); RebuildPageButtons(); ShowPage(0); } else if (_isSearchActive) { _isSearchActive = false; ShowCategory("All Cards"); } } private List<CardInfo> SearchCards(string query) { List<CardInfo> list = new List<CardInfo>(); if (string.IsNullOrEmpty(query)) { return list; } string value = query.ToLowerInvariant(); foreach (string key in CardManager.cards.Keys) { CardInfo cardInfoWithName = CardManager.GetCardInfoWithName(key); if (!((Object)(object)cardInfoWithName == (Object)null)) { bool num = !string.IsNullOrEmpty(cardInfoWithName.cardName) && cardInfoWithName.cardName.ToLowerInvariant().Contains(value); bool flag = !string.IsNullOrEmpty(cardInfoWithName.cardDestription) && cardInfoWithName.cardDestription.ToLowerInvariant().Contains(value); if (num || flag) { list.Add(cardInfoWithName); } } } SortCardsAlphabeticalThenRarity(list); return list; } private void ClearSearch() { if ((Object)(object)_searchField != (Object)null) { _searchField.text = ""; } _searchQuery = ""; _isSearchActive = false; } private static void SortCardsAlphabeticalThenRarity(List<CardInfo> cards) { cards.Sort(delegate(CardInfo a, CardInfo b) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) int num = CompareFirstLetter(a?.cardName, b?.cardName); if (num != 0) { return num; } int num2 = ((Enum)(Rarity)(ref a.rarity)).CompareTo((object?)b.rarity); return (num2 != 0) ? num2 : string.Compare(a.cardName, b.cardName, StringComparison.OrdinalIgnoreCase); }); } private static int CompareFirstLetter(string a, string b) { char sortLetter = GetSortLetter(a); char sortLetter2 = GetSortLetter(b); return sortLetter.CompareTo(sortLetter2); } private static char GetSortLetter(string name) { if (string.IsNullOrEmpty(name)) { return '\0'; } return char.ToUpperInvariant(name[0]); } private void BuildCardRow(CardInfo cardInfo) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00e5: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Expected O, but got Unknown //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Expected O, but got Unknown //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Expected O, but got Unknown //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_0647: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_065d: Unknown result type (might be due to invalid IL or missing references) //IL_0662: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_066a: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) //IL_06cb: Expected O, but got Unknown //IL_06d9: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Expected O, but got Unknown //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_06f9: Expected O, but got Unknown string name = ((Object)((Component)cardInfo).gameObject).name; CardEntry entry = GetOrCreateEntry(name); int maxCount = DeckManager.MaxCountForCard(cardInfo); GameObject val = new GameObject("Card_" + name); val.transform.SetParent(_cardGridContent, false); val.AddComponent<RectTransform>().sizeDelta = new Vector2(220f, 300f); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 220f; obj.preferredHeight = 300f; _cardRows.Add(val); Image bgImg = val.AddComponent<Image>(); ((Graphic)bgImg).color = new Color(0.1f, 0.1f, 0.15f, 1f); ((Graphic)bgImg).raycastTarget = true; SetupCardVisual(cardInfo, val); GameObject val2 = new GameObject("RarityLabel"); val2.transform.SetParent(val.transform, false); RectTransform obj2 = val2.AddComponent<RectTransform>(); obj2.anchorMin = new Vector2(0f, 0f); obj2.anchorMax = new Vector2(1f, 0.12f); Vector2 offsetMin = (obj2.offsetMax = Vector2.zero); obj2.offsetMin = offsetMin; Image obj3 = val2.AddComponent<Image>(); ((Graphic)obj3).color = new Color(0f, 0f, 0f, 0.7f); ((Graphic)obj3).raycastTarget = false; GameObject val3 = new GameObject("RarityText"); val3.transform.SetParent(val2.transform, false); RectTransform obj4 = val3.AddComponent<RectTransform>(); obj4.anchorMin = Vector2.zero; obj4.anchorMax = Vector2.one; offsetMin = (obj4.offsetMax = Vector2.zero); obj4.offsetMin = offsetMin; TextMeshProUGUI obj5 = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj5).text = $"{cardInfo.cardName} ({cardInfo.rarity})"; ((TMP_Text)obj5).fontSize = 11f; ((TMP_Text)obj5).alignment = (TextAlignmentOptions)514; ((Graphic)obj5).color = RarityColor(cardInfo.rarity); ((TMP_Text)obj5).enableWordWrapping = false; ((TMP_Text)obj5).overflowMode = (TextOverflowModes)1; ((Graphic)obj5).raycastTarget = false; GameObject controlsGo = new GameObject("Controls"); controlsGo.transform.SetParent(val.transform, false); RectTransform obj6 = controlsGo.AddComponent<RectTransform>(); obj6.anchorMin = Vector2.zero; obj6.anchorMax = Vector2.one; offsetMin = (obj6.offsetMax = Vector2.zero); obj6.offsetMin = offsetMin; controlsGo.SetActive(entry.count > 0); GameObject val4 = new GameObject("MinusBtn"); val4.transform.SetParent(controlsGo.transform, false); RectTransform obj7 = val4.AddComponent<RectTransform>(); obj7.anchorMin = new Vector2(0f, 0f); obj7.anchorMax = new Vector2(0f, 0f); obj7.pivot = new Vector2(0f, 0f); obj7.anchoredPosition = new Vector2(4f, 4f); obj7.sizeDelta = new Vector2(36f, 36f); Image val5 = val4.AddComponent<Image>(); ((Graphic)val5).color = new Color(0.7f, 0.15f, 0.15f, 0.95f); Button val6 = val4.AddComponent<Button>(); ((Selectable)val6).targetGraphic = (Graphic)(object)val5; TextMeshProUGUI obj8 = new GameObject("Text").AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj8).transform.SetParent(val4.transform, false); RectTransform component = ((Component)obj8).GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; ((TMP_Text)obj8).text = "-"; ((Graphic)obj8).raycastTarget = false; ((TMP_Text)obj8).fontSize = 24f; ((TMP_Text)obj8).alignment = (TextAlignmentOptions)514; ((Graphic)obj8).color = Color.white; GameObject val7 = new GameObject("CountLabel"); val7.transform.SetParent(controlsGo.transform, false); RectTransform obj9 = val7.AddComponent<RectTransform>(); obj9.anchorMin = new Vector2(0.5f, 0f); obj9.anchorMax = new Vector2(0.5f, 0f); obj9.pivot = new Vector2(0.5f, 0f); obj9.anchoredPosition = new Vector2(0f, 4f); obj9.sizeDelta = new Vector2(40f, 36f); Image obj10 = val7.AddComponent<Image>(); ((Graphic)obj10).color = new Color(0f, 0f, 0f, 0.8f); ((Graphic)obj10).raycastTarget = false; GameObject val8 = new GameObject("CountText"); val8.transform.SetParent(val7.transform, false); RectTransform obj11 = val8.AddComponent<RectTransform>(); obj11.anchorMin = Vector2.zero; obj11.anchorMax = Vector2.one; offsetMin = (obj11.offsetMax = Vector2.zero); obj11.offsetMin = offsetMin; TextMeshProUGUI countTmp = val8.AddComponent<TextMeshProUGUI>(); ((TMP_Text)countTmp).text = entry.count.ToString(); ((TMP_Text)countTmp).fontSize = 22f; ((TMP_Text)countTmp).alignment = (TextAlignmentOptions)514; ((Graphic)countTmp).color = Color.white; ((Graphic)countTmp).raycastTarget = false; GameObject val9 = new GameObject("PlusBtn"); val9.transform.SetParent(controlsGo.transform, false); RectTransform obj12 = val9.AddComponent<RectTransform>(); obj12.anchorMin = new Vector2(1f, 0f); obj12.anchorMax = new Vector2(1f, 0f); obj12.pivot = new Vector2(1f, 0f); obj12.anchoredPosition = new Vector2(-4f, 4f); obj12.sizeDelta = new Vector2(36f, 36f); Image val10 = val9.AddComponent<Image>(); ((Graphic)val10).color = new Color(0.15f, 0.6f, 0.15f, 0.95f); Button obj13 = val9.AddComponent<Button>(); ((Selectable)obj13).targetGraphic = (Graphic)(object)val10; TextMeshProUGUI obj14 = new GameObject("Text").AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj14).transform.SetParent(val9.transform, false); RectTransform component2 = ((Component)obj14).GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; offsetMin = (component2.offsetMax = Vector2.zero); component2.offsetMin = offsetMin; ((TMP_Text)obj14).text = "+"; ((TMP_Text)obj14).fontSize = 24f; ((TMP_Text)obj14).alignment = (TextAlignmentOptions)514; ((Graphic)obj14).color = Color.white; ((Graphic)obj14).raycastTarget = false; Button obj15 = val.AddComponent<Button>(); ((Selectable)obj15).targetGraphic = (Graphic)(object)bgImg; ((UnityEvent)obj15.onClick).AddListener((UnityAction)delegate { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (entry.count == 0) { entry.count = 1; controlsGo.SetActive(true); ((TMP_Text)countTmp).text = "1"; ((Graphic)bgImg).color = new Color(0.15f, 0.25f, 0.15f, 0.9f); UpdateDeckCountDisplay(); } }); ((UnityEvent)val6.onClick).AddListener((UnityAction)delegate { //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (entry.count > 0) { entry.count--; ((TMP_Text)countTmp).text = entry.count.ToString(); if (entry.count == 0) { controlsGo.SetActive(false); ((Graphic)bgImg).color = new Color(0.1f, 0.1f, 0.14f, 0.85f); UpdateDeckCountDisplay(); RefreshMyDeckViewIfActive(); } else { UpdateDeckCountDisplay(); } } }); ((UnityEvent)obj13.onClick).AddListener((UnityAction)delegate { if (entry.count < maxCount) { entry.count++; ((TMP_Text)countTmp).text = entry.count.ToString(); UpdateDeckCountDisplay(); } }); } private void SetupCardVisual(CardInfo cardInfo, GameObject parent) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) RTGLog.Line("SetupCardVisual '" + cardInfo.cardName + "': cardArt=" + (((Object)(object)cardInfo.cardArt != (Object)null) ? ((Object)cardInfo.cardArt).name : "NULL")); GameObject val = Object.Instantiate<GameObject>(((Component)cardInfo).gameObject, parent.transform); ((Object)val).name = "CardVisual"; val.SetActive(true); GameObject val2 = FindChildByName(val, "Back"); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } GameObject val3 = FindChildByName(val, "Damagable"); if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)val3); } GameObject val4 = FindChildByName(val, "UI_ParticleSystem"); if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)val4); } GameObject val5 = FindChildByName(val, "BlockFront"); if ((Object)(object)val5 != (Object)null) { val5.SetActive(false); } CanvasGroup[] componentsInChildren = val.GetComponentsInChildren<CanvasGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].alpha = 1f; } CardVisuals[] componentsInChildren2 = val.GetComponentsInChildren<CardVisuals>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].firstValueToSet = true; } Animator[] componentsInChildren3 = val.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } CurveAnimation[] componentsInChildren4 = val.GetComponentsInChildren<CurveAnimation>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { ((Behaviour)componentsInChildren4[i]).enabled = false; } RectTransform orAddComponent = ExtensionMethods.GetOrAddComponent<RectTransform>(val, false); ((Transform)orAddComponent).localScale = Vector3.one * 15f; orAddComponent.anchorMin = new Vector2(0.5f, 0.5f); orAddComponent.anchorMax = new Vector2(0.5f, 0.5f); orAddComponent.pivot = new Vector2(0.5f, 0.5f); orAddComponent.anchoredPosition = new Vector2(0f, 10f); Graphic[] componentsInChildren5 = val.GetComponentsInChildren<Graphic>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { componentsInChildren5[i].raycastTarget = false; } if ((Object)(object)cardInfo.cardArt != (Object)null) { GameObject val6 = FindChildByName(val, "Art"); RTGLog.Line("SetupCardVisual '" + cardInfo.cardName + "': Art transform=" + (((Object)(object)val6 != (Object)null) ? ((Object)val6).name : "NOT FOUND")); if ((Object)(object)val6 != (Object)null) { GameObject val7 = Object.Instantiate<GameObject>(cardInfo.cardArt, val6.transform); val7.transform.SetAsFirstSibling(); RectTransform component = val7.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localPosition = Vector3.zero; ((Transform)component).localScale = Vector3.one; RTGLog.Line("SetupCardVisual '" + cardInfo.cardName + "': Art RectTransform reset to fill parent."); } else { val7.transform.localPosition = Vector3.zero; val7.transform.localScale = Vector3.one; } RTGLog.Line("SetupCardVisual '" + cardInfo.cardName + "': Art placed successfully."); } else { RTGLog.Warn("SetupCardVisual '" + cardInfo.cardName + "': 'Art' child not found — cannot place card art."); } } else { RTGLog.Line("SetupCardVisual '" + cardInfo.cardName + "': no cardArt set, skipping art placement."); } } private static GameObject FindChildByName(GameObject parent, string name) { Transform[] componentsInChildren = parent.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return ((Component)val).gameObject; } } return null; } private CardEntry GetOrCreateEntry(string cardObjectName) { CardEntry cardEntry = _deck.cards.Find((CardEntry e) => e.cardObjectName == cardObjectName); if (cardEntry == null) { cardEntry = new CardEntry { cardObjectName = cardObjectName, count = 0 }; _deck.cards.Add(cardEntry); } return cardEntry; } private void UpdateDeckCountDisplay() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (_deck != null) { int totalCount = _deck.TotalCount; if (_isSearchActive) { ((TMP_Text)_deckCountText).text = $"Found {_cachedCategoryCards.Count} cards — Deck: {totalCount} / {_deck.maxSize}"; } else { ((TMP_Text)_deckCountText).text = $"Cards in Deck: {totalCount} / {_deck.maxSize}"; } ((Graphic)_deckCountText).color = (Color)((totalCount > _deck.maxSize) ? new Color(1f, 0.3f, 0.3f) : Color.white); } } private void BuildMaxSizeModal(Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: 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) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown _maxSizeModal = new GameObject("MaxSizeModal"); _maxSizeModal.transform.SetParent(parent, false); _maxSizeModal.SetActive(false); RectTransform val = _maxSizeModal.AddComponent<RectTransform>(); val.anchorMin = new Vector2(0.3f, 0.35f); val.anchorMax = new Vector2(0.7f, 0.65f); Vector2 offsetMin = (val.offsetMax = Vector2.zero); val.offsetMin = offsetMin; ((Graphic)_maxSizeModal.AddComponent<Image>()).color = new Color(0.08f, 0.08f, 0.14f, 0.98f); UIHelper.CreateText((Transform)(object)val, "Title", "Change Max Deck Size", 26, (TextAlignmentOptions)514); _maxSizeModalField = UIHelper.CreateInputField((Transform)(object)val, "SizeField", _deck?.maxSize.ToString() ?? "50", Vector2.zero, Vector2.zero, 22, (ContentType)2); RectTransform component = ((Component)_maxSizeModalField).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.1f, 0.38f); component.anchorMax = new Vector2(0.9f, 0.55f); offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; ((UnityEvent<string>)(object)_maxSizeModalField.onValueChanged).AddListener((UnityAction<string>)delegate { ValidateModal(); }); _maxSizeModalError = UIHelper.CreateText((Transform)(object)val, "ModalError", "", 17, (TextAlignmentOptions)514, (Color?)new Color(1f, 0.35f, 0.35f)); RectTransform component2 = ((Component)_maxSizeModalError).GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.05f, 0.25f); component2.anchorMax = new Vector2(0.95f, 0.37f); offsetMin = (component2.offsetMax = Vector2.zero); component2.offsetMin = offsetMin; Button obj = UIHelper.CreateButton((Transform)(object)val, "ConfirmBtn", "Confirm", Vector2.zero, Vector2.zero, 22, (Color?)new Color(0.15f, 0.5f, 0.15f), (Color?)null); RectTransform component3 = ((Component)obj).GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0.1f, 0.06f); component3.anchorMax = new Vector2(0.55f, 0.23f); offsetMin = (component3.offsetMax = Vector2.zero); component3.offsetMin = offsetMin; ((UnityEvent)obj.onClick).AddListener(new UnityAction(ConfirmMaxSize)); Button obj2 = UIHelper.CreateButton((Transform)(object)val, "CancelBtn", "Cancel", Vector2.zero, Vector2.zero, 22, (Color?)new Color(0.45f, 0.1f, 0.1f), (Color?)null); RectTransform component4 = ((Component)obj2).GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.57f, 0.06f); component4.anchorMax = new Vector2(0.9f, 0.23f); offsetMin = (component4.offsetMax = Vector2.zero); component4.offsetMin = offsetMin; ((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate { _maxSizeModal.SetActive(false); }); } private void OpenMaxSizeModal() { if (_deck != null) { RTGLog.Section($"DeckEditorScreen — Change Max Size (current={_deck.maxSize})"); _maxSizeModalField.text = _deck.maxSize.ToString(); ((TMP_Text)_maxSizeModalError).text = ""; _maxSizeModal.SetActive(true); } } private void ValidateModal() { int result; bool flag = int.TryParse(_maxSizeModalField.text, out result) && result >= 1; ((TMP_Text)_maxSizeModalError).text = (flag ? "" : "Must be a number ≥ 1."); } private void ConfirmMaxSize() { if (int.TryParse(_maxSizeModalField.text, out var result) && result >= 1) { RTGLog.Section($"DeckEditorScreen — Confirm Max Size {result}"); _deck.maxSize = result; UpdateDeckCountDisplay(); _maxSizeModal.SetActive(false); DeckManager.instance?.Save(); } } private void CloseScreen() { RTGLog.Section("DeckEditorScreen — Close"); ((Component)_canvas).gameObject.SetActive(false); DeckSelectorScreen.instance?.Show(); } private static Color RarityColor(Rarity rarity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown //IL_0023: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) return (Color)((int)rarity switch { 0 => new Color(0.6f, 0.6f, 0.6f), 1 => new Color(0.2f, 0.8f, 0.2f), 2 => new Color(0.2f, 0.4f, 1f), _ => new Color(1f, 0.65f, 0f), }); } } public class DeckSelectorScreen : MonoBehaviour { public static DeckSelectorScreen instance; private Canvas _canvas; private Button _createBtn; private Button _editBtn; private Button _deleteBtn; private TextMeshProUGUI _deleteBtnLabel; private TMP_Dropdown _deckDropdown; private TextMeshProUGUI _activeDeckLabel; private GameObject _deleteModal; private TextMeshProUGUI _deleteModalMessage; private string _pendingDeleteDeckName; public bool IsOpen { get { if ((Object)(object)_canvas != (Object)null) { return ((Component)_canvas).gameObject.activeInHierarchy; } return false; } } private void Awake() { instance = this; BuildUI(); } private void BuildUI() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Expected O, but got Unknown _canvas = UIHelper.CreateFullscreenCanvas("RTG_DeckSelectorScreen", 200); UIHelper.CreateDimmedBackground(((Component)_canvas).transform); Transform transform = ((Component)_canvas).transform; Vector2 anchorMin = new Vector2(0.3f, 0.15f); Vector2 anchorMax = new Vector2(0.7f, 0.85f); Color? bg = new Color(0.08f, 0.08f, 0.12f, 1f); RectTransform parent = UIHelper.CreatePanel(transform, "Panel", anchorMin, anchorMax, default(Vector2), default(Vector2), bg); UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "Title", new Vector2(0f, 0.85f), Vector2.one), "TitleText", "Your Decks", 38, (TextAlignmentOptions)514); _createBtn = AnchorButton(parent, "CreateBtn", "Create New Deck", new Vector2(0.08f, 0.74f), new Vector2(0.92f, 0.85f), new Color(0.15f, 0.5f, 0.15f), 26); ((UnityEvent)_createBtn.onClick).AddListener(new UnityAction(OnCreateClicked)); _editBtn = AnchorButton(parent, "EditBtn", "Edit Deck", new Vector2(0.08f, 0.6f), new Vector2(0.92f, 0.72f), new Color(0.2f, 0.3f, 0.55f), 26); ((UnityEvent)_editBtn.onClick).AddListener(new UnityAction(OnEditClicked)); _deckDropdown = BuildDropdown(parent, new Vector2(0.08f, 0.46f), new Vector2(0.92f, 0.58f)); ((UnityEvent)AnchorButton(parent, "SetBtn", "Set Playable Deck", new Vector2(0.08f, 0.31f), new Vector2(0.5f, 0.43f), new Color(0.55f, 0.35f, 0.05f), 22).onClick).AddListener(new UnityAction(OnSetPlayableDeckClicked)); _deleteBtn = AnchorButton(parent, "DeleteBtn", "Delete Deck", new Vector2(0.52f, 0.31f), new Vector2(0.92f, 0.43f), new Color(0.55f, 0.12f, 0.12f), 22); ((UnityEvent)_deleteBtn.onClick).AddListener(new UnityAction(OnDeleteClicked)); ColorBlock colors = ((Selectable)_deleteBtn).colors; ((ColorBlock)(ref colors)).disabledColor = new Color(0.28f, 0.28f, 0.32f, 1f); ((Selectable)_deleteBtn).colors = colors; Transform obj = ((Component)_deleteBtn).transform.Find("Label"); _deleteBtnLabel = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null); BuildDeleteModal(parent); Vector2 anchorMin2 = new Vector2(0.05f, 0.19f); Vector2 anchorMax2 = new Vector2(0.95f, 0.29f); bg = new Color(0.05f, 0.05f, 0.08f, 0.8f); RectTransform parent2 = UIHelper.CreatePanel((Transform)(object)parent, "ActiveDeckPanel", anchorMin2, anchorMax2, default(Vector2), default(Vector2), bg); _activeDeckLabel = UIHelper.CreateText((Transform)(object)parent2, "ActiveDeckLabel", "Active: —", 20, (TextAlignmentOptions)514); ((UnityEvent)AnchorButton(parent, "CloseBtn", "Close", new Vector2(0.2f, 0.06f), new Vector2(0.8f, 0.16f), new Color(0.45f, 0.1f, 0.1f), 22).onClick).AddListener(new UnityAction(Hide)); ((Component)_canvas).gameObject.SetActive(false); } private static Button AnchorButton(RectTransform parent, string name, string label, Vector2 anchorMin, Vector2 anchorMax, Color bgColor, int fontSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = bgColor; Button obj2 = val.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val2; ColorBlock val3 = default(ColorBlock); ((ColorBlock)(ref val3)).normalColor = bgColor; ((ColorBlock)(ref val3)).highlightedColor = bgColor * 1.3f; ((ColorBlock)(ref val3)).pressedColor = bgColor * 0.7f; ((ColorBlock)(ref val3)).disabledColor = new Color(0.25f, 0.25f, 0.25f, 0.6f); ((ColorBlock)(ref val3)).colorMultiplier = 1f; ((ColorBlock)(ref val3)).fadeDuration = 0.1f; ColorBlock colors = val3; ((Selectable)obj2).colors = colors; GameObject val4 = new GameObject("Label"); val4.transform.SetParent(val.transform, false); RectTransform obj3 = val4.AddComponent<RectTransform>(); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; offsetMin = (obj3.offsetMax = Vector2.zero); obj3.offsetMin = offsetMin; TextMeshProUGUI obj4 = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj4).text = label; ((TMP_Text)obj4).fontSize = fontSize; ((TMP_Text)obj4).alignment = (TextAlignmentOptions)514; ((Graphic)obj4).color = Color.white; return obj2; } private TMP_Dropdown BuildDropdown(RectTransform parent, Vector2 anchorMin, Vector2 anchorMax) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_001f: 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_002d: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing r
InfoOverhaul.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using InfoOverhaul.Compat; using InfoOverhaul.Delta; using InfoOverhaul.Stats; using InfoOverhaul.UI; using Microsoft.CodeAnalysis; using TMPro; using UnboundLib.GameModes; using UnboundLib.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyCompany("InfoOverhaul")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+146ac727a7fc6b83f382d57f53cce40478349c58")] [assembly: AssemblyProduct("Info Overhaul")] [assembly: AssemblyTitle("InfoOverhaul")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 InfoOverhaul { internal static class IOLog { private static ManualLogSource _logger; internal static void Init(ManualLogSource logger) { _logger = logger; } internal static void Section(string title) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)("── " + title + " ──")); } } internal static void Line(string message) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)message); } } internal static void Warn(string message) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)message); } } internal static void Error(string message) { ManualLogSource logger = _logger; if (logger != null) { logger.LogError((object)message); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("InfoOverhaul", "Info Overhaul", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; IOLog.Init(Logger); IOLog.Section("Plugin Awake"); new Harmony("InfoOverhaul").PatchAll(); StatTemplateDeltaRegistrar.Init(); MfmTier2Compat.Init(); ((Component)this).gameObject.AddComponent<PickStatsController>(); ((Component)this).gameObject.AddComponent<CardDeltaPreviewOverlay>(); IOLog.Line("Plugin InfoOverhaul loaded."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "InfoOverhaul"; public const string PLUGIN_NAME = "Info Overhaul"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace InfoOverhaul.UI { public class CardDeltaPreviewOverlay : MonoBehaviour { [CompilerGenerated] private sealed class <OnPickSequenceEnd>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CardDeltaPreviewOverlay <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnPickSequenceEnd>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CardDeltaPreviewOverlay cardDeltaPreviewOverlay = <>4__this; if (num != 0) { return false; } <>1__state = -1; cardDeltaPreviewOverlay.OnPickSequenceEnded(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static CardDeltaPreviewOverlay instance; private static readonly FieldInfo SpawnedCardsField = AccessTools.Field(typeof(CardChoice), "spawnedCards"); private static readonly FieldInfo SelectedCardField = AccessTools.Field(typeof(CardChoice), "currentlySelectedCard"); private const int RowsPerCol = 3; private const int MaxCols = 5; private Canvas _canvas; private TextMeshProUGUI _headerText; private TextMeshProUGUI[] _colTexts; private bool _pickSequenceActive; private void Awake() { instance = this; BuildUI(); GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)OnPickSequenceEnd); IOLog.Section("CardDeltaPreviewOverlay initialized"); } private void BuildUI() { //IL_002c: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_01a6: Unknown result type (might be due to invalid IL or missing references) _canvas = UIHelper.CreateFullscreenCanvas("IO_CardDeltaPreview", 55); Transform transform = ((Component)_canvas).transform; Vector2 anchorMin = new Vector2(0.18f, 0.085f); Vector2 anchorMax = new Vector2(0.82f, 0.22f); Color? bg = new Color(0.04f, 0.06f, 0.1f, 0.92f); RectTransform parent = UIHelper.CreatePanel(transform, "DeltaPanel", anchorMin, anchorMax, default(Vector2), default(Vector2), bg); RectTransform parent2 = UIHelper.CreatePanel((Transform)(object)parent, "Header", new Vector2(0.01f, 0.72f), new Vector2(0.99f, 0.98f)); _headerText = UIHelper.CreateText((Transform)(object)parent2, "HeaderText", "Card preview", 20, (TextAlignmentOptions)4097, (Color?)new Color(0.75f, 0.85f, 1f)); _colTexts = (TextMeshProUGUI[])(object)new TextMeshProUGUI[5]; float num = 0.2f; for (int i = 0; i < 5; i++) { float num2 = (float)i * num + 0.01f; float num3 = (float)(i + 1) * num - 0.01f; RectTransform parent3 = UIHelper.CreatePanel((Transform)(object)parent, $"Col{i}", new Vector2(num2, 0.02f), new Vector2(num3, 0.7f)); _colTexts[i] = UIHelper.CreateText((Transform)(object)parent3, "Text", string.Empty, 17, (TextAlignmentOptions)257, (Color?)new Color(0.92f, 0.94f, 1f)); ((TMP_Text)_colTexts[i]).richText = true; } ((Component)_canvas).gameObject.SetActive(false); } public void OnPickSequenceStarted() { if ((Object)(object)GetLocalHumanPlayer() == (Object)null) { SetVisible(visible: false); return; } _pickSequenceActive = true; SetVisible(visible: true); Refresh(); } public void OnPickSequenceEnded() { _pickSequenceActive = false; SetVisible(visible: false); } private void Update() { if (_pickSequenceActive && !((Object)(object)_canvas == (Object)null) && ((Component)_canvas).gameObject.activeSelf) { if (!IsGameActive()) { OnPickSequenceEnded(); } else { Refresh(); } } } private static bool IsGameActive() { if ((Object)(object)GameManager.instance == (Object)null) { return false; } if (!GameManager.instance.isPlaying) { return false; } if ((Object)(object)PlayerManager.instance == (Object)null) { return false; } if (PlayerManager.instance.players == null || PlayerManager.instance.players.Count == 0) { return false; } return true; } private void Refresh() { Player localHumanPlayer = GetLocalHumanPlayer(); if ((Object)(object)localHumanPlayer == (Object)null) { SetVisible(visible: false); return; } if (!TryGetHighlightedCard(out var card)) { ((TMP_Text)_headerText).text = "Card preview"; SetColumns(null); ((TMP_Text)_colTexts[0]).text = "—"; return; } ((TMP_Text)_headerText).text = "If selecting " + card.cardName + ":"; if (!CardDeltaRegistry.TryGetDeltas(localHumanPlayer, card, out var deltas)) { SetColumns(null); ((TMP_Text)_colTexts[0]).text = "N/A"; } else if (deltas.Count == 0) { SetColumns(null); ((TMP_Text)_colTexts[0]).text = "No stat changes"; } else { SetColumns(deltas); } } private void SetColumns(IReadOnlyList<StatDeltaLine> deltas) { if (deltas == null) { for (int i = 0; i < 5; i++) { ((TMP_Text)_colTexts[i]).text = string.Empty; ((Component)_colTexts[i]).gameObject.SetActive(i == 0); } return; } int num = Mathf.Clamp(Mathf.CeilToInt((float)deltas.Count / 3f), 1, 5); for (int j = 0; j < 5; j++) { bool flag = j < num; ((Component)_colTexts[j]).gameObject.SetActive(flag); if (!flag) { continue; } StringBuilder stringBuilder = new StringBuilder(); int num2 = j * 3; int num3 = Mathf.Min(num2 + 3, deltas.Count); for (int k = num2; k < num3; k++) { if (k > num2) { stringBuilder.AppendLine(); } stringBuilder.Append(deltas[k].FormatRichText()); } ((TMP_Text)_colTexts[j]).text = stringBuilder.ToString(); } } private static bool TryGetHighlightedCard(out CardInfo card) { card = null; CardChoice val = CardChoice.instance; if ((Object)(object)val == (Object)null || !val.IsPicking || SpawnedCardsField == null || SelectedCardField == null) { return false; } if (!(SpawnedCardsField.GetValue(val) is List<GameObject> list) || list.Count == 0) { return false; } int num = (int)SelectedCardField.GetValue(val); num = Mathf.Clamp(num, 0, list.Count - 1); GameObject val2 = list[num]; if ((Object)(object)val2 == (Object)null) { return false; } card = val2.GetComponent<CardInfo>(); if ((Object)(object)card == (Object)null) { card = val2.GetComponentInChildren<CardInfo>(); } return (Object)(object)card != (Object)null; } private static Player GetLocalHumanPlayer() { if ((Object)(object)PlayerManager.instance == (Object)null) { return null; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player == (Object)null) { continue; } PlayerAPI component = ((Component)player).GetComponent<PlayerAPI>(); if (component == null || !((Behaviour)component).enabled) { object value = AccessTools.Field(typeof(CharacterData), "view").GetValue(player.data); if (value == null) { return player; } if ((bool)AccessTools.Property(value.GetType(), "IsMine").GetValue(value, null)) { return player; } } } return null; } private void SetVisible(bool visible) { if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(visible); } } [IteratorStateMachine(typeof(<OnPickSequenceEnd>d__20))] private IEnumerator OnPickSequenceEnd(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnPickSequenceEnd>d__20(0) { <>4__this = this }; } } public class PickStatsController : MonoBehaviour { [CompilerGenerated] private sealed class <OnPickSequenceEnd>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PickStatsController <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnPickSequenceEnd>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; PickStatsController pickStatsController = <>4__this; if (num != 0) { return false; } <>1__state = -1; IOLog.Line("Pick sequence ended — auto-closing stats window."); pickStatsController.EndPickPhase("HookPickEnd"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnPlayerPickEnd>d__13 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnPlayerPickEnd>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; IOLog.Line($"Single player pick ended (picker={currentPickerID}); keeping stats UI up until pick sequence ends."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static PickStatsController instance; public static bool isPickPhase; public static int currentPickerID = -1; private Canvas _canvas; private StatsPopup _popup; private GameObject _showStatsBtnGo; private void Awake() { instance = this; BuildUI(); GameModeManager.AddHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)OnPlayerPickEnd); GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)OnPickSequenceEnd); IOLog.Section("PickStatsController initialized"); } private void BuildUI() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown _canvas = UIHelper.CreateFullscreenCanvas("IO_PickStatsCanvas", 160); RectTransform component = ((Component)_canvas).GetComponent<RectTransform>(); Button val = UIHelper.AnchorButton(component, "ShowStatsBtn", "Show Stats", new Vector2(0.02f, 0.02f), new Vector2(0.16f, 0.08f), new Color(0.18f, 0.35f, 0.55f, 1f), 24); ((UnityEvent)val.onClick).AddListener(new UnityAction(TogglePopup)); _showStatsBtnGo = ((Component)val).gameObject; _popup = StatsPopup.Create((Transform)(object)component); ((Component)_canvas).gameObject.SetActive(false); } public void BeginPickPhase(int pickerID, string source) { if (pickerID >= 0) { if ((Object)(object)GetLocalHumanPlayer() == (Object)null) { HideAll(); IOLog.Line($"Pick phase for player {pickerID} (source={source}) — no local human, UI hidden."); return; } currentPickerID = pickerID; isPickPhase = true; ((Component)_canvas).gameObject.SetActive(true); _showStatsBtnGo.SetActive(true); CardDeltaPreviewOverlay.instance?.OnPickSequenceStarted(); IOLog.Line($"Pick phase active — picker={pickerID}, showing local stats (source={source})."); } } public void EndPickPhase(string source) { IOLog.Line($"Pick phase ended (source={source}), was picker={currentPickerID}"); isPickPhase = false; currentPickerID = -1; CardDeltaPreviewOverlay.instance?.OnPickSequenceEnded(); HideAll(); } private void HideAll() { _popup?.Hide(); if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(false); } } private void TogglePopup() { Player localHumanPlayer = GetLocalHumanPlayer(); if (!((Object)(object)localHumanPlayer == (Object)null)) { if (_popup.IsVisible) { _popup.Hide(); } else { _popup.Show(localHumanPlayer); } } } private static Player GetLocalHumanPlayer() { if ((Object)(object)PlayerManager.instance == (Object)null) { return null; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player == (Object)null) { continue; } PlayerAPI component = ((Component)player).GetComponent<PlayerAPI>(); if (component == null || !((Behaviour)component).enabled) { object value = AccessTools.Field(typeof(CharacterData), "view").GetValue(player.data); if (value == null) { return player; } if ((bool)AccessTools.Property(value.GetType(), "IsMine").GetValue(value, null)) { return player; } } } return null; } [IteratorStateMachine(typeof(<OnPlayerPickEnd>d__13))] private IEnumerator OnPlayerPickEnd(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnPlayerPickEnd>d__13(0); } [IteratorStateMachine(typeof(<OnPickSequenceEnd>d__14))] private IEnumerator OnPickSequenceEnd(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnPickSequenceEnd>d__14(0) { <>4__this = this }; } private void Update() { if ((Object)(object)_canvas != (Object)null && ((Component)_canvas).gameObject.activeSelf && !IsGameActive()) { IOLog.Line("PickStatsController — game no longer active, hiding UI."); EndPickPhase("GameEnded"); } } private static bool IsGameActive() { if ((Object)(object)GameManager.instance == (Object)null) { return false; } if (!GameManager.instance.isPlaying) { return false; } if ((Object)(object)PlayerManager.instance == (Object)null) { return false; } if (PlayerManager.instance.players == null || PlayerManager.instance.players.Count == 0) { return false; } return true; } } internal class StatsPopup : MonoBehaviour { private readonly List<TextMeshProUGUI> _leftLines = new List<TextMeshProUGUI>(); private readonly List<TextMeshProUGUI> _rightLines = new List<TextMeshProUGUI>(); private RectTransform _root; private Player _player; public bool IsVisible => ((Component)this).gameObject.activeSelf; public static StatsPopup Create(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("IO_StatsPopup"); val.transform.SetParent(parent, false); StatsPopup statsPopup = val.AddComponent<StatsPopup>(); statsPopup.Build(); val.SetActive(false); return statsPopup; } private void Build() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00fc: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) _root = ((Component)this).gameObject.AddComponent<RectTransform>(); _root.anchorMin = Vector2.zero; _root.anchorMax = Vector2.one; RectTransform root = _root; Vector2 offsetMin = (_root.offsetMax = Vector2.zero); root.offsetMin = offsetMin; GameObject val = new GameObject("Backdrop"); val.transform.SetParent(((Component)this).transform, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; ((Graphic)val.AddComponent<Image>()).color = new Color(0.02f, 0.02f, 0.05f, 1f); Transform transform = ((Component)this).transform; Vector2 anchorMin = new Vector2(0.12f, 0.08f); Vector2 anchorMax = new Vector2(0.88f, 0.92f); Color? bg = new Color(0.08f, 0.09f, 0.14f, 1f); RectTransform parent = UIHelper.CreatePanel(transform, "Panel", anchorMin, anchorMax, default(Vector2), default(Vector2), bg); UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, "Title", new Vector2(0f, 0.9f), Vector2.one), "TitleText", "Player Stats", 36, (TextAlignmentOptions)514); ((UnityEvent)UIHelper.AnchorButton(parent, "CloseBtn", "Close", new Vector2(0.82f, 0.91f), new Vector2(0.98f, 0.99f), new Color(0.45f, 0.12f, 0.12f), 22).onClick).AddListener(new UnityAction(Hide)); RectTransform parent2 = UIHelper.CreatePanel((Transform)(object)parent, "Columns", new Vector2(0.04f, 0.04f), new Vector2(0.96f, 0.88f)); RectTransform parent3 = UIHelper.CreatePanel((Transform)(object)parent2, "LeftColumn", new Vector2(0f, 0f), new Vector2(0.48f, 1f)); RectTransform parent4 = UIHelper.CreatePanel((Transform)(object)parent2, "RightColumn", new Vector2(0.52f, 0f), Vector2.one); BuildColumn(parent3, _leftLines, 12); BuildColumn(parent4, _rightLines, 12); } private static void BuildColumn(RectTransform parent, List<TextMeshProUGUI> sink, int lineCount) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) float num = 1f / (float)lineCount; for (int i = 0; i < lineCount; i++) { float num2 = 1f - (float)i * num; float num3 = num2 - num; TextMeshProUGUI item = UIHelper.CreateText((Transform)(object)UIHelper.CreatePanel((Transform)(object)parent, $"Line{i}", new Vector2(0f, num3), new Vector2(1f, num2)), "Text", "—", 22, (TextAlignmentOptions)4097, (Color?)new Color(0.92f, 0.94f, 1f)); sink.Add(item); } } public void Show(Player player) { _player = player; ((Component)this).gameObject.SetActive(true); Refresh(); } public void Hide() { ((Component)this).gameObject.SetActive(false); _player = null; } private void Update() { if (IsVisible && !((Object)(object)_player == (Object)null)) { Refresh(); } } private void Refresh() { List<StatsReader.StatLine> stats = StatsReader.Collect(_player); ApplyColumn(_leftLines, stats, 0); ApplyColumn(_rightLines, stats, _leftLines.Count); } private static void ApplyColumn(List<TextMeshProUGUI> labels, List<StatsReader.StatLine> stats, int offset) { for (int i = 0; i < labels.Count; i++) { int num = offset + i; ((TMP_Text)labels[i]).text = ((num < stats.Count) ? stats[num].Text : string.Empty); } } } internal static class UIHelper { public static Canvas CreateFullscreenCanvas(string name, int sortOrder = 100) { //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_000c: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); Object.DontDestroyOnLoad((Object)val); val.SetActive(false); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = sortOrder; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); return val2; } public static RectTransform CreatePanel(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin = default(Vector2), Vector2 offsetMax = default(Vector2), Color? bg = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0049: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; obj.offsetMin = offsetMin; obj.offsetMax = offsetMax; if (bg.HasValue) { ((Graphic)val.AddComponent<Image>()).color = bg.Value; } return obj; } public static TextMeshProUGUI CreateText(Transform parent, string name, string text, int fontSize = 24, TextAlignmentOptions alignment = 514, Color? color = null) { //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_0013: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj2).text = text; ((TMP_Text)obj2).fontSize = fontSize; ((TMP_Text)obj2).alignment = alignment; ((Graphic)obj2).color = (Color)(((??)color) ?? Color.white); return obj2; } public static Button AnchorButton(RectTransform parent, string name, string label, Vector2 anchorMin, Vector2 anchorMax, Color bgColor, int fontSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent((Transform)(object)parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = bgColor; Button obj2 = val.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val2; ColorBlock val3 = default(ColorBlock); ((ColorBlock)(ref val3)).normalColor = bgColor; ((ColorBlock)(ref val3)).highlightedColor = bgColor * 1.3f; ((ColorBlock)(ref val3)).pressedColor = bgColor * 0.7f; ((ColorBlock)(ref val3)).disabledColor = new Color(0.25f, 0.25f, 0.25f, 0.6f); ((ColorBlock)(ref val3)).colorMultiplier = 1f; ((ColorBlock)(ref val3)).fadeDuration = 0.1f; ColorBlock colors = val3; ((Selectable)obj2).colors = colors; GameObject val4 = new GameObject("Label"); val4.transform.SetParent(val.transform, false); RectTransform obj3 = val4.AddComponent<RectTransform>(); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; offsetMin = (obj3.offsetMax = Vector2.zero); obj3.offsetMin = offsetMin; TextMeshProUGUI obj4 = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj4).text = label; ((TMP_Text)obj4).fontSize = fontSize; ((TMP_Text)obj4).alignment = (TextAlignmentOptions)514; ((Graphic)obj4).color = Color.white; return obj2; } } } namespace InfoOverhaul.Stats { internal static class LifestealResistanceStatsBridge { private static bool _resolved; private static FieldInfo _instanceField; private static MethodInfo _getPercent; public static bool IsAvailable { get { Resolve(); if (_instanceField != null) { return _getPercent != null; } return false; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ShieldsMod"); if (!(assembly == null)) { Type type = assembly.GetType("ShieldsMod.Lifesteal.LifestealResistanceManager"); if (!(type == null)) { _instanceField = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); _getPercent = type.GetMethod("GetReductionPercent", BindingFlags.Instance | BindingFlags.Public); } } } catch (Exception ex) { IOLog.Warn("LifestealResistanceStatsBridge resolve failed: " + ex.Message); } } public static bool TryGetPercent(int playerID, out float percent) { percent = 0f; Resolve(); if (_instanceField == null || _getPercent == null) { return false; } try { object value = _instanceField.GetValue(null); if (value == null) { return false; } percent = (float)_getPercent.Invoke(value, new object[1] { playerID }); return true; } catch (Exception ex) { IOLog.Warn("TryGetPercent failed: " + ex.Message); return false; } } } internal static class PoisonResistanceStatsBridge { private static bool _resolved; private static FieldInfo _instanceField; private static MethodInfo _getPercent; public static bool IsAvailable { get { Resolve(); if (_instanceField != null) { return _getPercent != null; } return false; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ShieldsMod"); if (!(assembly == null)) { Type type = assembly.GetType("ShieldsMod.Poison.PoisonResistanceManager"); if (!(type == null)) { _instanceField = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); _getPercent = type.GetMethod("GetReductionPercent", BindingFlags.Instance | BindingFlags.Public); } } } catch (Exception ex) { IOLog.Warn("PoisonResistanceStatsBridge resolve failed: " + ex.Message); } } public static bool TryGetPercent(int playerID, out float percent) { percent = 0f; Resolve(); if (_instanceField == null || _getPercent == null) { return false; } try { object value = _instanceField.GetValue(null); if (value == null) { return false; } percent = (float)_getPercent.Invoke(value, new object[1] { playerID }); return true; } catch (Exception ex) { IOLog.Warn("TryGetPercent failed: " + ex.Message); return false; } } } internal static class ShieldStatsBridge { private static bool _resolved; private static FieldInfo _instanceField; private static MethodInfo _getShield; private static FieldInfo _currentField; private static FieldInfo _maxField; public static bool IsAvailable { get { Resolve(); if (_instanceField != null) { return _getShield != null; } return false; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ShieldsMod"); if (assembly == null) { IOLog.Line("ShieldsMod not loaded — Shield Health will show as N/A."); return; } Type type = assembly.GetType("ShieldsMod.Shield.ShieldManager"); Type type2 = assembly.GetType("ShieldsMod.Shield.ShieldState"); if (type == null || type2 == null) { IOLog.Warn("ShieldsMod shield types not found."); return; } _instanceField = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); _getShield = type.GetMethod("GetShield", BindingFlags.Instance | BindingFlags.Public); _currentField = type2.GetField("Current", BindingFlags.Instance | BindingFlags.Public); _maxField = type2.GetField("Max", BindingFlags.Instance | BindingFlags.Public); if (_instanceField == null || _getShield == null || _currentField == null || _maxField == null) { IOLog.Warn("ShieldsMod shield API incomplete."); } } catch (Exception ex) { IOLog.Error("ShieldStatsBridge resolve failed: " + ex.Message); } } public static bool TryGetShieldHealth(int playerID, out float current, out float max) { current = 0f; max = 0f; Resolve(); if (_instanceField == null || _getShield == null) { return false; } try { object value = _instanceField.GetValue(null); if (value == null) { return false; } object obj = _getShield.Invoke(value, new object[1] { playerID }); if (obj == null) { return false; } current = (float)_currentField.GetValue(obj); max = (float)_maxField.GetValue(obj); return true; } catch (Exception ex) { IOLog.Warn("TryGetShieldHealth failed: " + ex.Message); return false; } } } internal static class StatsReader { internal readonly struct StatLine { public readonly string Text; public StatLine(string text) { Text = text; } } public static List<StatLine> Collect(Player player) { List<StatLine> list = new List<StatLine>(24); if ((Object)(object)player == (Object)null) { return list; } Gun val = player.data?.weaponHandler?.gun; Block val2 = player.data?.block; list.Add(new StatLine($"HP: {player.data.health:f0} / {player.data.maxHealth:f0}")); list.Add(new StatLine($"Lives: {player.data.stats.respawns + 1:f0}")); list.Add(new StatLine(((Object)(object)val2 != (Object)null) ? $"Block CD: {val2.Cooldown():f2}s" : "Block CD: —")); list.Add(new StatLine(((Object)(object)val2 != (Object)null) ? $"Block Count: {val2.additionalBlocks + 1:f0}" : "Block Count: —")); list.Add(new StatLine(FormatShieldHealth(player.playerID))); list.Add(new StatLine(FormatPoisonResistance(player.playerID))); list.Add(new StatLine(FormatStunResistance(player.playerID))); list.Add(new StatLine(FormatLifestealResistance(player.playerID))); if ((Object)(object)val != (Object)null) { list.Add(new StatLine($"DMG: {val.damage * 55f * val.bulletDamageMultiplier:f0}")); list.Add(new StatLine($"Knockback: {val.knockback:f2}")); list.Add(new StatLine($"Life Steal: {player.data.stats.lifeSteal:f2}")); list.Add(new StatLine($"Damage Grow: {val.damageAfterDistanceMultiplier:f2}")); list.Add(new StatLine($"Bullet Slow: {val.slow:f2}")); list.Add(new StatLine($"Move SPD: {player.data.stats.movementSpeed:f2}")); list.Add(new StatLine($"Jump Height: {player.data.stats.jump:f2}")); list.Add(new StatLine($"Player Size: {player.data.stats.sizeMultiplier:f2}")); list.Add(new StatLine($"Attack SPD: {val.attackSpeed * val.attackSpeedMultiplier:f2}s")); list.Add(new StatLine($"Bullet SPD: {val.projectileSpeed:f2}")); list.Add(new StatLine($"Projectile SPD: {val.projectielSimulatonSpeed:f2}")); GunAmmo componentInChildren = ((Component)val).GetComponentInChildren<GunAmmo>(); if ((Object)(object)componentInChildren != (Object)null) { float num = (componentInChildren.reloadTime + componentInChildren.reloadTimeAdd) * componentInChildren.reloadTimeMultiplier; list.Add(new StatLine($"Reload Time: {num:f2}s")); list.Add(new StatLine($"Ammo: {componentInChildren.maxAmmo:f0}")); } else { list.Add(new StatLine("Reload Time: —")); list.Add(new StatLine("Ammo: —")); } list.Add(new StatLine($"Bullet Gravity: {val.gravity:f2}")); list.Add(new StatLine($"Bullets: {val.numberOfProjectiles:f0}")); list.Add(new StatLine($"Bullet Range: {val.destroyBulletAfter:f2}")); list.Add(new StatLine($"Bounces: {val.reflects:f0}")); list.Add(new StatLine($"Bursts: {val.bursts:f0}")); } else { list.Add(new StatLine("DMG: —")); list.Add(new StatLine("Knockback: —")); list.Add(new StatLine($"Life Steal: {player.data.stats.lifeSteal:f2}")); list.Add(new StatLine("Damage Grow: —")); list.Add(new StatLine("Bullet Slow: —")); list.Add(new StatLine($"Move SPD: {player.data.stats.movementSpeed:f2}")); list.Add(new StatLine($"Jump Height: {player.data.stats.jump:f2}")); list.Add(new StatLine($"Player Size: {player.data.stats.sizeMultiplier:f2}")); list.Add(new StatLine("Attack SPD: —")); list.Add(new StatLine("Bullet SPD: —")); list.Add(new StatLine("Projectile SPD: —")); list.Add(new StatLine("Reload Time: —")); list.Add(new StatLine("Ammo: —")); list.Add(new StatLine("Bullet Gravity: —")); list.Add(new StatLine("Bullets: —")); list.Add(new StatLine("Bullet Range: —")); list.Add(new StatLine("Bounces: —")); list.Add(new StatLine("Bursts: —")); } return list; } private static string FormatShieldHealth(int playerID) { if (ShieldStatsBridge.TryGetShieldHealth(playerID, out var current, out var max)) { if (!(max > 0f)) { return "Shield Health: None"; } return $"Shield Health: {current:f0} / {max:f0}"; } if (!ShieldStatsBridge.IsAvailable) { return "Shield Health: N/A"; } return "Shield Health: — / —"; } private static string FormatPoisonResistance(int playerID) { if (PoisonResistanceStatsBridge.TryGetPercent(playerID, out var percent)) { return $"Poison Resistance: {percent:f0}%"; } if (!PoisonResistanceStatsBridge.IsAvailable) { return "Poison Resistance: N/A"; } return "Poison Resistance: 0%"; } private static string FormatStunResistance(int playerID) { if (StunResistanceStatsBridge.TryGetPercent(playerID, out var percent)) { return $"Stun Resistance: {percent:f0}%"; } if (!StunResistanceStatsBridge.IsAvailable) { return "Stun Resistance: N/A"; } return "Stun Resistance: 0%"; } private static string FormatLifestealResistance(int playerID) { if (LifestealResistanceStatsBridge.TryGetPercent(playerID, out var percent)) { return $"Lifesteal Resistance: {percent:f0}%"; } if (!LifestealResistanceStatsBridge.IsAvailable) { return "Lifesteal Resistance: N/A"; } return "Lifesteal Resistance: 0%"; } } internal static class StunResistanceStatsBridge { private static bool _resolved; private static FieldInfo _instanceField; private static MethodInfo _getPercent; public static bool IsAvailable { get { Resolve(); if (_instanceField != null) { return _getPercent != null; } return false; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ShieldsMod"); if (!(assembly == null)) { Type type = assembly.GetType("ShieldsMod.Stun.StunResistanceManager"); if (!(type == null)) { _instanceField = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); _getPercent = type.GetMethod("GetReductionPercent", BindingFlags.Instance | BindingFlags.Public); } } } catch (Exception ex) { IOLog.Warn("StunResistanceStatsBridge resolve failed: " + ex.Message); } } public static bool TryGetPercent(int playerID, out float percent) { percent = 0f; Resolve(); if (_instanceField == null || _getPercent == null) { return false; } try { object value = _instanceField.GetValue(null); if (value == null) { return false; } percent = (float)_getPercent.Invoke(value, new object[1] { playerID }); return true; } catch (Exception ex) { IOLog.Warn("TryGetPercent failed: " + ex.Message); return false; } } } } namespace InfoOverhaul.Patches { [HarmonyPatch] internal static class PickPhasePatches { [HarmonyPatch(typeof(CardChoiceVisuals), "Show")] [HarmonyPrefix] private static void CardChoiceVisuals_Show_Prefix(int pickerID, bool animateIn) { PickStatsController.instance?.BeginPickPhase(pickerID, "CardChoiceVisuals.Show"); } [HarmonyPatch(typeof(CardChoice), "StartPick")] [HarmonyPostfix] private static void CardChoice_StartPick_Postfix(int picksToSet, int pickerIDToSet) { PickStatsController.instance?.BeginPickPhase(pickerIDToSet, "CardChoice.StartPick"); } } } namespace InfoOverhaul.Delta { public static class CardDeltaRegistry { public delegate IReadOnlyList<StatDeltaLine> DeltaProvider(Player player, CardInfo card); public delegate IReadOnlyList<(string label, string before, string after)> SimpleDeltaProvider(Player player, CardInfo card); private static readonly Dictionary<string, DeltaProvider> Providers = new Dictionary<string, DeltaProvider>(StringComparer.Ordinal); private static readonly Dictionary<string, List<DeltaProvider>> Addons = new Dictionary<string, List<DeltaProvider>>(StringComparer.Ordinal); private static readonly Dictionary<string, DeltaProvider> RemovalProviders = new Dictionary<string, DeltaProvider>(StringComparer.Ordinal); public static void RegisterSimple(string cardName, SimpleDeltaProvider provider) { Register(cardName, (Player player, CardInfo card) => ToLines(provider(player, card))); } public static void Register(string cardName, DeltaProvider provider) { if (!string.IsNullOrEmpty(cardName) && provider != null) { Providers[cardName] = provider; IOLog.Line("CardDeltaRegistry — registered '" + cardName + "'."); } } public static void RegisterAddon(string cardName, DeltaProvider addon) { if (!string.IsNullOrEmpty(cardName) && addon != null) { if (!Addons.TryGetValue(cardName, out var value)) { value = new List<DeltaProvider>(); Addons[cardName] = value; } value.Add(addon); IOLog.Line("CardDeltaRegistry — addon registered for '" + cardName + "'."); } } public static void RegisterAddonSimple(string cardName, SimpleDeltaProvider addon) { RegisterAddon(cardName, (Player player, CardInfo card) => ToLines(addon(player, card))); } public static void RegisterRemovalSimple(string cardName, SimpleDeltaProvider provider) { RegisterRemoval(cardName, (Player player, CardInfo card) => ToLines(provider(player, card))); } public static void RegisterRemoval(string cardName, DeltaProvider provider) { if (!string.IsNullOrEmpty(cardName) && provider != null) { RemovalProviders[cardName] = provider; IOLog.Line("CardDeltaRegistry — removal registered '" + cardName + "'."); } } public static bool IsRegistered(string cardName) { if (!string.IsNullOrEmpty(cardName)) { if (!Providers.ContainsKey(cardName)) { if (Addons.TryGetValue(cardName, out var value)) { return value.Count > 0; } return false; } return true; } return false; } public static bool TryGetDeltas(Player player, CardInfo card, out IReadOnlyList<StatDeltaLine> deltas) { deltas = null; if ((Object)(object)player == (Object)null || (Object)(object)card == (Object)null) { return false; } string text = ResolveCardName(card); if (string.IsNullOrEmpty(text)) { return false; } DeltaProvider value; bool flag = Providers.TryGetValue(text, out value); List<DeltaProvider> value2; bool flag2 = Addons.TryGetValue(text, out value2) && value2.Count > 0; if (!flag && !flag2) { return false; } List<StatDeltaLine> list = new List<StatDeltaLine>(); if (flag) { list.AddRange(value(player, card) ?? Array.Empty<StatDeltaLine>()); } if (flag2) { foreach (DeltaProvider item in value2) { list.AddRange(item(player, card) ?? Array.Empty<StatDeltaLine>()); } } deltas = list; return true; } public static bool TryGetRemovalDeltas(Player player, CardInfo card, out IReadOnlyList<StatDeltaLine> deltas) { deltas = null; if ((Object)(object)player == (Object)null || (Object)(object)card == (Object)null) { return false; } string text = ResolveCardName(card); if (string.IsNullOrEmpty(text)) { return false; } if (RemovalProviders.TryGetValue(text, out var value)) { deltas = value(player, card) ?? Array.Empty<StatDeltaLine>(); return true; } IReadOnlyList<StatDeltaLine> readOnlyList = StatTemplateDeltaProvider.ComputeRemoval(player, card); if (readOnlyList.Count > 0) { deltas = readOnlyList; return true; } if (!TryGetDeltas(player, card, out var deltas2) || deltas2.Count == 0) { return false; } deltas = deltas2.Select((StatDeltaLine line) => line.Inverted).ToList(); return true; } internal static string ResolveCardName(CardInfo card) { if (!string.IsNullOrEmpty(card.cardName)) { return card.cardName; } if (!((Object)(object)card.sourceCard != (Object)null)) { return null; } return card.sourceCard.cardName; } private static IReadOnlyList<StatDeltaLine> ToLines(IReadOnlyList<(string label, string before, string after)> tuples) { if (tuples == null || tuples.Count == 0) { return Array.Empty<StatDeltaLine>(); } return tuples.Select(((string label, string before, string after) t) => (string.IsNullOrEmpty(t.before) && string.IsNullOrEmpty(t.after)) ? StatDeltaLine.Note(t.label) : new StatDeltaLine(t.label, t.before, t.after)).ToList(); } } public static class CardDeltaTier2 { public static void RegisterEffectNotes(string cardName, params string[] notes) { if (notes != null && notes.Length != 0) { CardDeltaRegistry.RegisterAddon(cardName, (Player _, CardInfo __) => notes.Select(StatDeltaLine.Note).ToList()); } } public static void RegisterEffectNotes(string cardName, Func<Player, CardInfo, IReadOnlyList<string>> notes) { if (notes != null) { CardDeltaRegistry.RegisterAddon(cardName, (Player player, CardInfo card) => (notes(player, card) ?? Array.Empty<string>()).Select(StatDeltaLine.Note).ToList()); } } public static void RegisterOverrideSimple(string cardName, CardDeltaRegistry.SimpleDeltaProvider provider) { CardDeltaRegistry.RegisterSimple(cardName, provider); } } public readonly struct StatDeltaLine { private const string IncreaseColor = "#66FF88"; private const string DecreaseColor = "#FF6666"; private const string NeutralColor = "#EBF0FF"; private static readonly HashSet<string> LowerIsBetterStats = new HashSet<string> { "Block CD", "Player Size", "Attack SPD", "Reload Time", "Bullet Gravity" }; public readonly string Label; public readonly string Before; public readonly string After; public readonly bool IsNote; public StatDeltaLine Inverted { get { if (!IsNote) { return new StatDeltaLine(Label, After, Before); } return this; } } public StatDeltaLine(string label, string before, string after, bool isNote = false) { Label = label; Before = before; After = after; IsNote = isNote; } public static StatDeltaLine Note(string text) { return new StatDeltaLine(text, null, null, isNote: true); } public string Format() { if (!IsNote) { return Label + ": " + Before + " --> " + After; } return Label; } public string FormatRichText() { if (IsNote) { return Label; } if (!TryParseStatValue(Before, out var value) || !TryParseStatValue(After, out var value2)) { return Format(); } bool num = LowerIsBetterStats.Contains(Label); bool flag = value2 > value; bool flag2 = (num ? (!flag) : flag); string text = ((value2 == value) ? "#EBF0FF" : (flag2 ? "#66FF88" : "#FF6666")); return Label + ": " + Before + " --> <color=" + text + ">" + After + "</color>"; } private static bool TryParseStatValue(string text, out float value) { value = 0f; if (string.IsNullOrEmpty(text)) { return false; } int i; for (i = 0; i < text.Length && (char.IsDigit(text[i]) || text[i] == '.' || text[i] == '-'); i++) { } if (i == 0) { return false; } return float.TryParse(text.Substring(0, i), NumberStyles.Float, CultureInfo.InvariantCulture, out value); } } internal static class StatTemplateDeltaProvider { private const float Epsilon = 0.0001f; public static IReadOnlyList<StatDeltaLine> Compute(Player player, CardInfo card) { if ((Object)(object)player == (Object)null || (Object)(object)card == (Object)null) { return Array.Empty<StatDeltaLine>(); } GameObject obj = (((Object)(object)card.sourceCard != (Object)null) ? ((Component)card.sourceCard).gameObject : ((Component)card).gameObject); Gun component = obj.GetComponent<Gun>(); CharacterStatModifiers component2 = obj.GetComponent<CharacterStatModifiers>(); Block componentInChildren = obj.GetComponentInChildren<Block>(); if (!HasStatTemplate(component, component2, componentInChildren)) { return Array.Empty<StatDeltaLine>(); } Gun val = player.data?.weaponHandler?.gun; Block val2 = player.data?.block; CharacterData data = player.data; CharacterStatModifiers component3 = ((Component)player).GetComponent<CharacterStatModifiers>(); GunAmmo val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<GunAmmo>() : null); List<StatDeltaLine> list = new List<StatDeltaLine>(); if ((Object)(object)component2 != (Object)null && (Object)(object)data != (Object)null && (Object)(object)component3 != (Object)null) { TryAdd(list, "HP", data.maxHealth, data.maxHealth * component2.health, "f0"); TryAdd(list, "Lives", (float)component3.respawns + 1f, (float)(component3.respawns + component2.respawns) + 1f, "f0"); TryAdd(list, "Move SPD", component3.movementSpeed, component3.movementSpeed * component2.movementSpeed, "f2"); TryAdd(list, "Jump Height", component3.jump, component3.jump * component2.jump, "f2"); TryAdd(list, "Player Size", component3.sizeMultiplier, component3.sizeMultiplier * component2.sizeMultiplier, "f2"); TryAdd(list, "Life Steal", component3.lifeSteal, component3.lifeSteal + component2.lifeSteal, "f2"); } if ((Object)(object)componentInChildren != (Object)null && (Object)(object)val2 != (Object)null) { float before = val2.Cooldown(); float after = (val2.cooldown + val2.cdAdd + componentInChildren.cdAdd) * (val2.cdMultiplier * componentInChildren.cdMultiplier); TryAdd(list, "Block CD", before, after, "f2", "s"); TryAdd(list, "Block Count", (float)val2.additionalBlocks + 1f, (float)(val2.additionalBlocks + componentInChildren.additionalBlocks) + 1f, "f0"); } if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null) { float before2 = val.damage * 55f * val.bulletDamageMultiplier; float after2 = ApplyGunDamage(val.damage, val.numberOfProjectiles, component) * 55f * (val.bulletDamageMultiplier * component.bulletDamageMultiplier); TryAdd(list, "DMG", before2, after2, "f0"); TryAdd(list, "Knockback", val.knockback, ApplyKnockback(val.knockback, val.numberOfProjectiles, component), "f2"); TryAdd(list, "Damage Grow", val.damageAfterDistanceMultiplier, val.damageAfterDistanceMultiplier * component.damageAfterDistanceMultiplier, "f2"); TryAdd(list, "Bullet Slow", val.slow, val.slow + component.slow, "f2"); TryAdd(list, "Attack SPD", val.attackSpeed * val.attackSpeedMultiplier, val.attackSpeed * component.attackSpeed * val.attackSpeedMultiplier, "f2", "s"); TryAdd(list, "Bullet SPD", val.projectileSpeed, val.projectileSpeed * component.projectileSpeed, "f2"); TryAdd(list, "Projectile SPD", val.projectielSimulatonSpeed, val.projectielSimulatonSpeed * component.projectielSimulatonSpeed, "f2"); TryAdd(list, "Bullet Gravity", val.gravity, val.gravity * component.gravity, "f2"); TryAdd(list, "Bullets", val.numberOfProjectiles, val.numberOfProjectiles + component.numberOfProjectiles, "f0"); TryAdd(list, "Bounces", val.reflects, val.reflects + component.reflects, "f0"); TryAdd(list, "Bursts", val.bursts, val.bursts + component.bursts, "f0"); if (component.destroyBulletAfter != 0f) { TryAdd(list, "Bullet Range", val.destroyBulletAfter, component.destroyBulletAfter, "f2"); } else { TryAdd(list, "Bullet Range", val.destroyBulletAfter, val.destroyBulletAfter + component.destroyBulletAfter, "f2"); } } if ((Object)(object)component != (Object)null && (Object)(object)val3 != (Object)null) { float before3 = (val3.reloadTime + val3.reloadTimeAdd) * val3.reloadTimeMultiplier; float after3 = (val3.reloadTime + val3.reloadTimeAdd + component.reloadTimeAdd) * (val3.reloadTimeMultiplier * component.reloadTime); TryAdd(list, "Reload Time", before3, after3, "f2", "s"); TryAdd(list, "Ammo", val3.maxAmmo, Mathf.Clamp(val3.maxAmmo + component.ammo, 1, 90), "f0"); } return list; } public static IReadOnlyList<StatDeltaLine> ComputeRemoval(Player player, CardInfo card) { if ((Object)(object)player == (Object)null || (Object)(object)card == (Object)null) { return Array.Empty<StatDeltaLine>(); } GameObject obj = (((Object)(object)card.sourceCard != (Object)null) ? ((Component)card.sourceCard).gameObject : ((Component)card).gameObject); Gun component = obj.GetComponent<Gun>(); CharacterStatModifiers component2 = obj.GetComponent<CharacterStatModifiers>(); Block componentInChildren = obj.GetComponentInChildren<Block>(); if (!HasStatTemplate(component, component2, componentInChildren)) { return Array.Empty<StatDeltaLine>(); } Gun val = player.data?.weaponHandler?.gun; Block val2 = player.data?.block; CharacterData data = player.data; CharacterStatModifiers component3 = ((Component)player).GetComponent<CharacterStatModifiers>(); GunAmmo val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<GunAmmo>() : null); List<StatDeltaLine> list = new List<StatDeltaLine>(); if ((Object)(object)component2 != (Object)null && (Object)(object)data != (Object)null && (Object)(object)component3 != (Object)null) { TryAdd(list, "HP", data.maxHealth, SafeDivide(data.maxHealth, component2.health), "f0"); TryAdd(list, "Lives", (float)component3.respawns + 1f, (float)(component3.respawns - component2.respawns) + 1f, "f0"); TryAdd(list, "Move SPD", component3.movementSpeed, SafeDivide(component3.movementSpeed, component2.movementSpeed), "f2"); TryAdd(list, "Jump Height", component3.jump, SafeDivide(component3.jump, component2.jump), "f2"); TryAdd(list, "Player Size", component3.sizeMultiplier, SafeDivide(component3.sizeMultiplier, component2.sizeMultiplier), "f2"); TryAdd(list, "Life Steal", component3.lifeSteal, component3.lifeSteal - component2.lifeSteal, "f2"); } if ((Object)(object)componentInChildren != (Object)null && (Object)(object)val2 != (Object)null) { float num = val2.Cooldown(); float num2 = SafeDivide(num, val2.cdMultiplier * componentInChildren.cdMultiplier); num2 = (num2 - val2.cdAdd - componentInChildren.cdAdd) / Mathf.Max(val2.cdMultiplier, 0.0001f); TryAdd(list, "Block CD", num, num2, "f2", "s"); TryAdd(list, "Block Count", (float)val2.additionalBlocks + 1f, (float)(val2.additionalBlocks - componentInChildren.additionalBlocks) + 1f, "f0"); } if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null) { float before = val.damage * 55f * val.bulletDamageMultiplier; float after = InverseApplyGunDamage(val.damage, val.numberOfProjectiles, component) * 55f * SafeDivide(val.bulletDamageMultiplier, component.bulletDamageMultiplier); TryAdd(list, "DMG", before, after, "f0"); TryAdd(list, "Knockback", val.knockback, InverseApplyKnockback(val.knockback, val.numberOfProjectiles, component), "f2"); TryAdd(list, "Damage Grow", val.damageAfterDistanceMultiplier, SafeDivide(val.damageAfterDistanceMultiplier, component.damageAfterDistanceMultiplier), "f2"); TryAdd(list, "Bullet Slow", val.slow, val.slow - component.slow, "f2"); TryAdd(list, "Attack SPD", val.attackSpeed * val.attackSpeedMultiplier, SafeDivide(val.attackSpeed, component.attackSpeed) * val.attackSpeedMultiplier, "f2", "s"); TryAdd(list, "Bullet SPD", val.projectileSpeed, SafeDivide(val.projectileSpeed, component.projectileSpeed), "f2"); TryAdd(list, "Projectile SPD", val.projectielSimulatonSpeed, SafeDivide(val.projectielSimulatonSpeed, component.projectielSimulatonSpeed), "f2"); TryAdd(list, "Bullet Gravity", val.gravity, SafeDivide(val.gravity, component.gravity), "f2"); TryAdd(list, "Bullets", val.numberOfProjectiles, val.numberOfProjectiles - component.numberOfProjectiles, "f0"); TryAdd(list, "Bounces", val.reflects, val.reflects - component.reflects, "f0"); TryAdd(list, "Bursts", val.bursts, val.bursts - component.bursts, "f0"); if (component.destroyBulletAfter != 0f) { TryAdd(list, "Bullet Range", val.destroyBulletAfter, val.destroyBulletAfter - component.destroyBulletAfter, "f2"); } else { TryAdd(list, "Bullet Range", val.destroyBulletAfter, val.destroyBulletAfter - component.destroyBulletAfter, "f2"); } } if ((Object)(object)component != (Object)null && (Object)(object)val3 != (Object)null) { float before2 = (val3.reloadTime + val3.reloadTimeAdd) * val3.reloadTimeMultiplier; float after2 = (val3.reloadTime + val3.reloadTimeAdd - component.reloadTimeAdd) * SafeDivide(val3.reloadTimeMultiplier, component.reloadTime); TryAdd(list, "Reload Time", before2, after2, "f2", "s"); TryAdd(list, "Ammo", val3.maxAmmo, Mathf.Clamp(val3.maxAmmo - component.ammo, 1, 90), "f0"); } return list; } internal static bool HasStatTemplate(Gun cardGun, CharacterStatModifiers cardPlayer, Block cardBlock) { if ((Object)(object)cardGun != (Object)null && GunHasChanges(cardGun)) { return true; } if ((Object)(object)cardPlayer != (Object)null && PlayerHasChanges(cardPlayer)) { return true; } if ((Object)(object)cardBlock != (Object)null && BlockHasChanges(cardBlock)) { return true; } return false; } private static bool GunHasChanges(Gun g) { if (Mathf.Approximately(g.damage, 1f) && Mathf.Approximately(g.bulletDamageMultiplier, 1f) && Mathf.Approximately(g.knockback, 1f) && Mathf.Approximately(g.attackSpeed, 1f) && Mathf.Approximately(g.projectileSpeed, 1f) && Mathf.Approximately(g.projectielSimulatonSpeed, 1f) && Mathf.Approximately(g.gravity, 1f) && Mathf.Approximately(g.damageAfterDistanceMultiplier, 1f) && Mathf.Approximately(g.reloadTime, 1f) && Mathf.Approximately(g.reloadTimeAdd, 0f) && g.ammo == 0 && g.numberOfProjectiles == 0 && g.reflects == 0 && g.bursts == 0 && g.slow == 0f) { return g.destroyBulletAfter != 0f; } return true; } private static bool PlayerHasChanges(CharacterStatModifiers s) { if (Mathf.Approximately(s.health, 1f) && Mathf.Approximately(s.movementSpeed, 1f) && Mathf.Approximately(s.jump, 1f) && Mathf.Approximately(s.sizeMultiplier, 1f) && s.respawns == 0) { return s.lifeSteal != 0f; } return true; } private static bool BlockHasChanges(Block b) { if (Mathf.Approximately(b.cdMultiplier, 1f) && b.cdAdd == 0f) { return b.additionalBlocks != 0; } return true; } private static float ProjectileBlendFactor(int cardProjectiles, int currentProjectiles) { if (cardProjectiles == 0 || currentProjectiles == 1) { return 1f; } return (float)cardProjectiles / (float)(cardProjectiles + currentProjectiles); } private static float ApplyGunDamage(float currentDamage, int currentProjectiles, Gun cardGun) { float num = ProjectileBlendFactor(cardGun.numberOfProjectiles, currentProjectiles); return Mathf.Max(currentDamage * (1f - num * (1f - cardGun.damage)), 0.25f); } private static float ApplyKnockback(float currentKnockback, int currentProjectiles, Gun cardGun) { float num = ProjectileBlendFactor(cardGun.numberOfProjectiles, currentProjectiles); return currentKnockback * (1f - num * (1f - cardGun.knockback)); } private static float SafeDivide(float value, float divisor) { if (Mathf.Abs(divisor) < 0.0001f) { return value; } return value / divisor; } private static float InverseApplyGunDamage(float currentDamage, int currentProjectiles, Gun cardGun) { int currentProjectiles2 = Mathf.Max(1, currentProjectiles - cardGun.numberOfProjectiles); float num = ProjectileBlendFactor(cardGun.numberOfProjectiles, currentProjectiles2); float num2 = 1f - num * (1f - cardGun.damage); if (Mathf.Abs(num2) < 0.0001f) { return currentDamage; } return Mathf.Max(currentDamage / num2, 0.25f); } private static float InverseApplyKnockback(float currentKnockback, int currentProjectiles, Gun cardGun) { int currentProjectiles2 = Mathf.Max(1, currentProjectiles - cardGun.numberOfProjectiles); float num = ProjectileBlendFactor(cardGun.numberOfProjectiles, currentProjectiles2); float num2 = 1f - num * (1f - cardGun.knockback); if (Mathf.Abs(num2) < 0.0001f) { return currentKnockback; } return currentKnockback / num2; } private static void TryAdd(List<StatDeltaLine> lines, string label, float before, float after, string format, string suffix = "") { if (!(Mathf.Abs(before - after) < 0.0001f)) { lines.Add(new StatDeltaLine(label, before.ToString(format) + suffix, after.ToString(format) + suffix)); } } } internal static class StatTemplateDeltaRegistrar { internal static void Init() { CardManager.AddAllCardsCallback((Action<CardInfo[]>)RegisterAll); IOLog.Line("StatTemplateDeltaRegistrar — waiting for CardManager.FirstTimeStart."); } private static void RegisterAll(CardInfo[] cards) { IOLog.Section("StatTemplateDeltaRegistrar — RegisterAll"); int num = 0; int num2 = 0; foreach (CardInfo val in cards) { if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(val.cardName)) { continue; } if (CardDeltaRegistry.IsRegistered(val.cardName)) { num2++; continue; } GameObject obj = (((Object)(object)val.sourceCard != (Object)null) ? ((Component)val.sourceCard).gameObject : ((Component)val).gameObject); Gun component = obj.GetComponent<Gun>(); CharacterStatModifiers component2 = obj.GetComponent<CharacterStatModifiers>(); Block componentInChildren = obj.GetComponentInChildren<Block>(); if (StatTemplateDeltaProvider.HasStatTemplate(component, component2, componentInChildren)) { CardDeltaRegistry.Register(val.cardName, StatTemplateDeltaProvider.Compute); num++; } } IOLog.Line($"Registered {num} stat-template cards (skipped {num2} already registered)."); } } } namespace InfoOverhaul.Compat { internal static class MfmTier2Compat { internal static void Init() { CardManager.AddAllCardsCallback((Action<CardInfo[]>)delegate { RegisterEffectNotes(); }); } private static void RegisterEffectNotes() { IOLog.Section("MfmTier2Compat — RegisterEffectNotes"); IOLog.Line("MfmTier2Compat ready (no notes registered yet — add per card as validated)."); } } }
Keybound.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Keybound.Cards; using Keybound.Compat; using Keybound.Core; using Keybound.Effects; using Keybound.UI; using Microsoft.CodeAnalysis; using TMPro; using UnboundLib.Cards; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyCompany("Keybound")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+146ac727a7fc6b83f382d57f53cce40478349c58")] [assembly: AssemblyProduct("Keybound Mod for ROUNDS")] [assembly: AssemblyTitle("Keybound")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 Keybound { internal static class KLog { private static ManualLogSource Logger => Plugin.Logger; internal static void Section(string title) { ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)"====================="); } ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)("[Keybound] " + title)); } ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogInfo((object)"====================="); } } internal static void Line(string message) { ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)("[Keybound] " + message)); } } internal static void Warn(string message) { ManualLogSource logger = Logger; if (logger != null) { logger.LogWarning((object)("[Keybound] " + message)); } } internal static void Error(string message) { ManualLogSource logger = Logger; if (logger != null) { logger.LogError((object)("[Keybound] " + message)); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Keybound", "Keybound Mod for ROUNDS", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static string PluginDirectory { get; private set; } private void Awake() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? ""; KLog.Section("Plugin Awake"); KLog.Line("PluginDirectory = " + PluginDirectory); new Harmony("Keybound").PatchAll(); ((Component)this).gameObject.AddComponent<EffectStackManager>(); GameObject val = new GameObject("KB_UIRoot"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<KeybindModalUI>(); val.AddComponent<EffectStackOverlay>(); KLog.Line("Plugin Keybound loaded."); } private void Start() { KeyboundCardRegistrar.RegisterAll(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Keybound"; public const string PLUGIN_NAME = "Keybound Mod for ROUNDS"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace Keybound.UI { public class EffectStackOverlay : MonoBehaviour { private sealed class PlayerEffectRow { internal GameObject Root; private RectTransform _slotRow; private readonly List<EffectSlotView> _slots = new List<EffectSlotView>(); private Action<KeyboundBinding, Vector3> _onHover; private Action _onHoverExit; internal static PlayerEffectRow Create(Transform parent, int playerID, Action<KeyboundBinding, Vector3> onHover, Action onHoverExit) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown GameObject val = new GameObject($"EffectRow_P{playerID}"); val.transform.SetParent(parent, false); val.AddComponent<RectTransform>(); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredHeight = 35f; obj.minHeight = 35f; HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)5; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; return new PlayerEffectRow { Root = val, _slotRow = val.GetComponent<RectTransform>(), _onHover = onHover, _onHoverExit = onHoverExit }; } internal void Refresh(IReadOnlyList<KeyboundBinding> bindings) { Root.SetActive(true); EnsureSlotCount(bindings.Count); for (int i = 0; i < bindings.Count; i++) { _slots[i].Bind(bindings[i]); } for (int j = bindings.Count; j < _slots.Count; j++) { _slots[j].Root.SetActive(false); } } private void EnsureSlotCount(int count) { while (_slots.Count < count) { EffectSlotView item = EffectSlotView.Create((Transform)(object)_slotRow, _onHover, _onHoverExit); _slots.Add(item); } } } private sealed class EffectSlotView : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { internal GameObject Root; private Image _bg; private TextMeshProUGUI _label; private static readonly Color CooldownRed = new Color(0.55f, 0.12f, 0.12f, 0.95f); private static readonly Color ReadyGreen = new Color(0.12f, 0.55f, 0.18f, 0.95f); private static readonly Color BorderRed = new Color(0.95f, 0.2f, 0.2f, 1f); private static readonly Color BorderGreen = new Color(0.2f, 1f, 0.2f, 1f); private KeyboundBinding _binding; private Action<KeyboundBinding, Vector3> _onHover; private Action _onHoverExit; internal static EffectSlotView Create(Transform parent, Action<KeyboundBinding, Vector3> onHover, Action onHoverExit) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("EffectSlot"); val.transform.SetParent(parent, false); val.AddComponent<RectTransform>().sizeDelta = new Vector2(35f, 35f); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 35f; obj.preferredHeight = 35f; EffectSlotView effectSlotView = val.AddComponent<EffectSlotView>(); effectSlotView._onHover = onHover; effectSlotView._onHoverExit = onHoverExit; effectSlotView.Root = val; effectSlotView.Build(); return effectSlotView; } private void Build() { //IL_0017: 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_0046: Unknown result type (might be due to invalid IL or missing references) _bg = ((Component)this).gameObject.AddComponent<Image>(); ((Graphic)_bg).color = CooldownRed; Outline obj = ((Component)_bg).gameObject.AddComponent<Outline>(); ((Shadow)obj).effectColor = BorderRed; ((Shadow)obj).effectDistance = new Vector2(3f, -3f); _label = UIHelper.CreateText(((Component)this).transform, "Abbr", "—", 12, (TextAlignmentOptions)514); } internal void Bind(KeyboundBinding binding) { _binding = binding; ((TMP_Text)_label).text = Abbreviate(binding.CardName); RefreshVisual(); } private void Update() { if (_binding != null) { RefreshVisual(); } } private void RefreshVisual() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) float num = 1f - _binding.CooldownFill(); ((Graphic)_bg).color = Color.Lerp(CooldownRed, ReadyGreen, num); Outline obj = ((Component)_bg).GetComponent<Outline>() ?? ((Component)_bg).gameObject.AddComponent<Outline>(); ((Shadow)obj).effectColor = (_binding.IsReady() ? BorderGreen : BorderRed); ((Shadow)obj).effectDistance = new Vector2(3f, -3f); } public void OnPointerEnter(PointerEventData _) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_binding != null) { _onHover?.Invoke(_binding, ((Component)this).transform.position); } } public void OnPointerExit(PointerEventData _) { _onHoverExit?.Invoke(); } private static string Abbreviate(string name) { if (string.IsNullOrEmpty(name)) { return "?"; } if (name.Length == 1) { return name.ToUpper(); } return char.ToUpper(name[0]) + name.Substring(1, 1).ToLower(); } } public static EffectStackOverlay instance; private const float RowHeight = 35f; private const float RowSpacing = 4f; private const float SlotSize = 35f; private Canvas _canvas; private RectTransform _container; private readonly Dictionary<int, PlayerEffectRow> _playerRows = new Dictionary<int, PlayerEffectRow>(); private GameObject _hoverCard; private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); BuildUI(); ((Component)_canvas).gameObject.SetActive(false); } private void BuildUI() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown _canvas = UIHelper.CreateFullscreenCanvas("KB_EffectStack", 45); _container = UIHelper.CreatePanel(((Component)_canvas).transform, "EffectContainer", new Vector2(0.55f, 0.02f), new Vector2(0.98f, 0.3f)); VerticalLayoutGroup obj = ((Component)_container).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj).childAlignment = (TextAnchor)8; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((LayoutGroup)obj).padding = new RectOffset(0, 4, 4, 0); } public void RefreshAll() { if ((Object)(object)EffectStackManager.instance == (Object)null) { HideAll(); return; } bool flag = false; HashSet<int> hashSet = new HashSet<int>(); foreach (KeyValuePair<int, IReadOnlyList<KeyboundBinding>> allBinding in EffectStackManager.instance.GetAllBindings()) { hashSet.Add(allBinding.Key); GetOrCreateRow(allBinding.Key).Refresh(allBinding.Value); flag = true; } foreach (KeyValuePair<int, PlayerEffectRow> playerRow in _playerRows) { if (!hashSet.Contains(playerRow.Key)) { playerRow.Value.Root.SetActive(false); } } if (!flag) { HideAll(); } else { ((Component)_canvas).gameObject.SetActive(true); } } public void Refresh(int playerID) { RefreshAll(); } public void HideAll() { ClearHover(); foreach (PlayerEffectRow value in _playerRows.Values) { value.Root.SetActive(false); } if ((Object)(object)_canvas != (Object)null) { ((Component)_canvas).gameObject.SetActive(false); } } private void Update() { if (!((Object)(object)_canvas == (Object)null) && ((Component)_canvas).gameObject.activeSelf && !IsGameActive()) { HideAll(); } } private PlayerEffectRow GetOrCreateRow(int playerID) { if (_playerRows.TryGetValue(playerID, out var value)) { return value; } value = PlayerEffectRow.Create((Transform)(object)_container, playerID, OnSlotHover, OnSlotHoverExit); _playerRows[playerID] = value; return value; } private void OnSlotHover(KeyboundBinding binding, Vector3 worldPos) { //IL_003b: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) ClearHover(); if ((Object)(object)CardChoice.instance == (Object)null) { return; } CardInfo val = binding.Card ?? FindCardTemplate(binding.CardName); if ((Object)(object)val == (Object)null) { return; } _hoverCard = CardChoice.instance.AddCardVisual(val, worldPos); if (!((Object)(object)_hoverCard == (Object)null)) { Collider2D[] componentsInChildren = ((Component)_hoverCard.transform.root).GetComponentsInChildren<Collider2D>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Canvas componentInChildren = _hoverCard.GetComponentInChildren<Canvas>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.sortingLayerName = "MostFront"; } RectTransform component = ((Component)UIHelper.CreateText(_hoverCard.transform, "KeyLabel", "Bound to " + KeybindModalUI.FormatKey(binding.Key), 18, (TextAlignmentOptions)1026, (Color?)new Color(0.75f, 0.9f, 1f))).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0.18f); Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; } } private void OnSlotHoverExit() { ClearHover(); } private void ClearHover() { if ((Object)(object)_hoverCard != (Object)null) { Object.Destroy((Object)(object)_hoverCard); _hoverCard = null; } } private static CardInfo FindCardTemplate(string cardName) { if (CardChoice.instance?.cards == null) { return null; } CardInfo[] cards = CardChoice.instance.cards; foreach (CardInfo val in cards) { if ((Object)(object)val != (Object)null && val.cardName == cardName) { return val; } } return null; } private static bool IsGameActive() { if ((Object)(object)GameManager.instance == (Object)null) { return false; } if (!GameManager.instance.isPlaying) { return false; } if (PlayerManager.instance?.players == null || PlayerManager.instance.players.Count == 0) { return false; } return true; } } public class KeybindModalUI : MonoBehaviour { public static KeybindModalUI instance; private const int KeyA = 97; private const int KeyZ = 122; private const int KeyAlpha0 = 48; private const int KeyAlpha9 = 57; private Canvas _canvas; private TextMeshProUGUI _messageText; private Button _bindButton; private Image _bindImage; private TextMeshProUGUI _bindLabel; private Action<int> _onConfirm; private Action _onCancel; private int _pickerID; private CardInfo _card; private int? _pendingKey; private static readonly Color PanelBg = new Color(0.04f, 0.06f, 0.12f, 1f); private static readonly Color CancelBg = new Color(0.4f, 0.1f, 0.1f, 0.95f); private static readonly Color BindReadyBg = new Color(0.1f, 0.45f, 0.12f, 0.95f); private static readonly Color BindGrayBg = new Color(0.18f, 0.18f, 0.18f, 0.55f); private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); BuildUI(); ((Component)_canvas).gameObject.SetActive(false); } private void BuildUI() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) _canvas = UIHelper.CreateFullscreenCanvas("KB_KeybindModal", 190); UIHelper.CreatePanel(((Component)_canvas).transform, "Dim", Vector2.zero, Vector2.one, (Color?)new Color(0f, 0f, 0f, 0.55f)); RectTransform val = UIHelper.CreatePanel(((Component)_canvas).transform, "Panel", new Vector2(0.25f, 0.35f), new Vector2(0.75f, 0.65f), PanelBg); UIHelper.CreateText((Transform)(object)val, "Title", "Bind Key", 28, (TextAlignmentOptions)258, (Color?)new Color(0.9f, 0.93f, 1f)); _messageText = UIHelper.CreateText((Transform)(object)val, "Message", "Press a key to bind this effect.", 22, (TextAlignmentOptions)4098, (Color?)new Color(0.88f, 0.92f, 1f)); RectTransform component = ((Component)_messageText).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.05f, 0.35f); component.anchorMax = new Vector2(0.95f, 0.75f); Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; ((UnityEvent)UIHelper.CreateButton((Transform)(object)val, "CancelBtn", "[Cancel]", new Vector2(0.08f, 0.1f), new Vector2(0.42f, 0.28f), 20, CancelBg).onClick).AddListener(new UnityAction(OnCancelClicked)); GameObject val2 = new GameObject("BindBtn"); val2.transform.SetParent((Transform)(object)val, false); RectTransform obj = val2.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0.58f, 0.1f); obj.anchorMax = new Vector2(0.92f, 0.28f); offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; _bindImage = val2.AddComponent<Image>(); ((Graphic)_bindImage).color = BindGrayBg; _bindButton = val2.AddComponent<Button>(); ((Selectable)_bindButton).targetGraphic = (Graphic)(object)_bindImage; ((Selectable)_bindButton).interactable = false; ((UnityEvent)_bindButton.onClick).AddListener(new UnityAction(OnBindClicked)); GameObject val3 = new GameObject("Label"); val3.transform.SetParent(val2.transform, false); RectTransform obj2 = val3.AddComponent<RectTransform>(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; offsetMin = (obj2.offsetMax = Vector2.zero); obj2.offsetMin = offsetMin; _bindLabel = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_bindLabel).text = "[Bind Key]"; ((TMP_Text)_bindLabel).fontSize = 20f; ((TMP_Text)_bindLabel).alignment = (TextAlignmentOptions)514; ((Graphic)_bindLabel).color = new Color(0.45f, 0.45f, 0.45f); } public void Show(int pickerID, CardInfo card, Action<int> onConfirm, Action onCancel) { _pickerID = pickerID; _card = card; _onConfirm = onConfirm; _onCancel = onCancel; _pendingKey = null; ((TMP_Text)_messageText).text = "Press a key to bind <b>" + card.cardName + "</b>."; RefreshBindButton(); ((Component)_canvas).gameObject.SetActive(true); KLog.Line($"Keybind modal shown for '{card.cardName}' (picker={pickerID})."); } public void Hide() { ((Component)_canvas).gameObject.SetActive(false); _onConfirm = null; _onCancel = null; _card = null; _pendingKey = null; } private void Update() { if (!((Component)_canvas).gameObject.activeSelf || (Object)(object)_card == (Object)null) { return; } if (InputCompat.GetKeyDown(27)) { OnCancelClicked(); return; } int[] bindableKeys = GetBindableKeys(); foreach (int num in bindableKeys) { if (InputCompat.GetKeyDown(num)) { EffectStackManager effectStackManager = EffectStackManager.instance; if (effectStackManager != null && effectStackManager.IsKeyTaken(_pickerID, num)) { ((TMP_Text)_messageText).text = "<color=#ff8888>" + FormatKey(num) + " is already bound.</color>"; _pendingKey = null; RefreshBindButton(); break; } _pendingKey = num; ((TMP_Text)_messageText).text = "Bind <b>" + _card.cardName + "</b> to <b>" + FormatKey(num) + "</b>?"; RefreshBindButton(); break; } } } private void RefreshBindButton() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) bool hasValue = _pendingKey.HasValue; ((Selectable)_bindButton).interactable = hasValue; ((Graphic)_bindImage).color = (hasValue ? BindReadyBg : BindGrayBg); ((Graphic)_bindLabel).color = (Color)(hasValue ? Color.white : new Color(0.45f, 0.45f, 0.45f)); } private void OnBindClicked() { if (_pendingKey.HasValue) { int value = _pendingKey.Value; Action<int> onConfirm = _onConfirm; Hide(); onConfirm?.Invoke(value); } } private void OnCancelClicked() { Action onCancel = _onCancel; Hide(); onCancel?.Invoke(); } private static int[] GetBindableKeys() { int[] array = new int[36]; int num = 0; for (int i = 97; i <= 122; i++) { array[num++] = i; } for (int j = 48; j <= 57; j++) { array[num++] = j; } return array; } internal static string FormatKey(int key) { if (key >= 48 && key <= 57) { return (key - 48).ToString(); } if (key >= 97 && key <= 122) { return ((char)key).ToString().ToUpper(); } return key.ToString(); } } internal static class UIHelper { public static Canvas CreateFullscreenCanvas(string name, int sortOrder = 100) { //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_000c: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) GameObject val = new GameObject(name); Object.DontDestroyOnLoad((Object)val); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = sortOrder; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); return val2; } public static RectTransform CreatePanel(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Color? bg = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; if (bg.HasValue) { ((Graphic)val.AddComponent<Image>()).color = bg.Value; } return obj; } public static TextMeshProUGUI CreateText(Transform parent, string name, string text, int fontSize = 24, TextAlignmentOptions alignment = 514, Color? color = null) { //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_0013: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj2).text = text; ((TMP_Text)obj2).fontSize = fontSize; ((TMP_Text)obj2).alignment = alignment; ((Graphic)obj2).color = (Color)(((??)color) ?? Color.white); return obj2; } public static Button CreateButton(Transform parent, string name, string label, Vector2 anchorMin, Vector2 anchorMax, int fontSize = 20, Color? bgColor = null, Color? textColor = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = anchorMin; obj.anchorMax = anchorMax; Vector2 offsetMin = (obj.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; Image val2 = val.AddComponent<Image>(); ((Graphic)val2).color = (Color)(((??)bgColor) ?? new Color(0.2f, 0.2f, 0.2f, 0.9f)); Button obj2 = val.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val2; ColorBlock colors = default(ColorBlock); ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = new Color(1.15f, 1.15f, 1.15f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.8f, 0.8f); ((ColorBlock)(ref colors)).disabledColor = Color.white; ((ColorBlock)(ref colors)).colorMultiplier = 1f; ((ColorBlock)(ref colors)).fadeDuration = 0.1f; ((Selectable)obj2).colors = colors; GameObject val3 = new GameObject("Label"); val3.transform.SetParent(val.transform, false); RectTransform obj3 = val3.AddComponent<RectTransform>(); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; offsetMin = (obj3.offsetMax = Vector2.zero); obj3.offsetMin = offsetMin; TextMeshProUGUI obj4 = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj4).text = label; ((TMP_Text)obj4).fontSize = fontSize; ((TMP_Text)obj4).alignment = (TextAlignmentOptions)514; ((Graphic)obj4).color = (Color)(((??)textColor) ?? Color.white); return obj2; } } } namespace Keybound.Patches { [HarmonyPatch] internal static class DeckPickCompatPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("DeckBuilder.GameIntegration.DeckPickPatch"); if (!(type == null)) { return AccessTools.Method(type, "ApplyStats_Postfix", (Type[])null, (Type[])null); } return null; } [HarmonyPrefix] [HarmonyPriority(800)] private static bool SuppressDeckConsume(ApplyCardStats __instance) { if ((Object)(object)__instance == (Object)null) { return true; } CardInfo componentInParent = ((Component)__instance).GetComponentInParent<CardInfo>(); if ((Object)(object)componentInParent == (Object)null) { return true; } if (!KeyboundCardRegistry.IsKeybound(componentInParent.cardName)) { return true; } KLog.Line("Suppressed DeckPickPatch consume for keybound card '" + componentInParent.cardName + "'."); return false; } } [HarmonyPatch] internal static class KeyboundPickPatches { internal static bool IsBindFlowActive; private static int _pickerID = -1; private static CardInfo _pendingCard; [HarmonyPatch(typeof(ApplyCardStats), "ApplyStats")] [HarmonyPrefix] private static bool ApplyStats_Prefix(ApplyCardStats __instance) { if ((Object)(object)CardChoice.instance == (Object)null || !CardChoice.instance.IsPicking) { return true; } CardInfo componentInParent = ((Component)__instance).GetComponentInParent<CardInfo>(); if ((Object)(object)componentInParent == (Object)null || !KeyboundCardRegistry.IsKeybound(componentInParent.cardName)) { return true; } int pickrID = CardChoice.instance.pickrID; if (!IsLocalPicker(pickrID)) { return true; } KLog.Section("Keybind flow started — '" + componentInParent.cardName + "'"); StartBindFlow(pickrID, componentInParent); return false; } [HarmonyPatch(typeof(CardChoice), "RPCA_DoEndPick")] [HarmonyPrefix] private static bool RPCA_DoEndPick_Prefix() { if (!IsBindFlowActive) { return true; } KLog.Line("RPCA_DoEndPick suppressed (keybind modal open)."); return false; } [HarmonyPatch(typeof(CardBarHandler), "AddCard")] [HarmonyPrefix] private static bool CardBarHandler_AddCard_Prefix(CardInfo card) { if ((Object)(object)card == (Object)null) { return true; } if (!KeyboundCardRegistry.IsKeybound(card.cardName)) { return true; } KLog.Line("Blocked card-bar add for keybound card '" + card.cardName + "'."); return false; } private static void StartBindFlow(int pickerID, CardInfo card) { _pickerID = pickerID; _pendingCard = card; IsBindFlowActive = true; KeybindModalUI.instance?.Show(pickerID, card, OnConfirm, OnCancel); } private static void OnConfirm(int key) { KLog.Section($"Keybind confirmed — {_pendingCard?.cardName} -> {key}"); IsBindFlowActive = false; if ((Object)(object)_pendingCard != (Object)null) { EffectStackManager.instance?.AddBinding(_pickerID, _pendingCard, key); DeckBuilderBridge.ConsumeCard(_pickerID, _pendingCard); } PickPhaseHelper.EndPickPhase(); _pendingCard = null; } private static void OnCancel() { KLog.Section("Keybind cancelled"); IsBindFlowActive = false; PickPhaseHelper.RestorePickState(_pickerID, _pendingCard); _pendingCard = null; } private static bool IsLocalPicker(int pickerID) { Player val = PlayerManager.instance?.players?.Find((Player p) => p.playerID == pickerID); if ((Object)(object)val == (Object)null) { return false; } object obj = AccessTools.Field(typeof(CharacterData), "view")?.GetValue(val.data); if (obj == null) { return true; } PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), "IsMine"); if (propertyInfo == null) { return true; } return (bool)propertyInfo.GetValue(obj, null); } } } namespace Keybound.Effects { internal static class TeleportEffect { internal const string CardName = "Teleport"; internal const float InitialDelay = 10f; internal const float Cooldown = 15f; internal static readonly KeyboundEffectDef Def = new KeyboundEffectDef { CardName = "Teleport", InitialDelay = 10f, Cooldown = 15f, Activate = TryTeleport }; private static bool TryTeleport(Player player) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player?.data == (Object)null || (Object)(object)MainCam.instance?.cam == (Object)null) { return false; } Vector3 val = MainCam.instance.cam.ScreenToWorldPoint(InputCompat.MousePosition); val.z = 0f; PlayerCollision componentInParent = ((Component)player).GetComponentInParent<PlayerCollision>(); if (componentInParent != null) { componentInParent.IgnoreWallForFrames(2); } ((Component)player).transform.position = val; if ((Object)(object)player.data.playerVel != (Object)null) { Traverse.Create((object)player.data.playerVel).Field("velocity").SetValue((object)Vector2.zero); } player.data.sinceGrounded = 0f; KLog.Line($"Teleport activated for player {player.playerID} -> ({val.x:F1}, {val.y:F1})."); return true; } } } namespace Keybound.Core { public class EffectStackManager : MonoBehaviour { [CompilerGenerated] private sealed class <GetAllBindings>d__4 : IEnumerable<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>>, IEnumerable, IEnumerator<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>>, IDisposable, IEnumerator { private int <>1__state; private KeyValuePair<int, IReadOnlyList<KeyboundBinding>> <>2__current; private int <>l__initialThreadId; public EffectStackManager <>4__this; private Dictionary<int, List<KeyboundBinding>>.Enumerator <>7__wrap1; KeyValuePair<int, IReadOnlyList<KeyboundBinding>> IEnumerator<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAllBindings>d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(Dictionary<int, List<KeyboundBinding>>.Enumerator); <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; EffectStackManager effectStackManager = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = effectStackManager._bindings.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { KeyValuePair<int, List<KeyboundBinding>> current = <>7__wrap1.Current; if (current.Value != null && current.Value.Count > 0) { <>2__current = new KeyValuePair<int, IReadOnlyList<KeyboundBinding>>(current.Key, current.Value); <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap1 = default(Dictionary<int, List<KeyboundBinding>>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>> IEnumerable<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>>.GetEnumerator() { <GetAllBindings>d__4 result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new <GetAllBindings>d__4(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>>)this).GetEnumerator(); } } public static EffectStackManager instance; private readonly Dictionary<int, List<KeyboundBinding>> _bindings = new Dictionary<int, List<KeyboundBinding>>(); private bool _wasGameActive; private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } internal IReadOnlyList<KeyboundBinding> GetBindings(int playerID) { if (!_bindings.TryGetValue(playerID, out var value)) { return Array.Empty<KeyboundBinding>(); } return value; } [IteratorStateMachine(typeof(<GetAllBindings>d__4))] internal IEnumerable<KeyValuePair<int, IReadOnlyList<KeyboundBinding>>> GetAllBindings() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetAllBindings>d__4(-2) { <>4__this = this }; } internal bool IsKeyTaken(int playerID, int key) { return GetBindings(playerID).Any((KeyboundBinding b) => b.Key == key); } internal void AddBinding(int playerID, CardInfo card, int key) { if ((Object)(object)card == (Object)null || !KeyboundCardRegistry.TryGet(card.cardName, out var def)) { KLog.Warn("AddBinding failed — '" + (card?.cardName ?? "null") + "' is not keybound."); return; } if (!_bindings.TryGetValue(playerID, out var value)) { value = new List<KeyboundBinding>(); _bindings[playerID] = value; } KeyboundBinding keyboundBinding = new KeyboundBinding { PlayerID = playerID, CardName = card.cardName, Card = card, Key = key, Def = def }; keyboundBinding.ArmInitialDelay(); value.Add(keyboundBinding); KLog.Line($"Bound '{card.cardName}' to {key} for player {playerID}."); EffectStackOverlay.instance?.RefreshAll(); } internal void ClearAll() { _bindings.Clear(); EffectStackOverlay.instance?.HideAll(); } private void Update() { bool flag = IsGameActive(); if (_wasGameActive && !flag) { ClearAll(); } _wasGameActive = flag; if (!flag) { return; } Player localHumanPlayer = GetLocalHumanPlayer(); if ((Object)(object)localHumanPlayer == (Object)null) { return; } foreach (KeyboundBinding binding in GetBindings(localHumanPlayer.playerID)) { if (binding.IsReady() && InputCompat.GetKeyDown(binding.Key) && binding.Def.Activate(localHumanPlayer)) { binding.ArmCooldown(); } } EffectStackOverlay.instance?.RefreshAll(); } private static bool IsGameActive() { if ((Object)(object)GameManager.instance == (Object)null) { return false; } if (!GameManager.instance.isPlaying) { return false; } if (PlayerManager.instance?.players == null || PlayerManager.instance.players.Count == 0) { return false; } return true; } internal static Player GetLocalHumanPlayer() { if ((Object)(object)PlayerManager.instance == (Object)null) { return null; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player == (Object)null) { continue; } PlayerAPI component = ((Component)player).GetComponent<PlayerAPI>(); if (component == null || !((Behaviour)component).enabled) { object obj = AccessTools.Field(typeof(CharacterData), "view")?.GetValue(player.data); if (obj == null) { return player; } PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), "IsMine"); if (propertyInfo == null) { return player; } if ((bool)propertyInfo.GetValue(obj, null)) { return player; } } } return null; } } internal static class InputCompat { internal const int KeyEscape = 27; private static Type _keyCodeType; private static MethodInfo _getKeyDown; private static PropertyInfo _mousePosition; private static bool _resolved; private static bool _available; internal static Vector3 MousePosition { get { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0024: Unknown result type (might be due to invalid IL or missing references) Resolve(); if (!_available) { return Vector3.zero; } try { return (Vector3)_mousePosition.GetValue(null, null); } catch (Exception ex) { KLog.Warn("InputCompat.MousePosition failed: " + ex.Message); return Vector3.zero; } } } internal static bool GetKeyDown(int keyCode) { Resolve(); if (!_available) { return false; } try { object obj = Enum.ToObject(_keyCodeType, keyCode); return (bool)_getKeyDown.Invoke(null, new object[1] { obj }); } catch (Exception ex) { KLog.Warn("InputCompat.GetKeyDown failed: " + ex.Message); return false; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { _keyCodeType = Type.GetType("UnityEngine.KeyCode, UnityEngine.CoreModule") ?? Type.GetType("UnityEngine.KeyCode, UnityEngine"); Type type = Type.GetType("UnityEngine.Input, UnityEngine.CoreModule") ?? Type.GetType("UnityEngine.Input, UnityEngine"); if (_keyCodeType == null || type == null) { KLog.Warn("InputCompat: UnityEngine.Input/KeyCode not found in CoreModule."); return; } _getKeyDown = type.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { _keyCodeType }, null); _mousePosition = type.GetProperty("mousePosition", BindingFlags.Static | BindingFlags.Public); _available = _getKeyDown != null && _mousePosition != null; if (_available) { KLog.Line("InputCompat resolved against UnityEngine.CoreModule."); } else { KLog.Warn("InputCompat: GetKeyDown or mousePosition not found."); } } catch (Exception ex) { KLog.Warn("InputCompat resolve failed: " + ex.Message); } } } internal sealed class KeyboundBinding { public int PlayerID; public string CardName; public CardInfo Card; public int Key; public KeyboundEffectDef Def; public float ReadyAt; public float LockoutDuration; public bool IsReady() { return Time.time >= ReadyAt; } public float CooldownFill() { if (IsReady()) { return 0f; } float num = ReadyAt - Time.time; if (LockoutDuration <= 0f) { return 1f; } return Mathf.Clamp01(num / LockoutDuration); } public void ArmInitialDelay() { LockoutDuration = Def.InitialDelay; ReadyAt = Time.time + Def.InitialDelay; } public void ArmCooldown() { LockoutDuration = Def.Cooldown; ReadyAt = Time.time + Def.Cooldown; } } internal static class KeyboundCardRegistry { private static readonly Dictionary<string, KeyboundEffectDef> Effects = new Dictionary<string, KeyboundEffectDef>(); internal static void Register(KeyboundEffectDef def) { Effects[def.CardName] = def; KLog.Line($"Registered keybound effect '{def.CardName}' (delay={def.InitialDelay}s, cd={def.Cooldown}s)."); } internal static bool IsKeybound(string cardName) { if (!string.IsNullOrEmpty(cardName)) { return Effects.ContainsKey(cardName); } return false; } internal static bool TryGet(string cardName, out KeyboundEffectDef def) { return Effects.TryGetValue(cardName, out def); } internal static void RegisterBuiltInEffects() { Register(TeleportEffect.Def); } } internal sealed class KeyboundEffectDef { public string CardName; public float InitialDelay; public float Cooldown; public Func<Player, bool> Activate; } internal static class PickPhaseHelper { private static readonly FieldInfo s_isPlayingField = AccessTools.Field(typeof(CardChoice), "isPlaying"); private static readonly FieldInfo s_picksField = AccessTools.Field(typeof(CardChoice), "picks"); private static readonly FieldInfo s_spawnedCardsField = AccessTools.Field(typeof(CardChoice), "spawnedCards"); private static readonly MethodInfo s_rpca_donePicking = AccessTools.Method(typeof(CardChoice), "RPCA_DonePicking", (Type[])null, (Type[])null); internal static void EndPickPhase() { KLog.Section("EndPickPhase"); CardChoice instance = CardChoice.instance; if ((Object)(object)instance == (Object)null) { KLog.Error("CardChoice.instance is null."); return; } ((MonoBehaviour)instance).StopAllCoroutines(); CleanupSpawnedDraftCards(instance); if (s_isPlayingField != null) { s_isPlayingField.SetValue(instance, false); } if (s_picksField != null) { s_picksField.SetValue(instance, 0); } if (s_rpca_donePicking == null) { instance.IsPicking = false; } else { try { s_rpca_donePicking.Invoke(instance, null); } catch (Exception ex) { KLog.Error("RPCA_DonePicking failed: " + ex.Message); instance.IsPicking = false; } } KLog.Line($"Pick ended. IsPicking={instance.IsPicking}"); } internal static void RestorePickState(int pickerID, CardInfo card) { CardChoice instance = CardChoice.instance; if (!((Object)(object)instance == (Object)null)) { ((MonoBehaviour)instance).StopAllCoroutines(); instance.pickrID = pickerID; if (s_isPlayingField != null) { s_isPlayingField.SetValue(instance, false); } instance.IsPicking = true; if ((Object)(object)card != (Object)null) { ApplyCardStats componentInChildren = ((Component)card).GetComponentInChildren<ApplyCardStats>(); AccessTools.Field(typeof(ApplyCardStats), "done")?.SetValue(componentInChildren, false); } ResetSpawnedDoneFlags(instance); KLog.Line($"Restored pick state for picker {pickerID}."); } } private static void ResetSpawnedDoneFlags(CardChoice cc) { if (!(s_spawnedCardsField?.GetValue(cc) is IList list)) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ApplyCardStats), "done"); foreach (object item in list) { GameObject val = (GameObject)((item is GameObject) ? item : null); if (val != null) { ApplyCardStats componentInChildren = val.GetComponentInChildren<ApplyCardStats>(); if ((Object)(object)componentInChildren != (Object)null) { fieldInfo?.SetValue(componentInChildren, false); } } } } private static void CleanupSpawnedDraftCards(CardChoice cc) { if (!(s_spawnedCardsField?.GetValue(cc) is IList list)) { return; } for (int num = list.Count - 1; num >= 0; num--) { object? obj = list[num]; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null && (Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } list.Clear(); } } } namespace Keybound.Compat { internal static class DeckBuilderBridge { private static Type _deckManagerType; private static MethodInfo _consumeCard; private static MethodInfo _getRemaining; private static Type _networkSyncType; private static MethodInfo _broadcastRemaining; private static bool _resolved; internal static bool IsAvailable { get { Resolve(); return _consumeCard != null; } } internal static void ConsumeCard(int playerID, CardInfo card) { Resolve(); if (_consumeCard == null || (Object)(object)card == (Object)null) { return; } try { _consumeCard.Invoke(null, new object[2] { playerID, card }); KLog.Line($"Consumed '{card.cardName}' from runtime deck (player {playerID})."); BroadcastRemaining(playerID); } catch (Exception ex) { KLog.Warn("DeckBuilder ConsumeCard failed: " + ex.Message); } } private static void BroadcastRemaining(int playerID) { if (_broadcastRemaining == null || _getRemaining == null) { return; } try { int num = (int)_getRemaining.Invoke(null, new object[1] { playerID }); if (num >= 0) { _broadcastRemaining.Invoke(null, new object[2] { playerID, num }); } } catch (Exception ex) { KLog.Warn("DeckBuilder broadcast failed: " + ex.Message); } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "DeckBuilder"); if (assembly == null) { KLog.Line("DeckBuilder not installed — runtime deck consumption skipped."); return; } _deckManagerType = assembly.GetType("DeckBuilder.Data.DeckManager"); if (!(_deckManagerType == null)) { _consumeCard = _deckManagerType.GetMethod("ConsumeCard", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(int), typeof(CardInfo) }, null); _getRemaining = _deckManagerType.GetMethod("GetRemainingCount", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); _networkSyncType = assembly.GetType("DeckBuilder.Networking.DeckNetworkSync"); _broadcastRemaining = _networkSyncType?.GetMethod("BroadcastRemainingCount", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(int), typeof(int) }, null); } } catch (Exception ex) { KLog.Warn("DeckBuilder bridge resolve failed: " + ex.Message); } } } } namespace Keybound.Cards { internal static class CardArtLoader { private static readonly Dictionary<string, GameObject> Cache = new Dictionary<string, GameObject>(); private static string AssetsDirectory => Path.Combine(Plugin.PluginDirectory, "assets"); internal static GameObject Load(string fileName) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00ce: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(fileName)) { return null; } if (Cache.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null) { KLog.Line("CardArtLoader: Returning cached art for '" + fileName + "'."); return value; } string text = Path.Combine(AssetsDirectory, fileName); KLog.Line("CardArtLoader: Loading '" + fileName + "' from " + text); if (!File.Exists(text)) { KLog.Warn("CardArtLoader: Card art not found: " + text); return null; } byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { KLog.Warn("CardArtLoader: Failed to decode card art: " + text); Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); GameObject val2 = new GameObject("KeyboundCardArt_" + fileName); Object.DontDestroyOnLoad((Object)(object)val2); RectTransform obj = val2.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; ((Transform)obj).localPosition = Vector3.up * 10000f; Image obj2 = val2.AddComponent<Image>(); obj2.sprite = sprite; obj2.preserveAspect = true; ((Graphic)obj2).raycastTarget = false; Cache[fileName] = val2; KLog.Line($"CardArtLoader: Loaded {((Texture)val).width}x{((Texture)val).height} from {text}"); return val2; } } internal static class KeyboundCardRegistrar { internal static void RegisterAll() { KLog.Section("KeyboundCardRegistrar — RegisterAll"); KeyboundCardRegistry.RegisterBuiltInEffects(); CustomCard.BuildCard<TeleportCard>((Action<CardInfo>)delegate(CardInfo ci) { KLog.Line("Registered keybound card: " + ci.cardName); }); } } public class TeleportCard : CustomCard { public const string CardDisplayName = "Teleport"; protected override string GetTitle() { return "Teleport"; } protected override string GetDescription() { return "[Keybound] Press your bound key to teleport to your cursor.\nBecomes available 10s after the round starts. Cooldown: 15s."; } protected override CardInfoStat[] GetStats() { return Array.Empty<CardInfoStat>(); } protected override Rarity GetRarity() { return (Rarity)2; } protected override GameObject GetCardArt() { return CardArtLoader.Load("Teleport.png"); } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)2; } public override string GetModName() { return "Keybound"; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } } }
ShieldsMod.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using InfoOverhaul.Delta; using Microsoft.CodeAnalysis; using Photon.Pun; using RarityLib.Utils; using ShieldsMod.Cards; using ShieldsMod.Lifesteal; using ShieldsMod.Networking; using ShieldsMod.Poison; using ShieldsMod.Resistance; using ShieldsMod.Shield; using ShieldsMod.Stun; using UnboundLib; using UnboundLib.Cards; using UnboundLib.GameModes; using UnboundLib.Networking; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyCompany("ShieldsMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+146ac727a7fc6b83f382d57f53cce40478349c58")] [assembly: AssemblyProduct("Shields Mod for ROUNDS")] [assembly: AssemblyTitle("ShieldsMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ShieldsMod { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("ShieldsMod", "Shields Mod for ROUNDS", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static string PluginDirectory { get; private set; } private void Awake() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? ""; SLog.Section("Plugin Awake"); SLog.Line("PluginDirectory = " + PluginDirectory); new Harmony("ShieldsMod").PatchAll(); ((Component)this).gameObject.AddComponent<ShieldManager>(); ((Component)this).gameObject.AddComponent<PoisonResistanceManager>(); ((Component)this).gameObject.AddComponent<StunResistanceManager>(); ((Component)this).gameObject.AddComponent<LifestealResistanceManager>(); SLog.Line("Plugin ShieldsMod loaded."); } private void Start() { ShieldCardRegistrar.RegisterAll(); PoisonCardRegistrar.RegisterAll(); StunCardRegistrar.RegisterAll(); LifestealCardRegistrar.RegisterAll(); } } internal static class SLog { private const string Sep = "====================="; public static void Section(string title) { Plugin.Logger.LogInfo((object)"====================="); Plugin.Logger.LogInfo((object)("[ShieldsMod] " + title)); Plugin.Logger.LogInfo((object)"====================="); } public static void Line(string message) { Plugin.Logger.LogInfo((object)("[ShieldsMod] " + message)); } public static void Warn(string message) { Plugin.Logger.LogWarning((object)("[ShieldsMod] " + message)); } public static void Error(string message) { Plugin.Logger.LogError((object)("[ShieldsMod] " + message)); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ShieldsMod"; public const string PLUGIN_NAME = "Shields Mod for ROUNDS"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace ShieldsMod.Stun { internal static class StunHandRebuild { private static Dictionary<string, int> _levelByCardName; internal static void RegisterTier(string cardName, int level) { if (!string.IsNullOrEmpty(cardName) && level >= 1 && level <= 3) { if (_levelByCardName == null) { _levelByCardName = new Dictionary<string, int>(StringComparer.Ordinal); } _levelByCardName[cardName] = level; } } internal static float ComputeReductionFromHand(IEnumerable<CardInfo> cards, CardInfo exclude = null) { return ResistanceTierLogic.ComputeFromHand(cards, _levelByCardName, exclude); } internal static void RebuildForPlayer(int playerID) { StunResistanceManager.instance?.RebuildForPlayer(playerID); } } public class StunResistanceManager : MonoBehaviour { [CompilerGenerated] private sealed class <OnBattleStart>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnBattleStart>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; if ((Object)(object)PlayerManager.instance == (Object)null) { return false; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player != (Object)null) { instance?.RebuildForPlayer(player.playerID); } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static StunResistanceManager instance; private readonly Dictionary<int, float> _reductionByPlayer = new Dictionary<int, float>(); private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); GameModeManager.AddHook("BattleStart", (Func<IGameModeHandler, IEnumerator>)OnBattleStart); SLog.Section("StunResistanceManager — Awake"); } [IteratorStateMachine(typeof(<OnBattleStart>d__3))] private static IEnumerator OnBattleStart(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnBattleStart>d__3(0); } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } public float GetReduction(int playerID) { if (!_reductionByPlayer.TryGetValue(playerID, out var value)) { return 0f; } return value; } public float GetReductionPercent(int playerID) { return GetReduction(playerID) * 100f; } public void RebuildForPlayer(int playerID) { if (!((Object)(object)PlayerManager.instance == (Object)null)) { Player val = PlayerManager.instance.players.Find((Player p) => p.playerID == playerID); if (val?.data?.currentCards != null) { float num = StunHandRebuild.ComputeReductionFromHand(val.data.currentCards); _reductionByPlayer[playerID] = num; SLog.Line($"StunResistance rebuild player={playerID} reduction={num * 100f:F0}%"); } } } public float ApplyResistance(int playerID, float rawDuration, out float resistedAmount) { float reduction = GetReduction(playerID); resistedAmount = rawDuration * reduction; return rawDuration - resistedAmount; } } } namespace ShieldsMod.Shield { internal static class ShieldHandRebuild { private readonly struct ShieldTier { public readonly float FirstShieldMax; public readonly float StackMultiplier; public ShieldTier(float firstShieldMax, float stackMultiplier) { FirstShieldMax = firstShieldMax; StackMultiplier = stackMultiplier; } } private static Dictionary<string, ShieldTier> _tierByCardName; internal static void RegisterTier(CardInfo card, float firstShieldMax, float stackMultiplier) { if (!((Object)(object)card == (Object)null) && !string.IsNullOrEmpty(card.cardName)) { if (_tierByCardName == null) { _tierByCardName = new Dictionary<string, ShieldTier>(StringComparer.Ordinal); } _tierByCardName[card.cardName] = new ShieldTier(firstShieldMax, stackMultiplier); } } internal static float ComputeMaxFromHandExcluding(IEnumerable<CardInfo> cards, CardInfo exclude) { return ComputeMaxFromCards(cards, exclude); } internal static void RebuildForPlayer(int playerID) { if ((Object)(object)ShieldManager.instance == (Object)null || (Object)(object)PlayerManager.instance == (Object)null) { return; } Player val = PlayerManager.instance.players.Find((Player p) => p.playerID == playerID); if (val?.data?.currentCards != null) { ShieldState orCreateShield = ShieldManager.instance.GetOrCreateShield(playerID); float max = orCreateShield.Max; float num = ComputeMaxFromCards(val.data.currentCards); if (num <= 0f) { orCreateShield.Max = 0f; orCreateShield.Current = 0f; } else { orCreateShield.Max = num; orCreateShield.Current = Mathf.Min(orCreateShield.Current, orCreateShield.Max); } ShieldManager.instance.RefreshVisual(playerID); SLog.Line($"ShieldHandRebuild player={playerID} max {max:F0} -> {orCreateShield.Max:F0} current={orCreateShield.Current:F0}"); } } private static float ComputeMaxFromCards(IEnumerable<CardInfo> cards, CardInfo exclude = null) { if (_tierByCardName == null || cards == null) { return 0f; } float num = 0f; bool flag = false; foreach (CardInfo card in cards) { if ((Object)(object)card == (Object)null || ((Object)(object)exclude != (Object)null && ((Object)card).name == ((Object)exclude).name)) { continue; } string cardName = card.cardName; if (string.IsNullOrEmpty(cardName) && (Object)(object)card.sourceCard != (Object)null) { cardName = card.sourceCard.cardName; } if (!string.IsNullOrEmpty(cardName) && _tierByCardName.TryGetValue(cardName, out var value)) { if (!flag) { num = value.FirstShieldMax; flag = true; } else { num *= value.StackMultiplier; } } } if (!flag) { return 0f; } return num; } } public class ShieldManager : MonoBehaviour { [CompilerGenerated] private sealed class <OnBattleStart>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnBattleStart>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; instance?.ResetAllForBattle(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnGameStart>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnGameStart>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; instance?.CleanupOrphanedAttachments(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnPointEnd>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnPointEnd>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; instance?.CleanupOrphanedAttachments(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static ShieldManager instance; private readonly Dictionary<int, ShieldState> _shields = new Dictionary<int, ShieldState>(); private readonly Dictionary<int, ShieldVisual> _visuals = new Dictionary<int, ShieldVisual>(); private readonly Dictionary<int, ShieldParryTrigger> _parryTriggers = new Dictionary<int, ShieldParryTrigger>(); private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); SLog.Section("ShieldManager — Awake"); GameModeManager.AddHook("BattleStart", (Func<IGameModeHandler, IEnumerator>)OnBattleStart); GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)OnPointEnd); GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart); } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } [IteratorStateMachine(typeof(<OnBattleStart>d__6))] private static IEnumerator OnBattleStart(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnBattleStart>d__6(0); } [IteratorStateMachine(typeof(<OnPointEnd>d__7))] private static IEnumerator OnPointEnd(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnPointEnd>d__7(0); } [IteratorStateMachine(typeof(<OnGameStart>d__8))] private static IEnumerator OnGameStart(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnGameStart>d__8(0); } public void ResetAllForBattle() { SLog.Section("ShieldManager — ResetAllForBattle"); if ((Object)(object)PlayerManager.instance == (Object)null) { SLog.Warn("PlayerManager.instance is null."); return; } foreach (Player player in PlayerManager.instance.players) { if (!((Object)(object)player == (Object)null)) { ShieldHandRebuild.RebuildForPlayer(player.playerID); ShieldState orCreateShield = GetOrCreateShield(player.playerID); if (orCreateShield.HasShield) { orCreateShield.ResetToFull(); } else { orCreateShield.Current = 0f; } EnsureAttachments(player, orCreateShield); RefreshVisual(player.playerID); SLog.Line($"player={player.playerID} shield={orCreateShield.Current}/{orCreateShield.Max}"); } } } public ShieldState GetOrCreateShield(int playerID) { if (!_shields.TryGetValue(playerID, out var value)) { value = new ShieldState(); _shields[playerID] = value; } return value; } public ShieldState GetShield(int playerID) { return GetOrCreateShield(playerID); } public bool TryAbsorbFull(int playerID, float damageAmount, out bool depleted) { depleted = false; ShieldState orCreateShield = GetOrCreateShield(playerID); if (!orCreateShield.IsActive || damageAmount <= 0f) { return false; } if (damageAmount >= orCreateShield.Current) { orCreateShield.Current = 0f; depleted = true; } else { orCreateShield.Current -= damageAmount; } RefreshVisual(playerID); return true; } public void RefreshVisual(int playerID) { if (_visuals.TryGetValue(playerID, out var value) && (Object)(object)value != (Object)null) { value.Refresh(); } if (_parryTriggers.TryGetValue(playerID, out var value2) && (Object)(object)value2 != (Object)null) { value2.UpdateEnabled(); } } private void EnsureAttachments(Player player, ShieldState state) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) int playerID = player.playerID; if (!_visuals.TryGetValue(playerID, out var value) || (Object)(object)value == (Object)null) { GameObject val = new GameObject($"ShieldVisual_P{playerID}"); val.transform.SetParent(((Component)player).transform, false); value = val.AddComponent<ShieldVisual>(); value.Init(player, state); _visuals[playerID] = value; } else { value.SetState(state); value.Refresh(); } if (!_parryTriggers.TryGetValue(playerID, out var value2) || (Object)(object)value2 == (Object)null) { GameObject val2 = new GameObject($"ShieldParry_P{playerID}"); val2.transform.SetParent(((Component)player).transform, false); value2 = val2.AddComponent<ShieldParryTrigger>(); float radius = ShieldVisual.GetBodyRadius(player) * 1.44f; value2.Init(player, state, radius); _parryTriggers[playerID] = value2; } else { value2.SetState(state); value2.UpdateEnabled(); } } private void CleanupOrphanedAttachments() { List<int> list = new List<int>(); foreach (KeyValuePair<int, ShieldVisual> visual in _visuals) { if ((Object)(object)visual.Value == (Object)null) { list.Add(visual.Key); } } foreach (int item in list) { _visuals.Remove(item); } List<int> list2 = new List<int>(); foreach (KeyValuePair<int, ShieldParryTrigger> parryTrigger in _parryTriggers) { if ((Object)(object)parryTrigger.Value == (Object)null) { list2.Add(parryTrigger.Key); } } foreach (int item2 in list2) { _parryTriggers.Remove(item2); } } } public class ShieldParryTrigger : MonoBehaviour { private Player _owner; private Block _block; private CircleCollider2D _trigger; private ShieldState _state; private readonly HashSet<int> _recentlyDeflected = new HashSet<int>(); public void Init(Player owner, ShieldState state, float radius) { _owner = owner; _state = state; _block = ((Component)owner).GetComponent<Block>(); _trigger = ((Component)this).gameObject.AddComponent<CircleCollider2D>(); ((Collider2D)_trigger).isTrigger = true; _trigger.radius = radius; Rigidbody2D obj = ((Component)this).gameObject.AddComponent<Rigidbody2D>(); obj.bodyType = (RigidbodyType2D)1; obj.simulated = true; UpdateEnabled(); } public void SetState(ShieldState state) { _state = state; } public void SetRadius(float worldRadius) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_owner == (Object)null) && !((Object)(object)_trigger == (Object)null)) { float num = Mathf.Max(((Component)_owner).transform.localScale.x, 0.01f); _trigger.radius = worldRadius / num; } } public void UpdateEnabled() { if ((Object)(object)_trigger != (Object)null) { ((Behaviour)_trigger).enabled = _state != null && _state.IsActive; } } private void LateUpdate() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_owner == (Object)null)) { ((Component)this).transform.position = ((Component)_owner).transform.position; float bodyRadius = ShieldVisual.GetBodyRadius(_owner); SetRadius(bodyRadius * 1.44f); UpdateEnabled(); } } private void OnTriggerEnter2D(Collider2D other) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner == (Object)null || (Object)(object)_block == (Object)null || _state == null || !_state.IsActive || !_block.IsBlocking()) { return; } ProjectileHit val = ((Component)other).GetComponent<ProjectileHit>() ?? ((Component)other).GetComponentInParent<ProjectileHit>(); if ((Object)(object)val == (Object)null) { return; } PhotonView component = ((Component)val).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || !component.IsMine) { return; } int instanceID = ((Object)((Component)val).gameObject).GetInstanceID(); if (!_recentlyDeflected.Contains(instanceID) && IsEnemyProjectile(val)) { Vector3 position = ((Component)val).transform.position; Vector3 val2 = ((Component)val).transform.forward; if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { Vector3 val3 = position - ((Component)_owner).transform.position; val2 = ((Vector3)(ref val3)).normalized; } _recentlyDeflected.Add(instanceID); _block.DoBlock(((Component)val).gameObject, val2, position); SLog.Line($"Outer parry player={_owner.playerID} projectile={((Object)((Component)val).gameObject).name}"); } } private bool IsEnemyProjectile(ProjectileHit projHit) { Player val = projHit.ownPlayer; if ((Object)(object)val == (Object)null) { SpawnedAttack component = ((Component)projHit).GetComponent<SpawnedAttack>(); if ((Object)(object)component != (Object)null) { val = component.spawner; } } if ((Object)(object)val == (Object)null) { return true; } if (val.playerID != _owner.playerID) { return (Object)(object)((Component)val).transform.root != (Object)(object)((Component)_owner).transform.root; } return false; } private void OnTriggerExit2D(Collider2D other) { ProjectileHit val = ((Component)other).GetComponent<ProjectileHit>() ?? ((Component)other).GetComponentInParent<ProjectileHit>(); if ((Object)(object)val != (Object)null) { _recentlyDeflected.Remove(((Object)((Component)val).gameObject).GetInstanceID()); } } } public class ShieldState { public const float DefaultMax = 100f; public float Max; public float Current; public const float BubbleAlpha = 0.05f; public bool HasShield => Max > 0f; public float Percent { get { if (!(Max > 0f)) { return 0f; } return Current / Max; } } public bool IsActive => Current > 0f; public void ResetToFull() { Current = Max; } public Color GetBubbleColor(float alpha = 0.05f) { //IL_005d: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) float percent = Percent; Color val = default(Color); if (percent > 0.65f) { ((Color)(ref val))..ctor(0.2f, 0.9f, 0.25f); } else if (percent > 0.35f) { ((Color)(ref val))..ctor(0.95f, 0.85f, 0.15f); } else { ((Color)(ref val))..ctor(0.95f, 0.2f, 0.15f); } return new Color(val.r, val.g, val.b, alpha); } } public class ShieldVisual : MonoBehaviour { public const float SizeMultiplier = 1.44f; private const int CircleTexSize = 128; private Player _player; private SpriteRenderer _sprite; private ShieldState _state; public static Sprite SharedCircleSprite { get; private set; } public void Init(Player player, ShieldState state) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown _player = player; _state = state; if ((Object)(object)SharedCircleSprite == (Object)null) { SharedCircleSprite = CreateCircleSprite(128); } GameObject val = new GameObject("ShieldBubbleSprite"); val.transform.SetParent(((Component)this).transform, false); _sprite = val.AddComponent<SpriteRenderer>(); _sprite.sprite = SharedCircleSprite; ((Renderer)_sprite).sortingOrder = -1; int num = SortingLayer.NameToID("Player" + (player.playerID + 1)); if (num != 0) { ((Renderer)_sprite).sortingLayerID = num; } player.data.SetWobbleObjectChild(((Component)this).transform); Refresh(); } public void SetState(ShieldState state) { _state = state; } public void Refresh() { //IL_005c: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sprite == (Object)null || (Object)(object)_player == (Object)null || _state == null) { return; } if (!_state.IsActive) { ((Renderer)_sprite).enabled = false; return; } ((Renderer)_sprite).enabled = true; _sprite.color = _state.GetBubbleColor(); float num = GetBodyRadius(_player) * 2f * 1.44f; Bounds bounds = _sprite.sprite.bounds; float x = ((Bounds)(ref bounds)).size.x; if (x > 0.0001f) { ((Component)_sprite).transform.localScale = Vector3.one * (num / x); } } public static float GetBodyRadius(Player player) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0.5f; } CircleCollider2D val = ((Component)player).GetComponent<CircleCollider2D>(); if ((Object)(object)val == (Object)null) { val = ((Component)player).GetComponentInChildren<CircleCollider2D>(); } return (((Object)(object)val != (Object)null) ? val.radius : 0.5f) * ((Component)player).transform.localScale.x; } private void LateUpdate() { if (_state != null && _state.IsActive) { Refresh(); } } private static Sprite CreateCircleSprite(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; float num = (float)(size - 1) * 0.5f; float num2 = num - 1f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num3 = (float)j - num; float num4 = (float)i - num; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); float num6 = ((num5 <= num2) ? 1f : Mathf.Clamp01(1f - (num5 - num2))); val.SetPixel(j, i, new Color(1f, 1f, 1f, num6)); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), (float)size); } } } namespace ShieldsMod.Resistance { internal static class ResistanceTierLogic { public const float StackBonus = 0.05f; public const float Lv2UpgradeThreshold = 0.5f; public const float Lv3UpgradeThreshold = 0.75f; private static readonly float[] FirstReductionByLevel = new float[4] { 0f, 0.25f, 0.5f, 0.75f }; internal static float GetFirstReduction(int level) { if (level < 1 || level > 3) { return 0f; } return FirstReductionByLevel[level]; } internal static float ComputeFromHand(IEnumerable<CardInfo> cards, IReadOnlyDictionary<string, int> tierByCardName, CardInfo exclude = null) { if (tierByCardName == null || cards == null) { return 0f; } float num = 0f; bool flag = false; foreach (CardInfo card in cards) { if (!((Object)(object)card == (Object)null) && (!((Object)(object)exclude != (Object)null) || !(((Object)card).name == ((Object)exclude).name)) && TryGetLevel(card, tierByCardName, out var level)) { if (!flag) { num = GetFirstReduction(level); flag = true; } else { num = ApplyStacking(num, level, out var _); } } } if (!flag) { return 0f; } return ClampReduction(num); } internal static float ApplyCard(float currentReduction, int level, out float? healthMultiplier) { healthMultiplier = null; if (!(currentReduction > 0.0001f)) { return ClampReduction(GetFirstReduction(level)); } return ClampReduction(ApplyStacking(currentReduction, level, out healthMultiplier)); } internal static void ApplyHealthBonus(CharacterData data, float multiplier) { if (!((Object)(object)data == (Object)null) && !(multiplier <= 1.0001f)) { float num = ((data.maxHealth > 0f) ? (data.health / data.maxHealth) : 1f); data.maxHealth *= multiplier; data.health = Mathf.Clamp(data.maxHealth * num, 1f, data.maxHealth); } } private static float ApplyStacking(float current, int level, out float? healthMultiplier) { healthMultiplier = null; switch (level) { case 1: return current + 0.05f; case 2: if (current < 0.5f) { return 0.5f; } healthMultiplier = 1.1f; return current + 0.05f; case 3: if (current < 0.75f) { return 0.75f; } healthMultiplier = 1.25f; return current + 0.05f; default: return current; } } private static bool TryGetLevel(CardInfo card, IReadOnlyDictionary<string, int> tierByCardName, out int level) { level = 0; if ((Object)(object)card == (Object)null) { return false; } string cardName = card.cardName; if (string.IsNullOrEmpty(cardName) && (Object)(object)card.sourceCard != (Object)null) { cardName = card.sourceCard.cardName; } if (!string.IsNullOrEmpty(cardName)) { return tierByCardName.TryGetValue(cardName, out level); } return false; } private static float ClampReduction(float value) { return Mathf.Clamp01(value); } } } namespace ShieldsMod.Poison { internal static class PoisonDamageDetector { public static bool IsPoisonDamage(Color blinkColor, GameObject damagingWeapon) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)damagingWeapon != (Object)null) { if ((Object)(object)damagingWeapon.GetComponentInChildren<RayHitPoison>() != (Object)null) { return true; } Transform root = damagingWeapon.transform.root; if ((Object)(object)root != (Object)null && (Object)(object)((Component)root).GetComponentInChildren<RayHitPoison>() != (Object)null) { return true; } } if (blinkColor.g > 0.35f && blinkColor.g >= blinkColor.r) { return blinkColor.g >= blinkColor.b; } return false; } } internal static class PoisonHandRebuild { private static Dictionary<string, int> _levelByCardName; internal static void RegisterTier(string cardName, int level) { if (!string.IsNullOrEmpty(cardName) && level >= 1 && level <= 3) { if (_levelByCardName == null) { _levelByCardName = new Dictionary<string, int>(StringComparer.Ordinal); } _levelByCardName[cardName] = level; } } internal static float ComputeReductionFromHand(IEnumerable<CardInfo> cards, CardInfo exclude = null) { return ResistanceTierLogic.ComputeFromHand(cards, _levelByCardName, exclude); } internal static void RebuildForPlayer(int playerID) { PoisonResistanceManager.instance?.RebuildForPlayer(playerID); } } public class PoisonResistanceManager : MonoBehaviour { [CompilerGenerated] private sealed class <OnBattleStart>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnBattleStart>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; if ((Object)(object)PlayerManager.instance == (Object)null) { return false; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player != (Object)null) { instance?.RebuildForPlayer(player.playerID); } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static PoisonResistanceManager instance; private readonly Dictionary<int, float> _reductionByPlayer = new Dictionary<int, float>(); private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); GameModeManager.AddHook("BattleStart", (Func<IGameModeHandler, IEnumerator>)OnBattleStart); SLog.Section("PoisonResistanceManager — Awake"); } [IteratorStateMachine(typeof(<OnBattleStart>d__3))] private static IEnumerator OnBattleStart(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnBattleStart>d__3(0); } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } public float GetReduction(int playerID) { if (!_reductionByPlayer.TryGetValue(playerID, out var value)) { return 0f; } return value; } public float GetReductionPercent(int playerID) { return GetReduction(playerID) * 100f; } public void RebuildForPlayer(int playerID) { if (!((Object)(object)PlayerManager.instance == (Object)null)) { Player val = PlayerManager.instance.players.Find((Player p) => p.playerID == playerID); if (val?.data?.currentCards != null) { float num = PoisonHandRebuild.ComputeReductionFromHand(val.data.currentCards); _reductionByPlayer[playerID] = num; SLog.Line($"PoisonResistance rebuild player={playerID} reduction={num * 100f:F0}%"); } } } public float ApplyResistance(int playerID, float rawDamage, out float resistedAmount) { float reduction = GetReduction(playerID); resistedAmount = rawDamage * reduction; return rawDamage - resistedAmount; } } } namespace ShieldsMod.Patches { [HarmonyPatch] internal static class CardDeleteRebuildPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("DeckBuilder.CardDelete.CardDeleteManager"); if (!(type == null)) { return AccessTools.Method(type, "URPC_SyncDelete", (Type[])null, (Type[])null); } return null; } private static bool Prepare() { bool num = TargetMethod() != null; if (!num) { SLog.Line("CardDeleteRebuildPatch — CardDeleteManager not found; delete hook skipped."); } return num; } private static void Postfix(int playerID) { ShieldHandRebuild.RebuildForPlayer(playerID); PoisonHandRebuild.RebuildForPlayer(playerID); StunHandRebuild.RebuildForPlayer(playerID); LifestealHandRebuild.RebuildForPlayer(playerID); } } [HarmonyPatch(typeof(CharacterStatModifiers), "DealtDamage")] internal static class CharacterStatModifiersDealtDamagePatch { [HarmonyPostfix] private static void Postfix(CharacterStatModifiers __instance, Vector2 damage, bool selfDamage, Player damagedPlayer) { if (selfDamage || (Object)(object)damagedPlayer == (Object)null || __instance.lifeSteal == 0f || (Object)(object)LifestealResistanceManager.instance == (Object)null || LifestealResistanceManager.instance.GetReduction(damagedPlayer.playerID) <= 0f) { return; } float num = ((Vector2)(ref damage)).magnitude * __instance.lifeSteal; float resistedAmount; float num2 = LifestealResistanceManager.instance.ApplyResistance(damagedPlayer.playerID, num, out resistedAmount); if (!(resistedAmount <= 0f)) { Player component = ((Component)__instance).GetComponent<Player>(); if (!((Object)(object)component?.data == (Object)null)) { CharacterData data = component.data; data.health -= resistedAmount; component.data.health = Mathf.Clamp(component.data.health, 1f, component.data.maxHealth); SLog.Section("Lifesteal resistance"); SLog.Line($"Player {component?.playerID ?? (-1)} would've healed {num:F1} from life steal but healed {num2:F1} instead (victim {damagedPlayer.playerID} resisted {resistedAmount:F1})."); } } } } [HarmonyPatch(typeof(HealthHandler), "DoDamage")] internal static class HealthHandlerDoDamagePatch { [HarmonyPrefix] private static bool Prefix(HealthHandler __instance, ref Vector2 damage, Vector2 position, Color blinkColor, GameObject damagingWeapon, Player damagingPlayer, bool healthRemoval, bool lethal, bool ignoreBlock) { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_010e: Unknown result type (might be due to invalid IL or missing references) if (damage == Vector2.zero) { return true; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null) { return true; } float magnitude = ((Vector2)(ref damage)).magnitude; float num = magnitude; bool flag = PoisonDamageDetector.IsPoisonDamage(blinkColor, damagingWeapon); if (flag && (Object)(object)PoisonResistanceManager.instance != (Object)null && PoisonResistanceManager.instance.GetReduction(component.playerID) > 0f) { num = PoisonResistanceManager.instance.ApplyResistance(component.playerID, magnitude, out var _); if (num > 0f) { damage = ((Vector2)(ref damage)).normalized * num; } else { damage = Vector2.zero; } } if (num <= 0f) { return false; } if ((Object)(object)ShieldManager.instance == (Object)null) { if (flag && magnitude > num) { LogPoisonPlayerDamage(component.playerID, magnitude, num); } return true; } if (!ShieldManager.instance.TryAbsorbFull(component.playerID, num, out var depleted)) { if (flag && magnitude > num) { LogPoisonPlayerDamage(component.playerID, magnitude, num); } return true; } if (flag && magnitude > num) { LogPoisonShieldDamage(component.playerID, magnitude, num, depleted); } damage = Vector2.zero; if ((Object)(object)component.data?.view != (Object)null && component.data.view.IsMine) { ShieldNetworkSync.BroadcastShieldHealth(component.playerID, ShieldManager.instance.GetShield(component.playerID).Current); } return false; } private static void LogPoisonPlayerDamage(int playerID, float rawAmount, float actualAmount) { SLog.Section("Poison resistance — player"); SLog.Line($"Player {playerID} would've taken {rawAmount:F1} poison damage but took {actualAmount:F1} instead."); } private static void LogPoisonShieldDamage(int playerID, float rawAmount, float actualAmount, bool depleted) { SLog.Section("Poison resistance — shield"); SLog.Line($"Player {playerID}'s shield would've taken {rawAmount:F1} poison damage but took {actualAmount:F1} instead (depleted={depleted})."); } } [HarmonyPatch(typeof(StunHandler), "AddStun")] internal static class StunHandlerAddStunPatch { [HarmonyPrefix] private static bool Prefix(StunHandler __instance, ref float f) { if (f <= 0f || (Object)(object)StunResistanceManager.instance == (Object)null) { return true; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null) { return true; } if (StunResistanceManager.instance.GetReduction(component.playerID) <= 0f) { return true; } float num = f; f = StunResistanceManager.instance.ApplyResistance(component.playerID, num, out var _); if (num > f) { SLog.Section("Stun resistance"); SLog.Line($"Player {component.playerID} would've been stunned for {num:F2}s but duration was reduced to {f:F2}s."); } if (f <= 0f) { return false; } return true; } } } namespace ShieldsMod.Networking { public static class ShieldNetworkSync { public static void BroadcastShieldHealth(int playerID, float current) { SLog.Line($"BroadcastShieldHealth player={playerID} current={current:F1}"); NetworkingManager.RPC(typeof(ShieldNetworkSync), "URPC_SetShieldHealth", new object[2] { playerID, current }); } [UnboundRPC] public static void URPC_SetShieldHealth(int playerID, float current) { if (!((Object)(object)ShieldManager.instance == (Object)null)) { ShieldState orCreateShield = ShieldManager.instance.GetOrCreateShield(playerID); orCreateShield.Current = Mathf.Clamp(current, 0f, orCreateShield.Max); ShieldManager.instance.RefreshVisual(playerID); SLog.Line($"URPC_SetShieldHealth player={playerID} current={orCreateShield.Current:F1}"); } } } } namespace ShieldsMod.Lifesteal { internal static class LifestealHandRebuild { private static Dictionary<string, int> _levelByCardName; internal static void RegisterTier(string cardName, int level) { if (!string.IsNullOrEmpty(cardName) && level >= 1 && level <= 3) { if (_levelByCardName == null) { _levelByCardName = new Dictionary<string, int>(StringComparer.Ordinal); } _levelByCardName[cardName] = level; } } internal static float ComputeReductionFromHand(IEnumerable<CardInfo> cards, CardInfo exclude = null) { return ResistanceTierLogic.ComputeFromHand(cards, _levelByCardName, exclude); } internal static void RebuildForPlayer(int playerID) { LifestealResistanceManager.instance?.RebuildForPlayer(playerID); } } public class LifestealResistanceManager : MonoBehaviour { [CompilerGenerated] private sealed class <OnBattleStart>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnBattleStart>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; if ((Object)(object)PlayerManager.instance == (Object)null) { return false; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player != (Object)null) { instance?.RebuildForPlayer(player.playerID); } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static LifestealResistanceManager instance; private readonly Dictionary<int, float> _reductionByPlayer = new Dictionary<int, float>(); private void Awake() { instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); GameModeManager.AddHook("BattleStart", (Func<IGameModeHandler, IEnumerator>)OnBattleStart); SLog.Section("LifestealResistanceManager — Awake"); } [IteratorStateMachine(typeof(<OnBattleStart>d__3))] private static IEnumerator OnBattleStart(IGameModeHandler gm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnBattleStart>d__3(0); } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } public float GetReduction(int playerID) { if (!_reductionByPlayer.TryGetValue(playerID, out var value)) { return 0f; } return value; } public float GetReductionPercent(int playerID) { return GetReduction(playerID) * 100f; } public void RebuildForPlayer(int playerID) { if (!((Object)(object)PlayerManager.instance == (Object)null)) { Player val = PlayerManager.instance.players.Find((Player p) => p.playerID == playerID); if (val?.data?.currentCards != null) { float num = LifestealHandRebuild.ComputeReductionFromHand(val.data.currentCards); _reductionByPlayer[playerID] = num; SLog.Line($"LifestealResistance rebuild player={playerID} reduction={num * 100f:F0}%"); } } } public float ApplyResistance(int playerID, float rawHeal, out float resistedAmount) { float reduction = GetReduction(playerID); resistedAmount = rawHeal * reduction; return rawHeal - resistedAmount; } } } namespace ShieldsMod.Cards { public static class CardArtLoader { private static readonly Dictionary<string, GameObject> Cache = new Dictionary<string, GameObject>(); public static string AssetsDirectory => Path.Combine(Plugin.PluginDirectory, "assets"); public static GameObject Load(string fileName) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) SLog.Section("CardArtLoader.Load — '" + fileName + "'"); SLog.Line("AssetsDirectory = " + AssetsDirectory); if (string.IsNullOrEmpty(fileName)) { SLog.Warn("Load called with empty fileName — returning null."); return null; } if (Cache.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null) { SLog.Line("Returning cached art object."); return value; } string text = Path.Combine(AssetsDirectory, fileName); SLog.Line("Full path = " + text); SLog.Line($"File.Exists = {File.Exists(text)}"); if (!File.Exists(text)) { SLog.Warn("Card art not found at: " + text); return null; } byte[] array = File.ReadAllBytes(text); SLog.Line($"Read {array.Length} bytes."); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); bool flag = ImageConversion.LoadImage(val, array); SLog.Line($"Texture.LoadImage = {flag}, size = {((Texture)val).width}x{((Texture)val).height}"); if (!flag) { SLog.Warn("Failed to decode card art: " + text); Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); GameObject val2 = new GameObject("ShieldsCardArt_" + fileName); Object.DontDestroyOnLoad((Object)(object)val2); RectTransform obj = val2.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; ((Transform)obj).localPosition = Vector3.up * 10000f; Image obj2 = val2.AddComponent<Image>(); obj2.sprite = sprite; obj2.preserveAspect = true; ((Graphic)obj2).raycastTarget = false; Cache[fileName] = val2; SLog.Line("Loaded card art '" + fileName + "' from " + text); return val2; } } internal static class LifestealCardDeltaRegistrar { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<int, float> <>9__1_2; public static Func<int, float> <>9__1_3; public static Func<IEnumerable<CardInfo>, float> <>9__1_4; public static SimpleDeltaProvider <>9__1_1; internal float <RegisterTier>b__1_2(int id) { return LifestealResistanceManager.instance.GetReductionPercent(id); } internal IReadOnlyList<(string label, string before, string after)> <RegisterTier>b__1_1(Player player, CardInfo cardInfo) { return ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Lifesteal Resistance", (int id) => LifestealResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => LifestealHandRebuild.ComputeReductionFromHand(cards)); } internal float <RegisterTier>b__1_3(int id) { return LifestealResistanceManager.instance.GetReductionPercent(id); } internal float <RegisterTier>b__1_4(IEnumerable<CardInfo> cards) { return LifestealHandRebuild.ComputeReductionFromHand(cards); } } internal static void RegisterAll() { SLog.Section("LifestealCardDeltaRegistrar — RegisterAll"); RegisterTier(LifestealCardRegistry.Lv1, 1); RegisterTier(LifestealCardRegistry.Lv2, 2); RegisterTier(LifestealCardRegistry.Lv3, 3); } private static void RegisterTier(CardInfo card, int level) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if ((Object)(object)card == (Object)null) { return; } LifestealHandRebuild.RegisterTier(card.cardName, level); CardDeltaRegistry.RegisterSimple(card.cardName, (SimpleDeltaProvider)((Player player, CardInfo _) => ResistanceDeltaHelper.ComputeAddDelta(player, level, "Lifesteal Resistance", (int id) => LifestealResistanceManager.instance.GetReductionPercent(id)))); string cardName = card.cardName; object obj = <>c.<>9__1_1; if (obj == null) { SimpleDeltaProvider val = (Player player, CardInfo cardInfo) => ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Lifesteal Resistance", (int id) => LifestealResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => LifestealHandRebuild.ComputeReductionFromHand(cards)); <>c.<>9__1_1 = val; obj = (object)val; } CardDeltaRegistry.RegisterRemovalSimple(cardName, (SimpleDeltaProvider)obj); SLog.Line($"Registered lifesteal delta preview for '{card.cardName}' (LV{level})."); } } internal static class LifestealCardRegistrar { internal static void RegisterAll() { SLog.Section("LifestealCardRegistrar — RegisterAll"); CustomCard.BuildCard<LifestealResistanceLv3>((Action<CardInfo>)delegate(CardInfo ci) { LifestealCardRegistry.Lv3 = ci; }); CustomCard.BuildCard<LifestealResistanceLv2>((Action<CardInfo>)delegate(CardInfo ci) { LifestealCardRegistry.Lv2 = ci; }); CustomCard.BuildCard<LifestealResistanceLv1>((Action<CardInfo>)OnLv1Built); } private static void OnLv1Built(CardInfo ci) { LifestealCardRegistry.Lv1 = ci; SLog.Line("Registered Lifesteal Resistance LV1: " + ci.cardName); LifestealCardDeltaRegistrar.RegisterAll(); } } internal static class LifestealCardRegistry { internal static CardInfo Lv1; internal static CardInfo Lv2; internal static CardInfo Lv3; } public abstract class LifestealResistanceBase : CustomCard { protected abstract int Level { get; } protected abstract string ArtFileName { get; } protected abstract Rarity CardRarity { get; } protected override string GetTitle() { return "Lifesteal Resistance " + Roman(Level); } protected override string GetDescription() { return ResistanceCardText.Description(Level, "lifesteal"); } protected override CardInfoStat[] GetStats() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[1] { new CardInfoStat { positive = true, amount = ResistanceCardText.StatAmount(Level), stat = "Life Steal Resist", simepleAmount = (SimpleAmount)0 } }; } protected override Rarity GetRarity() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CardRarity; } protected override GameObject GetCardArt() { return CardArtLoader.Load(ArtFileName); } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)4; } public override string GetModName() { return "ShieldsMod"; } public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if (!((Object)(object)player == (Object)null)) { string cardName = (((Object)(object)base.cardInfo != (Object)null) ? base.cardInfo.cardName : null); ResistanceCardOnAdd.Apply(player, data, Level, cardName, (IEnumerable<CardInfo> cards) => LifestealHandRebuild.ComputeReductionFromHand(cards), delegate(int id) { LifestealResistanceManager.instance?.RebuildForPlayer(id); }); SLog.Section($"LifestealResistance LV{Level} — OnAddCard"); SLog.Line($"player={player.playerID} reduction={LifestealResistanceManager.instance?.GetReductionPercent(player.playerID):F0}%"); } } private static string Roman(int level) { return level switch { 1 => "I", 2 => "II", 3 => "III", _ => level.ToString(), }; } } public class LifestealResistanceLv1 : LifestealResistanceBase { protected override int Level => 1; protected override string ArtFileName => "lifesteal_resistance_lv1.png"; protected override Rarity CardRarity => (Rarity)1; } public class LifestealResistanceLv2 : LifestealResistanceBase { protected override int Level => 2; protected override string ArtFileName => "lifesteal_resistance_lv2.png"; protected override Rarity CardRarity => (Rarity)2; } public class LifestealResistanceLv3 : LifestealResistanceBase { protected override int Level => 3; protected override string ArtFileName => "lifesteal_resistance_lv3.png"; protected override Rarity CardRarity => RarityHelper.Epic; } internal static class PoisonCardDeltaRegistrar { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<int, float> <>9__1_2; public static Func<int, float> <>9__1_3; public static Func<IEnumerable<CardInfo>, float> <>9__1_4; public static SimpleDeltaProvider <>9__1_1; internal float <RegisterTier>b__1_2(int id) { return PoisonResistanceManager.instance.GetReductionPercent(id); } internal IReadOnlyList<(string label, string before, string after)> <RegisterTier>b__1_1(Player player, CardInfo cardInfo) { return ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Poison Resistance", (int id) => PoisonResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => PoisonHandRebuild.ComputeReductionFromHand(cards)); } internal float <RegisterTier>b__1_3(int id) { return PoisonResistanceManager.instance.GetReductionPercent(id); } internal float <RegisterTier>b__1_4(IEnumerable<CardInfo> cards) { return PoisonHandRebuild.ComputeReductionFromHand(cards); } } internal static void RegisterAll() { SLog.Section("PoisonCardDeltaRegistrar — RegisterAll"); RegisterTier(PoisonCardRegistry.Lv1, 1); RegisterTier(PoisonCardRegistry.Lv2, 2); RegisterTier(PoisonCardRegistry.Lv3, 3); } private static void RegisterTier(CardInfo card, int level) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if ((Object)(object)card == (Object)null) { return; } PoisonHandRebuild.RegisterTier(card.cardName, level); CardDeltaRegistry.RegisterSimple(card.cardName, (SimpleDeltaProvider)((Player player, CardInfo _) => ResistanceDeltaHelper.ComputeAddDelta(player, level, "Poison Resistance", (int id) => PoisonResistanceManager.instance.GetReductionPercent(id)))); string cardName = card.cardName; object obj = <>c.<>9__1_1; if (obj == null) { SimpleDeltaProvider val = (Player player, CardInfo cardInfo) => ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Poison Resistance", (int id) => PoisonResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => PoisonHandRebuild.ComputeReductionFromHand(cards)); <>c.<>9__1_1 = val; obj = (object)val; } CardDeltaRegistry.RegisterRemovalSimple(cardName, (SimpleDeltaProvider)obj); SLog.Line($"Registered poison delta preview for '{card.cardName}' (LV{level})."); } } internal static class PoisonCardRegistrar { internal static void RegisterAll() { SLog.Section("PoisonCardRegistrar — RegisterAll"); CustomCard.BuildCard<PoisonResistanceLv3>((Action<CardInfo>)delegate(CardInfo ci) { PoisonCardRegistry.Lv3 = ci; }); CustomCard.BuildCard<PoisonResistanceLv2>((Action<CardInfo>)delegate(CardInfo ci) { PoisonCardRegistry.Lv2 = ci; }); CustomCard.BuildCard<PoisonResistanceLv1>((Action<CardInfo>)OnLv1Built); } private static void OnLv1Built(CardInfo ci) { PoisonCardRegistry.Lv1 = ci; SLog.Line("Registered Poison Resistance LV1: " + ci.cardName); PoisonCardDeltaRegistrar.RegisterAll(); } } internal static class PoisonCardRegistry { internal static CardInfo Lv1; internal static CardInfo Lv2; internal static CardInfo Lv3; } public abstract class PoisonResistanceBase : CustomCard { protected abstract int Level { get; } protected abstract string ArtFileName { get; } protected abstract Rarity CardRarity { get; } protected override string GetTitle() { return "Poison Resistance " + Roman(Level); } protected override string GetDescription() { return ResistanceCardText.Description(Level, "poison"); } protected override CardInfoStat[] GetStats() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[1] { new CardInfoStat { positive = true, amount = ResistanceCardText.StatAmount(Level), stat = "Poison Resist", simepleAmount = (SimpleAmount)0 } }; } protected override Rarity GetRarity() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CardRarity; } protected override GameObject GetCardArt() { return CardArtLoader.Load(ArtFileName); } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)5; } public override string GetModName() { return "ShieldsMod"; } public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if (!((Object)(object)player == (Object)null)) { string cardName = (((Object)(object)base.cardInfo != (Object)null) ? base.cardInfo.cardName : null); ResistanceCardOnAdd.Apply(player, data, Level, cardName, (IEnumerable<CardInfo> cards) => PoisonHandRebuild.ComputeReductionFromHand(cards), delegate(int id) { PoisonResistanceManager.instance?.RebuildForPlayer(id); }); SLog.Section($"PoisonResistance LV{Level} — OnAddCard"); SLog.Line($"player={player.playerID} reduction={PoisonResistanceManager.instance?.GetReductionPercent(player.playerID):F0}%"); } } private static string Roman(int level) { return level switch { 1 => "I", 2 => "II", 3 => "III", _ => level.ToString(), }; } } public class PoisonResistanceLv1 : PoisonResistanceBase { protected override int Level => 1; protected override string ArtFileName => "poison_resistance_lv1.png"; protected override Rarity CardRarity => (Rarity)1; } public class PoisonResistanceLv2 : PoisonResistanceBase { protected override int Level => 2; protected override string ArtFileName => "poison_resistance_lv2.png"; protected override Rarity CardRarity => (Rarity)2; } public class PoisonResistanceLv3 : PoisonResistanceBase { protected override int Level => 3; protected override string ArtFileName => "poison_resistance_lv3.png"; protected override Rarity CardRarity => RarityHelper.Epic; } internal static class RarityHelper { public static Rarity Scarce => RarityUtils.GetRarity("Scarce"); public static Rarity Epic => RarityUtils.GetRarity("Epic"); public static Rarity Legendary => RarityUtils.GetRarity("Legendary"); } internal static class ResistanceCardOnAdd { internal static void Apply(Player player, CharacterData data, int level, string cardName, Func<IEnumerable<CardInfo>, float> computeFromHand, Action<int> rebuild) { if (!((Object)(object)player == (Object)null) && computeFromHand != null) { IEnumerable<CardInfo> arg = player.data?.currentCards?.Where((CardInfo c) => (Object)(object)c != (Object)null && c.cardName != cardName) ?? Enumerable.Empty<CardInfo>(); ResistanceTierLogic.ApplyCard(computeFromHand(arg), level, out var healthMultiplier); if (healthMultiplier.HasValue) { ResistanceTierLogic.ApplyHealthBonus(data, healthMultiplier.Value); } rebuild?.Invoke(player.playerID); } } } internal static class ResistanceCardText { internal static string Description(int level, string effectLabel) { return level switch { 1 => "Sets " + effectLabel + " resistance to 25%, or +5% if you already have resistance.", 2 => "Sets " + effectLabel + " resistance to 50% if below 50%; otherwise +5% resistance and +10% max HP.", 3 => "Sets " + effectLabel + " resistance to 75% if below 75%; otherwise +5% resistance and +25% max HP.", _ => "Improves " + effectLabel + " resistance.", }; } internal static string StatAmount(int level) { return level switch { 1 => "25% / +5%", 2 => "50% / +5%", 3 => "75% / +5%", _ => "—", }; } } internal static class ResistanceDeltaHelper { internal static IReadOnlyList<(string label, string before, string after)> ComputeAddDelta(Player player, int level, string statLabel, Func<int, float> getReductionPercent) { if ((Object)(object)player == (Object)null || getReductionPercent == null) { return Array.Empty<(string, string, string)>(); } float num = getReductionPercent(player.playerID); float? healthMultiplier; float num2 = ResistanceTierLogic.ApplyCard(num / 100f, level, out healthMultiplier) * 100f; List<(string, string, string)> list = new List<(string, string, string)> { (statLabel, $"{num:F0}%", $"{num2:F0}%") }; if (healthMultiplier.HasValue && (Object)(object)player.data != (Object)null) { float maxHealth = player.data.maxHealth; float num3 = maxHealth * healthMultiplier.Value; list.Add(("HP", $"{maxHealth:F0}", $"{num3:F0}")); } return list; } internal static IReadOnlyList<(string label, string before, string after)> ComputeRemovalDelta(Player player, CardInfo cardToRemove, string statLabel, Func<int, float> getReductionPercent, Func<IEnumerable<CardInfo>, float> computeFromHand) { if ((Object)(object)player == (Object)null || (Object)(object)cardToRemove == (Object)null || getReductionPercent == null || computeFromHand == null) { return Array.Empty<(string, string, string)>(); } float num = getReductionPercent(player.playerID); IEnumerable<CardInfo> arg = player.data?.currentCards?.Where((CardInfo c) => (Object)(object)c != (Object)null && ((Object)c).name != ((Object)cardToRemove).name) ?? Enumerable.Empty<CardInfo>(); float num2 = computeFromHand(arg) * 100f; if (Mathf.Approximately(num, num2)) { return Array.Empty<(string, string, string)>(); } return new(string, string, string)[1] { (statLabel, $"{num:F0}%", $"{num2:F0}%") }; } } internal static class RtgPrerequisiteBridge { private static MethodInfo _registerMethod; private static bool _resolved; public static bool IsAvailable { get { Resolve(); return _registerMethod != null; } } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "DeckBuilder"); if (assembly == null) { SLog.Warn("DeckBuilder assembly not found — shield unlock chain will not be registered."); return; } Type type = assembly.GetType("DeckBuilder.CardPrerequisiteRegistry"); if (type == null) { SLog.Warn("DeckBuilder CardPrerequisiteRegistry type not found."); return; } _registerMethod = type.GetMethod("RegisterPrerequisite", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(string), typeof(string) }, null); if (_registerMethod == null) { SLog.Warn("RegisterPrerequisite(string, string) not found on CardPrerequisiteRegistry."); } } catch (Exception ex) { SLog.Error("Failed to resolve DeckBuilder registry: " + ex.Message); } } internal static bool Register(string cardName, string requiredCardName) { Resolve(); if (_registerMethod == null) { return false; } try { _registerMethod.Invoke(null, new object[2] { cardName, requiredCardName }); return true; } catch (Exception ex) { SLog.Error("RegisterPrerequisite invoke failed: " + ex.Message); return false; } } } internal static class ShieldCardDeltaRegistrar { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static SimpleDeltaProvider <>9__1_1; internal IReadOnlyList<(string label, string before, string after)> <RegisterTier>b__1_1(Player player, CardInfo cardInfo) { return ComputeShieldRemoval(player, cardInfo); } } internal static void RegisterAll() { SLog.Section("ShieldCardDeltaRegistrar — RegisterAll"); RegisterTier(ShieldCardRegistry.Lv1, 100f, 1.2f); RegisterTier(ShieldCardRegistry.Lv2, 150f, 1.5f); RegisterTier(ShieldCardRegistry.Lv3, 250f, 2f); RegisterTier(ShieldCardRegistry.Lv4, 500f, 3f); RegisterTier(ShieldCardRegistry.Lv5, 1000f, 3.5f); } private static void RegisterTier(CardInfo card, float firstShieldMax, float stackMultiplier) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if ((Object)(object)card == (Object)null) { SLog.Warn("ShieldCardDeltaRegistrar — skipped null card reference."); return; } ShieldHandRebuild.RegisterTier(card, firstShieldMax, stackMultiplier); CardDeltaRegistry.RegisterSimple(card.cardName, (SimpleDeltaProvider)((Player player, CardInfo _) => ComputeShieldDelta(player, firstShieldMax, stackMultiplier))); string cardName = card.cardName; object obj = <>c.<>9__1_1; if (obj == null) { SimpleDeltaProvider val = (Player player, CardInfo cardInfo) => ComputeShieldRemoval(player, cardInfo); <>c.<>9__1_1 = val; obj = (object)val; } CardDeltaRegistry.RegisterRemovalSimple(cardName, (SimpleDeltaProvider)obj); SLog.Line($"Registered stat-delta preview for '{card.cardName}' (first={firstShieldMax:F0}, x{stackMultiplier:F2})."); } private static IReadOnlyList<(string label, string before, string after)> ComputeShieldDelta(Player player, float firstShieldMax, float stackMultiplier) { if ((Object)(object)player == (Object)null || (Object)(object)ShieldManager.instance == (Object)null) { return Array.Empty<(string, string, string)>(); } ShieldState shield = ShieldManager.instance.GetShield(player.playerID); float max = shield.Max; float num = (shield.HasShield ? (max * stackMultiplier) : firstShieldMax); return new(string, string, string)[1] { ("Shield Max", $"{max:F0}", $"{num:F0}") }; } private static IReadOnlyList<(string label, string before, string after)> ComputeShieldRemoval(Player player, CardInfo cardToRemove) { if ((Object)(object)player == (Object)null || (Object)(object)ShieldManager.instance == (Object)null || (Object)(object)cardToRemove == (Object)null) { return Array.Empty<(string, string, string)>(); } float max = ShieldManager.instance.GetShield(player.playerID).Max; float num = ShieldHandRebuild.ComputeMaxFromHandExcluding(player.data?.currentCards, cardToRemove); if (Mathf.Approximately(max, num)) { return Array.Empty<(string, string, string)>(); } string item = ((num > 0f) ? $"{num:F0}" : "None"); return new(string, string, string)[1] { ("Shield Health", $"{max:F0}", item) }; } } internal static class ShieldCardRegistrar { internal static void RegisterAll() { SLog.Section("ShieldCardRegistrar — RegisterAll"); CustomCard.BuildCard<UpgradeShieldLv5>((Action<CardInfo>)delegate(CardInfo ci) { ShieldCardRegistry.Lv5 = ci; }); CustomCard.BuildCard<UpgradeShieldLv4>((Action<CardInfo>)delegate(CardInfo ci) { ShieldCardRegistry.Lv4 = ci; }); CustomCard.BuildCard<UpgradeShieldLv3>((Action<CardInfo>)delegate(CardInfo ci) { ShieldCardRegistry.Lv3 = ci; }); CustomCard.BuildCard<UpgradeShieldLv2>((Action<CardInfo>)delegate(CardInfo ci) { ShieldCardRegistry.Lv2 = ci; }); CustomCard.BuildCard<UpgradeShieldLv1>((Action<CardInfo>)OnLv1Built); } private static void OnLv1Built(CardInfo ci) { ShieldCardRegistry.Lv1 = ci; SLog.Line("Registered LV1: " + ci.cardName); ShieldCardDeltaRegistrar.RegisterAll(); } } internal static class ShieldCardRegistry { internal static CardInfo Lv1; internal static CardInfo Lv2; internal static CardInfo Lv3; internal static CardInfo Lv4; internal static CardInfo Lv5; } internal static class StunCardDeltaRegistrar { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<int, float> <>9__1_2; public static Func<int, float> <>9__1_3; public static Func<IEnumerable<CardInfo>, float> <>9__1_4; public static SimpleDeltaProvider <>9__1_1; internal float <RegisterTier>b__1_2(int id) { return StunResistanceManager.instance.GetReductionPercent(id); } internal IReadOnlyList<(string label, string before, string after)> <RegisterTier>b__1_1(Player player, CardInfo cardInfo) { return ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Stun Resistance", (int id) => StunResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => StunHandRebuild.ComputeReductionFromHand(cards)); } internal float <RegisterTier>b__1_3(int id) { return StunResistanceManager.instance.GetReductionPercent(id); } internal float <RegisterTier>b__1_4(IEnumerable<CardInfo> cards) { return StunHandRebuild.ComputeReductionFromHand(cards); } } internal static void RegisterAll() { SLog.Section("StunCardDeltaRegistrar — RegisterAll"); RegisterTier(StunCardRegistry.Lv1, 1); RegisterTier(StunCardRegistry.Lv2, 2); RegisterTier(StunCardRegistry.Lv3, 3); } private static void RegisterTier(CardInfo card, int level) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if ((Object)(object)card == (Object)null) { return; } StunHandRebuild.RegisterTier(card.cardName, level); CardDeltaRegistry.RegisterSimple(card.cardName, (SimpleDeltaProvider)((Player player, CardInfo _) => ResistanceDeltaHelper.ComputeAddDelta(player, level, "Stun Resistance", (int id) => StunResistanceManager.instance.GetReductionPercent(id)))); string cardName = card.cardName; object obj = <>c.<>9__1_1; if (obj == null) { SimpleDeltaProvider val = (Player player, CardInfo cardInfo) => ResistanceDeltaHelper.ComputeRemovalDelta(player, cardInfo, "Stun Resistance", (int id) => StunResistanceManager.instance.GetReductionPercent(id), (IEnumerable<CardInfo> cards) => StunHandRebuild.ComputeReductionFromHand(cards)); <>c.<>9__1_1 = val; obj = (object)val; } CardDeltaRegistry.RegisterRemovalSimple(cardName, (SimpleDeltaProvider)obj); SLog.Line($"Registered stun delta preview for '{card.cardName}' (LV{level})."); } } internal static class StunCardRegistrar { internal static void RegisterAll() { SLog.Section("StunCardRegistrar — RegisterAll"); CustomCard.BuildCard<StunResistanceLv3>((Action<CardInfo>)delegate(CardInfo ci) { StunCardRegistry.Lv3 = ci; }); CustomCard.BuildCard<StunResistanceLv2>((Action<CardInfo>)delegate(CardInfo ci) { StunCardRegistry.Lv2 = ci; }); CustomCard.BuildCard<StunResistanceLv1>((Action<CardInfo>)OnLv1Built); } private static void OnLv1Built(CardInfo ci) { StunCardRegistry.Lv1 = ci; SLog.Line("Registered Stun Resistance LV1: " + ci.cardName); StunCardDeltaRegistrar.RegisterAll(); } } internal static class StunCardRegistry { internal static CardInfo Lv1; internal static CardInfo Lv2; internal static CardInfo Lv3; } public abstract class StunResistanceBase : CustomCard { protected abstract int Level { get; } protected abstract string ArtFileName { get; } protected abstract Rarity CardRarity { get; } protected override string GetTitle() { return "Stun Resistance " + Roman(Level); } protected override string GetDescription() { return ResistanceCardText.Description(Level, "stun"); } protected override CardInfoStat[] GetStats() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[1] { new CardInfoStat { positive = true, amount = ResistanceCardText.StatAmount(Level), stat = "Stun Resist", simepleAmount = (SimpleAmount)0 } }; } protected override Rarity GetRarity() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CardRarity; } protected override GameObject GetCardArt() { return CardArtLoader.Load(ArtFileName); } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)7; } public override string GetModName() { return "ShieldsMod"; } public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if (!((Object)(object)player == (Object)null)) { string cardName = (((Object)(object)base.cardInfo != (Object)null) ? base.cardInfo.cardName : null); ResistanceCardOnAdd.Apply(player, data, Level, cardName, (IEnumerable<CardInfo> cards) => StunHandRebuild.ComputeReductionFromHand(cards), delegate(int id) { StunResistanceManager.instance?.RebuildForPlayer(id); }); SLog.Section($"StunResistance LV{Level} — OnAddCard"); SLog.Line($"player={player.playerID} reduction={StunResistanceManager.instance?.GetReductionPercent(player.playerID):F0}%"); } } private static string Roman(int level) { return level switch { 1 => "I", 2 => "II", 3 => "III", _ => level.ToString(), }; } } public class StunResistanceLv1 : StunResistanceBase { protected override int Level => 1; protected override string ArtFileName => "stun_resistance_lv1.png"; protected override Rarity CardRarity => (Rarity)1; } public class StunResistanceLv2 : StunResistanceBase { protected override int Level => 2; protected override string ArtFileName => "stun_resistance_lv2.png"; protected override Rarity CardRarity => (Rarity)2; } public class StunResistanceLv3 : StunResistanceBase { protected override int Level => 3; protected override string ArtFileName => "stun_resistance_lv3.png"; protected override Rarity CardRarity => RarityHelper.Epic; } public abstract class UpgradeShieldHealthBase : CustomCard { protected abstract int Level { get; } protected abstract float FirstShieldMax { get; } protected abstract float Multiplier { get; } protected abstract string ArtFileName { get; } protected abstract Rarity CardRarity { get; } protected override string GetTitle() { return "Upgrade Shield Health " + Roman(Level); } protected override string GetDescription() { return "Grants or increases max shield health by " + PercentLabel(Multiplier) + ". First pickup sets a base shield if you have none."; } protected override CardInfoStat[] GetStats() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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: Expected O, but got Unknown return (CardInfoStat[])(object)new CardInfoStat[1] { new CardInfoStat { positive = true, amount = PercentLabel(Multiplier), stat = "Shield Max", simepleAmount = (SimpleAmount)0 } }; } protected override Rarity GetRarity() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CardRarity; } protected override GameObject GetCardArt() { return CardArtLoader.Load(ArtFileName); } protected override CardThemeColorType GetTheme() { return (CardThemeColorType)2; } public override string GetModName() { return "ShieldsMod"; } public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { if (!((Object)(object)player == (Object)null) && !((Object)(object)ShieldManager.instance == (Object)null)) { int playerID = player.playerID; ShieldState orCreateShield = ShieldManager.instance.GetOrCreateShield(playerID); float max = orCreateShield.Max; if (!orCreateShield.HasShield) { orCreateShield.Max = FirstShieldMax; orCreateShield.Current = orCreateShield.Max; } else { orCreateShield.Max *= Multiplier; orCreateShield.Current = Mathf.Min(orCreateShield.Current, orCreateShield.Max); } ShieldManager.instance.RefreshVisual(playerID); SLog.Section($"UpgradeShieldHealth LV{Level} — OnAddCard"); SLog.Line($"player={playerID} firstMax={FirstShieldMax:F0} multiplier={Multiplier:F2} max {max:F1} -> {orCreateShield.Max:F1}"); } } private static string PercentLabel(float multiplier) { return $"+{Mathf.RoundToInt((multiplier - 1f) * 100f)}%"; } private static string Roman(int level) { return level switch { 1 => "I", 2 => "II", 3 => "III", 4 => "IV", 5 => "V", _ => level.ToString(), }; } } public class UpgradeShieldLv1 : UpgradeShieldHealthBase { protected override int Level => 1; protected override float FirstShieldMax => 100f; protected override float Multiplier => 1.2f; protected override string ArtFileName => "lv1_artwork.png"; protected override Rarity CardRarity => (Rarity)0; } public class UpgradeShieldLv2 : UpgradeShieldHealthBase { protected override int Level => 2; protected override float FirstShieldMax => 150f; protected override float Multiplier => 1.5f; protected override string ArtFileName => "lv2_artwork.png"; protected override Rarity CardRarity => RarityHelper.Scarce; } public class UpgradeShieldLv3 : UpgradeShieldHealthBase { protected override int Level => 3; protected override float FirstShieldMax => 250f; protected override float Multiplier => 2f; protected override string ArtFileName => "lv3_artwork.png"; protected override Rarity CardRarity => (Rarity)1; } public class UpgradeShieldLv4 : UpgradeShieldHealthBase { protected override int Level => 4; protected override float FirstShieldMax => 500f; protected override float Multiplier => 3f; protected override string ArtFileName => "lv4_artwork.png"; protected override Rarity CardRarity => RarityHelper.Epic; } public class UpgradeShieldLv5 : UpgradeShieldHealthBase { protected override int Level => 5; protected override float FirstShieldMax => 1000f; protected override float Multiplier => 3.5f; protected override string ArtFileName => "lv5_artwork.png"; protected override Rarity CardRarity => RarityHelper.Legendary; } }