Decompiled source of MulliganMadness v0.4.9
MulliganMadness.dll
Decompiled a day 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.Globalization; 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.Configuration; using BepInEx.Logging; using CardChoiceSpawnUniqueCardPatch.CustomCategories; using HarmonyLib; using Microsoft.CodeAnalysis; using ModdingUtils.Extensions; using ModdingUtils.Utils; using MulliganMadness.Cards; using MulliganMadness.Curses; using MulliganMadness.Patches; using MulliganMadness.Stats; using MulliganMadness.UI; using MulliganMadness.Utils; using Photon.Pun; using Photon.Realtime; using TMPro; using UnboundLib; using UnboundLib.Cards; using UnboundLib.GameModes; using UnboundLib.Networking; using UnboundLib.Utils.UI; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using WillsWackyManagers.UnityTools; using WillsWackyManagers.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MulliganMadness")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.4.9+55a591fc121163598b5481c37f4191e629e67bfc")] [assembly: AssemblyProduct("MulliganMadness")] [assembly: AssemblyTitle("MulliganMadness")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MulliganMadness { [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.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.bukey.rounds.mulliganmadness", "Mulligan Madness", "0.4.9")] [BepInProcess("Rounds.exe")] public class Plugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__12_0; internal void <Start>b__12_0() { } } public const string ModId = "com.bukey.rounds.mulliganmadness"; public const string ModName = "Mulligan Madness"; public const string Version = "0.4.9"; public const string ModInitials = "MM"; public const string CurseInitials = "MMC"; public const string CardsMenuName = "MulliganMadness"; internal static Configs Configs; public static Plugin Instance { get; private set; } private void Awake() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown Instance = this; Configs = new Configs(((BaseUnityPlugin)this).Config); SessionSettings.InitializeFromConfig(); SessionSettingsSync.Register(); SessionRulesBanner.RegisterHooks(); RoundWinTracker.RegisterHooks(); try { Harmony val = new Harmony("com.bukey.rounds.mulliganmadness"); Type[] types; try { types = typeof(Plugin).Assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; ManualLogSource logger = ((BaseUnityPlugin)this).Logger; Exception?[] loaderExceptions = ex.LoaderExceptions; logger.LogWarning((object)$"Harmony GetTypes partial load: {((loaderExceptions != null) ? loaderExceptions.Length : 0)} loader error(s)"); } Type[] array = types; foreach (Type type in array) { if (!(type == null)) { try { val.CreateClassProcessor(type).Patch(); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Harmony skip " + type.FullName + ": " + ex2.GetType().Name + ": " + ex2.Message)); } } } } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Harmony patching failed: {arg}"); } } private void Start() { //IL_0032: 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_003d: Expected O, but got Unknown AutoPickCurse.RegisterAll(); CardRegistration.RegisterAll(); CardArtFactory.BindLoadedCardInfos(); NestEggManager.RegisterHooks(); MmStatus.Register(); object obj = <>c.<>9__12_0; if (obj == null) { UnityAction val = delegate { }; <>c.<>9__12_0 = val; obj = (object)val; } Unbound.RegisterMenu("Mulligan Madness", (UnityAction)obj, (Action<GameObject>)DrawSettingsMenu, (GameObject)null, true); Unbound.RegisterHandshake("com.bukey.rounds.mulliganmadness", (Action)OnHandshake); GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart); GameModeManager.AddHook("PlayerPickStart", (Func<IGameModeHandler, IEnumerator>)OnPlayerPickStart); GameModeManager.AddHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)OnPlayerPickEnd); GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)OnPickEnd); ExtensionMethods.GetOrAddComponent<TakeAllButton>(((Component)this).gameObject, false); ExtensionMethods.GetOrAddComponent<AutoPickController>(((Component)this).gameObject, false); ExtensionMethods.GetOrAddComponent<SessionVoteTicker>(((Component)this).gameObject, false); ExtensionMethods.GetOrAddComponent<FumbleController>(((Component)this).gameObject, false); ExtensionMethods.GetOrAddComponent<BlindDraftController>(((Component)this).gameObject, false); ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 0.5f, (Action)CardArtFactory.BindLoadedCardInfos); ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 2.5f, (Action)CardArtFactory.BindLoadedCardInfos); } private static void OnHandshake() { if (SessionSettings.IsHost && !PhotonNetwork.OfflineMode && PhotonNetwork.InRoom) { SessionSettingsSync.BroadcastToAllIfHost(); } } private static IEnumerator OnGameStart(IGameModeHandler gm) { TakeAllManager.ResetForNewGame(); NestEggManager.ResetForNewGame(); TakeAllVoteManager.ResetForNewGame(); MercyTakeAllManager.ResetForNewGame(); RoundWinTracker.Reset(); AutoPickController.ResetForNewGame(); KeysUnlockReset.Reapply(); ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 0.35f, (Action)KeysUnlockReset.Reapply); yield break; } private static IEnumerator OnPlayerPickStart(IGameModeHandler gm) { FumbleController.ResetForPick(); TakeAllManager.ClearAuthorization(); TakeAllManager.ClearPickTransientState(); TakeAllManager.ApplyDeferredKnowledge(); TakeAllButton.RefreshVisibility(); AutoPickController.NotifyPlayerPickStarted(); Player picker = TakeAllManager.GetCurrentPicker(); if ((Object)(object)picker != (Object)null) { ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 0.5f, (Action)delegate { MercyTakeAllManager.TryOfferMercy(picker); }); } yield break; } private static IEnumerator OnPlayerPickEnd(IGameModeHandler gm) { FumbleController.ResetForPick(); TakeAllVoteManager.CancelIfActive("Take All vote cancelled - pick ended."); TakeAllManager.ClearAuthorization(); TakeAllManager.ClearActingPicker(); TakeAllManager.ClearPickTransientState(); PickAnnounceUi.HidePanic(); TakeAllButton.RefreshVisibility(); yield break; } private static IEnumerator OnPickEnd(IGameModeHandler gm) { FumbleController.ResetForPick(); TakeAllVoteManager.CancelIfActive("Take All vote cancelled - pick ended."); TakeAllManager.ClearAuthorization(); TakeAllManager.ClearActingPicker(); TakeAllManager.ClearPickTransientState(); PickAnnounceUi.HidePanic(); TakeAllButton.Hide(); CardBarMiniIcons.RestampAll(); ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 0.25f, (Action)CardBarMiniIcons.RestampAll); ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)Instance, 1f, (Action)CardBarMiniIcons.RestampAll); yield break; } private static void DrawSettingsMenu(GameObject menu) { MenuBuilder.Build(menu); } internal void Log(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Mulligan Madness] " + message)); } internal void LogWarn(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[Mulligan Madness] " + message)); } } internal sealed class SessionVoteTicker : MonoBehaviour { private void Update() { TakeAllVoteManager.Tick(); } } } namespace MulliganMadness.Utils { public class AutoPickController : MonoBehaviour { private enum AutoPickMode { None, ForcedImmediate, PanicTimer, Leftmost } private static AutoPickController _instance; private Coroutine _running; private int _pickGeneration; private int _runningPlayerId = -1; private void Awake() { _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } public static void ResetForNewGame() { ResetForCurrentPick(); } public static void ResetForCurrentPick() { if (!((Object)(object)_instance == (Object)null)) { if (_instance._running != null) { ((MonoBehaviour)_instance).StopCoroutine(_instance._running); _instance._running = null; } _instance._runningPlayerId = -1; _instance._pickGeneration++; PickAnnounceUi.HidePanic(); } } public static void NotifyPlayerPickStarted() { if (!((Object)(object)_instance == (Object)null)) { _instance.BeginForCurrentPick(); } } private void BeginForCurrentPick() { Player currentPicker = TakeAllManager.GetCurrentPicker(); if ((Object)(object)currentPicker == (Object)null || currentPicker.data?.currentCards == null || !LocalPlayerUtil.IsLocallyControlled(currentPicker)) { return; } AutoPickMode autoPickMode = ResolveMode(currentPicker); if (autoPickMode != AutoPickMode.None && (_running == null || _runningPlayerId != currentPicker.playerID)) { if (_running != null) { ((MonoBehaviour)this).StopCoroutine(_running); _running = null; } _pickGeneration++; int pickGeneration = _pickGeneration; _runningPlayerId = currentPicker.playerID; _running = ((MonoBehaviour)this).StartCoroutine(RunAutoPick(currentPicker.playerID, autoPickMode, pickGeneration)); } } private static AutoPickMode ResolveMode(Player player) { if (HasCurse(player, ForcedChoice.Card)) { return AutoPickMode.ForcedImmediate; } if (HasCurse(player, LeftmostLuck.Card)) { return AutoPickMode.Leftmost; } if (HasCurse(player, PanicPick.Card)) { return AutoPickMode.PanicTimer; } return AutoPickMode.None; } private static bool HasCurse(Player player, CardInfo curse) { if (player?.data?.currentCards == null || (Object)(object)curse == (Object)null) { return false; } foreach (CardInfo currentCard in player.data.currentCards) { if (!((Object)(object)currentCard == (Object)null)) { if ((Object)(object)currentCard == (Object)(object)curse) { return true; } if (!string.IsNullOrEmpty(curse.cardName) && string.Equals(currentCard.cardName, curse.cardName, StringComparison.OrdinalIgnoreCase)) { return true; } } } return false; } private IEnumerator RunAutoPick(int playerID, AutoPickMode mode, int generation) { try { int safety = 12; while (safety-- > 0 && generation == _pickGeneration && WaitForOwnPick(playerID)) { float timeout = 10f; while (timeout > 0f && generation == _pickGeneration) { if (TakeAllManager.IsBusy || !WaitForOwnPick(playerID)) { yield break; } if (TakeAllManager.IsOfferedHandReady() && HandIsSelectable()) { break; } timeout -= Time.unscaledDeltaTime; yield return null; } if (generation != _pickGeneration || !WaitForOwnPick(playerID)) { break; } yield return WaitForFumbleIfNeeded(playerID, generation); if (generation != _pickGeneration || !WaitForOwnPick(playerID)) { break; } if (mode == AutoPickMode.PanicTimer) { float wait = Mathf.Max(0.1f, SessionSettings.Current.PanicTimerSeconds); PickAnnounceUi.BroadcastPanic(playerID, wait); float elapsed = 0f; while (elapsed < wait && generation == _pickGeneration && WaitForOwnPick(playerID)) { if (TakeAllManager.IsBusy) { PickAnnounceUi.HidePanic(broadcast: true); yield break; } List<GameObject> spawnedCards = TakeAllManager.GetSpawnedCards(); if (spawnedCards == null || spawnedCards.Count == 0) { PickAnnounceUi.HidePanic(broadcast: true); yield break; } elapsed += Time.unscaledDeltaTime; yield return null; } PickAnnounceUi.HidePanic(broadcast: true); if (generation != _pickGeneration || !WaitForOwnPick(playerID)) { break; } } List<GameObject> readySpawnedCards = TakeAllManager.GetReadySpawnedCards(); if (readySpawnedCards == null || readySpawnedCards.Count == 0) { break; } GameObject val = SelectCard(readySpawnedCards, mode); if ((Object)(object)val == (Object)null || !readySpawnedCards.Contains(val)) { yield return (object)new WaitForSecondsRealtime(0.1f); continue; } Plugin.Instance.Log($"Auto-pick ({mode}) for player {playerID}."); TryPick(val); GameObject picked = val; float settle = 2.5f; while (settle > 0f && generation == _pickGeneration) { yield return null; settle -= Time.unscaledDeltaTime; if (!WaitForOwnPick(playerID)) { yield break; } List<GameObject> spawnedCards2 = TakeAllManager.GetSpawnedCards(); if (spawnedCards2 == null || spawnedCards2.Count == 0 || !spawnedCards2.Contains(picked)) { break; } } yield return (object)new WaitForSecondsRealtime(0.2f); if (WaitForOwnPick(playerID)) { continue; } break; } } finally { AutoPickController autoPickController = this; if (generation == autoPickController._pickGeneration) { autoPickController._running = null; autoPickController._runningPlayerId = -1; } } } private static bool WaitForOwnPick(int playerID) { if ((Object)(object)CardChoice.instance == (Object)null || !CardChoice.instance.IsPicking) { return false; } Player currentPicker = TakeAllManager.GetCurrentPicker(); if ((Object)(object)currentPicker != (Object)null) { return currentPicker.playerID == playerID; } return false; } private IEnumerator WaitForFumbleIfNeeded(int playerID, int generation) { Player val = TakeAllManager.FindPlayer(playerID) ?? TakeAllManager.GetCurrentPicker(); if ((Object)(object)val == (Object)null || !CurseOwnership.Has(val, Fumble.Card)) { yield break; } List<GameObject> spawnedCards = TakeAllManager.GetSpawnedCards(); if (spawnedCards != null && spawnedCards.Count > 1) { float timeout = 1.25f; while (timeout > 0f && generation == _pickGeneration && WaitForOwnPick(playerID) && !FumbleController.HasRoll(playerID)) { timeout -= Time.unscaledDeltaTime; yield return null; } } } private static GameObject SelectCard(List<GameObject> spawned, AutoPickMode mode) { if (spawned == null || spawned.Count == 0) { return null; } List<GameObject> list = spawned.FindAll((GameObject go) => (Object)(object)go != (Object)null); if (list.Count == 0) { return null; } switch (mode) { case AutoPickMode.Leftmost: return SelectLeftmost(list); case AutoPickMode.ForcedImmediate: case AutoPickMode.PanicTimer: return list[Random.Range(0, list.Count)]; default: return null; } } private static GameObject SelectLeftmost(List<GameObject> spawned) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; float num = float.MaxValue; foreach (GameObject item in spawned) { if (!((Object)(object)item == (Object)null)) { float x = item.transform.position.x; if (!(x >= num)) { num = x; val = item; } } } return val ?? spawned[0]; } private static bool HandIsSelectable() { List<GameObject> readySpawnedCards = TakeAllManager.GetReadySpawnedCards(); List<GameObject> spawnedCards = TakeAllManager.GetSpawnedCards(); if (readySpawnedCards == null || spawnedCards == null || readySpawnedCards.Count == 0) { return false; } return readySpawnedCards.Count >= spawnedCards.Count; } private static void TryPick(GameObject pick) { CardChoice instance = CardChoice.instance; if ((Object)(object)instance == (Object)null || (Object)(object)pick == (Object)null || !instance.IsPicking) { return; } List<GameObject> spawnedCards = TakeAllManager.GetSpawnedCards(); if (spawnedCards == null || !spawnedCards.Contains(pick)) { return; } try { instance.Pick(pick, false); } catch (Exception ex) { Plugin.Instance.LogWarn("Auto-pick Pick failed: " + ex.Message); } } } internal sealed class MmCardArtTag : MonoBehaviour { public string ArtName; } internal static class CardArtFactory { private static readonly HashSet<string> RegisteredCardNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> CardNameToArt = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> MissingMiniLogged = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> ArtNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static string _artFolder; private static bool _artFolderResolved; private static bool _artIndexBuilt; private static bool _folderLogged; private static Sprite _vanillaTemplateSprite; private static Type _nullCardInfoType; private static bool _nullCardInfoResolved; private static readonly Dictionary<string, Sprite> FullSprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, Sprite> MiniSprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, GameObject> Templates = new Dictionary<string, GameObject>(); private static string DllDir => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ""; private static string ArtFolder { get { if (_artFolderResolved) { return _artFolder; } _artFolderResolved = true; string dllDir = DllDir; string text = Path.Combine(dllDir, "Art"); if (DirHasPng(text)) { _artFolder = text; } else if (DirHasPng(dllDir)) { _artFolder = dllDir; } else { string text2 = Path.Combine(Directory.GetParent(dllDir)?.FullName ?? dllDir, "Art"); _artFolder = (DirHasPng(text2) ? text2 : text); } if (!_folderLogged) { _folderLogged = true; Plugin.Instance?.Log("Card art folder: " + _artFolder); } return _artFolder; } } internal static GameObject Create(string artName) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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) //IL_00d9: 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_00ee: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(artName)) { return null; } if (Templates.TryGetValue(artName, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite fullSprite = GetFullSprite(artName); if ((Object)(object)fullSprite == (Object)null) { return null; } GameObject val = new GameObject("MM_CardArt_" + artName, new Type[1] { typeof(RectTransform) }); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<MmCardArtTag>().ArtName = artName; Image obj = val.AddComponent<Image>(); obj.sprite = fullSprite; obj.preserveAspect = true; ((Graphic)obj).raycastTarget = false; ((Graphic)obj).color = Color.white; RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 0.5f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; component.anchoredPosition = Vector2.zero; ((Transform)component).localScale = Vector3.one; ((Transform)component).localRotation = Quaternion.identity; CardArtFx.AttachToTemplate(val, artName); Templates[artName] = val; return val; } internal static Sprite GetMiniSprite(string artName) { //IL_00c9: 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) if (string.IsNullOrEmpty(artName)) { return null; } if (MiniSprites.TryGetValue(artName, out var value) && (Object)(object)value != (Object)null) { return value; } string text = ResolvePng(artName + "_mini.png") ?? ResolvePng(artName + ".png"); if (text == null) { if (MissingMiniLogged.Add(artName)) { Plugin.Instance?.LogWarn("No mini PNG for '" + artName + "' in " + ArtFolder + " or next to the DLL"); } return null; } try { Texture2D val = LoadTexture(text); if ((Object)(object)val == (Object)null) { return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); MiniSprites[artName] = val2; return val2; } catch { return null; } } internal static bool IsNullPlaceholder(CardInfo card) { if ((Object)(object)card == (Object)null) { return false; } Type type = NullCardInfoType(); if (type != null && type.IsInstanceOfType(card)) { return true; } if (GameObjectHasNullCardInfo(((Component)card).gameObject)) { return true; } string text = (card.cardName ?? "").Trim(); if (text.StartsWith("[]", StringComparison.Ordinal)) { return true; } if (text.Equals("null", StringComparison.OrdinalIgnoreCase)) { return true; } if (text.Equals("NullCard", StringComparison.OrdinalIgnoreCase)) { return true; } if (text.Equals("Null Card", StringComparison.OrdinalIgnoreCase)) { return true; } return false; } internal static bool GameObjectHasNullCardInfo(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } Type type = NullCardInfoType(); if (type == null) { return false; } return (Object)(object)go.GetComponent(type) != (Object)null; } private static Type NullCardInfoType() { if (_nullCardInfoResolved) { return _nullCardInfoType; } _nullCardInfoResolved = true; _nullCardInfoType = AccessTools.TypeByName("Nullmanager.NullCardInfo"); return _nullCardInfoType; } internal static void TryAssignSprite(CardInfo info) { try { if ((Object)(object)info == (Object)null || IsNullPlaceholder(info)) { return; } string text = ArtNameFor(info); if (string.IsNullOrEmpty(text)) { return; } RegisterCard(info, text); Sprite miniSprite = GetMiniSprite(text); if (!((Object)(object)miniSprite == (Object)null)) { Sprite sprite = info.sprite; if ((Object)(object)_vanillaTemplateSprite == (Object)null && (Object)(object)sprite != (Object)null && (Object)(object)sprite != (Object)(object)miniSprite) { _vanillaTemplateSprite = sprite; } info.sprite = miniSprite; CardBarMiniIcons.AttachFancyIcon(info); StampPickIcons(info, miniSprite, sprite); } } catch (Exception ex) { Plugin.Instance?.LogWarn("TryAssignSprite skipped: " + ex.Message); } } internal static void RegisterCard(CardInfo info, string artName) { if (!((Object)(object)info == (Object)null) && !string.IsNullOrEmpty(artName) && !IsNullPlaceholder(info)) { if (!string.IsNullOrEmpty(info.cardName)) { RegisteredCardNames.Add(info.cardName); CardNameToArt[info.cardName] = artName; } MmCardArtTag mmCardArtTag = ((Component)info).GetComponent<MmCardArtTag>(); if ((Object)(object)mmCardArtTag == (Object)null) { mmCardArtTag = ((Component)info).gameObject.AddComponent<MmCardArtTag>(); } if (string.IsNullOrEmpty(mmCardArtTag.ArtName)) { mmCardArtTag.ArtName = artName; } } } internal static bool IsRegisteredCardName(string cardName) { if (!string.IsNullOrEmpty(cardName)) { return CardNameToArt.ContainsKey(cardName); } return false; } internal static string ArtNameFor(CardInfo info) { if ((Object)(object)info == (Object)null || IsNullPlaceholder(info)) { return null; } MmCardArtTag component = ((Component)info).GetComponent<MmCardArtTag>(); if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.ArtName)) { return component.ArtName; } if ((Object)(object)info.cardArt != (Object)null) { MmCardArtTag component2 = info.cardArt.GetComponent<MmCardArtTag>(); if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(component2.ArtName)) { return component2.ArtName; } } if ((Object)(object)info.sourceCard != (Object)null && (Object)(object)info.sourceCard != (Object)(object)info) { string text = ArtNameFor(info.sourceCard); if (!string.IsNullOrEmpty(text)) { return text; } } return GuessArtName(info.cardName); } internal static string GuessArtName(string cardName) { if (string.IsNullOrEmpty(cardName)) { return null; } if (cardName.Trim().StartsWith("[]", StringComparison.Ordinal)) { return null; } if (CardNameToArt.TryGetValue(cardName, out var value)) { return value; } EnsureArtIndex(); string text = Compact(cardName); if (ArtNames.Contains(text)) { return text; } return null; } internal static void BindLoadedCardInfos() { CardInfo[] array = Resources.FindObjectsOfTypeAll<CardInfo>(); for (int i = 0; i < array.Length; i++) { TryAssignSprite(array[i]); } } private static void StampPickIcons(CardInfo info, Sprite mini, Sprite oldSprite) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)info == (Object)null || (Object)(object)mini == (Object)null) { return; } Image[] componentsInChildren = ((Component)info).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if (IsStampableImage(val) && SpriteMatches(val.sprite, mini, oldSprite)) { ApplyMini(val, mini); } } SpriteRenderer[] componentsInChildren2 = ((Component)info).GetComponentsInChildren<SpriteRenderer>(true); foreach (SpriteRenderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).GetComponent<MmCardArtTag>() != (Object)null) && SpriteMatches(val2.sprite, mini, oldSprite)) { val2.sprite = mini; val2.color = MmArtColorLock.ArtColor; if ((Object)(object)((Component)val2).GetComponent<MmArtColorLock>() == (Object)null) { ((Component)val2).gameObject.AddComponent<MmArtColorLock>(); } } } StampCornerCluster(info, mini); } private static void StampCornerCluster(CardInfo info, Sprite mini) { //IL_0091: 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_00a6: 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) Transform val = null; Transform[] componentsInChildren = ((Component)info).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "EdgePart (2)") { val = val2; break; } } if ((Object)(object)val == (Object)null) { return; } Image val3 = null; Image[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Image>(true); foreach (Image val4 in componentsInChildren2) { if (!IsStampableImage(val4) || ((Object)((Component)val4).transform).name.StartsWith("EdgePart", StringComparison.Ordinal)) { continue; } RectTransform rectTransform = ((Graphic)val4).rectTransform; Rect rect = rectTransform.rect; float num = Mathf.Abs(((Rect)(ref rect)).width); rect = rectTransform.rect; float num2 = Mathf.Abs(((Rect)(ref rect)).height); if (!(num > 140f) && !(num2 > 140f) && (!(num < 8f) || !(num2 < 8f))) { if ((Object)(object)val3 == (Object)null) { val3 = val4; ApplyMini(val4, mini); } else if (SpriteMatches(val4.sprite, mini, _vanillaTemplateSprite) || (Object)(object)val4.sprite == (Object)(object)val3.sprite) { ((Behaviour)val4).enabled = false; } } } } private static bool IsStampableImage(Image img) { if ((Object)(object)img == (Object)null) { return false; } if ((Object)(object)((Component)img).GetComponent<MmCardArtTag>() != (Object)null) { return false; } if ((Object)(object)((Component)img).GetComponent<MmMovingCardBackground>() != (Object)null) { return false; } string name = ((Object)((Component)img).gameObject).name; if (name.StartsWith("MM_", StringComparison.Ordinal)) { return false; } if (name == "ModNameText") { return false; } return true; } private static bool SpriteMatches(Sprite current, Sprite mini, Sprite oldSprite) { if ((Object)(object)current == (Object)null) { return false; } if ((Object)(object)current == (Object)(object)mini) { return true; } if ((Object)(object)oldSprite != (Object)null && (Object)(object)current == (Object)(object)oldSprite) { return true; } if ((Object)(object)_vanillaTemplateSprite != (Object)null) { return (Object)(object)current == (Object)(object)_vanillaTemplateSprite; } return false; } private static void ApplyMini(Image img, Sprite mini) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) img.sprite = mini; img.overrideSprite = mini; img.preserveAspect = true; ((Graphic)img).color = MmArtColorLock.ArtColor; ((Behaviour)img).enabled = true; if ((Object)(object)((Component)img).GetComponent<MmArtColorLock>() == (Object)null) { ((Component)img).gameObject.AddComponent<MmArtColorLock>(); } } private static Sprite GetFullSprite(string artName) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (FullSprites.TryGetValue(artName, out var value) && (Object)(object)value != (Object)null) { return value; } string text = ResolvePng(artName + ".png"); if (text == null) { return null; } try { Texture2D val = LoadTexture(text); if ((Object)(object)val == (Object)null) { return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); FullSprites[artName] = val2; return val2; } catch { return null; } } private static string ResolvePng(string fileName) { string text = Path.Combine(ArtFolder, fileName); if (File.Exists(text)) { return text; } string dllDir = DllDir; string text2 = Path.Combine(dllDir, fileName); if (File.Exists(text2)) { return text2; } string text3 = Path.Combine(dllDir, "Art", fileName); if (File.Exists(text3)) { return text3; } return null; } private static bool DirHasPng(string dir) { try { return Directory.Exists(dir) && Directory.GetFiles(dir, "*.png").Length != 0; } catch { return false; } } private static void EnsureArtIndex() { if (_artIndexBuilt) { return; } _artIndexBuilt = true; try { IndexDir(ArtFolder); IndexDir(DllDir); IndexDir(Path.Combine(DllDir, "Art")); } catch { } } private static void IndexDir(string dir) { if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return; } string[] files = Directory.GetFiles(dir, "*.png"); for (int i = 0; i < files.Length; i++) { string text = Path.GetFileNameWithoutExtension(files[i]); if (!string.IsNullOrEmpty(text)) { if (text.EndsWith("_mini", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 5); } ArtNames.Add(text); } } } private static string Compact(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(char.ToLowerInvariant(c)); } } return stringBuilder.ToString(); } private static Texture2D LoadTexture(string path) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Object.DontDestroyOnLoad((Object)(object)val); return val; } } internal enum MmCardArtMotion { None, SubtleShake, EnergeticShake, Jitter } internal sealed class MmCardArtFxTag : MonoBehaviour { public MmCardArtMotion Motion; public bool MovingBackground; public float GlowScale; } internal sealed class MmArtColorLock : MonoBehaviour { internal static readonly Color ArtColor = new Color(0.82f, 0.82f, 0.82f, 1f); private Image _image; private void Awake() { _image = ((Component)this).GetComponent<Image>(); } private void LateUpdate() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_image != (Object)null) { ((Graphic)_image).color = ArtColor; } } } internal sealed class MmMovingCardBackground : CardAnimation { private const int BlobCount = 5; private Image[] _blobs; private Vector2[] _seeds; private Color _tint = new Color(1f, 0.55f, 0.15f, 0.05f); private bool _built; internal void SetTint(Color themeColor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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) _tint = themeColor; _tint.a = 0.05f; if (_blobs == null) { return; } Image[] blobs = _blobs; foreach (Image val in blobs) { if ((Object)(object)val != (Object)null) { ((Graphic)val).color = _tint; } } } private void OnEnable() { EnsureBuilt(); SetBlobsVisible(on: true); } private void OnDisable() { SetBlobsVisible(on: false); } private void Update() { //IL_003a: 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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_0081: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00dd: 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_0101: 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) if (!_built || _blobs == null) { return; } float unscaledTime = Time.unscaledTime; for (int i = 0; i < _blobs.Length; i++) { Image val = _blobs[i]; if (!((Object)(object)val == (Object)null)) { Vector2 val2 = _seeds[i]; RectTransform rectTransform = ((Graphic)val).rectTransform; float num = Mathf.Sin((unscaledTime + val2.x) * (0.35f + val2.y * 0.4f)) * 28f; float num2 = Mathf.Cos((unscaledTime * 0.7f + val2.y) * (0.4f + val2.x * 0.35f)) * 22f; rectTransform.anchoredPosition = new Vector2(num, num2); float num3 = 0.85f + 0.15f * Mathf.Sin(unscaledTime * (1.1f + val2.x) + val2.y); ((Transform)rectTransform).localScale = Vector3.one * (0.7f + val2.x * 0.5f) * num3; Color tint = _tint; tint.a = _tint.a * (0.65f + 0.35f * num3); ((Graphic)val).color = tint; } } } private void EnsureBuilt() { //IL_006d: 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_0084: 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_00a0: 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_00ca: 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_00fb: 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_0165: 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) if (!_built) { _built = true; _blobs = (Image[])(object)new Image[5]; _seeds = (Vector2[])(object)new Vector2[5]; for (int i = 0; i < 5; i++) { GameObject val = new GameObject("MM_BgBlob_" + i, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(((Component)this).transform, false); val.transform.SetAsFirstSibling(); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(220f + (float)i * 40f, 180f + (float)i * 30f); component.anchoredPosition = Vector2.zero; Image component2 = val.GetComponent<Image>(); component2.sprite = SoftBlobSprite.Instance; component2.type = (Type)0; component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; ((Graphic)component2).color = _tint; _blobs[i] = component2; _seeds[i] = new Vector2(0.15f + (float)i * 0.17f, 0.4f + (float)(i % 3) * 0.2f); } } } private void SetBlobsVisible(bool on) { if (_blobs == null) { return; } Image[] blobs = _blobs; foreach (Image val in blobs) { if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = on; } } } } internal static class SoftBlobSprite { private static Sprite _sprite; internal static Sprite Instance { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sprite != (Object)null) { return _sprite; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); float num = 31.5f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = Mathf.Clamp01(1f - num4); num5 = num5 * num5 * (3f - 2f * num5); val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(false, true); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Object.DontDestroyOnLoad((Object)(object)val); _sprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); Object.DontDestroyOnLoad((Object)(object)_sprite); return _sprite; } } } internal static class CardArtFx { private struct FxSpec { internal MmCardArtMotion Motion; internal bool MovingBg; internal float Glow; internal FxSpec(MmCardArtMotion motion, bool movingBg, float glow) { Motion = motion; MovingBg = movingBg; Glow = glow; } } private static readonly Dictionary<string, FxSpec> Specs = new Dictionary<string, FxSpec> { ["dynamite"] = new FxSpec(MmCardArtMotion.EnergeticShake, movingBg: false, 0f), ["yeetcannon"] = new FxSpec(MmCardArtMotion.EnergeticShake, movingBg: false, 0f), ["kickback"] = new FxSpec(MmCardArtMotion.EnergeticShake, movingBg: false, 0f), ["tasertasertaser"] = new FxSpec(MmCardArtMotion.Jitter, movingBg: false, 0f), ["fumble"] = new FxSpec(MmCardArtMotion.Jitter, movingBg: false, 0f), ["bozoshoes"] = new FxSpec(MmCardArtMotion.SubtleShake, movingBg: false, 0f), ["shove"] = new FxSpec(MmCardArtMotion.SubtleShake, movingBg: false, 0f), ["thief"] = new FxSpec(MmCardArtMotion.SubtleShake, movingBg: false, 0f), ["confetti"] = new FxSpec(MmCardArtMotion.SubtleShake, movingBg: false, 0f), ["returntosender"] = new FxSpec(MmCardArtMotion.None, movingBg: false, 0f), ["nestegg"] = new FxSpec(MmCardArtMotion.None, movingBg: false, 0f) }; private const float DefaultGlow = 0f; internal static void AttachToTemplate(GameObject root, string artName) { if (!((Object)(object)root == (Object)null) && !string.IsNullOrEmpty(artName)) { FxSpec fxSpec = Resolve(artName); MmCardArtFxTag mmCardArtFxTag = root.GetComponent<MmCardArtFxTag>() ?? root.AddComponent<MmCardArtFxTag>(); mmCardArtFxTag.Motion = fxSpec.Motion; mmCardArtFxTag.MovingBackground = fxSpec.MovingBg; mmCardArtFxTag.GlowScale = fxSpec.Glow; if ((Object)(object)root.GetComponent<MmArtColorLock>() == (Object)null) { root.AddComponent<MmArtColorLock>(); } if (!Specs.ContainsKey(artName)) { mmCardArtFxTag.GlowScale = 0f; } ApplyMotion(root, fxSpec.Motion); if (fxSpec.MovingBg) { ((Behaviour)(root.GetComponent<MmMovingCardBackground>() ?? root.AddComponent<MmMovingCardBackground>())).enabled = false; } } } internal static float GlowScaleFor(MmCardArtFxTag fx) { if (!((Object)(object)fx != (Object)null)) { return 0f; } return Mathf.Clamp(fx.GlowScale, 0f, 0.28f); } private static FxSpec Resolve(string artName) { if (Specs.TryGetValue(artName, out var value)) { return value; } return new FxSpec(MmCardArtMotion.None, movingBg: false, 0f); } private static void ApplyMotion(GameObject root, MmCardArtMotion motion) { PositionNoise component = root.GetComponent<PositionNoise>(); if (motion == MmCardArtMotion.None) { if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } return; } PositionNoise val = component ?? root.AddComponent<PositionNoise>(); ((Behaviour)val).enabled = false; switch (motion) { case MmCardArtMotion.SubtleShake: val.amount = 4.5f; val.speed = 1.1f; break; case MmCardArtMotion.EnergeticShake: val.amount = 9f; val.speed = 2.2f; break; case MmCardArtMotion.Jitter: val.amount = 7f; val.speed = 4.5f; break; } } } internal static class CardBarMiniIcons { private const string ChildName = "MM_MiniIcon"; private static readonly Dictionary<string, GameObject> FancyPrefabs = new Dictionary<string, GameObject>(); private static GameObject _fancyHolder; private static Type _fancyIconType; private static bool _fancyResolved; private static readonly FieldInfo CardField = AccessTools.Field(typeof(CardBarButton), "card"); internal static bool IsMmCard(CardInfo card) { if ((Object)(object)card == (Object)null || CardArtFactory.IsNullPlaceholder(card)) { return false; } return !string.IsNullOrEmpty(CardArtFactory.ArtNameFor(card)); } internal static void RestampAll() { CardBar[] array = Object.FindObjectsOfType<CardBar>(); for (int i = 0; i < array.Length; i++) { ApplyAllMmOnBar(array[i]); } } internal static void ApplyToLatestButton(CardBar bar) { ApplyAllMmOnBar(bar); } internal static void ApplyAllMmOnBar(CardBar bar) { if ((Object)(object)bar == (Object)null) { return; } Transform transform = ((Component)bar).transform; for (int i = 0; i < transform.childCount; i++) { GameObject gameObject = ((Component)transform.GetChild(i)).gameObject; CardBarButton component = gameObject.GetComponent<CardBarButton>(); if (!((Object)(object)component == (Object)null)) { object? obj = CardField?.GetValue(component); CardInfo card = (CardInfo)((obj is CardInfo) ? obj : null); Apply(gameObject, card); } } } internal static void Apply(GameObject button, CardInfo card) { if ((Object)(object)button == (Object)null || (Object)(object)card == (Object)null) { return; } if (CardArtFactory.IsNullPlaceholder(card) || CardArtFactory.GameObjectHasNullCardInfo(button)) { ClearMmStamp(button); } else { if (!IsMmCard(card)) { return; } CardArtFactory.TryAssignSprite(card); AttachFancyIcon(card); Sprite val = SpriteFor(card); if (!((Object)(object)val == (Object)null)) { TMP_Text[] componentsInChildren = button.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text obj in componentsInChildren) { ((Behaviour)obj).enabled = false; obj.text = ""; } StripFancyOverlays(button); EnsureCleanOverlay(button, val); card.sprite = val; } } } internal static Sprite SpriteFor(CardInfo card) { if ((Object)(object)card == (Object)null) { return null; } string text = CardArtFactory.ArtNameFor(card); if (!string.IsNullOrEmpty(text)) { Sprite miniSprite = CardArtFactory.GetMiniSprite(text); if ((Object)(object)miniSprite != (Object)null) { return miniSprite; } } if (!IsMmCard(card)) { return null; } return card.sprite; } internal static void AttachFancyIcon(CardInfo info) { try { if ((Object)(object)info == (Object)null || !IsMmCard(info) || CardArtFactory.IsNullPlaceholder(info)) { return; } Type type = FancyIconType(); if (type == null) { return; } string text = CardArtFactory.ArtNameFor(info); if (string.IsNullOrEmpty(text)) { return; } GameObject orCreateFancyPrefab = GetOrCreateFancyPrefab(text); if (!((Object)(object)orCreateFancyPrefab == (Object)null)) { Component val = ((Component)info).gameObject.GetComponent(type); if ((Object)(object)val == (Object)null) { val = ((Component)info).gameObject.AddComponent(type); } AccessTools.Field(type, "fancyIcon")?.SetValue(val, orCreateFancyPrefab); } } catch (Exception ex) { Plugin.Instance?.LogWarn("AttachFancyIcon skipped: " + ex.Message); } } private static Type FancyIconType() { if (_fancyResolved) { return _fancyIconType; } _fancyResolved = true; _fancyIconType = AccessTools.TypeByName("FancyCardBar.FancyIcon"); return _fancyIconType; } private static GameObject GetOrCreateFancyPrefab(string artName) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00c8: 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_00f2: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_0047: Expected O, but got Unknown if (FancyPrefabs.TryGetValue(artName, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite miniSprite = CardArtFactory.GetMiniSprite(artName); if ((Object)(object)miniSprite == (Object)null) { return null; } if (!Object.op_Implicit((Object)(object)_fancyHolder)) { _fancyHolder = new GameObject("MM_FancyBarIconHolder"); Object.DontDestroyOnLoad((Object)(object)_fancyHolder); _fancyHolder.SetActive(false); } GameObject val = new GameObject("MM_FancyBarIcon_" + artName, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(_fancyHolder.transform, false); val.SetActive(true); RectTransform component = val.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(128f, 128f); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; Image component2 = val.GetComponent<Image>(); component2.sprite = miniSprite; component2.overrideSprite = miniSprite; component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; ((Graphic)component2).color = Color.white; FancyPrefabs[artName] = val; return val; } private static void StripFancyOverlays(GameObject button) { if ((Object)(object)button == (Object)null) { return; } MonoBehaviour[] componentsInChildren = button.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(((object)val).GetType().Name != "RGBColorShift")) { ((Behaviour)val).enabled = false; if ((Object)(object)((Component)val).gameObject != (Object)(object)button) { ((Component)val).gameObject.SetActive(false); } } } for (int num = button.transform.childCount - 1; num >= 0; num--) { Transform child = button.transform.GetChild(num); if (!((Object)(object)child == (Object)null) && !(((Object)child).name == "MM_MiniIcon") && !((Object)child).name.StartsWith("MM_FancyBarIcon_", StringComparison.Ordinal) && (Object)(object)((Component)child).GetComponentInChildren<MmCardArtTag>(true) != (Object)null) { ((Component)child).gameObject.SetActive(false); } } } private static void EnsureCleanOverlay(GameObject button, Sprite sprite) { //IL_004f: 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_0066: 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_0078: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) Transform val = button.transform.Find("MM_MiniIcon"); Image component2; if ((Object)(object)val == (Object)null) { GameObject val2 = new GameObject("MM_MiniIcon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val2.transform.SetParent(button.transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 0.5f); component.offsetMin = new Vector2(3f, 3f); component.offsetMax = new Vector2(-3f, -3f); component2 = val2.GetComponent<Image>(); ((Graphic)component2).raycastTarget = false; component2.preserveAspect = true; } else { component2 = ((Component)val).GetComponent<Image>(); val.SetAsLastSibling(); } if (!((Object)(object)component2 == (Object)null)) { component2.sprite = sprite; component2.overrideSprite = sprite; ((Graphic)component2).color = Color.white; ((Behaviour)component2).enabled = true; ((Component)component2).gameObject.SetActive(true); } } private static void ClearMmStamp(GameObject button) { if ((Object)(object)button == (Object)null) { return; } Transform val = button.transform.Find("MM_MiniIcon"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } for (int i = 0; i < button.transform.childCount; i++) { Transform child = button.transform.GetChild(i); if (!((Object)(object)child == (Object)null) && (((Object)child).name.StartsWith("MM_FancyBarIcon_", StringComparison.Ordinal) || (Object)(object)((Component)child).GetComponentInChildren<MmCardArtTag>(true) != (Object)null)) { ((Component)child).gameObject.SetActive(false); } } TMP_Text[] componentsInChildren = button.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { ((Behaviour)val2).enabled = true; } } } } internal static class CardEncoding { internal static string Encode(CardInfo card) { if ((Object)(object)card == (Object)null) { return ""; } string obj = (((Object)(object)((Component)card).gameObject != (Object)null) ? StripClone(((Object)((Component)card).gameObject).name) : ""); string text = card.cardName ?? ""; return obj + "\n" + text; } internal static void Decode(string payload, out string objectName, out string cardName) { objectName = payload ?? ""; cardName = ""; if (!string.IsNullOrEmpty(payload)) { int num = payload.IndexOf('\n'); if (num >= 0) { objectName = payload.Substring(0, num); cardName = payload.Substring(num + 1); } } } internal static CardInfo Resolve(string payload) { Decode(payload, out var objectName, out var cardName); objectName = StripClone(objectName); CardInfo val = null; if (!string.IsNullOrEmpty(objectName)) { try { val = Cards.instance.GetCardWithObjectName(objectName); } catch { } } if ((Object)(object)val == (Object)null && !string.IsNullOrEmpty(cardName)) { try { val = Cards.instance.GetCardWithName(cardName); } catch { } if (val == null) { val = Cards.all?.FirstOrDefault((Func<CardInfo, bool>)((CardInfo c) => (Object)(object)c != (Object)null && !string.IsNullOrEmpty(c.cardName) && string.Equals(c.cardName, cardName, StringComparison.OrdinalIgnoreCase))); } } return val; } internal static string StripClone(string name) { if (string.IsNullOrEmpty(name)) { return name; } while (name.EndsWith("(Clone)", StringComparison.Ordinal)) { name = name.Substring(0, name.Length - "(Clone)".Length).Trim(); } return name.Trim(); } internal static bool Matches(CardInfo card, string payload) { if ((Object)(object)card == (Object)null || string.IsNullOrEmpty(payload)) { return false; } Decode(payload, out var objectName, out var cardName); objectName = StripClone(objectName); if (!string.IsNullOrEmpty(objectName) && (Object)(object)((Component)card).gameObject != (Object)null && string.Equals(StripClone(((Object)((Component)card).gameObject).name), objectName, StringComparison.OrdinalIgnoreCase)) { return true; } if (!string.IsNullOrEmpty(cardName)) { return string.Equals(card.cardName, cardName, StringComparison.OrdinalIgnoreCase); } return false; } internal static int FindCardIndex(Player player, string payload) { List<CardInfo> list = player?.data?.currentCards; if (list == null) { return -1; } for (int i = 0; i < list.Count; i++) { if (Matches(list[i], payload)) { return i; } } return -1; } internal static Player FindHolder(string payload) { if (PlayerManager.instance?.players == null) { return null; } foreach (Player player in PlayerManager.instance.players) { if (!((Object)(object)player == (Object)null) && FindCardIndex(player, payload) >= 0) { return player; } } return null; } } internal static class CardPool { private static MethodInfo _isCardActive; internal static bool IsActive(CardInfo card) { if ((Object)(object)card == (Object)null) { return false; } try { if ((object)_isCardActive == null) { _isCardActive = AccessTools.Method(AccessTools.TypeByName("UnboundLib.Utils.CardManager"), "IsCardActive", (Type[])null, (Type[])null); } if (_isCardActive == null) { return true; } object obj = card; ParameterInfo[] parameters = _isCardActive.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string)) { obj = (((Object)(object)((Component)card).gameObject != (Object)null) ? CardEncoding.StripClone(((Object)((Component)card).gameObject).name) : card.cardName); } if (_isCardActive.Invoke(null, new object[1] { obj }) is bool result) { return result; } } catch { } return true; } } internal static class CardStatApply { internal static CardInfoStat Stat(bool positive, string stat, string amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new CardInfoStat { positive = positive, stat = stat, amount = amount, simepleAmount = (SimpleAmount)0 }; } internal static void AddAmmo(Gun gun, int amount) { if (!((Object)(object)gun == (Object)null)) { gun.ammo = amount; GunAmmo val = ((Component)gun).GetComponent<GunAmmo>() ?? ((Component)gun).GetComponentInChildren<GunAmmo>(true); if ((Object)(object)val != (Object)null) { val.maxAmmo = amount; } } } } internal static class CardTargetUi { private sealed class ToastHost : MonoBehaviour { private TextMeshProUGUI _label; private CanvasGroup _group; private Image _bg; private RectTransform _rect; internal void Build() { //IL_0021: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_0191: 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_01c5: 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_01f3: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0240: 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) _rect = ((Component)this).gameObject.GetComponent<RectTransform>(); _rect.anchorMin = new Vector2(0.5f, 1f); _rect.anchorMax = new Vector2(0.5f, 1f); _rect.pivot = new Vector2(0.5f, 1f); _rect.anchoredPosition = new Vector2(0f, -28f); _rect.sizeDelta = new Vector2(720f, 56f); _group = ((Component)this).gameObject.AddComponent<CanvasGroup>(); _group.blocksRaycasts = false; _group.interactable = false; _group.alpha = 0f; GameObject val = new GameObject("Border", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(((Component)this).transform, false); MmUiGfx.Stretch(val.GetComponent<RectTransform>(), Vector2.zero, Vector2.zero); MmUiGfx.Solid(val.GetComponent<Image>(), new Color(0.95f, 0.82f, 0.35f, 1f)); GameObject val2 = new GameObject("Fill", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(val.transform, false); MmUiGfx.Stretch(val2.GetComponent<RectTransform>(), new Vector2(3f, 3f), new Vector2(-3f, -3f)); _bg = MmUiGfx.Solid(val2.GetComponent<Image>(), new Color(0.06f, 0.1f, 0.08f, 0.92f)); GameObject val3 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val2.transform, false); RectTransform component = val3.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(16f, 8f); component.offsetMax = new Vector2(-16f, -8f); _label = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_label).alignment = (TextAlignmentOptions)514; ((TMP_Text)_label).fontSize = 20f; ((TMP_Text)_label).fontStyle = (FontStyles)1; ((Graphic)_label).color = new Color(1f, 0.95f, 0.82f, 1f); ((Graphic)_label).raycastTarget = false; ((TMP_Text)_label).enableWordWrapping = false; ((TMP_Text)_label).overflowMode = (TextOverflowModes)0; } internal void Show(string message) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_label == (Object)null) && !string.IsNullOrWhiteSpace(message)) { ((Component)this).gameObject.SetActive(true); ((TMP_Text)_label).text = message; ((TMP_Text)_label).enableWordWrapping = false; ((TMP_Text)_label).ForceMeshUpdate(); Canvas.ForceUpdateCanvases(); if ((Object)(object)_rect != (Object)null) { float num = ((TMP_Text)_label).preferredWidth + 32f; float num2 = Mathf.Max(32f, ((TMP_Text)_label).preferredHeight) + 16f; _rect.sizeDelta = new Vector2(Mathf.Clamp(num + 6f, 280f, 980f), num2 + 6f); } _group.alpha = 1f; ((MonoBehaviour)this).CancelInvoke("Hide"); ((MonoBehaviour)this).Invoke("Hide", 3f); } } private void Hide() { if ((Object)(object)_group != (Object)null) { _group.alpha = 0f; } } } private class Overlay : MonoBehaviour { private RectTransform _panel; private TextMeshProUGUI _title; private TextMeshProUGUI _subtitle; private Transform _playerGrid; private Button _confirmButton; private Button _cancelButton; private Player _actor; private Player _selected; private Action<Player> _onConfirm; private string _confirmLabel; internal void Build(Transform canvasRoot) { //IL_000c: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) //IL_004b: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00f2: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_019e: 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_01c8: 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_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown RectTransform component = ((Component)this).gameObject.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Graphic)CreateImage("Dim", ((Component)this).transform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero)).color = new Color(0f, 0f, 0f, 0.72f); _panel = CreatePanel("Panel", ((Component)this).transform, new Vector2(0.5f, 0.5f), new Vector2(680f, 520f)); MmUiGfx.Solid(((Component)_panel).gameObject.AddComponent<Image>(), new Color(0.08f, 0.12f, 0.1f, 0.98f)); _title = CreateText("Title", (Transform)(object)_panel, new Vector2(24f, -20f), 30f, (FontStyles)1); _subtitle = CreateText("Subtitle", (Transform)(object)_panel, new Vector2(24f, -58f), 18f, (FontStyles)0); ((Graphic)_subtitle).color = new Color(0.85f, 0.88f, 0.82f); GameObject val = new GameObject("PlayerGrid", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_panel, false); _playerGrid = val.transform; RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0.22f); component2.anchorMax = new Vector2(1f, 0.78f); component2.offsetMin = new Vector2(24f, 0f); component2.offsetMax = new Vector2(-24f, 0f); GridLayoutGroup obj = val.AddComponent<GridLayoutGroup>(); obj.cellSize = new Vector2(190f, 72f); obj.spacing = new Vector2(12f, 12f); obj.constraint = (Constraint)1; obj.constraintCount = 2; _confirmButton = CreateButton("Confirm", (Transform)(object)_panel, new Vector2(0.56f, 0.08f), _confirmLabel = "CONFIRM"); _cancelButton = CreateButton("Cancel", (Transform)(object)_panel, new Vector2(0.08f, 0.08f), "CANCEL"); ((UnityEvent)_cancelButton.onClick).AddListener(new UnityAction(Close)); } internal void OpenTargetOnly(Player actor, string title, string subtitle, string confirmLabel, Action<Player> onConfirm, bool includeSelf = true) { _actor = actor; _onConfirm = onConfirm; _confirmLabel = confirmLabel; ((TMP_Text)_title).text = title; ((TMP_Text)_subtitle).text = subtitle; ((TMP_Text)((Component)_confirmButton).GetComponentInChildren<TextMeshProUGUI>()).text = confirmLabel; _selected = (includeSelf ? actor : null); RebuildPlayerButtons(includeSelf, filterStealable: false); ((Component)this).gameObject.SetActive(true); } internal void OpenCardChoices(string title, string subtitle, string confirmLabel, List<(string label, GameObject card)> cards, Action<GameObject> onConfirm, Action onCancel) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown _actor = null; _onConfirm = null; _confirmLabel = confirmLabel; ((TMP_Text)_title).text = title; ((TMP_Text)_subtitle).text = subtitle; ((TMP_Text)((Component)_confirmButton).GetComponentInChildren<TextMeshProUGUI>()).text = confirmLabel; _selected = null; ClearGrid(); GameObject picked = null; foreach (var card in cards) { if ((Object)(object)card.card == (Object)null) { continue; } Button button = CreateLabeledButton(card.label); GameObject captured = card.card; ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { //IL_002f: 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_009c: Unknown result type (might be due to invalid IL or missing references) picked = captured; foreach (Transform item in _playerGrid) { Image component = ((Component)item).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0.14f, 0.2f, 0.16f, 1f); } } ((Graphic)((Component)button).GetComponent<Image>()).color = new Color(0.18f, 0.48f, 0.3f, 1f); }); } ((UnityEventBase)_confirmButton.onClick).RemoveAllListeners(); ((UnityEvent)_confirmButton.onClick).AddListener((UnityAction)delegate { if (!((Object)(object)picked == (Object)null)) { onConfirm?.Invoke(picked); Close(); } }); ((UnityEventBase)_cancelButton.onClick).RemoveAllListeners(); ((UnityEvent)_cancelButton.onClick).AddListener((UnityAction)delegate { onCancel?.Invoke(); Close(); }); ((Component)this).gameObject.SetActive(true); } internal void Close() { ((Component)this).gameObject.SetActive(false); ClearGrid(); } private void RebuildPlayerButtons(bool includeSelf, bool filterStealable) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown ClearGrid(); if (PlayerManager.instance?.players == null) { return; } foreach (Player player in PlayerManager.instance.players) { if (!((Object)(object)player == (Object)null) && (includeSelf || !((Object)(object)_actor != (Object)null) || player.playerID != _actor.playerID)) { int stealable = 0; string label = BuildPlayerLabel(player, stealable, filterStealable); Button button = CreateGridButton(label, player); Player captured = player; ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { SelectPlayer(captured, button); }); } } ((UnityEventBase)_confirmButton.onClick).RemoveAllListeners(); ((UnityEvent)_confirmButton.onClick).AddListener((UnityAction)delegate { if (!((Object)(object)_selected == (Object)null)) { _onConfirm?.Invoke(_selected); Close(); } }); ((UnityEventBase)_cancelButton.onClick).RemoveAllListeners(); ((UnityEvent)_cancelButton.onClick).AddListener(new UnityAction(Close)); } private void SelectPlayer(Player player, Button button) { //IL_001b: 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_0083: Unknown result type (might be due to invalid IL or missing references) _selected = player; foreach (Transform item in _playerGrid) { Image component = ((Component)item).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0.14f, 0.2f, 0.16f, 1f); } } ((Graphic)((Component)button).GetComponent<Image>()).color = new Color(0.18f, 0.48f, 0.3f, 1f); } private Button CreateLabeledButton(string label) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0064: 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_0094: 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_00ad: 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_00cd: 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_010d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Choice", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); val.transform.SetParent(_playerGrid, false); MmUiGfx.Solid(val.GetComponent<Image>(), new Color(0.14f, 0.2f, 0.16f, 1f), raycast: true); Button component = val.GetComponent<Button>(); GameObject val2 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(8f, 4f); component2.offsetMax = new Vector2(-8f, -4f); TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).text = label; ((TMP_Text)obj).fontSize = 16f; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((Graphic)obj).color = Color.white; return component; } private Button CreateGridButton(string label, Player player) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0095: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0159: 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) GameObject val = new GameObject("Player_" + player.playerID, new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); val.transform.SetParent(_playerGrid, false); MmUiGfx.Solid(val.GetComponent<Image>(), ((Object)(object)_selected != (Object)null && _selected.playerID == player.playerID) ? new Color(0.18f, 0.48f, 0.3f, 1f) : new Color(0.14f, 0.2f, 0.16f, 1f), raycast: true); Button component = val.GetComponent<Button>(); GameObject val2 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(8f, 4f); component2.offsetMax = new Vector2(-8f, -4f); TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).text = label; ((TMP_Text)obj).fontSize = 16f; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((Graphic)obj).color = Color.white; return component; } private static string BuildPlayerLabel(Player player, int stealable, bool showStealable) { CharacterData data = player.data; object obj; if (data == null) { obj = null; } else { PhotonView view = data.view; if (view == null) { obj = null; } else { Player owner = view.Owner; obj = ((owner != null) ? owner.NickName : null); } } string text = (string)obj; if (string.IsNullOrEmpty(text)) { text = "Player " + (player.playerID + 1); } if (!showStealable) { return text; } if (stealable <= 0) { return text + "\nno cards"; } return $"{text}\n{stealable} stealable"; } private void ClearGrid() { if (!((Object)(object)_playerGrid == (Object)null)) { for (int num = _playerGrid.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)_playerGrid.GetChild(num)).gameObject); } } } private static RectTransform CreatePanel(string name, Transform parent, Vector2 anchor, Vector2 size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: 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_0056: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = anchor; component.anchorMax = anchor; component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = size; component.anchoredPosition = Vector2.zero; return component; } private static Image CreateImage(string name, Transform parent, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax) { //IL_0021: 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_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_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_004f: 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) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = min; component.anchorMax = max; component.offsetMin = offsetMin; component.offsetMax = offsetMax; return MmUiGfx.Solid(val.GetComponent<Image>(), Color.white); } private static TextMeshProUGUI CreateText(string name, Transform parent, Vector2 anchoredPos, float size, FontStyles style) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_006c: 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_0093: 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) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = anchoredPos; component.sizeDelta = new Vector2(-48f, 32f); TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).fontSize = size; ((TMP_Text)obj).fontStyle = style; ((Graphic)obj).color = Color.white; return obj; } private static Button CreateButton(string name, Transform parent, Vector2 anchorMin, string label) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0048: 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_0060: 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) //IL_007f: 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_00ce: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0102: 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) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = anchorMin; component.anchorMax = anchorMin; component.pivot = new Vector2(0f, 0f); component.sizeDelta = new Vector2(260f, 48f); component.anchoredPosition = Vector2.zero; MmUiGfx.Solid(val.GetComponent<Image>(), new Color(0.12f, 0.42f, 0.28f, 1f), raycast: true); Button component2 = val.GetComponent<Button>(); GameObject val2 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = Vector2.zero; component3.offsetMax = Vector2.zero; TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).text = label; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).fontSize = 18f; ((TMP_Text)obj).fontStyle = (FontStyles)1; return component2; } } private static Overlay _overlay; private static ToastHost _toast; internal static bool IsOpen { get { if ((Object)(object)_overlay != (Object)null) { return ((Component)_overlay).gameObject.activeSelf; } return false; } } internal static void OpenSandbag(Player user, Action<Player> onConfirm) { OpenPlayerTarget(user, "Sandbag Simulator", "Choose who rerolls their current pick hand.", "REROLL HAND", onConfirm, includeSelf: true); } internal static void OpenPlayerTarget(Player user, string title, string subtitle, string confirmLabel, Action<Player> onConfirm, bool includeSelf) { EnsureOverlay(); _overlay.OpenTargetOnly(user, title, subtitle, confirmLabel, onConfirm, includeSelf); } internal static void OpenCardChoices(string title, string subtitle, string confirmLabel, List<(string label, GameObject card)> cards, Action<GameObject> onConfirm, Action onCancel = null) { EnsureOverlay(); _overlay.OpenCardChoices(title, subtitle, confirmLabel, cards, onConfirm, onCancel); } internal static void ShowToast(string message) { EnsureToast(); _toast?.Show(message); } internal static void Close() { if ((Object)(object)_overlay != (Object)null) { _overlay.Close(); } } private static void EnsureOverlay() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) if (!((Object)(object)_overlay != (Object)null)) { Unbound instance = Unbound.Instance; Canvas val = ((instance != null) ? instance.canvas : null); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("MM_CardTargetUi", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Component)val).transform, false); _overlay = val2.AddComponent<Overlay>(); _overlay.Build(((Component)val).transform); val2.SetActive(false); } } } private static void EnsureToast() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) if (!((Object)(object)_toast != (Object)null)) { Unbound instance = Unbound.Instance; Canvas val = ((instance != null) ? instance.canvas : null); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("MM_Toast", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Component)val).transform, false); _toast = val2.AddComponent<ToastHost>(); _toast.Build(); val2.SetActive(true); } } } } public class Configs { public ConfigEntry<TakeAllMode> DefaultTakeAllMode { get; } public ConfigEntry<int> DefaultTakeAllUsesPerPlayer { get; } public ConfigEntry<float> DefaultVoteThreshold { get; } public ConfigEntry<float> DefaultVoteTimeoutSeconds { get; } public ConfigEntry<bool> DefaultVoteConsumesUse { get; } public ConfigEntry<bool> DefaultTakeAllCurseCost { get; } public ConfigEntry<TakeAllCurseOnExisting> DefaultCurseOnExisting { get; } public ConfigEntry<bool> DefaultEnableMercyVote { get; } public ConfigEntry<int> DefaultMercyRoundDeficit { get; } public ConfigEntry<bool> DefaultMercyOncePerGame { get; } public ConfigEntry<bool> EnableAutoPickCurses { get; } public ConfigEntry<float> PanicTimerSeconds { get; } public ConfigEntry<bool> FixPristineHealth { get; } public ConfigEntry<bool> EnableThiefCard { get; } public ConfigEntry<bool> EnableTakebacksies { get; } public ConfigEntry<bool> EnableSandbagSimulator { get; } public ConfigEntry<bool> EnableJarOfDirt { get; } public ConfigEntry<bool> SandbagOncePerGame { get; } public ConfigEntry<bool> LogPickPhase { get; } public ConfigEntry<bool> EnableStatsHud { get; } public ConfigEntry<bool> StatsHudVisible { get; } public ConfigEntry<bool> StatsHudCollapsed { get; } public ConfigEntry<bool> StatsHudSimpleMode { get; } public ConfigEntry<bool> StatsHudUltraCompact { get; } public ConfigEntry<bool> StatsHudPeekMode { get; } public ConfigEntry<KeyCode> StatsHudPeekKey { get; } public ConfigEntry<bool> HideStatsHudDuringPick { get; } public ConfigEntry<bool> HideStatsHudDuringBattle { get; } public ConfigEntry<KeyCode> StatsHudToggleKey { get; } public ConfigEntry<float> StatsHudOpacity { get; } public ConfigEntry<float> StatsHudFontScale { get; } public ConfigEntry<float> StatsHudColorR { get; } public ConfigEntry<float> StatsHudColorG { get; } public ConfigEntry<float> StatsHudColorB { get; } public ConfigEntry<bool> EnableStatsTab { get; } public ConfigEntry<bool> EnableTabCompare { get; } public ConfigEntry<float> TabPanelWidth { get; } public ConfigEntry<float> TabPanelHeightFraction { get; } public ConfigEntry<float> TabPanelOpacity { get; } public ConfigEntry<bool> TabAnchorLeft { get; } public ConfigEntry<float> TabPosX { get; } public ConfigEntry<float> TabPosY { get; } public ConfigEntry<bool> ShowPing { get; } public ConfigEntry<bool> ShowPickDeltasOnHud { get; } public ConfigEntry<float> StatsPanelScale { get; } public ConfigEntry<float> StatsHudOffsetX { get; } public ConfigEntry<float> StatsHudOffsetY { get; } public ConfigEntry<float> StatsAccentR { get; } public ConfigEntry<float> StatsAccentG { get; } public ConfigEntry<float> StatsAccentB { get; } public ConfigEntry<bool> AutoCloseTabDuringPick { get; } public Configs(ConfigFile config) { DefaultTakeAllMode = config.Bind<TakeAllMode>("Session Defaults", "TakeAllMode", TakeAllMode.OncePerGame, "0=Disabled, 1=Once per game, 2=Multi-use, 3=Vote"); DefaultTakeAllUsesPerPlayer = config.Bind<int>("Session Defaults", "TakeAllUsesPerPlayer", 1, "Take All uses per player per game (0-3)."); DefaultVoteThreshold = config.Bind<float>("Session Defaults", "VoteThreshold", 0.5f, "Fraction of voters who must accept (excluding requester)."); DefaultVoteTimeoutSeconds = config.Bind<float>("Session Defaults", "VoteTimeoutSeconds", 15f, "Seconds before a Take All vote expires."); DefaultVoteConsumesUse = config.Bind<bool>("Session Defaults", "VoteConsumesUse", true, "Whether a passed vote consumes a Take All use."); DefaultTakeAllCurseCost = config.Bind<bool>("Session Defaults", "TakeAllCurseCost", false, "Take All grants a random Mulligan Madness auto-pick curse afterward."); DefaultCurseOnExisting = config.Bind<TakeAllCurseOnExisting>("Session Defaults", "CurseOnExisting", TakeAllCurseOnExisting.ReplaceExisting, "0=Replace existing MulliganMadness curse, 1=Skip curse if player already has one."); DefaultEnableMercyVote = config.Bind<bool>("Session Defaults", "EnableMercyVote", false, "Auto-offer a Take All vote when a player is down by MercyRoundDeficit round wins."); DefaultMercyRoundDeficit = config.Bind<int>("Session Defaults", "MercyRoundDeficit", 2, "Round-win deficit vs the leader before mercy vote can trigger."); DefaultMercyOncePerGame = config.Bind<bool>("Session Defaults", "MercyOncePerGame", true, "Limit mercy vote to once per player per game."); FixPristineHealth = config.Bind<bool>("Session Defaults", "FixPristineHealth", true, "Stop Pristine Perseverance from collapsing HP when a later card reduces health."); EnableAutoPickCurses = config.Bind<bool>("Session Defaults", "EnableAutoPickCurses", true, "Register the auto-pick curse set (mutually exclusive with each other)."); PanicTimerSeconds = config.Bind<float>("Session Defaults", "PanicTimerSeconds", 3f, "How long Panic Pick waits before choosing for you."); EnableThiefCard = config.Bind<bool>("Session Defaults", "EnableThief", true, "Allow the Thief legendary card in this session."); EnableTakebacksies = config.Bind<bool>("Session Defaults", "EnableTakebacksies", true, "Allow Takebacksies and inject it for stolen-from players."); EnableSandbagSimulator = config.Bind<bool>("Session Defaults", "EnableSandbagSimulator", true, "Allow the Sandbag Simulator legendary card in this session."); EnableJarOfDirt = config.Bind<bool>("Session Defaults", "EnableJarOfDirt", true, "Allow the Jar of Dirt unique card in this session."); SandbagOncePerGame = config.Bind<bool>("Session Defaults", "SandbagOncePerGame", true, "Limit Sandbag Simulator to once per game per player."); LogPickPhase = config.Bind<bool>("Diagnostics", "LogPickPhase", false, "Log a line each time a card pick starts. Only useful when reporting a bug."); if (!config.Bind<bool>("Take All", "Enabled", true, "Deprecated - use Session Defaults.TakeAllMode.").Value && DefaultTakeAllMode.Value != TakeAllMode.Disabled) { DefaultTakeAllMode.Value = TakeAllMode.Disabled; } EnableStatsHud = config.Bind<bool>("Stats HUD", "Enabled", true, "Always-on stats panel (replaces Infoholic)."); StatsHudVisible = config.Bind<bool>("Stats HUD", "Visible", true, "Whether the HUD is currently shown (toggle in-game with StatsHudToggleKey)."); StatsHudCollapsed = config.Bind<bool>("Stats HUD", "Collapsed", false, "Show the HUD as a minimal strip instead of the full panel."); StatsHudSimpleMode = config.Bind<bool>("Stats HUD", "SimpleMode", true, "Show a compact stat list instead of every stat."); StatsHudUltraCompact = config.Bind<bool>("Stats HUD", "UltraCompact", false, "Narrow HUD with fewer lines."); StatsHudPeekMode = config.Bind<bool>("Stats HUD", "PeekMode", false, "Only show the HUD while holding the peek key."); StatsHudPeekKey = config.Bind<KeyCode>("Stats HUD", "PeekKey", (KeyCode)308, "Hold to show HUD when PeekMode is enabled."); HideStatsHudDuringPick = config.Bind<bool>("Stats HUD", "HideDuringPick", false, "Hide the always-on HUD during card pick."); HideStatsHudDuringBattle = config.Bind<bool>("Stats HUD", "HideDuringBattle", false, "Hide the always-on HUD during battle rounds."); StatsHudToggleKey = config.Bind<KeyCode>("Stats HUD", "ToggleKey", (KeyCode)111, "Toggle the always-on HUD visibility."); StatsHudOpacity = config.Bind<float>("Stats HUD", "Opacity", 0f, "Background opacity for the HUD panel (0 = text only)."); if (Mathf.Abs(StatsHudOpacity.Value - 0.78f) < 0.001f) { StatsHudOpacity.Value = 0f; } StatsHudFontScale = config.Bind<float>("Stats HUD", "FontScale", 1f, "Text scale multiplier (auto-scales with resolution too)."); StatsHudColorR = config.Bind<float>("Stats HUD", "ColorR", 1f, "HUD text red channel."); StatsHudColorG = config.Bind<float>("Stats HUD", "ColorG", 1f, "HUD text green channel."); StatsHudColorB = config.Bind<float>("Stats HUD", "ColorB", 1f, "HUD text blue channel."); EnableStatsTab = config.Bind<bool>("Stats Tab", "Enabled", true, "Tab overlay for all players (replaces TabInfo). Press Tab in-game."); EnableTabCompare = config.Bind<bool>("Stats Tab", "EnableCompare", true, "Compare mode inside the Tab overlay (C toggles, [ ] switches opponent)."); TabPanelWidth = config.Bind<float>("Stats Tab", "PanelWidth", 480f, "Tab overlay width in pixels (before scale)."); TabPanelHeightFraction = config.Bind<float>("Stats Tab", "PanelHeightFraction", 0.82f, "Tab overlay height as a fraction of screen height."); TabPanelOpacity = config.Bind<float>("Stats Tab", "PanelOpacity", 0.94f, "Tab overlay background opacity."); TabAnchorLeft = config.Bind<bool>("Stats Tab", "AnchorLeft", false, "Deprecated - drag the Tab panel in-game."); TabPosX = config.Bind<float>("Stats Tab", "PosX", -1f, "Tab overlay X in canvas pixels. Negative = default centered."); TabPosY = config.Bind<float>("Stats Tab", "PosY", -1f, "Tab overlay Y in canvas pixels. Negative = default centered."); ShowPing = config.Bind<bool>("Stats Tab", "ShowPing", true, "Show Photon ping next to player names in the Tab overlay and HUD (online games)."); ShowPickDeltasOnHud = config.Bind<bool>("Stats HUD", "ShowPickDeltas", true, "During picks, show card deltas on the bottom-left HUD for whoever is picking (hover a card to preview)."); StatsPanelScale = config.Bind<float>("Stats Layout", "PanelScale", 1f, "Global UI scale multiplier."); StatsHudOffsetX = config.Bind<float>("Stats Layout", "HudOffsetX", 14f, "HUD distance from left edge."); StatsHudOffsetY = config.Bind<float>("Stats Layout", "HudOffsetY", 14f, "HUD distance from bottom edge."); StatsAccentR = config.Bind<float>("Stats Layout", "AccentR", 0.35f, "Accent color red."); StatsAccentG = config.Bind<float>("Stats Layout", "AccentG", 0.82f, "Accent color green."); StatsAccentB = config.Bind<float>("Stats Layout", "AccentB", 0.72f, "Accent color blue."); AutoCloseTabDuringPick = config.Bind<bool>("Stats Tab", "AutoCloseDuringPick", false, "Close the Tab overlay when a card pick starts so cards stay clickable. Tab still toggles it open again."); } } internal static class CurseOwnership { internal const float FumbleChance = 0.5f; internal const float KickbackDamageMultiplier = 1.25f; internal const float KickbackForce = 1700f; internal static bo